This commit is contained in:
Liam Young 2016-04-12 13:46:04 +00:00
parent 16ef721120
commit c1d57d63b8
5 changed files with 64 additions and 22 deletions

View File

@ -191,6 +191,15 @@ get_iface_for_address = partial(_get_for_address, key='iface')
get_netmask_for_address = partial(_get_for_address, key='netmask') 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): def format_ipv6_addr(address):
"""If address is IPv6, wrap it in '[]' otherwise return None. """If address is IPv6, wrap it in '[]' otherwise return None.

View File

@ -137,7 +137,7 @@ SWIFT_CODENAMES = OrderedDict([
('liberty', ('liberty',
['2.3.0', '2.4.0', '2.5.0']), ['2.3.0', '2.4.0', '2.5.0']),
('mitaka', ('mitaka',
['2.5.0', '2.6.0']), ['2.5.0', '2.6.0', '2.7.0']),
]) ])
# >= Liberty version->codename mapping # >= Liberty version->codename mapping
@ -156,6 +156,7 @@ PACKAGE_CODENAMES = {
]), ]),
'keystone': OrderedDict([ 'keystone': OrderedDict([
('8.0', 'liberty'), ('8.0', 'liberty'),
('8.1', 'liberty'),
('9.0', 'mitaka'), ('9.0', 'mitaka'),
]), ]),
'horizon-common': OrderedDict([ 'horizon-common': OrderedDict([
@ -1534,7 +1535,8 @@ def make_assess_status_func(*args, **kwargs):
return _assess_status_func 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 """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. 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) return f(*args, **kwargs)
# otherwise, normal restart_on_change functionality # otherwise, normal restart_on_change functionality
return restart_on_change_helper( 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 wrapped_f
return wrap return wrap

View File

@ -128,6 +128,13 @@ def service(action, service_name):
return subprocess.call(cmd) == 0 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): def service_running(service_name):
"""Determine whether a system service is running""" """Determine whether a system service is running"""
if init_is_systemd(): if init_is_systemd():
@ -140,11 +147,15 @@ def service_running(service_name):
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return False return False
else: 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 if ("start/running" in output or "is running" in output or
"up and running" in output): "up and running" in output):
return True return True
else: # Check System V scripts init script return codes
return False if service_name in systemv_services_running():
return True
return False
def service_available(service_name): def service_available(service_name):
@ -412,7 +423,7 @@ class ChecksumError(ValueError):
pass 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 """Restart services based on configuration files changing
This function is used a decorator, for example:: 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 restart_map: {path_file_name: [service_name, ...]
@param stopstart: DEFAULT false; whether to stop, start OR restart @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 @returns result from decorated function
""" """
def wrap(f): def wrap(f):
@functools.wraps(f) @functools.wraps(f)
def wrapped_f(*args, **kwargs): def wrapped_f(*args, **kwargs):
return restart_on_change_helper( 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 wrapped_f
return wrap 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. """Helper function to perform the restart_on_change function.
This is provided for decorators to restart services if files described 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 lambda_f: function to call.
@param restart_map: {file: [service, ...]} @param restart_map: {file: [service, ...]}
@param stopstart: whether to stop, start or restart a 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() @returns result of lambda_f()
""" """
if restart_functions is None:
restart_functions = {}
checksums = {path: path_hash(path) for path in restart_map} checksums = {path: path_hash(path) for path in restart_map}
r = lambda_f() r = lambda_f()
# create a list of lists of the services to restart # 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))) services_list = list(OrderedDict.fromkeys(itertools.chain(*restarts)))
if services_list: if services_list:
actions = ('stop', 'start') if stopstart else ('restart',) actions = ('stop', 'start') if stopstart else ('restart',)
for action in actions: for service_name in services_list:
for service_name in services_list: if service_name in restart_functions:
service(action, service_name) restart_functions[service_name](service_name)
else:
for action in actions:
service(action, service_name)
return r return r

View File

@ -601,7 +601,7 @@ class AmuletUtils(object):
return ('Process name count mismatch. expected, actual: {}, ' return ('Process name count mismatch. expected, actual: {}, '
'{}'.format(len(expected), len(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()): zip(e_proc_names.items(), a_proc_names.items()):
if e_proc_name != a_proc_name: if e_proc_name != a_proc_name:
return ('Process name mismatch. expected, actual: {}, ' return ('Process name mismatch. expected, actual: {}, '
@ -610,25 +610,31 @@ class AmuletUtils(object):
a_pids_length = len(a_pids) a_pids_length = len(a_pids)
fail_msg = ('PID count mismatch. {} ({}) expected, actual: ' fail_msg = ('PID count mismatch. {} ({}) expected, actual: '
'{}, {} ({})'.format(e_sentry_name, e_proc_name, '{}, {} ({})'.format(e_sentry_name, e_proc_name,
e_pids_length, a_pids_length, e_pids, a_pids_length,
a_pids)) a_pids))
# If expected is not bool, ensure PID quantities match # If expected is a list, ensure at least one PID quantity match
if not isinstance(e_pids_length, bool) and \ if isinstance(e_pids, list) and \
a_pids_length != e_pids_length: 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 return fail_msg
# If expected is bool True, ensure 1 or more PIDs exist # If expected is bool True, ensure 1 or more PIDs exist
elif isinstance(e_pids_length, bool) and \ elif isinstance(e_pids, bool) and \
e_pids_length is True and a_pids_length < 1: e_pids is True and a_pids_length < 1:
return fail_msg return fail_msg
# If expected is bool False, ensure 0 PIDs exist # If expected is bool False, ensure 0 PIDs exist
elif isinstance(e_pids_length, bool) and \ elif isinstance(e_pids, bool) and \
e_pids_length is False and a_pids_length != 0: e_pids is False and a_pids_length != 0:
return fail_msg return fail_msg
else: else:
self.log.debug('PID check OK: {} {} {}: ' self.log.debug('PID check OK: {} {} {}: '
'{}'.format(e_sentry_name, e_proc_name, '{}'.format(e_sentry_name, e_proc_name,
e_pids_length, a_pids)) e_pids, a_pids))
return None return None
def validate_list_of_identical_dicts(self, list_of_dicts): def validate_list_of_identical_dicts(self, list_of_dicts):

View File

@ -126,7 +126,9 @@ class OpenStackAmuletDeployment(AmuletDeployment):
# Charms which can not use openstack-origin, ie. many subordinates # Charms which can not use openstack-origin, ie. many subordinates
no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe', no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
'openvswitch-odl', 'neutron-api-odl', 'odl-controller', '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: if self.openstack:
for svc in services: for svc in services: