Skip existing VMs when hosts apply force_config_drive

When hosts apply config `CONF.force_config_drive=True`, the existing
VMs shouldn't be enforced to must have config drive device. For they
may have been cloud-inited via metadata service, and may not need and
have any config drive device ever. In contrast, the newly being-built
ones should. Instance attr `launched_at` serves as an apparent flag
to distinguish the two kinds of VMs.

When hard reboots happend, existing VMs skip config drive enforcement,
and therefore avoid hitting 'No such file or directory (config drive
device)' error.

Change-Id: I0558ece92f8657c2f6294e07965c619eb7c8dfcf
Closes-Bug: #1827492
This commit is contained in:
pandatt 2019-05-16 02:50:57 +08:00 committed by Matt Riedemann
parent 2e85453879
commit 2af89cfea0
4 changed files with 24 additions and 3 deletions

View File

@ -56,7 +56,8 @@ Force injection to take place on a config drive
When this option is set to true configuration drive functionality will be
forced enabled by default, otherwise user can still enable configuration
drives via the REST API or image metadata properties.
drives via the REST API or image metadata properties. Launched VMs are not
affected by this option.
Possible values:

View File

@ -55,6 +55,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
'ephemeral_gb': 20,
'instance_type_id': 2, # m1.tiny
'config_drive': None,
'launched_at': None,
'system_metadata': {},
}
self.test_image_meta = {

View File

@ -42,11 +42,12 @@ class ConfigDriveTestCase(test.NoDBTestCase):
self.assertTrue(configdrive.required_by(instance))
def test_config_flag_force(self):
def test_config_flag_force_for_new_vms(self):
self.flags(force_config_drive=True)
instance = objects.Instance(
config_drive=None,
launched_at=None,
system_metadata={
"image_img_config_drive": "optional",
}
@ -54,6 +55,19 @@ class ConfigDriveTestCase(test.NoDBTestCase):
self.assertTrue(configdrive.required_by(instance))
def test_config_flag_force_for_existing_vms(self):
self.flags(force_config_drive=True)
instance = objects.Instance(
config_drive=None,
launched_at='2019-05-17T00:00:00.000000',
system_metadata={
"image_img_config_drive": "optional",
}
)
self.assertFalse(configdrive.required_by(instance))
def test_no_config_drive(self):
self.flags(force_config_drive=False)

View File

@ -160,8 +160,13 @@ def required_by(instance):
"img_config_drive",
fields.ConfigDrivePolicy.OPTIONAL)
# NOTE(pandatt): Option CONF.force_config_drive only applies to newly
# being-built VMs. And already launched VMs shouldn't be forced a config
# drive, because they may have been cloud-inited via metadata service, and
# do not need and have any config drive device. The `launched_at` property
# is an apparent flag to tell VMs being built from launched ones.
return (instance.config_drive or
CONF.force_config_drive or
(CONF.force_config_drive and not instance.launched_at) or
image_prop == fields.ConfigDrivePolicy.MANDATORY
)