Skip to content

Commit 9a94ff3

Browse files
authored
Merge pull request #160 from stackhpc/upstream/zed-2025-10-13
Synchronise zed with upstream
2 parents adf8c49 + 09c9826 commit 9a94ff3

File tree

6 files changed

+82
-9
lines changed

6 files changed

+82
-9
lines changed

nova/cmd/manage.py

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

3261-
def _update_image_properties(self, instance, image_properties):
3261+
def _update_image_properties(self, ctxt, instance, image_properties):
32623262
"""Update instance image properties
32633263
3264+
:param ctxt: nova.context.RequestContext
32643265
:param instance: The instance to update
32653266
:param image_properties: List of image properties and values to update
32663267
"""
@@ -3284,8 +3285,13 @@ def _update_image_properties(self, instance, image_properties):
32843285
for image_property, value in image_properties.items():
32853286
instance.system_metadata[f'image_{image_property}'] = value
32863287

3288+
request_spec = objects.RequestSpec.get_by_instance_uuid(
3289+
ctxt, instance.uuid)
3290+
request_spec.image = instance.image_meta
3291+
32873292
# Save and return 0
32883293
instance.save()
3294+
request_spec.save()
32893295
return 0
32903296

32913297
@action_description(_(
@@ -3320,7 +3326,7 @@ def set(self, instance_uuid=None, image_properties=None):
33203326
instance = objects.Instance.get_by_uuid(
33213327
cctxt, instance_uuid, expected_attrs=['system_metadata'])
33223328
return self._update_image_properties(
3323-
instance, image_properties)
3329+
ctxt, instance, image_properties)
33243330
except ValueError as e:
33253331
print(str(e))
33263332
return 6

nova/tests/unit/cmd/test_manage.py

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

4103+
@mock.patch('nova.objects.RequestSpec.save')
4104+
@mock.patch('nova.objects.RequestSpec.get_by_instance_uuid')
41034105
@mock.patch('nova.objects.Instance.get_by_uuid')
41044106
@mock.patch('nova.context.target_cell')
41054107
@mock.patch('nova.objects.Instance.save')
@@ -4108,7 +4110,8 @@ def test_show_image_properties_unknown_failure(
41084110
@mock.patch('nova.context.get_admin_context',
41094111
new=mock.Mock(return_value=mock.sentinel.ctxt))
41104112
def test_set_image_properties(
4111-
self, mock_instance_save, mock_target_cell, mock_get_instance
4113+
self, mock_instance_save, mock_target_cell, mock_get_instance,
4114+
mock_get_request_spec, mock_request_spec_save
41124115
):
41134116
mock_target_cell.return_value.__enter__.return_value = \
41144117
mock.sentinel.cctxt
@@ -4117,9 +4120,11 @@ def test_set_image_properties(
41174120
vm_state=obj_fields.InstanceState.STOPPED,
41184121
system_metadata={
41194122
'image_hw_disk_bus': 'virtio',
4120-
}
4123+
},
4124+
image_ref=''
41214125
)
41224126
mock_get_instance.return_value = instance
4127+
mock_get_request_spec.return_value = objects.RequestSpec()
41234128
ret = self.commands.set(
41244129
instance_uuid=uuidsentinel.instance,
41254130
image_properties=['hw_cdrom_bus=sata']
@@ -4136,7 +4141,12 @@ def test_set_image_properties(
41364141
instance.system_metadata.get('image_hw_disk_bus'),
41374142
'image_hw_disk_bus'
41384143
)
4144+
image_props = mock_get_request_spec.return_value.image.properties
4145+
self.assertEqual('sata', image_props.get('hw_cdrom_bus'))
4146+
self.assertEqual('virtio', image_props.get('hw_disk_bus'))
4147+
41394148
mock_instance_save.assert_called_once()
4149+
mock_request_spec_save.assert_called_once()
41404150

41414151
@mock.patch('nova.objects.Instance.get_by_uuid')
41424152
@mock.patch('nova.objects.InstanceMapping.get_by_instance_uuid',

nova/tests/unit/virt/libvirt/test_blockinfo.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,7 @@ def test_get_root_info_no_bdm_empty_image_meta(self, mock_find_dev):
12891289

12901290
@mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm')
12911291
def test_get_root_info_bdm(self, mock_get_info):
1292+
# call get_root_info() with DriverBlockDevice
12921293
instance = objects.Instance(**self.test_instance)
12931294
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
12941295
root_bdm = {'mount_device': '/dev/vda',
@@ -1318,6 +1319,49 @@ def test_get_root_info_bdm(self, mock_get_info):
13181319
{}, 'virtio')
13191320
mock_get_info.reset_mock()
13201321

1322+
@mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm')
1323+
def test_get_root_info_bdm_with_deepcopy(self, mock_get_info):
1324+
# call get_root_info() with BlockDeviceMapping
1325+
instance = objects.Instance(**self.test_instance)
1326+
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
1327+
root_bdm = objects.BlockDeviceMapping(self.context,
1328+
**fake_block_device.FakeDbBlockDeviceDict(
1329+
{'id': 3, 'instance_uuid': uuids.instance,
1330+
'device_name': '/dev/sda',
1331+
'source_type': 'blank',
1332+
'destination_type': 'local',
1333+
'device_type': 'cdrom',
1334+
'disk_bus': 'virtio',
1335+
'volume_id': 'fake-volume-id-1',
1336+
'boot_index': 0}))
1337+
# No root_device_name
1338+
blockinfo.get_root_info(
1339+
instance, 'kvm', image_meta, root_bdm, 'virtio', 'ide')
1340+
mock_get_info.assert_called_once_with(
1341+
instance, 'kvm', image_meta, root_bdm, {}, 'virtio')
1342+
mock_get_info.reset_mock()
1343+
# Both device names
1344+
blockinfo.get_root_info(
1345+
instance, 'kvm', image_meta, root_bdm, 'virtio', 'scsi',
1346+
root_device_name='/dev/sda')
1347+
mock_get_info.assert_called_once_with(
1348+
instance, 'kvm', image_meta, root_bdm, {}, 'virtio')
1349+
mock_get_info.reset_mock()
1350+
# Missing device names
1351+
original_bdm = copy.deepcopy(root_bdm)
1352+
root_bdm.device_name = ''
1353+
blockinfo.get_root_info(
1354+
instance, 'kvm', image_meta, root_bdm, 'virtio', 'scsi',
1355+
root_device_name='/dev/sda')
1356+
mock_get_info.assert_called_with(
1357+
instance, 'kvm', image_meta, mock.ANY, {}, 'virtio')
1358+
actual_call = mock_get_info.call_args
1359+
_, _, _, actual_bdm, _, _ = actual_call[0]
1360+
self.assertEqual(
1361+
original_bdm.obj_to_primitive(),
1362+
actual_bdm.obj_to_primitive()
1363+
)
1364+
13211365
def test_get_boot_order_simple(self):
13221366
disk_info = {
13231367
'disk_bus': 'virtio',

nova/virt/libvirt/blockinfo.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
7070
"""
7171

72+
import copy
7273
import itertools
7374
import operator
7475

@@ -444,12 +445,13 @@ def get_root_info(instance, virt_type, image_meta, root_bdm,
444445
'dev': block_device.strip_dev(root_device_name),
445446
'boot_index': '1'}
446447

448+
root_bdm_copy = root_bdm
447449
if not get_device_name(root_bdm) and root_device_name:
448-
root_bdm = root_bdm.copy()
449-
root_bdm['device_name'] = root_device_name
450+
root_bdm_copy = copy.deepcopy(root_bdm)
451+
root_bdm_copy['device_name'] = root_device_name
450452

451453
return get_info_from_bdm(
452-
instance, virt_type, image_meta, root_bdm, {}, disk_bus,
454+
instance, virt_type, image_meta, root_bdm_copy, {}, disk_bus,
453455
)
454456

455457

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.

tools/check-cherry-picks.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ branches+=""
2626
for hash in $hashes; do
2727
branch=$(git branch -a --contains "$hash" 2>/dev/null| grep -oE '(master|stable/[a-z0-9.]+|unmaintained/[a-z0-9.]+)')
2828
if [ $? -ne 0 ]; then
29-
echo "Cherry pick hash $hash not on any master, stable or unmaintained branches"
30-
exit 1
29+
branch=$(git tag --contains "$hash" 2>/dev/null| grep -oE '([0-9.]+-eol)')
30+
if [ $? -ne 0 ]; then
31+
echo "Cherry pick hash $hash not on any master, stable, unmaintained or EOL'd branches"
32+
exit 1
33+
fi
3134
fi
3235
branches+=" $branch"
3336
checked=$(($checked + 1))

0 commit comments

Comments
 (0)