mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.20' of https://github.com/apache/cloudstack
This commit is contained in:
commit
2df1ac5106
@ -16,52 +16,55 @@
|
||||
// under the License.
|
||||
package com.cloud.cpu;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CPU {
|
||||
public enum CPUArch {
|
||||
x86("i686", 32),
|
||||
amd64("x86_64", 64),
|
||||
arm64("aarch64", 64);
|
||||
|
||||
public static final String archX86Identifier = "i686";
|
||||
public static final String archX86_64Identifier = "x86_64";
|
||||
public static final String archARM64Identifier = "aarch64";
|
||||
private final String type;
|
||||
private final int bits;
|
||||
|
||||
public static class CPUArch {
|
||||
private static final Map<String, CPUArch> cpuArchMap = new LinkedHashMap<>();
|
||||
|
||||
public static final CPUArch archX86 = new CPUArch(archX86Identifier, 32);
|
||||
public static final CPUArch amd64 = new CPUArch(archX86_64Identifier, 64);
|
||||
public static final CPUArch arm64 = new CPUArch(archARM64Identifier, 64);
|
||||
|
||||
private String type;
|
||||
private int bits;
|
||||
|
||||
public CPUArch(String type, int bits) {
|
||||
CPUArch(String type, int bits) {
|
||||
this.type = type;
|
||||
this.bits = bits;
|
||||
cpuArchMap.put(type, this);
|
||||
}
|
||||
|
||||
public static CPUArch getDefault() {
|
||||
return amd64;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return this.type;
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getBits() {
|
||||
return this.bits;
|
||||
return bits;
|
||||
}
|
||||
|
||||
public static CPUArch fromType(String type) {
|
||||
if (StringUtils.isBlank(type)) {
|
||||
return amd64;
|
||||
return getDefault();
|
||||
}
|
||||
switch (type) {
|
||||
case archX86Identifier: return archX86;
|
||||
case archX86_64Identifier: return amd64;
|
||||
case archARM64Identifier: return arm64;
|
||||
default: throw new CloudRuntimeException(String.format("Unsupported arch type: %s", type));
|
||||
for (CPUArch arch : values()) {
|
||||
if (arch.type.equals(type)) {
|
||||
return arch;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported arch type: " + type);
|
||||
}
|
||||
|
||||
public static String getTypesAsCSV() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (CPUArch arch : values()) {
|
||||
sb.append(arch.getType()).append(",");
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
sb.setLength(sb.length() - 1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -485,12 +485,11 @@ public class ApiConstants {
|
||||
public static final String STATE = "state";
|
||||
public static final String STATS = "stats";
|
||||
public static final String STATUS = "status";
|
||||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String STORAGE_POLICY = "storagepolicy";
|
||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
||||
public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
|
||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||
public static final String STORAGE_POLICY = "storagepolicy";
|
||||
public static final String STORAGE_POOL = "storagepool";
|
||||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String SUBNET = "subnet";
|
||||
public static final String OWNER = "owner";
|
||||
public static final String SWAP_OWNER = "swapowner";
|
||||
|
||||
@ -19,7 +19,6 @@ package org.apache.cloudstack.api.command.admin.cluster;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
@ -28,7 +27,9 @@ import org.apache.cloudstack.api.response.ClusterResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
@ -68,6 +69,11 @@ public class ListClustersCmd extends BaseListCmd {
|
||||
@Parameter(name = ApiConstants.SHOW_CAPACITIES, type = CommandType.BOOLEAN, description = "flag to display the capacity of the clusters")
|
||||
private Boolean showCapacities;
|
||||
|
||||
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||
description = "CPU arch of the clusters",
|
||||
since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -112,6 +118,10 @@ public class ListClustersCmd extends BaseListCmd {
|
||||
return showCapacities;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -21,7 +21,6 @@ import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -35,7 +34,9 @@ import org.apache.cloudstack.api.response.ManagementServerResponse;
|
||||
import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
@ -109,6 +110,9 @@ public class ListHostsCmd extends BaseListCmd {
|
||||
@Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID, type = CommandType.UUID, entityType = ManagementServerResponse.class, description = "the id of the management server", since="4.21.0")
|
||||
private Long managementServerId;
|
||||
|
||||
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING, description = "CPU Arch of the host", since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -197,6 +201,10 @@ public class ListHostsCmd extends BaseListCmd {
|
||||
return managementServerId;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -16,8 +16,6 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.router;
|
||||
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -32,7 +30,10 @@ import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.network.router.VirtualRouter.Role;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
@ -86,6 +87,11 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd {
|
||||
description = "if true is passed for this parameter, also fetch last executed health check results for the router. Default is false")
|
||||
private Boolean fetchHealthCheckResults;
|
||||
|
||||
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||
description = "CPU arch of the router",
|
||||
since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -146,6 +152,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd {
|
||||
return BooleanUtils.isTrue(fetchHealthCheckResults);
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
|
||||
@ -19,7 +19,6 @@ package org.apache.cloudstack.api.command.admin.systemvm;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -31,7 +30,9 @@ import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||
import org.apache.cloudstack.api.response.SystemVmResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
@ -74,6 +75,11 @@ public class ListSystemVMsCmd extends BaseListCmd {
|
||||
since = "3.0.1")
|
||||
private Long storageId;
|
||||
|
||||
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||
description = "CPU arch of the system VM",
|
||||
since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -110,6 +116,10 @@ public class ListSystemVMsCmd extends BaseListCmd {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -46,9 +46,11 @@ import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.server.ResourceIcon;
|
||||
import com.cloud.server.ResourceTag;
|
||||
@ -153,6 +155,11 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
|
||||
@Parameter(name = ApiConstants.USER_DATA_ID, type = CommandType.UUID, entityType = UserDataResponse.class, required = false, description = "the instances by userdata", since = "4.20.1")
|
||||
private Long userdataId;
|
||||
|
||||
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||
description = "CPU arch of the VM",
|
||||
since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -292,6 +299,10 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
|
||||
return isVnf;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -245,6 +245,10 @@ public class DomainRouterResponse extends BaseResponseWithAnnotations implements
|
||||
@Param(description = "the version of the code / software in the router")
|
||||
private String softwareVersion;
|
||||
|
||||
@SerializedName(ApiConstants.ARCH)
|
||||
@Param(description = "CPU arch of the router", since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
public DomainRouterResponse() {
|
||||
nics = new LinkedHashSet<NicResponse>();
|
||||
}
|
||||
@ -518,4 +522,8 @@ public class DomainRouterResponse extends BaseResponseWithAnnotations implements
|
||||
public void setSoftwareVersion(String softwareVersion) {
|
||||
this.softwareVersion = softwareVersion;
|
||||
}
|
||||
|
||||
public void setArch(String arch) {
|
||||
this.arch = arch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
||||
@Deprecated
|
||||
@SerializedName("memoryallocated")
|
||||
@Param(description = "the amount of the host's memory currently allocated")
|
||||
private Long memoryAllocated;
|
||||
private long memoryAllocated;
|
||||
|
||||
@SerializedName("memoryallocatedpercentage")
|
||||
@Param(description = "the amount of the host's memory currently allocated in percentage")
|
||||
@ -415,7 +415,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
||||
this.memWithOverprovisioning=memWithOverprovisioning;
|
||||
}
|
||||
|
||||
public void setMemoryAllocated(Long memoryAllocated) {
|
||||
public void setMemoryAllocated(long memoryAllocated) {
|
||||
this.memoryAllocated = memoryAllocated;
|
||||
}
|
||||
|
||||
@ -703,8 +703,8 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
||||
return memoryTotal;
|
||||
}
|
||||
|
||||
public Long getMemoryAllocated() {
|
||||
return memoryAllocated == null ? 0 : memoryAllocated;
|
||||
public long getMemoryAllocated() {
|
||||
return memoryAllocated;
|
||||
}
|
||||
|
||||
public void setMemoryAllocatedPercentage(String memoryAllocatedPercentage) {
|
||||
|
||||
@ -186,6 +186,10 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
|
||||
@Param(description = "the name of the service offering of the system virtual machine.")
|
||||
private String serviceOfferingName;
|
||||
|
||||
@SerializedName(ApiConstants.ARCH)
|
||||
@Param(description = "CPU arch of the system VM", since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
@Override
|
||||
public String getObjectId() {
|
||||
return this.getId();
|
||||
@ -490,4 +494,8 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
|
||||
public void setServiceOfferingName(String serviceOfferingName) {
|
||||
this.serviceOfferingName = serviceOfferingName;
|
||||
}
|
||||
|
||||
public void setArch(String arch) {
|
||||
this.arch = arch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,13 +31,13 @@ import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
|
||||
@ -396,6 +396,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
@Param(description = "User VM type", since = "4.20.0")
|
||||
private String vmType;
|
||||
|
||||
@SerializedName(ApiConstants.ARCH)
|
||||
@Param(description = "CPU arch of the VM", since = "4.20.1")
|
||||
private String arch;
|
||||
|
||||
public UserVmResponse() {
|
||||
securityGroupList = new LinkedHashSet<>();
|
||||
nics = new TreeSet<>(Comparator.comparingInt(x -> Integer.parseInt(x.getDeviceId())));
|
||||
@ -1169,4 +1173,12 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public String getArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public void setArch(String arch) {
|
||||
this.arch = arch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
67
api/src/test/java/com/cloud/cpu/CPUTest.java
Normal file
67
api/src/test/java/com/cloud/cpu/CPUTest.java
Normal file
@ -0,0 +1,67 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.cpu;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CPUTest {
|
||||
@Test
|
||||
public void testCPUArchGetType() {
|
||||
assertEquals("i686", CPU.CPUArch.x86.getType());
|
||||
assertEquals("x86_64", CPU.CPUArch.amd64.getType());
|
||||
assertEquals("aarch64", CPU.CPUArch.arm64.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCPUArchGetBits() {
|
||||
assertEquals(32, CPU.CPUArch.x86.getBits());
|
||||
assertEquals(64, CPU.CPUArch.amd64.getBits());
|
||||
assertEquals(64, CPU.CPUArch.arm64.getBits());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCPUArchFromTypeWithValidValues() {
|
||||
assertEquals(CPU.CPUArch.x86, CPU.CPUArch.fromType("i686"));
|
||||
assertEquals(CPU.CPUArch.amd64, CPU.CPUArch.fromType("x86_64"));
|
||||
assertEquals(CPU.CPUArch.arm64, CPU.CPUArch.fromType("aarch64"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCPUArchFromTypeWithDefaultForBlankOrNull() {
|
||||
assertEquals(CPU.CPUArch.amd64, CPU.CPUArch.fromType(""));
|
||||
assertEquals(CPU.CPUArch.amd64, CPU.CPUArch.fromType(" "));
|
||||
assertEquals(CPU.CPUArch.amd64, CPU.CPUArch.fromType(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCPUArchFromTypeWithInvalidValue() {
|
||||
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
|
||||
CPU.CPUArch.fromType("unsupported");
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Unsupported arch type: unsupported"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCPUArchGetTypesAsCSV() {
|
||||
String expectedCSV = "i686,x86_64,aarch64";
|
||||
assertEquals(expectedCSV, CPU.CPUArch.getTypesAsCSV());
|
||||
}
|
||||
}
|
||||
2
debian/cloudstack-management.postinst
vendored
2
debian/cloudstack-management.postinst
vendored
@ -56,6 +56,8 @@ if [ "$1" = configure ]; then
|
||||
chmod 0640 ${CONFDIR}/${DBPROPS}
|
||||
chgrp cloud ${CONFDIR}/${DBPROPS}
|
||||
chown -R cloud:cloud /var/log/cloudstack/management
|
||||
chown -R cloud:cloud /usr/share/cloudstack-management/templates
|
||||
find /usr/share/cloudstack-management/templates -type d -exec chmod 0770 {} \;
|
||||
|
||||
ln -sf ${CONFDIR}/log4j-cloud.xml ${CONFDIR}/log4j2.xml
|
||||
|
||||
|
||||
@ -309,4 +309,8 @@ public interface VirtualMachineManager extends Manager {
|
||||
|
||||
Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long> diskOfferingIds);
|
||||
|
||||
void checkDeploymentPlan(VirtualMachine virtualMachine, VirtualMachineTemplate template,
|
||||
ServiceOffering serviceOffering, Account systemAccount, DeploymentPlan plan)
|
||||
throws InsufficientServerCapacityException;
|
||||
|
||||
}
|
||||
|
||||
@ -25,14 +25,16 @@ import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.events.Event;
|
||||
import org.apache.cloudstack.framework.events.EventBus;
|
||||
import org.apache.cloudstack.framework.events.EventDistributor;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
@ -243,4 +245,22 @@ public class UsageEventUtils {
|
||||
|
||||
static final String Name = "management-server";
|
||||
|
||||
public static void publishNetworkCreation(Network network) {
|
||||
publishUsageEvent(EventTypes.EVENT_NETWORK_CREATE, network.getAccountId(), network.getDataCenterId(),
|
||||
network.getId(), network.getName(), network.getNetworkOfferingId(), null, null, null, network.getState().name(),
|
||||
network.getUuid());
|
||||
}
|
||||
|
||||
public static void publishNetworkUpdate(Network network) {
|
||||
publishUsageEvent(EventTypes.EVENT_NETWORK_UPDATE, network.getAccountId(), network.getDataCenterId(),
|
||||
network.getId(), network.getName(), network.getNetworkOfferingId(), null, network.getState().name(),
|
||||
Network.class.getName(), network.getUuid(), true);
|
||||
}
|
||||
|
||||
public static void publishNetworkDeletion(Network network) {
|
||||
publishUsageEvent(EventTypes.EVENT_NETWORK_DELETE, network.getAccountId(), network.getDataCenterId(),
|
||||
network.getId(), network.getName(), network.getNetworkOfferingId(), null, null, null,
|
||||
Network.class.getName(), network.getUuid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.agent.api.VgpuTypesInfo;
|
||||
import com.cloud.agent.api.to.GPUDeviceTO;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.PodCluster;
|
||||
@ -61,6 +62,17 @@ public interface ResourceManager extends ResourceService, Configurable {
|
||||
+ "To force-stop VMs, choose 'ForceStop' strategy",
|
||||
true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.Select, "Error,Migration,ForceStop");
|
||||
|
||||
ConfigKey<String> SystemVmPreferredArchitecture = new ConfigKey<>(
|
||||
String.class,
|
||||
"system.vm.preferred.architecture",
|
||||
"Advanced",
|
||||
CPU.CPUArch.getDefault().getType(),
|
||||
"Preferred architecture for the system VMs including virtual routers",
|
||||
true,
|
||||
ConfigKey.Scope.Zone, null, null, null, null, null,
|
||||
ConfigKey.Kind.Select,
|
||||
"," + CPU.CPUArch.getTypesAsCSV());
|
||||
|
||||
/**
|
||||
* Register a listener for different types of resource life cycle events.
|
||||
* There can only be one type of listener per type of host.
|
||||
|
||||
@ -6083,4 +6083,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkDeploymentPlan(VirtualMachine virtualMachine, VirtualMachineTemplate template,
|
||||
ServiceOffering serviceOffering, Account systemAccount, DeploymentPlan plan)
|
||||
throws InsufficientServerCapacityException {
|
||||
final VirtualMachineProfileImpl vmProfile =
|
||||
new VirtualMachineProfileImpl(virtualMachine, template, serviceOffering, systemAccount, null);
|
||||
DeployDestination destination =
|
||||
_dpMgr.planDeployment(vmProfile, plan, new DeploymentPlanner.ExcludeList(), null);
|
||||
if (destination == null) {
|
||||
throw new InsufficientServerCapacityException(String.format("Unable to create a deployment for %s",
|
||||
vmProfile), DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1528,8 +1528,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
if (isNetworkImplemented(network)) {
|
||||
logger.debug("Network {} is already implemented", network);
|
||||
implemented.set(guru, network);
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_UPDATE, network.getAccountId(), network.getDataCenterId(), network.getId(),
|
||||
network.getName(), network.getNetworkOfferingId(), null, network.getState().name(), Network.class.getName(), network.getUuid(), true);
|
||||
return implemented;
|
||||
}
|
||||
|
||||
@ -1585,9 +1583,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
|
||||
network.setRestartRequired(false);
|
||||
_networksDao.update(network.getId(), network);
|
||||
UsageEventUtils.publishNetworkUpdate(network);
|
||||
implemented.set(guru, network);
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_CREATE, network.getAccountId(), network.getDataCenterId(), network.getId(),
|
||||
network.getName(), network.getNetworkOfferingId(), null, null, null, network.getState().name(), network.getUuid());
|
||||
return implemented;
|
||||
} catch (final NoTransitionException e) {
|
||||
logger.error(e.getMessage());
|
||||
@ -3087,6 +3084,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
if (updateResourceCount) {
|
||||
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
|
||||
}
|
||||
UsageEventUtils.publishNetworkCreation(network);
|
||||
|
||||
return network;
|
||||
}
|
||||
@ -3168,13 +3166,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
}
|
||||
logger.debug("Lock is acquired for network {} as a part of network shutdown", network);
|
||||
|
||||
if (network.getState() == Network.State.Allocated) {
|
||||
logger.debug("Network is already shutdown: {}", network);
|
||||
final Network.State initialState = network.getState();
|
||||
if (initialState == Network.State.Allocated) {
|
||||
logger.debug(String.format("Network [%s] is in Allocated state, no need to shutdown.", network));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
|
||||
logger.debug("Network is not implemented: {}", network);
|
||||
if (initialState != Network.State.Implemented && initialState != Network.State.Shutdown) {
|
||||
logger.debug("Network is not implemented: " + network);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3218,6 +3217,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
}
|
||||
_networksDao.update(networkFinal.getId(), networkFinal);
|
||||
_networksDao.clearCheckForGc(networkId);
|
||||
if (initialState == Network.State.Implemented) {
|
||||
UsageEventUtils.publishNetworkUpdate(networkFinal);
|
||||
}
|
||||
result = true;
|
||||
} else {
|
||||
try {
|
||||
@ -3469,8 +3471,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
final Pair<Class<?>, Long> networkMsg = new Pair<Class<?>, Long>(Network.class, networkFinal.getId());
|
||||
_messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg);
|
||||
}
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_DELETE, network.getAccountId(), network.getDataCenterId(), network.getId(),
|
||||
network.getName(), network.getNetworkOfferingId(), null, null, null, Network.class.getName(), network.getUuid());
|
||||
UsageEventUtils.publishNetworkDeletion(network);
|
||||
return true;
|
||||
} catch (final CloudRuntimeException e) {
|
||||
logger.error("Failed to delete network", e);
|
||||
|
||||
@ -891,7 +891,7 @@ public class NetworkOrchestratorTest extends TestCase {
|
||||
boolean shutdownNetworkStatus = testOrchestrator.shutdownNetwork(networkId, reservationContext, false);
|
||||
Assert.assertFalse(shutdownNetworkStatus);
|
||||
|
||||
verify(network, times(3)).getState();
|
||||
verify(network).getState();
|
||||
verify(testOrchestrator._networksDao, times(1)).acquireInLockTable(networkId, NetworkLockTimeout.value());
|
||||
verify(testOrchestrator._networksDao, times(1)).releaseFromLockTable(networkId);
|
||||
}
|
||||
|
||||
@ -165,6 +165,15 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mode>true</test.mode>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
|
||||
@ -18,11 +18,11 @@ package com.cloud.dc.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
||||
@ -30,13 +30,11 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
||||
|
||||
ClusterVO findBy(String name, long podId);
|
||||
|
||||
List<ClusterVO> listByHyTypeWithoutGuid(String hyType);
|
||||
|
||||
List<ClusterVO> listByZoneId(long zoneId);
|
||||
|
||||
List<HypervisorType> getAvailableHypervisorInZone(Long zoneId);
|
||||
|
||||
Set<HypervisorType> getDistinctAvailableHypervisorsAcrossClusters();
|
||||
List<Pair<HypervisorType, CPU.CPUArch>> listDistinctHypervisorsArchAcrossClusters(Long zoneId);
|
||||
|
||||
List<ClusterVO> listByDcHyType(long dcId, String hyType);
|
||||
|
||||
|
||||
@ -21,10 +21,8 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -39,6 +37,7 @@ import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.org.Managed;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
@ -148,14 +147,6 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClusterVO> listByHyTypeWithoutGuid(String hyType) {
|
||||
SearchCriteria<ClusterVO> sc = HyTypeWithoutGuidSearch.create();
|
||||
sc.setParameters("hypervisorType", hyType);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClusterVO> listByDcHyType(long dcId, String hyType) {
|
||||
SearchCriteria<ClusterVO> sc = ZoneHyTypeSearch.create();
|
||||
@ -178,8 +169,19 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<HypervisorType> getDistinctAvailableHypervisorsAcrossClusters() {
|
||||
return new HashSet<>(getAvailableHypervisorInZone(null));
|
||||
public List<Pair<HypervisorType, CPU.CPUArch>> listDistinctHypervisorsArchAcrossClusters(Long zoneId) {
|
||||
SearchBuilder<ClusterVO> sb = createSearchBuilder();
|
||||
sb.select(null, Func.DISTINCT_PAIR, sb.entity().getHypervisorType(), sb.entity().getArch());
|
||||
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<ClusterVO> sc = sb.create();
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
final List<ClusterVO> clusters = search(sc, null);
|
||||
return clusters.stream()
|
||||
.map(c -> new Pair<>(c.getHypervisorType(), c.getArch()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -19,6 +19,7 @@ package com.cloud.host.dao;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.host.HostVO;
|
||||
@ -212,5 +213,9 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
||||
|
||||
List<HypervisorType> listDistinctHypervisorTypes(final Long zoneId);
|
||||
|
||||
List<Pair<HypervisorType, CPU.CPUArch>> listDistinctHypervisorArchTypes(final Long zoneId);
|
||||
|
||||
List<CPU.CPUArch> listDistinctArchTypes(final Long clusterId);
|
||||
|
||||
List<HostVO> listByIds(final List<Long> ids);
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ import com.cloud.agent.api.VgpuTypesInfo;
|
||||
import com.cloud.cluster.agentlb.HostTransferMapVO;
|
||||
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
|
||||
import com.cloud.configuration.ManagementServiceConfiguration;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
||||
@ -1795,17 +1796,52 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
||||
|
||||
@Override
|
||||
public List<HypervisorType> listDistinctHypervisorTypes(final Long zoneId) {
|
||||
GenericSearchBuilder<HostVO, HypervisorType> sb = createSearchBuilder(HypervisorType.class);
|
||||
GenericSearchBuilder<HostVO, String> sb = createSearchBuilder(String.class);
|
||||
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.select(null, Func.DISTINCT, sb.entity().getHypervisorType());
|
||||
sb.done();
|
||||
SearchCriteria<HypervisorType> sc = sb.create();
|
||||
SearchCriteria<String> sc = sb.create();
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
sc.setParameters("type", Type.Routing);
|
||||
return customSearch(sc, null);
|
||||
List<String> hypervisorString = customSearch(sc, null);
|
||||
return hypervisorString.stream().map(HypervisorType::getType).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<HypervisorType, CPU.CPUArch>> listDistinctHypervisorArchTypes(final Long zoneId) {
|
||||
SearchBuilder<HostVO> sb = createSearchBuilder();
|
||||
sb.select(null, Func.DISTINCT_PAIR, sb.entity().getHypervisorType(), sb.entity().getArch());
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<HostVO> sc = sb.create();
|
||||
sc.setParameters("type", Type.Routing);
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
final List<HostVO> hosts = search(sc, null);
|
||||
return hosts.stream()
|
||||
.map(h -> new Pair<>(h.getHypervisorType(), h.getArch()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CPU.CPUArch> listDistinctArchTypes(final Long clusterId) {
|
||||
GenericSearchBuilder<HostVO, String> sb = createSearchBuilder(String.class);
|
||||
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.select(null, Func.DISTINCT, sb.entity().getArch());
|
||||
sb.done();
|
||||
SearchCriteria<String> sc = sb.create();
|
||||
if (clusterId != null) {
|
||||
sc.setParameters("clusterId", clusterId);
|
||||
}
|
||||
sc.setParameters("type", Type.Routing);
|
||||
List<String> archStrings = customSearch(sc, null);
|
||||
return archStrings.stream().map(CPU.CPUArch::fromType).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -19,6 +19,7 @@ package com.cloud.storage.dao;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
@ -73,9 +74,13 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
||||
|
||||
VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType);
|
||||
|
||||
List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType, String preferredArch);
|
||||
|
||||
VMTemplateVO findRoutingTemplate(HypervisorType type, String templateName);
|
||||
|
||||
VMTemplateVO findLatestTemplateByTypeAndHypervisor(HypervisorType hypervisorType, Storage.TemplateType type);
|
||||
List<VMTemplateVO> findRoutingTemplates(HypervisorType type, String templateName, String preferredArch);
|
||||
|
||||
VMTemplateVO findLatestTemplateByTypeAndHypervisorAndArch(HypervisorType hypervisorType, CPU.CPUArch arch, Storage.TemplateType type);
|
||||
|
||||
public Long countTemplatesForAccount(long accountId);
|
||||
|
||||
@ -87,7 +92,7 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
||||
|
||||
List<VMTemplateVO> listByParentTemplatetId(long parentTemplatetId);
|
||||
|
||||
VMTemplateVO findLatestTemplateByName(String name);
|
||||
VMTemplateVO findLatestTemplateByName(String name, CPU.CPUArch arch);
|
||||
|
||||
List<VMTemplateVO> findTemplatesLinkedToUserdata(long userdataId);
|
||||
|
||||
|
||||
@ -18,7 +18,9 @@ package com.cloud.storage.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -28,8 +30,10 @@ import javax.naming.ConfigurationException;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.host.Host;
|
||||
@ -47,6 +51,7 @@ import com.cloud.storage.VMTemplateZoneVO;
|
||||
import com.cloud.tags.ResourceTagVO;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
@ -111,6 +116,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
||||
LatestTemplateByHypervisorTypeSearch = createSearchBuilder();
|
||||
LatestTemplateByHypervisorTypeSearch.and("hypervisorType", LatestTemplateByHypervisorTypeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
LatestTemplateByHypervisorTypeSearch.and("templateType", LatestTemplateByHypervisorTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
|
||||
LatestTemplateByHypervisorTypeSearch.and("arch", LatestTemplateByHypervisorTypeSearch.entity().getArch(), SearchCriteria.Op.EQ);
|
||||
LatestTemplateByHypervisorTypeSearch.and("removed", LatestTemplateByHypervisorTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
}
|
||||
|
||||
@ -238,10 +244,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
||||
|
||||
|
||||
@Override
|
||||
public VMTemplateVO findLatestTemplateByName(String name) {
|
||||
SearchCriteria<VMTemplateVO> sc = createSearchCriteria();
|
||||
sc.addAnd("name", SearchCriteria.Op.EQ, name);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
public VMTemplateVO findLatestTemplateByName(String name, CPU.CPUArch arch) {
|
||||
SearchBuilder<VMTemplateVO> sb = createSearchBuilder();
|
||||
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
|
||||
sb.and("arch", sb.entity().getArch(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<VMTemplateVO> sc = sb.create();
|
||||
sc.setParameters("name", name);
|
||||
if (arch != null) {
|
||||
sc.setParameters("arch", arch);
|
||||
}
|
||||
Filter filter = new Filter(VMTemplateVO.class, "id", false, null, 1L);
|
||||
List<VMTemplateVO> templates = listBy(sc, filter);
|
||||
if ((templates != null) && !templates.isEmpty()) {
|
||||
@ -580,6 +592,59 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
protected List<VMTemplateVO> getSortedTemplatesListWithPreferredArch(
|
||||
Map<Pair<HypervisorType, CPU.CPUArch>, VMTemplateVO> uniqueTemplates, String preferredArch) {
|
||||
List<VMTemplateVO> result = new ArrayList<>(uniqueTemplates.values());
|
||||
if (StringUtils.isNotBlank(preferredArch)) {
|
||||
result.sort((t1, t2) -> {
|
||||
boolean t1Preferred = t1.getArch().getType().equalsIgnoreCase(preferredArch);
|
||||
boolean t2Preferred = t2.getArch().getType().equalsIgnoreCase(preferredArch);
|
||||
if (t1Preferred && !t2Preferred) {
|
||||
return -1; // t1 comes before t2
|
||||
} else if (!t1Preferred && t2Preferred) {
|
||||
return 1; // t2 comes before t1
|
||||
} else {
|
||||
// Both are either preferred or not preferred; use template id as a secondary sorting key.
|
||||
return Long.compare(t1.getId(), t2.getId());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
result.sort(Comparator.comparing(VMTemplateVO::getId).reversed());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType,
|
||||
String preferredArch) {
|
||||
List<Pair<HypervisorType, CPU.CPUArch>> availableHypervisors = _hostDao.listDistinctHypervisorArchTypes(zoneId);
|
||||
if (CollectionUtils.isEmpty(availableHypervisors)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
SearchCriteria<VMTemplateVO> sc = readySystemTemplateSearch.create();
|
||||
sc.setParameters("templateType", Storage.TemplateType.SYSTEM);
|
||||
sc.setParameters("state", VirtualMachineTemplate.State.Active);
|
||||
if (hypervisorType != null && !HypervisorType.Any.equals(hypervisorType)) {
|
||||
sc.setParameters("hypervisorType", List.of(hypervisorType).toArray());
|
||||
} else {
|
||||
sc.setParameters("hypervisorType",
|
||||
availableHypervisors.stream().map(Pair::first).distinct().toArray());
|
||||
}
|
||||
sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState",
|
||||
List.of(VMTemplateStorageResourceAssoc.Status.DOWNLOADED,
|
||||
VMTemplateStorageResourceAssoc.Status.BYPASSED).toArray());
|
||||
// order by descending order of id
|
||||
List<VMTemplateVO> templates = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null));
|
||||
Map<Pair<HypervisorType, CPU.CPUArch>, VMTemplateVO> uniqueTemplates = new HashMap<>();
|
||||
for (VMTemplateVO template : templates) {
|
||||
Pair<HypervisorType, CPU.CPUArch> key = new Pair<>(template.getHypervisorType(), template.getArch());
|
||||
if (availableHypervisors.contains(key) && !uniqueTemplates.containsKey(key)) {
|
||||
uniqueTemplates.put(key, template);
|
||||
}
|
||||
}
|
||||
return getSortedTemplatesListWithPreferredArch(uniqueTemplates, preferredArch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMTemplateVO findRoutingTemplate(HypervisorType hType, String templateName) {
|
||||
SearchCriteria<VMTemplateVO> sc = tmpltTypeHyperSearch2.create();
|
||||
@ -618,10 +683,43 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMTemplateVO findLatestTemplateByTypeAndHypervisor(HypervisorType hypervisorType, TemplateType type) {
|
||||
public List<VMTemplateVO> findRoutingTemplates(HypervisorType hType, String templateName, String preferredArch) {
|
||||
SearchCriteria<VMTemplateVO> sc = tmpltTypeHyperSearch2.create();
|
||||
sc.setParameters("templateType", TemplateType.ROUTING);
|
||||
sc.setParameters("hypervisorType", hType);
|
||||
sc.setParameters("state", VirtualMachineTemplate.State.Active.toString());
|
||||
if (templateName != null) {
|
||||
sc.setParameters("templateName", templateName);
|
||||
}
|
||||
List<VMTemplateVO> templates = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1L));
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
sc = tmpltTypeHyperSearch2.create();
|
||||
sc.setParameters("templateType", TemplateType.SYSTEM);
|
||||
sc.setParameters("hypervisorType", hType);
|
||||
sc.setParameters("state", VirtualMachineTemplate.State.Active.toString());
|
||||
if (templateName != null) {
|
||||
sc.setParameters("templateName", templateName);
|
||||
}
|
||||
templates = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1L));
|
||||
}
|
||||
Map<Pair<HypervisorType, CPU.CPUArch>, VMTemplateVO> uniqueTemplates = new HashMap<>();
|
||||
for (VMTemplateVO template : templates) {
|
||||
Pair<HypervisorType, CPU.CPUArch> key = new Pair<>(template.getHypervisorType(), template.getArch());
|
||||
if (!uniqueTemplates.containsKey(key)) {
|
||||
uniqueTemplates.put(key, template);
|
||||
}
|
||||
}
|
||||
return getSortedTemplatesListWithPreferredArch(uniqueTemplates, preferredArch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMTemplateVO findLatestTemplateByTypeAndHypervisorAndArch(HypervisorType hypervisorType, CPU.CPUArch arch, TemplateType type) {
|
||||
SearchCriteria<VMTemplateVO> sc = LatestTemplateByHypervisorTypeSearch.create();
|
||||
sc.setParameters("hypervisorType", hypervisorType);
|
||||
sc.setParameters("templateType", type);
|
||||
if (arch != null) {
|
||||
sc.setParameters("arch", arch);
|
||||
}
|
||||
Filter filter = new Filter(VMTemplateVO.class, "id", false, null, 1L);
|
||||
List<VMTemplateVO> templates = listBy(sc, filter);
|
||||
if (templates != null && !templates.isEmpty()) {
|
||||
|
||||
@ -16,6 +16,47 @@
|
||||
// under the License.
|
||||
package com.cloud.upgrade;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl;
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.cloudstack.utils.security.DigestHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.ini4j.Ini;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.ClusterDaoImpl;
|
||||
@ -36,6 +77,7 @@ import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.upgrade.dao.BasicTemplateDataStoreDaoImpl;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.HttpUtils;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.db.GlobalLock;
|
||||
@ -46,48 +88,10 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.dao.VMInstanceDaoImpl;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl;
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.cloudstack.utils.security.DigestHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.ini4j.Ini;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SystemVmTemplateRegistration {
|
||||
protected static Logger LOGGER = LogManager.getLogger(SystemVmTemplateRegistration.class);
|
||||
private static final String MOUNT_COMMAND = "sudo mount -t nfs %s %s";
|
||||
private static final String MOUNT_COMMAND_BASE = "sudo mount -t nfs";
|
||||
private static final String UMOUNT_COMMAND = "sudo umount %s";
|
||||
private static final String RELATIVE_TEMPLATE_PATH = "./engine/schema/dist/systemvm-templates/";
|
||||
private static final String ABSOLUTE_TEMPLATE_PATH = "/usr/share/cloudstack-management/templates/systemvm/";
|
||||
@ -102,6 +106,9 @@ public class SystemVmTemplateRegistration {
|
||||
private static final Integer LINUX_7_ID = 183;
|
||||
private static final Integer SCRIPT_TIMEOUT = 1800000;
|
||||
private static final Integer LOCK_WAIT_TIMEOUT = 1200;
|
||||
protected static final List<CPU.CPUArch> DOWNLOADABLE_TEMPLATE_ARCH_TYPES = Arrays.asList(
|
||||
CPU.CPUArch.arm64
|
||||
);
|
||||
|
||||
|
||||
public static String CS_MAJOR_VERSION = null;
|
||||
@ -128,6 +135,8 @@ public class SystemVmTemplateRegistration {
|
||||
|
||||
private String systemVmTemplateVersion;
|
||||
|
||||
private final File tempDownloadDir;
|
||||
|
||||
public SystemVmTemplateRegistration() {
|
||||
dataCenterDao = new DataCenterDaoImpl();
|
||||
vmTemplateDao = new VMTemplateDaoImpl();
|
||||
@ -138,6 +147,7 @@ public class SystemVmTemplateRegistration {
|
||||
imageStoreDetailsDao = new ImageStoreDetailsDaoImpl();
|
||||
clusterDao = new ClusterDaoImpl();
|
||||
configurationDao = new ConfigurationDaoImpl();
|
||||
tempDownloadDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,7 +159,7 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
|
||||
public static String getMountCommand(String nfsVersion, String device, String dir) {
|
||||
String cmd = "sudo mount -t nfs";
|
||||
String cmd = MOUNT_COMMAND_BASE;
|
||||
if (StringUtils.isNotBlank(nfsVersion)) {
|
||||
cmd = String.format("%s -o vers=%s", cmd, nfsVersion);
|
||||
}
|
||||
@ -163,6 +173,10 @@ public class SystemVmTemplateRegistration {
|
||||
return systemVmTemplateVersion;
|
||||
}
|
||||
|
||||
public File getTempDownloadDir() {
|
||||
return tempDownloadDir;
|
||||
}
|
||||
|
||||
private static class SystemVMTemplateDetails {
|
||||
Long id;
|
||||
String uuid;
|
||||
@ -174,6 +188,7 @@ public class SystemVmTemplateRegistration {
|
||||
ImageFormat format;
|
||||
Integer guestOsId;
|
||||
Hypervisor.HypervisorType hypervisorType;
|
||||
CPU.CPUArch arch;
|
||||
Long storeId;
|
||||
Long size;
|
||||
Long physicalSize;
|
||||
@ -183,7 +198,7 @@ public class SystemVmTemplateRegistration {
|
||||
|
||||
SystemVMTemplateDetails(String uuid, String name, Date created, String url, String checksum,
|
||||
ImageFormat format, Integer guestOsId, Hypervisor.HypervisorType hypervisorType,
|
||||
Long storeId) {
|
||||
CPU.CPUArch arch, Long storeId) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.created = created;
|
||||
@ -192,6 +207,7 @@ public class SystemVmTemplateRegistration {
|
||||
this.format = format;
|
||||
this.guestOsId = guestOsId;
|
||||
this.hypervisorType = hypervisorType;
|
||||
this.arch = arch;
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
@ -235,6 +251,10 @@ public class SystemVmTemplateRegistration {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
@ -288,18 +308,17 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
public static final List<Hypervisor.HypervisorType> hypervisorList = Arrays.asList(Hypervisor.HypervisorType.KVM,
|
||||
Hypervisor.HypervisorType.VMware,
|
||||
Hypervisor.HypervisorType.XenServer,
|
||||
Hypervisor.HypervisorType.Hyperv,
|
||||
Hypervisor.HypervisorType.LXC,
|
||||
Hypervisor.HypervisorType.Ovm3
|
||||
public static final List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorList = Arrays.asList(
|
||||
new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64),
|
||||
new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64),
|
||||
new Pair<>(Hypervisor.HypervisorType.VMware, null),
|
||||
new Pair<>(Hypervisor.HypervisorType.XenServer, null),
|
||||
new Pair<>(Hypervisor.HypervisorType.Hyperv, null),
|
||||
new Pair<>(Hypervisor.HypervisorType.LXC, null),
|
||||
new Pair<>(Hypervisor.HypervisorType.Ovm3, null)
|
||||
);
|
||||
|
||||
public static final Map<Hypervisor.HypervisorType, String> NewTemplateNameList = new HashMap<Hypervisor.HypervisorType, String>();
|
||||
public static final Map<Hypervisor.HypervisorType, String> FileNames = new HashMap<Hypervisor.HypervisorType, String>();
|
||||
public static final Map<Hypervisor.HypervisorType, String> NewTemplateUrl = new HashMap<Hypervisor.HypervisorType, String>();
|
||||
public static final Map<Hypervisor.HypervisorType, String> NewTemplateChecksum = new HashMap<Hypervisor.HypervisorType, String>();
|
||||
public static final Map<String, MetadataTemplateDetails> NewTemplateMap = new HashMap<>();
|
||||
|
||||
public static final Map<Hypervisor.HypervisorType, String> RouterTemplateConfigurationNames = new HashMap<Hypervisor.HypervisorType, String>() {
|
||||
{
|
||||
@ -368,55 +387,73 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
public Long getRegisteredTemplateId(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
||||
VMTemplateVO vmTemplate = vmTemplateDao.findLatestTemplateByName(hypervisorAndTemplateName.second());
|
||||
Long templateId = null;
|
||||
if (vmTemplate != null) {
|
||||
templateId = vmTemplate.getId();
|
||||
private static String getHypervisorArchLog(Hypervisor.HypervisorType hypervisorType, CPU.CPUArch arch) {
|
||||
StringBuilder sb = new StringBuilder("hypervisor: ").append(hypervisorType.name());
|
||||
if (Hypervisor.HypervisorType.KVM.equals(hypervisorType)) {
|
||||
sb.append(", arch: ").append(arch == null ? CPU.CPUArch.amd64.getType() : arch.getType());
|
||||
}
|
||||
return templateId;
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String fetchTemplatesPath() {
|
||||
String filePath = RELATIVE_TEMPLATE_PATH + METADATA_FILE_NAME;
|
||||
LOGGER.debug(String.format("Looking for file [ %s ] in the classpath.", filePath));
|
||||
File metaFile = new File(filePath);
|
||||
String templatePath = null;
|
||||
if (metaFile.exists()) {
|
||||
templatePath = RELATIVE_TEMPLATE_PATH;
|
||||
protected static String getHypervisorArchKey(Hypervisor.HypervisorType hypervisorType, CPU.CPUArch arch) {
|
||||
if (Hypervisor.HypervisorType.KVM.equals(hypervisorType)) {
|
||||
return String.format("%s-%s", hypervisorType.name().toLowerCase(),
|
||||
arch == null ? CPU.CPUArch.amd64.getType() : arch.getType());
|
||||
}
|
||||
if (templatePath == null) {
|
||||
filePath = ABSOLUTE_TEMPLATE_PATH + METADATA_FILE_NAME;
|
||||
metaFile = new File(filePath);
|
||||
templatePath = ABSOLUTE_TEMPLATE_PATH;
|
||||
LOGGER.debug(String.format("Looking for file [ %s ] in the classpath.", filePath));
|
||||
if (!metaFile.exists()) {
|
||||
String errMsg = String.format("Unable to locate metadata file in your setup at %s", filePath.toString());
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
return hypervisorType.name().toLowerCase();
|
||||
}
|
||||
|
||||
protected static MetadataTemplateDetails getMetadataTemplateDetails(Hypervisor.HypervisorType hypervisorType,
|
||||
CPU.CPUArch arch) {
|
||||
return NewTemplateMap.get(getHypervisorArchKey(hypervisorType, arch));
|
||||
}
|
||||
|
||||
public VMTemplateVO getRegisteredTemplate(String templateName, CPU.CPUArch arch) {
|
||||
return vmTemplateDao.findLatestTemplateByName(templateName, arch);
|
||||
}
|
||||
|
||||
private static boolean isRunningInTest() {
|
||||
return "true".equalsIgnoreCase(System.getProperty("test.mode"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to determine the templates directory path by locating the metadata file.
|
||||
* <p>
|
||||
* This method checks if the application is running in a test environment by invoking
|
||||
* {@code isRunningInTest()}. If so, it immediately returns the {@code RELATIVE_TEMPLATE_PATH}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Otherwise, it creates a list of candidate paths (typically including both relative and absolute
|
||||
* template paths) and iterates through them. For each candidate, it constructs the metadata file
|
||||
* path by appending {@code METADATA_FILE_NAME} to {@code RELATIVE_TEMPLATE_PATH} (note: the candidate
|
||||
* path is not used in the file path construction in this implementation) and checks if that file exists.
|
||||
* If the metadata file exists, the candidate path is returned.
|
||||
* </p>
|
||||
* <p>
|
||||
* If none of the candidate paths contain the metadata file, the method logs an error and throws a
|
||||
* {@link CloudRuntimeException}.
|
||||
* </p>
|
||||
*
|
||||
* @return the path to the templates directory if the metadata file is found, or {@code RELATIVE_TEMPLATE_PATH}
|
||||
* when running in a test environment.
|
||||
* @throws CloudRuntimeException if the metadata file cannot be located in any of the candidate paths.
|
||||
*/
|
||||
private static String fetchTemplatesPath() {
|
||||
if (isRunningInTest()) {
|
||||
return RELATIVE_TEMPLATE_PATH;
|
||||
}
|
||||
List<String> paths = Arrays.asList(RELATIVE_TEMPLATE_PATH, ABSOLUTE_TEMPLATE_PATH);
|
||||
for (String path : paths) {
|
||||
String filePath = path + METADATA_FILE_NAME;
|
||||
LOGGER.debug("Looking for file [ {} ] in the classpath.", filePath);
|
||||
File metaFile = new File(filePath);
|
||||
if (metaFile.exists()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return templatePath;
|
||||
}
|
||||
|
||||
private String getHypervisorName(String name) {
|
||||
if (name.equals("xenserver")) {
|
||||
return "xen";
|
||||
}
|
||||
if (name.equals("ovm3")) {
|
||||
return "ovm";
|
||||
}
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
private Hypervisor.HypervisorType getHypervisorType(String hypervisor) {
|
||||
if (hypervisor.equalsIgnoreCase("xen")) {
|
||||
hypervisor = "xenserver";
|
||||
} else if (hypervisor.equalsIgnoreCase("ovm")) {
|
||||
hypervisor = "ovm3";
|
||||
}
|
||||
return Hypervisor.HypervisorType.getType(hypervisor);
|
||||
String errMsg = String.format("Unable to locate metadata file in your setup at %s", StringUtils.join(paths));
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
private List<Long> getEligibleZoneIds() {
|
||||
@ -430,28 +467,28 @@ public class SystemVmTemplateRegistration {
|
||||
return zoneIds;
|
||||
}
|
||||
|
||||
private Pair<String, Long> getNfsStoreInZone(Long zoneId) {
|
||||
String url = null;
|
||||
Long storeId = null;
|
||||
protected Pair<String, Long> getNfsStoreInZone(Long zoneId) {
|
||||
ImageStoreVO storeVO = imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
|
||||
if (storeVO == null) {
|
||||
String errMsg = String.format("Failed to fetch NFS store in zone = %s for SystemVM template registration", zoneId);
|
||||
String errMsg = String.format("Failed to fetch NFS store in zone = %s for SystemVM template registration",
|
||||
zoneId);
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
url = storeVO.getUrl();
|
||||
storeId = storeVO.getId();
|
||||
String url = storeVO.getUrl();
|
||||
Long storeId = storeVO.getId();
|
||||
return new Pair<>(url, storeId);
|
||||
}
|
||||
|
||||
public static void mountStore(String storeUrl, String path, String nfsVersion) {
|
||||
try {
|
||||
if (storeUrl != null) {
|
||||
URI uri = new URI(UriUtils.encodeURIComponent(storeUrl));
|
||||
String host = uri.getHost();
|
||||
String mountPath = uri.getPath();
|
||||
Script.runSimpleBashScript(getMountCommand(nfsVersion, host + ":" + mountPath, path));
|
||||
if (storeUrl == null) {
|
||||
return;
|
||||
}
|
||||
URI uri = new URI(UriUtils.encodeURIComponent(storeUrl));
|
||||
String host = uri.getHost();
|
||||
String mountPath = uri.getPath();
|
||||
Script.runSimpleBashScript(getMountCommand(nfsVersion, host + ":" + mountPath, path));
|
||||
} catch (Exception e) {
|
||||
String msg = "NFS Store URL is not in the correct format";
|
||||
LOGGER.error(msg, e);
|
||||
@ -459,13 +496,6 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> fetchAllHypervisors(Long zoneId) {
|
||||
List<String> hypervisorList = new ArrayList<>();
|
||||
List<Hypervisor.HypervisorType> hypervisorTypes = clusterDao.getAvailableHypervisorInZone(zoneId);
|
||||
hypervisorList = hypervisorTypes.stream().distinct().map(Hypervisor.HypervisorType::name).collect(Collectors.toList());
|
||||
return hypervisorList;
|
||||
}
|
||||
|
||||
private VMTemplateVO createTemplateObjectInDB(SystemVMTemplateDetails details) {
|
||||
Long templateId = vmTemplateDao.getNextInSequence(Long.class, "id");
|
||||
VMTemplateVO template = new VMTemplateVO();
|
||||
@ -486,6 +516,7 @@ public class SystemVmTemplateRegistration {
|
||||
template.setGuestOSId(details.getGuestOsId());
|
||||
template.setCrossZones(true);
|
||||
template.setHypervisorType(details.getHypervisorType());
|
||||
template.setArch(details.getArch());
|
||||
template.setState(VirtualMachineTemplate.State.Inactive);
|
||||
template.setDeployAsIs(false);
|
||||
template = vmTemplateDao.persist(template);
|
||||
@ -627,16 +658,20 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
private void setupTemplate(String templateName, Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
|
||||
String destTempFolder) throws CloudRuntimeException {
|
||||
private void setupTemplate(String templateName, Hypervisor.HypervisorType hypervisor, CPU.CPUArch arch,
|
||||
String destTempFolder) throws CloudRuntimeException {
|
||||
String setupTmpltScript = Script.findScript(storageScriptsDir, "setup-sysvm-tmplt");
|
||||
if (setupTmpltScript == null) {
|
||||
throw new CloudRuntimeException("Unable to find the createtmplt.sh");
|
||||
}
|
||||
Script scr = new Script(setupTmpltScript, SCRIPT_TIMEOUT, LOGGER);
|
||||
scr.add("-u", templateName);
|
||||
scr.add("-f", TEMPLATES_PATH + FileNames.get(hypervisorAndTemplateName.first()));
|
||||
scr.add("-h", hypervisorAndTemplateName.first().name().toLowerCase(Locale.ROOT));
|
||||
MetadataTemplateDetails templateDetails = NewTemplateMap.get(getHypervisorArchKey(hypervisor, arch));
|
||||
String filePath = StringUtils.isNotBlank(templateDetails.getDownloadedFilePath()) ?
|
||||
templateDetails.getDownloadedFilePath() :
|
||||
templateDetails.getDefaultFilePath();
|
||||
scr.add("-f", filePath);
|
||||
scr.add("-h", hypervisor.name().toLowerCase(Locale.ROOT));
|
||||
scr.add("-d", destTempFolder);
|
||||
String result = scr.execute();
|
||||
if (result != null) {
|
||||
@ -644,17 +679,15 @@ public class SystemVmTemplateRegistration {
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Long performTemplateRegistrationOperations(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
|
||||
String url, String checksum, ImageFormat format, long guestOsId,
|
||||
Long storeId, Long templateId, String filePath, TemplateDataStoreVO templateDataStoreVO) {
|
||||
Hypervisor.HypervisorType hypervisor = hypervisorAndTemplateName.first();
|
||||
private Long performTemplateRegistrationOperations(Hypervisor.HypervisorType hypervisor,
|
||||
String name, CPU.CPUArch arch, String url, String checksum, ImageFormat format, long guestOsId,
|
||||
Long storeId, Long templateId, String filePath, TemplateDataStoreVO templateDataStoreVO) {
|
||||
String templateName = UUID.randomUUID().toString();
|
||||
Date created = new Date(DateUtil.currentGMTTime().getTime());
|
||||
SystemVMTemplateDetails details = new SystemVMTemplateDetails(templateName, hypervisorAndTemplateName.second(), created,
|
||||
url, checksum, format, (int) guestOsId, hypervisor, storeId);
|
||||
SystemVMTemplateDetails details = new SystemVMTemplateDetails(templateName, name, created,
|
||||
url, checksum, format, (int) guestOsId, hypervisor, arch, storeId);
|
||||
if (templateId == null) {
|
||||
VMTemplateVO template = createTemplateObjectInDB(details);
|
||||
if (template == null) {
|
||||
@ -671,23 +704,44 @@ public class SystemVmTemplateRegistration {
|
||||
if (templateDataStoreVO == null) {
|
||||
createTemplateStoreRefEntry(details);
|
||||
}
|
||||
setupTemplate(templateName, hypervisorAndTemplateName, destTempFolder);
|
||||
setupTemplate(templateName, hypervisor, arch, destTempFolder);
|
||||
readTemplateProperties(destTempFolder + "/template.properties", details);
|
||||
details.setUpdated(new Date(DateUtil.currentGMTTime().getTime()));
|
||||
updateTemplateDetails(details);
|
||||
return templateId;
|
||||
}
|
||||
|
||||
public void registerTemplate(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
|
||||
Pair<String, Long> storeUrlAndId, VMTemplateVO templateVO,
|
||||
TemplateDataStoreVO templateDataStoreVO, String filePath) {
|
||||
public void registerTemplate(Hypervisor.HypervisorType hypervisor, String name, Long storeId,
|
||||
VMTemplateVO templateVO, TemplateDataStoreVO templateDataStoreVO, String filePath) {
|
||||
try {
|
||||
performTemplateRegistrationOperations(hypervisor, name, templateVO.getArch(), templateVO.getUrl(),
|
||||
templateVO.getChecksum(), templateVO.getFormat(), templateVO.getGuestOSId(), storeId,
|
||||
templateVO.getId(), filePath, templateDataStoreVO);
|
||||
} catch (Exception e) {
|
||||
String errMsg = String.format("Failed to register template for hypervisor: %s", hypervisor);
|
||||
LOGGER.error(errMsg, e);
|
||||
updateTemplateTablesOnFailure(templateVO.getId());
|
||||
cleanupStore(templateVO.getId(), filePath);
|
||||
throw new CloudRuntimeException(errMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTemplateForNonExistingEntries(Hypervisor.HypervisorType hypervisor, CPU.CPUArch arch,
|
||||
String name, Pair<String, Long> storeUrlAndId, String filePath) {
|
||||
Long templateId = null;
|
||||
try {
|
||||
templateId = templateVO.getId();
|
||||
performTemplateRegistrationOperations(hypervisorAndTemplateName, templateVO.getUrl(), templateVO.getChecksum(),
|
||||
templateVO.getFormat(), templateVO.getGuestOSId(), storeUrlAndId.second(), templateId, filePath, templateDataStoreVO);
|
||||
MetadataTemplateDetails templateDetails = getMetadataTemplateDetails(hypervisor, arch);
|
||||
templateId = performTemplateRegistrationOperations(hypervisor, name,
|
||||
templateDetails.getArch(), templateDetails.getUrl(),
|
||||
templateDetails.getChecksum(), hypervisorImageFormat.get(hypervisor),
|
||||
hypervisorGuestOsMap.get(hypervisor), storeUrlAndId.second(), null, filePath, null);
|
||||
Map<String, String> configParams = new HashMap<>();
|
||||
configParams.put(RouterTemplateConfigurationNames.get(hypervisor), templateDetails.getName());
|
||||
configParams.put("minreq.sysvmtemplate.version", getSystemVmTemplateVersion());
|
||||
updateConfigurationParams(configParams);
|
||||
updateSystemVMEntries(templateId, hypervisor);
|
||||
} catch (Exception e) {
|
||||
String errMsg = String.format("Failed to register template for hypervisor: %s", hypervisorAndTemplateName.first());
|
||||
String errMsg = String.format("Failed to register template for hypervisor: %s", hypervisor);
|
||||
LOGGER.error(errMsg, e);
|
||||
if (templateId != null) {
|
||||
updateTemplateTablesOnFailure(templateId);
|
||||
@ -697,26 +751,31 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTemplate(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName, Pair<String, Long> storeUrlAndId, String filePath) {
|
||||
Long templateId = null;
|
||||
try {
|
||||
Hypervisor.HypervisorType hypervisor = hypervisorAndTemplateName.first();
|
||||
templateId = performTemplateRegistrationOperations(hypervisorAndTemplateName, NewTemplateUrl.get(hypervisor), NewTemplateChecksum.get(hypervisor),
|
||||
hypervisorImageFormat.get(hypervisor), hypervisorGuestOsMap.get(hypervisor), storeUrlAndId.second(), null, filePath, null);
|
||||
Map<String, String> configParams = new HashMap<>();
|
||||
configParams.put(RouterTemplateConfigurationNames.get(hypervisorAndTemplateName.first()), hypervisorAndTemplateName.second());
|
||||
configParams.put("minreq.sysvmtemplate.version", getSystemVmTemplateVersion());
|
||||
updateConfigurationParams(configParams);
|
||||
updateSystemVMEntries(templateId, hypervisorAndTemplateName.first());
|
||||
} catch (Exception e) {
|
||||
String errMsg = String.format("Failed to register template for hypervisor: %s", hypervisorAndTemplateName.first());
|
||||
LOGGER.error(errMsg, e);
|
||||
if (templateId != null) {
|
||||
updateTemplateTablesOnFailure(templateId);
|
||||
cleanupStore(templateId, filePath);
|
||||
}
|
||||
throw new CloudRuntimeException(errMsg, e);
|
||||
protected void validateTemplateFileForHypervisorAndArch(Hypervisor.HypervisorType hypervisor, CPU.CPUArch arch) {
|
||||
MetadataTemplateDetails templateDetails = getMetadataTemplateDetails(hypervisor, arch);
|
||||
File templateFile = getTemplateFile(templateDetails);
|
||||
if (templateFile == null) {
|
||||
throw new CloudRuntimeException("Failed to find local template file");
|
||||
}
|
||||
if (isTemplateFileChecksumDifferent(templateDetails, templateFile)) {
|
||||
throw new CloudRuntimeException("Checksum failed for local template file");
|
||||
}
|
||||
}
|
||||
|
||||
public void validateAndRegisterTemplate(Hypervisor.HypervisorType hypervisor, String name, Long storeId,
|
||||
VMTemplateVO templateVO, TemplateDataStoreVO templateDataStoreVO, String filePath) {
|
||||
validateTemplateFileForHypervisorAndArch(hypervisor, templateVO.getArch());
|
||||
registerTemplate(hypervisor, name, storeId, templateVO, templateDataStoreVO, filePath);
|
||||
}
|
||||
|
||||
public void validateAndRegisterTemplateForNonExistingEntries(Hypervisor.HypervisorType hypervisor,
|
||||
CPU.CPUArch arch, String name, Pair<String, Long> storeUrlAndId, String filePath) {
|
||||
validateTemplateFileForHypervisorAndArch(hypervisor, arch);
|
||||
registerTemplateForNonExistingEntries(hypervisor, arch, name, storeUrlAndId, filePath);
|
||||
}
|
||||
|
||||
protected static String getMetadataFilePath() {
|
||||
return METADATA_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -726,26 +785,41 @@ public class SystemVmTemplateRegistration {
|
||||
* exist a template corresponding to the current code version.
|
||||
*/
|
||||
public static String parseMetadataFile() {
|
||||
try {
|
||||
Ini ini = new Ini();
|
||||
ini.load(new FileReader(METADATA_FILE));
|
||||
for (Hypervisor.HypervisorType hypervisorType : hypervisorList) {
|
||||
String hypervisor = hypervisorType.name().toLowerCase(Locale.ROOT);
|
||||
Ini.Section section = ini.get(hypervisor);
|
||||
NewTemplateNameList.put(hypervisorType, section.get("templatename"));
|
||||
FileNames.put(hypervisorType, section.get("filename"));
|
||||
NewTemplateChecksum.put(hypervisorType, section.get("checksum"));
|
||||
NewTemplateUrl.put(hypervisorType, section.get("downloadurl"));
|
||||
}
|
||||
Ini.Section section = ini.get("default");
|
||||
return section.get("version");
|
||||
} catch (Exception e) {
|
||||
String errMsg = String.format("Failed to parse systemVM template metadata file: %s", METADATA_FILE);
|
||||
String metadataFilePath = getMetadataFilePath();
|
||||
String errMsg = String.format("Failed to parse systemVM template metadata file: %s", metadataFilePath);
|
||||
final Ini ini = new Ini();
|
||||
try (FileReader reader = new FileReader(metadataFilePath)) {
|
||||
ini.load(reader);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(errMsg, e);
|
||||
throw new CloudRuntimeException(errMsg, e);
|
||||
}
|
||||
if (!ini.containsKey("default")) {
|
||||
errMsg = String.format("%s as unable to default section", errMsg);
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
for (Pair<Hypervisor.HypervisorType, CPU.CPUArch> hypervisorType : hypervisorList) {
|
||||
String key = getHypervisorArchKey(hypervisorType.first(), hypervisorType.second());
|
||||
Ini.Section section = ini.get(key);
|
||||
if (section == null) {
|
||||
LOGGER.error("Failed to find details for {} in template metadata file: {}",
|
||||
key, metadataFilePath);
|
||||
continue;
|
||||
}
|
||||
NewTemplateMap.put(key, new MetadataTemplateDetails(
|
||||
hypervisorType.first(),
|
||||
section.get("templatename"),
|
||||
section.get("filename"),
|
||||
section.get("downloadurl"),
|
||||
section.get("checksum"),
|
||||
hypervisorType.second()));
|
||||
}
|
||||
Ini.Section defaultSection = ini.get("default");
|
||||
return defaultSection.get("version").trim();
|
||||
}
|
||||
|
||||
|
||||
private static void cleanupStore(Long templateId, String filePath) {
|
||||
String destTempFolder = filePath + PARTIAL_TEMPLATE_FOLDER + String.valueOf(templateId);
|
||||
try {
|
||||
@ -755,31 +829,60 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTemplates(Set<Hypervisor.HypervisorType> hypervisorsInUse) {
|
||||
Set<String> hypervisors = hypervisorsInUse.stream().
|
||||
map(Hypervisor.HypervisorType::name).map(name -> name.toLowerCase(Locale.ROOT)).map(this::getHypervisorName).collect(Collectors.toSet());
|
||||
List<String> templates = new ArrayList<>();
|
||||
for (Hypervisor.HypervisorType hypervisorType : hypervisorsInUse) {
|
||||
templates.add(FileNames.get(hypervisorType));
|
||||
protected File getTemplateFile(MetadataTemplateDetails templateDetails) {
|
||||
File templateFile = new File(templateDetails.getDefaultFilePath());
|
||||
if (templateFile.exists()) {
|
||||
return templateFile;
|
||||
}
|
||||
LOGGER.debug("{} is not present", templateFile.getAbsolutePath());
|
||||
if (DOWNLOADABLE_TEMPLATE_ARCH_TYPES.contains(templateDetails.getArch()) &&
|
||||
StringUtils.isNotBlank(templateDetails.getUrl())) {
|
||||
LOGGER.debug("Downloading the template file {} for {}",
|
||||
templateDetails.getUrl(), templateDetails.getHypervisorArchLog());
|
||||
Path path = Path.of(TEMPLATES_PATH);
|
||||
if (!Files.isWritable(path)) {
|
||||
templateFile = new File(tempDownloadDir, templateDetails.getFilename());
|
||||
}
|
||||
if (!templateFile.exists() &&
|
||||
!HttpUtils.downloadFileWithProgress(templateDetails.getUrl(), templateFile.getAbsolutePath(),
|
||||
LOGGER)) {
|
||||
return null;
|
||||
}
|
||||
templateDetails.setDownloadedFilePath(templateFile.getAbsolutePath());
|
||||
}
|
||||
return templateFile;
|
||||
}
|
||||
|
||||
protected boolean isTemplateFileChecksumDifferent(MetadataTemplateDetails templateDetails, File templateFile) {
|
||||
String templateChecksum = DigestHelper.calculateChecksum(templateFile);
|
||||
if (!templateChecksum.equals(templateDetails.getChecksum())) {
|
||||
LOGGER.error("Checksum {} for file {} does not match checksum {} from metadata",
|
||||
templateChecksum, templateFile, templateDetails.getChecksum());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void validateTemplates(List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsArchInUse) {
|
||||
boolean templatesFound = true;
|
||||
for (String hypervisor : hypervisors) {
|
||||
String matchedTemplate = templates.stream().filter(x -> x.contains(hypervisor)).findAny().orElse(null);
|
||||
for (Pair<Hypervisor.HypervisorType, CPU.CPUArch> hypervisorArch : hypervisorsArchInUse) {
|
||||
MetadataTemplateDetails matchedTemplate = getMetadataTemplateDetails(hypervisorArch.first(),
|
||||
hypervisorArch.second());
|
||||
if (matchedTemplate == null) {
|
||||
templatesFound = false;
|
||||
break;
|
||||
}
|
||||
|
||||
File tempFile = new File(TEMPLATES_PATH + matchedTemplate);
|
||||
String templateChecksum = DigestHelper.calculateChecksum(tempFile);
|
||||
if (!templateChecksum.equals(NewTemplateChecksum.get(getHypervisorType(hypervisor)))) {
|
||||
LOGGER.error(String.format("Checksum mismatch: %s != %s ", templateChecksum, NewTemplateChecksum.get(getHypervisorType(hypervisor))));
|
||||
File tempFile = getTemplateFile(matchedTemplate);
|
||||
if (tempFile == null) {
|
||||
LOGGER.warn("Failed to download template for {}, moving ahead",
|
||||
matchedTemplate.getHypervisorArchLog());
|
||||
continue;
|
||||
}
|
||||
if (isTemplateFileChecksumDifferent(matchedTemplate, tempFile)) {
|
||||
templatesFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!templatesFound) {
|
||||
String errMsg = "SystemVm template not found. Cannot upgrade system Vms";
|
||||
LOGGER.error(errMsg);
|
||||
@ -787,7 +890,40 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTemplates(Set<Hypervisor.HypervisorType> hypervisorsInUse) {
|
||||
protected void registerTemplatesForZone(long zoneId, String filePath) {
|
||||
Pair<String, Long> storeUrlAndId = getNfsStoreInZone(zoneId);
|
||||
String nfsVersion = getNfsVersion(storeUrlAndId.second());
|
||||
mountStore(storeUrlAndId.first(), filePath, nfsVersion);
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorArchList =
|
||||
clusterDao.listDistinctHypervisorsArchAcrossClusters(zoneId);
|
||||
for (Pair<Hypervisor.HypervisorType, CPU.CPUArch> hypervisorArch : hypervisorArchList) {
|
||||
Hypervisor.HypervisorType hypervisorType = hypervisorArch.first();
|
||||
MetadataTemplateDetails templateDetails = getMetadataTemplateDetails(hypervisorType,
|
||||
hypervisorArch.second());
|
||||
if (templateDetails == null) {
|
||||
continue;
|
||||
}
|
||||
VMTemplateVO templateVO = getRegisteredTemplate(templateDetails.getName(), templateDetails.getArch());
|
||||
if (templateVO != null) {
|
||||
TemplateDataStoreVO templateDataStoreVO =
|
||||
templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateVO.getId());
|
||||
if (templateDataStoreVO != null) {
|
||||
String installPath = templateDataStoreVO.getInstallPath();
|
||||
if (validateIfSeeded(templateDataStoreVO, storeUrlAndId.first(), installPath, nfsVersion)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
registerTemplate(hypervisorType, templateDetails.getName(), storeUrlAndId.second(), templateVO,
|
||||
templateDataStoreVO, filePath);
|
||||
updateRegisteredTemplateDetails(templateVO.getId(), templateDetails);
|
||||
continue;
|
||||
}
|
||||
registerTemplateForNonExistingEntries(hypervisorType, templateDetails.getArch(), templateDetails.getName(),
|
||||
storeUrlAndId, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTemplates(List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsArchInUse) {
|
||||
GlobalLock lock = GlobalLock.getInternLock("UpgradeDatabase-Lock");
|
||||
try {
|
||||
LOGGER.info("Grabbing lock to register templates.");
|
||||
@ -795,7 +931,7 @@ public class SystemVmTemplateRegistration {
|
||||
throw new CloudRuntimeException("Unable to acquire lock to register SystemVM template.");
|
||||
}
|
||||
try {
|
||||
validateTemplates(hypervisorsInUse);
|
||||
validateTemplates(hypervisorsArchInUse);
|
||||
// Perform Registration if templates not already registered
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
@ -808,32 +944,7 @@ public class SystemVmTemplateRegistration {
|
||||
if (filePath == null) {
|
||||
throw new CloudRuntimeException("Failed to create temporary file path to mount the store");
|
||||
}
|
||||
Pair<String, Long> storeUrlAndId = getNfsStoreInZone(zoneId);
|
||||
String nfsVersion = getNfsVersion(storeUrlAndId.second());
|
||||
mountStore(storeUrlAndId.first(), filePath, nfsVersion);
|
||||
List<String> hypervisorList = fetchAllHypervisors(zoneId);
|
||||
for (String hypervisor : hypervisorList) {
|
||||
Hypervisor.HypervisorType name = Hypervisor.HypervisorType.getType(hypervisor);
|
||||
String templateName = NewTemplateNameList.get(name);
|
||||
Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName = new Pair<Hypervisor.HypervisorType, String>(name, templateName);
|
||||
Long templateId = getRegisteredTemplateId(hypervisorAndTemplateName);
|
||||
if (templateId != null) {
|
||||
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
|
||||
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateId);
|
||||
if (templateDataStoreVO != null) {
|
||||
String installPath = templateDataStoreVO.getInstallPath();
|
||||
if (validateIfSeeded(templateDataStoreVO, storeUrlAndId.first(), installPath, nfsVersion)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (templateVO != null) {
|
||||
registerTemplate(hypervisorAndTemplateName, storeUrlAndId, templateVO, templateDataStoreVO, filePath);
|
||||
updateRegisteredTemplateDetails(templateId, hypervisorAndTemplateName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
registerTemplate(hypervisorAndTemplateName, storeUrlAndId, filePath);
|
||||
}
|
||||
registerTemplatesForZone(zoneId, filePath);
|
||||
unmountStore(filePath);
|
||||
} catch (Exception e) {
|
||||
unmountStore(filePath);
|
||||
@ -851,12 +962,7 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRegisteredTemplateDetails(Long templateId, Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
||||
Pair<Hypervisor.HypervisorType, String> entry = new Pair<>(hypervisorAndTemplateName.getKey(), hypervisorAndTemplateName.getValue());
|
||||
updateRegisteredTemplateDetails(templateId, entry);
|
||||
}
|
||||
|
||||
private void updateRegisteredTemplateDetails(Long templateId, Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
||||
private void updateRegisteredTemplateDetails(Long templateId, MetadataTemplateDetails templateDetails) {
|
||||
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
|
||||
templateVO.setTemplateType(Storage.TemplateType.SYSTEM);
|
||||
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
|
||||
@ -865,68 +971,81 @@ public class SystemVmTemplateRegistration {
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
updateSystemVMEntries(templateId, hypervisorAndTemplateName.first());
|
||||
|
||||
Hypervisor.HypervisorType hypervisorType = templateDetails.getHypervisorType();
|
||||
updateSystemVMEntries(templateId, hypervisorType);
|
||||
// Change value of global configuration parameter router.template.* for the corresponding hypervisor and minreq.sysvmtemplate.version for the ACS version
|
||||
Map<String, String> configParams = new HashMap<>();
|
||||
configParams.put(RouterTemplateConfigurationNames.get(hypervisorAndTemplateName.first()), hypervisorAndTemplateName.second());
|
||||
configParams.put(RouterTemplateConfigurationNames.get(hypervisorType), templateDetails.getName());
|
||||
configParams.put("minreq.sysvmtemplate.version", getSystemVmTemplateVersion());
|
||||
updateConfigurationParams(configParams);
|
||||
}
|
||||
|
||||
private void updateTemplateUrlAndChecksum(VMTemplateVO templateVO, Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
||||
templateVO.setUrl(NewTemplateUrl.get(hypervisorAndTemplateName.getKey()));
|
||||
templateVO.setChecksum(NewTemplateChecksum.get(hypervisorAndTemplateName.getKey()));
|
||||
private void updateTemplateUrlAndChecksum(VMTemplateVO templateVO, MetadataTemplateDetails templateDetails) {
|
||||
templateVO.setUrl(templateDetails.getUrl());
|
||||
templateVO.setChecksum(templateDetails.getChecksum());
|
||||
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
|
||||
if (!updated) {
|
||||
String errMsg = String.format("updateSystemVmTemplates:Exception while updating 'url' and 'checksum' for hypervisor type %s", hypervisorAndTemplateName.getKey().name());
|
||||
String errMsg = String.format("updateSystemVmTemplates:Exception while updating 'url' and 'checksum' for hypervisor type %s", templateDetails.getHypervisorType());
|
||||
LOGGER.error(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean registerOrUpdateSystemVmTemplate(MetadataTemplateDetails templateDetails,
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsInUse) {
|
||||
LOGGER.debug("Updating System VM template for {}", templateDetails.getHypervisorArchLog());
|
||||
VMTemplateVO registeredTemplate = getRegisteredTemplate(templateDetails.getName(), templateDetails.getArch());
|
||||
// change template type to SYSTEM
|
||||
if (registeredTemplate != null) {
|
||||
updateRegisteredTemplateDetails(registeredTemplate.getId(), templateDetails);
|
||||
} else {
|
||||
boolean isHypervisorArchMatchMetadata = hypervisorsInUse.stream()
|
||||
.anyMatch(p -> p.first().equals(templateDetails.getHypervisorType())
|
||||
&& Objects.equals(p.second(), templateDetails.getArch()));
|
||||
if (isHypervisorArchMatchMetadata) {
|
||||
try {
|
||||
registerTemplates(hypervisorsInUse);
|
||||
return true;
|
||||
} catch (final Exception e) {
|
||||
throw new CloudRuntimeException(String.format("Failed to register %s templates for hypervisors: [%s]. " +
|
||||
"Cannot upgrade system VMs",
|
||||
getSystemVmTemplateVersion(),
|
||||
StringUtils.join(hypervisorsInUse.stream()
|
||||
.map(x -> getHypervisorArchKey(x.first(), x.second()))
|
||||
.collect(Collectors.toList()), ",")), e);
|
||||
}
|
||||
} else {
|
||||
LOGGER.warn("Cannot upgrade {} system VM template for {} as it is not used, not failing upgrade",
|
||||
getSystemVmTemplateVersion(), templateDetails.getHypervisorArchLog());
|
||||
VMTemplateVO templateVO = vmTemplateDao.findLatestTemplateByTypeAndHypervisorAndArch(
|
||||
templateDetails.getHypervisorType(), templateDetails.getArch(), Storage.TemplateType.SYSTEM);
|
||||
if (templateVO != null) {
|
||||
updateTemplateUrlAndChecksum(templateVO, templateDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void updateSystemVmTemplates(final Connection conn) {
|
||||
LOGGER.debug("Updating System Vm template IDs");
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||
Set<Hypervisor.HypervisorType> hypervisorsListInUse = new HashSet<Hypervisor.HypervisorType>();
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsInUse;
|
||||
try {
|
||||
hypervisorsListInUse = clusterDao.getDistinctAvailableHypervisorsAcrossClusters();
|
||||
|
||||
hypervisorsInUse = clusterDao.listDistinctHypervisorsArchAcrossClusters(null);
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("updateSystemVmTemplates: Exception caught while getting hypervisor types from clusters: " + e.getMessage());
|
||||
throw new CloudRuntimeException("updateSystemVmTemplates:Exception while getting hypervisor types from clusters", e);
|
||||
throw new CloudRuntimeException("Exception while getting hypervisor types from clusters", e);
|
||||
}
|
||||
|
||||
for (final Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName : NewTemplateNameList.entrySet()) {
|
||||
LOGGER.debug("Updating " + hypervisorAndTemplateName.getKey() + " System Vms");
|
||||
Long templateId = getRegisteredTemplateId(new Pair<>(hypervisorAndTemplateName.getKey(), hypervisorAndTemplateName.getValue()));
|
||||
Collection<MetadataTemplateDetails> templateEntries = NewTemplateMap.values();
|
||||
for (MetadataTemplateDetails templateDetails : templateEntries) {
|
||||
try {
|
||||
// change template type to SYSTEM
|
||||
if (templateId != null) {
|
||||
updateRegisteredTemplateDetails(templateId, hypervisorAndTemplateName);
|
||||
} else {
|
||||
if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())) {
|
||||
try {
|
||||
registerTemplates(hypervisorsListInUse);
|
||||
break;
|
||||
} catch (final Exception e) {
|
||||
throw new CloudRuntimeException(String.format("%s %s SystemVm template not found. Cannot upgrade system Vms", getSystemVmTemplateVersion(), hypervisorAndTemplateName.getKey()));
|
||||
}
|
||||
} else {
|
||||
LOGGER.warn(String.format("%s %s SystemVm template not found. Cannot upgrade system Vms hypervisor is not used, so not failing upgrade",
|
||||
getSystemVmTemplateVersion(), hypervisorAndTemplateName.getKey()));
|
||||
// Update the latest template URLs for corresponding hypervisor
|
||||
VMTemplateVO templateVO = vmTemplateDao.findLatestTemplateByTypeAndHypervisor(hypervisorAndTemplateName.getKey(), Storage.TemplateType.SYSTEM);
|
||||
if (templateVO != null) {
|
||||
updateTemplateUrlAndChecksum(templateVO, hypervisorAndTemplateName);
|
||||
}
|
||||
}
|
||||
if (registerOrUpdateSystemVmTemplate(templateDetails, hypervisorsInUse)) {
|
||||
break;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
String errMsg = "updateSystemVmTemplates:Exception while getting ids of templates";
|
||||
String errMsg = "Exception while registering/updating system VM templates for hypervisors in metadata";
|
||||
LOGGER.error(errMsg, e);
|
||||
throw new CloudRuntimeException(errMsg, e);
|
||||
}
|
||||
@ -948,4 +1067,64 @@ public class SystemVmTemplateRegistration {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static class MetadataTemplateDetails {
|
||||
private final Hypervisor.HypervisorType hypervisorType;
|
||||
private final String name;
|
||||
private final String filename;
|
||||
private final String url;
|
||||
private final String checksum;
|
||||
private final CPU.CPUArch arch;
|
||||
private String downloadedFilePath;
|
||||
|
||||
MetadataTemplateDetails(Hypervisor.HypervisorType hypervisorType, String name, String filename, String url,
|
||||
String checksum, CPU.CPUArch arch) {
|
||||
this.hypervisorType = hypervisorType;
|
||||
this.name = name;
|
||||
this.filename = filename;
|
||||
this.url = url;
|
||||
this.checksum = checksum;
|
||||
this.arch = arch;
|
||||
}
|
||||
|
||||
public Hypervisor.HypervisorType getHypervisorType() {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getChecksum() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public String getDownloadedFilePath() {
|
||||
return downloadedFilePath;
|
||||
}
|
||||
|
||||
public void setDownloadedFilePath(String downloadedFilePath) {
|
||||
this.downloadedFilePath = downloadedFilePath;
|
||||
}
|
||||
|
||||
public String getDefaultFilePath() {
|
||||
return TEMPLATES_PATH + filename;
|
||||
}
|
||||
|
||||
public String getHypervisorArchLog() {
|
||||
return SystemVmTemplateRegistration.getHypervisorArchLog(hypervisorType, arch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ public class Upgrade42000to42010 extends DbUpgradeAbstractImpl implements DbUpgr
|
||||
try {
|
||||
systemVmTemplateRegistration.updateSystemVmTemplates(conn);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to find / register SystemVM template(s)");
|
||||
throw new CloudRuntimeException("Failed to find / register SystemVM template(s)", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
|
||||
|
||||
List<ImageStoreVO> listStoresByZoneId(long zoneId);
|
||||
|
||||
List<ImageStoreVO> listAllStoresInZone(Long zoneId, String provider, DataStoreRole role);
|
||||
List<ImageStoreVO> listAllStoresInZoneExceptId(Long zoneId, String provider, DataStoreRole role, long storeId);
|
||||
|
||||
List<ImageStoreVO> findByProtocol(String protocol);
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
|
||||
private SearchBuilder<ImageStoreVO> nameSearch;
|
||||
private SearchBuilder<ImageStoreVO> providerSearch;
|
||||
private SearchBuilder<ImageStoreVO> regionSearch;
|
||||
private SearchBuilder<ImageStoreVO> storeSearch;
|
||||
private SearchBuilder<ImageStoreVO> storesExceptIdSearch;
|
||||
private SearchBuilder<ImageStoreVO> protocolSearch;
|
||||
private SearchBuilder<ImageStoreVO> zoneProtocolSearch;
|
||||
|
||||
@ -88,11 +88,12 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
|
||||
regionSearch.and("role", regionSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||
regionSearch.done();
|
||||
|
||||
storeSearch = createSearchBuilder();
|
||||
storeSearch.and("providerName", storeSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
|
||||
storeSearch.and("role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||
storeSearch.and("dataCenterId", storeSearch.entity().getDcId(), SearchCriteria.Op.EQ);
|
||||
storeSearch.done();
|
||||
storesExceptIdSearch = createSearchBuilder();
|
||||
storesExceptIdSearch.and("providerName", storesExceptIdSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
|
||||
storesExceptIdSearch.and("role", storesExceptIdSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||
storesExceptIdSearch.and("dataCenterId", storesExceptIdSearch.entity().getDcId(), SearchCriteria.Op.EQ);
|
||||
storesExceptIdSearch.and("id", storesExceptIdSearch.entity().getId(), SearchCriteria.Op.NEQ);
|
||||
storesExceptIdSearch.done();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -113,11 +114,12 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ImageStoreVO> listAllStoresInZone(Long zoneId, String provider, DataStoreRole role) {
|
||||
SearchCriteria<ImageStoreVO> sc = storeSearch.create();
|
||||
public List<ImageStoreVO> listAllStoresInZoneExceptId(Long zoneId, String provider, DataStoreRole role, long id) {
|
||||
SearchCriteria<ImageStoreVO> sc = storesExceptIdSearch.create();
|
||||
sc.setParameters("providerName", provider);
|
||||
sc.setParameters("role", role);
|
||||
sc.setParameters("dataCenterId", zoneId);
|
||||
sc.setParameters("id", id);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import com.cloud.cpu.CPU;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
@Converter
|
||||
@Converter(autoApply = true)
|
||||
public class CPUArchConverter implements AttributeConverter<CPU.CPUArch, String> {
|
||||
|
||||
@Override
|
||||
|
||||
@ -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" ');
|
||||
|
||||
@ -58,6 +58,7 @@ select
|
||||
host.resource_state host_resource_state,
|
||||
vm_template.id template_id,
|
||||
vm_template.uuid template_uuid,
|
||||
vm_template.arch arch,
|
||||
service_offering.id service_offering_id,
|
||||
service_offering.uuid service_offering_uuid,
|
||||
service_offering.name service_offering_name,
|
||||
|
||||
@ -83,6 +83,7 @@ SELECT
|
||||
`iso`.`uuid` AS `iso_uuid`,
|
||||
`iso`.`name` AS `iso_name`,
|
||||
`iso`.`display_text` AS `iso_display_text`,
|
||||
`vm_template`.`arch` AS `arch`,
|
||||
`service_offering`.`id` AS `service_offering_id`,
|
||||
`service_offering`.`uuid` AS `service_offering_uuid`,
|
||||
`disk_offering`.`uuid` AS `disk_offering_uuid`,
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@ -36,9 +37,13 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ClusterDaoImplTest {
|
||||
@ -75,4 +80,39 @@ public class ClusterDaoImplTest {
|
||||
verify(clusterDao).customSearch(genericSearchBuilder.create(), null);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listDistinctHypervisorsArchAcrossClusters_WithZone() {
|
||||
Long zoneId = 123L;
|
||||
ClusterVO cluster1 = mock(ClusterVO.class);
|
||||
when(cluster1.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
|
||||
when(cluster1.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
ClusterVO cluster2 = mock(ClusterVO.class);
|
||||
when(cluster2.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(cluster2.getArch()).thenReturn(CPU.CPUArch.arm64);
|
||||
List<ClusterVO> dummyHosts = Arrays.asList(cluster1, cluster2);
|
||||
doReturn(dummyHosts).when(clusterDao).search(any(SearchCriteria.class), isNull());
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> result = clusterDao.listDistinctHypervisorsArchAcrossClusters(zoneId);
|
||||
assertNotNull(result);
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(Hypervisor.HypervisorType.XenServer, result.get(0).first());
|
||||
assertEquals(CPU.CPUArch.amd64, result.get(0).second());
|
||||
assertEquals(Hypervisor.HypervisorType.KVM, result.get(1).first());
|
||||
assertEquals(CPU.CPUArch.arm64, result.get(1).second());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listDistinctHypervisorsArchAcrossClusters_WithoutZone() {
|
||||
Long zoneId = null;
|
||||
ClusterVO cluster = mock(ClusterVO.class);
|
||||
when(cluster.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.VMware);
|
||||
when(cluster.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
List<ClusterVO> dummyHosts = Collections.singletonList(cluster);
|
||||
doReturn(dummyHosts).when(clusterDao).search(any(SearchCriteria.class), isNull());
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> result = clusterDao.listDistinctHypervisorsArchAcrossClusters(zoneId);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(Hypervisor.HypervisorType.VMware, result.get(0).first());
|
||||
assertEquals(CPU.CPUArch.amd64, result.get(0).second());
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,18 @@
|
||||
// under the License.
|
||||
package com.cloud.host.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@ -26,6 +37,7 @@ import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
@ -52,10 +64,10 @@ public class HostDaoImplTest {
|
||||
public void testCountUpAndEnabledHostsInZone() {
|
||||
long testZoneId = 100L;
|
||||
hostDao.HostTypeCountSearch = mockSearchBuilder;
|
||||
Mockito.when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||
Mockito.doNothing().when(mockSearchCriteria).setParameters(Mockito.anyString(), Mockito.any());
|
||||
when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||
Mockito.doNothing().when(mockSearchCriteria).setParameters(Mockito.anyString(), any());
|
||||
int expected = 5;
|
||||
Mockito.doReturn(expected).when(hostDao).getCount(mockSearchCriteria);
|
||||
doReturn(expected).when(hostDao).getCount(mockSearchCriteria);
|
||||
Integer count = hostDao.countUpAndEnabledHostsInZone(testZoneId);
|
||||
Assert.assertSame(expected, count);
|
||||
Mockito.verify(mockSearchCriteria).setParameters("type", Host.Type.Routing);
|
||||
@ -70,16 +82,16 @@ public class HostDaoImplTest {
|
||||
GenericDaoBase.SumCount mockSumCount = new GenericDaoBase.SumCount();
|
||||
mockSumCount.count = 10;
|
||||
mockSumCount.sum = 20;
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, GenericDaoBase.SumCount> sb = Mockito.mock(GenericSearchBuilder.class);
|
||||
Mockito.when(sb.entity()).thenReturn(host);
|
||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(GenericDaoBase.SumCount.class);
|
||||
SearchCriteria<GenericDaoBase.SumCount> sc = Mockito.mock(SearchCriteria.class);
|
||||
Mockito.when(sb.create()).thenReturn(sc);
|
||||
Mockito.doReturn(List.of(mockSumCount)).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
||||
HostVO host = mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, GenericDaoBase.SumCount> sb = mock(GenericSearchBuilder.class);
|
||||
when(sb.entity()).thenReturn(host);
|
||||
doReturn(sb).when(hostDao).createSearchBuilder(GenericDaoBase.SumCount.class);
|
||||
SearchCriteria<GenericDaoBase.SumCount> sc = mock(SearchCriteria.class);
|
||||
when(sb.create()).thenReturn(sc);
|
||||
doReturn(List.of(mockSumCount)).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||
Pair<Integer, Integer> result = hostDao.countAllHostsAndCPUSocketsByType(type);
|
||||
Assert.assertEquals(10, result.first().intValue());
|
||||
Assert.assertEquals(20, result.second().intValue());
|
||||
assertEquals(10, result.first().intValue());
|
||||
assertEquals(20, result.second().intValue());
|
||||
Mockito.verify(sc).setParameters("type", type);
|
||||
}
|
||||
|
||||
@ -87,13 +99,13 @@ public class HostDaoImplTest {
|
||||
public void testIsHostUp() {
|
||||
long testHostId = 101L;
|
||||
List<Status> statuses = List.of(Status.Up);
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Status> sb = Mockito.mock(GenericSearchBuilder.class);
|
||||
Mockito.when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Status> sc = Mockito.mock(SearchCriteria.class);
|
||||
Mockito.when(sb.create()).thenReturn(sc);
|
||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Status.class);
|
||||
Mockito.doReturn(statuses).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
||||
HostVO host = mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Status> sb = mock(GenericSearchBuilder.class);
|
||||
when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Status> sc = mock(SearchCriteria.class);
|
||||
when(sb.create()).thenReturn(sc);
|
||||
doReturn(sb).when(hostDao).createSearchBuilder(Status.class);
|
||||
doReturn(statuses).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||
boolean result = hostDao.isHostUp(testHostId);
|
||||
Assert.assertTrue("Host should be up", result);
|
||||
Mockito.verify(sc).setParameters("id", testHostId);
|
||||
@ -109,17 +121,17 @@ public class HostDaoImplTest {
|
||||
List<Host.Type> types = List.of(Host.Type.Routing);
|
||||
List<Hypervisor.HypervisorType> hypervisorTypes = List.of(Hypervisor.HypervisorType.KVM);
|
||||
List<Long> mockResults = List.of(1001L, 1002L); // Mocked result
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Long> sb = Mockito.mock(GenericSearchBuilder.class);
|
||||
Mockito.when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Long> sc = Mockito.mock(SearchCriteria.class);
|
||||
Mockito.when(sb.create()).thenReturn(sc);
|
||||
Mockito.when(sb.and()).thenReturn(sb);
|
||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
||||
Mockito.doReturn(mockResults).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
||||
HostVO host = mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Long> sb = mock(GenericSearchBuilder.class);
|
||||
when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Long> sc = mock(SearchCriteria.class);
|
||||
when(sb.create()).thenReturn(sc);
|
||||
when(sb.and()).thenReturn(sb);
|
||||
doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
||||
doReturn(mockResults).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||
List<Long> hostIds = hostDao.findHostIdsByZoneClusterResourceStateTypeAndHypervisorType(
|
||||
zoneId, clusterId, msId, resourceStates, types, hypervisorTypes);
|
||||
Assert.assertEquals(mockResults, hostIds);
|
||||
assertEquals(mockResults, hostIds);
|
||||
Mockito.verify(sc).setParameters("zoneId", zoneId);
|
||||
Mockito.verify(sc).setParameters("clusterId", clusterId);
|
||||
Mockito.verify(sc).setParameters("msId", msId);
|
||||
@ -132,15 +144,16 @@ public class HostDaoImplTest {
|
||||
public void testListDistinctHypervisorTypes() {
|
||||
Long zoneId = 1L;
|
||||
List<Hypervisor.HypervisorType> mockResults = List.of(Hypervisor.HypervisorType.KVM, Hypervisor.HypervisorType.XenServer);
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Hypervisor.HypervisorType> sb = Mockito.mock(GenericSearchBuilder.class);
|
||||
Mockito.when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Hypervisor.HypervisorType> sc = Mockito.mock(SearchCriteria.class);
|
||||
Mockito.when(sb.create()).thenReturn(sc);
|
||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Hypervisor.HypervisorType.class);
|
||||
Mockito.doReturn(mockResults).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
||||
HostVO host = mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, String> sb = mock(GenericSearchBuilder.class);
|
||||
when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<String> sc = mock(SearchCriteria.class);
|
||||
when(sb.create()).thenReturn(sc);
|
||||
doReturn(sb).when(hostDao).createSearchBuilder(String.class);
|
||||
doReturn(mockResults.stream().map(h -> h.name()).collect(Collectors.toList())).when(hostDao)
|
||||
.customSearch(any(SearchCriteria.class), any());
|
||||
List<Hypervisor.HypervisorType> hypervisorTypes = hostDao.listDistinctHypervisorTypes(zoneId);
|
||||
Assert.assertEquals(mockResults, hypervisorTypes);
|
||||
assertEquals(mockResults, hypervisorTypes);
|
||||
Mockito.verify(sc).setParameters("zoneId", zoneId);
|
||||
Mockito.verify(sc).setParameters("type", Host.Type.Routing);
|
||||
}
|
||||
@ -148,12 +161,12 @@ public class HostDaoImplTest {
|
||||
@Test
|
||||
public void testListByIds() {
|
||||
List<Long> ids = List.of(101L, 102L);
|
||||
List<HostVO> mockResults = List.of(Mockito.mock(HostVO.class), Mockito.mock(HostVO.class));
|
||||
List<HostVO> mockResults = List.of(mock(HostVO.class), mock(HostVO.class));
|
||||
hostDao.IdsSearch = mockSearchBuilder;
|
||||
Mockito.when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||
Mockito.doReturn(mockResults).when(hostDao).search(Mockito.any(SearchCriteria.class), Mockito.any());
|
||||
when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||
doReturn(mockResults).when(hostDao).search(any(SearchCriteria.class), any());
|
||||
List<HostVO> hosts = hostDao.listByIds(ids);
|
||||
Assert.assertEquals(mockResults, hosts);
|
||||
assertEquals(mockResults, hosts);
|
||||
Mockito.verify(mockSearchCriteria).setParameters("id", ids.toArray());
|
||||
Mockito.verify(hostDao).search(mockSearchCriteria, null);
|
||||
}
|
||||
@ -166,15 +179,15 @@ public class HostDaoImplTest {
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
||||
Long zoneId = 1L, podId = 2L, clusterId = 3L;
|
||||
List<Long> mockResults = List.of(1001L, 1002L);
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Long> sb = Mockito.mock(GenericSearchBuilder.class);
|
||||
Mockito.when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Long> sc = Mockito.mock(SearchCriteria.class);
|
||||
Mockito.when(sb.create()).thenReturn(sc);
|
||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
||||
Mockito.doReturn(mockResults).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
||||
HostVO host = mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, Long> sb = mock(GenericSearchBuilder.class);
|
||||
when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<Long> sc = mock(SearchCriteria.class);
|
||||
when(sb.create()).thenReturn(sc);
|
||||
doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
||||
doReturn(mockResults).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||
List<Long> hostIds = hostDao.listIdsBy(type, status, resourceState, hypervisorType, zoneId, podId, clusterId);
|
||||
Assert.assertEquals(mockResults, hostIds);
|
||||
assertEquals(mockResults, hostIds);
|
||||
Mockito.verify(sc).setParameters("type", type);
|
||||
Mockito.verify(sc).setParameters("status", status);
|
||||
Mockito.verify(sc).setParameters("resourceState", resourceState);
|
||||
@ -183,4 +196,57 @@ public class HostDaoImplTest {
|
||||
Mockito.verify(sc).setParameters("podId", podId);
|
||||
Mockito.verify(sc).setParameters("clusterId", clusterId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDistinctHypervisorArchTypes_WithZone() {
|
||||
Long zoneId = 123L;
|
||||
HostVO host1 = mock(HostVO.class);
|
||||
when(host1.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
|
||||
when(host1.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
HostVO host2 = mock(HostVO.class);
|
||||
when(host2.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(host2.getArch()).thenReturn(CPU.CPUArch.arm64);
|
||||
List<HostVO> dummyHosts = Arrays.asList(host1, host2);
|
||||
doReturn(dummyHosts).when(hostDao).search(any(SearchCriteria.class), isNull());
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> result = hostDao.listDistinctHypervisorArchTypes(zoneId);
|
||||
assertNotNull(result);
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(Hypervisor.HypervisorType.XenServer, result.get(0).first());
|
||||
assertEquals(CPU.CPUArch.amd64, result.get(0).second());
|
||||
assertEquals(Hypervisor.HypervisorType.KVM, result.get(1).first());
|
||||
assertEquals(CPU.CPUArch.arm64, result.get(1).second());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDistinctHypervisorArchTypes_WithoutZone() {
|
||||
Long zoneId = null;
|
||||
HostVO host1 = mock(HostVO.class);
|
||||
when(host1.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.VMware);
|
||||
when(host1.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
List<HostVO> dummyHosts = Collections.singletonList(host1);
|
||||
doReturn(dummyHosts).when(hostDao).search(any(SearchCriteria.class), isNull());
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> result = hostDao.listDistinctHypervisorArchTypes(zoneId);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(Hypervisor.HypervisorType.VMware, result.get(0).first());
|
||||
assertEquals(CPU.CPUArch.amd64, result.get(0).second());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDistinctArchTypes() {
|
||||
Long clusterId = 1L;
|
||||
List<CPU.CPUArch> mockResults = List.of(CPU.CPUArch.amd64, CPU.CPUArch.arm64);
|
||||
HostVO host = mock(HostVO.class);
|
||||
GenericSearchBuilder<HostVO, String> sb = mock(GenericSearchBuilder.class);
|
||||
when(sb.entity()).thenReturn(host);
|
||||
SearchCriteria<String> sc = mock(SearchCriteria.class);
|
||||
when(sb.create()).thenReturn(sc);
|
||||
doReturn(sb).when(hostDao).createSearchBuilder(String.class);
|
||||
doReturn(mockResults.stream().map(h -> h.getType()).collect(Collectors.toList())).when(hostDao)
|
||||
.customSearch(any(SearchCriteria.class), any());
|
||||
List<CPU.CPUArch> hypervisorTypes = hostDao.listDistinctArchTypes(clusterId);
|
||||
assertEquals(mockResults, hypervisorTypes);
|
||||
Mockito.verify(sc).setParameters("clusterId", clusterId);
|
||||
Mockito.verify(sc).setParameters("type", Host.Type.Routing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,189 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class VMTemplateDaoImplTest {
|
||||
|
||||
@Mock
|
||||
HostDao hostDao;
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
VMTemplateDaoImpl templateDao = new VMTemplateDaoImpl();
|
||||
|
||||
@Test
|
||||
public void testFindLatestTemplateByName_ReturnsTemplate() {
|
||||
VMTemplateVO expectedTemplate = new VMTemplateVO();
|
||||
List<VMTemplateVO> returnedList = Collections.singletonList(expectedTemplate);
|
||||
doReturn(returnedList).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
|
||||
VMTemplateVO result = templateDao.findLatestTemplateByName("test", CPU.CPUArch.getDefault());
|
||||
assertNotNull("Expected a non-null template", result);
|
||||
assertEquals("Expected the returned template to be the first element", expectedTemplate, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindLatestTemplateByName_ReturnsNullWhenNoTemplateFound() {
|
||||
List<VMTemplateVO> emptyList = Collections.emptyList();
|
||||
doReturn(emptyList).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
|
||||
VMTemplateVO result = templateDao.findLatestTemplateByName("test", CPU.CPUArch.getDefault());
|
||||
assertNull("Expected null when no templates are found", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindLatestTemplateByName_NullArch() {
|
||||
VMTemplateVO expectedTemplate = new VMTemplateVO();
|
||||
List<VMTemplateVO> returnedList = Collections.singletonList(expectedTemplate);
|
||||
doReturn(returnedList).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
|
||||
VMTemplateVO result = templateDao.findLatestTemplateByName("test", null);
|
||||
assertNotNull("Expected a non-null template even if arch is null", result);
|
||||
assertEquals("Expected the returned template to be the first element", expectedTemplate, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSortedTemplatesListWithPreferredArch_PreferredProvided() {
|
||||
VMTemplateVO templatePreferred = Mockito.mock(VMTemplateVO.class);
|
||||
when(templatePreferred.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
VMTemplateVO templateOther = Mockito.mock(VMTemplateVO.class);
|
||||
when(templateOther.getArch()).thenReturn(CPU.CPUArch.arm64);
|
||||
|
||||
Map<Pair<Hypervisor.HypervisorType, CPU.CPUArch>, VMTemplateVO> uniqueTemplates = new HashMap<>();
|
||||
uniqueTemplates.put(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64), templatePreferred);
|
||||
uniqueTemplates.put(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64), templateOther);
|
||||
List<VMTemplateVO> sortedList = templateDao.getSortedTemplatesListWithPreferredArch(uniqueTemplates,
|
||||
CPU.CPUArch.amd64.getType());
|
||||
assertEquals(2, sortedList.size());
|
||||
assertEquals(templatePreferred, sortedList.get(0));
|
||||
assertEquals(templateOther, sortedList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSortedTemplatesListWithPreferredArch_NoPreferred() {
|
||||
VMTemplateVO template1 = Mockito.mock(VMTemplateVO.class);
|
||||
when(template1.getId()).thenReturn(1L);
|
||||
VMTemplateVO template2 = Mockito.mock(VMTemplateVO.class);
|
||||
when(template2.getId()).thenReturn(2L);
|
||||
Map<Pair<Hypervisor.HypervisorType, CPU.CPUArch>, VMTemplateVO> uniqueTemplates = new HashMap<>();
|
||||
uniqueTemplates.put(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64), template1);
|
||||
uniqueTemplates.put(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64), template2);
|
||||
List<VMTemplateVO> sortedList = templateDao.getSortedTemplatesListWithPreferredArch(uniqueTemplates, "");
|
||||
assertEquals(2, sortedList.size());
|
||||
assertEquals(template2, sortedList.get(0));
|
||||
assertEquals(template1, sortedList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindSystemVMReadyTemplates() {
|
||||
long zoneId = 1L;
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
||||
String preferredArch = CPU.CPUArch.arm64.getType();
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> availableHypervisors = new ArrayList<>();
|
||||
availableHypervisors.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64));
|
||||
availableHypervisors.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64));
|
||||
doReturn(availableHypervisors).when(hostDao).listDistinctHypervisorArchTypes(zoneId);
|
||||
VMTemplateVO template1 = Mockito.mock(VMTemplateVO.class);
|
||||
when(template1.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(template1.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
VMTemplateVO template2 = Mockito.mock(VMTemplateVO.class);
|
||||
when(template2.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(template2.getArch()).thenReturn(CPU.CPUArch.arm64);
|
||||
List<VMTemplateVO> templatesFromDb = Arrays.asList(template1, template2);
|
||||
doReturn(templatesFromDb).when(templateDao).listBy(any(), any());
|
||||
SearchBuilder<VMTemplateVO> sb = mock(SearchBuilder.class);
|
||||
templateDao.readySystemTemplateSearch = sb;
|
||||
when(sb.create()).thenReturn(mock(SearchCriteria.class));
|
||||
List<VMTemplateVO> result = templateDao.findSystemVMReadyTemplates(zoneId, hypervisorType, preferredArch);
|
||||
assertNotNull(result);
|
||||
assertEquals(2, result.size());
|
||||
assertEquals(template2, result.get(0));
|
||||
assertEquals(template1, result.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindRoutingTemplates() {
|
||||
Hypervisor.HypervisorType hType = Hypervisor.HypervisorType.KVM;
|
||||
String templateName = "TestRouting";
|
||||
String preferredArch = CPU.CPUArch.amd64.getType();
|
||||
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
||||
when(template.getArch()).thenReturn(CPU.CPUArch.amd64);
|
||||
List<VMTemplateVO> templatesFromDb = Collections.singletonList(template);
|
||||
doReturn(templatesFromDb).when(templateDao).listBy(any(), any());
|
||||
SearchBuilder<VMTemplateVO> sb = mock(SearchBuilder.class);
|
||||
when(sb.create()).thenReturn(mock(SearchCriteria.class));
|
||||
templateDao.tmpltTypeHyperSearch2 = sb;
|
||||
List<VMTemplateVO> result = templateDao.findRoutingTemplates(hType, templateName, preferredArch);
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(template, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindLatestTemplateByTypeAndHypervisorAndArch_Found() {
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
||||
CPU.CPUArch arch = CPU.CPUArch.amd64;
|
||||
Storage.TemplateType type = Storage.TemplateType.SYSTEM;
|
||||
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
||||
List<VMTemplateVO> templatesFromDb = Collections.singletonList(template);
|
||||
doReturn(templatesFromDb).when(templateDao).listBy(any(), any());
|
||||
VMTemplateVO result = templateDao.findLatestTemplateByTypeAndHypervisorAndArch(hypervisorType, arch, type);
|
||||
assertNotNull(result);
|
||||
assertEquals(template, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindLatestTemplateByTypeAndHypervisorAndArch_NotFound() {
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
||||
CPU.CPUArch arch = CPU.CPUArch.x86;
|
||||
Storage.TemplateType type = Storage.TemplateType.SYSTEM;
|
||||
doReturn(Collections.emptyList()).when(templateDao).listBy(any(), any());
|
||||
VMTemplateVO result = templateDao.findLatestTemplateByTypeAndHypervisorAndArch(hypervisorType, arch, type);
|
||||
assertNull(result);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,427 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.upgrade;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.cloudstack.utils.security.DigestHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.utils.HttpUtils;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SystemVmTemplateRegistrationTest {
|
||||
|
||||
@Mock
|
||||
ClusterDao clusterDao;
|
||||
|
||||
@Mock
|
||||
VMTemplateDao vmTemplateDao;
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
SystemVmTemplateRegistration systemVmTemplateRegistration = new SystemVmTemplateRegistration();
|
||||
|
||||
private void setupMetadataFile(MockedStatic<SystemVmTemplateRegistration> mockedStatic, String content) {
|
||||
try {
|
||||
String location = "metadata.ini";
|
||||
if (StringUtils.isNotBlank(content)) {
|
||||
File tempFile = File.createTempFile("metadata", ".ini");
|
||||
location = tempFile.getAbsolutePath();
|
||||
Files.write(Paths.get(location), content.getBytes());
|
||||
tempFile.deleteOnExit();
|
||||
}
|
||||
mockedStatic.when(SystemVmTemplateRegistration::getMetadataFilePath).thenReturn(location);
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parseMetadataFile_noFile() {
|
||||
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
|
||||
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) {
|
||||
setupMetadataFile(mockedStatic, null);
|
||||
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
|
||||
SystemVmTemplateRegistration::parseMetadataFile);
|
||||
assertTrue(exception.getMessage().contains("Failed to parse systemVM template metadata file"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parseMetadataFile_invalidContent() {
|
||||
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
|
||||
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) {
|
||||
setupMetadataFile(mockedStatic, "abc");
|
||||
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
|
||||
SystemVmTemplateRegistration::parseMetadataFile);
|
||||
assertTrue(exception.getMessage().contains("Failed to parse systemVM template metadata file"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parseMetadataFile_success() {
|
||||
String metadataFileContent = "[default]\n" +
|
||||
"version = x.y.z.0\n" +
|
||||
"\n" +
|
||||
"[kvm-x86_64]\n" +
|
||||
"templatename = systemvm-kvm-x.y.z\n" +
|
||||
"checksum = abc1\n" +
|
||||
"downloadurl = https://download.cloudstack.org/systemvm/x.y/systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
|
||||
"filename = systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
|
||||
"\n" +
|
||||
"[kvm-aarch64]\n" +
|
||||
"templatename = systemvm-kvm-x.y.z\n" +
|
||||
"checksum = abc2\n" +
|
||||
"downloadurl = https://download.cloudstack.org/systemvm/x.y/systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
|
||||
"filename = systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
|
||||
"\n" +
|
||||
"[vmware]\n" +
|
||||
"templatename = systemvm-vmware-x.y.z\n" +
|
||||
"checksum = abc3\n" +
|
||||
"downloadurl = https://download.cloudstack.org/systemvm/x.y/systemvmtemplate-x.y.z-vmware.ova\n" +
|
||||
"filename = systemvmtemplate-x.y.z-vmware.ova\n";
|
||||
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
|
||||
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) {
|
||||
setupMetadataFile(mockedStatic, metadataFileContent);
|
||||
String version = SystemVmTemplateRegistration.parseMetadataFile();
|
||||
assertEquals("x.y.z.0", version);
|
||||
}
|
||||
assertNull(SystemVmTemplateRegistration.NewTemplateMap.get("xenserver"));
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
|
||||
SystemVmTemplateRegistration.NewTemplateMap.get("kvm-x86_64");
|
||||
assertNotNull(templateDetails);
|
||||
assertEquals(CPU.CPUArch.amd64, templateDetails.getArch());
|
||||
assertEquals(Hypervisor.HypervisorType.KVM, templateDetails.getHypervisorType());
|
||||
templateDetails =
|
||||
SystemVmTemplateRegistration.NewTemplateMap.get("kvm-aarch64");
|
||||
assertNotNull(templateDetails);
|
||||
assertEquals(CPU.CPUArch.arm64, templateDetails.getArch());
|
||||
assertEquals(Hypervisor.HypervisorType.KVM, templateDetails.getHypervisorType());
|
||||
templateDetails =
|
||||
SystemVmTemplateRegistration.NewTemplateMap.get("vmware");
|
||||
assertNotNull(templateDetails);
|
||||
assertNull(templateDetails.getArch());
|
||||
assertEquals(Hypervisor.HypervisorType.VMware, templateDetails.getHypervisorType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMountStore_nullStoreUrl() throws Exception {
|
||||
try (MockedStatic<Script> scriptMock = Mockito.mockStatic(Script.class)) {
|
||||
SystemVmTemplateRegistration.mountStore(null, "/mnt/nfs", "nfs3");
|
||||
scriptMock.verifyNoInteractions();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMountStore_validStoreUrl() throws Exception {
|
||||
String storeUrl = "nfs://192.168.1.100/export";
|
||||
String path = "/mnt/nfs";
|
||||
String nfsVersion = "nfs3";
|
||||
String expectedMountCommand = "expectedMountCommand";
|
||||
try (MockedStatic<UriUtils> uriUtilsMock = Mockito.mockStatic(UriUtils.class);
|
||||
MockedStatic<SystemVmTemplateRegistration> sysVmMock =
|
||||
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS);
|
||||
MockedStatic<Script> scriptMock = Mockito.mockStatic(Script.class)) {
|
||||
uriUtilsMock.when(() -> UriUtils.encodeURIComponent(storeUrl)).thenReturn(storeUrl);
|
||||
sysVmMock.when(() -> SystemVmTemplateRegistration.getMountCommand(
|
||||
eq(nfsVersion),
|
||||
eq("192.168.1.100:/export"),
|
||||
eq(path)
|
||||
)).thenReturn(expectedMountCommand);
|
||||
SystemVmTemplateRegistration.mountStore(storeUrl, path, nfsVersion);
|
||||
scriptMock.verify(() -> Script.runSimpleBashScript(expectedMountCommand), times(1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateTemplateFile_fileNotFound() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
|
||||
"name", "file", "url", "checksum", CPU.CPUArch.amd64);
|
||||
SystemVmTemplateRegistration.NewTemplateMap.put(SystemVmTemplateRegistration.getHypervisorArchKey(
|
||||
details.getHypervisorType(), details.getArch()), details);
|
||||
doReturn(null).when(systemVmTemplateRegistration).getTemplateFile(details);
|
||||
try {
|
||||
systemVmTemplateRegistration.validateTemplateFileForHypervisorAndArch(details.getHypervisorType(),
|
||||
details.getArch());
|
||||
fail("Expected CloudRuntimeException due to missing template file");
|
||||
} catch (CloudRuntimeException e) {
|
||||
assertEquals("Failed to find local template file", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateTemplateFile_checksumMismatch() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
|
||||
"name", "file", "url", "checksum", CPU.CPUArch.amd64);
|
||||
File dummyFile = new File("dummy.txt");
|
||||
SystemVmTemplateRegistration.NewTemplateMap.put(SystemVmTemplateRegistration.getHypervisorArchKey(
|
||||
details.getHypervisorType(), details.getArch()), details);
|
||||
doReturn(dummyFile).when(systemVmTemplateRegistration).getTemplateFile(details);
|
||||
doReturn(true).when(systemVmTemplateRegistration).isTemplateFileChecksumDifferent(details, dummyFile);
|
||||
try {
|
||||
systemVmTemplateRegistration.validateTemplateFileForHypervisorAndArch(details.getHypervisorType(),
|
||||
details.getArch());
|
||||
fail("Expected CloudRuntimeException due to checksum failure");
|
||||
} catch (CloudRuntimeException e) {
|
||||
assertEquals("Checksum failed for local template file", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateTemplateFile_success() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
|
||||
"name", "file", "url", "checksum", CPU.CPUArch.amd64);
|
||||
File dummyFile = new File("dummy.txt");
|
||||
SystemVmTemplateRegistration.NewTemplateMap.put(SystemVmTemplateRegistration.getHypervisorArchKey(
|
||||
details.getHypervisorType(), details.getArch()), details);
|
||||
doReturn(dummyFile).when(systemVmTemplateRegistration).getTemplateFile(details);
|
||||
doReturn(false).when(systemVmTemplateRegistration).isTemplateFileChecksumDifferent(details, dummyFile);
|
||||
systemVmTemplateRegistration.validateTemplateFileForHypervisorAndArch(details.getHypervisorType(),
|
||||
details.getArch());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateAndRegisterTemplate() {
|
||||
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
|
||||
String name = "TestTemplate";
|
||||
Long storeId = 123L;
|
||||
VMTemplateVO templateVO = new VMTemplateVO();
|
||||
templateVO.setArch(CPU.CPUArch.x86);
|
||||
TemplateDataStoreVO templateDataStoreVO = new TemplateDataStoreVO();
|
||||
String filePath = "/dummy/path";
|
||||
doNothing().when(systemVmTemplateRegistration).validateTemplateFileForHypervisorAndArch(hypervisor, templateVO.getArch());
|
||||
doNothing().when(systemVmTemplateRegistration).registerTemplate(hypervisor, name, storeId, templateVO, templateDataStoreVO, filePath);
|
||||
systemVmTemplateRegistration.validateAndRegisterTemplate(hypervisor, name, storeId, templateVO, templateDataStoreVO, filePath);
|
||||
verify(systemVmTemplateRegistration).validateTemplateFileForHypervisorAndArch(eq(hypervisor), eq(templateVO.getArch()));
|
||||
verify(systemVmTemplateRegistration).registerTemplate(eq(hypervisor), eq(name), eq(storeId), eq(templateVO), eq(templateDataStoreVO), eq(filePath));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateAndRegisterTemplateForNonExistingEntries() {
|
||||
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
|
||||
CPU.CPUArch arch = CPU.CPUArch.amd64;
|
||||
String name = "TestTemplateNonExisting";
|
||||
Pair<String, Long> storeUrlAndId = new Pair<>("nfs://dummy", 456L);
|
||||
String filePath = "/dummy/path/nonexisting";
|
||||
doNothing().when(systemVmTemplateRegistration).validateTemplateFileForHypervisorAndArch(hypervisor, arch);
|
||||
doNothing().when(systemVmTemplateRegistration).registerTemplateForNonExistingEntries(hypervisor, arch, name, storeUrlAndId, filePath);
|
||||
systemVmTemplateRegistration.validateAndRegisterTemplateForNonExistingEntries(hypervisor, arch, name, storeUrlAndId, filePath);
|
||||
verify(systemVmTemplateRegistration).validateTemplateFileForHypervisorAndArch(eq(hypervisor), eq(arch));
|
||||
verify(systemVmTemplateRegistration).registerTemplateForNonExistingEntries(eq(hypervisor), eq(arch), eq(name), eq(storeUrlAndId), eq(filePath));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTemplateFile_fileExists() throws Exception {
|
||||
File tempFile = File.createTempFile("template", ".qcow2");
|
||||
tempFile.deleteOnExit();
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
when(details.getDefaultFilePath()).thenReturn(tempFile.getAbsolutePath());
|
||||
File result = systemVmTemplateRegistration.getTemplateFile(details);
|
||||
assertNotNull(result);
|
||||
assertEquals(tempFile.getAbsolutePath(), result.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTemplateFile_fileDoesNotExist_downloadFails() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
|
||||
"name", "nonexistent.qcow2", "http://example.com/file.qcow2",
|
||||
"", CPU.CPUArch.arm64);
|
||||
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class);
|
||||
MockedStatic<HttpUtils> httpMock = Mockito.mockStatic(HttpUtils.class)) {
|
||||
filesMock.when(() -> Files.isWritable(any(Path.class))).thenReturn(true);
|
||||
httpMock.when(() -> HttpUtils.downloadFileWithProgress(eq(details.getUrl()), anyString(), any()))
|
||||
.thenReturn(false);
|
||||
File result = systemVmTemplateRegistration.getTemplateFile(details);
|
||||
assertNull(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTemplateFile_fileDoesNotExist_downloadSucceeds() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
|
||||
"name", "file.qcow2", "http://example.com/file.qcow2",
|
||||
"", CPU.CPUArch.arm64);
|
||||
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class);
|
||||
MockedStatic<HttpUtils> httpMock = Mockito.mockStatic(HttpUtils.class)) {
|
||||
filesMock.when(() -> Files.isWritable(any(Path.class))).thenReturn(false);
|
||||
File expectedFile = new File(systemVmTemplateRegistration.getTempDownloadDir(), details.getFilename());
|
||||
httpMock.when(() -> HttpUtils.downloadFileWithProgress(eq(details.getUrl()), eq(expectedFile.getAbsolutePath()), any()))
|
||||
.thenReturn(true);
|
||||
File result = systemVmTemplateRegistration.getTemplateFile(details);
|
||||
assertNotNull(result);
|
||||
assertEquals(expectedFile.getAbsolutePath(), result.getAbsolutePath());
|
||||
assertEquals(expectedFile.getAbsolutePath(), details.getDownloadedFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsTemplateFileChecksumDifferent_noMismatch() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
when(details.getChecksum()).thenReturn("dummyChecksum");
|
||||
File file = new File("dummy.txt");
|
||||
try (MockedStatic<DigestHelper> digestMock = Mockito.mockStatic(DigestHelper.class)) {
|
||||
digestMock.when(() -> DigestHelper.calculateChecksum(file)).thenReturn("dummyChecksum");
|
||||
boolean result = systemVmTemplateRegistration.isTemplateFileChecksumDifferent(details, file);
|
||||
assertFalse(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsTemplateFileChecksumDifferent_mismatch() {
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
when(details.getChecksum()).thenReturn("expectedChecksum");
|
||||
File file = new File("dummy.txt");
|
||||
try (MockedStatic<DigestHelper> digestMock = Mockito.mockStatic(DigestHelper.class)) {
|
||||
digestMock.when(() -> DigestHelper.calculateChecksum(file)).thenReturn("actualChecksum");
|
||||
boolean result = systemVmTemplateRegistration.isTemplateFileChecksumDifferent(details, file);
|
||||
assertTrue(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testValidateTemplates_metadataTemplateFailure() {
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
|
||||
list.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64));
|
||||
systemVmTemplateRegistration.validateTemplates(list);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testValidateTemplates_fileFailure() {
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
|
||||
list.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64));
|
||||
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
SystemVmTemplateRegistration.NewTemplateMap.put(SystemVmTemplateRegistration.getHypervisorArchKey(
|
||||
Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64), details);
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
doReturn(mockFile).when(systemVmTemplateRegistration).getTemplateFile(details);
|
||||
doReturn(true).when(systemVmTemplateRegistration).isTemplateFileChecksumDifferent(details, mockFile);
|
||||
systemVmTemplateRegistration.validateTemplates(list);
|
||||
}
|
||||
|
||||
public void testValidateTemplates_downloadableFileNotFound() {
|
||||
CPU.CPUArch arch = SystemVmTemplateRegistration.DOWNLOADABLE_TEMPLATE_ARCH_TYPES.get(0);
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
|
||||
list.add(new Pair<>(Hypervisor.HypervisorType.KVM, arch));
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
SystemVmTemplateRegistration.NewTemplateMap.put(SystemVmTemplateRegistration.getHypervisorArchKey(
|
||||
Hypervisor.HypervisorType.KVM, arch), details);
|
||||
doReturn(null).when(systemVmTemplateRegistration).getTemplateFile(details);
|
||||
systemVmTemplateRegistration.validateTemplates(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateTemplates_success() {
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
|
||||
list.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64));
|
||||
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
SystemVmTemplateRegistration.NewTemplateMap.put(SystemVmTemplateRegistration.getHypervisorArchKey(
|
||||
Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64), details);
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
doReturn(mockFile).when(systemVmTemplateRegistration).getTemplateFile(details);
|
||||
doReturn(false).when(systemVmTemplateRegistration).isTemplateFileChecksumDifferent(details, mockFile);
|
||||
systemVmTemplateRegistration.validateTemplates(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterTemplatesForZone() {
|
||||
long zoneId = 1L;
|
||||
String filePath = "dummyFilePath";
|
||||
String nfsVersion = "nfs3";
|
||||
Pair<String, Long> storeUrlAndId = new Pair<>("nfs://dummy", 100L);
|
||||
doReturn(storeUrlAndId).when(systemVmTemplateRegistration).getNfsStoreInZone(zoneId);
|
||||
doReturn(nfsVersion).when(systemVmTemplateRegistration).getNfsVersion(storeUrlAndId.second());
|
||||
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic = Mockito.mockStatic(
|
||||
SystemVmTemplateRegistration.class)) {
|
||||
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorArchList = new ArrayList<>();
|
||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
||||
CPU.CPUArch arch = CPU.CPUArch.getDefault();
|
||||
hypervisorArchList.add(new Pair<>(hypervisorType, arch));
|
||||
doReturn(hypervisorArchList).when(clusterDao).listDistinctHypervisorsArchAcrossClusters(zoneId);
|
||||
SystemVmTemplateRegistration.MetadataTemplateDetails details =
|
||||
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
|
||||
String name = "existing";
|
||||
Mockito.when(details.getArch()).thenReturn(CPU.CPUArch.getDefault());
|
||||
Mockito.when(details.getName()).thenReturn(name);
|
||||
mockedStatic.when(() -> SystemVmTemplateRegistration.getMetadataTemplateDetails(Mockito.any(),
|
||||
Mockito.any())).thenReturn(details);
|
||||
when(systemVmTemplateRegistration.getRegisteredTemplate(name, arch))
|
||||
.thenReturn(null);
|
||||
doNothing().when(systemVmTemplateRegistration).registerTemplateForNonExistingEntries(
|
||||
hypervisorType, arch,
|
||||
name, storeUrlAndId, filePath);
|
||||
systemVmTemplateRegistration.registerTemplatesForZone(zoneId, filePath);
|
||||
mockedStatic.verify(() -> SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath,
|
||||
nfsVersion));
|
||||
verify(systemVmTemplateRegistration).registerTemplateForNonExistingEntries(hypervisorType,
|
||||
arch, name, storeUrlAndId, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,11 +58,12 @@ function createMetadataFile() {
|
||||
for template in "${templates[@]}"
|
||||
do
|
||||
section="${template%%:*}"
|
||||
hvName=$(getGenericName $section)
|
||||
sectionHv="${section%%-*}"
|
||||
hvName=$(getGenericName $sectionHv)
|
||||
|
||||
downloadurl="${template#*:}"
|
||||
arch=$(echo ${downloadurl#*"/systemvmtemplate-$VERSION-"} | cut -d'-' -f 1)
|
||||
templatename="systemvm-${section%.*}-${VERSION}-${arch}"
|
||||
templatename="systemvm-${sectionHv%.*}-${VERSION}-${arch}"
|
||||
checksum=$(getChecksum "$fileData" "$VERSION-${arch}-$hvName")
|
||||
filename=$(echo ${downloadurl##*'/'})
|
||||
echo -e "["$section"]\ntemplatename = $templatename\nchecksum = $checksum\ndownloadurl = $downloadurl\nfilename = $filename\narch = $arch\n" >> $METADATAFILE
|
||||
@ -71,7 +72,8 @@ function createMetadataFile() {
|
||||
|
||||
declare -a templates
|
||||
getTemplateVersion $1
|
||||
templates=( "kvm:https://download.cloudstack.org/systemvm/${CS_VERSION}/systemvmtemplate-$VERSION-x86_64-kvm.qcow2.bz2"
|
||||
templates=( "kvm-x86_64:https://download.cloudstack.org/systemvm/${CS_VERSION}/systemvmtemplate-$VERSION-x86_64-kvm.qcow2.bz2"
|
||||
"kvm-aarch64:https://download.cloudstack.org/systemvm/${CS_VERSION}/systemvmtemplate-$VERSION-aarch64-kvm.qcow2.bz2"
|
||||
"vmware:https://download.cloudstack.org/systemvm/${CS_VERSION}/systemvmtemplate-$VERSION-x86_64-vmware.ova"
|
||||
"xenserver:https://download.cloudstack.org/systemvm/$CS_VERSION/systemvmtemplate-$VERSION-x86_64-xen.vhd.bz2"
|
||||
"hyperv:https://download.cloudstack.org/systemvm/$CS_VERSION/systemvmtemplate-$VERSION-x86_64-hyperv.vhd.zip"
|
||||
|
||||
@ -573,6 +573,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
||||
} else {
|
||||
field.set(entity, rs.getLong(index));
|
||||
}
|
||||
} else if (field.getDeclaredAnnotation(Convert.class) != null) {
|
||||
Object val = _conversionSupport.convertToEntityAttribute(field, rs.getObject(index));
|
||||
field.set(entity, val);
|
||||
} else if (type.isEnum()) {
|
||||
final Enumerated enumerated = field.getAnnotation(Enumerated.class);
|
||||
final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
|
||||
@ -677,9 +680,6 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
||||
}
|
||||
} else if (type == byte[].class) {
|
||||
field.set(entity, rs.getBytes(index));
|
||||
} else if (field.getDeclaredAnnotation(Convert.class) != null) {
|
||||
Object val = _conversionSupport.convertToEntityAttribute(field, rs.getObject(index));
|
||||
field.set(entity, val);
|
||||
} else {
|
||||
field.set(entity, rs.getObject(index));
|
||||
}
|
||||
@ -949,7 +949,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
||||
}
|
||||
|
||||
@DB()
|
||||
protected List<T> listBy(SearchCriteria<T> sc, final Filter filter) {
|
||||
public List<T> listBy(SearchCriteria<T> sc, final Filter filter) {
|
||||
sc = checkAndSetRemovedIsNull(sc);
|
||||
return listIncludingRemovedBy(sc, filter);
|
||||
}
|
||||
|
||||
@ -36,6 +36,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import net.sf.cglib.proxy.Factory;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
@ -122,7 +124,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
||||
if (_entity == null) {
|
||||
throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
|
||||
}
|
||||
if (_specifiedAttrs.size() > 1) {
|
||||
if (func.getCount() <= 1 && _specifiedAttrs.size() > 1) {
|
||||
throw new RuntimeException("You can't specify more than one field to search on");
|
||||
}
|
||||
if (func.getCount() != -1 && (func.getCount() != (params.length + 1))) {
|
||||
@ -150,7 +152,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
||||
}
|
||||
}
|
||||
|
||||
final Select select = new Select(func, _specifiedAttrs.size() == 0 ? null : _specifiedAttrs.get(0), declaredField, params);
|
||||
final Select select = new Select(func, _specifiedAttrs, declaredField, params);
|
||||
_selects.add(select);
|
||||
|
||||
_specifiedAttrs.clear();
|
||||
@ -185,7 +187,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
||||
} catch (final SecurityException e) {
|
||||
} catch (final NoSuchFieldException e) {
|
||||
}
|
||||
_selects.add(new Select(Func.NATIVE, attr, field, null));
|
||||
_selects.add(new Select(Func.NATIVE, List.of(attr), field, null));
|
||||
}
|
||||
|
||||
_specifiedAttrs.clear();
|
||||
@ -531,16 +533,18 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
||||
|
||||
protected static class Select {
|
||||
public Func func;
|
||||
public Attribute attr;
|
||||
public List<Attribute> attributes = new ArrayList<>();
|
||||
public Object[] params;
|
||||
public Field field;
|
||||
|
||||
protected Select() {
|
||||
}
|
||||
|
||||
public Select(final Func func, final Attribute attr, final Field field, final Object[] params) {
|
||||
public Select(final Func func, final List<Attribute> attributes, final Field field, final Object[] params) {
|
||||
this.func = func;
|
||||
this.attr = attr;
|
||||
if (CollectionUtils.isNotEmpty(attributes)) {
|
||||
this.attributes.addAll(attributes);
|
||||
}
|
||||
this.params = params;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
@ -59,7 +60,7 @@ public class SearchCriteria<K> {
|
||||
}
|
||||
|
||||
public enum Func {
|
||||
NATIVE("@", 1), MAX("MAX(@)", 1), MIN("MIN(@)", 1), FIRST("FIRST(@)", 1), LAST("LAST(@)", 1), SUM("SUM(@)", 1), COUNT("COUNT(@)", 1), DISTINCT("DISTINCT(@)", 1);
|
||||
NATIVE("@", 1), MAX("MAX(@)", 1), MIN("MIN(@)", 1), FIRST("FIRST(@)", 1), LAST("LAST(@)", 1), SUM("SUM(@)", 1), COUNT("COUNT(@)", 1), DISTINCT("DISTINCT(@)", 1), DISTINCT_PAIR("DISTINCT @, @", 2);
|
||||
|
||||
private String func;
|
||||
private int count;
|
||||
@ -135,10 +136,12 @@ public class SearchCriteria<K> {
|
||||
|
||||
for (Select select : _selects) {
|
||||
String func = select.func.toString() + ",";
|
||||
if (select.attr == null) {
|
||||
if (CollectionUtils.isEmpty(select.attributes)) {
|
||||
func = func.replace("@", "*");
|
||||
} else {
|
||||
func = func.replace("@", select.attr.table + "." + select.attr.columnName);
|
||||
for (Attribute attribute : select.attributes) {
|
||||
func = func.replaceFirst("@", attribute.table + "." + attribute.columnName);
|
||||
}
|
||||
}
|
||||
str.insert(insertAt, func);
|
||||
insertAt += func.length();
|
||||
|
||||
@ -470,6 +470,8 @@ if [ -f %{_sysconfdir}/sysconfig/%{name}-management ] ; then
|
||||
fi
|
||||
|
||||
chown -R cloud:cloud /var/log/cloudstack/management
|
||||
chown -R cloud:cloud /usr/share/cloudstack-management/templates
|
||||
find /usr/share/cloudstack-management/templates -type d -exec chmod 0770 {} \;
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
@ -610,6 +612,9 @@ pip3 install --upgrade /usr/share/cloudstack-marvin/Marvin-*.tar.gz
|
||||
%{_datadir}/%{name}-management/setup/*.sh
|
||||
%{_datadir}/%{name}-management/setup/server-setup.xml
|
||||
%{_datadir}/%{name}-management/webapp/*
|
||||
%dir %attr(0770, cloud, cloud) %{_datadir}/%{name}-management/templates
|
||||
%dir %attr(0770, cloud, cloud) %{_datadir}/%{name}-management/templates/systemvm
|
||||
%attr(0644, cloud, cloud) %{_datadir}/%{name}-management/templates/systemvm/*
|
||||
%attr(0755,root,root) %{_bindir}/%{name}-external-ipallocator.py
|
||||
%attr(0755,root,root) %{_initrddir}/%{name}-ipallocator
|
||||
%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/ipallocator
|
||||
|
||||
@ -47,7 +47,7 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
||||
private RoleService roleService;
|
||||
|
||||
private List<PluggableService> services;
|
||||
private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<>();
|
||||
private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<RoleType, Set<String>>();
|
||||
|
||||
private LazyCache<Long, Account> accountCache;
|
||||
private LazyCache<Long, Pair<Role, List<RolePermission>>> rolePermissionsCache;
|
||||
@ -56,7 +56,7 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
||||
protected DynamicRoleBasedAPIAccessChecker() {
|
||||
super();
|
||||
for (RoleType roleType : RoleType.values()) {
|
||||
annotationRoleBasedApisMap.put(roleType, new HashSet<>());
|
||||
annotationRoleBasedApisMap.put(roleType, new HashSet<String>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -167,6 +167,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;
|
||||
@ -2671,9 +2672,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
devices.addDevice(createVideoDef(vmTO));
|
||||
devices.addDevice(createConsoleDef());
|
||||
devices.addDevice(createGraphicDef(vmTO));
|
||||
|
||||
if (!isGuestS390x()) {
|
||||
devices.addDevice(createTabletInputDef());
|
||||
}
|
||||
|
||||
TpmDef tpmDef = createTpmDef(vmTO);
|
||||
if (tpmDef != null) {
|
||||
devices.addDevice(tpmDef);
|
||||
}
|
||||
|
||||
if (isGuestAarch64()) {
|
||||
createArm64UsbDef(devices);
|
||||
}
|
||||
@ -2856,8 +2864,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);
|
||||
}
|
||||
@ -2866,6 +2877,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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ public interface MockAgentManager extends Manager {
|
||||
public static final long DEFAULT_HOST_MEM_SIZE = 8 * 1024 * 1024 * 1024L; // 8G, unit of Mbytes
|
||||
public static final int DEFAULT_HOST_CPU_CORES = 4; // 2 dual core CPUs (2 x 2)
|
||||
public static final int DEFAULT_HOST_SPEED_MHZ = 8000; // 1 GHz CPUs
|
||||
public static final String DEFAULT_HOST_ARCH = "x86_64";
|
||||
|
||||
@Override
|
||||
boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
|
||||
|
||||
@ -153,6 +153,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage
|
||||
long cpuSpeed = Long.parseLong((String)params.get("cpuspeed"));
|
||||
long memory = Long.parseLong((String)params.get("memory"));
|
||||
long localStorageSize = Long.parseLong((String)params.get("localstorage"));
|
||||
String arch = (String)params.get("arch");
|
||||
synchronized (this) {
|
||||
long dataCenterId = Long.parseLong((String)params.get("zone"));
|
||||
long podId = Long.parseLong((String)params.get("pod"));
|
||||
@ -170,6 +171,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage
|
||||
mockHost.setCpuCount(cpuCore);
|
||||
mockHost.setCpuSpeed(cpuSpeed);
|
||||
mockHost.setMemorySize(memory);
|
||||
mockHost.setArch(arch);
|
||||
String guid = UUID.randomUUID().toString();
|
||||
mockHost.setGuid(guid);
|
||||
mockHost.setName("SimulatedAgent." + guid);
|
||||
|
||||
@ -177,6 +177,7 @@ public class AgentRoutingResource extends AgentStorageResource {
|
||||
StartupRoutingCommand cmd =
|
||||
new StartupRoutingCommand((Integer)info.get(0), (Long)info.get(1), (Long)info.get(2), (Long)info.get(4), (String)info.get(3), HypervisorType.Simulator,
|
||||
RouterPrivateIpStrategy.HostLocal);
|
||||
cmd.setCpuArch((String)info.get(5));
|
||||
|
||||
Map<String, String> hostDetails = new HashMap<String, String>();
|
||||
hostDetails.put(RouterPrivateIpStrategy.class.getCanonicalName(), RouterPrivateIpStrategy.DcGlobal.toString());
|
||||
@ -274,12 +275,14 @@ public class AgentRoutingResource extends AgentStorageResource {
|
||||
long cpus = agentHost.getCpuCount();
|
||||
long ram = agentHost.getMemorySize();
|
||||
long dom0Ram = agentHost.getMemorySize() / 10;
|
||||
String arch = agentHost.getArch();
|
||||
|
||||
info.add((int)cpus);
|
||||
info.add(speed);
|
||||
info.add(ram);
|
||||
info.add(agentHost.getCapabilities());
|
||||
info.add(dom0Ram);
|
||||
info.add(arch);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -87,6 +87,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L
|
||||
long cpuCores = MockAgentManager.DEFAULT_HOST_CPU_CORES;
|
||||
long memory = MockAgentManager.DEFAULT_HOST_MEM_SIZE;
|
||||
long localstorageSize = MockStorageManager.DEFAULT_HOST_STORAGE_SIZE;
|
||||
String arch = MockAgentManager.DEFAULT_HOST_ARCH;
|
||||
if (scheme.equals("http")) {
|
||||
if (host == null || !host.startsWith("sim")) {
|
||||
String msg = "uri is not of simulator type so we're not taking care of the discovery for this: " + uri;
|
||||
@ -111,6 +112,8 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L
|
||||
memory = Long.parseLong(parameter[1]);
|
||||
} else if (parameter[0].equalsIgnoreCase("localstorage") && parameter[1] != null) {
|
||||
localstorageSize = Long.parseLong(parameter[1]);
|
||||
} else if (parameter[0].equalsIgnoreCase("arch") && parameter[1] != null) {
|
||||
arch = parameter[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,6 +171,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L
|
||||
params.put("cpucore", Long.toString(cpuCores));
|
||||
params.put("memory", Long.toString(memory));
|
||||
params.put("localstorage", Long.toString(localstorageSize));
|
||||
params.put("arch", arch);
|
||||
|
||||
resources = createAgentResources(params);
|
||||
return resources;
|
||||
|
||||
@ -23,6 +23,8 @@ public interface MockHost {
|
||||
|
||||
public long getMemorySize();
|
||||
|
||||
String getArch();
|
||||
|
||||
public String getCapabilities();
|
||||
|
||||
public long getId();
|
||||
|
||||
@ -87,6 +87,9 @@ public class MockHostVO implements MockHost, InternalIdentity {
|
||||
@Column(name = "ram")
|
||||
private long memorySize;
|
||||
|
||||
@Column(name = "arch")
|
||||
private String arch;
|
||||
|
||||
@Column(name = "capabilities")
|
||||
private String capabilities;
|
||||
|
||||
@ -143,6 +146,14 @@ public class MockHostVO implements MockHost, InternalIdentity {
|
||||
this.memorySize = memorySize;
|
||||
}
|
||||
|
||||
public String getArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public void setArch(String arch) {
|
||||
this.arch = arch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCapabilities() {
|
||||
return this.capabilities;
|
||||
|
||||
@ -22,15 +22,12 @@ import com.cloud.dc.VmwareDatacenterVO;
|
||||
import com.cloud.dc.VsphereStoragePolicy;
|
||||
import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcHostsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
||||
@ -56,7 +53,5 @@ public interface VmwareDatacenterService extends PluggableService {
|
||||
|
||||
List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
|
||||
|
||||
List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd);
|
||||
|
||||
Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
|
||||
List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
|
||||
}
|
||||
|
||||
@ -19,12 +19,10 @@ package com.cloud.hypervisor.vmware.manager;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.rmi.RemoteException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@ -45,11 +43,10 @@ import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcHostsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcItems;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
||||
@ -89,7 +86,6 @@ import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.ClusterVSMMapVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.VmwareDatacenter;
|
||||
import com.cloud.dc.VsphereStoragePolicy;
|
||||
import com.cloud.dc.VsphereStoragePolicyVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
@ -115,8 +111,7 @@ import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||
import com.cloud.hypervisor.vmware.LegacyZoneVO;
|
||||
import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareClientException;
|
||||
import com.cloud.dc.VmwareDatacenter;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.dc.VmwareDatacenterVO;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
|
||||
@ -173,16 +168,9 @@ import com.cloud.utils.ssh.SshHelper;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
// TODO move these items upstream?
|
||||
import com.vmware.pbm.PbmProfile;
|
||||
import com.vmware.vim25.AboutInfo;
|
||||
import com.vmware.vim25.ManagedObjectReference;
|
||||
import com.vmware.vim25.InvalidLocaleFaultMsg;
|
||||
import com.vmware.vim25.InvalidLoginFaultMsg;
|
||||
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
|
||||
|
||||
@ -257,11 +245,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
private StorageLayer _storage;
|
||||
private final String _privateNetworkVSwitchName = "vSwitch0";
|
||||
|
||||
private final int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
|
||||
private int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
|
||||
private boolean _fullCloneFlag;
|
||||
private boolean _instanceNameFlag;
|
||||
private String _serviceConsoleName;
|
||||
private String _managementPortGroupName;
|
||||
private String _managemetPortGroupName;
|
||||
private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
||||
private String _recycleHungWorker = "false";
|
||||
private int _additionalPortRangeStart;
|
||||
@ -275,7 +263,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
private final Random _rand = new Random(System.currentTimeMillis());
|
||||
|
||||
private static final ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));
|
||||
private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));;
|
||||
|
||||
private final VmwareStorageManager _storageMgr;
|
||||
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
||||
@ -359,9 +347,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
_serviceConsoleName = "Service Console";
|
||||
}
|
||||
|
||||
_managementPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
|
||||
if (_managementPortGroupName == null) {
|
||||
_managementPortGroupName = "Management Network";
|
||||
_managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
|
||||
if (_managemetPortGroupName == null) {
|
||||
_managemetPortGroupName = "Management Network";
|
||||
}
|
||||
|
||||
_defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
|
||||
@ -460,7 +448,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
|
||||
VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
|
||||
//The management network is probably always going to be a physical network with isolation type of vlans, so assume BroadcastDomainType VLAN
|
||||
//The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
|
||||
if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
|
||||
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
|
||||
}
|
||||
@ -469,7 +457,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
AboutInfo about = hostMo.getHostAboutInfo();
|
||||
if (about != null) {
|
||||
String version = about.getApiVersion();
|
||||
if (version != null && (version.equals("4.0") || version.equals("4.1")) ) { // && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x)
|
||||
if (version != null && (version.equals("4.0") || version.equals("4.1")) && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x) {
|
||||
portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x;
|
||||
}
|
||||
}
|
||||
@ -492,7 +480,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
URI uriForHost = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url") + "/" + host.getName()));
|
||||
morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), StandardCharsets.UTF_8));
|
||||
morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), "UTF-8"));
|
||||
if (morSrcHost == null) {
|
||||
return null;
|
||||
}
|
||||
@ -508,18 +496,19 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
throw new CloudRuntimeException("Invalid serviceContext");
|
||||
}
|
||||
ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
|
||||
String privateTrafficLabel;
|
||||
String privateTrafficLabel = null;
|
||||
privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
|
||||
if (privateTrafficLabel == null) {
|
||||
privateTrafficLabel = _privateNetworkVSwitchName;
|
||||
}
|
||||
|
||||
if (mor != null) {
|
||||
List<ManagedObjectReference> returnedHostList = new ArrayList<>();
|
||||
List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>();
|
||||
|
||||
if (mor.getType().equals("ComputeResource")) {
|
||||
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
||||
assert (CollectionUtils.isNullOrEmpty(hosts));
|
||||
assert (hosts != null && hosts.size() > 0);
|
||||
|
||||
// For ESX host, we need to enable host firewall to allow VNC access
|
||||
HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
|
||||
|
||||
@ -530,8 +519,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
||||
assert (hosts != null);
|
||||
|
||||
if (!hosts.isEmpty()) {
|
||||
AboutInfo about = serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product");
|
||||
if (hosts.size() > 0) {
|
||||
AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"));
|
||||
String version = about.getApiVersion();
|
||||
int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
|
||||
if (hosts.size() > maxHostsPerCluster) {
|
||||
@ -625,13 +614,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
@Override
|
||||
public String getManagementPortGroupName() {
|
||||
return _managementPortGroupName;
|
||||
return _managemetPortGroupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
|
||||
if (hostMo.getHostType() == VmwareHostType.ESXi) {
|
||||
return _managementPortGroupName;
|
||||
return _managemetPortGroupName;
|
||||
}
|
||||
return _serviceConsoleName;
|
||||
}
|
||||
@ -641,7 +630,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
params.put("vmware.create.full.clone", _fullCloneFlag);
|
||||
params.put("vm.instancename.flag", _instanceNameFlag);
|
||||
params.put("service.console.name", _serviceConsoleName);
|
||||
params.put("management.portgroup.name", _managementPortGroupName);
|
||||
params.put("management.portgroup.name", _managemetPortGroupName);
|
||||
params.put("vmware.root.disk.controller", _rootDiskController);
|
||||
params.put("vmware.data.disk.controller", _dataDiskController);
|
||||
params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
|
||||
@ -668,23 +657,23 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] tokens = workerTag.split("-");
|
||||
String tokens[] = workerTag.split("-");
|
||||
if (tokens.length != 3) {
|
||||
logger.error("Invalid worker VM tag " + workerTag);
|
||||
return false;
|
||||
}
|
||||
|
||||
long startTick = Long.parseLong(tokens[0]);
|
||||
long msId = Long.parseLong(tokens[1]);
|
||||
long runId = Long.parseLong(tokens[2]);
|
||||
long msid = Long.parseLong(tokens[1]);
|
||||
long runid = Long.parseLong(tokens[2]);
|
||||
|
||||
if (msHostPeerDao.countStateSeenInPeers(msId, runId, ManagementServerHost.State.Down) > 0) {
|
||||
if (msHostPeerDao.countStateSeenInPeers(msid, runid, ManagementServerHost.State.Down) > 0) {
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (runId != clusterManager.getManagementRunId(msId)) {
|
||||
if (runid != clusterManager.getManagementRunId(msid)) {
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Worker VM's owner management server has changed runid, recycle it");
|
||||
return true;
|
||||
@ -782,6 +771,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
|
||||
}
|
||||
|
||||
assert (isoFile != null);
|
||||
if (!isoFile.exists()) {
|
||||
logger.error("Unable to locate systemvm.iso in your setup at " + isoFile);
|
||||
}
|
||||
@ -798,7 +788,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
if (keyFile == null || !keyFile.exists()) {
|
||||
keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
|
||||
}
|
||||
|
||||
assert (keyFile != null);
|
||||
if (!keyFile.exists()) {
|
||||
logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile);
|
||||
}
|
||||
@ -807,7 +797,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
@Override
|
||||
public String getMountPoint(String storageUrl, String nfsVersion) {
|
||||
String mountPoint;
|
||||
String mountPoint = null;
|
||||
synchronized (_storageMounts) {
|
||||
mountPoint = _storageMounts.get(storageUrl);
|
||||
if (mountPoint != null) {
|
||||
@ -837,7 +827,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
String mountPoint = null;
|
||||
long mshostId = ManagementServerNode.getManagementServerId();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String mntPt = parent + File.separator + mshostId + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
|
||||
String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
|
||||
File file = new File(mntPt);
|
||||
if (!file.exists()) {
|
||||
if (_storage.mkdir(mntPt)) {
|
||||
@ -862,9 +852,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
for (String mountPoint : mounts) {
|
||||
logger.info("umount NFS mount from previous session: " + mountPoint);
|
||||
|
||||
String result = null;
|
||||
Script command = new Script(true, "umount", _timeout, logger);
|
||||
command.add(mountPoint);
|
||||
String result = command.execute();
|
||||
result = command.execute();
|
||||
if (result != null) {
|
||||
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
||||
}
|
||||
@ -882,9 +873,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
for (String mountPoint : _storageMounts.values()) {
|
||||
logger.info("umount NFS mount: " + mountPoint);
|
||||
|
||||
String result = null;
|
||||
Script command = new Script(true, "umount", _timeout, logger);
|
||||
command.add(mountPoint);
|
||||
String result = command.execute();
|
||||
result = command.execute();
|
||||
if (result != null) {
|
||||
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
||||
}
|
||||
@ -902,8 +894,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
return null;
|
||||
}
|
||||
|
||||
Script script;
|
||||
String result;
|
||||
Script script = null;
|
||||
String result = null;
|
||||
Script command = new Script(true, "mount", _timeout, logger);
|
||||
command.add("-t", "nfs");
|
||||
if (nfsVersion != null){
|
||||
@ -990,9 +982,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
@Override
|
||||
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
|
||||
if (cmd != null) {
|
||||
if (cmd instanceof StartupCommand) {
|
||||
if (host.getHypervisorType() == HypervisorType.VMware) {
|
||||
updateClusterNativeHAState(host, cmd);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1062,16 +1056,16 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
@Override
|
||||
public Pair<Integer, Integer> getAddiionalVncPortRange() {
|
||||
return new Pair<>(_additionalPortRangeStart, _additionalPortRangeSize);
|
||||
return new Pair<Integer, Integer>(_additionalPortRangeStart, _additionalPortRangeSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
|
||||
CiscoNexusVSMDeviceVO nexusVSM;
|
||||
ClusterVSMMapVO vsmMapVO;
|
||||
CiscoNexusVSMDeviceVO nexusVSM = null;
|
||||
ClusterVSMMapVO vsmMapVO = null;
|
||||
|
||||
vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
|
||||
long vsmId;
|
||||
long vsmId = 0;
|
||||
if (vsmMapVO != null) {
|
||||
vsmId = vsmMapVO.getVsmId();
|
||||
logger.info("vsmId is " + vsmId);
|
||||
@ -1082,7 +1076,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, String> nexusVSMCredentials = new HashMap<>();
|
||||
Map<String, String> nexusVSMCredentials = new HashMap<String, String>();
|
||||
if (nexusVSM != null) {
|
||||
nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
|
||||
nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
|
||||
@ -1109,7 +1103,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmdList = new ArrayList<>();
|
||||
List<Class<?>> cmdList = new ArrayList<Class<?>>();
|
||||
cmdList.add(AddVmwareDcCmd.class);
|
||||
cmdList.add(UpdateVmwareDcCmd.class);
|
||||
cmdList.add(RemoveVmwareDcCmd.class);
|
||||
@ -1118,14 +1112,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
cmdList.add(ListVsphereStoragePoliciesCmd.class);
|
||||
cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
|
||||
cmdList.add(ListVmwareDcVmsCmd.class);
|
||||
cmdList.add(ListVmwareDcHostsCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
|
||||
VmwareDatacenterVO vmwareDc;
|
||||
VmwareDatacenterVO vmwareDc = null;
|
||||
Long zoneId = cmd.getZoneId();
|
||||
String userName = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
@ -1181,10 +1174,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId);
|
||||
|
||||
VmwareContext context = null;
|
||||
DatacenterMO dcMo;
|
||||
DatacenterMO dcMo = null;
|
||||
String dcCustomFieldValue;
|
||||
boolean addDcCustomFieldDef = false;
|
||||
boolean dcInUse;
|
||||
boolean dcInUse = false;
|
||||
String guid;
|
||||
ManagedObjectReference dcMor;
|
||||
try {
|
||||
@ -1217,7 +1210,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
// Map zone with vmware datacenter
|
||||
vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
|
||||
|
||||
vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
|
||||
vmwareDcZoneMap = vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
|
||||
|
||||
// Set custom field for this DC
|
||||
if (addDcCustomFieldDef) {
|
||||
@ -1237,6 +1230,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
context = null;
|
||||
}
|
||||
importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
|
||||
return vmwareDc;
|
||||
@ -1261,9 +1255,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
* Check if DC is already part of zone
|
||||
* In that case vmware_data_center table should have the DC and a dc zone mapping should exist
|
||||
*
|
||||
* @param vCenterHost the vcenter appliance hostname
|
||||
* @param vmwareDcName the name of the vmware DC
|
||||
* @param zoneId zone that the DC should be connected to
|
||||
* @param vCenterHost
|
||||
* @param vmwareDcName
|
||||
* @param zoneId
|
||||
* @throws ResourceInUseException if the DC can not be used.
|
||||
*/
|
||||
private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneId) throws ResourceInUseException {
|
||||
@ -1271,7 +1265,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
|
||||
if (vmwareDc != null) {
|
||||
VmwareDatacenterZoneMapVO mapping = vmwareDatacenterZoneMapDao.findByVmwareDcId(vmwareDc.getId());
|
||||
if (mapping != null && zoneId == mapping.getZoneId()) {
|
||||
if (mapping != null && Long.compare(zoneId, mapping.getZoneId()) == 0) {
|
||||
throw new ResourceInUseException(String.format("This DC (%s) is already part of other CloudStack zone (%d). Cannot add this DC to more zones.", vmwareDc.getUuid(), zoneId));
|
||||
}
|
||||
}
|
||||
@ -1280,7 +1274,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
|
||||
public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
|
||||
final long zoneId = cmd.getZoneId();
|
||||
final Long zoneId = cmd.getZoneId();
|
||||
final String userName = cmd.getUsername();
|
||||
final String password = cmd.getPassword();
|
||||
final String vCenterHost = cmd.getVcenter();
|
||||
@ -1308,7 +1302,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost()));
|
||||
|
||||
return Transaction.execute(new TransactionCallback<>() {
|
||||
return Transaction.execute(new TransactionCallback<VmwareDatacenter>() {
|
||||
@Override
|
||||
public VmwareDatacenter doInTransaction(TransactionStatus status) {
|
||||
if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
|
||||
@ -1357,7 +1351,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
String vCenterHost;
|
||||
String userName;
|
||||
String password;
|
||||
DatacenterMO dcMo;
|
||||
DatacenterMO dcMo = null;
|
||||
final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
|
||||
// Check if zone is associated with VMware DC
|
||||
if (vmwareDcZoneMap == null) {
|
||||
@ -1394,9 +1388,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
throw new DiscoveryException(msg);
|
||||
}
|
||||
|
||||
assert (dcMo != null);
|
||||
|
||||
// Reset custom field property cloud.zone over this DC
|
||||
dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
|
||||
logger.info("Sucessfully reset custom field property cloud.zone over DC {}", vmwareDcName);
|
||||
logger.info("Successfully reset custom field property cloud.zone over DC {}", vmwareDcName);
|
||||
} catch (Exception e) {
|
||||
String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
|
||||
logger.error(msg);
|
||||
@ -1405,6 +1401,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
context = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1425,7 +1422,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
|
||||
// Check if zone has resources? - For now look for clusters
|
||||
List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
|
||||
if (!CollectionUtils.isNullOrEmpty(clusters)) {
|
||||
if (clusters != null && clusters.size() > 0) {
|
||||
// Look for VMware hypervisor.
|
||||
for (ClusterVO cluster : clusters) {
|
||||
if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
|
||||
@ -1446,9 +1443,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException {
|
||||
public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException {
|
||||
Long zoneId = cmd.getZoneId();
|
||||
List<VmwareDatacenterVO> vmwareDcList = new ArrayList<>();
|
||||
List<VmwareDatacenterVO> vmwareDcList = new ArrayList<VmwareDatacenterVO>();
|
||||
VmwareDatacenterZoneMapVO vmwareDcZoneMap;
|
||||
VmwareDatacenterVO vmwareDatacenter;
|
||||
long vmwareDcId;
|
||||
@ -1506,7 +1503,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
String vCenterHost = vmwareDatacenter.getVcenterHost();
|
||||
String userName = vmwareDatacenter.getUser();
|
||||
String password = vmwareDatacenter.getPassword();
|
||||
List<PbmProfile> storageProfiles;
|
||||
List<PbmProfile> storageProfiles = null;
|
||||
try {
|
||||
logger.debug(String.format("Importing vSphere Storage Policies for the vmware DC %d in zone %d", vmwareDcId, zoneId));
|
||||
VmwareContext context = VmwareContextFactory.getContext(vCenterHost, userName, password);
|
||||
@ -1534,15 +1531,16 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
List<VsphereStoragePolicyVO> allStoragePolicies = vsphereStoragePolicyDao.listAll();
|
||||
List<PbmProfile> finalStorageProfiles = storageProfiles;
|
||||
List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
|
||||
.filter(existingPolicy -> finalStorageProfiles.stream()
|
||||
.noneMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
|
||||
.filter(existingPolicy -> !finalStorageProfiles.stream()
|
||||
.anyMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
|
||||
vsphereStoragePolicyDao.remove(storagePolicy.getId());
|
||||
}
|
||||
|
||||
return vsphereStoragePolicyDao.listAll();
|
||||
List<VsphereStoragePolicyVO> storagePolicies = vsphereStoragePolicyDao.listAll();
|
||||
return storagePolicies;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1588,87 +1586,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd) {
|
||||
VcenterData vmwaredc = getVcenterData(cmd);
|
||||
|
||||
try {
|
||||
VmwareContext context = getVmwareContext(vmwaredc);
|
||||
DatacenterMO dcMo = getDatacenterMO(context, vmwaredc);
|
||||
return dcMo.getAllHostsOnDatacenter();
|
||||
} catch (RuntimeFaultFaultMsg | URISyntaxException | VmwareClientException | InvalidLocaleFaultMsg |
|
||||
InvalidLoginFaultMsg | InvalidPropertyFaultMsg e) {
|
||||
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
||||
vmwaredc.vcenter, vmwaredc.datacenterName, e.getMessage());
|
||||
logger.error(errorMsg, e);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
|
||||
Integer maxObjects = cmd.getBatchSize();
|
||||
String token = cmd.getToken();
|
||||
String host = cmd.getHost();
|
||||
|
||||
VcenterData vmwaredc = getVcenterData(cmd);
|
||||
|
||||
try {
|
||||
VmwareContext context = getVmwareContext(vmwaredc);
|
||||
|
||||
DatacenterMO dcMo = getDatacenterMO(context, vmwaredc);
|
||||
|
||||
if (com.cloud.utils.StringUtils.isNotBlank(host)) {
|
||||
ManagedObjectReference hostMor = dcMo.findHost(host);
|
||||
if (hostMor == null) {
|
||||
throw new VmwareClientException(String.format("No host '%s' found on DC: %s.", host, dcMo.getName()));
|
||||
}
|
||||
HostMO hostMo = new HostMO(context, hostMor);
|
||||
return hostMo.getVms(maxObjects, token);
|
||||
} else {
|
||||
return dcMo.getVms(maxObjects, token);
|
||||
}
|
||||
} catch (InvalidParameterValueException | VmwareClientException | InvalidLocaleFaultMsg | InvalidLoginFaultMsg |
|
||||
RuntimeFaultFaultMsg | URISyntaxException | InvalidPropertyFaultMsg | InvocationTargetException |
|
||||
NoSuchMethodException | IllegalAccessException e) {
|
||||
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
||||
vmwaredc.vcenter, vmwaredc.datacenterName, e.getMessage());
|
||||
logger.error(errorMsg, e);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DatacenterMO getDatacenterMO(VmwareContext context, VcenterData vmwaredc) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||
DatacenterMO dcMo = new DatacenterMO(context, vmwaredc.datacenterName);
|
||||
ManagedObjectReference dcMor = dcMo.getMor();
|
||||
if (dcMor == null) {
|
||||
String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
|
||||
vmwaredc.datacenterName, vmwaredc.vcenter);
|
||||
logger.error(msg);
|
||||
throw new InvalidParameterValueException(msg);
|
||||
}
|
||||
return dcMo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private VmwareContext getVmwareContext(VcenterData vmwaredc) throws RuntimeFaultFaultMsg, URISyntaxException, VmwareClientException, InvalidLocaleFaultMsg, InvalidLoginFaultMsg {
|
||||
logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
|
||||
vmwaredc.datacenterName, vmwaredc.vcenter));
|
||||
String serviceUrl = String.format("https://%s/sdk/vimService", vmwaredc.vcenter);
|
||||
VmwareClient vimClient = new VmwareClient(vmwaredc.vcenter);
|
||||
vimClient.connect(serviceUrl, vmwaredc.username, vmwaredc.password);
|
||||
VmwareContext context = new VmwareContext(vimClient, vmwaredc.vcenter);
|
||||
return context;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private VcenterData getVcenterData(ListVmwareDcItems cmd) {
|
||||
public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
|
||||
String vcenter = cmd.getVcenter();
|
||||
String datacenterName = cmd.getDatacenterName();
|
||||
String username = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
Long existingVcenterId = cmd.getExistingVcenterId();
|
||||
String keyword = cmd.getKeyword();
|
||||
|
||||
if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
|
||||
(existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
|
||||
@ -1689,27 +1613,37 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
username = vmwareDc.getUser();
|
||||
password = vmwareDc.getPassword();
|
||||
}
|
||||
VcenterData vmwaredc = new VcenterData(vcenter, datacenterName, username, password);
|
||||
return vmwaredc;
|
||||
}
|
||||
|
||||
private static class VcenterData {
|
||||
public final String vcenter;
|
||||
public final String datacenterName;
|
||||
public final String username;
|
||||
public final String password;
|
||||
try {
|
||||
logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
|
||||
datacenterName, vcenter));
|
||||
String serviceUrl = String.format("https://%s/sdk/vimService", vcenter);
|
||||
VmwareClient vimClient = new VmwareClient(vcenter);
|
||||
vimClient.connect(serviceUrl, username, password);
|
||||
VmwareContext context = new VmwareContext(vimClient, vcenter);
|
||||
|
||||
public VcenterData(String vcenter, String datacenterName, String username, String password) {
|
||||
this.vcenter = vcenter;
|
||||
this.datacenterName = datacenterName;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
DatacenterMO dcMo = new DatacenterMO(context, datacenterName);
|
||||
ManagedObjectReference dcMor = dcMo.getMor();
|
||||
if (dcMor == null) {
|
||||
String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
|
||||
datacenterName, vcenter);
|
||||
logger.error(msg);
|
||||
throw new InvalidParameterValueException(msg);
|
||||
}
|
||||
List<UnmanagedInstanceTO> instances = dcMo.getAllVmsOnDatacenter();
|
||||
return StringUtils.isBlank(keyword) ? instances :
|
||||
instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
||||
vcenter, datacenterName, e.getMessage());
|
||||
logger.error(errorMsg, e);
|
||||
throw new CloudRuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNexusVSM(Long clusterId) {
|
||||
ClusterVSMMapVO vsmMapVo;
|
||||
ClusterVSMMapVO vsmMapVo = null;
|
||||
|
||||
vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
|
||||
if (vsmMapVo == null) {
|
||||
@ -1759,7 +1693,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
/**
|
||||
* This task is to clean-up templates from primary storage that are otherwise not cleaned by the {@see com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
|
||||
* This task is to cleanup templates from primary storage that are otherwise not cleaned by the {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
|
||||
* it is called at regular intervals when storage.template.cleanup.enabled == true
|
||||
* It collect all templates that
|
||||
* - are deleted from cloudstack
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -36,8 +36,8 @@ import com.cloud.dc.VmwareDatacenterVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = "addVmwareDc", description = "Adds a Vmware datacenter to specified zone",
|
||||
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false)
|
||||
@APICommand(name = "addVmwareDc", description = "Adds a VMware datacenter to specified zone", responseObject = VmwareDatacenterResponse.class,
|
||||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
|
||||
public class AddVmwareDcCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
@ -45,7 +45,7 @@ public class AddVmwareDcCmd extends BaseCmd {
|
||||
|
||||
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of Vmware datacenter to be added to specified zone.")
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of VMware datacenter to be added to specified zone.")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.VCENTER,
|
||||
@ -54,10 +54,10 @@ public class AddVmwareDcCmd extends BaseCmd {
|
||||
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
||||
private String vCenter;
|
||||
|
||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = false, description = "The Username required to connect to resource.")
|
||||
private String username;
|
||||
|
||||
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = false, description = "The password for specified username.")
|
||||
private String password;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID.")
|
||||
@ -99,7 +99,7 @@ public class AddVmwareDcCmd extends BaseCmd {
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("vmwaredc");
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Vmware Datacenter to zone.");
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add VMware Datacenter to zone.");
|
||||
}
|
||||
this.setResponseObject(response);
|
||||
} catch (DiscoveryException ex) {
|
||||
|
||||
@ -72,13 +72,6 @@ public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
||||
|
||||
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
|
||||
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
||||
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter);
|
||||
responseList.setResponses(storagePoliciesResponseList);
|
||||
responseList.setResponseName(getCommandName());
|
||||
setResponseObject(responseList);
|
||||
}
|
||||
|
||||
private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesResponses(List<? extends VsphereStoragePolicy> storagePolicies, DataCenter dataCenter) {
|
||||
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
||||
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
||||
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
||||
@ -91,7 +84,9 @@ public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
||||
|
||||
storagePoliciesResponseList.add(storagePoliciesResponse);
|
||||
}
|
||||
return storagePoliciesResponseList;
|
||||
responseList.setResponses(storagePoliciesResponseList);
|
||||
responseList.setResponseName(getCommandName());
|
||||
setResponseObject(responseList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,144 +0,0 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.zone;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listVmwareDcHosts", responseObject = VmwareRequestResponse.class,
|
||||
description = "Lists the VMs in a Vmware Datacenter",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class ListVmwareDcHostsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
|
||||
@Inject
|
||||
public VmwareDatacenterService _vmwareDatacenterService;
|
||||
|
||||
@Parameter(name = ApiConstants.EXISTING_VCENTER_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = VmwareDatacenterResponse.class,
|
||||
description = "UUID of a linked existing vCenter")
|
||||
private Long existingVcenterId;
|
||||
|
||||
@Parameter(name = ApiConstants.VCENTER,
|
||||
type = CommandType.STRING,
|
||||
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
||||
private String vcenter;
|
||||
|
||||
@Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of Vmware datacenter.")
|
||||
private String datacenterName;
|
||||
|
||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
||||
private String username;
|
||||
|
||||
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||
private String password;
|
||||
|
||||
public String getVcenter() {
|
||||
return vcenter;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getDatacenterName() {
|
||||
return datacenterName;
|
||||
}
|
||||
|
||||
public Long getExistingVcenterId() {
|
||||
return existingVcenterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
checkParameters();
|
||||
try {
|
||||
List<HostMO> hosts = _vmwareDatacenterService.listHostsInDatacenter(this);
|
||||
List<BaseResponse> baseResponseList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(hosts)) {
|
||||
for (HostMO vmwareHost : hosts) {
|
||||
HostResponse resp = createHostResponse(vmwareHost);
|
||||
baseResponseList.add(resp);
|
||||
}
|
||||
}
|
||||
VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
|
||||
response.setResponses(baseResponseList, baseResponseList.size());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (CloudRuntimeException | InvalidPropertyFaultMsg | RuntimeFaultFaultMsg | InvocationTargetException |
|
||||
NoSuchMethodException | IllegalAccessException e) {
|
||||
String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage());
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private HostResponse createHostResponse(HostMO hostInstance) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||
HostResponse response = new HostResponse();
|
||||
response.setHypervisor(Hypervisor.HypervisorType.VMware.toString());
|
||||
response.setName(hostInstance.getHostName());
|
||||
response.setObjectName("host");
|
||||
return response;
|
||||
}
|
||||
|
||||
private void checkParameters() {
|
||||
if ((existingVcenterId == null && vcenter == null) || (existingVcenterId != null && vcenter != null)) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
|
||||
"Please provide an existing vCenter ID or a vCenter IP/Name, parameters are mutually exclusive");
|
||||
}
|
||||
if (existingVcenterId == null && StringUtils.isAnyBlank(vcenter, datacenterName, username, password)) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
|
||||
"Please set all the information for a vCenter IP/Name, datacenter, username and password");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.zone;
|
||||
|
||||
public interface ListVmwareDcItems {
|
||||
String getVcenter();
|
||||
|
||||
String getDatacenterName();
|
||||
|
||||
String getUsername();
|
||||
|
||||
String getPassword();
|
||||
|
||||
Long getExistingVcenterId();
|
||||
}
|
||||
@ -23,15 +23,15 @@ import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
|
||||
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||
@ -42,10 +42,10 @@ import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestResponse.class,
|
||||
description = "Lists the VMs in a Vmware Datacenter",
|
||||
@APICommand(name = "listVmwareDcVms", responseObject = UnmanagedInstanceResponse.class,
|
||||
description = "Lists the VMs in a VMware Datacenter",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
public class ListVmwareDcVmsCmd extends BaseListCmd {
|
||||
|
||||
@Inject
|
||||
public VmwareDatacenterService _vmwareDatacenterService;
|
||||
@ -61,7 +61,7 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
||||
private String vcenter;
|
||||
|
||||
@Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of Vmware datacenter.")
|
||||
@Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of VMware datacenter.")
|
||||
private String datacenterName;
|
||||
|
||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
||||
@ -70,18 +70,6 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||
private String password;
|
||||
|
||||
@Parameter(name = ApiConstants.HOST, type = CommandType.STRING, description = "get only the VMs from the specified host.")
|
||||
private String host;
|
||||
|
||||
@Parameter(name = ApiConstants.BATCH_SIZE, type = CommandType.INTEGER, description = "The maximum number of results to return.")
|
||||
private Integer batchSize;
|
||||
|
||||
@Parameter(name = ApiConstants.TOKEN, type = CommandType.STRING,
|
||||
description = "For listVmwareDcVms, if the maximum number of results (the `batchsize`) is exceeded, " +
|
||||
" a token is returned. This token can be used in subsequent calls to retrieve more results." +
|
||||
" As long as a token is returned, more results can be retrieved.")
|
||||
private String token;
|
||||
|
||||
public String getVcenter() {
|
||||
return vcenter;
|
||||
}
|
||||
@ -94,18 +82,6 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
return password;
|
||||
}
|
||||
|
||||
public Integer getBatchSize() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public String getDatacenterName() {
|
||||
return datacenterName;
|
||||
}
|
||||
@ -118,8 +94,7 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
checkParameters();
|
||||
try {
|
||||
Pair<String, List<UnmanagedInstanceTO>> results = _vmwareDatacenterService.listVMsInDatacenter(this);
|
||||
List<UnmanagedInstanceTO> vms = results.second();
|
||||
List<UnmanagedInstanceTO> vms = _vmwareDatacenterService.listVMsInDatacenter(this);
|
||||
List<BaseResponse> baseResponseList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(vms)) {
|
||||
for (UnmanagedInstanceTO vmwareVm : vms) {
|
||||
@ -127,13 +102,16 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
baseResponseList.add(resp);
|
||||
}
|
||||
}
|
||||
VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
|
||||
response.setResponses(baseResponseList, baseResponseList.size());
|
||||
List<BaseResponse> pagingList = com.cloud.utils.StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal());
|
||||
if (CollectionUtils.isEmpty(pagingList)) {
|
||||
pagingList = baseResponseList;
|
||||
}
|
||||
ListResponse<BaseResponse> response = new ListResponse<>();
|
||||
response.setResponses(pagingList, baseResponseList.size());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setToken(results.first());
|
||||
setResponseObject(response);
|
||||
} catch (CloudRuntimeException e) {
|
||||
String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage());
|
||||
String errorMsg = String.format("Error retrieving VMs from VMware VC: %s", e.getMessage());
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
|
||||
}
|
||||
}
|
||||
@ -156,6 +134,6 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "listVmwareDcVmsResponse".toLowerCase();
|
||||
return "listvmwaredcvmsresponse";
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ import com.cloud.dc.VmwareDatacenter;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "listVmwareDcs", responseObject = VmwareDatacenterResponse.class, description = "Retrieves Vmware DC(s) associated with a zone.",
|
||||
@APICommand(name = "listVmwareDcs", responseObject = VmwareDatacenterResponse.class, description = "Retrieves VMware DC(s) associated with a zone.",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class ListVmwareDcsCmd extends BaseListCmd {
|
||||
|
||||
@ -50,6 +50,7 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
||||
public VmwareDatacenterService _vmwareDatacenterService;
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -72,27 +73,20 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||
ResourceAllocationException {
|
||||
List<? extends VmwareDatacenter> vmwareDcList;
|
||||
List<? extends VmwareDatacenter> vmwareDcList = null;
|
||||
|
||||
try {
|
||||
vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
|
||||
} catch (InvalidParameterValueException ie) {
|
||||
throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated Vmware DCs associated with zone " + getZoneId());
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated VMware DCs associated with zone " + getZoneId());
|
||||
}
|
||||
|
||||
ListResponse<VmwareDatacenterResponse> response = new ListResponse<>();
|
||||
List<VmwareDatacenterResponse> vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList);
|
||||
response.setResponses(vmwareDcResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
ListResponse<VmwareDatacenterResponse> response = new ListResponse<VmwareDatacenterResponse>();
|
||||
List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<VmwareDatacenterResponse>();
|
||||
|
||||
private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? extends VmwareDatacenter> vmwareDcList) {
|
||||
List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<>();
|
||||
|
||||
if (vmwareDcList != null && !vmwareDcList.isEmpty()) {
|
||||
if (vmwareDcList != null && vmwareDcList.size() > 0) {
|
||||
for (VmwareDatacenter vmwareDc : vmwareDcList) {
|
||||
VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
|
||||
|
||||
@ -100,12 +94,14 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
||||
vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
|
||||
vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
|
||||
vmwareDcResponse.setZoneId(getZoneId());
|
||||
vmwareDcResponse.setObjectName(ApiConstants.VMWARE_DC);
|
||||
vmwareDcResponse.setObjectName("VMwareDC");
|
||||
|
||||
vmwareDcResponses.add(vmwareDcResponse);
|
||||
}
|
||||
}
|
||||
return vmwareDcResponses;
|
||||
response.setResponses(vmwareDcResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -71,13 +71,6 @@ public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
||||
|
||||
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
|
||||
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
||||
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter);
|
||||
responseList.setResponses(storagePoliciesResponseList);
|
||||
responseList.setResponseName(getCommandName());
|
||||
setResponseObject(responseList);
|
||||
}
|
||||
|
||||
private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesResponses(List<? extends VsphereStoragePolicy> storagePolicies, DataCenter dataCenter) {
|
||||
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
||||
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
||||
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
||||
@ -86,11 +79,13 @@ public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
||||
storagePoliciesResponse.setName(storagePolicy.getName());
|
||||
storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
|
||||
storagePoliciesResponse.setDescription(storagePolicy.getDescription());
|
||||
storagePoliciesResponse.setObjectName(ApiConstants.STORAGE_POLICY);
|
||||
storagePoliciesResponse.setObjectName("StoragePolicy");
|
||||
|
||||
storagePoliciesResponseList.add(storagePoliciesResponse);
|
||||
}
|
||||
return storagePoliciesResponseList;
|
||||
responseList.setResponses(storagePoliciesResponseList);
|
||||
responseList.setResponseName(getCommandName());
|
||||
setResponseObject(responseList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -68,7 +68,7 @@ public class ListVsphereStoragePolicyCompatiblePoolsCmd extends BaseListCmd {
|
||||
List<StoragePoolResponse> poolResponses = new ArrayList<>();
|
||||
for (StoragePool pool : pools) {
|
||||
StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
|
||||
poolResponse.setObjectName(ApiConstants.STORAGE_POOL);
|
||||
poolResponse.setObjectName("storagepool");
|
||||
poolResponses.add(poolResponse);
|
||||
}
|
||||
response.setResponses(poolResponses);
|
||||
|
||||
@ -34,7 +34,7 @@ import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = "removeVmwareDc", responseObject = SuccessResponse.class, description = "Remove a Vmware datacenter from a zone.",
|
||||
@APICommand(name = "removeVmwareDc", responseObject = SuccessResponse.class, description = "Remove a VMware datacenter from a zone.",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class RemoveVmwareDcCmd extends BaseCmd {
|
||||
|
||||
@ -47,7 +47,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
|
||||
type = CommandType.UUID,
|
||||
entityType = ZoneResponse.class,
|
||||
required = true,
|
||||
description = "The id of Zone from which Vmware datacenter has to be removed.")
|
||||
description = "The id of Zone from which VMware datacenter has to be removed.")
|
||||
private Long zoneId;
|
||||
|
||||
public Long getZoneId() {
|
||||
@ -63,7 +63,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove Vmware datacenter from zone");
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove VMware datacenter from zone");
|
||||
}
|
||||
} catch (ResourceInUseException ex) {
|
||||
logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone."
|
||||
|
||||
@ -33,7 +33,7 @@ import com.cloud.dc.VmwareDatacenter;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "updateVmwareDc", description = "Updates a Vmware datacenter details for a zone",
|
||||
@APICommand(name = "updateVmwareDc", description = "Updates a VMware datacenter details for a zone",
|
||||
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false,
|
||||
since = "4.12.0", authorized = {RoleType.Admin})
|
||||
public class UpdateVmwareDcCmd extends BaseCmd {
|
||||
@ -50,7 +50,7 @@ public class UpdateVmwareDcCmd extends BaseCmd {
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
|
||||
description = "Vmware datacenter name.")
|
||||
description = "VMware datacenter name.")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
|
||||
@ -105,13 +105,13 @@ public class UpdateVmwareDcCmd extends BaseCmd {
|
||||
public void execute() {
|
||||
final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
|
||||
if (vmwareDatacenter == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update Vmware datacenter");
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VMware datacenter");
|
||||
}
|
||||
final VmwareDatacenterResponse response = new VmwareDatacenterResponse();
|
||||
response.setId(vmwareDatacenter.getUuid());
|
||||
response.setName(vmwareDatacenter.getVmwareDatacenterName());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName(ApiConstants.VMWARE_DC);
|
||||
response.setObjectName("vmwaredc");
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.zone;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ResponseObject;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
|
||||
public class VmwareRequestResponse<T extends ResponseObject> extends ListResponse<T> {
|
||||
@SerializedName(ApiConstants.TOKEN)
|
||||
@Param(description = "The Vmware API token to use for retrieving further responses with")
|
||||
private String token;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
}
|
||||
@ -50,6 +50,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;
|
||||
@ -835,4 +837,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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
|
||||
@ -38,6 +37,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||
import com.cloud.api.query.vo.TemplateJoinVO;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
@ -58,6 +58,7 @@ import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
@ -94,6 +95,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||
if (template.getState() != null) {
|
||||
response.setIsoState(template.getState().toString());
|
||||
}
|
||||
response.setIsoArch(template.getArch().getType());
|
||||
response.setDirectDownload(template.isDirectDownload());
|
||||
}
|
||||
|
||||
@ -267,6 +269,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||
final Long zoneId = cmd.getZoneId();
|
||||
String minimumSemanticVersion = cmd.getMinimumSemanticVersion();
|
||||
final Long minimumKubernetesVersionId = cmd.getMinimumKubernetesVersionId();
|
||||
final String arch = cmd.getArch();
|
||||
if (StringUtils.isNotEmpty(minimumSemanticVersion) && minimumKubernetesVersionId != null) {
|
||||
throw new CloudRuntimeException(String.format("Both parameters %s and %s can not be passed together", ApiConstants.MIN_SEMANTIC_VERSION, ApiConstants.MIN_KUBERNETES_VERSION_ID));
|
||||
}
|
||||
@ -281,6 +284,13 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||
SearchBuilder<KubernetesSupportedVersionVO> sb = kubernetesSupportedVersionDao.createSearchBuilder();
|
||||
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||
sb.and("keyword", sb.entity().getName(), SearchCriteria.Op.LIKE);
|
||||
if (StringUtils.isNotBlank(arch)) {
|
||||
SearchBuilder<VMTemplateVO> isoSearch = templateDao.createSearchBuilder();
|
||||
isoSearch.and("arch", isoSearch.entity().getArch(), SearchCriteria.Op.EQ);
|
||||
sb.join("isoSearch", isoSearch, isoSearch.entity().getId(), sb.entity().getIsoId(), JoinBuilder.JoinType.INNER);
|
||||
isoSearch.done();
|
||||
}
|
||||
sb.done();
|
||||
SearchCriteria<KubernetesSupportedVersionVO> sc = sb.create();
|
||||
String keyword = cmd.getKeyword();
|
||||
if (versionId != null) {
|
||||
@ -295,6 +305,9 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||
if(keyword != null){
|
||||
sc.setParameters("keyword", "%" + keyword + "%");
|
||||
}
|
||||
if (StringUtils.isNotBlank(arch)) {
|
||||
sc.setJoinParameters("isoSearch", "arch", arch);
|
||||
}
|
||||
Pair<List<KubernetesSupportedVersionVO>, Integer> versionsAndCount =
|
||||
kubernetesSupportedVersionDao.searchAndCount(sc, searchFilter);
|
||||
List<KubernetesSupportedVersionVO> versions =
|
||||
|
||||
@ -66,6 +66,11 @@ public class ListKubernetesSupportedVersionsCmd extends BaseListCmd {
|
||||
description = "the ID of the minimum Kubernetes supported version")
|
||||
private Long minimumKubernetesVersionId;
|
||||
|
||||
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||
description = "the CPU arch of the binaries ISO. Valid options are: x86_64, aarch64",
|
||||
since = "4.20")
|
||||
private String arch;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -85,6 +90,10 @@ public class ListKubernetesSupportedVersionsCmd extends BaseListCmd {
|
||||
return minimumSemanticVersion;
|
||||
}
|
||||
|
||||
public String getArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public Long getMinimumKubernetesVersionId() {
|
||||
return minimumKubernetesVersionId;
|
||||
}
|
||||
|
||||
@ -54,6 +54,10 @@ public class KubernetesSupportedVersionResponse extends BaseResponse {
|
||||
@Param(description = "the state of the binaries ISO for Kubernetes supported version")
|
||||
private String isoState;
|
||||
|
||||
@SerializedName(ApiConstants.ARCH)
|
||||
@Param(description = "the arch of the binaries ISO for Kubernetes supported version", since = "4.20.1")
|
||||
private String isoArch;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "the id of the zone in which Kubernetes supported version is available")
|
||||
private String zoneId;
|
||||
@ -138,6 +142,14 @@ public class KubernetesSupportedVersionResponse extends BaseResponse {
|
||||
this.isoState = isoState;
|
||||
}
|
||||
|
||||
public String getIsoArch() {
|
||||
return isoArch;
|
||||
}
|
||||
|
||||
public void setIsoArch(String isoArch) {
|
||||
this.isoArch = isoArch;
|
||||
}
|
||||
|
||||
public String getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||
import com.cloud.api.query.vo.TemplateJoinVO;
|
||||
import com.cloud.cpu.CPU;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class KubernetesVersionManagerImplTest {
|
||||
@ -57,6 +58,7 @@ public class KubernetesVersionManagerImplTest {
|
||||
Mockito.when(kubernetesSupportedVersion.getIsoId()).thenReturn(1L);
|
||||
KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse();
|
||||
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
||||
Mockito.when(templateJoinVO.getArch()).thenReturn(CPU.CPUArch.getDefault());
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
Mockito.when(templateJoinVO.getUuid()).thenReturn(uuid);
|
||||
Mockito.when(templateJoinDao.findById(1L)).thenReturn(templateJoinVO);
|
||||
|
||||
@ -125,6 +125,7 @@ public class KubernetesVersionServiceTest {
|
||||
|
||||
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
||||
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
|
||||
when(templateJoinVO.getArch()).thenReturn(CPU.CPUArch.getDefault());
|
||||
when(templateJoinDao.findById(Mockito.anyLong())).thenReturn(templateJoinVO);
|
||||
|
||||
KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class);
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.network.lb;
|
||||
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Hyperv;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.KVM;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.LXC;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.VMware;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.XenServer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@ -31,6 +37,7 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
|
||||
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
@ -118,12 +125,6 @@ import com.cloud.vm.VirtualMachineProfile.Param;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Hyperv;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.KVM;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.LXC;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.VMware;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.XenServer;
|
||||
|
||||
public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements InternalLoadBalancerVMManager, InternalLoadBalancerVMService, VirtualMachineGuru {
|
||||
static final private String InternalLbVmNamePrefix = "b";
|
||||
|
||||
@ -732,6 +733,70 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
||||
return internalLbVms;
|
||||
}
|
||||
|
||||
protected String getRouterTemplateForHypervisor(HypervisorType hypervisorType, long dataCenterId) {
|
||||
String templateName = null;
|
||||
if (XenServer.equals(hypervisorType)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateXen.valueIn(dataCenterId);
|
||||
} else if (KVM.equals(hypervisorType)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateKvm.valueIn(dataCenterId);
|
||||
} else if (VMware.equals(hypervisorType)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateVmware.valueIn(dataCenterId);
|
||||
} else if (Hyperv.equals(hypervisorType)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateHyperV.valueIn(dataCenterId);
|
||||
} else if (LXC.equals(hypervisorType)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateLxc.valueIn(dataCenterId);
|
||||
}
|
||||
return templateName;
|
||||
}
|
||||
|
||||
protected DomainRouterVO createOrUpdateInternalLb(DomainRouterVO internalLbVm, final long id,
|
||||
final long internalLbProviderId, final Account owner, final long userId, final Long vpcId,
|
||||
final ServiceOffering routerOffering, final VMTemplateVO template) {
|
||||
if (internalLbVm == null) {
|
||||
internalLbVm = new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId,
|
||||
VirtualMachineName.getSystemVmName(id, _instance, InternalLbVmNamePrefix),
|
||||
template.getId(), template.getHypervisorType(), template.getGuestOSId(),
|
||||
owner.getDomainId(), owner.getId(), userId, false,
|
||||
RedundantState.UNKNOWN, false, false,
|
||||
VirtualMachine.Type.InternalLoadBalancerVm, vpcId);
|
||||
internalLbVm.setRole(Role.INTERNAL_LB_VM);
|
||||
internalLbVm.setLimitCpuUse(routerOffering.getLimitCpuUse());
|
||||
internalLbVm.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
return _internalLbVmDao.persist(internalLbVm);
|
||||
}
|
||||
internalLbVm.setTemplateId(template.getId());
|
||||
internalLbVm.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
_internalLbVmDao.update(internalLbVm.getId(), internalLbVm);
|
||||
return internalLbVm;
|
||||
}
|
||||
|
||||
protected DomainRouterVO deployInternalLbVmWithTemplates(DomainRouterVO internalLbVm, final long id,
|
||||
final DeploymentPlan plan, final long internalLbProviderId, final Account owner, final long userId,
|
||||
final Long vpcId, final ServiceOffering routerOffering,
|
||||
final LinkedHashMap<Network, List<? extends NicProfile>> networks, final List<VMTemplateVO> templates)
|
||||
throws InsufficientCapacityException {
|
||||
for (final Iterator<VMTemplateVO> templatesIterator = templates.iterator(); templatesIterator.hasNext();) {
|
||||
final VMTemplateVO template = templatesIterator.next();
|
||||
try {
|
||||
internalLbVm = createOrUpdateInternalLb(internalLbVm, id, internalLbProviderId, owner, userId, vpcId,
|
||||
routerOffering, template);
|
||||
_itMgr.allocate(internalLbVm.getInstanceName(), template, routerOffering, networks, plan, null);
|
||||
internalLbVm = _internalLbVmDao.findById(internalLbVm.getId());
|
||||
if (templatesIterator.hasNext()) {
|
||||
_itMgr.checkDeploymentPlan(internalLbVm, template, routerOffering, owner, plan);
|
||||
}
|
||||
return internalLbVm;
|
||||
} catch (InsufficientCapacityException ex) {
|
||||
if (templatesIterator.hasNext()) {
|
||||
logger.debug("Failed to allocate the VR with hypervisor {} and {}, retrying with another template", template.getHypervisorType(), template);
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DomainRouterVO deployInternalLbVm(final Account owner, final DeployDestination dest, final DeploymentPlan plan, final Map<Param, Object> params, final long internalLbProviderId,
|
||||
final long svcOffId, final Long vpcId, final LinkedHashMap<Network, List<? extends NicProfile>> networks, final boolean startVm) throws ConcurrentOperationException,
|
||||
InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException,
|
||||
@ -743,6 +808,14 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
||||
// Try to allocate the internal lb twice using diff hypervisors, and when failed both times, throw the exception up
|
||||
final List<HypervisorType> hypervisors = getHypervisors(dest, plan, null);
|
||||
|
||||
long userId = CallContext.current().getCallingUserId();
|
||||
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
|
||||
List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
|
||||
if (!userVOs.isEmpty()) {
|
||||
userId = userVOs.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
int allocateRetry = 0;
|
||||
int startRetry = 0;
|
||||
DomainRouterVO internalLbVm = null;
|
||||
@ -751,45 +824,23 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
||||
try {
|
||||
final long id = _internalLbVmDao.getNextInSequence(Long.class, "id");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating the internal lb vm " + id + " in datacenter " + dest.getDataCenter() + " with hypervisor type " + hType);
|
||||
logger.debug("Creating the internal lb vm {} in datacenter {} with hypervisor type {}",
|
||||
id, dest.getDataCenter(), hType);
|
||||
}
|
||||
String templateName = null;
|
||||
if (hType.equals(XenServer)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateXen.valueIn(dest.getDataCenter().getId());
|
||||
} else if (hType.equals(KVM)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateKvm.valueIn(dest.getDataCenter().getId());
|
||||
} else if (hType.equals(VMware)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateVmware.valueIn(dest.getDataCenter().getId());
|
||||
} else if (hType.equals(Hyperv)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateHyperV.valueIn(dest.getDataCenter().getId());
|
||||
} else if (hType.equals(LXC)) {
|
||||
templateName = VirtualNetworkApplianceManager.RouterTemplateLxc.valueIn(dest.getDataCenter().getId());
|
||||
}
|
||||
final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);
|
||||
|
||||
if (template == null) {
|
||||
logger.debug(hType + " won't support system vm, skip it");
|
||||
final long zoneId = dest.getDataCenter().getId();
|
||||
final String templateName = getRouterTemplateForHypervisor(hType, zoneId);
|
||||
final String preferredArch = ResourceManager.SystemVmPreferredArchitecture.valueIn(zoneId);
|
||||
final List<VMTemplateVO> templates = _templateDao.findRoutingTemplates(hType, templateName,
|
||||
preferredArch);
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
logger.debug("{} won't support system vm, skip it", hType);
|
||||
continue;
|
||||
}
|
||||
|
||||
long userId = CallContext.current().getCallingUserId();
|
||||
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
|
||||
List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
|
||||
if (!userVOs.isEmpty()) {
|
||||
userId = userVOs.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
internalLbVm =
|
||||
new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId, VirtualMachineName.getSystemVmName(id, _instance, InternalLbVmNamePrefix),
|
||||
template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN, false, false, VirtualMachine.Type.InternalLoadBalancerVm, vpcId);
|
||||
internalLbVm.setRole(Role.INTERNAL_LB_VM);
|
||||
internalLbVm = _internalLbVmDao.persist(internalLbVm);
|
||||
_itMgr.allocate(internalLbVm.getInstanceName(), template, routerOffering, networks, plan, null);
|
||||
internalLbVm = _internalLbVmDao.findById(internalLbVm.getId());
|
||||
internalLbVm = deployInternalLbVmWithTemplates(internalLbVm, id, plan, internalLbProviderId, owner,
|
||||
userId, vpcId, routerOffering, networks, templates);
|
||||
} catch (final InsufficientCapacityException ex) {
|
||||
if (allocateRetry < 2 && iter.hasNext()) {
|
||||
logger.debug("Failed to allocate the Internal lb vm with hypervisor type " + hType + ", retrying one more time");
|
||||
logger.debug("Failed to allocate the Internal lb vm with hypervisor type {}, retrying one more time", hType);
|
||||
continue;
|
||||
} else {
|
||||
throw ex;
|
||||
@ -804,8 +855,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
||||
break;
|
||||
} catch (final InsufficientCapacityException ex) {
|
||||
if (startRetry < 2 && iter.hasNext()) {
|
||||
logger.debug("Failed to start the Internal lb vm " + internalLbVm + " with hypervisor type " + hType + ", " +
|
||||
"destroying it and recreating one more time");
|
||||
logger.debug("Failed to start the Internal lb vm {} with hypervisor type {}, destroying it and recreating one more time", internalLbVm, hType);
|
||||
// destroy the internal lb vm
|
||||
destroyInternalLbVm(internalLbVm.getId(), _accountMgr.getSystemAccount(), User.UID_SYSTEM);
|
||||
continue;
|
||||
|
||||
@ -0,0 +1,172 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.network.lb;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class InternalLoadBalancerVMManagerImplTest {
|
||||
@Mock
|
||||
private DomainRouterDao internalLbVmDao;
|
||||
|
||||
@Mock
|
||||
private VirtualMachineManager virtualMachineManager;
|
||||
|
||||
@InjectMocks
|
||||
private InternalLoadBalancerVMManagerImpl service;
|
||||
|
||||
// Dummy objects for testing.
|
||||
private Account account;
|
||||
private ServiceOffering serviceOffering;
|
||||
private VMTemplateVO template1;
|
||||
private VMTemplateVO template2;
|
||||
private DeploymentPlan plan;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
account = mock(Account.class);
|
||||
serviceOffering = mock(ServiceOffering.class);
|
||||
template1 = mock(VMTemplateVO.class);
|
||||
template2 = mock(VMTemplateVO.class);
|
||||
plan = new DataCenterDeployment(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOrUpdateInternalLb_New() {
|
||||
long id = 1L;
|
||||
long internalLbProviderId = 2L;
|
||||
long userId = 100L;
|
||||
Long vpcId = 200L;
|
||||
when(template1.isDynamicallyScalable()).thenReturn(true);
|
||||
when(serviceOffering.getLimitCpuUse()).thenReturn(true);
|
||||
when(internalLbVmDao.persist(any(DomainRouterVO.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
DomainRouterVO result = service.createOrUpdateInternalLb(null, id, internalLbProviderId, account,
|
||||
userId, vpcId, serviceOffering, template1);
|
||||
verify(internalLbVmDao).persist(any(DomainRouterVO.class));
|
||||
assertEquals(template1.getId(), result.getTemplateId());
|
||||
assertTrue(result.isDynamicallyScalable());
|
||||
assertEquals(VirtualRouter.Role.INTERNAL_LB_VM, result.getRole());
|
||||
assertTrue(result.limitCpuUse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOrUpdateInternalLb_Update() {
|
||||
long id = 1L;
|
||||
long internalLbProviderId = 2L;
|
||||
long userId = 100L;
|
||||
Long vpcId = 200L;
|
||||
DomainRouterVO existing = mock(DomainRouterVO.class);
|
||||
when(existing.getId()).thenReturn(id);
|
||||
when(template1.isDynamicallyScalable()).thenReturn(true);
|
||||
final boolean[] dsResult = {false};
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
dsResult[0] = invocation.getArgument(0);
|
||||
return null;
|
||||
}).when(existing).setDynamicallyScalable(anyBoolean());
|
||||
DomainRouterVO result = service.createOrUpdateInternalLb(existing, id, internalLbProviderId, account, userId, vpcId, serviceOffering, template1);
|
||||
verify(internalLbVmDao).update(existing.getId(), existing);
|
||||
assertEquals(template1.getId(), result.getTemplateId());
|
||||
assertTrue(dsResult[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeployInternalLbVmWithTemplates_SuccessfulFirstTemplate() throws Exception {
|
||||
long id = 1L;
|
||||
long internalLbProviderId = 2L;
|
||||
long userId = 100L;
|
||||
Long vpcId = 200L;
|
||||
List<VMTemplateVO> templates = Arrays.asList(template1);
|
||||
LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<>();
|
||||
when(internalLbVmDao.persist(any(DomainRouterVO.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
when(internalLbVmDao.findById(anyLong())).thenReturn(mock(DomainRouterVO.class));
|
||||
DomainRouterVO result = service.deployInternalLbVmWithTemplates(null, id, plan, internalLbProviderId, account, userId, vpcId, serviceOffering, networks, templates);
|
||||
assertNotNull(result);
|
||||
verify(virtualMachineManager).allocate(anyString(), eq(template1), eq(serviceOffering), eq(networks), eq(plan), isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeployInternalLbVmWithTemplates_RetryOnInsufficientCapacity() throws Exception {
|
||||
long id = 1L;
|
||||
long internalLbProviderId = 2L;
|
||||
long userId = 100L;
|
||||
Long vpcId = 200L;
|
||||
|
||||
List<VMTemplateVO> templates = Arrays.asList(template1, template2);
|
||||
LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<>();
|
||||
when(internalLbVmDao.persist(any(DomainRouterVO.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
when(internalLbVmDao.findById(anyLong())).thenReturn(mock(DomainRouterVO.class));
|
||||
doThrow(new InsufficientServerCapacityException("Not enough capacity", id))
|
||||
.when(virtualMachineManager).allocate(anyString(), eq(template1), eq(serviceOffering), eq(networks), eq(plan), isNull());
|
||||
DomainRouterVO result = service.deployInternalLbVmWithTemplates(null, id, plan, internalLbProviderId, account, userId, vpcId, serviceOffering, networks, templates);
|
||||
assertNotNull(result);
|
||||
verify(virtualMachineManager).allocate(anyString(), eq(template1), eq(serviceOffering), eq(networks), eq(plan), isNull());
|
||||
verify(virtualMachineManager).allocate(anyString(), eq(template2), eq(serviceOffering), eq(networks), eq(plan), isNull());
|
||||
}
|
||||
|
||||
@Test(expected = InsufficientCapacityException.class)
|
||||
public void testDeployInternalLbVmWithTemplates_AllTemplatesFail() throws Exception {
|
||||
long id = 1L;
|
||||
long internalLbProviderId = 2L;
|
||||
long userId = 100L;
|
||||
Long vpcId = 200L;
|
||||
List<VMTemplateVO> templates = Arrays.asList(template1, template2);
|
||||
LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<>();
|
||||
when(internalLbVmDao.persist(any(DomainRouterVO.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
doThrow(new InsufficientServerCapacityException("Insufficient capacity", id))
|
||||
.when(virtualMachineManager).allocate(anyString(), any(VMTemplateVO.class), eq(serviceOffering), eq(networks), eq(plan), isNull());
|
||||
service.deployInternalLbVmWithTemplates(null, id, plan, internalLbProviderId, account, userId, vpcId, serviceOffering, networks, templates);
|
||||
}
|
||||
}
|
||||
@ -1718,6 +1718,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
if (template != null) {
|
||||
vmResponse.setTemplateId(template.getUuid());
|
||||
vmResponse.setTemplateName(template.getName());
|
||||
vmResponse.setArch(template.getArch().getType());
|
||||
}
|
||||
vmResponse.setCreated(vm.getCreated());
|
||||
vmResponse.setHypervisor(vm.getHypervisorType().getHypervisorDisplayName());
|
||||
|
||||
@ -1308,6 +1308,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
Long userId = cmd.getUserId();
|
||||
Long userdataId = cmd.getUserdataId();
|
||||
Map<String, String> tags = cmd.getTags();
|
||||
final CPU.CPUArch arch = cmd.getArch();
|
||||
|
||||
boolean isAdmin = false;
|
||||
boolean isRootAdmin = false;
|
||||
@ -1535,8 +1536,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
}
|
||||
|
||||
Boolean isVnf = cmd.getVnf();
|
||||
if (isVnf != null) {
|
||||
boolean templateJoinNeeded = isVnf != null || arch != null;
|
||||
if (templateJoinNeeded) {
|
||||
SearchBuilder<VMTemplateVO> templateSearch = _templateDao.createSearchBuilder();
|
||||
templateSearch.and("templateArch", templateSearch.entity().getArch(), Op.EQ);
|
||||
templateSearch.and("templateTypeEQ", templateSearch.entity().getTemplateType(), Op.EQ);
|
||||
templateSearch.and("templateTypeNEQ", templateSearch.entity().getTemplateType(), Op.NEQ);
|
||||
|
||||
@ -1665,6 +1668,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
userVmSearchCriteria.setJoinParameters("vmTemplate", "templateTypeNEQ", TemplateType.VNF);
|
||||
}
|
||||
}
|
||||
if (arch != null) {
|
||||
userVmSearchCriteria.setJoinParameters("vmTemplate", "templateArch", arch);
|
||||
}
|
||||
|
||||
if (isRootAdmin) {
|
||||
if (podId != null) {
|
||||
@ -2366,6 +2372,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
Long pageSize = cmd.getPageSizeVal();
|
||||
Hypervisor.HypervisorType hypervisorType = cmd.getHypervisor();
|
||||
Long msId = cmd.getManagementServerId();
|
||||
final CPU.CPUArch arch = cmd.getArch();
|
||||
|
||||
Filter searchFilter = new Filter(HostVO.class, "id", Boolean.TRUE, startIndex, pageSize);
|
||||
|
||||
@ -2382,6 +2389,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
hostSearchBuilder.and("resourceState", hostSearchBuilder.entity().getResourceState(), SearchCriteria.Op.EQ);
|
||||
hostSearchBuilder.and("hypervisor_type", hostSearchBuilder.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
hostSearchBuilder.and("mgmt_server_id", hostSearchBuilder.entity().getManagementServerId(), SearchCriteria.Op.EQ);
|
||||
hostSearchBuilder.and("arch", hostSearchBuilder.entity().getArch(), SearchCriteria.Op.EQ);
|
||||
|
||||
if (keyword != null) {
|
||||
hostSearchBuilder.and().op("keywordName", hostSearchBuilder.entity().getName(), SearchCriteria.Op.LIKE);
|
||||
@ -2469,6 +2477,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
}
|
||||
}
|
||||
|
||||
if (arch != null) {
|
||||
sc.setParameters("arch", arch);
|
||||
}
|
||||
|
||||
Pair<List<HostVO>, Integer> uniqueHostPair = hostDao.searchAndCount(sc, searchFilter);
|
||||
Integer count = uniqueHostPair.second();
|
||||
List<Long> hostIds = uniqueHostPair.first().stream().map(HostVO::getId).collect(Collectors.toList());
|
||||
@ -5053,6 +5065,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);
|
||||
@ -5103,6 +5116,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)) {
|
||||
@ -5112,6 +5129,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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,6 +88,7 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
|
||||
routerResponse.setZoneId(router.getDataCenterUuid());
|
||||
routerResponse.setName(router.getName());
|
||||
routerResponse.setTemplateId(router.getTemplateUuid());
|
||||
routerResponse.setArch(router.getArch().getType());
|
||||
VMTemplateVO template = ApiDBUtils.findTemplateById(router.getTemplateId());
|
||||
if (template != null) {
|
||||
routerResponse.setTemplateName(template.getName());
|
||||
|
||||
@ -188,6 +188,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
||||
userVmResponse.setInstanceName(userVm.getInstanceName());
|
||||
userVmResponse.setHostId(userVm.getHostUuid());
|
||||
userVmResponse.setHostName(userVm.getHostName());
|
||||
userVmResponse.setArch(userVm.getArch());
|
||||
}
|
||||
if (userVm.getHostStatus() != null) {
|
||||
userVmResponse.setHostControlState(ControlState.getControlState(userVm.getHostStatus(), userVm.getHostResourceState()).toString());
|
||||
|
||||
@ -27,6 +27,7 @@ import javax.persistence.Enumerated;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.Network.GuestType;
|
||||
@ -38,6 +39,8 @@ import com.cloud.user.Account;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
import org.apache.cloudstack.util.CPUArchConverter;
|
||||
import org.apache.cloudstack.util.HypervisorTypeConverter;
|
||||
|
||||
@Entity
|
||||
@ -143,6 +146,10 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
|
||||
@Convert(converter = HypervisorTypeConverter.class)
|
||||
private Hypervisor.HypervisorType hypervisorType;
|
||||
|
||||
@Column(name="arch")
|
||||
@Convert(converter = CPUArchConverter.class)
|
||||
private CPU.CPUArch arch;
|
||||
|
||||
@Column(name = "template_id", updatable = true, nullable = true, length = 17)
|
||||
private long templateId;
|
||||
|
||||
@ -376,6 +383,10 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
|
||||
return hypervisorType;
|
||||
}
|
||||
|
||||
public CPU.CPUArch getArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
@ -439,6 +439,9 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
||||
@Column(name = "delete_protection")
|
||||
protected Boolean deleteProtection;
|
||||
|
||||
@Column(name = "arch")
|
||||
protected String arch;
|
||||
|
||||
|
||||
public UserVmJoinVO() {
|
||||
// Empty constructor
|
||||
@ -977,4 +980,8 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
||||
public String getUserDataDetails() {
|
||||
return userDataDetails;
|
||||
}
|
||||
|
||||
public String getArch() {
|
||||
return arch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,6 @@ import org.apache.cloudstack.framework.security.keystore.KeystoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
@ -82,9 +81,9 @@ import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.info.ConsoleProxyConnectionInfo;
|
||||
@ -111,10 +110,8 @@ import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.UnableDeleteHostException;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.user.Account;
|
||||
@ -281,9 +278,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
|
||||
public void onAgentDisconnect(long agentId, Status state) {
|
||||
|
||||
if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
|
||||
if (state == Status.Alert || state == Status.Disconnected) {
|
||||
HostVO host = _hostDao.findById(agentId);
|
||||
if (host.getType() == Type.ConsoleProxy) {
|
||||
String name = host.getName();
|
||||
@ -465,7 +462,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
|
||||
try {
|
||||
ConsoleProxyVO proxy = consoleProxyDao.findById(proxyVmId);
|
||||
if (proxy.getState() == VirtualMachine.State.Running) {
|
||||
if (proxy.getState() == State.Running) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@ -474,7 +471,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
return null;
|
||||
}
|
||||
|
||||
if (proxy.getState() == VirtualMachine.State.Stopped) {
|
||||
if (proxy.getState() == State.Stopped) {
|
||||
virtualMachineManager.advanceStart(proxy.getUuid(), null, null);
|
||||
proxy = consoleProxyDao.findById(proxy.getId());
|
||||
return proxy;
|
||||
@ -575,12 +572,13 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
}
|
||||
|
||||
HypervisorType availableHypervisor = resourceManager.getAvailableHypervisor(dataCenterId);
|
||||
VMTemplateVO template = vmTemplateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
|
||||
if (template == null) {
|
||||
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenterId, availableHypervisor,
|
||||
ResourceManager.SystemVmPreferredArchitecture.valueIn(dataCenterId));
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
|
||||
}
|
||||
|
||||
Map<String, Object> context = createProxyInstance(dataCenterId, template);
|
||||
Map<String, Object> context = createProxyInstance(dataCenterId, templates);
|
||||
|
||||
long proxyVmId = (Long)context.get("proxyVmId");
|
||||
if (proxyVmId == 0) {
|
||||
@ -673,7 +671,26 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
return defaultNetworks.get(0);
|
||||
}
|
||||
|
||||
protected Map<String, Object> createProxyInstance(long dataCenterId, VMTemplateVO template) throws ConcurrentOperationException {
|
||||
protected ConsoleProxyVO createOrUpdateConsoleProxy(ConsoleProxyVO proxy, long dataCenterId, long id, String name,
|
||||
ServiceOffering serviceOffering, VMTemplateVO template, Account systemAccount) {
|
||||
if (proxy == null) {
|
||||
proxy = new ConsoleProxyVO(id, serviceOffering.getId(), name, template.getId(),
|
||||
template.getHypervisorType(), template.getGuestOSId(), dataCenterId, systemAccount.getDomainId(),
|
||||
systemAccount.getId(), accountManager.getSystemUser().getId(), 0,
|
||||
serviceOffering.isOfferHA());
|
||||
proxy.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
proxy.setLimitCpuUse(serviceOffering.getLimitCpuUse());
|
||||
return consoleProxyDao.persist(proxy);
|
||||
}
|
||||
proxy.setTemplateId(template.getId());
|
||||
proxy.setHypervisorType(template.getHypervisorType());
|
||||
proxy.setGuestOSId(template.getGuestOSId());
|
||||
proxy.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
consoleProxyDao.update(proxy.getId(), proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
protected Map<String, Object> createProxyInstance(long dataCenterId, List<VMTemplateVO> templates) throws ConcurrentOperationException {
|
||||
|
||||
long id = consoleProxyDao.getNextInSequence(Long.class, "id");
|
||||
String name = VirtualMachineName.getConsoleProxyName(id, instance);
|
||||
@ -702,18 +719,23 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
if (serviceOffering == null) {
|
||||
serviceOffering = serviceOfferingDao.findDefaultSystemOffering(ServiceOffering.consoleProxyDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
||||
}
|
||||
ConsoleProxyVO proxy =
|
||||
new ConsoleProxyVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
|
||||
systemAcct.getDomainId(), systemAcct.getId(), accountManager.getSystemUser().getId(), 0, serviceOffering.isOfferHA());
|
||||
proxy.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
proxy.setLimitCpuUse(serviceOffering.getLimitCpuUse());
|
||||
proxy = consoleProxyDao.persist(proxy);
|
||||
try {
|
||||
virtualMachineManager.allocate(name, template, serviceOffering, networks, plan, null);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
String message = String.format("Unable to allocate proxy [%s] on zone [%s] due to [%s].", proxy.toString(), dataCenterId, e.getMessage());
|
||||
logger.warn(message, e);
|
||||
throw new CloudRuntimeException(message, e);
|
||||
ConsoleProxyVO proxy = null;
|
||||
for (final Iterator<VMTemplateVO> templateIterator = templates.iterator(); templateIterator.hasNext();) {
|
||||
VMTemplateVO template = templateIterator.next();
|
||||
proxy = createOrUpdateConsoleProxy(proxy, dataCenterId, id, name, serviceOffering, template, systemAcct);
|
||||
try {
|
||||
virtualMachineManager.allocate(name, template, serviceOffering, networks, plan,
|
||||
template.getHypervisorType());
|
||||
proxy = consoleProxyDao.findById(proxy.getId());
|
||||
virtualMachineManager.checkDeploymentPlan(proxy, template, serviceOffering, systemAcct, plan);
|
||||
break;
|
||||
} catch (InsufficientCapacityException e) {
|
||||
if (templateIterator.hasNext()) {
|
||||
logger.debug("Unable to allocate proxy {} with {} in {} due to [{}]. Retrying with another template", proxy, template, dc, e.getMessage(), e);
|
||||
continue;
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to allocate proxy [%s] in zone [%s] with available templates", e);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
@ -737,8 +759,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
updateConsoleProxyStatus(answer.getDetails(), answer.getProxyVmId());
|
||||
}
|
||||
|
||||
public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
|
||||
if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
|
||||
public void handleAgentDisconnect(long agentId, Status state) {
|
||||
if (state == Status.Alert || state == Status.Disconnected) {
|
||||
HostVO host = hostDao.findById(agentId);
|
||||
if (host.getType() == Type.ConsoleProxy) {
|
||||
String name = host.getName();
|
||||
@ -789,8 +811,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
return false;
|
||||
}
|
||||
List<ConsoleProxyVO> l =
|
||||
consoleProxyDao.getProxyListInStates(dcId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Stopping,
|
||||
VirtualMachine.State.Stopped, VirtualMachine.State.Migrating, VirtualMachine.State.Shutdown, VirtualMachine.State.Unknown);
|
||||
consoleProxyDao.getProxyListInStates(dcId, State.Starting, State.Running, State.Stopping,
|
||||
State.Stopped, State.Migrating, State.Shutdown, State.Unknown);
|
||||
|
||||
String value = configurationDao.getValue(Config.ConsoleProxyLaunchMax.key());
|
||||
int launchLimit = NumbersUtil.parseInt(value, 10);
|
||||
@ -876,33 +898,21 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
}
|
||||
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenter.getId());
|
||||
if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
|
||||
VMTemplateVO template = vmTemplateDao.findSystemVMReadyTemplate(dataCenter.getId(), HypervisorType.Any);
|
||||
if (template == null) {
|
||||
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenter.getId(),
|
||||
HypervisorType.Any, null);
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("System vm template is not ready at data center {}, wait until it is ready to launch console proxy vm", dataCenter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TemplateDataStoreVO templateHostRef;
|
||||
if (template.isDirectDownload()) {
|
||||
templateHostRef = templateDataStoreDao.findByTemplate(template.getId(), DataStoreRole.Image);
|
||||
} else {
|
||||
templateHostRef = templateDataStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dataCenter.getId(), Status.DOWNLOADED);
|
||||
}
|
||||
|
||||
if (templateHostRef != null) {
|
||||
Boolean useLocalStorage = BooleanUtils.toBoolean(ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenter.getId()));
|
||||
boolean hasDatacenterStoragePoolHostInfo = consoleProxyDao.hasDatacenterStoragePoolHostInfo(dataCenter.getId(), !useLocalStorage);
|
||||
if (hasDatacenterStoragePoolHostInfo) {
|
||||
return true;
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Primary storage is not ready, wait until it is ready to launch console proxy");
|
||||
}
|
||||
}
|
||||
boolean useLocalStorage = BooleanUtils.toBoolean(ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenter.getId()));
|
||||
boolean hasDatacenterStoragePoolHostInfo = consoleProxyDao.hasDatacenterStoragePoolHostInfo(dataCenter.getId(), !useLocalStorage);
|
||||
if (hasDatacenterStoragePoolHostInfo) {
|
||||
return true;
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Zone [{}] is ready, but console proxy template [{}] is not ready on secondary storage.", dataCenter, template);
|
||||
logger.debug("Primary storage is not ready, wait until it is ready to launch console proxy");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -912,9 +922,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
private boolean isZoneHostReady(ZoneHostInfo zoneHostInfo) {
|
||||
int expectedFlags;
|
||||
if (useStorageVm) {
|
||||
expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK;
|
||||
expectedFlags = ZoneHostInfo.ROUTING_HOST_MASK;
|
||||
} else {
|
||||
expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ALL_HOST_MASK;
|
||||
expectedFlags = ZoneHostInfo.ALL_HOST_MASK;
|
||||
}
|
||||
|
||||
return (zoneHostInfo.getFlags() & expectedFlags) == expectedFlags;
|
||||
@ -1093,7 +1103,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
proxy.setPrivateIpAddress(null);
|
||||
consoleProxyDao.update(proxy.getId(), proxy);
|
||||
consoleProxyDao.remove(vmId);
|
||||
HostVO host = hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), Host.Type.ConsoleProxy);
|
||||
HostVO host = hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), Type.ConsoleProxy);
|
||||
if (host != null) {
|
||||
logger.debug("Removing host [{}] entry for proxy [{}].", host, proxy);
|
||||
return hostDao.remove(host.getId());
|
||||
@ -1511,7 +1521,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ConsoleProxyVO> l = consoleProxyDao.getProxyListInStates(VirtualMachine.State.Starting, VirtualMachine.State.Stopping);
|
||||
List<ConsoleProxyVO> l = consoleProxyDao.getProxyListInStates(State.Starting, State.Stopping);
|
||||
if (l.size() > 0) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Zone {} has {} console proxy VM(s) in transition state", zone, l.size());
|
||||
@ -1568,7 +1578,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
return null;
|
||||
}
|
||||
|
||||
host.setType(com.cloud.host.Host.Type.ConsoleProxy);
|
||||
host.setType(Type.ConsoleProxy);
|
||||
return host;
|
||||
}
|
||||
|
||||
@ -1584,7 +1594,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
||||
|
||||
protected HostVO findConsoleProxyHostByName(String name) {
|
||||
QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
|
||||
sc.and(sc.entity().getType(), Op.EQ, Host.Type.ConsoleProxy);
|
||||
sc.and(sc.entity().getType(), Op.EQ, Type.ConsoleProxy);
|
||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
@ -1788,8 +1788,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
if (ipv4 && Objects.isNull(startIP)) {
|
||||
throw new CloudRuntimeException("IPv4 address range needs to be provided");
|
||||
}
|
||||
if (ipv6 && Objects.isNull(startIPv6)) {
|
||||
throw new CloudRuntimeException("IPv6 address range needs to be provided");
|
||||
if (ipv6) {
|
||||
logger.info(String.format("ip range for network '%s' is specified as %s - %s", name, startIPv6, endIPv6));
|
||||
}
|
||||
}
|
||||
Pair<Integer, Integer> interfaceMTUs = validateMtuConfig(publicMtu, privateMtu, zone.getId());
|
||||
@ -2186,12 +2186,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
if (implementedNetwork == null || implementedNetwork.first() == null) {
|
||||
logger.warn("Failed to provision the network " + network);
|
||||
}
|
||||
Network implemented = implementedNetwork.second();
|
||||
if (implemented != null) {
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_CREATE, implemented.getAccountId(), implemented.getDataCenterId(), implemented.getId(),
|
||||
implemented.getName(), implemented.getNetworkOfferingId(), null, null, null, Network.class.getName(), implemented.getUuid());
|
||||
}
|
||||
return implemented;
|
||||
return implementedNetwork.second();
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
|
||||
CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network");
|
||||
@ -3592,8 +3587,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
}
|
||||
}
|
||||
Network updatedNetwork = getNetwork(network.getId());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_UPDATE, updatedNetwork.getAccountId(), updatedNetwork.getDataCenterId(), updatedNetwork.getId(),
|
||||
updatedNetwork.getName(), updatedNetwork.getNetworkOfferingId(), null, updatedNetwork.getState().name(), Network.class.getName(), updatedNetwork.getUuid(), true);
|
||||
UsageEventUtils.publishNetworkUpdate(updatedNetwork);
|
||||
return updatedNetwork;
|
||||
}
|
||||
|
||||
|
||||
@ -28,8 +28,6 @@ import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.utils.validation.ChecksumUtil;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
@ -38,8 +36,8 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinition;
|
||||
import org.apache.cloudstack.utils.CloudStackVersion;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
@ -86,6 +84,7 @@ import com.cloud.network.lb.LoadBalancingRule;
|
||||
import com.cloud.network.router.VirtualRouter.RedundantState;
|
||||
import com.cloud.network.router.VirtualRouter.Role;
|
||||
import com.cloud.network.rules.LbStickinessMethod;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
@ -104,6 +103,7 @@ import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.validation.ChecksumUtil;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
@ -498,18 +498,77 @@ public class NetworkHelperImpl implements NetworkHelper {
|
||||
return templateName;
|
||||
}
|
||||
|
||||
protected DomainRouterVO createOrUpdateDomainRouter(DomainRouterVO router, final long id,
|
||||
final RouterDeploymentDefinition routerDeploymentDefinition, final Account owner, final long userId,
|
||||
final ServiceOfferingVO routerOffering, final boolean offerHA, final Long vpcId,
|
||||
final VMTemplateVO template) {
|
||||
if (router == null) {
|
||||
router = new DomainRouterVO(id, routerOffering.getId(),
|
||||
routerDeploymentDefinition.getVirtualProvider().getId(),
|
||||
VirtualMachineName.getRouterName(id, s_vmInstanceName), template.getId(),
|
||||
template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(),
|
||||
userId, routerDeploymentDefinition.isRedundant(), RedundantState.UNKNOWN, offerHA, false,
|
||||
vpcId);
|
||||
router.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
router.setRole(Role.VIRTUAL_ROUTER);
|
||||
router.setLimitCpuUse(routerOffering.getLimitCpuUse());
|
||||
return _routerDao.persist(router);
|
||||
}
|
||||
router.setTemplateId(template.getId());
|
||||
router.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
_routerDao.update(router.getId(), router);
|
||||
return router;
|
||||
}
|
||||
|
||||
protected DomainRouterVO deployRouterWithTemplates(DomainRouterVO router, final long id,
|
||||
final RouterDeploymentDefinition routerDeploymentDefinition, final Account owner, final long userId,
|
||||
final ServiceOfferingVO routerOffering, final boolean offerHA, final Long vpcId,
|
||||
final List<VMTemplateVO> templates) throws InsufficientCapacityException {
|
||||
for (final Iterator<VMTemplateVO> templatesIterator = templates.iterator(); templatesIterator.hasNext();) {
|
||||
final VMTemplateVO template = templatesIterator.next();
|
||||
try {
|
||||
router = createOrUpdateDomainRouter(router, id, routerDeploymentDefinition, owner, userId,
|
||||
routerOffering, offerHA, vpcId, template);
|
||||
reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
|
||||
router = _routerDao.findById(router.getId());
|
||||
if (templatesIterator.hasNext()) {
|
||||
_itMgr.checkDeploymentPlan(router, template, routerOffering, owner,
|
||||
routerDeploymentDefinition.getPlan());
|
||||
}
|
||||
return router;
|
||||
} catch (InsufficientCapacityException ex) {
|
||||
if (templatesIterator.hasNext()) {
|
||||
logger.debug("Failed to allocate the VR with hypervisor {} and {}, retrying with another template", template.getHypervisorType(), template);
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
|
||||
throws InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {
|
||||
|
||||
final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
|
||||
final boolean offerHA = routerOffering.isOfferHA();
|
||||
final Account owner = routerDeploymentDefinition.getOwner();
|
||||
final Long vpcId = routerDeploymentDefinition.getVpc() != null ? routerDeploymentDefinition.getVpc().getId() : null;
|
||||
|
||||
// Router is the network element, we don't know the hypervisor type yet.
|
||||
// Try to allocate the domR twice using diff hypervisors, and when
|
||||
// failed both times, throw the exception up
|
||||
final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);
|
||||
|
||||
long userId = CallContext.current().getCallingUserId();
|
||||
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
|
||||
final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
|
||||
if (!userVOs.isEmpty()) {
|
||||
userId = userVOs.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
DomainRouterVO router = null;
|
||||
for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
|
||||
final HypervisorType hType = iter.next();
|
||||
@ -521,43 +580,20 @@ public class NetworkHelperImpl implements NetworkHelper {
|
||||
logger.debug(String.format("Allocating the VR with id=%s in datacenter %s with the hypervisor type %s", id, routerDeploymentDefinition.getDest()
|
||||
.getDataCenter(), hType));
|
||||
}
|
||||
|
||||
final String templateName = retrieveTemplateName(hType, routerDeploymentDefinition.getDest().getDataCenter().getId());
|
||||
final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);
|
||||
|
||||
if (template == null) {
|
||||
logger.debug(hType + " won't support system vm, skip it");
|
||||
final long zoneId = routerDeploymentDefinition.getDest().getDataCenter().getId();
|
||||
final String templateName = retrieveTemplateName(hType, zoneId);
|
||||
final String preferredArch = ResourceManager.SystemVmPreferredArchitecture.valueIn(zoneId);
|
||||
final List<VMTemplateVO> templates = _templateDao.findRoutingTemplates(hType, templateName,
|
||||
preferredArch);
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
logger.debug("{} won't support system vm, skip it", hType);
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean offerHA = routerOffering.isOfferHA();
|
||||
|
||||
// routerDeploymentDefinition.getVpc().getId() ==> do not use
|
||||
// VPC because it is not a VPC offering.
|
||||
final Long vpcId = routerDeploymentDefinition.getVpc() != null ? routerDeploymentDefinition.getVpc().getId() : null;
|
||||
|
||||
long userId = CallContext.current().getCallingUserId();
|
||||
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
|
||||
final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
|
||||
if (!userVOs.isEmpty()) {
|
||||
userId = userVOs.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
router = new DomainRouterVO(id, routerOffering.getId(), routerDeploymentDefinition.getVirtualProvider().getId(), VirtualMachineName.getRouterName(id,
|
||||
s_vmInstanceName), template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(),
|
||||
userId, routerDeploymentDefinition.isRedundant(), RedundantState.UNKNOWN, offerHA, false, vpcId);
|
||||
|
||||
router.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
router.setRole(Role.VIRTUAL_ROUTER);
|
||||
router.setLimitCpuUse(routerOffering.getLimitCpuUse());
|
||||
router = _routerDao.persist(router);
|
||||
|
||||
reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
|
||||
router = _routerDao.findById(router.getId());
|
||||
router = deployRouterWithTemplates(router, id, routerDeploymentDefinition, owner, userId,
|
||||
routerOffering, offerHA, vpcId, templates);
|
||||
} catch (final InsufficientCapacityException ex) {
|
||||
if (iter.hasNext()) {
|
||||
logger.debug("Failed to allocate the VR with hypervisor type " + hType + ", retrying one more time");
|
||||
logger.debug("Failed to allocate the VR with {}, retrying with another hypervisor", hType);
|
||||
continue;
|
||||
} else {
|
||||
throw ex;
|
||||
|
||||
@ -32,7 +32,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -60,10 +59,8 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -175,6 +172,7 @@ import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.component.Manager;
|
||||
@ -201,7 +199,6 @@ import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.ssh.SSHCmdHelper;
|
||||
import com.cloud.utils.ssh.SshException;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
@ -1204,6 +1201,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
|
||||
if (arch != null) {
|
||||
List<CPU.CPUArch> architectureTypes = _hostDao.listDistinctArchTypes(cluster.getId());
|
||||
if (architectureTypes.stream().anyMatch(a -> !a.equals(arch))) {
|
||||
throw new InvalidParameterValueException(String.format(
|
||||
"Cluster has host(s) present with arch type(s): %s",
|
||||
StringUtils.join(architectureTypes.stream().map(CPU.CPUArch::getType).toArray())));
|
||||
}
|
||||
cluster.setArch(arch.getType());
|
||||
doUpdate = true;
|
||||
}
|
||||
@ -3276,12 +3279,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
@Override
|
||||
public List<HypervisorType> listAvailHypervisorInZone(final Long zoneId) {
|
||||
List<VMTemplateVO> systemVMTemplates = _templateDao.listAllReadySystemVMTemplates(zoneId);
|
||||
final Set<HypervisorType> hypervisors = new HashSet<>();
|
||||
for (final VMTemplateVO systemVMTemplate : systemVMTemplates) {
|
||||
hypervisors.add(systemVMTemplate.getHypervisorType());
|
||||
final SearchCriteria<String> sc = _hypervisorsInDC.create();
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("dataCenter", zoneId);
|
||||
}
|
||||
return new ArrayList<>(hypervisors);
|
||||
sc.setParameters("type", Host.Type.Routing);
|
||||
|
||||
return _hostDao.customSearch(sc, null).stream()
|
||||
// The search is not able to return list of enums, so getting
|
||||
// list of hypervisors as strings and then converting them to enum
|
||||
.map(HypervisorType::getType).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -3546,6 +3553,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {KvmSshToAgentEnabled, HOST_MAINTENANCE_LOCAL_STRATEGY};
|
||||
return new ConfigKey<?>[] {
|
||||
KvmSshToAgentEnabled,
|
||||
HOST_MAINTENANCE_LOCAL_STRATEGY,
|
||||
SystemVmPreferredArchitecture
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||
@ -674,6 +673,7 @@ import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManagerImpl;
|
||||
import com.cloud.consoleproxy.ConsoleProxyManagementState;
|
||||
import com.cloud.consoleproxy.ConsoleProxyManager;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.AccountVlanMapVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
@ -1274,6 +1274,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
final Object clusterType = cmd.getClusterType();
|
||||
final Object allocationState = cmd.getAllocationState();
|
||||
final String keyword = cmd.getKeyword();
|
||||
final CPU.CPUArch arch = cmd.getArch();
|
||||
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
||||
|
||||
final Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
@ -1286,6 +1287,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ);
|
||||
sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ);
|
||||
sb.and("arch", sb.entity().getArch(), SearchCriteria.Op.EQ);
|
||||
|
||||
final SearchCriteria<ClusterVO> sc = sb.create();
|
||||
if (id != null) {
|
||||
@ -1325,6 +1327,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
||||
}
|
||||
|
||||
if (arch != null) {
|
||||
sc.setParameters("arch", arch);
|
||||
}
|
||||
|
||||
final Pair<List<ClusterVO>, Integer> result = _clusterDao.searchAndCount(sc, searchFilter);
|
||||
return new Pair<>(result.first(), result.second());
|
||||
}
|
||||
@ -4182,6 +4188,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
final Long podId = cmd.getPodId();
|
||||
final Long hostId = cmd.getHostId();
|
||||
final Long storageId = cmd.getStorageId();
|
||||
final CPU.CPUArch arch = cmd.getArch();
|
||||
|
||||
final Filter searchFilter = new Filter(VMInstanceVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
final SearchBuilder<VMInstanceVO> sb = _vmInstanceDao.createSearchBuilder();
|
||||
@ -4208,6 +4215,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
}
|
||||
}
|
||||
|
||||
boolean templateJoinNeeded = arch != null;
|
||||
if (templateJoinNeeded) {
|
||||
SearchBuilder<VMTemplateVO> templateSearch = templateDao.createSearchBuilder();
|
||||
templateSearch.and("templateArch", templateSearch.entity().getArch(), SearchCriteria.Op.EQ);
|
||||
sb.join("vmTemplate", templateSearch, templateSearch.entity().getId(), sb.entity().getTemplateId(), JoinBuilder.JoinType.INNER);
|
||||
}
|
||||
|
||||
final SearchCriteria<VMInstanceVO> sc = sb.create();
|
||||
|
||||
if (keyword != null) {
|
||||
@ -4255,6 +4269,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
}
|
||||
}
|
||||
|
||||
if (arch != null) {
|
||||
sc.setJoinParameters("vmTemplate", "templateArch", arch);
|
||||
}
|
||||
|
||||
final Pair<List<VMInstanceVO>, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter);
|
||||
return new Pair<>(result.first(), result.second());
|
||||
}
|
||||
|
||||
@ -178,6 +178,7 @@ import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.configuration.ConfigurationManagerImpl;
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.VsphereStoragePolicyVO;
|
||||
@ -3585,17 +3586,49 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
|
||||
}
|
||||
|
||||
protected void registerSystemVmTemplateForHypervisorArch(final HypervisorType hypervisorType,
|
||||
final CPU.CPUArch arch, final Long zoneId, final String url, final DataStore store,
|
||||
final SystemVmTemplateRegistration systemVmTemplateRegistration, final String filePath,
|
||||
final Pair<String, Long> storeUrlAndId, final String nfsVersion) {
|
||||
if (HypervisorType.Simulator.equals(hypervisorType)) {
|
||||
return;
|
||||
}
|
||||
String templateName = getValidTemplateName(zoneId, hypervisorType);
|
||||
VMTemplateVO registeredTemplate = systemVmTemplateRegistration.getRegisteredTemplate(templateName, arch);
|
||||
TemplateDataStoreVO templateDataStoreVO = null;
|
||||
if (registeredTemplate != null) {
|
||||
templateDataStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), registeredTemplate.getId());
|
||||
if (templateDataStoreVO != null) {
|
||||
try {
|
||||
if (systemVmTemplateRegistration.validateIfSeeded(templateDataStoreVO, url,
|
||||
templateDataStoreVO.getInstallPath(), nfsVersion)) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to validated if template is seeded", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath, nfsVersion);
|
||||
if (templateDataStoreVO != null) {
|
||||
systemVmTemplateRegistration.validateAndRegisterTemplate(hypervisorType, templateName,
|
||||
storeUrlAndId.second(), registeredTemplate, templateDataStoreVO, filePath);
|
||||
} else {
|
||||
systemVmTemplateRegistration.validateAndRegisterTemplateForNonExistingEntries(hypervisorType, arch,
|
||||
templateName, storeUrlAndId, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerSystemVmTemplateOnFirstNfsStore(Long zoneId, String providerName, String url, DataStore store) {
|
||||
if (DataStoreProvider.NFS_IMAGE.equals(providerName) && zoneId != null) {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||
List<ImageStoreVO> stores = _imageStoreDao.listAllStoresInZone(zoneId, providerName, DataStoreRole.Image);
|
||||
stores = stores.stream().filter(str -> str.getId() != store.getId()).collect(Collectors.toList());
|
||||
// Check if it's the only/first store in the zone
|
||||
if (stores.size() == 0) {
|
||||
List<HypervisorType> hypervisorTypes = _clusterDao.getAvailableHypervisorInZone(zoneId);
|
||||
Set<HypervisorType> hypSet = new HashSet<>(hypervisorTypes);
|
||||
List<ImageStoreVO> stores = _imageStoreDao.listAllStoresInZoneExceptId(zoneId, providerName,
|
||||
DataStoreRole.Image, store.getId());
|
||||
if (CollectionUtils.isEmpty(stores)) {
|
||||
List<Pair<HypervisorType, CPU.CPUArch>> hypervisorTypes =
|
||||
_clusterDao.listDistinctHypervisorsArchAcrossClusters(zoneId);
|
||||
TransactionLegacy txn = TransactionLegacy.open("AutomaticTemplateRegister");
|
||||
SystemVmTemplateRegistration systemVmTemplateRegistration = new SystemVmTemplateRegistration();
|
||||
String filePath = null;
|
||||
@ -3606,40 +3639,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
}
|
||||
Pair<String, Long> storeUrlAndId = new Pair<>(url, store.getId());
|
||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId());
|
||||
for (HypervisorType hypervisorType : hypSet) {
|
||||
for (Pair<HypervisorType, CPU.CPUArch> hypervisorArchType : hypervisorTypes) {
|
||||
try {
|
||||
if (HypervisorType.Simulator == hypervisorType) {
|
||||
continue;
|
||||
}
|
||||
String templateName = getValidTemplateName(zoneId, hypervisorType);
|
||||
Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName =
|
||||
new Pair<>(hypervisorType, templateName);
|
||||
Long templateId = systemVmTemplateRegistration.getRegisteredTemplateId(hypervisorAndTemplateName);
|
||||
VMTemplateVO vmTemplateVO = null;
|
||||
TemplateDataStoreVO templateVO = null;
|
||||
if (templateId != null) {
|
||||
vmTemplateVO = _templateDao.findById(templateId);
|
||||
templateVO = _templateStoreDao.findByStoreTemplate(store.getId(), templateId);
|
||||
if (templateVO != null) {
|
||||
try {
|
||||
if (systemVmTemplateRegistration.validateIfSeeded(
|
||||
templateVO, url, templateVO.getInstallPath(), nfsVersion)) {
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to validated if template is seeded", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath, nfsVersion);
|
||||
if (templateVO != null && vmTemplateVO != null) {
|
||||
systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, vmTemplateVO, templateVO, filePath);
|
||||
} else {
|
||||
systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, filePath);
|
||||
}
|
||||
registerSystemVmTemplateForHypervisorArch(hypervisorArchType.first(),
|
||||
hypervisorArchType.second(), zoneId, url, store,
|
||||
systemVmTemplateRegistration, filePath, storeUrlAndId, nfsVersion);
|
||||
} catch (CloudRuntimeException e) {
|
||||
SystemVmTemplateRegistration.unmountStore(filePath);
|
||||
logger.error(String.format("Failed to register systemVM template for hypervisor: %s", hypervisorType.name()), e);
|
||||
logger.error("Failed to register system VM template for hypervisor: {} {}",
|
||||
hypervisorArchType.first().name(), hypervisorArchType.second().name(), e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -21,6 +21,7 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -243,7 +244,11 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
||||
|
||||
List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
|
||||
for (VMTemplateVO template : systemvmTmplts) {
|
||||
if (template.getName().equalsIgnoreCase(name) || template.getDisplayText().equalsIgnoreCase(displayText)) {
|
||||
if ((template.getName().equalsIgnoreCase(name) ||
|
||||
template.getDisplayText().equalsIgnoreCase(displayText)) &&
|
||||
Objects.equals(template.getArch(), arch)) {
|
||||
logger.error("{} for same arch {} is having same name or description", template,
|
||||
template.getArch());
|
||||
throw new IllegalArgumentException("Cannot use reserved names for templates");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.consoleproxy;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.vm.ConsoleProxyVO;
|
||||
import com.cloud.vm.dao.ConsoleProxyDao;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ConsoleProxyManagerImplTest {
|
||||
@InjectMocks
|
||||
private ConsoleProxyManagerImpl consoleProxyManager;
|
||||
|
||||
@Mock
|
||||
private ConsoleProxyDao consoleProxyDao;
|
||||
|
||||
@Mock
|
||||
private AccountManager accountManager;
|
||||
|
||||
@Mock
|
||||
private ServiceOffering serviceOffering;
|
||||
@Mock
|
||||
private VMTemplateVO template;
|
||||
@Mock
|
||||
private Account systemAccount;
|
||||
@Mock
|
||||
private User systemUser;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(accountManager.getSystemUser()).thenReturn(systemUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConsoleProxy_New() {
|
||||
long dataCenterId = 1L;
|
||||
long id = 10L;
|
||||
String name = "console1";
|
||||
// When creating a new proxy, persist should be called.
|
||||
when(consoleProxyDao.persist(any(ConsoleProxyVO.class)))
|
||||
.thenAnswer(invocation -> invocation.getArgument(0));
|
||||
ConsoleProxyVO result = consoleProxyManager.createOrUpdateConsoleProxy(null, dataCenterId, id, name, serviceOffering, template, systemAccount);
|
||||
assertNotNull(result);
|
||||
assertEquals(id, result.getId());
|
||||
assertEquals(serviceOffering.getId(), result.getServiceOfferingId());
|
||||
assertEquals(name, result.getName());
|
||||
assertEquals(template.getId(), result.getTemplateId());
|
||||
assertEquals(template.getHypervisorType(), result.getHypervisorType());
|
||||
assertEquals(template.getGuestOSId(), result.getGuestOSId());
|
||||
assertEquals(dataCenterId, result.getDataCenterId());
|
||||
assertEquals(systemAccount.getDomainId(), result.getDomainId());
|
||||
assertEquals(systemAccount.getId(), result.getAccountId());
|
||||
assertEquals(serviceOffering.isOfferHA(), result.isHaEnabled());
|
||||
assertEquals(template.isDynamicallyScalable(), result.isDynamicallyScalable());
|
||||
assertEquals(serviceOffering.getLimitCpuUse(), result.limitCpuUse());
|
||||
verify(consoleProxyDao).persist(any(ConsoleProxyVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateConsoleProxy() {
|
||||
long dataCenterId = 1L;
|
||||
long id = 10L;
|
||||
String name = "console1";
|
||||
ConsoleProxyVO existing = new ConsoleProxyVO(id, serviceOffering.getId(), name, 999L, Hypervisor.HypervisorType.KVM, 111L,
|
||||
dataCenterId, systemAccount.getDomainId(), systemAccount.getId(),
|
||||
systemUser.getId(), 0, serviceOffering.isOfferHA());
|
||||
existing.setDynamicallyScalable(false);
|
||||
ConsoleProxyVO result = consoleProxyManager.createOrUpdateConsoleProxy(existing, dataCenterId, id, name, serviceOffering, template, systemAccount);
|
||||
verify(consoleProxyDao).update(existing.getId(), existing);
|
||||
assertEquals(template.getId(), result.getTemplateId());
|
||||
assertEquals(template.getHypervisorType(), result.getHypervisorType());
|
||||
assertEquals(template.getGuestOSId(), result.getGuestOSId());
|
||||
assertEquals(template.isDynamicallyScalable(), result.isDynamicallyScalable());
|
||||
}
|
||||
}
|
||||
@ -16,27 +16,11 @@
|
||||
// under the License.
|
||||
package com.cloud.network.router;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@ -45,6 +29,34 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinition;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.VirtualRouterProvider;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.VirtualMachineName;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NetworkHelperImplTest {
|
||||
@ -54,6 +66,9 @@ public class NetworkHelperImplTest {
|
||||
@Mock
|
||||
protected AgentManager agentManager;
|
||||
|
||||
@Mock
|
||||
DomainRouterDao routerDao;
|
||||
|
||||
@InjectMocks
|
||||
protected NetworkHelperImpl nwHelper = new NetworkHelperImpl();
|
||||
@Mock
|
||||
@ -65,10 +80,27 @@ public class NetworkHelperImplTest {
|
||||
@Mock
|
||||
NicDao nicDao;
|
||||
|
||||
@Mock
|
||||
private RouterDeploymentDefinition routerDeploymentDefinition;
|
||||
@Mock
|
||||
private VirtualRouterProvider virtualProvider;
|
||||
@Mock
|
||||
private Account owner;
|
||||
@Mock
|
||||
private ServiceOfferingVO routerOffering;
|
||||
@Mock
|
||||
private VMTemplateVO template;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
nwHelper._networkDao = networkDao;
|
||||
nwHelper._networkModel = networkModel;
|
||||
when(template.getId()).thenReturn(1L);
|
||||
when(template.isDynamicallyScalable()).thenReturn(true);
|
||||
when(virtualProvider.getId()).thenReturn(1L);
|
||||
when(routerDeploymentDefinition.getVirtualProvider()).thenReturn(virtualProvider);
|
||||
when(routerDeploymentDefinition.isRedundant()).thenReturn(true);
|
||||
when(routerOffering.getLimitCpuUse()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test(expected=ResourceUnavailableException.class)
|
||||
@ -83,7 +115,7 @@ public class NetworkHelperImplTest {
|
||||
nwHelperUT.sendCommandsToRouter(vr, null);
|
||||
|
||||
// Assert
|
||||
verify(this.agentManager, times(0)).send((Long) ArgumentMatchers.any(), (Command) ArgumentMatchers.any());
|
||||
verify(this.agentManager, times(0)).send((Long) any(), (Command) any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -187,4 +219,53 @@ public class NetworkHelperImplTest {
|
||||
verify(answer1, times(0)).getResult();
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDomainRouter_New() {
|
||||
long id = 1L;
|
||||
long userId = 800L;
|
||||
boolean offerHA = false;
|
||||
Long vpcId = 900L;
|
||||
when(routerDao.persist(any(DomainRouterVO.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
DomainRouterVO result = nwHelper.createOrUpdateDomainRouter(
|
||||
null, id, routerDeploymentDefinition, owner, userId, routerOffering, offerHA, vpcId, template);
|
||||
assertNotNull(result);
|
||||
assertEquals(id, result.getId());
|
||||
assertEquals(routerOffering.getId(), result.getServiceOfferingId());
|
||||
assertEquals(1L, result.getElementId());
|
||||
assertEquals(VirtualMachineName.getRouterName(id, NetworkHelperImpl.s_vmInstanceName), result.getInstanceName());
|
||||
assertEquals(template.getId(), result.getTemplateId());
|
||||
assertEquals(template.getHypervisorType(), result.getHypervisorType());
|
||||
assertEquals(template.getGuestOSId(), result.getGuestOSId());
|
||||
assertEquals(owner.getDomainId(), result.getDomainId());
|
||||
assertEquals(owner.getId(), result.getAccountId());
|
||||
assertEquals(userId, result.getUserId());
|
||||
assertTrue(result.getIsRedundantRouter());
|
||||
assertEquals(VirtualRouter.RedundantState.UNKNOWN, result.getRedundantState());
|
||||
assertEquals(offerHA, result.isHaEnabled());
|
||||
assertEquals(vpcId, result.getVpcId());
|
||||
assertTrue(result.isDynamicallyScalable());
|
||||
assertEquals(VirtualRouter.Role.VIRTUAL_ROUTER, result.getRole());
|
||||
assertTrue(result.limitCpuUse());
|
||||
verify(routerDao).persist(any(DomainRouterVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDomainRouter() {
|
||||
long id = 1L;
|
||||
long userId = 800L;
|
||||
boolean offerHA = false;
|
||||
Long vpcId = 900L;
|
||||
DomainRouterVO existing = new DomainRouterVO(id, routerOffering.getId(), virtualProvider.getId(),
|
||||
VirtualMachineName.getRouterName(id, NetworkHelperImpl.s_vmInstanceName), 999L, Hypervisor.HypervisorType.KVM, 888L,
|
||||
owner.getDomainId(), owner.getId(), userId, routerDeploymentDefinition.isRedundant(), VirtualRouter.RedundantState.UNKNOWN,
|
||||
offerHA, false, vpcId);
|
||||
existing.setDynamicallyScalable(false);
|
||||
DomainRouterVO result = nwHelper.createOrUpdateDomainRouter(
|
||||
existing, id, routerDeploymentDefinition, owner, userId, routerOffering, offerHA, vpcId, template);
|
||||
verify(routerDao).update(existing.getId(), existing);
|
||||
assertEquals(template.getId(), result.getTemplateId());
|
||||
assertEquals(Hypervisor.HypervisorType.KVM, result.getHypervisorType());
|
||||
assertTrue(result.isDynamicallyScalable());
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -618,6 +619,25 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
return defaultNetworks.get(0);
|
||||
}
|
||||
|
||||
protected SecondaryStorageVmVO createOrUpdateSecondaryStorageVm(SecondaryStorageVmVO ssvm, long dataCenterId,
|
||||
long id, String name, ServiceOffering serviceOffering, VMTemplateVO template, Account systemAccount,
|
||||
SecondaryStorageVm.Role role) {
|
||||
if (ssvm == null) {
|
||||
ssvm = new SecondaryStorageVmVO(id, serviceOffering.getId(), name, template.getId(),
|
||||
template.getHypervisorType(), template.getGuestOSId(), dataCenterId, systemAccount.getDomainId(),
|
||||
systemAccount.getId(), _accountMgr.getSystemUser().getId(), role, serviceOffering.isOfferHA());
|
||||
ssvm.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
ssvm.setLimitCpuUse(serviceOffering.getLimitCpuUse());
|
||||
return _secStorageVmDao.persist(ssvm);
|
||||
}
|
||||
ssvm.setTemplateId(template.getId());
|
||||
ssvm.setHypervisorType(template.getHypervisorType());
|
||||
ssvm.setGuestOSId(template.getGuestOSId());
|
||||
ssvm.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
_secStorageVmDao.update(ssvm.getId(), ssvm);
|
||||
return ssvm;
|
||||
}
|
||||
|
||||
protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
|
||||
DataStore secStore = _dataStoreMgr.getImageStoreWithFreeCapacity(dataCenterId);
|
||||
if (secStore == null) {
|
||||
@ -657,28 +677,33 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
}
|
||||
|
||||
HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
|
||||
VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
|
||||
if (template == null) {
|
||||
throw new CloudRuntimeException(String.format("Unable to find the system templates or it was not downloaded in %s.", dc.toString()));
|
||||
List<VMTemplateVO> templates = _templateDao.findSystemVMReadyTemplates(dataCenterId, availableHypervisor,
|
||||
ResourceManager.SystemVmPreferredArchitecture.valueIn(dataCenterId));
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to find the system templates or it was not downloaded in %s.", dc));
|
||||
}
|
||||
|
||||
ServiceOfferingVO serviceOffering = _serviceOffering;
|
||||
if (serviceOffering == null) {
|
||||
serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.ssvmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
||||
}
|
||||
SecondaryStorageVmVO secStorageVm =
|
||||
new SecondaryStorageVmVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
|
||||
systemAcct.getDomainId(), systemAcct.getId(), _accountMgr.getSystemUser().getId(), role, serviceOffering.isOfferHA());
|
||||
secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
secStorageVm.setLimitCpuUse(serviceOffering.getLimitCpuUse());
|
||||
secStorageVm = _secStorageVmDao.persist(secStorageVm);
|
||||
try {
|
||||
_itMgr.allocate(name, template, serviceOffering, networks, plan, null);
|
||||
secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
|
||||
} catch (InsufficientCapacityException e) {
|
||||
String errorMessage = String.format("Unable to allocate secondary storage VM [%s] due to [%s].", name, e.getMessage());
|
||||
logger.warn(errorMessage, e);
|
||||
throw new CloudRuntimeException(errorMessage, e);
|
||||
SecondaryStorageVmVO secStorageVm = null;
|
||||
for (final Iterator<VMTemplateVO> templateIterator = templates.iterator(); templateIterator.hasNext();) {
|
||||
VMTemplateVO template = templateIterator.next();
|
||||
secStorageVm = createOrUpdateSecondaryStorageVm(secStorageVm, dataCenterId, id, name, serviceOffering,
|
||||
template, systemAcct, role);
|
||||
try {
|
||||
_itMgr.allocate(name, template, serviceOffering, networks, plan, template.getHypervisorType());
|
||||
secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
|
||||
_itMgr.checkDeploymentPlan(secStorageVm, template, serviceOffering, systemAcct, plan);
|
||||
break;
|
||||
} catch (InsufficientCapacityException e) {
|
||||
if (templateIterator.hasNext()) {
|
||||
logger.debug("Unable to allocate secondary storage {} with {} due to [{}]. Retrying with another template", secStorageVm, template, e.getMessage(), e);
|
||||
continue;
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to allocate secondary storage VM [%s] in zone [%s] with available templates", e);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
@ -820,8 +845,9 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
}
|
||||
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
|
||||
if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
|
||||
VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
|
||||
if (template == null) {
|
||||
List<VMTemplateVO> templates = _templateDao.findSystemVMReadyTemplates(dataCenterId,
|
||||
HypervisorType.Any, null);
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("System VM template is not ready at zone [%s], wait until it is ready to launch secondary storage VM.", dataCenterId));
|
||||
}
|
||||
@ -834,13 +860,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!template.isDirectDownload() && templateMgr.getImageStore(dataCenterId, template.getId()) == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("No secondary storage available in zone [%s], wait until it is ready to launch secondary storage VM.", dataCenterId));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean useLocalStorage = BooleanUtils.toBoolean(ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
||||
boolean hasStoragePoolHostInfo = _storagePoolHostDao.hasDatacenterStoragePoolHostInfo(dataCenterId, !useLocalStorage);
|
||||
if (hasStoragePoolHostInfo) {
|
||||
|
||||
@ -16,39 +16,69 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.secondarystorage;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.SecondaryStorageVm;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.google.common.net.InetAddresses;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SecondaryStorageManagerImplTest {
|
||||
private final SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
@Mock
|
||||
private SecondaryStorageVmDao secStorageVmDao;
|
||||
|
||||
@Mock
|
||||
private AccountManager accountManager;
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
private SecondaryStorageManagerImpl secondaryStorageManager;
|
||||
|
||||
@Mock
|
||||
private ServiceOffering serviceOffering;
|
||||
@Mock
|
||||
private VMTemplateVO template;
|
||||
@Mock
|
||||
private Account systemAccount;
|
||||
@Mock
|
||||
private User systemUser;
|
||||
|
||||
private List<DataStore> mockDataStoresForTestAddSecondaryStorageServerAddressToBuffer(List<String> addresses) {
|
||||
List<DataStore> dataStores = new ArrayList<>();
|
||||
for (String address: addresses) {
|
||||
DataStore dataStore = Mockito.mock(DataStore.class);
|
||||
DataStoreTO dataStoreTO = Mockito.mock(DataStoreTO.class);
|
||||
Mockito.when(dataStoreTO.getUrl()).thenReturn(NetUtils.isValidIp4(address) ? String.format("http://%s", address) : address);
|
||||
Mockito.when(dataStore.getTO()).thenReturn(dataStoreTO);
|
||||
when(dataStoreTO.getUrl()).thenReturn(NetUtils.isValidIp4(address) ? String.format("http://%s", address) : address);
|
||||
when(dataStore.getTO()).thenReturn(dataStoreTO);
|
||||
dataStores.add(dataStore);
|
||||
}
|
||||
return dataStores;
|
||||
@ -60,7 +90,7 @@ public class SecondaryStorageManagerImplTest {
|
||||
secondaryStorageManager.addSecondaryStorageServerAddressToBuffer(builder, dataStores, "VM");
|
||||
String result = builder.toString();
|
||||
result = result.contains("=") ? result.split("=")[1] : null;
|
||||
Assert.assertEquals(expected, result);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -86,4 +116,55 @@ public class SecondaryStorageManagerImplTest {
|
||||
List<String> addresses = List.of(randomIp1, "garbage", randomIp2);
|
||||
runAddSecondaryStorageServerAddressToBufferTest(addresses, StringUtils.join(List.of(randomIp1, randomIp2), ","));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSecondaryStorageVm_New() {
|
||||
long dataCenterId = 1L;
|
||||
long id = 100L;
|
||||
String name = "ssvm1";
|
||||
SecondaryStorageVm.Role role = SecondaryStorageVm.Role.templateProcessor;
|
||||
when(systemUser.getId()).thenReturn(1L);
|
||||
when(accountManager.getSystemUser()).thenReturn(systemUser);
|
||||
when(secStorageVmDao.persist(any(SecondaryStorageVmVO.class)))
|
||||
.thenAnswer(invocation -> invocation.getArgument(0));
|
||||
SecondaryStorageVmVO result = secondaryStorageManager.createOrUpdateSecondaryStorageVm(
|
||||
null, dataCenterId, id, name, serviceOffering, template, systemAccount, role);
|
||||
assertNotNull(result);
|
||||
assertEquals(id, result.getId());
|
||||
assertEquals(serviceOffering.getId(), result.getServiceOfferingId());
|
||||
assertEquals(name, result.getName());
|
||||
assertEquals(template.getId(), result.getTemplateId());
|
||||
assertEquals(template.getHypervisorType(), result.getHypervisorType());
|
||||
assertEquals(template.getGuestOSId(), result.getGuestOSId());
|
||||
assertEquals(dataCenterId, result.getDataCenterId());
|
||||
assertEquals(systemAccount.getDomainId(), result.getDomainId());
|
||||
assertEquals(systemAccount.getId(), result.getAccountId());
|
||||
assertEquals(role, result.getRole());
|
||||
assertEquals(template.isDynamicallyScalable(), result.isDynamicallyScalable());
|
||||
assertEquals(serviceOffering.getLimitCpuUse(), result.limitCpuUse());
|
||||
|
||||
verify(secStorageVmDao).persist(any(SecondaryStorageVmVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSecondaryStorageVm() {
|
||||
long dataCenterId = 1L;
|
||||
long id = 100L;
|
||||
String name = "ssvm1";
|
||||
SecondaryStorageVm.Role role = SecondaryStorageVm.Role.commandExecutor;
|
||||
SecondaryStorageVmVO existing = new SecondaryStorageVmVO(id, serviceOffering.getId(), name,
|
||||
999L, Hypervisor.HypervisorType.KVM, 888L, dataCenterId, systemAccount.getDomainId(), systemAccount.getId(),
|
||||
systemUser.getId(), role, serviceOffering.isOfferHA());
|
||||
existing.setDynamicallyScalable(false);
|
||||
|
||||
SecondaryStorageVmVO result = secondaryStorageManager.createOrUpdateSecondaryStorageVm(
|
||||
existing, dataCenterId, id, name, serviceOffering, template, systemAccount, role);
|
||||
assertNotNull(result);
|
||||
assertEquals(template.getId(), result.getTemplateId());
|
||||
assertEquals(template.getHypervisorType(), result.getHypervisorType());
|
||||
assertEquals(template.getGuestOSId(), result.getGuestOSId());
|
||||
assertEquals(template.isDynamicallyScalable(), result.isDynamicallyScalable());
|
||||
|
||||
verify(secStorageVmDao).update(existing.getId(), existing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ CREATE TABLE `simulator`.`mockhost` (
|
||||
`cpus` int(10) unsigned,
|
||||
`speed` int(10) unsigned,
|
||||
`ram` bigint unsigned,
|
||||
`arch` varchar(8) DEFAULT "x86_64" COMMENT "the CPU architecture of the host",
|
||||
`capabilities` varchar(255) COMMENT 'host capabilities in comma separated list',
|
||||
`vm_id` bigint unsigned,
|
||||
`resource` varchar(255) DEFAULT NULL COMMENT 'If it is a local resource, this is the class name',
|
||||
|
||||
@ -24,13 +24,7 @@ from marvin.lib.common import list_hosts
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from OpenSSL.crypto import FILETYPE_PEM, verify, X509
|
||||
|
||||
PUBKEY_VERIFY=True
|
||||
try:
|
||||
from OpenSSL.crypto import load_publickey
|
||||
except ImportError:
|
||||
PUBKEY_VERIFY=False
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
|
||||
|
||||
class TestCARootProvider(cloudstackTestCase):
|
||||
@ -52,6 +46,20 @@ class TestCARootProvider(cloudstackTestCase):
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
|
||||
def verifySignature(self, caCert, cert):
|
||||
print("Verifying Certificate")
|
||||
caPublicKey = caCert.public_key()
|
||||
try:
|
||||
caPublicKey.verify(
|
||||
cert.signature,
|
||||
cert.tbs_certificate_bytes,
|
||||
padding.PKCS1v15(),
|
||||
cert.signature_hash_algorithm,
|
||||
)
|
||||
print("Certificate is valid!")
|
||||
except Exception as e:
|
||||
print(f"Certificate verification failed: {e}")
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
@ -136,13 +144,8 @@ class TestCARootProvider(cloudstackTestCase):
|
||||
self.assertTrue(address in [str(x) for x in altNames.value.get_values_for_type(x509.IPAddress)])
|
||||
|
||||
# Validate certificate against CA public key
|
||||
global PUBKEY_VERIFY
|
||||
if not PUBKEY_VERIFY:
|
||||
return
|
||||
caCert = x509.load_pem_x509_certificate(self.getCaCertificate().encode(), default_backend())
|
||||
x = X509()
|
||||
x.set_pubkey(load_publickey(FILETYPE_PEM, caCert.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)))
|
||||
verify(x, cert.signature, cert.tbs_certificate_bytes, cert.signature_hash_algorithm.name)
|
||||
self.verifySignature(caCert, cert)
|
||||
|
||||
|
||||
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
|
||||
@ -165,13 +168,8 @@ class TestCARootProvider(cloudstackTestCase):
|
||||
self.assertEqual(cert.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[0].value, 'v-1-VM')
|
||||
|
||||
# Validate certificate against CA public key
|
||||
global PUBKEY_VERIFY
|
||||
if not PUBKEY_VERIFY:
|
||||
return
|
||||
caCert = x509.load_pem_x509_certificate(self.getCaCertificate().encode(), default_backend())
|
||||
x = X509()
|
||||
x.set_pubkey(load_publickey(FILETYPE_PEM, caCert.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)))
|
||||
verify(x, cert.signature, cert.tbs_certificate_bytes, cert.signature_hash_algorithm.name)
|
||||
self.verifySignature(caCert, cert)
|
||||
|
||||
|
||||
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
|
||||
|
||||
@ -23,11 +23,12 @@ import logging
|
||||
import time
|
||||
from collections.abc import Iterable
|
||||
|
||||
from marvin.codes import FAILED
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.cloudstackAPI import (migrateSystemVm, listRouters, listSystemVms)
|
||||
from marvin.lib.base import (Cluster, Configurations, Host, Network, NetworkOffering, ServiceOffering, VirtualMachine,
|
||||
Zone)
|
||||
from marvin.lib.common import (get_domain, get_zone, get_template)
|
||||
from marvin.lib.common import (get_domain, get_zone, get_test_template)
|
||||
from marvin.lib.utils import wait_until
|
||||
from marvin import jsonHelper
|
||||
from nose.plugins.attrib import attr
|
||||
@ -43,7 +44,15 @@ class TestClusterDRS(cloudstackTestCase):
|
||||
|
||||
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
cls.zone = Zone(zone.__dict__)
|
||||
cls.template = get_template(cls.apiclient, cls.zone.id)
|
||||
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
||||
cls.template = get_test_template(
|
||||
cls.apiclient,
|
||||
cls.zone.id,
|
||||
cls.hypervisor
|
||||
)
|
||||
if cls.template == FAILED:
|
||||
assert False, "get_test_template() failed to return template\
|
||||
with hypervisor %s" % cls.hypervisor
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger("TestClusterDRS")
|
||||
|
||||
@ -74,7 +74,6 @@ class TestData(object):
|
||||
"listApis": "allow",
|
||||
"listAccounts": "allow",
|
||||
"listClusters": "deny",
|
||||
"*VmwareDc*": "allow",
|
||||
"*VM*": "allow",
|
||||
"*Host*": "deny"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user