diff options
author | Vlastimil Holer <vlastimil.holer@gmail.com> | 2013-09-10 15:37:15 +0200 |
---|---|---|
committer | Vlastimil Holer <vlastimil.holer@gmail.com> | 2013-09-10 15:37:15 +0200 |
commit | 64a2f3c7d4eae1354134c021db232c117eb1c772 (patch) | |
tree | 58953301347055f991ead4dee48e93a96f41b528 /cloudinit/sources/DataSourceOpenNebula.py | |
parent | 7f3b1198da74430345d69e485326b03a3fa5b455 (diff) | |
download | vyos-cloud-init-64a2f3c7d4eae1354134c021db232c117eb1c772.tar.gz vyos-cloud-init-64a2f3c7d4eae1354134c021db232c117eb1c772.zip |
Configurable OpenNebula::parseuser. Seed search dir+dev merge.
Eat shell parser error output. Few tests for tests for get_data.
Diffstat (limited to 'cloudinit/sources/DataSourceOpenNebula.py')
-rw-r--r-- | cloudinit/sources/DataSourceOpenNebula.py | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/cloudinit/sources/DataSourceOpenNebula.py b/cloudinit/sources/DataSourceOpenNebula.py index a1995aca..1b419cfd 100644 --- a/cloudinit/sources/DataSourceOpenNebula.py +++ b/cloudinit/sources/DataSourceOpenNebula.py @@ -35,6 +35,7 @@ LOG = logging.getLogger(__name__) DEFAULT_IID = "iid-dsopennebula" DEFAULT_MODE = 'net' +DEFAULT_PARSEUSER = 'nobody' CONTEXT_DISK_FILES = ["context.sh"] VALID_DSMODES = ("local", "net", "disabled") @@ -51,33 +52,35 @@ class DataSourceOpenNebula(sources.DataSource): return "%s [seed=%s][dsmode=%s]" % (root, self.seed, self.dsmode) def get_data(self): - defaults = { - "instance-id": DEFAULT_IID, #TODO:???? - "DSMODE": self.dsmode - } - + defaults = {"instance-id": DEFAULT_IID} + results = None seed = None - results = {} - # first try to read local seed_dir - if os.path.isdir(self.seed_dir): + # decide parseuser for context.sh shell reader + parseuser = DEFAULT_PARSEUSER + if self.ds_cfg.get('parseuser'): + parseuser = self.ds_cfg.get('parseuser') + + candidates = [self.seed_dir] + candidates.extend(find_candidate_devs()) + for cdev in candidates: try: - results = read_context_disk_dir(self.seed_dir) - seed = self.seed_dir + if os.path.isdir(self.seed_dir): + results = read_context_disk_dir(cdev, asuser=parseuser) + elif cdev.startswith("/dev"): + results = util.mount_cb(cdev, read_context_disk_dir, + data=parseuser) except NonContextDiskDir: - util.logexc(LOG, "Failed reading context from %s", - self.seed_dir) + continue + except BrokenContextDiskDir as exc: + raise exc + except util.MountFailedError: + LOG.warn("%s was not mountable" % cdev) - if not seed: - # then try to detect and mount candidate devices and - # read contextualization if present - for dev in find_candidate_devs(): - try: - results = util.mount_cb(dev, read_context_disk_dir) - seed = dev - break - except (NonContextDiskDir, util.MountFailedError): - pass + if results: + seed = cdev + LOG.debug("found datasource in %s", cdev) + break if not seed: return False @@ -95,7 +98,7 @@ class DataSourceOpenNebula(sources.DataSource): # decide dsmode if user_dsmode: dsmode = user_dsmode - elif self.ds_cfg.get('dsmode'): #TODO: fakt se k tomu nekdy dostane? + elif self.ds_cfg.get('dsmode'): dsmode = self.ds_cfg.get('dsmode') else: dsmode = DEFAULT_MODE @@ -137,6 +140,10 @@ class NonContextDiskDir(Exception): pass +class BrokenContextDiskDir(Exception): + pass + + class OpenNebulaNetwork(object): REG_DEV_MAC = re.compile( r'^\d+: (eth\d+):.*?link\/ether (..:..:..:..:..:..) ?', @@ -306,7 +313,8 @@ def parse_shell_config(content, keylist=None, bash=None, asuser=None): cmd.extend(bash) sp = subprocess.Popen(cmd, stdin=subprocess.PIPE, - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) (output, error) = sp.communicate(input=bcmd) if sp.returncode != 0: @@ -340,7 +348,7 @@ def parse_shell_config(content, keylist=None, bash=None, asuser=None): return ret -def read_context_disk_dir(source_dir): +def read_context_disk_dir(source_dir, asuser=None): """ read_context_disk_dir(source_dir): read source_dir and return a tuple with metadata dict and user-data @@ -355,23 +363,31 @@ def read_context_disk_dir(source_dir): if not found: raise NonContextDiskDir("%s: %s" % (source_dir, "no files found")) - results = {'userdata': None, 'metadata': {}} context = {} + results = {'userdata': None, 'metadata': {}} if "context.sh" in found: try: with open(os.path.join(source_dir, 'context.sh'), 'r') as f: - content = f.read().strip() - if content: - context = parse_shell_config(content) + content = f.read().strip() f.close() - except (IOError, Exception) as e: + + # don't pass empty context script + # to shell parser + non_empty = re.match(r'.*?^\s*([^# ]+)', content, + re.MULTILINE | re.DOTALL) + + if non_empty: + context = parse_shell_config(content, asuser=asuser) + except IOError as e: raise NonContextDiskDir("Error reading context.sh: %s" % (e)) + except Exception as e: + raise BrokenContextDiskDir("Error processing context.sh: %s" % (e)) else: raise NonContextDiskDir("Missing context.sh") if not context: - raise NonContextDiskDir("No context variables found") + return results results['metadata'] = context |