summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2012-10-05 13:38:54 -0700
committerJoshua Harlow <harlowja@yahoo-inc.com>2012-10-05 13:38:54 -0700
commitffa19cbd80ba10453f0ef448c1c10dbcbf5be504 (patch)
treec29ffbc5f58a22ba85a584e86b3cf58c1f30d316
parentcb30e7ed56e2c26e654d1703d3f44495a160c6eb (diff)
downloadvyos-cloud-init-ffa19cbd80ba10453f0ef448c1c10dbcbf5be504.tar.gz
vyos-cloud-init-ffa19cbd80ba10453f0ef448c1c10dbcbf5be504.zip
Ensure that config drive datasource attempts to
translate the device name to a actual device using logic that will try the ec2 metadata (if avail) or will try using 'blkid' to find a corresponding label. LP: #1062540
-rw-r--r--cloudinit/sources/DataSourceConfigDrive.py58
-rw-r--r--cloudinit/sources/DataSourceEc2.py16
-rw-r--r--cloudinit/sources/__init__.py17
3 files changed, 75 insertions, 16 deletions
diff --git a/cloudinit/sources/DataSourceConfigDrive.py b/cloudinit/sources/DataSourceConfigDrive.py
index b1cf942e..495eee82 100644
--- a/cloudinit/sources/DataSourceConfigDrive.py
+++ b/cloudinit/sources/DataSourceConfigDrive.py
@@ -48,6 +48,7 @@ class DataSourceConfigDrive(sources.DataSource):
self.dsmode = 'local'
self.seed_dir = os.path.join(paths.seed_dir, 'config_drive')
self.version = None
+ self.ec2_metadata = None
def __str__(self):
mstr = "%s [%s,ver=%s]" % (util.obj_name(self), self.dsmode,
@@ -55,6 +56,62 @@ class DataSourceConfigDrive(sources.DataSource):
mstr += "[source=%s]" % (self.source)
return mstr
+ def _ec2_name_to_device(self, name):
+ if not self.ec2_metadata:
+ return None
+ bdm = self.ec2_metadata.get('block-device-mapping', {})
+ for (ent_name, device) in bdm.items():
+ if name == ent_name:
+ return device
+ return None
+
+ def _os_name_to_device(self, name):
+ device = None
+ try:
+ dev_entries = util.find_devs_with('LABEL=%s' % (name))
+ if dev_entries:
+ device = dev_entries[0]
+ except util.ProcessExecutionError:
+ pass
+ return device
+
+ def device_name_to_device(self, name):
+ # Translate a 'name' to a 'physical' device
+ if not name:
+ return None
+ # Try the ec2 mapping first
+ names = [name]
+ if name == 'root':
+ names.insert(0, 'ami')
+ if name == 'ami':
+ names.append('root')
+ device = None
+ for n in names:
+ device = self._ec2_name_to_device(n)
+ if device:
+ break
+ # Try the openstack way second
+ if not device:
+ for n in names:
+ device = self._os_name_to_device(n)
+ if device:
+ break
+ # Ok give up...
+ if not device:
+ return None
+ # Ensure translated ok
+ if not device.startswith("/"):
+ device = "/dev/%s" % device
+ if os.path.exists(device):
+ return device
+ # Durn, try adjusting the mapping
+ remapped = self._remap_device(os.path.basename(device))
+ if remapped:
+ LOG.debug("Remapped device name %s => %s", device, remapped)
+ return remapped
+ # Really give up now
+ return None
+
def get_data(self):
found = None
md = {}
@@ -143,6 +200,7 @@ class DataSourceConfigDrive(sources.DataSource):
self.source = found
self.metadata = md
+ self.ec2_metadata = results.get('ec2-metadata')
self.userdata_raw = results.get('userdata')
self.version = results['cfgdrive_ver']
diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
index c7ad6d54..3686fa10 100644
--- a/cloudinit/sources/DataSourceEc2.py
+++ b/cloudinit/sources/DataSourceEc2.py
@@ -151,22 +151,6 @@ class DataSourceEc2(sources.DataSource):
self.metadata_address = url2base.get(url)
return bool(url)
- def _remap_device(self, short_name):
- # LP: #611137
- # the metadata service may believe that devices are named 'sda'
- # when the kernel named them 'vda' or 'xvda'
- # we want to return the correct value for what will actually
- # exist in this instance
- mappings = {"sd": ("vd", "xvd")}
- for (nfrom, tlist) in mappings.iteritems():
- if not short_name.startswith(nfrom):
- continue
- for nto in tlist:
- cand = "/dev/%s%s" % (nto, short_name[len(nfrom):])
- if os.path.exists(cand):
- return cand
- return None
-
def device_name_to_device(self, name):
# Consult metadata service, that has
# ephemeral0: sdb
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 04083d0c..b22369a8 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -23,6 +23,7 @@
from email.mime.multipart import MIMEMultipart
import abc
+import os
from cloudinit import importer
from cloudinit import log as logging
@@ -128,6 +129,22 @@ class DataSource(object):
return keys
+ def _remap_device(self, short_name):
+ # LP: #611137
+ # the metadata service may believe that devices are named 'sda'
+ # when the kernel named them 'vda' or 'xvda'
+ # we want to return the correct value for what will actually
+ # exist in this instance
+ mappings = {"sd": ("vd", "xvd")}
+ for (nfrom, tlist) in mappings.iteritems():
+ if not short_name.startswith(nfrom):
+ continue
+ for nto in tlist:
+ cand = "/dev/%s%s" % (nto, short_name[len(nfrom):])
+ if os.path.exists(cand):
+ return cand
+ return None
+
def device_name_to_device(self, _name):
# translate a 'name' to a device
# the primary function at this point is on ec2