diff --git a/doc/source/support-matrix.ini b/doc/source/support-matrix.ini index dddefdb80f..00d8fa8c89 100644 --- a/doc/source/support-matrix.ini +++ b/doc/source/support-matrix.ini @@ -456,8 +456,10 @@ driver-impl-libvirt-xen=missing driver-impl-vmware=missing driver-impl-hyperv=missing driver-impl-ironic=missing -driver-impl-libvirt-vz-vm=missing -driver-impl-libvirt-vz-ct=missing +driver-impl-libvirt-vz-vm=complete +driver-notes-libvirt-vz-vm=Requires libvirt>=2.0.0 +driver-impl-libvirt-vz-ct=complete +driver-notes-libvirt-vz-ct=Requires libvirt>=2.0.0 [operation.snapshot] title=Save snapshot of instance disk diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 5d4eee65cc..c72209de75 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -1230,6 +1230,20 @@ class LibvirtConnTestCase(test.NoDBTestCase): mock_guest.set_user_password.assert_called_once_with("root", "123") + @mock.patch.object(host.Host, + 'has_min_version', return_value=True) + @mock.patch('nova.virt.libvirt.host.Host.get_guest') + def test_set_admin_password_parallels(self, mock_get_guest, ver): + self.flags(virt_type='parallels', group='libvirt') + instance = objects.Instance(**self.test_instance) + mock_guest = mock.Mock(spec=libvirt_guest.Guest) + mock_get_guest.return_value = mock_guest + + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + drvr.set_admin_password(instance, "123") + + mock_guest.set_user_password.assert_called_once_with("root", "123") + @mock.patch('nova.utils.get_image_from_system_metadata') @mock.patch.object(host.Host, 'has_min_version', return_value=True) @@ -1272,13 +1286,15 @@ class LibvirtConnTestCase(test.NoDBTestCase): @mock.patch.object(host.Host, 'has_min_version', return_value=False) def test_set_admin_password_bad_version(self, mock_svc, mock_image): - self.flags(virt_type='kvm', group='libvirt') + instance = objects.Instance(**self.test_instance) mock_image.return_value = {"properties": { "hw_qemu_guest_agent": "yes"}} - drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) - self.assertRaises(exception.SetAdminPasswdNotSupported, - drvr.set_admin_password, instance, "123") + for hyp in ('kvm', 'parallels'): + self.flags(virt_type=hyp, group='libvirt') + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + self.assertRaises(exception.SetAdminPasswdNotSupported, + drvr.set_admin_password, instance, "123") @mock.patch('nova.utils.get_image_from_system_metadata') @mock.patch.object(host.Host, diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 94c2964bae..96df4457b2 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -259,6 +259,9 @@ MIN_LIBVIRT_PARALLELS_VERSION = (1, 2, 12) # Ability to set the user guest password with Qemu MIN_LIBVIRT_SET_ADMIN_PASSWD = (1, 2, 16) +# Ability to set the user guest password with parallels +MIN_LIBVIRT_PARALLELS_SET_ADMIN_PASSWD = (2, 0, 0) + # s/390 & s/390x architectures with KVM MIN_LIBVIRT_KVM_S390_VERSION = (1, 2, 13) MIN_QEMU_S390_VERSION = (2, 3, 0) @@ -1570,13 +1573,20 @@ class LibvirtDriver(driver.ComputeDriver): self._attach_sriov_ports(context, instance, guest) def _can_set_admin_password(self, image_meta): - if (CONF.libvirt.virt_type not in ('kvm', 'qemu') or - not self._host.has_min_version(MIN_LIBVIRT_SET_ADMIN_PASSWD)): - raise exception.SetAdminPasswdNotSupported() - hw_qga = image_meta.properties.get('hw_qemu_guest_agent', '') - if not strutils.bool_from_string(hw_qga): - raise exception.QemuGuestAgentNotEnabled() + if CONF.libvirt.virt_type == 'parallels': + if not self._host.has_min_version( + MIN_LIBVIRT_PARALLELS_SET_ADMIN_PASSWD): + raise exception.SetAdminPasswdNotSupported() + elif CONF.libvirt.virt_type in ('kvm', 'qemu'): + if not self._host.has_min_version( + MIN_LIBVIRT_SET_ADMIN_PASSWD): + raise exception.SetAdminPasswdNotSupported() + hw_qga = image_meta.properties.get('hw_qemu_guest_agent', '') + if not strutils.bool_from_string(hw_qga): + raise exception.QemuGuestAgentNotEnabled() + else: + raise exception.SetAdminPasswdNotSupported() def set_admin_password(self, instance, new_pass): self._can_set_admin_password(instance.image_meta) diff --git a/releasenotes/notes/bp-virtuozzo-instance-admin-password-8278cad73f3be98d.yaml b/releasenotes/notes/bp-virtuozzo-instance-admin-password-8278cad73f3be98d.yaml new file mode 100644 index 0000000000..4ff8460949 --- /dev/null +++ b/releasenotes/notes/bp-virtuozzo-instance-admin-password-8278cad73f3be98d.yaml @@ -0,0 +1,4 @@ +--- +features: + - Virtuozzo hypervisor now supports libvirt callback to set admin password. + Requires libvirt>=2.0.0.