← Back to team overview

cloud-init-dev team mailing list archive

[Merge] lp:~harlowja/cloud-init/cfg-drive-dev-map-fix into lp:cloud-init

 

Joshua Harlow has proposed merging lp:~harlowja/cloud-init/cfg-drive-dev-map-fix into lp:cloud-init.

Requested reviews:
  cloud init development team (cloud-init-dev)
Related bugs:
  Bug #1062540 in cloud-init: "Using config drive default mounts not mapped."
  https://bugs.launchpad.net/cloud-init/+bug/1062540

For more details, see:
https://code.launchpad.net/~harlowja/cloud-init/cfg-drive-dev-map-fix/+merge/128315
-- 
https://code.launchpad.net/~harlowja/cloud-init/cfg-drive-dev-map-fix/+merge/128315
Your team cloud init development team is requested to review the proposed merge of lp:~harlowja/cloud-init/cfg-drive-dev-map-fix into lp:cloud-init.
=== modified file 'cloudinit/sources/DataSourceConfigDrive.py'
--- cloudinit/sources/DataSourceConfigDrive.py	2012-10-05 00:32:26 +0000
+++ cloudinit/sources/DataSourceConfigDrive.py	2012-10-05 20:41:32 +0000
@@ -48,6 +48,7 @@
         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 @@
         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 @@
 
         self.source = found
         self.metadata = md
+        self.ec2_metadata = results.get('ec2-metadata')
         self.userdata_raw = results.get('userdata')
         self.version = results['cfgdrive_ver']
 

=== modified file 'cloudinit/sources/DataSourceEc2.py'
--- cloudinit/sources/DataSourceEc2.py	2012-08-31 19:44:50 +0000
+++ cloudinit/sources/DataSourceEc2.py	2012-10-05 20:41:32 +0000
@@ -151,22 +151,6 @@
         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

=== modified file 'cloudinit/sources/__init__.py'
--- cloudinit/sources/__init__.py	2012-09-24 20:54:51 +0000
+++ cloudinit/sources/__init__.py	2012-10-05 20:41:32 +0000
@@ -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 @@
 
         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


Follow ups