diff --git a/config.yaml b/config.yaml index 237beae..835a786 100644 --- a/config.yaml +++ b/config.yaml @@ -1,4 +1,12 @@ options: + debug: + default: False + type: boolean + description: Enable debug logging. + verbose: + default: False + type: boolean + description: Enable verbose logging. openstack-origin: default: distro type: string @@ -102,3 +110,15 @@ options: wait for you to execute the openstack-upgrade action for this charm on each unit. If False it will revert to existing behavior of upgrading all units on config change. + prefer-ipv6: + type: boolean + default: False + description: | + If True enables IPv6 support. The charm will expect network interfaces + to be configured with an IPv6 address. If set to False (default) IPv4 + is expected. + . + NOTE: these charms do not currently support IPv6 privacy extension. In + order for this charm to function correctly, the privacy extension must be + disabled and a non-temporary address must be configured/available on + your network interface. diff --git a/hooks/heat_relations.py b/hooks/heat_relations.py index e6d0e0b..8a22963 100755 --- a/hooks/heat_relations.py +++ b/hooks/heat_relations.py @@ -39,6 +39,7 @@ from charmhelpers.contrib.openstack.utils import ( configure_installation_source, openstack_upgrade_available, set_os_workload_status, + sync_db_with_multi_ipv6_addresses, ) from charmhelpers.contrib.openstack.ip import ( @@ -56,6 +57,7 @@ from heat_utils import ( register_configs, HEAT_CONF, REQUIRED_INTERFACES, + setup_ipv6, ) from heat_context import ( @@ -95,6 +97,14 @@ def config_changed(): if openstack_upgrade_available('heat-common'): status_set('maintenance', 'Running openstack upgrade') do_openstack_upgrade(CONFIGS) + + if config('prefer-ipv6'): + status_set('maintenance', 'configuring ipv6') + setup_ipv6() + sync_db_with_multi_ipv6_addresses(config('database'), + config('database-user'), + relation_prefix='heat') + CONFIGS.write_all() configure_https() @@ -116,9 +126,14 @@ def amqp_changed(): @hooks.hook('shared-db-relation-joined') def db_joined(): - relation_set(heat_database=config('database'), - heat_username=config('database-user'), - heat_hostname=unit_get('private-address')) + if config('prefer-ipv6'): + sync_db_with_multi_ipv6_addresses(config('database'), + config('database-user'), + relation_prefix='heat') + else: + relation_set(heat_database=config('database'), + heat_username=config('database-user'), + heat_hostname=unit_get('private-address')) @hooks.hook('shared-db-relation-changed') diff --git a/hooks/heat_utils.py b/hooks/heat_utils.py index c834e43..92ef8bb 100644 --- a/hooks/heat_utils.py +++ b/hooks/heat_utils.py @@ -17,6 +17,7 @@ from charmhelpers.contrib.openstack.utils import ( os_release) from charmhelpers.fetch import ( + add_source, apt_install, apt_update, apt_upgrade, @@ -24,10 +25,11 @@ from charmhelpers.fetch import ( from charmhelpers.core.hookenv import ( log, - config + config, ) from charmhelpers.core.host import ( + lsb_release, service_start, service_stop, ) @@ -86,7 +88,9 @@ CONFIG_FILES = OrderedDict([ HeatHAProxyContext(), EncryptionContext(), InstanceUserContext(), - context.SyslogContext()] + context.SyslogContext(), + context.LogLevelContext(), + context.BindHostContext()] }), (HEAT_API_PASTE, { 'services': [s for s in BASE_SERVICES if 'api' in s], @@ -202,3 +206,18 @@ def migrate_database(): [service_stop(s) for s in services()] check_call(['heat-manage', 'db_sync']) [service_start(s) for s in services()] + + +def setup_ipv6(): + ubuntu_rel = lsb_release()['DISTRIB_CODENAME'].lower() + if ubuntu_rel < "trusty": + raise Exception("IPv6 is not supported in the charms for Ubuntu " + "versions less than Trusty 14.04") + + # Need haproxy >= 1.5.3 for ipv6 so for Trusty if we are <= Kilo we need to + # use trusty-backports otherwise we can use the UCA. + if ubuntu_rel == 'trusty' and os_release('heat-common') < 'liberty': + add_source('deb http://archive.ubuntu.com/ubuntu trusty-backports ' + 'main') + apt_update() + apt_install('haproxy/trusty-backports', fatal=True) diff --git a/metadata.yaml b/metadata.yaml index 4613da0..c30d3ae 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -1,6 +1,6 @@ name: heat summary: OpenStack orchestration engine -maintainer: Yolanda Robla +maintainer: OpenStack Charmers description: | Heat is the main project in the OpenStack Orchestration program. It implements an orchestration engine to launch multiple composite cloud applications based on diff --git a/templates/heat.conf b/templates/heat.conf index 2fa58c0..19b4fad 100644 --- a/templates/heat.conf +++ b/templates/heat.conf @@ -1,7 +1,7 @@ [DEFAULT] use_syslog = {{ use_syslog }} -debug = False -verbose = False +verbose = {{ verbose }} +debug = {{ debug }} log_dir = /var/log/heat # Icehouse expects 'instance_user=' to allow the image's default user # Not including instance_user at all results in 'ec2-user' being used diff --git a/templates/kilo/heat.conf b/templates/kilo/heat.conf index 2cbc62f..81da4aa 100644 --- a/templates/kilo/heat.conf +++ b/templates/kilo/heat.conf @@ -64,6 +64,7 @@ connection = {{ database_type }}://{{ database_user }}:{{ database_password }}@{ api_paste_config=/etc/heat/api-paste.ini [heat_api] +bind_host = {{ bind_host }} {% if api_listen_port -%} bind_port={{ api_listen_port }} {% else -%} @@ -71,6 +72,7 @@ bind_port=8004 {% endif %} [heat_api_cfn] +bind_host = {{ bind_host }} {% if api_cfn_listen_port -%} bind_port={{ api_cfn_listen_port }} {% else -%} diff --git a/unit_tests/test_heat_relations.py b/unit_tests/test_heat_relations.py index 2b3a625..dfcd60d 100644 --- a/unit_tests/test_heat_relations.py +++ b/unit_tests/test_heat_relations.py @@ -31,6 +31,7 @@ TO_PATCH = [ 'openstack_upgrade_available', 'determine_packages', 'charm_dir', + 'sync_db_with_multi_ipv6_addresses', # charmhelpers.contrib.hahelpers.cluster_utils # heat_utils 'restart_map', @@ -232,3 +233,12 @@ class HeatRelationTests(CharmTestCase): relations.identity_changed() self.assertTrue(self.log.called) self.assertFalse(configs.write.called) + + def test_db_joined_with_ipv6(self): + 'It properly requests access to a shared-db service' + self.unit_get.return_value = 'heatnode1' + self.sync_db_with_multi_ipv6_addresses.return_value = MagicMock() + self.test_config.set('prefer-ipv6', True) + relations.db_joined() + self.sync_db_with_multi_ipv6_addresses.assert_called_with_once( + 'heat', 'heat')