Skip to content

Commit 3fe5c69

Browse files
es-zhouzhongmelwitt
authored andcommitted
nova-manage: modify image properties in request_spec
At present, we can modify the properties in the instance system_metadata through the sub command image_property of nova-manage, but there may be inconsistencies between their values and those in request_specs. And the migration is based on request_specs, so the same image properties are also written to request_specs. Closes-Bug: 2078999 Change-Id: Id36ecd022cb6f7f9a0fb131b0d202b79715870a9 (cherry picked from commit 2a1fad4) (cherry picked from commit ebae97c) (cherry picked from commit ee30457)
1 parent c1c6d67 commit 3fe5c69

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

nova/cmd/manage.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3306,9 +3306,10 @@ def _validate_image_properties(self, image_properties):
33063306
# Return the dict so we can update the instance system_metadata
33073307
return image_properties
33083308

3309-
def _update_image_properties(self, instance, image_properties):
3309+
def _update_image_properties(self, ctxt, instance, image_properties):
33103310
"""Update instance image properties
33113311
3312+
:param ctxt: nova.context.RequestContext
33123313
:param instance: The instance to update
33133314
:param image_properties: List of image properties and values to update
33143315
"""
@@ -3332,8 +3333,13 @@ def _update_image_properties(self, instance, image_properties):
33323333
for image_property, value in image_properties.items():
33333334
instance.system_metadata[f'image_{image_property}'] = value
33343335

3336+
request_spec = objects.RequestSpec.get_by_instance_uuid(
3337+
ctxt, instance.uuid)
3338+
request_spec.image = instance.image_meta
3339+
33353340
# Save and return 0
33363341
instance.save()
3342+
request_spec.save()
33373343
return 0
33383344

33393345
@action_description(_(
@@ -3368,7 +3374,7 @@ def set(self, instance_uuid=None, image_properties=None):
33683374
instance = objects.Instance.get_by_uuid(
33693375
cctxt, instance_uuid, expected_attrs=['system_metadata'])
33703376
return self._update_image_properties(
3371-
instance, image_properties)
3377+
ctxt, instance, image_properties)
33723378
except ValueError as e:
33733379
print(str(e))
33743380
return 6

nova/tests/unit/cmd/test_manage.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,6 +4219,8 @@ def test_show_image_properties_unknown_failure(
42194219
image_property='hw_disk_bus')
42204220
self.assertEqual(1, ret, 'return code')
42214221

4222+
@mock.patch('nova.objects.RequestSpec.save')
4223+
@mock.patch('nova.objects.RequestSpec.get_by_instance_uuid')
42224224
@mock.patch('nova.objects.Instance.get_by_uuid')
42234225
@mock.patch('nova.context.target_cell')
42244226
@mock.patch('nova.objects.Instance.save')
@@ -4227,7 +4229,8 @@ def test_show_image_properties_unknown_failure(
42274229
@mock.patch('nova.context.get_admin_context',
42284230
new=mock.Mock(return_value=mock.sentinel.ctxt))
42294231
def test_set_image_properties(
4230-
self, mock_instance_save, mock_target_cell, mock_get_instance
4232+
self, mock_instance_save, mock_target_cell, mock_get_instance,
4233+
mock_get_request_spec, mock_request_spec_save
42314234
):
42324235
mock_target_cell.return_value.__enter__.return_value = \
42334236
mock.sentinel.cctxt
@@ -4236,9 +4239,11 @@ def test_set_image_properties(
42364239
vm_state=obj_fields.InstanceState.STOPPED,
42374240
system_metadata={
42384241
'image_hw_disk_bus': 'virtio',
4239-
}
4242+
},
4243+
image_ref=''
42404244
)
42414245
mock_get_instance.return_value = instance
4246+
mock_get_request_spec.return_value = objects.RequestSpec()
42424247
ret = self.commands.set(
42434248
instance_uuid=uuidsentinel.instance,
42444249
image_properties=['hw_cdrom_bus=sata']
@@ -4255,7 +4260,12 @@ def test_set_image_properties(
42554260
instance.system_metadata.get('image_hw_disk_bus'),
42564261
'image_hw_disk_bus'
42574262
)
4263+
image_props = mock_get_request_spec.return_value.image.properties
4264+
self.assertEqual('sata', image_props.get('hw_cdrom_bus'))
4265+
self.assertEqual('virtio', image_props.get('hw_disk_bus'))
4266+
42584267
mock_instance_save.assert_called_once()
4268+
mock_request_spec_save.assert_called_once()
42594269

42604270
@mock.patch('nova.objects.Instance.get_by_uuid')
42614271
@mock.patch('nova.objects.InstanceMapping.get_by_instance_uuid',
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
fixes:
3+
- |
4+
Before the `Bug 2078999 <https://bugs.launchpad.net/nova/+bug/2078999>`_ was fixed,
5+
the ``nova-manage image_property set`` command would update the image properties
6+
embedded in the instance but would not update the ones in the request specs. This
7+
led to an unexpected rollback of the image properties that were updated by the
8+
command after an instance migration.

0 commit comments

Comments
 (0)