From c1d57d63b85f0b68fa04130ebf59c7986fb6ceb8 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 12 Apr 2016 13:46:04 +0000 Subject: [PATCH] CH sync --- hooks/charmhelpers/contrib/network/ip.py | 9 +++++ hooks/charmhelpers/contrib/openstack/utils.py | 9 +++-- hooks/charmhelpers/core/host.py | 38 +++++++++++++++---- tests/charmhelpers/contrib/amulet/utils.py | 26 ++++++++----- .../contrib/openstack/amulet/deployment.py | 4 +- 5 files changed, 64 insertions(+), 22 deletions(-) diff --git a/hooks/charmhelpers/contrib/network/ip.py b/hooks/charmhelpers/contrib/network/ip.py index 4efe799..b9c7900 100644 --- a/hooks/charmhelpers/contrib/network/ip.py +++ b/hooks/charmhelpers/contrib/network/ip.py @@ -191,6 +191,15 @@ get_iface_for_address = partial(_get_for_address, key='iface') get_netmask_for_address = partial(_get_for_address, key='netmask') +def resolve_network_cidr(ip_address): + ''' + Resolves the full address cidr of an ip_address based on + configured network interfaces + ''' + netmask = get_netmask_for_address(ip_address) + return str(netaddr.IPNetwork("%s/%s" % (ip_address, netmask)).cidr) + + def format_ipv6_addr(address): """If address is IPv6, wrap it in '[]' otherwise return None. diff --git a/hooks/charmhelpers/contrib/openstack/utils.py b/hooks/charmhelpers/contrib/openstack/utils.py index 3fb67b1..61d5879 100644 --- a/hooks/charmhelpers/contrib/openstack/utils.py +++ b/hooks/charmhelpers/contrib/openstack/utils.py @@ -137,7 +137,7 @@ SWIFT_CODENAMES = OrderedDict([ ('liberty', ['2.3.0', '2.4.0', '2.5.0']), ('mitaka', - ['2.5.0', '2.6.0']), + ['2.5.0', '2.6.0', '2.7.0']), ]) # >= Liberty version->codename mapping @@ -156,6 +156,7 @@ PACKAGE_CODENAMES = { ]), 'keystone': OrderedDict([ ('8.0', 'liberty'), + ('8.1', 'liberty'), ('9.0', 'mitaka'), ]), 'horizon-common': OrderedDict([ @@ -1534,7 +1535,8 @@ def make_assess_status_func(*args, **kwargs): return _assess_status_func -def pausable_restart_on_change(restart_map, stopstart=False): +def pausable_restart_on_change(restart_map, stopstart=False, + restart_functions=None): """A restart_on_change decorator that checks to see if the unit is paused. If it is paused then the decorated function doesn't fire. @@ -1567,6 +1569,7 @@ def pausable_restart_on_change(restart_map, stopstart=False): return f(*args, **kwargs) # otherwise, normal restart_on_change functionality return restart_on_change_helper( - (lambda: f(*args, **kwargs)), restart_map, stopstart) + (lambda: f(*args, **kwargs)), restart_map, stopstart, + restart_functions) return wrapped_f return wrap diff --git a/hooks/charmhelpers/core/host.py b/hooks/charmhelpers/core/host.py index 481087b..bfea6a1 100644 --- a/hooks/charmhelpers/core/host.py +++ b/hooks/charmhelpers/core/host.py @@ -128,6 +128,13 @@ def service(action, service_name): return subprocess.call(cmd) == 0 +def systemv_services_running(): + output = subprocess.check_output( + ['service', '--status-all'], + stderr=subprocess.STDOUT).decode('UTF-8') + return [row.split()[-1] for row in output.split('\n') if '[ + ]' in row] + + def service_running(service_name): """Determine whether a system service is running""" if init_is_systemd(): @@ -140,11 +147,15 @@ def service_running(service_name): except subprocess.CalledProcessError: return False else: + # This works for upstart scripts where the 'service' command + # returns a consistent string to represent running 'start/running' if ("start/running" in output or "is running" in output or "up and running" in output): return True - else: - return False + # Check System V scripts init script return codes + if service_name in systemv_services_running(): + return True + return False def service_available(service_name): @@ -412,7 +423,7 @@ class ChecksumError(ValueError): pass -def restart_on_change(restart_map, stopstart=False): +def restart_on_change(restart_map, stopstart=False, restart_functions=None): """Restart services based on configuration files changing This function is used a decorator, for example:: @@ -433,18 +444,22 @@ def restart_on_change(restart_map, stopstart=False): @param restart_map: {path_file_name: [service_name, ...] @param stopstart: DEFAULT false; whether to stop, start OR restart + @param restart_functions: nonstandard functions to use to restart services + {svc: func, ...} @returns result from decorated function """ def wrap(f): @functools.wraps(f) def wrapped_f(*args, **kwargs): return restart_on_change_helper( - (lambda: f(*args, **kwargs)), restart_map, stopstart) + (lambda: f(*args, **kwargs)), restart_map, stopstart, + restart_functions) return wrapped_f return wrap -def restart_on_change_helper(lambda_f, restart_map, stopstart=False): +def restart_on_change_helper(lambda_f, restart_map, stopstart=False, + restart_functions=None): """Helper function to perform the restart_on_change function. This is provided for decorators to restart services if files described @@ -453,8 +468,12 @@ def restart_on_change_helper(lambda_f, restart_map, stopstart=False): @param lambda_f: function to call. @param restart_map: {file: [service, ...]} @param stopstart: whether to stop, start or restart a service + @param restart_functions: nonstandard functions to use to restart services + {svc: func, ...} @returns result of lambda_f() """ + if restart_functions is None: + restart_functions = {} checksums = {path: path_hash(path) for path in restart_map} r = lambda_f() # create a list of lists of the services to restart @@ -465,9 +484,12 @@ def restart_on_change_helper(lambda_f, restart_map, stopstart=False): services_list = list(OrderedDict.fromkeys(itertools.chain(*restarts))) if services_list: actions = ('stop', 'start') if stopstart else ('restart',) - for action in actions: - for service_name in services_list: - service(action, service_name) + for service_name in services_list: + if service_name in restart_functions: + restart_functions[service_name](service_name) + else: + for action in actions: + service(action, service_name) return r diff --git a/tests/charmhelpers/contrib/amulet/utils.py b/tests/charmhelpers/contrib/amulet/utils.py index 3e15903..7e5c25a 100644 --- a/tests/charmhelpers/contrib/amulet/utils.py +++ b/tests/charmhelpers/contrib/amulet/utils.py @@ -601,7 +601,7 @@ class AmuletUtils(object): return ('Process name count mismatch. expected, actual: {}, ' '{}'.format(len(expected), len(actual))) - for (e_proc_name, e_pids_length), (a_proc_name, a_pids) in \ + for (e_proc_name, e_pids), (a_proc_name, a_pids) in \ zip(e_proc_names.items(), a_proc_names.items()): if e_proc_name != a_proc_name: return ('Process name mismatch. expected, actual: {}, ' @@ -610,25 +610,31 @@ class AmuletUtils(object): a_pids_length = len(a_pids) fail_msg = ('PID count mismatch. {} ({}) expected, actual: ' '{}, {} ({})'.format(e_sentry_name, e_proc_name, - e_pids_length, a_pids_length, + e_pids, a_pids_length, a_pids)) - # If expected is not bool, ensure PID quantities match - if not isinstance(e_pids_length, bool) and \ - a_pids_length != e_pids_length: + # If expected is a list, ensure at least one PID quantity match + if isinstance(e_pids, list) and \ + a_pids_length not in e_pids: + return fail_msg + # If expected is not bool and not list, + # ensure PID quantities match + elif not isinstance(e_pids, bool) and \ + not isinstance(e_pids, list) and \ + a_pids_length != e_pids: return fail_msg # If expected is bool True, ensure 1 or more PIDs exist - elif isinstance(e_pids_length, bool) and \ - e_pids_length is True and a_pids_length < 1: + elif isinstance(e_pids, bool) and \ + e_pids is True and a_pids_length < 1: return fail_msg # If expected is bool False, ensure 0 PIDs exist - elif isinstance(e_pids_length, bool) and \ - e_pids_length is False and a_pids_length != 0: + elif isinstance(e_pids, bool) and \ + e_pids is False and a_pids_length != 0: return fail_msg else: self.log.debug('PID check OK: {} {} {}: ' '{}'.format(e_sentry_name, e_proc_name, - e_pids_length, a_pids)) + e_pids, a_pids)) return None def validate_list_of_identical_dicts(self, list_of_dicts): diff --git a/tests/charmhelpers/contrib/openstack/amulet/deployment.py b/tests/charmhelpers/contrib/openstack/amulet/deployment.py index d2ede32..d21c9c7 100644 --- a/tests/charmhelpers/contrib/openstack/amulet/deployment.py +++ b/tests/charmhelpers/contrib/openstack/amulet/deployment.py @@ -126,7 +126,9 @@ class OpenStackAmuletDeployment(AmuletDeployment): # Charms which can not use openstack-origin, ie. many subordinates no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe', 'openvswitch-odl', 'neutron-api-odl', 'odl-controller', - 'cinder-backup'] + 'cinder-backup', 'nexentaedge-data', + 'nexentaedge-iscsi-gw', 'nexentaedge-swift-gw', + 'cinder-nexentaedge', 'nexentaedge-mgmt'] if self.openstack: for svc in services: