Resync charm-helpers

Avoid use of 'service --status-all' which is currently
broken on trusty for upstart managed daemons; the change
moves to detecting how the daemon is managed, and then
using upstart status XXX or the return code of service XXX
status to determine whether a process is running.

Fixes for IPv6 network address detection under Ubuntu
16.04 which changes the output format of the ip commands
slightly.

Update the version map to include 8.1.x as a Neutron
version for Mitaka.

Change-Id: Ic565bf17f13315c9511636c7ee9ede560c37e91f
Closes-Bug: 1581171
Closes-Bug: 1581598
Closes-Bug: 1580674
This commit is contained in:
James Page 2016-05-18 14:03:33 +01:00
parent 13cf8d9350
commit d9a6cb7606
2 changed files with 35 additions and 25 deletions

View File

@ -214,7 +214,16 @@ def format_ipv6_addr(address):
def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False, def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False,
fatal=True, exc_list=None): fatal=True, exc_list=None):
"""Return the assigned IP address for a given interface, if any.""" """Return the assigned IP address for a given interface, if any.
:param iface: network interface on which address(es) are expected to
be found.
:param inet_type: inet address family
:param inc_aliases: include alias interfaces in search
:param fatal: if True, raise exception if address not found
:param exc_list: list of addresses to ignore
:return: list of ip addresses
"""
# Extract nic if passed /dev/ethX # Extract nic if passed /dev/ethX
if '/' in iface: if '/' in iface:
iface = iface.split('/')[-1] iface = iface.split('/')[-1]
@ -315,6 +324,14 @@ def get_ipv6_addr(iface=None, inc_aliases=False, fatal=True, exc_list=None,
We currently only support scope global IPv6 addresses i.e. non-temporary We currently only support scope global IPv6 addresses i.e. non-temporary
addresses. If no global IPv6 address is found, return the first one found addresses. If no global IPv6 address is found, return the first one found
in the ipv6 address list. in the ipv6 address list.
:param iface: network interface on which ipv6 address(es) are expected to
be found.
:param inc_aliases: include alias interfaces in search
:param fatal: if True, raise exception if address not found
:param exc_list: list of addresses to ignore
:param dynamic_only: only recognise dynamic addresses
:return: list of ipv6 addresses
""" """
addresses = get_iface_addr(iface=iface, inet_type='AF_INET6', addresses = get_iface_addr(iface=iface, inet_type='AF_INET6',
inc_aliases=inc_aliases, fatal=fatal, inc_aliases=inc_aliases, fatal=fatal,
@ -336,7 +353,7 @@ def get_ipv6_addr(iface=None, inc_aliases=False, fatal=True, exc_list=None,
cmd = ['ip', 'addr', 'show', iface] cmd = ['ip', 'addr', 'show', iface]
out = subprocess.check_output(cmd).decode('UTF-8') out = subprocess.check_output(cmd).decode('UTF-8')
if dynamic_only: if dynamic_only:
key = re.compile("inet6 (.+)/[0-9]+ scope global dynamic.*") key = re.compile("inet6 (.+)/[0-9]+ scope global.* dynamic.*")
else: else:
key = re.compile("inet6 (.+)/[0-9]+ scope global.*") key = re.compile("inet6 (.+)/[0-9]+ scope global.*")

View File

@ -128,11 +128,8 @@ def service(action, service_name):
return subprocess.call(cmd) == 0 return subprocess.call(cmd) == 0
def systemv_services_running(): _UPSTART_CONF = "/etc/init/{}.conf"
output = subprocess.check_output( _INIT_D_CONF = "/etc/init.d/{}"
['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):
@ -140,26 +137,22 @@ def service_running(service_name):
if init_is_systemd(): if init_is_systemd():
return service('is-active', service_name) return service('is-active', service_name)
else: else:
try: if os.path.exists(_UPSTART_CONF.format(service_name)):
output = subprocess.check_output( try:
['service', service_name, 'status'], output = subprocess.check_output(
stderr=subprocess.STDOUT).decode('UTF-8') ['status', service_name],
except subprocess.CalledProcessError: stderr=subprocess.STDOUT).decode('UTF-8')
return False except subprocess.CalledProcessError:
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
# Actively check for upstart stopped message(s) as the fall through
# SystemV check can return false positives
if ("stop/waiting" in output):
return False 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:
return True
elif os.path.exists(_INIT_D_CONF.format(service_name)):
# Check System V scripts init script return codes # Check System V scripts init script return codes
if service_name in systemv_services_running(): return service('status', service_name)
return True return False
return False
def service_available(service_name): def service_available(service_name):