Only attempt to inject files if the injection disk exists
_inject_data was checking for the existence of the image to inject into. However, the only caller of _inject_data has just created that image. We move the _inject_data call up to where the image is created, and pass the existing image object in directly. We modify _inject_data to remove the existence check as, bar a delete race which was present anyway, we know it exists. Change-Id: Icb926e64151048c6ce8353de604417d5d79858e4
This commit is contained in:
parent
547dc45044
commit
eb4229506c
|
@ -14949,11 +14949,6 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||||
class ImageBackend(object):
|
class ImageBackend(object):
|
||||||
path = '/path'
|
path = '/path'
|
||||||
|
|
||||||
def check_image_exists(self):
|
|
||||||
if self.path == '/fail/path':
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_model(self, connection):
|
def get_model(self, connection):
|
||||||
return imgmodel.LocalFileImage(self.path,
|
return imgmodel.LocalFileImage(self.path,
|
||||||
imgmodel.FORMAT_RAW)
|
imgmodel.FORMAT_RAW)
|
||||||
|
@ -14971,7 +14966,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||||
return_value=image_backend):
|
return_value=image_backend):
|
||||||
self.flags(inject_partition=0, group='libvirt')
|
self.flags(inject_partition=0, group='libvirt')
|
||||||
|
|
||||||
self.drvr._inject_data(**driver_params)
|
self.drvr._inject_data(image_backend, **driver_params)
|
||||||
|
|
||||||
if called:
|
if called:
|
||||||
disk_inject_data.assert_called_once_with(
|
disk_inject_data.assert_called_once_with(
|
||||||
|
@ -14986,8 +14981,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||||
'instance': self._create_instance(params=params),
|
'instance': self._create_instance(params=params),
|
||||||
'network_info': None,
|
'network_info': None,
|
||||||
'admin_pass': None,
|
'admin_pass': None,
|
||||||
'files': None,
|
'files': None
|
||||||
'suffix': ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_inject_data_adminpass(self):
|
def test_inject_data_adminpass(self):
|
||||||
|
@ -15326,10 +15320,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||||
).AndReturn(mock_backend.kernel)
|
).AndReturn(mock_backend.kernel)
|
||||||
imagebackend.Backend.image(instance, 'ramdisk.rescue', 'raw'
|
imagebackend.Backend.image(instance, 'ramdisk.rescue', 'raw'
|
||||||
).AndReturn(mock_backend.ramdisk)
|
).AndReturn(mock_backend.ramdisk)
|
||||||
|
imagebackend.Backend.image(instance, 'disk.config.rescue', 'raw'
|
||||||
|
).AndReturn(mock_backend.config)
|
||||||
imagebackend.Backend.image(instance, 'disk.rescue', 'default'
|
imagebackend.Backend.image(instance, 'disk.rescue', 'default'
|
||||||
).AndReturn(mock_backend.root)
|
).AndReturn(mock_backend.root)
|
||||||
imagebackend.Backend.image(instance, 'disk.config.rescue', 'raw'
|
|
||||||
).AndReturn(mock_backend.config)
|
|
||||||
|
|
||||||
instance_metadata.InstanceMetadata.__init__(mox.IgnoreArg(),
|
instance_metadata.InstanceMetadata.__init__(mox.IgnoreArg(),
|
||||||
content=mox.IgnoreArg(),
|
content=mox.IgnoreArg(),
|
||||||
|
|
|
@ -2836,17 +2836,18 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
return True
|
return True
|
||||||
return False
|
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
|
"""Injects data in a disk image
|
||||||
|
|
||||||
Helper used for injecting data in a disk image file system.
|
Helper used for injecting data in a disk image file system.
|
||||||
|
|
||||||
Keyword arguments:
|
Keyword arguments:
|
||||||
|
injection_image -- An Image object we're injecting into
|
||||||
instance -- a dict that refers instance specifications
|
instance -- a dict that refers instance specifications
|
||||||
network_info -- a dict that refers network speficications
|
network_info -- a dict that refers network speficications
|
||||||
admin_pass -- a string used to set an admin password
|
admin_pass -- a string used to set an admin password
|
||||||
files -- a list of files needs to be injected
|
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.
|
# Handles the partition need to be used.
|
||||||
target_partition = None
|
target_partition = None
|
||||||
|
@ -2874,19 +2875,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
# Handles the metadata injection
|
# Handles the metadata injection
|
||||||
metadata = instance.get('metadata')
|
metadata = instance.get('metadata')
|
||||||
|
|
||||||
image_type = CONF.libvirt.images_type
|
|
||||||
if any((key, net, metadata, admin_pass, files)):
|
if any((key, net, metadata, admin_pass, files)):
|
||||||
injection_image = self.image_backend.image(
|
|
||||||
instance,
|
|
||||||
'disk' + suffix,
|
|
||||||
image_type)
|
|
||||||
img_id = instance.image_ref
|
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:
|
try:
|
||||||
disk.inject_data(injection_image.get_model(self._conn),
|
disk.inject_data(injection_image.get_model(self._conn),
|
||||||
key, net, metadata, admin_pass, files,
|
key, net, metadata, admin_pass, files,
|
||||||
|
@ -2954,6 +2944,46 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
|
|
||||||
inst_type = instance.get_flavor()
|
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
|
# NOTE(ndipanov): Even if disk_mapping was passed in, which
|
||||||
# currently happens only on rescue - we still don't want to
|
# currently happens only on rescue - we still don't want to
|
||||||
# create a base image.
|
# create a base image.
|
||||||
|
@ -2980,6 +3010,14 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
root_fname, disk_images['image_id'],
|
root_fname, disk_images['image_id'],
|
||||||
instance, size, fallback_from_host)
|
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
|
# Lookup the filesystem type if required
|
||||||
os_type_with_default = disk.get_fs_type_for_os_type(instance.os_type)
|
os_type_with_default = disk.get_fs_type_for_os_type(instance.os_type)
|
||||||
# Generate a file extension based on the file system
|
# Generate a file extension based on the file system
|
||||||
|
@ -3044,50 +3082,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
size=size,
|
size=size,
|
||||||
swap_mb=swap_mb)
|
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':
|
if CONF.libvirt.virt_type == 'uml':
|
||||||
libvirt_utils.chown(image('disk').path, 'root')
|
libvirt_utils.chown(image('disk').path, 'root')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue