Merge "Only attempt to inject files if the injection disk exists"
This commit is contained in:
commit
1528db4cbe
|
@ -14949,11 +14949,6 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
|||
class ImageBackend(object):
|
||||
path = '/path'
|
||||
|
||||
def check_image_exists(self):
|
||||
if self.path == '/fail/path':
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_model(self, connection):
|
||||
return imgmodel.LocalFileImage(self.path,
|
||||
imgmodel.FORMAT_RAW)
|
||||
|
@ -14971,7 +14966,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
|||
return_value=image_backend):
|
||||
self.flags(inject_partition=0, group='libvirt')
|
||||
|
||||
self.drvr._inject_data(**driver_params)
|
||||
self.drvr._inject_data(image_backend, **driver_params)
|
||||
|
||||
if called:
|
||||
disk_inject_data.assert_called_once_with(
|
||||
|
@ -14986,8 +14981,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
|||
'instance': self._create_instance(params=params),
|
||||
'network_info': None,
|
||||
'admin_pass': None,
|
||||
'files': None,
|
||||
'suffix': ''
|
||||
'files': None
|
||||
}
|
||||
|
||||
def test_inject_data_adminpass(self):
|
||||
|
@ -15326,10 +15320,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
|||
).AndReturn(mock_backend.kernel)
|
||||
imagebackend.Backend.image(instance, 'ramdisk.rescue', 'raw'
|
||||
).AndReturn(mock_backend.ramdisk)
|
||||
imagebackend.Backend.image(instance, 'disk.config.rescue', 'raw'
|
||||
).AndReturn(mock_backend.config)
|
||||
imagebackend.Backend.image(instance, 'disk.rescue', 'default'
|
||||
).AndReturn(mock_backend.root)
|
||||
imagebackend.Backend.image(instance, 'disk.config.rescue', 'raw'
|
||||
).AndReturn(mock_backend.config)
|
||||
|
||||
instance_metadata.InstanceMetadata.__init__(mox.IgnoreArg(),
|
||||
content=mox.IgnoreArg(),
|
||||
|
|
|
@ -2836,17 +2836,18 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
return True
|
||||
return False
|
||||
|
||||
def _inject_data(self, instance, network_info, admin_pass, files, suffix):
|
||||
def _inject_data(self, injection_image, instance, network_info,
|
||||
admin_pass, files):
|
||||
"""Injects data in a disk image
|
||||
|
||||
Helper used for injecting data in a disk image file system.
|
||||
|
||||
Keyword arguments:
|
||||
injection_image -- An Image object we're injecting into
|
||||
instance -- a dict that refers instance specifications
|
||||
network_info -- a dict that refers network speficications
|
||||
admin_pass -- a string used to set an admin password
|
||||
files -- a list of files needs to be injected
|
||||
suffix -- a string used as an image name suffix
|
||||
"""
|
||||
# Handles the partition need to be used.
|
||||
target_partition = None
|
||||
|
@ -2874,19 +2875,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
# Handles the metadata injection
|
||||
metadata = instance.get('metadata')
|
||||
|
||||
image_type = CONF.libvirt.images_type
|
||||
if any((key, net, metadata, admin_pass, files)):
|
||||
injection_image = self.image_backend.image(
|
||||
instance,
|
||||
'disk' + suffix,
|
||||
image_type)
|
||||
img_id = instance.image_ref
|
||||
|
||||
if not injection_image.check_image_exists():
|
||||
LOG.warning(_LW('Image %s not found on disk storage. '
|
||||
'Continue without injecting data'),
|
||||
injection_image.path, instance=instance)
|
||||
return
|
||||
try:
|
||||
disk.inject_data(injection_image.get_model(self._conn),
|
||||
key, net, metadata, admin_pass, files,
|
||||
|
@ -2954,6 +2944,46 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
|
||||
inst_type = instance.get_flavor()
|
||||
|
||||
# Config drive
|
||||
config_drive_image = None
|
||||
if configdrive.required_by(instance):
|
||||
LOG.info(_LI('Using config drive'), instance=instance)
|
||||
extra_md = {}
|
||||
if admin_pass:
|
||||
extra_md['admin_pass'] = admin_pass
|
||||
|
||||
inst_md = instance_metadata.InstanceMetadata(instance,
|
||||
content=files, extra_md=extra_md, network_info=network_info)
|
||||
with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb:
|
||||
configdrive_path = self._get_disk_config_path(instance, suffix)
|
||||
LOG.info(_LI('Creating config drive at %(path)s'),
|
||||
{'path': configdrive_path}, instance=instance)
|
||||
|
||||
try:
|
||||
cdb.make_drive(configdrive_path)
|
||||
except processutils.ProcessExecutionError as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE('Creating config drive failed '
|
||||
'with error: %s'),
|
||||
e, instance=instance)
|
||||
|
||||
try:
|
||||
# Tell the storage backend about the config drive
|
||||
config_drive_image = self.image_backend.image(
|
||||
instance, 'disk.config' + suffix,
|
||||
self._get_disk_config_image_type())
|
||||
|
||||
config_drive_image.import_file(
|
||||
instance, configdrive_path, 'disk.config' + suffix)
|
||||
finally:
|
||||
# NOTE(mikal): if the config drive was imported into RBD, then
|
||||
# we no longer need the local copy
|
||||
if CONF.libvirt.images_type == 'rbd':
|
||||
os.unlink(configdrive_path)
|
||||
|
||||
need_inject = (config_drive_image is None and inject_files and
|
||||
CONF.libvirt.inject_partition != -2)
|
||||
|
||||
# NOTE(ndipanov): Even if disk_mapping was passed in, which
|
||||
# currently happens only on rescue - we still don't want to
|
||||
# create a base image.
|
||||
|
@ -2980,6 +3010,14 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
root_fname, disk_images['image_id'],
|
||||
instance, size, fallback_from_host)
|
||||
|
||||
if need_inject:
|
||||
self._inject_data(backend, instance, network_info, admin_pass,
|
||||
files)
|
||||
|
||||
elif need_inject:
|
||||
LOG.warn(_LW('File injection into a boot from volume '
|
||||
'instance is not supported'), instance=instance)
|
||||
|
||||
# Lookup the filesystem type if required
|
||||
os_type_with_default = disk.get_fs_type_for_os_type(instance.os_type)
|
||||
# Generate a file extension based on the file system
|
||||
|
@ -3044,50 +3082,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
size=size,
|
||||
swap_mb=swap_mb)
|
||||
|
||||
# Config drive
|
||||
if configdrive.required_by(instance):
|
||||
LOG.info(_LI('Using config drive'), instance=instance)
|
||||
extra_md = {}
|
||||
if admin_pass:
|
||||
extra_md['admin_pass'] = admin_pass
|
||||
|
||||
inst_md = instance_metadata.InstanceMetadata(instance,
|
||||
content=files, extra_md=extra_md, network_info=network_info)
|
||||
with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb:
|
||||
configdrive_path = self._get_disk_config_path(instance, suffix)
|
||||
LOG.info(_LI('Creating config drive at %(path)s'),
|
||||
{'path': configdrive_path}, instance=instance)
|
||||
|
||||
try:
|
||||
cdb.make_drive(configdrive_path)
|
||||
except processutils.ProcessExecutionError as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE('Creating config drive failed '
|
||||
'with error: %s'),
|
||||
e, instance=instance)
|
||||
|
||||
try:
|
||||
# Tell the storage backend about the config drive
|
||||
config_drive_image = self.image_backend.image(
|
||||
instance, 'disk.config' + suffix,
|
||||
self._get_disk_config_image_type())
|
||||
|
||||
config_drive_image.import_file(
|
||||
instance, configdrive_path, 'disk.config' + suffix)
|
||||
finally:
|
||||
# NOTE(mikal): if the config drive was imported into RBD, then
|
||||
# we no longer need the local copy
|
||||
if CONF.libvirt.images_type == 'rbd':
|
||||
os.unlink(configdrive_path)
|
||||
|
||||
# File injection only if needed
|
||||
elif inject_files and CONF.libvirt.inject_partition != -2:
|
||||
if booted_from_volume:
|
||||
LOG.warning(_LW('File injection into a boot from volume '
|
||||
'instance is not supported'), instance=instance)
|
||||
self._inject_data(
|
||||
instance, network_info, admin_pass, files, suffix)
|
||||
|
||||
if CONF.libvirt.virt_type == 'uml':
|
||||
libvirt_utils.chown(image('disk').path, 'root')
|
||||
|
||||
|
|
Loading…
Reference in New Issue