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.
This commit is contained in:
parent
0001a0e2fa
commit
13aa637222
@ -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']
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user