Check for HIMN using dhcp discovery

A future plan for this plugin is to not require the HIMN XC
plugin but to support adding the network just in XenCenter
(with hidden objects displayed). Therefore the fuel plugin
should try to auto detect the HIMN as the MAC would not be
written to XenStore.

Cherry-pick of 01402e857c

Change-Id: I83aa26b16f9839979b63616bdf358219ff23739f
This commit is contained in:
Bob Ball 2016-09-12 09:40:48 +01:00
parent 60c6a9cafc
commit fa98aab579
1 changed files with 77 additions and 15 deletions

View File

@ -68,7 +68,11 @@ def execute(*cmd, **kwargs):
logging.error(err)
if proc.returncode is not None and proc.returncode != 0:
raise Exception(err)
if proc.returncode in kwargs.get('allowed_return_codes', [0]):
logging.info('Swallowed acceptable return code of %d',
proc.returncode)
else:
raise Exception(err)
return out
@ -161,13 +165,25 @@ def get_endpoints(astute):
return endpoints
def init_eth():
"""Initialize the net interface connected to HIMN
def eth_to_mac(eth):
return netifaces.ifaddresses(eth).get(netifaces.AF_LINK)[0]['addr']
Returns:
the IP addresses of local host and XenServer.
"""
def detect_himn_ip(eths=None):
if eths is None:
eths = netifaces.interfaces()
for eth in eths:
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
if ip is None:
continue
himn_local = ip[0]['addr']
himn_xs = '.'.join(himn_local.split('.')[:-1] + ['1'])
if HIMN_IP == himn_xs:
return eth, ip
return None, None
def find_eth_xenstore():
domid = execute('xenstore-read', 'domid')
himn_mac = execute(
'xenstore-read',
@ -176,16 +192,56 @@ def init_eth():
_mac = lambda eth: \
netifaces.ifaddresses(eth).get(netifaces.AF_LINK)[0]['addr']
eths = [eth for eth in netifaces.interfaces() if _mac(eth) == himn_mac]
eths = [eth for eth in netifaces.interfaces()
if eth_to_mac(eth) == himn_mac]
if len(eths) != 1:
reportError('Cannot find eth matches himn_mac')
eth = eths[0]
logging.info('himn_eth: %s' % eth)
return eths[0]
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
def detect_eth_dhclient():
for eth in netifaces.interfaces():
# Don't try and dhclient for devices an IP address already
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
if ip:
continue
# DHCP replies from HIMN should be super fast
execute('timeout', '2s', 'dhclient', eth,
allowed_return_codes=[0, 124])
try:
_, ip = detect_himn_ip([eth])
if ip is not None:
return eth
finally:
execute('dhclient', '-r', eth)
def init_eth():
"""Initialize the net interface connected to HIMN
Returns:
the IP addresses of local host and hypervisor.
"""
eth, ip = detect_himn_ip()
if not ip:
eth = None
try:
eth = find_eth_xenstore()
except Exception:
logging.debug('Failed to find MAC through xenstore', exc_info=True)
if eth is None:
eth = detect_eth_dhclient()
if eth is None:
reportError('Failed to detect HIMN ethernet device')
logging.info('himn_eth: %s' % eth)
execute('dhclient', eth)
fname = '/etc/network/interfaces.d/ifcfg-' + eth
s = ('auto {eth}\n'
@ -196,16 +252,22 @@ def init_eth():
logging.info('%s created' % fname)
execute('ifdown', eth)
execute('ifup', eth)
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
if ip:
himn_local = ip[0]['addr']
himn_xs = '.'.join(himn_local.split('.')[:-1] + ['1'])
if HIMN_IP == himn_xs:
logging.info('himn_local: %s' % himn_local)
return eth, himn_local
if HIMN_IP != himn_xs:
# Not on the HIMN - we failed here.
logging.info('himn_local: DHCP returned incorrect IP %s' %
ip[0]['addr'])
ip = None
reportError('HIMN failed to get IP address from XenServer')
if not ip:
reportError('HIMN failed to get IP address from Hypervisor')
logging.info('himn_local: %s' % ip[0]['addr'])
return eth, ip[0]['addr']
def check_host_compatibility(himn, username):