mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
vTPM: support KVM and VMware (#10543)
* KVM: add Virtual TPM model and version * KVM: add admin-only VM setting GUEST.CPU.MODE and GUEST.CPU.MODEL * VMware: add vTPM * vTPM: do not set Key due to 'Cannot add multiple devices using the same device key..' * vTPM: add unit test testTpmModel * engine/schema: remove user vm details for guest CPU mode/model * vTPM: extra methods as Daan's requests * vTPM: add unit tests in VmwareResourceTest * vTPM: update unit tests in VmwareResourceTest * vTPM: add unit test in LibvirtComputingResourceTest * vTPM: use the default TPM version if an invalid version is passed * vTPM: requires UEFI on vmware and do nothing if it is not enabled/disabled * vTPM: let uses to add UEFI on vmware * Update plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java Co-authored-by: Suresh Kumar Anaparti <sureshkumar.anaparti@gmail.com> * Update plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java Co-authored-by: Suresh Kumar Anaparti <sureshkumar.anaparti@gmail.com> * vTPM: remove template details for guest CPU mode/model * UI: boot vm from ISO into UEFI/SECURE mode --------- Co-authored-by: Suresh Kumar Anaparti <sureshkumar.anaparti@gmail.com>
This commit is contained in:
parent
12c077d704
commit
5d28e66b52
@ -101,4 +101,13 @@ public interface VmDetailConstants {
|
||||
String VMWARE_HOST_NAME = String.format("%s-host", VMWARE_TO_KVM_PREFIX);
|
||||
String VMWARE_DISK = String.format("%s-disk", VMWARE_TO_KVM_PREFIX);
|
||||
String VMWARE_MAC_ADDRESSES = String.format("%s-mac-addresses", VMWARE_TO_KVM_PREFIX);
|
||||
|
||||
// TPM
|
||||
String VIRTUAL_TPM_ENABLED = "virtual.tpm.enabled";
|
||||
String VIRTUAL_TPM_MODEL = "virtual.tpm.model";
|
||||
String VIRTUAL_TPM_VERSION = "virtual.tpm.version";
|
||||
|
||||
// CPU mode and model, ADMIN only
|
||||
String GUEST_CPU_MODE = "guest.cpu.mode";
|
||||
String GUEST_CPU_MODEL = "guest.cpu.model";
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.query;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
@ -97,6 +98,7 @@ import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
|
||||
/**
|
||||
* Service used for list api query.
|
||||
@ -104,6 +106,8 @@ import com.cloud.exception.PermissionDeniedException;
|
||||
*/
|
||||
public interface QueryService {
|
||||
|
||||
List<String> RootAdminOnlyVmSettings = Arrays.asList(VmDetailConstants.GUEST_CPU_MODE, VmDetailConstants.GUEST_CPU_MODEL);
|
||||
|
||||
// Config keys
|
||||
ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
|
||||
"Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
|
||||
|
||||
@ -19,6 +19,12 @@
|
||||
-- Schema upgrade from 4.20.0.0 to 4.20.1.0
|
||||
--;
|
||||
|
||||
-- Delete user vm details for guest CPU mode/model which are root admin only
|
||||
DELETE FROM `cloud`.`user_vm_details` WHERE `name` IN ('guest.cpu.mode','guest.cpu.model');
|
||||
|
||||
-- Delete template details for guest CPU mode/model which are root admin only
|
||||
DELETE FROM `cloud`.`vm_template_details` WHERE `name` IN ('guest.cpu.mode','guest.cpu.model');
|
||||
|
||||
-- Add column api_key_access to user and account tables
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the user" AFTER `secret_key`');
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
|
||||
|
||||
@ -166,6 +166,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TpmDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
|
||||
@ -2660,6 +2661,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
devices.addDevice(createGraphicDef(vmTO));
|
||||
devices.addDevice(createTabletInputDef());
|
||||
|
||||
TpmDef tpmDef = createTpmDef(vmTO);
|
||||
if (tpmDef != null) {
|
||||
devices.addDevice(tpmDef);
|
||||
}
|
||||
|
||||
if (isGuestAarch64()) {
|
||||
createArm64UsbDef(devices);
|
||||
}
|
||||
@ -2840,8 +2846,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
|
||||
private CpuModeDef createCpuModeDef(VirtualMachineTO vmTO, int vcpus) {
|
||||
final CpuModeDef cmd = new CpuModeDef();
|
||||
cmd.setMode(guestCpuMode);
|
||||
cmd.setModel(guestCpuModel);
|
||||
Map<String, String> details = vmTO.getDetails();
|
||||
String cpuMode = MapUtils.isNotEmpty(details) && details.get(VmDetailConstants.GUEST_CPU_MODE) != null ? details.get(VmDetailConstants.GUEST_CPU_MODE) : guestCpuMode;
|
||||
String cpuModel = MapUtils.isNotEmpty(details) && details.get(VmDetailConstants.GUEST_CPU_MODEL) != null ? details.get(VmDetailConstants.GUEST_CPU_MODEL) : guestCpuModel;
|
||||
cmd.setMode(cpuMode);
|
||||
cmd.setModel(cpuModel);
|
||||
if (VirtualMachine.Type.User.equals(vmTO.getType())) {
|
||||
cmd.setFeatures(cpuFeatures);
|
||||
}
|
||||
@ -2850,6 +2859,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return cmd;
|
||||
}
|
||||
|
||||
protected TpmDef createTpmDef(VirtualMachineTO vmTO) {
|
||||
Map<String, String> details = vmTO.getDetails();
|
||||
if (MapUtils.isEmpty(details)) {
|
||||
return null;
|
||||
}
|
||||
String tpmModel = details.get(VmDetailConstants.VIRTUAL_TPM_MODEL);
|
||||
if (tpmModel == null) {
|
||||
return null;
|
||||
}
|
||||
String tpmVersion = details.get(VmDetailConstants.VIRTUAL_TPM_VERSION);
|
||||
return new TpmDef(tpmModel, tpmVersion);
|
||||
}
|
||||
|
||||
private void configureGuestIfUefiEnabled(boolean isSecureBoot, String bootMode, GuestDef guest) {
|
||||
setGuestLoader(bootMode, SECURE, guest, GuestDef.GUEST_LOADER_SECURE);
|
||||
setGuestLoader(bootMode, LEGACY, guest, GuestDef.GUEST_LOADER_LEGACY);
|
||||
|
||||
@ -18,6 +18,7 @@ package com.cloud.hypervisor.kvm.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -2358,6 +2359,82 @@ public class LibvirtVMDef {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TpmDef {
|
||||
enum TpmModel {
|
||||
TIS("tpm-tis"), // TPM Interface Specification (TIS)
|
||||
CRB("tpm-crb"); // Command-Response Buffer (CRB)
|
||||
|
||||
final String model;
|
||||
|
||||
TpmModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
enum TpmVersion {
|
||||
V1_2("1.2"), // 1.2
|
||||
V2_0("2.0"); // 2.0. Default version. The CRB model is only supported with version 2.0.
|
||||
|
||||
final String version;
|
||||
|
||||
TpmVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
private TpmModel model;
|
||||
private TpmVersion version = TpmVersion.V2_0;
|
||||
|
||||
public TpmDef(TpmModel model, TpmVersion version) {
|
||||
this.model = model;
|
||||
if (version != null) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
public TpmDef(String model, String version) {
|
||||
this.model = Arrays.stream(TpmModel.values())
|
||||
.filter(tpmModel -> tpmModel.toString().equals(model))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (version != null) {
|
||||
this.version = Arrays.stream(TpmVersion.values())
|
||||
.filter(tpmVersion -> tpmVersion.toString().equals(version))
|
||||
.findFirst()
|
||||
.orElse(this.version);;
|
||||
}
|
||||
}
|
||||
|
||||
public TpmModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public TpmVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder tpmBuidler = new StringBuilder();
|
||||
if (model != null) {
|
||||
tpmBuidler.append("<tpm model='").append(model).append("'>\n");
|
||||
tpmBuidler.append("<backend type='emulator' version='").append(version).append("'/>\n");
|
||||
tpmBuidler.append("</tpm>\n");
|
||||
}
|
||||
return tpmBuidler.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public void setHvsType(String hvs) {
|
||||
_hvsType = hvs;
|
||||
}
|
||||
|
||||
@ -6541,4 +6541,28 @@ public class LibvirtComputingResourceTest {
|
||||
DiskDef.DiskBus diskBus = libvirtComputingResourceSpy.getDiskModelFromVMDetail(virtualMachineTO);
|
||||
assertEquals(DiskDef.DiskBus.VIRTIOBLK, diskBus);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTpmDef() {
|
||||
VirtualMachineTO virtualMachineTO = Mockito.mock(VirtualMachineTO.class);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(VmDetailConstants.VIRTUAL_TPM_MODEL, "tpm-tis");
|
||||
details.put(VmDetailConstants.VIRTUAL_TPM_VERSION, "2.0");
|
||||
Mockito.when(virtualMachineTO.getDetails()).thenReturn(details);
|
||||
LibvirtVMDef.TpmDef tpmDef = libvirtComputingResourceSpy.createTpmDef(virtualMachineTO);
|
||||
assertEquals(LibvirtVMDef.TpmDef.TpmModel.TIS, tpmDef.getModel());
|
||||
assertEquals(LibvirtVMDef.TpmDef.TpmVersion.V2_0, tpmDef.getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTpmDefWithInvalidVersion() {
|
||||
VirtualMachineTO virtualMachineTO = Mockito.mock(VirtualMachineTO.class);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(VmDetailConstants.VIRTUAL_TPM_MODEL, "tpm-crb");
|
||||
details.put(VmDetailConstants.VIRTUAL_TPM_VERSION, "3.0");
|
||||
Mockito.when(virtualMachineTO.getDetails()).thenReturn(details);
|
||||
LibvirtVMDef.TpmDef tpmDef = libvirtComputingResourceSpy.createTpmDef(virtualMachineTO);
|
||||
assertEquals(LibvirtVMDef.TpmDef.TpmModel.CRB, tpmDef.getModel());
|
||||
assertEquals(LibvirtVMDef.TpmDef.TpmVersion.V2_0, tpmDef.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
@ -566,9 +566,20 @@ public class LibvirtVMDefTest extends TestCase {
|
||||
assertEquals("<cpu><topology sockets='4' cores='2' threads='1' /></cpu>", cpuModeDef.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTopologyNoInfo() {
|
||||
LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef();
|
||||
cpuModeDef.setTopology(-1, -1, 4);
|
||||
assertEquals("<cpu></cpu>", cpuModeDef.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTpmModel() {
|
||||
LibvirtVMDef.TpmDef tpmDef = new LibvirtVMDef.TpmDef("tpm-tis", "2.0");
|
||||
assertEquals(LibvirtVMDef.TpmDef.TpmModel.TIS, tpmDef.getModel());
|
||||
assertEquals(LibvirtVMDef.TpmDef.TpmVersion.V2_0, tpmDef.getVersion());
|
||||
assertEquals("<tpm model='tpm-tis'>\n" +
|
||||
"<backend type='emulator' version='2.0'/>\n" +
|
||||
"</tpm>\n", tpmDef.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ import javax.xml.datatype.XMLGregorianCalendar;
|
||||
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.hypervisor.vmware.mo.HostDatastoreBrowserMO;
|
||||
import com.vmware.vim25.Description;
|
||||
import com.vmware.vim25.FileInfo;
|
||||
import com.vmware.vim25.FileQueryFlags;
|
||||
import com.vmware.vim25.FolderFileInfo;
|
||||
@ -58,6 +59,7 @@ import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
||||
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
||||
import com.vmware.vim25.VirtualCdromIsoBackingInfo;
|
||||
import com.vmware.vim25.VirtualMachineConfigSummary;
|
||||
import com.vmware.vim25.VirtualTPM;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.backup.PrepareForBackupRestorationCommand;
|
||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||
@ -2597,12 +2599,16 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||
|
||||
setBootOptions(vmSpec, bootMode, vmConfigSpec);
|
||||
|
||||
// Config vTPM
|
||||
configureVirtualTPM(vmMo, vmSpec, vmConfigSpec);
|
||||
|
||||
if (StringUtils.isNotEmpty(vmStoragePolicyId)) {
|
||||
vmConfigSpec.getVmProfile().add(vmProfileSpec);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Configuring the VM %s with storage policy: %s", vmInternalCSName, vmStoragePolicyId));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Configure VM
|
||||
//
|
||||
@ -3203,6 +3209,57 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
||||
vmConfigSpec.getDeviceChange().add(arrayVideoCardConfigSpecs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or Remove virtual TPM module
|
||||
*
|
||||
* @param vmMo virtual machine mo
|
||||
* @param vmSpec virtual machine specs
|
||||
* @param vmConfigSpec virtual machine config spec
|
||||
* @throws Exception exception
|
||||
*/
|
||||
protected void configureVirtualTPM(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
|
||||
String virtualTPMEnabled = vmSpec.getDetails().getOrDefault(VmDetailConstants.VIRTUAL_TPM_ENABLED, null);
|
||||
if (Boolean.parseBoolean(virtualTPMEnabled)) {
|
||||
for (VirtualDevice device : vmMo.getAllDeviceList()) {
|
||||
if (device instanceof VirtualTPM) {
|
||||
logger.debug(String.format("Virtual TPM device has already been added to VM %s, returning", vmMo.getVmName()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
logger.debug(String.format("Adding Virtual TPM device to the VM %s", vmMo.getVmName()));
|
||||
addVirtualTPMDevice(vmConfigSpec);
|
||||
} else if (virtualTPMEnabled == null) {
|
||||
logger.debug(String.format("Virtual TPM device is neither enabled nor disabled for VM %s, skipping", vmMo.getVmName()));
|
||||
} else {
|
||||
logger.debug(String.format("Virtual TPM device is disabled for VM %s", vmMo.getVmName()));
|
||||
for (VirtualDevice device : vmMo.getAllDeviceList()) {
|
||||
if (device instanceof VirtualTPM) {
|
||||
logger.debug(String.format("Removing Virtual TPM device from VM %s as it is disabled", vmMo.getVmName()));
|
||||
removeVirtualTPMDevice(vmConfigSpec, (VirtualTPM) device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void addVirtualTPMDevice(VirtualMachineConfigSpec vmConfigSpec) {
|
||||
Description description = new Description();
|
||||
description.setSummary("Trusted Platform Module");
|
||||
description.setLabel("Trusted Platform Module");
|
||||
VirtualTPM virtualTPM = new VirtualTPM();
|
||||
virtualTPM.setDeviceInfo(description);
|
||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||
deviceConfigSpec.setDevice(virtualTPM);
|
||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
||||
vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
||||
}
|
||||
|
||||
protected void removeVirtualTPMDevice(VirtualMachineConfigSpec vmConfigSpec, VirtualTPM virtualTPM) {
|
||||
VirtualDeviceConfigSpec virtualDeviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||
virtualDeviceConfigSpec.setDevice(virtualTPM);
|
||||
virtualDeviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
|
||||
vmConfigSpec.getDeviceChange().add(virtualDeviceConfigSpec);
|
||||
}
|
||||
|
||||
private void tearDownVm(VirtualMachineMO vmMo) throws Exception {
|
||||
|
||||
if (vmMo == null)
|
||||
|
||||
@ -48,6 +48,8 @@ import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||
import com.vmware.vim25.FileInfo;
|
||||
import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
||||
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
||||
import com.vmware.vim25.VirtualTPM;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||
import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsAnswer;
|
||||
import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsCommand;
|
||||
@ -842,4 +844,41 @@ public class VmwareResourceTest {
|
||||
assertEquals(Collections.singletonList(1L), answer.getSizes());
|
||||
assertEquals(Collections.singletonList(date.getTime()), answer.getLastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddVirtualTPMDevice() throws Exception {
|
||||
VirtualMachineMO vmMo = Mockito.mock(VirtualMachineMO.class);
|
||||
VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
|
||||
VirtualMachineConfigSpec vmConfigSpec = Mockito.mock(VirtualMachineConfigSpec.class);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(ApiConstants.BootType.UEFI.toString(), "SECURE");
|
||||
details.put(VmDetailConstants.VIRTUAL_TPM_ENABLED, "true");
|
||||
when(vmSpec.getDetails()).thenReturn(details);
|
||||
when(vmMo.getAllDeviceList()).thenReturn(new ArrayList<>());
|
||||
List<VirtualDeviceConfigSpec> deviceChanges = Mockito.mock(List.class);
|
||||
when(vmConfigSpec.getDeviceChange()).thenReturn(deviceChanges);
|
||||
|
||||
vmwareResource.configureVirtualTPM(vmMo, vmSpec, vmConfigSpec);
|
||||
Mockito.verify(vmwareResource, Mockito.times(1)).addVirtualTPMDevice(vmConfigSpec);
|
||||
Mockito.verify(deviceChanges, Mockito.times(1)).add(any(VirtualDeviceConfigSpec.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveVirtualTPMDevice() throws Exception {
|
||||
VirtualMachineMO vmMo = Mockito.mock(VirtualMachineMO.class);
|
||||
VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
|
||||
VirtualMachineConfigSpec vmConfigSpec = Mockito.mock(VirtualMachineConfigSpec.class);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(ApiConstants.BootType.UEFI.toString(), "SECURE");
|
||||
details.put(VmDetailConstants.VIRTUAL_TPM_ENABLED, "false");
|
||||
when(vmSpec.getDetails()).thenReturn(details);
|
||||
VirtualTPM tpm = new VirtualTPM();
|
||||
when(vmMo.getAllDeviceList()).thenReturn(List.of(tpm));
|
||||
List<VirtualDeviceConfigSpec> deviceChanges = Mockito.mock(List.class);
|
||||
when(vmConfigSpec.getDeviceChange()).thenReturn(deviceChanges);
|
||||
|
||||
vmwareResource.configureVirtualTPM(vmMo, vmSpec, vmConfigSpec);
|
||||
Mockito.verify(vmwareResource, Mockito.times(1)).removeVirtualTPMDevice(vmConfigSpec, tpm);
|
||||
Mockito.verify(deviceChanges, Mockito.times(1)).add(any(VirtualDeviceConfigSpec.class));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5033,6 +5033,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
final List<String> userDenyListedSettings = Stream.of(QueryService.UserVMDeniedDetails.value().split(","))
|
||||
.map(item -> (item).trim())
|
||||
.collect(Collectors.toList());
|
||||
userDenyListedSettings.addAll(QueryService.RootAdminOnlyVmSettings);
|
||||
for (final String detail : userDenyListedSettings) {
|
||||
if (options.containsKey(detail)) {
|
||||
options.remove(detail);
|
||||
@ -5083,6 +5084,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
options.put(VmDetailConstants.IOTHREADS, Arrays.asList("enabled"));
|
||||
options.put(VmDetailConstants.NIC_MULTIQUEUE_NUMBER, Collections.emptyList());
|
||||
options.put(VmDetailConstants.NIC_PACKED_VIRTQUEUES_ENABLED, Arrays.asList("true", "false"));
|
||||
options.put(VmDetailConstants.VIRTUAL_TPM_MODEL, Arrays.asList("tpm-tis", "tpm-crb"));
|
||||
options.put(VmDetailConstants.VIRTUAL_TPM_VERSION, Arrays.asList("1.2", "2.0"));
|
||||
options.put(VmDetailConstants.GUEST_CPU_MODE, Arrays.asList("custom", "host-model", "host-passthrough"));
|
||||
options.put(VmDetailConstants.GUEST_CPU_MODEL, Collections.emptyList());
|
||||
}
|
||||
|
||||
if (HypervisorType.VMware.equals(hypervisorType)) {
|
||||
@ -5092,6 +5097,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
options.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, Arrays.asList("true", "false"));
|
||||
options.put(VmDetailConstants.SVGA_VRAM_SIZE, Collections.emptyList());
|
||||
options.put(VmDetailConstants.RAM_RESERVATION, Collections.emptyList());
|
||||
options.put(VmDetailConstants.VIRTUAL_TPM_ENABLED, Arrays.asList("true", "false"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2839,6 +2839,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
final List<String> userDenyListedSettings = Stream.of(QueryService.UserVMDeniedDetails.value().split(","))
|
||||
.map(item -> (item).trim())
|
||||
.collect(Collectors.toList());
|
||||
userDenyListedSettings.addAll(QueryService.RootAdminOnlyVmSettings);
|
||||
final List<String> userReadOnlySettings = Stream.of(QueryService.UserVMReadOnlyDetails.value().split(","))
|
||||
.map(item -> (item).trim())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@ -559,7 +559,7 @@
|
||||
</span>
|
||||
<div style="margin-top: 15px" v-if="showDetails">
|
||||
<div
|
||||
v-if="vm.templateid && ['KVM', 'VMware', 'XenServer'].includes(hypervisor) && !template.deployasis">
|
||||
v-if="['KVM', 'VMware', 'XenServer'].includes(hypervisor) && ((vm.templateid && !template.deployasis) || vm.isoid)">
|
||||
<a-form-item :label="$t('label.boottype')" name="boottype" ref="boottype">
|
||||
<a-select
|
||||
v-model:value="form.boottype"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user