mirror of https://github.com/apache/cloudstack.git
Merge branch '4.20' into 4.22
This commit is contained in:
commit
e25cf437c0
|
|
@ -55,6 +55,9 @@ public interface VmDetailConstants {
|
|||
String NIC_MULTIQUEUE_NUMBER = "nic.multiqueue.number";
|
||||
String NIC_PACKED_VIRTQUEUES_ENABLED = "nic.packed.virtqueues.enabled";
|
||||
|
||||
// KVM specific, disk controllers
|
||||
String KVM_SKIP_FORCE_DISK_CONTROLLER = "skip.force.disk.controller";
|
||||
|
||||
// Mac OSX guest specific (internal)
|
||||
String SMC_PRESENT = "smc.present";
|
||||
String FIRMWARE = "firmware";
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
|
||||
private static final String LEFT_JOIN_VM_TEMPLATE = "LEFT JOIN vm_template ON vm_template.id = vi.vm_template_id ";
|
||||
|
||||
private static final String STORAGE_POOLS_WITH_CHILDREN = "SELECT DISTINCT parent FROM storage_pool WHERE parent != 0 AND removed IS NULL";
|
||||
|
||||
public CapacityDaoImpl() {
|
||||
_hostIdTypeSearch = createSearchBuilder();
|
||||
_hostIdTypeSearch.and("hostId", _hostIdTypeSearch.entity().getHostOrPoolId(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -379,6 +381,11 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
finalQuery.append(" AND capacity_type = ?");
|
||||
resourceIdList.add(capacityType.longValue());
|
||||
}
|
||||
|
||||
// Exclude storage pools with children from capacity calculations to avoid double counting
|
||||
finalQuery.append(" AND NOT (capacity.capacity_type = ").append(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED)
|
||||
.append(" AND capacity.host_id IN (").append(STORAGE_POOLS_WITH_CHILDREN).append("))");
|
||||
|
||||
if (CollectionUtils.isNotEmpty(hostIds)) {
|
||||
finalQuery.append(String.format(" AND capacity.host_id IN (%s)", StringUtils.join(hostIds, ",")));
|
||||
if (capacityType == null) {
|
||||
|
|
@ -541,6 +548,10 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
StringBuilder sql = new StringBuilder(LIST_CAPACITY_GROUP_BY_CAPACITY_PART1);
|
||||
List<Long> resourceIdList = new ArrayList<Long>();
|
||||
|
||||
// Exclude storage pools with children from capacity calculations to avoid double counting
|
||||
sql.append(" AND NOT (capacity.capacity_type = ").append(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED)
|
||||
.append(" AND capacity.host_id IN (").append(STORAGE_POOLS_WITH_CHILDREN).append("))");
|
||||
|
||||
if (zoneId != null) {
|
||||
sql.append(" AND capacity.data_center_id = ?");
|
||||
resourceIdList.add(zoneId);
|
||||
|
|
|
|||
|
|
@ -3481,6 +3481,44 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
return useBLOCKDiskType(physicalDisk) ? DiskDef.DiskType.BLOCK : DiskDef.DiskType.FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the disk configuration for the default pool type based on the provided parameters.
|
||||
* It determines the appropriate disk settings depending on whether the disk is a data disk, whether
|
||||
* it's a Windows template, whether UEFI is enabled, and whether secure boot is active.
|
||||
*
|
||||
* @param disk The disk definition object that will be configured with the disk settings.
|
||||
* @param volume The volume (disk) object, containing information about the type of disk.
|
||||
* @param isWindowsTemplate Flag indicating whether the template is a Windows template.
|
||||
* @param isUefiEnabled Flag indicating whether UEFI is enabled.
|
||||
* @param isSecureBoot Flag indicating whether secure boot is enabled.
|
||||
* @param physicalDisk The physical disk object that contains the path to the disk.
|
||||
* @param devId The device ID for the disk.
|
||||
* @param diskBusType The disk bus type to use if not skipping force disk controller.
|
||||
* @param diskBusTypeData The disk bus type to use for data disks, if applicable.
|
||||
* @param details A map of VM details containing additional configuration values, such as whether to skip force
|
||||
* disk controller.
|
||||
*/
|
||||
protected void defineDiskForDefaultPoolType(DiskDef disk, DiskTO volume, boolean isWindowsTemplate,
|
||||
boolean isUefiEnabled, boolean isSecureBoot, KVMPhysicalDisk physicalDisk, int devId,
|
||||
DiskDef.DiskBus diskBusType, DiskDef.DiskBus diskBusTypeData, Map<String, String> details) {
|
||||
boolean skipForceDiskController = MapUtils.getBoolean(details, VmDetailConstants.KVM_SKIP_FORCE_DISK_CONTROLLER,
|
||||
false);
|
||||
if (skipForceDiskController) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, Volume.Type.DATADISK.equals(volume.getType()) ?
|
||||
diskBusTypeData : diskBusType, DiskDef.DiskFmtType.QCOW2);
|
||||
return;
|
||||
}
|
||||
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
|
||||
} else {
|
||||
if (isSecureBoot) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, DiskDef.DiskFmtType.QCOW2, isWindowsTemplate);
|
||||
} else {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusType, DiskDef.DiskFmtType.QCOW2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException {
|
||||
final Map<String, String> details = vmSpec.getDetails();
|
||||
final List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
|
||||
|
|
@ -3642,15 +3680,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
disk.setDiscard(DiscardType.UNMAP);
|
||||
}
|
||||
} else {
|
||||
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
|
||||
} else {
|
||||
if (isSecureBoot) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, DiskDef.DiskFmtType.QCOW2, isWindowsTemplate);
|
||||
} else {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusType, DiskDef.DiskFmtType.QCOW2);
|
||||
}
|
||||
}
|
||||
defineDiskForDefaultPoolType(disk, volume, isWindowsTemplate, isUefiEnabled, isSecureBoot,
|
||||
physicalDisk, devId, diskBusType, diskBusTypeData, details);
|
||||
}
|
||||
pool.customizeLibvirtDiskDef(disk);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,11 +61,9 @@ import javax.xml.xpath.XPathConstants;
|
|||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants.IoDriverPolicy;
|
||||
import org.apache.cloudstack.storage.command.AttachAnswer;
|
||||
import org.apache.cloudstack.storage.command.AttachCommand;
|
||||
|
|
@ -227,13 +225,15 @@ import com.cloud.storage.template.TemplateLocation;
|
|||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.script.OutputInterpreter.OneLineParser;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.PowerState;
|
||||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LibvirtComputingResourceTest {
|
||||
|
|
@ -250,6 +250,19 @@ public class LibvirtComputingResourceTest {
|
|||
Connect connMock;
|
||||
@Mock
|
||||
LibvirtDomainXMLParser parserMock;
|
||||
@Mock
|
||||
private DiskDef diskDef;
|
||||
@Mock
|
||||
private DiskTO volume;
|
||||
@Mock
|
||||
private KVMPhysicalDisk physicalDisk;
|
||||
@Mock
|
||||
private Map<String, String> details;
|
||||
|
||||
private static final String PHYSICAL_DISK_PATH = "/path/to/disk";
|
||||
private static final int DEV_ID = 1;
|
||||
private static final DiskDef.DiskBus DISK_BUS_TYPE = DiskDef.DiskBus.VIRTIO;
|
||||
private static final DiskDef.DiskBus DISK_BUS_TYPE_DATA = DiskDef.DiskBus.SCSI;
|
||||
|
||||
@Mock
|
||||
DiskTO diskToMock;
|
||||
|
|
@ -7142,4 +7155,49 @@ public class LibvirtComputingResourceTest {
|
|||
Assert.assertEquals("-mmx", cpuFeatures.get(2));
|
||||
Assert.assertEquals("hle", cpuFeatures.get(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineDiskForDefaultPoolTypeSkipsForceDiskController() {
|
||||
Map<String, String> details = new HashMap<>();
|
||||
details.put(VmDetailConstants.KVM_SKIP_FORCE_DISK_CONTROLLER, "true");
|
||||
Mockito.when(volume.getType()).thenReturn(Volume.Type.DATADISK);
|
||||
Mockito.when(physicalDisk.getPath()).thenReturn(PHYSICAL_DISK_PATH);
|
||||
libvirtComputingResourceSpy.defineDiskForDefaultPoolType(diskDef, volume, false, false, false, physicalDisk, DEV_ID, DISK_BUS_TYPE, DISK_BUS_TYPE_DATA, details);
|
||||
Mockito.verify(diskDef).defFileBasedDisk(PHYSICAL_DISK_PATH, DEV_ID, DISK_BUS_TYPE_DATA, DiskDef.DiskFmtType.QCOW2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineDiskForDefaultPoolTypeUsesDiskBusTypeDataForDataDiskWithoutWindowsAndUefi() {
|
||||
Map<String, String> details = new HashMap<>();
|
||||
Mockito.when(volume.getType()).thenReturn(Volume.Type.DATADISK);
|
||||
Mockito.when(physicalDisk.getPath()).thenReturn(PHYSICAL_DISK_PATH);
|
||||
libvirtComputingResourceSpy.defineDiskForDefaultPoolType(diskDef, volume, false, false, false, physicalDisk, DEV_ID, DISK_BUS_TYPE, DISK_BUS_TYPE_DATA, details);
|
||||
Mockito.verify(diskDef).defFileBasedDisk(PHYSICAL_DISK_PATH, DEV_ID, DISK_BUS_TYPE_DATA, DiskDef.DiskFmtType.QCOW2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineDiskForDefaultPoolTypeUsesDiskBusTypeForRootDisk() {
|
||||
Map<String, String> details = new HashMap<>();
|
||||
Mockito.when(volume.getType()).thenReturn(Volume.Type.ROOT);
|
||||
Mockito.when(physicalDisk.getPath()).thenReturn(PHYSICAL_DISK_PATH);
|
||||
libvirtComputingResourceSpy.defineDiskForDefaultPoolType(diskDef, volume, false, false, false, physicalDisk, DEV_ID, DISK_BUS_TYPE, DISK_BUS_TYPE_DATA, details);
|
||||
Mockito.verify(diskDef).defFileBasedDisk(PHYSICAL_DISK_PATH, DEV_ID, DISK_BUS_TYPE, DiskDef.DiskFmtType.QCOW2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineDiskForDefaultPoolTypeUsesSecureBootConfiguration() {
|
||||
Map<String, String> details = new HashMap<>();
|
||||
Mockito.when(volume.getType()).thenReturn(Volume.Type.ROOT);
|
||||
Mockito.when(physicalDisk.getPath()).thenReturn(PHYSICAL_DISK_PATH);
|
||||
libvirtComputingResourceSpy.defineDiskForDefaultPoolType(diskDef, volume, true, true, true, physicalDisk, DEV_ID, DISK_BUS_TYPE, DISK_BUS_TYPE_DATA, details);
|
||||
Mockito.verify(diskDef).defFileBasedDisk(PHYSICAL_DISK_PATH, DEV_ID, DiskDef.DiskFmtType.QCOW2, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defineDiskForDefaultPoolTypeHandlesNullDetails() {
|
||||
Mockito.when(volume.getType()).thenReturn(Volume.Type.DATADISK);
|
||||
Mockito.when(physicalDisk.getPath()).thenReturn(PHYSICAL_DISK_PATH);
|
||||
libvirtComputingResourceSpy.defineDiskForDefaultPoolType(diskDef, volume, false, false, false, physicalDisk, DEV_ID, DISK_BUS_TYPE, DISK_BUS_TYPE_DATA, null);
|
||||
Mockito.verify(diskDef).defFileBasedDisk(PHYSICAL_DISK_PATH, DEV_ID, DISK_BUS_TYPE_DATA, DiskDef.DiskFmtType.QCOW2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5390,6 +5390,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
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());
|
||||
options.put(VmDetailConstants.KVM_SKIP_FORCE_DISK_CONTROLLER, Arrays.asList("true", "false"));
|
||||
}
|
||||
|
||||
if (HypervisorType.VMware.equals(hypervisorType)) {
|
||||
|
|
|
|||
|
|
@ -2457,7 +2457,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
}
|
||||
}
|
||||
|
||||
if (volume != null && ImageFormat.QCOW2.equals(volume.getFormat()) && !Volume.State.Allocated.equals(volume.getState()) && !StoragePoolType.StorPool.equals(volume.getPoolType())) {
|
||||
if (volume != null && ImageFormat.QCOW2.equals(volume.getFormat()) && !Volume.State.Allocated.equals(volume.getState()) &&
|
||||
!Arrays.asList(StoragePoolType.StorPool, StoragePoolType.Linstor).contains(volume.getPoolType())) {
|
||||
String message = "Unable to shrink volumes of type QCOW2";
|
||||
logger.warn(message);
|
||||
throw new InvalidParameterValueException(message);
|
||||
|
|
|
|||
Loading…
Reference in New Issue