diff options
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/distros/__init__.py | 2 | ||||
-rw-r--r-- | cloudinit/net/__init__.py | 172 | ||||
-rw-r--r-- | cloudinit/sources/__init__.py | 4 | ||||
-rw-r--r-- | cloudinit/stages.py | 24 |
4 files changed, 121 insertions, 81 deletions
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index 74b484a7..418421b9 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -135,7 +135,7 @@ class Distro(object): return self._bring_up_interfaces(dev_names) return False - def apply_network_config(self, netconfig, bring_up=True): + def apply_network_config(self, netconfig, bring_up=False): # Write it out dev_names = self._write_network_config(netconfig) # Now try to bring them up diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index 36f07a02..b45153f4 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -283,86 +283,6 @@ def parse_net_config(path): return ns -def generate_fallback_config(): - """Determine which attached net dev is most likely to have a connection and - generate network state to run dhcp on that interface""" - # by default use eth0 as primary interface - nconf = {'config': {'interfaces': {}, - 'dns': {'search': [], 'nameservers': []}, 'routes': [] - }, - 'version': 1 - } - - # get list of interfaces that could have connections - invalid_interfaces = set(['lo']) - potential_interfaces = set(os.listdir(SYS_CLASS_NET)) - potential_interfaces = potential_interfaces.difference(invalid_interfaces) - # sort into interfaces with carrier, interfaces which could have carrier, - # and ignore interfaces that are definitely disconnected - connected = [] - possibly_connected = [] - for interface in potential_interfaces: - try: - sysfs_carrier = os.path.join(SYS_CLASS_NET, interface, 'carrier') - carrier = int(util.load_file(sysfs_carrier).strip()) - if carrier: - connected.append(interface) - continue - except OSError: - pass - # check if nic is dormant or down, as this may make a nick appear to - # not have a carrier even though it could acquire one when brought - # online by dhclient - try: - sysfs_dormant = os.path.join(SYS_CLASS_NET, interface, 'dormant') - dormant = int(util.load_file(sysfs_dormant).strip()) - if dormant: - possibly_connected.append(interface) - continue - except OSError: - pass - try: - sysfs_operstate = os.path.join(SYS_CLASS_NET, interface, - 'operstate') - operstate = util.load_file(sysfs_operstate).strip() - if operstate in ['dormant', 'down', 'lowerlayerdown', 'unknown']: - possibly_connected.append(interface) - continue - except OSError: - pass - - # don't bother with interfaces that might not be connected if there are - # some that definitely are - if connected: - potential_interfaces = connected - else: - potential_interfaces = possibly_connected - # if there are no interfaces, give up - if not potential_interfaces: - return - # if eth0 exists use it above anything else, otherwise get the interface - # that looks 'first' - if DEFAULT_PRIMARY_INTERFACE in potential_interfaces: - name = DEFAULT_PRIMARY_INTERFACE - else: - potential_interfaces.sort( - key=lambda x: int(''.join(i for i in x if i in string.digits))) - name = potential_interfaces[0] - - sysfs_mac = os.path.join(SYS_CLASS_NET, name, 'address') - mac = util.load_file(sysfs_mac).strip() - target_name = name - - # generate net config for interface - nconf['config']['interfaces'][target_name] = { - 'mac_address': mac, 'name': target_name, 'type': 'physical', - 'mode': 'manual', 'inet': 'inet', - 'subnets': [{'type': 'dhcp4'}, {'type': 'dhcp6'}] - } - - return nconf - - def render_persistent_net(network_state): ''' Given state, emit udev rules to map mac to ifname @@ -517,4 +437,96 @@ def render_network_state(target, network_state): with open(netrules, 'w+') as f: f.write(render_persistent_net(network_state)) + +def is_disabled_cfg(cfg): + if not cfg or not isinstance(cfg, dict): + return False + return cfg.get('config') == "disabled" + + +def generate_fallback_config(): + """Determine which attached net dev is most likely to have a connection and + generate network state to run dhcp on that interface""" + # by default use eth0 as primary interface + nconf = {'config': {'interfaces': {}, + 'dns': {'search': [], 'nameservers': []}, 'routes': [] + }, + 'version': 1 + } + + # get list of interfaces that could have connections + invalid_interfaces = set(['lo']) + potential_interfaces = set(os.listdir(SYS_CLASS_NET)) + potential_interfaces = potential_interfaces.difference(invalid_interfaces) + # sort into interfaces with carrier, interfaces which could have carrier, + # and ignore interfaces that are definitely disconnected + connected = [] + possibly_connected = [] + for interface in potential_interfaces: + try: + sysfs_carrier = os.path.join(SYS_CLASS_NET, interface, 'carrier') + carrier = int(util.load_file(sysfs_carrier).strip()) + if carrier: + connected.append(interface) + continue + except OSError: + pass + # check if nic is dormant or down, as this may make a nick appear to + # not have a carrier even though it could acquire one when brought + # online by dhclient + try: + sysfs_dormant = os.path.join(SYS_CLASS_NET, interface, 'dormant') + dormant = int(util.load_file(sysfs_dormant).strip()) + if dormant: + possibly_connected.append(interface) + continue + except OSError: + pass + try: + sysfs_operstate = os.path.join(SYS_CLASS_NET, interface, + 'operstate') + operstate = util.load_file(sysfs_operstate).strip() + if operstate in ['dormant', 'down', 'lowerlayerdown', 'unknown']: + possibly_connected.append(interface) + continue + except OSError: + pass + + # don't bother with interfaces that might not be connected if there are + # some that definitely are + if connected: + potential_interfaces = connected + else: + potential_interfaces = possibly_connected + # if there are no interfaces, give up + if not potential_interfaces: + return + # if eth0 exists use it above anything else, otherwise get the interface + # that looks 'first' + if DEFAULT_PRIMARY_INTERFACE in potential_interfaces: + name = DEFAULT_PRIMARY_INTERFACE + else: + potential_interfaces.sort( + key=lambda x: int(''.join(i for i in x if i in string.digits))) + name = potential_interfaces[0] + + sysfs_mac = os.path.join(SYS_CLASS_NET, name, 'address') + mac = util.load_file(sysfs_mac).strip() + target_name = name + + # generate net config for interface + nconf['config']['interfaces'][target_name] = { + 'mac_address': mac, 'name': target_name, 'type': 'physical', + 'mode': 'manual', 'inet': 'inet', + 'subnets': [{'type': 'dhcp4'}, {'type': 'dhcp6'}] + } + + return nconf + + +def read_kernel_cmdline_config(): + # FIXME: add implementation here + return None + + # vi: ts=4 expandtab syntax=python diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py index 28540a7b..c63464b2 100644 --- a/cloudinit/sources/__init__.py +++ b/cloudinit/sources/__init__.py @@ -221,6 +221,10 @@ class DataSource(object): # quickly (local check only) if self.instance_id is still return False + @property + def network_config(self): + return None + def normalize_pubkey_data(pubkey_data): keys = [] diff --git a/cloudinit/stages.py b/cloudinit/stages.py index c230ec0d..8e681e29 100644 --- a/cloudinit/stages.py +++ b/cloudinit/stages.py @@ -43,6 +43,7 @@ from cloudinit import distros from cloudinit import helpers from cloudinit import importer from cloudinit import log as logging +from cloudinit import net from cloudinit import sources from cloudinit import type_utils from cloudinit import util @@ -567,6 +568,29 @@ class Init(object): # Run the handlers self._do_handlers(user_data_msg, c_handlers_list, frequency) + def _find_networking_config(self): + cmdline_cfg = ('cmdline', net.read_kernel_cmdline_config()) + dscfg = ('ds', None) + if self.datasource and hasattr(self.datasource, 'network_config'): + dscfg = ('ds', self.datasource.network_config) + sys_cfg = ('system_cfg', self.cfg.get('network')) + + for loc, ncfg in (cmdline_cfg, dscfg, sys_cfg): + if net.is_disabled_cfg(ncfg): + LOG.debug("network config disabled by %s", loc) + return None + if ncfg: + return ncfg + return net.generate_fallback_config() + + def apply_network_config(self): + netcfg = self._find_networking_config() + if netcfg is None: + LOG.info("network config is disabled") + return + + return self.distro.apply_network_config(netcfg) + class Modules(object): def __init__(self, init, cfg_files=None, reporter=None): |