From 2af89cfea0531ab75b4f5765bb220073f42662d0 Mon Sep 17 00:00:00 2001 From: pandatt Date: Thu, 16 May 2019 02:50:57 +0800 Subject: [PATCH] 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 --- nova/conf/configdrive.py | 3 ++- nova/tests/unit/virt/libvirt/test_blockinfo.py | 1 + nova/tests/unit/virt/test_configdrive.py | 16 +++++++++++++++- nova/virt/configdrive.py | 7 ++++++- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/nova/conf/configdrive.py b/nova/conf/configdrive.py index f19a825d910e..bb5cc514d8bf 100644 --- a/nova/conf/configdrive.py +++ b/nova/conf/configdrive.py @@ -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: diff --git a/nova/tests/unit/virt/libvirt/test_blockinfo.py b/nova/tests/unit/virt/libvirt/test_blockinfo.py index 022a85abb9aa..c2992308a3fe 100644 --- a/nova/tests/unit/virt/libvirt/test_blockinfo.py +++ b/nova/tests/unit/virt/libvirt/test_blockinfo.py @@ -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 = { diff --git a/nova/tests/unit/virt/test_configdrive.py b/nova/tests/unit/virt/test_configdrive.py index 91962d1d7e1c..b5946671f168 100644 --- a/nova/tests/unit/virt/test_configdrive.py +++ b/nova/tests/unit/virt/test_configdrive.py @@ -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) diff --git a/nova/virt/configdrive.py b/nova/virt/configdrive.py index 3e601ad436cc..7601872b25bc 100644 --- a/nova/virt/configdrive.py +++ b/nova/virt/configdrive.py @@ -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 )