diff options
Diffstat (limited to 'cloudinit/sources/DataSourceNoCloud.py')
-rw-r--r-- | cloudinit/sources/DataSourceNoCloud.py | 154 |
1 files changed, 87 insertions, 67 deletions
diff --git a/cloudinit/sources/DataSourceNoCloud.py b/cloudinit/sources/DataSourceNoCloud.py index 2d9e86b4..56559630 100644 --- a/cloudinit/sources/DataSourceNoCloud.py +++ b/cloudinit/sources/DataSourceNoCloud.py @@ -13,9 +13,8 @@ import os from cloudinit import dmi from cloudinit import log as logging +from cloudinit import sources, util from cloudinit.net import eni -from cloudinit import sources -from cloudinit import util LOG = logging.getLogger(__name__) @@ -27,8 +26,10 @@ class DataSourceNoCloud(sources.DataSource): def __init__(self, sys_cfg, distro, paths): sources.DataSource.__init__(self, sys_cfg, distro, paths) self.seed = None - self.seed_dirs = [os.path.join(paths.seed_dir, 'nocloud'), - os.path.join(paths.seed_dir, 'nocloud-net')] + self.seed_dirs = [ + os.path.join(paths.seed_dir, "nocloud"), + os.path.join(paths.seed_dir, "nocloud-net"), + ] self.seed_dir = None self.supported_seed_starts = ("/", "file://") @@ -55,17 +56,21 @@ class DataSourceNoCloud(sources.DataSource): } found = [] - mydata = {'meta-data': {}, 'user-data': "", 'vendor-data': "", - 'network-config': None} + mydata = { + "meta-data": {}, + "user-data": "", + "vendor-data": "", + "network-config": None, + } try: # Parse the system serial label from dmi. If not empty, try parsing # like the commandline md = {} - serial = dmi.read_dmi_data('system-serial-number') + serial = dmi.read_dmi_data("system-serial-number") if serial and load_cmdline_data(md, serial): found.append("dmi") - mydata = _merge_new_seed(mydata, {'meta-data': md}) + mydata = _merge_new_seed(mydata, {"meta-data": md}) except Exception: util.logexc(LOG, "Unable to parse dmi data") return False @@ -75,14 +80,16 @@ class DataSourceNoCloud(sources.DataSource): md = {} if load_cmdline_data(md): found.append("cmdline") - mydata = _merge_new_seed(mydata, {'meta-data': md}) + mydata = _merge_new_seed(mydata, {"meta-data": md}) except Exception: util.logexc(LOG, "Unable to parse command line data") return False # Check to see if the seed dir has data. - pp2d_kwargs = {'required': ['user-data', 'meta-data'], - 'optional': ['vendor-data', 'network-config']} + pp2d_kwargs = { + "required": ["user-data", "meta-data"], + "optional": ["vendor-data", "network-config"], + } for path in self.seed_dirs: try: @@ -97,31 +104,35 @@ class DataSourceNoCloud(sources.DataSource): # If the datasource config had a 'seedfrom' entry, then that takes # precedence over a 'seedfrom' that was found in a filesystem # but not over external media - if self.ds_cfg.get('seedfrom'): + if self.ds_cfg.get("seedfrom"): found.append("ds_config_seedfrom") - mydata['meta-data']["seedfrom"] = self.ds_cfg['seedfrom'] + mydata["meta-data"]["seedfrom"] = self.ds_cfg["seedfrom"] # fields appropriately named can also just come from the datasource # config (ie, 'user-data', 'meta-data', 'vendor-data' there) - if 'user-data' in self.ds_cfg and 'meta-data' in self.ds_cfg: + if "user-data" in self.ds_cfg and "meta-data" in self.ds_cfg: mydata = _merge_new_seed(mydata, self.ds_cfg) found.append("ds_config") def _pp2d_callback(mp, data): return util.pathprefix2dict(mp, **data) - label = self.ds_cfg.get('fs_label', "cidata") + label = self.ds_cfg.get("fs_label", "cidata") if label is not None: for dev in self._get_devices(label): try: LOG.debug("Attempting to use data from %s", dev) try: - seeded = util.mount_cb(dev, _pp2d_callback, - pp2d_kwargs) + seeded = util.mount_cb( + dev, _pp2d_callback, pp2d_kwargs + ) except ValueError: - LOG.warning("device %s with label=%s not a " - "valid seed.", dev, label) + LOG.warning( + "device %s with label=%s not a valid seed.", + dev, + label, + ) continue mydata = _merge_new_seed(mydata, seeded) @@ -133,8 +144,9 @@ class DataSourceNoCloud(sources.DataSource): if e.errno != errno.ENOENT: raise except util.MountFailedError: - util.logexc(LOG, "Failed to mount %s when looking for " - "data", dev) + util.logexc( + LOG, "Failed to mount %s when looking for data", dev + ) # There was no indication on kernel cmdline or data # in the seeddir suggesting this handler should be used. @@ -145,8 +157,8 @@ class DataSourceNoCloud(sources.DataSource): # attempt to seed the userdata / metadata from its value # its primarily value is in allowing the user to type less # on the command line, ie: ds=nocloud;s=http://bit.ly/abcdefg - if "seedfrom" in mydata['meta-data']: - seedfrom = mydata['meta-data']["seedfrom"] + if "seedfrom" in mydata["meta-data"]: + seedfrom = mydata["meta-data"]["seedfrom"] seedfound = False for proto in self.supported_seed_starts: if seedfrom.startswith(proto): @@ -162,39 +174,43 @@ class DataSourceNoCloud(sources.DataSource): LOG.debug("Using seeded cache data from %s", seedfrom) # Values in the command line override those from the seed - mydata['meta-data'] = util.mergemanydict([mydata['meta-data'], - md_seed]) - mydata['user-data'] = ud - mydata['vendor-data'] = vd + mydata["meta-data"] = util.mergemanydict( + [mydata["meta-data"], md_seed] + ) + mydata["user-data"] = ud + mydata["vendor-data"] = vd found.append(seedfrom) # Now that we have exhausted any other places merge in the defaults - mydata['meta-data'] = util.mergemanydict([mydata['meta-data'], - defaults]) + mydata["meta-data"] = util.mergemanydict( + [mydata["meta-data"], defaults] + ) self.dsmode = self._determine_dsmode( - [mydata['meta-data'].get('dsmode')]) + [mydata["meta-data"].get("dsmode")] + ) if self.dsmode == sources.DSMODE_DISABLED: - LOG.debug("%s: not claiming datasource, dsmode=%s", self, - self.dsmode) + LOG.debug( + "%s: not claiming datasource, dsmode=%s", self, self.dsmode + ) return False self.seed = ",".join(found) - self.metadata = mydata['meta-data'] - self.userdata_raw = mydata['user-data'] - self.vendordata_raw = mydata['vendor-data'] - self._network_config = mydata['network-config'] - self._network_eni = mydata['meta-data'].get('network-interfaces') + self.metadata = mydata["meta-data"] + self.userdata_raw = mydata["user-data"] + self.vendordata_raw = mydata["vendor-data"] + self._network_config = mydata["network-config"] + self._network_eni = mydata["meta-data"].get("network-interfaces") return True @property def platform_type(self): # Handle upgrade path of pickled ds - if not hasattr(self, '_platform_type'): + if not hasattr(self, "_platform_type"): self._platform_type = None if not self._platform_type: - self._platform_type = 'lxd' if util.is_lxd() else 'nocloud' + self._platform_type = "lxd" if util.is_lxd() else "nocloud" return self._platform_type def _get_cloud_name(self): @@ -203,11 +219,11 @@ class DataSourceNoCloud(sources.DataSource): def _get_subplatform(self): """Return the subplatform metadata source details.""" - if self.seed.startswith('/dev'): - subplatform_type = 'config-disk' + if self.seed.startswith("/dev"): + subplatform_type = "config-disk" else: - subplatform_type = 'seed-dir' - return '%s (%s)' % (subplatform_type, self.seed) + subplatform_type = "seed-dir" + return "%s (%s)" % (subplatform_type, self.seed) def check_instance_id(self, sys_cfg): # quickly (local check only) if self.instance_id is still valid @@ -218,7 +234,7 @@ class DataSourceNoCloud(sources.DataSource): # LP: #1568150 need getattr in the case that an old class object # has been loaded from a pickled file and now executing new source. - dirs = getattr(self, 'seed_dirs', [self.seed_dir]) + dirs = getattr(self, "seed_dirs", [self.seed_dir]) quick_id = _quick_read_instance_id(dirs=dirs) if not quick_id: return None @@ -236,7 +252,7 @@ def _quick_read_instance_id(dirs=None): if dirs is None: dirs = [] - iid_key = 'instance-id' + iid_key = "instance-id" fill = {} if load_cmdline_data(fill) and iid_key in fill: return fill[iid_key] @@ -245,8 +261,8 @@ def _quick_read_instance_id(dirs=None): if d is None: continue try: - data = util.pathprefix2dict(d, required=['meta-data']) - md = util.load_yaml(data['meta-data']) + data = util.pathprefix2dict(d, required=["meta-data"]) + md = util.load_yaml(data["meta-data"]) if md and iid_key in md: return md[iid_key] except ValueError: @@ -256,14 +272,16 @@ def _quick_read_instance_id(dirs=None): def load_cmdline_data(fill, cmdline=None): - pairs = [("ds=nocloud", sources.DSMODE_LOCAL), - ("ds=nocloud-net", sources.DSMODE_NETWORK)] + pairs = [ + ("ds=nocloud", sources.DSMODE_LOCAL), + ("ds=nocloud-net", sources.DSMODE_NETWORK), + ] for idstr, dsmode in pairs: if parse_cmdline_data(idstr, fill, cmdline): # if dsmode was explicitly in the command line, then # prefer it to the dsmode based on the command line id - if 'dsmode' not in fill: - fill['dsmode'] = dsmode + if "dsmode" not in fill: + fill["dsmode"] = dsmode return True return False @@ -323,19 +341,19 @@ def _maybe_remove_top_network(cfg): Return the original value if no change or the updated value if changed.""" nullval = object() - network_val = cfg.get('network', nullval) + network_val = cfg.get("network", nullval) if network_val is nullval: return cfg - bmsg = 'Top level network key in network-config %s: %s' + bmsg = "Top level network key in network-config %s: %s" if not isinstance(network_val, dict): LOG.debug(bmsg, "was not a dict", cfg) return cfg if len(list(cfg.keys())) != 1: LOG.debug(bmsg, "had multiple top level keys", cfg) return cfg - if network_val.get('config') == "disabled": + if network_val.get("config") == "disabled": LOG.debug(bmsg, "was config/disabled", cfg) - elif not all(('config' in network_val, 'version' in network_val)): + elif not all(("config" in network_val, "version" in network_val)): LOG.debug(bmsg, "but missing 'config' or 'version'", cfg) return cfg LOG.debug(bmsg, "fixed by removing shifting network.", cfg) @@ -345,19 +363,20 @@ def _maybe_remove_top_network(cfg): def _merge_new_seed(cur, seeded): ret = cur.copy() - newmd = seeded.get('meta-data', {}) - if not isinstance(seeded['meta-data'], dict): - newmd = util.load_yaml(seeded['meta-data']) - ret['meta-data'] = util.mergemanydict([cur['meta-data'], newmd]) + newmd = seeded.get("meta-data", {}) + if not isinstance(seeded["meta-data"], dict): + newmd = util.load_yaml(seeded["meta-data"]) + ret["meta-data"] = util.mergemanydict([cur["meta-data"], newmd]) - if seeded.get('network-config'): - ret['network-config'] = _maybe_remove_top_network( - util.load_yaml(seeded.get('network-config'))) + if seeded.get("network-config"): + ret["network-config"] = _maybe_remove_top_network( + util.load_yaml(seeded.get("network-config")) + ) - if 'user-data' in seeded: - ret['user-data'] = seeded['user-data'] - if 'vendor-data' in seeded: - ret['vendor-data'] = seeded['vendor-data'] + if "user-data" in seeded: + ret["user-data"] = seeded["user-data"] + if "vendor-data" in seeded: + ret["vendor-data"] = seeded["vendor-data"] return ret @@ -369,7 +388,7 @@ class DataSourceNoCloudNet(DataSourceNoCloud): # Used to match classes to dependencies datasources = [ - (DataSourceNoCloud, (sources.DEP_FILESYSTEM, )), + (DataSourceNoCloud, (sources.DEP_FILESYSTEM,)), (DataSourceNoCloudNet, (sources.DEP_FILESYSTEM, sources.DEP_NETWORK)), ] @@ -378,4 +397,5 @@ datasources = [ def get_datasource_list(depends): return sources.list_from_depends(depends, datasources) + # vi: ts=4 expandtab |