From 4b4410741f3a7581557e4885999b73c3652c234d Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Sun, 4 Oct 2026 12:02:48 +0200 Subject: [PATCH] feat(provisioning): accept cpu_type, and refuse one that cannot be honoured napalm_device_types' create_vm_from_cloud_init gained cpu_type, the CPU model a new VM gets (netork#494). VMware sets CPU compatibility per cluster (EVC), not per VM, and this driver has no get_vm_cpu_types() to offer a model, so None is the only value it can honour. Anything else raises ValueError before the image is fetched rather than being dropped silently. --- napalm_vmware/provisioning.py | 5 +++++ tests/test_provisioning.py | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/napalm_vmware/provisioning.py b/napalm_vmware/provisioning.py index 24770d0..0ae6f3c 100644 --- a/napalm_vmware/provisioning.py +++ b/napalm_vmware/provisioning.py @@ -147,9 +147,14 @@ class VmwareProvisioningMixin: ssh_public_keys: list[str] | None = None, disk_resize_gb: int | None = None, storage: str | None = None, + cpu_type: str | None = None, download_timeout: int = 300, timeout: int = 180, ) -> VMProvisionResultDict: + if cpu_type is not None: + # CPU compatibility is a cluster setting here (EVC), not a per-VM + # one, and there is no get_vm_cpu_types() that could offer a model. + raise ValueError(f"VMware cannot give a single VM a CPU type ({cpu_type!r})") self._check_nics(nics) try: vmdk, image_size = ImageCache(self._image_cache_dir).vmdk( diff --git a/tests/test_provisioning.py b/tests/test_provisioning.py index 941cae3..4f81dca 100644 --- a/tests/test_provisioning.py +++ b/tests/test_provisioning.py @@ -141,6 +141,17 @@ class TestCreate: _create(driver) staged.discard.assert_called_once_with("vm-99") + def test_no_cpu_type_is_the_normal_case(self, driver, staged): + assert _create(driver, cpu_type=None)["vmid"] == "uuid-99" + + def test_a_cpu_type_is_refused_before_anything_happens(self, driver, staged): + """VMware sets CPU compatibility per cluster (EVC), not per VM, so a + requested model cannot be honoured -- and is not silently dropped.""" + with pytest.raises(ValueError, match="CPU type"): + _create(driver, cpu_type="host") + staged.cache.return_value.vmdk.assert_not_called() + staged.import_ovf.assert_not_called() + def test_placement_refusal_is_a_runtime_error(self, driver, staged): with patch.object(prov, "choose_placement", side_effect=ValueError("no host")): with pytest.raises(RuntimeError, match="no host"): -- 2.54.0