Merge "Only attempt to inject files if the injection disk exists"

changes/61/243061/15
Jenkins 7 years ago committed by Gerrit Code Review
commit 1528db4cbe
  1. 14
      nova/tests/unit/virt/libvirt/test_driver.py
  2. 108
      nova/virt/libvirt/driver.py

@ -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…
Cancel
Save