From 3101266105bd56d61d04c546ed695cf5194c1f9d Mon Sep 17 00:00:00 2001 From: David Ames Date: Thu, 27 Apr 2017 11:16:50 -0700 Subject: [PATCH] Enable Zesty-Ocata Amulet Tests - Turn on Zesty-Ocata Amulet test definitions. - Standardize test-requirements.txt - Sync charm helpers for various fixes Change-Id: Ibe6fffd7f615e43342b73258bde870dee9dcc5ad --- .../charmhelpers/contrib/charmsupport/nrpe.py | 2 +- hooks/charmhelpers/contrib/network/ip.py | 59 ++++++++++++------- hooks/charmhelpers/core/host.py | 4 +- hooks/hooks.py | 6 ++ metadata.yaml | 1 + test-requirements.txt | 20 ++++--- tests/basic_deployment.py | 38 ++---------- .../contrib/openstack/amulet/utils.py | 2 +- tests/charmhelpers/core/host.py | 4 +- tests/gate-basic-zesty-ocata | 0 10 files changed, 66 insertions(+), 70 deletions(-) mode change 100644 => 100755 tests/gate-basic-zesty-ocata diff --git a/hooks/charmhelpers/contrib/charmsupport/nrpe.py b/hooks/charmhelpers/contrib/charmsupport/nrpe.py index 9646b83..8240249 100644 --- a/hooks/charmhelpers/contrib/charmsupport/nrpe.py +++ b/hooks/charmhelpers/contrib/charmsupport/nrpe.py @@ -373,7 +373,7 @@ def add_init_service_checks(nrpe, services, unit_name, immediate_check=True): checkpath = '%s/service-check-%s.txt' % (nrpe.homedir, svc) croncmd = ( '/usr/local/lib/nagios/plugins/check_exit_status.pl ' - '-s /etc/init.d/%s status' % svc + '-e -s /etc/init.d/%s status' % svc ) cron_file = '*/5 * * * * root %s > %s\n' % (croncmd, checkpath) f = open(cronpath, 'w') diff --git a/hooks/charmhelpers/contrib/network/ip.py b/hooks/charmhelpers/contrib/network/ip.py index 7451af9..fc3f5e3 100644 --- a/hooks/charmhelpers/contrib/network/ip.py +++ b/hooks/charmhelpers/contrib/network/ip.py @@ -111,11 +111,11 @@ def get_address_in_network(network, fallback=None, fatal=False): for iface in netifaces.interfaces(): addresses = netifaces.ifaddresses(iface) if network.version == 4 and netifaces.AF_INET in addresses: - addr = addresses[netifaces.AF_INET][0]['addr'] - netmask = addresses[netifaces.AF_INET][0]['netmask'] - cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask)) - if cidr in network: - return str(cidr.ip) + for addr in addresses[netifaces.AF_INET]: + cidr = netaddr.IPNetwork("%s/%s" % (addr['addr'], + addr['netmask'])) + if cidr in network: + return str(cidr.ip) if network.version == 6 and netifaces.AF_INET6 in addresses: for addr in addresses[netifaces.AF_INET6]: @@ -239,6 +239,16 @@ def format_ipv6_addr(address): return None +def is_ipv6_disabled(): + try: + result = subprocess.check_output( + ['sysctl', 'net.ipv6.conf.all.disable_ipv6'], + stderr=subprocess.STDOUT) + return "net.ipv6.conf.all.disable_ipv6 = 1" in result + except subprocess.CalledProcessError: + return True + + def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False, fatal=True, exc_list=None): """Return the assigned IP address for a given interface, if any. @@ -544,31 +554,38 @@ def assert_charm_supports_ipv6(): "versions less than Trusty 14.04") -def get_relation_ip(interface, config_override=None): - """Return this unit's IP for the given relation. +def get_relation_ip(interface, cidr_network=None): + """Return this unit's IP for the given interface. Allow for an arbitrary interface to use with network-get to select an IP. - Handle all address selection options including configuration parameter - override and IPv6. + Handle all address selection options including passed cidr network and + IPv6. - Usage: get_relation_ip('amqp', config_override='access-network') + Usage: get_relation_ip('amqp', cidr_network='10.0.0.0/8') @param interface: string name of the relation. - @param config_override: string name of the config option for network - override. Supports legacy network override configuration parameters. + @param cidr_network: string CIDR Network to select an address from. @raises Exception if prefer-ipv6 is configured but IPv6 unsupported. @returns IPv6 or IPv4 address """ + # Select the interface address first + # For possible use as a fallback bellow with get_address_in_network + try: + # Get the interface specific IP + address = network_get_primary_address(interface) + except NotImplementedError: + # If network-get is not available + address = get_host_ip(unit_get('private-address')) - fallback = get_host_ip(unit_get('private-address')) if config('prefer-ipv6'): + # Currently IPv6 has priority, eventually we want IPv6 to just be + # another network space. assert_charm_supports_ipv6() return get_ipv6_addr()[0] - elif config_override and config(config_override): - return get_address_in_network(config(config_override), - fallback) - else: - try: - return network_get_primary_address(interface) - except NotImplementedError: - return fallback + elif cidr_network: + # If a specific CIDR network is passed get the address from that + # network. + return get_address_in_network(cidr_network, address) + + # Return the interface address + return address diff --git a/hooks/charmhelpers/core/host.py b/hooks/charmhelpers/core/host.py index 0ee5cb9..88e80a4 100644 --- a/hooks/charmhelpers/core/host.py +++ b/hooks/charmhelpers/core/host.py @@ -191,7 +191,7 @@ def service_pause(service_name, init_dir="/etc/init", initd_dir="/etc/init.d", upstart_file = os.path.join(init_dir, "{}.conf".format(service_name)) sysv_file = os.path.join(initd_dir, service_name) if init_is_systemd(): - service('disable', service_name) + service('mask', service_name) elif os.path.exists(upstart_file): override_path = os.path.join( init_dir, '{}.override'.format(service_name)) @@ -224,7 +224,7 @@ def service_resume(service_name, init_dir="/etc/init", upstart_file = os.path.join(init_dir, "{}.conf".format(service_name)) sysv_file = os.path.join(initd_dir, service_name) if init_is_systemd(): - service('enable', service_name) + service('unmask', service_name) elif os.path.exists(upstart_file): override_path = os.path.join( init_dir, '{}.override'.format(service_name)) diff --git a/hooks/hooks.py b/hooks/hooks.py index 845933c..2677d69 100755 --- a/hooks/hooks.py +++ b/hooks/hooks.py @@ -40,6 +40,8 @@ from charmhelpers.core.hookenv import ( from charmhelpers.core.host import ( service_stop, service_running, + lsb_release, + CompareHostReleases, ) from charmhelpers.fetch import ( @@ -101,6 +103,10 @@ DEPRECATED_TRANSPORT_VALUES = {"multicast": "udp", "unicast": "udpu"} @hooks.hook() def install(): + ubuntu_release = lsb_release()['DISTRIB_CODENAME'].lower() + if CompareHostReleases(ubuntu_release) >= 'zesty': + PACKAGES.remove('libnagios-plugin-perl') + PACKAGES.append('libnagios-object-perl') # NOTE(dosaboy): we currently disallow upgrades due to bug #1382842. This # should be removed once the pacemaker package is fixed. status_set('maintenance', 'Installing apt packages') diff --git a/metadata.yaml b/metadata.yaml index fdb5090..077e918 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -10,6 +10,7 @@ series: - xenial - trusty - yakkety + - zesty requires: juju-info: interface: juju-info diff --git a/test-requirements.txt b/test-requirements.txt index 74baa12..9edd4bb 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -11,15 +11,17 @@ requests==2.6.0 # Liberty client lower constraints amulet>=1.14.3,<2.0 bundletester>=0.6.1,<1.0 -python-ceilometerclient>=1.5.0,<2.0 -python-cinderclient>=1.4.0,<2.0 -python-glanceclient>=1.1.0,<2.0 -python-heatclient>=0.8.0,<1.0 -python-keystoneclient>=1.7.1,<2.0 -python-neutronclient>=3.1.0,<4.0 -python-novaclient>=2.30.1,<3.0 -python-openstackclient>=1.7.0,<2.0 -python-swiftclient>=2.6.0,<3.0 +python-ceilometerclient>=1.5.0 +python-cinderclient>=1.4.0 +python-glanceclient>=1.1.0 +python-heatclient>=0.8.0 +python-keystoneclient>=1.7.1 +python-neutronclient>=3.1.0 +python-novaclient>=2.30.1 +python-openstackclient>=1.7.0 +python-swiftclient>=2.6.0 pika>=0.10.0,<1.0 distro-info # END: Amulet OpenStack Charm Helper Requirements +# NOTE: workaround for 14.04 pip/tox +pytz diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index b38f536..90071f4 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -15,10 +15,7 @@ # limitations under the License. import os -import subprocess -import json import amulet -import time from charmhelpers.contrib.openstack.amulet.deployment import ( OpenStackAmuletDeployment @@ -154,45 +151,18 @@ class HAClusterBasicDeployment(OpenStackAmuletDeployment): password='password', tenant=self.demo_tenant) - def _run_action(self, unit_id, action, *args): - command = ["juju", "action", "do", "--format=json", unit_id, action] - command.extend(args) - print("Running command: %s\n" % " ".join(command)) - output = subprocess.check_output(command) - output_json = output.decode(encoding="UTF-8") - data = json.loads(output_json) - action_id = data[u'Action queued with id'] - return action_id - - def _wait_on_action(self, action_id): - command = ["juju", "action", "fetch", "--format=json", action_id] - while True: - try: - output = subprocess.check_output(command) - except Exception as e: - print(e) - return False - output_json = output.decode(encoding="UTF-8") - data = json.loads(output_json) - if data[u"status"] == "completed": - return True - elif data[u"status"] == "failed": - return False - time.sleep(2) - def test_910_pause_and_resume(self): """The services can be paused and resumed. """ u.log.debug('Checking pause and resume actions...') unit = self.hacluster_sentry - unit_name = unit.info['unit_name'] assert u.status_get(unit)[0] == "active" - action_id = self._run_action(unit_name, "pause") - assert self._wait_on_action(action_id), "Pause action failed." + action_id = u.run_action(unit, "pause") + assert u.wait_on_action(action_id), "Pause action failed." assert u.status_get(unit)[0] == "maintenance" - action_id = self._run_action(unit_name, "resume") - assert self._wait_on_action(action_id), "Resume action failed." + action_id = u.run_action(unit, "resume") + assert u.wait_on_action(action_id), "Resume action failed." assert u.status_get(unit)[0] == "active" u.log.debug('OK') diff --git a/tests/charmhelpers/contrib/openstack/amulet/utils.py b/tests/charmhelpers/contrib/openstack/amulet/utils.py index 346e6fe..bcef4cd 100644 --- a/tests/charmhelpers/contrib/openstack/amulet/utils.py +++ b/tests/charmhelpers/contrib/openstack/amulet/utils.py @@ -547,7 +547,7 @@ class OpenStackAmuletUtils(AmuletUtils): """Create the specified instance.""" self.log.debug('Creating instance ' '({}|{}|{})'.format(instance_name, image_name, flavor)) - image = nova.images.find(name=image_name) + image = nova.glance.find_image(image_name) flavor = nova.flavors.find(name=flavor) instance = nova.servers.create(name=instance_name, image=image, flavor=flavor) diff --git a/tests/charmhelpers/core/host.py b/tests/charmhelpers/core/host.py index 0ee5cb9..88e80a4 100644 --- a/tests/charmhelpers/core/host.py +++ b/tests/charmhelpers/core/host.py @@ -191,7 +191,7 @@ def service_pause(service_name, init_dir="/etc/init", initd_dir="/etc/init.d", upstart_file = os.path.join(init_dir, "{}.conf".format(service_name)) sysv_file = os.path.join(initd_dir, service_name) if init_is_systemd(): - service('disable', service_name) + service('mask', service_name) elif os.path.exists(upstart_file): override_path = os.path.join( init_dir, '{}.override'.format(service_name)) @@ -224,7 +224,7 @@ def service_resume(service_name, init_dir="/etc/init", upstart_file = os.path.join(init_dir, "{}.conf".format(service_name)) sysv_file = os.path.join(initd_dir, service_name) if init_is_systemd(): - service('enable', service_name) + service('unmask', service_name) elif os.path.exists(upstart_file): override_path = os.path.join( init_dir, '{}.override'.format(service_name)) diff --git a/tests/gate-basic-zesty-ocata b/tests/gate-basic-zesty-ocata old mode 100644 new mode 100755