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.
|
// under the License.
|
||||||
package com.cloud.cpu;
|
package com.cloud.cpu;
|
||||||
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class CPU {
|
public class CPU {
|
||||||
|
public enum CPUArch {
|
||||||
|
x86("i686", 32),
|
||||||
|
amd64("x86_64", 64),
|
||||||
|
arm64("aarch64", 64);
|
||||||
|
|
||||||
public static final String archX86Identifier = "i686";
|
private final String type;
|
||||||
public static final String archX86_64Identifier = "x86_64";
|
private final int bits;
|
||||||
public static final String archARM64Identifier = "aarch64";
|
|
||||||
|
|
||||||
public static class CPUArch {
|
CPUArch(String type, int bits) {
|
||||||
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) {
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.bits = bits;
|
this.bits = bits;
|
||||||
cpuArchMap.put(type, this);
|
}
|
||||||
|
|
||||||
|
public static CPUArch getDefault() {
|
||||||
|
return amd64;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return this.type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBits() {
|
public int getBits() {
|
||||||
return this.bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CPUArch fromType(String type) {
|
public static CPUArch fromType(String type) {
|
||||||
if (StringUtils.isBlank(type)) {
|
if (StringUtils.isBlank(type)) {
|
||||||
return amd64;
|
return getDefault();
|
||||||
}
|
}
|
||||||
switch (type) {
|
for (CPUArch arch : values()) {
|
||||||
case archX86Identifier: return archX86;
|
if (arch.type.equals(type)) {
|
||||||
case archX86_64Identifier: return amd64;
|
return arch;
|
||||||
case archARM64Identifier: return arm64;
|
|
||||||
default: throw new CloudRuntimeException(String.format("Unsupported arch type: %s", type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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_HOST_NAME = String.format("%s-host", VMWARE_TO_KVM_PREFIX);
|
||||||
String VMWARE_DISK = String.format("%s-disk", 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);
|
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 STATE = "state";
|
||||||
public static final String STATS = "stats";
|
public static final String STATS = "stats";
|
||||||
public static final String STATUS = "status";
|
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_CAPABILITIES = "storagecapabilities";
|
||||||
public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
|
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 SUBNET = "subnet";
|
||||||
public static final String OWNER = "owner";
|
public static final String OWNER = "owner";
|
||||||
public static final String SWAP_OWNER = "swapowner";
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseListCmd;
|
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.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.PodResponse;
|
import org.apache.cloudstack.api.response.PodResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
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.org.Cluster;
|
||||||
import com.cloud.utils.Pair;
|
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")
|
@Parameter(name = ApiConstants.SHOW_CAPACITIES, type = CommandType.BOOLEAN, description = "flag to display the capacity of the clusters")
|
||||||
private Boolean showCapacities;
|
private Boolean showCapacities;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||||
|
description = "CPU arch of the clusters",
|
||||||
|
since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -112,6 +118,10 @@ public class ListClustersCmd extends BaseListCmd {
|
|||||||
return showCapacities;
|
return showCapacities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -21,7 +21,6 @@ import java.util.EnumSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
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.PodResponse;
|
||||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
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.exception.InvalidParameterValueException;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
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")
|
@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;
|
private Long managementServerId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING, description = "CPU Arch of the host", since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -197,6 +201,10 @@ public class ListHostsCmd extends BaseListCmd {
|
|||||||
return managementServerId;
|
return managementServerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -16,8 +16,6 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.admin.router;
|
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.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
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.UserVmResponse;
|
||||||
import org.apache.cloudstack.api.response.VpcResponse;
|
import org.apache.cloudstack.api.response.VpcResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
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.network.router.VirtualRouter.Role;
|
||||||
import com.cloud.vm.VirtualMachine;
|
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")
|
description = "if true is passed for this parameter, also fetch last executed health check results for the router. Default is false")
|
||||||
private Boolean fetchHealthCheckResults;
|
private Boolean fetchHealthCheckResults;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||||
|
description = "CPU arch of the router",
|
||||||
|
since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -146,6 +152,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd {
|
|||||||
return BooleanUtils.isTrue(fetchHealthCheckResults);
|
return BooleanUtils.isTrue(fetchHealthCheckResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
|
|||||||
@ -19,7 +19,6 @@ package org.apache.cloudstack.api.command.admin.systemvm;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
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.StoragePoolResponse;
|
||||||
import org.apache.cloudstack.api.response.SystemVmResponse;
|
import org.apache.cloudstack.api.response.SystemVmResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
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.utils.Pair;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
|
||||||
@ -74,6 +75,11 @@ public class ListSystemVMsCmd extends BaseListCmd {
|
|||||||
since = "3.0.1")
|
since = "3.0.1")
|
||||||
private Long storageId;
|
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 ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -110,6 +116,10 @@ public class ListSystemVMsCmd extends BaseListCmd {
|
|||||||
return storageId;
|
return storageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// 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.UserVmResponse;
|
||||||
import org.apache.cloudstack.api.response.VpcResponse;
|
import org.apache.cloudstack.api.response.VpcResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
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.exception.InvalidParameterValueException;
|
||||||
import com.cloud.server.ResourceIcon;
|
import com.cloud.server.ResourceIcon;
|
||||||
import com.cloud.server.ResourceTag;
|
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")
|
@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;
|
private Long userdataId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
|
||||||
|
description = "CPU arch of the VM",
|
||||||
|
since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -292,6 +299,10 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
|
|||||||
return isVnf;
|
return isVnf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return StringUtils.isBlank(arch) ? null : CPU.CPUArch.fromType(arch);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -245,6 +245,10 @@ public class DomainRouterResponse extends BaseResponseWithAnnotations implements
|
|||||||
@Param(description = "the version of the code / software in the router")
|
@Param(description = "the version of the code / software in the router")
|
||||||
private String softwareVersion;
|
private String softwareVersion;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.ARCH)
|
||||||
|
@Param(description = "CPU arch of the router", since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
public DomainRouterResponse() {
|
public DomainRouterResponse() {
|
||||||
nics = new LinkedHashSet<NicResponse>();
|
nics = new LinkedHashSet<NicResponse>();
|
||||||
}
|
}
|
||||||
@ -518,4 +522,8 @@ public class DomainRouterResponse extends BaseResponseWithAnnotations implements
|
|||||||
public void setSoftwareVersion(String softwareVersion) {
|
public void setSoftwareVersion(String softwareVersion) {
|
||||||
this.softwareVersion = softwareVersion;
|
this.softwareVersion = softwareVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setArch(String arch) {
|
||||||
|
this.arch = arch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -152,7 +152,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
@SerializedName("memoryallocated")
|
@SerializedName("memoryallocated")
|
||||||
@Param(description = "the amount of the host's memory currently allocated")
|
@Param(description = "the amount of the host's memory currently allocated")
|
||||||
private Long memoryAllocated;
|
private long memoryAllocated;
|
||||||
|
|
||||||
@SerializedName("memoryallocatedpercentage")
|
@SerializedName("memoryallocatedpercentage")
|
||||||
@Param(description = "the amount of the host's memory currently allocated in percentage")
|
@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;
|
this.memWithOverprovisioning=memWithOverprovisioning;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemoryAllocated(Long memoryAllocated) {
|
public void setMemoryAllocated(long memoryAllocated) {
|
||||||
this.memoryAllocated = memoryAllocated;
|
this.memoryAllocated = memoryAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,8 +703,8 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||||||
return memoryTotal;
|
return memoryTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getMemoryAllocated() {
|
public long getMemoryAllocated() {
|
||||||
return memoryAllocated == null ? 0 : memoryAllocated;
|
return memoryAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemoryAllocatedPercentage(String memoryAllocatedPercentage) {
|
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.")
|
@Param(description = "the name of the service offering of the system virtual machine.")
|
||||||
private String serviceOfferingName;
|
private String serviceOfferingName;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.ARCH)
|
||||||
|
@Param(description = "CPU arch of the system VM", since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getObjectId() {
|
public String getObjectId() {
|
||||||
return this.getId();
|
return this.getId();
|
||||||
@ -490,4 +494,8 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
|
|||||||
public void setServiceOfferingName(String serviceOfferingName) {
|
public void setServiceOfferingName(String serviceOfferingName) {
|
||||||
this.serviceOfferingName = 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.ApiConstants;
|
||||||
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
|
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
|
||||||
import org.apache.cloudstack.api.EntityReference;
|
import org.apache.cloudstack.api.EntityReference;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import com.cloud.network.router.VirtualRouter;
|
import com.cloud.network.router.VirtualRouter;
|
||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
import com.cloud.uservm.UserVm;
|
import com.cloud.uservm.UserVm;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
|
@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")
|
@Param(description = "User VM type", since = "4.20.0")
|
||||||
private String vmType;
|
private String vmType;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.ARCH)
|
||||||
|
@Param(description = "CPU arch of the VM", since = "4.20.1")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
public UserVmResponse() {
|
public UserVmResponse() {
|
||||||
securityGroupList = new LinkedHashSet<>();
|
securityGroupList = new LinkedHashSet<>();
|
||||||
nics = new TreeSet<>(Comparator.comparingInt(x -> Integer.parseInt(x.getDeviceId())));
|
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) {
|
public void setIpAddress(String ipAddress) {
|
||||||
this.ipAddress = ipAddress;
|
this.ipAddress = ipAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getArch() {
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArch(String arch) {
|
||||||
|
this.arch = arch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.query;
|
package org.apache.cloudstack.query;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
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 org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
|
import com.cloud.vm.VmDetailConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service used for list api query.
|
* Service used for list api query.
|
||||||
@ -104,6 +106,8 @@ import com.cloud.exception.PermissionDeniedException;
|
|||||||
*/
|
*/
|
||||||
public interface QueryService {
|
public interface QueryService {
|
||||||
|
|
||||||
|
List<String> RootAdminOnlyVmSettings = Arrays.asList(VmDetailConstants.GUEST_CPU_MODE, VmDetailConstants.GUEST_CPU_MODEL);
|
||||||
|
|
||||||
// Config keys
|
// Config keys
|
||||||
ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
|
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);
|
"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}
|
chmod 0640 ${CONFDIR}/${DBPROPS}
|
||||||
chgrp cloud ${CONFDIR}/${DBPROPS}
|
chgrp cloud ${CONFDIR}/${DBPROPS}
|
||||||
chown -R cloud:cloud /var/log/cloudstack/management
|
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
|
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);
|
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.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
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.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.framework.events.Event;
|
import org.apache.cloudstack.framework.events.Event;
|
||||||
import org.apache.cloudstack.framework.events.EventBus;
|
import org.apache.cloudstack.framework.events.EventBus;
|
||||||
import org.apache.cloudstack.framework.events.EventDistributor;
|
import org.apache.cloudstack.framework.events.EventDistributor;
|
||||||
import org.apache.commons.collections.MapUtils;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
|
||||||
|
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.dao.DataCenterDao;
|
import com.cloud.dc.dao.DataCenterDao;
|
||||||
@ -243,4 +245,22 @@ public class UsageEventUtils {
|
|||||||
|
|
||||||
static final String Name = "management-server";
|
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.StartupRoutingCommand;
|
||||||
import com.cloud.agent.api.VgpuTypesInfo;
|
import com.cloud.agent.api.VgpuTypesInfo;
|
||||||
import com.cloud.agent.api.to.GPUDeviceTO;
|
import com.cloud.agent.api.to.GPUDeviceTO;
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.HostPodVO;
|
import com.cloud.dc.HostPodVO;
|
||||||
import com.cloud.dc.PodCluster;
|
import com.cloud.dc.PodCluster;
|
||||||
@ -61,6 +62,17 @@ public interface ResourceManager extends ResourceService, Configurable {
|
|||||||
+ "To force-stop VMs, choose 'ForceStop' strategy",
|
+ "To force-stop VMs, choose 'ForceStop' strategy",
|
||||||
true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.Select, "Error,Migration,ForceStop");
|
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.
|
* Register a listener for different types of resource life cycle events.
|
||||||
* There can only be one type of listener per type of host.
|
* 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;
|
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)) {
|
if (isNetworkImplemented(network)) {
|
||||||
logger.debug("Network {} is already implemented", network);
|
logger.debug("Network {} is already implemented", network);
|
||||||
implemented.set(guru, 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;
|
return implemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1585,9 +1583,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
|
|
||||||
network.setRestartRequired(false);
|
network.setRestartRequired(false);
|
||||||
_networksDao.update(network.getId(), network);
|
_networksDao.update(network.getId(), network);
|
||||||
|
UsageEventUtils.publishNetworkUpdate(network);
|
||||||
implemented.set(guru, 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;
|
return implemented;
|
||||||
} catch (final NoTransitionException e) {
|
} catch (final NoTransitionException e) {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
@ -3087,6 +3084,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
if (updateResourceCount) {
|
if (updateResourceCount) {
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
|
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
|
||||||
}
|
}
|
||||||
|
UsageEventUtils.publishNetworkCreation(network);
|
||||||
|
|
||||||
return 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);
|
logger.debug("Lock is acquired for network {} as a part of network shutdown", network);
|
||||||
|
|
||||||
if (network.getState() == Network.State.Allocated) {
|
final Network.State initialState = network.getState();
|
||||||
logger.debug("Network is already shutdown: {}", network);
|
if (initialState == Network.State.Allocated) {
|
||||||
|
logger.debug(String.format("Network [%s] is in Allocated state, no need to shutdown.", network));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
|
if (initialState != Network.State.Implemented && initialState != Network.State.Shutdown) {
|
||||||
logger.debug("Network is not implemented: {}", network);
|
logger.debug("Network is not implemented: " + network);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3218,6 +3217,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
}
|
}
|
||||||
_networksDao.update(networkFinal.getId(), networkFinal);
|
_networksDao.update(networkFinal.getId(), networkFinal);
|
||||||
_networksDao.clearCheckForGc(networkId);
|
_networksDao.clearCheckForGc(networkId);
|
||||||
|
if (initialState == Network.State.Implemented) {
|
||||||
|
UsageEventUtils.publishNetworkUpdate(networkFinal);
|
||||||
|
}
|
||||||
result = true;
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
try {
|
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());
|
final Pair<Class<?>, Long> networkMsg = new Pair<Class<?>, Long>(Network.class, networkFinal.getId());
|
||||||
_messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg);
|
_messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg);
|
||||||
}
|
}
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_DELETE, network.getAccountId(), network.getDataCenterId(), network.getId(),
|
UsageEventUtils.publishNetworkDeletion(network);
|
||||||
network.getName(), network.getNetworkOfferingId(), null, null, null, Network.class.getName(), network.getUuid());
|
|
||||||
return true;
|
return true;
|
||||||
} catch (final CloudRuntimeException e) {
|
} catch (final CloudRuntimeException e) {
|
||||||
logger.error("Failed to delete network", e);
|
logger.error("Failed to delete network", e);
|
||||||
|
|||||||
@ -891,7 +891,7 @@ public class NetworkOrchestratorTest extends TestCase {
|
|||||||
boolean shutdownNetworkStatus = testOrchestrator.shutdownNetwork(networkId, reservationContext, false);
|
boolean shutdownNetworkStatus = testOrchestrator.shutdownNetwork(networkId, reservationContext, false);
|
||||||
Assert.assertFalse(shutdownNetworkStatus);
|
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)).acquireInLockTable(networkId, NetworkLockTimeout.value());
|
||||||
verify(testOrchestrator._networksDao, times(1)).releaseFromLockTable(networkId);
|
verify(testOrchestrator._networksDao, times(1)).releaseFromLockTable(networkId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -165,6 +165,15 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.mode>true</test.mode>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<profiles>
|
<profiles>
|
||||||
|
|||||||
@ -18,11 +18,11 @@ package com.cloud.dc.dao;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.cloud.cpu.CPU;
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
||||||
@ -30,13 +30,11 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
|||||||
|
|
||||||
ClusterVO findBy(String name, long podId);
|
ClusterVO findBy(String name, long podId);
|
||||||
|
|
||||||
List<ClusterVO> listByHyTypeWithoutGuid(String hyType);
|
|
||||||
|
|
||||||
List<ClusterVO> listByZoneId(long zoneId);
|
List<ClusterVO> listByZoneId(long zoneId);
|
||||||
|
|
||||||
List<HypervisorType> getAvailableHypervisorInZone(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);
|
List<ClusterVO> listByDcHyType(long dcId, String hyType);
|
||||||
|
|
||||||
|
|||||||
@ -21,10 +21,8 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -39,6 +37,7 @@ import com.cloud.dc.HostPodVO;
|
|||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.org.Grouping;
|
import com.cloud.org.Grouping;
|
||||||
import com.cloud.org.Managed;
|
import com.cloud.org.Managed;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.GenericSearchBuilder;
|
import com.cloud.utils.db.GenericSearchBuilder;
|
||||||
import com.cloud.utils.db.JoinBuilder;
|
import com.cloud.utils.db.JoinBuilder;
|
||||||
@ -148,14 +147,6 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||||||
return findOneBy(sc);
|
return findOneBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ClusterVO> listByHyTypeWithoutGuid(String hyType) {
|
|
||||||
SearchCriteria<ClusterVO> sc = HyTypeWithoutGuidSearch.create();
|
|
||||||
sc.setParameters("hypervisorType", hyType);
|
|
||||||
|
|
||||||
return listBy(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ClusterVO> listByDcHyType(long dcId, String hyType) {
|
public List<ClusterVO> listByDcHyType(long dcId, String hyType) {
|
||||||
SearchCriteria<ClusterVO> sc = ZoneHyTypeSearch.create();
|
SearchCriteria<ClusterVO> sc = ZoneHyTypeSearch.create();
|
||||||
@ -178,8 +169,19 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<HypervisorType> getDistinctAvailableHypervisorsAcrossClusters() {
|
public List<Pair<HypervisorType, CPU.CPUArch>> listDistinctHypervisorsArchAcrossClusters(Long zoneId) {
|
||||||
return new HashSet<>(getAvailableHypervisorInZone(null));
|
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
|
@Override
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package com.cloud.host.dao;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.Host.Type;
|
import com.cloud.host.Host.Type;
|
||||||
import com.cloud.host.HostVO;
|
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<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);
|
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.HostTransferMapVO;
|
||||||
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
|
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
|
||||||
import com.cloud.configuration.ManagementServiceConfiguration;
|
import com.cloud.configuration.ManagementServiceConfiguration;
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.dc.dao.ClusterDao;
|
import com.cloud.dc.dao.ClusterDao;
|
||||||
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
||||||
@ -1795,17 +1796,52 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HypervisorType> listDistinctHypervisorTypes(final Long zoneId) {
|
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("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||||
sb.select(null, Func.DISTINCT, sb.entity().getHypervisorType());
|
sb.select(null, Func.DISTINCT, sb.entity().getHypervisorType());
|
||||||
sb.done();
|
sb.done();
|
||||||
SearchCriteria<HypervisorType> sc = sb.create();
|
SearchCriteria<String> sc = sb.create();
|
||||||
if (zoneId != null) {
|
if (zoneId != null) {
|
||||||
sc.setParameters("zoneId", zoneId);
|
sc.setParameters("zoneId", zoneId);
|
||||||
}
|
}
|
||||||
sc.setParameters("type", Type.Routing);
|
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
|
@Override
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package com.cloud.storage.dao;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
@ -73,9 +74,13 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
|||||||
|
|
||||||
VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType);
|
VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType);
|
||||||
|
|
||||||
|
List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType, String preferredArch);
|
||||||
|
|
||||||
VMTemplateVO findRoutingTemplate(HypervisorType type, String templateName);
|
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);
|
public Long countTemplatesForAccount(long accountId);
|
||||||
|
|
||||||
@ -87,7 +92,7 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
|||||||
|
|
||||||
List<VMTemplateVO> listByParentTemplatetId(long parentTemplatetId);
|
List<VMTemplateVO> listByParentTemplatetId(long parentTemplatetId);
|
||||||
|
|
||||||
VMTemplateVO findLatestTemplateByName(String name);
|
VMTemplateVO findLatestTemplateByName(String name, CPU.CPUArch arch);
|
||||||
|
|
||||||
List<VMTemplateVO> findTemplatesLinkedToUserdata(long userdataId);
|
List<VMTemplateVO> findTemplatesLinkedToUserdata(long userdataId);
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,9 @@ package com.cloud.storage.dao;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.TemplateDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.dao.DataCenterDao;
|
import com.cloud.dc.dao.DataCenterDao;
|
||||||
import com.cloud.domain.dao.DomainDao;
|
import com.cloud.domain.dao.DomainDao;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
@ -47,6 +51,7 @@ import com.cloud.storage.VMTemplateZoneVO;
|
|||||||
import com.cloud.tags.ResourceTagVO;
|
import com.cloud.tags.ResourceTagVO;
|
||||||
import com.cloud.tags.dao.ResourceTagDao;
|
import com.cloud.tags.dao.ResourceTagDao;
|
||||||
import com.cloud.template.VirtualMachineTemplate;
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.db.Filter;
|
import com.cloud.utils.db.Filter;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
@ -111,6 +116,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||||||
LatestTemplateByHypervisorTypeSearch = createSearchBuilder();
|
LatestTemplateByHypervisorTypeSearch = createSearchBuilder();
|
||||||
LatestTemplateByHypervisorTypeSearch.and("hypervisorType", LatestTemplateByHypervisorTypeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
LatestTemplateByHypervisorTypeSearch.and("hypervisorType", LatestTemplateByHypervisorTypeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||||
LatestTemplateByHypervisorTypeSearch.and("templateType", LatestTemplateByHypervisorTypeSearch.entity().getTemplateType(), 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);
|
LatestTemplateByHypervisorTypeSearch.and("removed", LatestTemplateByHypervisorTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,10 +244,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VMTemplateVO findLatestTemplateByName(String name) {
|
public VMTemplateVO findLatestTemplateByName(String name, CPU.CPUArch arch) {
|
||||||
SearchCriteria<VMTemplateVO> sc = createSearchCriteria();
|
SearchBuilder<VMTemplateVO> sb = createSearchBuilder();
|
||||||
sc.addAnd("name", SearchCriteria.Op.EQ, name);
|
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
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);
|
Filter filter = new Filter(VMTemplateVO.class, "id", false, null, 1L);
|
||||||
List<VMTemplateVO> templates = listBy(sc, filter);
|
List<VMTemplateVO> templates = listBy(sc, filter);
|
||||||
if ((templates != null) && !templates.isEmpty()) {
|
if ((templates != null) && !templates.isEmpty()) {
|
||||||
@ -580,6 +592,59 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||||||
.orElse(null);
|
.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
|
@Override
|
||||||
public VMTemplateVO findRoutingTemplate(HypervisorType hType, String templateName) {
|
public VMTemplateVO findRoutingTemplate(HypervisorType hType, String templateName) {
|
||||||
SearchCriteria<VMTemplateVO> sc = tmpltTypeHyperSearch2.create();
|
SearchCriteria<VMTemplateVO> sc = tmpltTypeHyperSearch2.create();
|
||||||
@ -618,10 +683,43 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
SearchCriteria<VMTemplateVO> sc = LatestTemplateByHypervisorTypeSearch.create();
|
||||||
sc.setParameters("hypervisorType", hypervisorType);
|
sc.setParameters("hypervisorType", hypervisorType);
|
||||||
sc.setParameters("templateType", type);
|
sc.setParameters("templateType", type);
|
||||||
|
if (arch != null) {
|
||||||
|
sc.setParameters("arch", arch);
|
||||||
|
}
|
||||||
Filter filter = new Filter(VMTemplateVO.class, "id", false, null, 1L);
|
Filter filter = new Filter(VMTemplateVO.class, "id", false, null, 1L);
|
||||||
List<VMTemplateVO> templates = listBy(sc, filter);
|
List<VMTemplateVO> templates = listBy(sc, filter);
|
||||||
if (templates != null && !templates.isEmpty()) {
|
if (templates != null && !templates.isEmpty()) {
|
||||||
|
|||||||
@ -16,6 +16,47 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.upgrade;
|
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.DataCenterVO;
|
||||||
import com.cloud.dc.dao.ClusterDao;
|
import com.cloud.dc.dao.ClusterDao;
|
||||||
import com.cloud.dc.dao.ClusterDaoImpl;
|
import com.cloud.dc.dao.ClusterDaoImpl;
|
||||||
@ -36,6 +77,7 @@ import com.cloud.template.VirtualMachineTemplate;
|
|||||||
import com.cloud.upgrade.dao.BasicTemplateDataStoreDaoImpl;
|
import com.cloud.upgrade.dao.BasicTemplateDataStoreDaoImpl;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.DateUtil;
|
import com.cloud.utils.DateUtil;
|
||||||
|
import com.cloud.utils.HttpUtils;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.UriUtils;
|
import com.cloud.utils.UriUtils;
|
||||||
import com.cloud.utils.db.GlobalLock;
|
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.utils.script.Script;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
import com.cloud.vm.dao.VMInstanceDaoImpl;
|
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 {
|
public class SystemVmTemplateRegistration {
|
||||||
protected static Logger LOGGER = LogManager.getLogger(SystemVmTemplateRegistration.class);
|
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 UMOUNT_COMMAND = "sudo umount %s";
|
||||||
private static final String RELATIVE_TEMPLATE_PATH = "./engine/schema/dist/systemvm-templates/";
|
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/";
|
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 LINUX_7_ID = 183;
|
||||||
private static final Integer SCRIPT_TIMEOUT = 1800000;
|
private static final Integer SCRIPT_TIMEOUT = 1800000;
|
||||||
private static final Integer LOCK_WAIT_TIMEOUT = 1200;
|
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;
|
public static String CS_MAJOR_VERSION = null;
|
||||||
@ -128,6 +135,8 @@ public class SystemVmTemplateRegistration {
|
|||||||
|
|
||||||
private String systemVmTemplateVersion;
|
private String systemVmTemplateVersion;
|
||||||
|
|
||||||
|
private final File tempDownloadDir;
|
||||||
|
|
||||||
public SystemVmTemplateRegistration() {
|
public SystemVmTemplateRegistration() {
|
||||||
dataCenterDao = new DataCenterDaoImpl();
|
dataCenterDao = new DataCenterDaoImpl();
|
||||||
vmTemplateDao = new VMTemplateDaoImpl();
|
vmTemplateDao = new VMTemplateDaoImpl();
|
||||||
@ -138,6 +147,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
imageStoreDetailsDao = new ImageStoreDetailsDaoImpl();
|
imageStoreDetailsDao = new ImageStoreDetailsDaoImpl();
|
||||||
clusterDao = new ClusterDaoImpl();
|
clusterDao = new ClusterDaoImpl();
|
||||||
configurationDao = new ConfigurationDaoImpl();
|
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) {
|
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)) {
|
if (StringUtils.isNotBlank(nfsVersion)) {
|
||||||
cmd = String.format("%s -o vers=%s", cmd, nfsVersion);
|
cmd = String.format("%s -o vers=%s", cmd, nfsVersion);
|
||||||
}
|
}
|
||||||
@ -163,6 +173,10 @@ public class SystemVmTemplateRegistration {
|
|||||||
return systemVmTemplateVersion;
|
return systemVmTemplateVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getTempDownloadDir() {
|
||||||
|
return tempDownloadDir;
|
||||||
|
}
|
||||||
|
|
||||||
private static class SystemVMTemplateDetails {
|
private static class SystemVMTemplateDetails {
|
||||||
Long id;
|
Long id;
|
||||||
String uuid;
|
String uuid;
|
||||||
@ -174,6 +188,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
ImageFormat format;
|
ImageFormat format;
|
||||||
Integer guestOsId;
|
Integer guestOsId;
|
||||||
Hypervisor.HypervisorType hypervisorType;
|
Hypervisor.HypervisorType hypervisorType;
|
||||||
|
CPU.CPUArch arch;
|
||||||
Long storeId;
|
Long storeId;
|
||||||
Long size;
|
Long size;
|
||||||
Long physicalSize;
|
Long physicalSize;
|
||||||
@ -183,7 +198,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
|
|
||||||
SystemVMTemplateDetails(String uuid, String name, Date created, String url, String checksum,
|
SystemVMTemplateDetails(String uuid, String name, Date created, String url, String checksum,
|
||||||
ImageFormat format, Integer guestOsId, Hypervisor.HypervisorType hypervisorType,
|
ImageFormat format, Integer guestOsId, Hypervisor.HypervisorType hypervisorType,
|
||||||
Long storeId) {
|
CPU.CPUArch arch, Long storeId) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.created = created;
|
this.created = created;
|
||||||
@ -192,6 +207,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
this.format = format;
|
this.format = format;
|
||||||
this.guestOsId = guestOsId;
|
this.guestOsId = guestOsId;
|
||||||
this.hypervisorType = hypervisorType;
|
this.hypervisorType = hypervisorType;
|
||||||
|
this.arch = arch;
|
||||||
this.storeId = storeId;
|
this.storeId = storeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +251,10 @@ public class SystemVmTemplateRegistration {
|
|||||||
return hypervisorType;
|
return hypervisorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getStoreId() {
|
public Long getStoreId() {
|
||||||
return storeId;
|
return storeId;
|
||||||
}
|
}
|
||||||
@ -288,18 +308,17 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final List<Hypervisor.HypervisorType> hypervisorList = Arrays.asList(Hypervisor.HypervisorType.KVM,
|
public static final List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorList = Arrays.asList(
|
||||||
Hypervisor.HypervisorType.VMware,
|
new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64),
|
||||||
Hypervisor.HypervisorType.XenServer,
|
new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64),
|
||||||
Hypervisor.HypervisorType.Hyperv,
|
new Pair<>(Hypervisor.HypervisorType.VMware, null),
|
||||||
Hypervisor.HypervisorType.LXC,
|
new Pair<>(Hypervisor.HypervisorType.XenServer, null),
|
||||||
Hypervisor.HypervisorType.Ovm3
|
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<String, MetadataTemplateDetails> NewTemplateMap = new HashMap<>();
|
||||||
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<Hypervisor.HypervisorType, String> RouterTemplateConfigurationNames = new HashMap<Hypervisor.HypervisorType, String>() {
|
public static final Map<Hypervisor.HypervisorType, String> RouterTemplateConfigurationNames = new HashMap<Hypervisor.HypervisorType, String>() {
|
||||||
{
|
{
|
||||||
@ -368,56 +387,74 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getRegisteredTemplateId(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
private static String getHypervisorArchLog(Hypervisor.HypervisorType hypervisorType, CPU.CPUArch arch) {
|
||||||
VMTemplateVO vmTemplate = vmTemplateDao.findLatestTemplateByName(hypervisorAndTemplateName.second());
|
StringBuilder sb = new StringBuilder("hypervisor: ").append(hypervisorType.name());
|
||||||
Long templateId = null;
|
if (Hypervisor.HypervisorType.KVM.equals(hypervisorType)) {
|
||||||
if (vmTemplate != null) {
|
sb.append(", arch: ").append(arch == null ? CPU.CPUArch.amd64.getType() : arch.getType());
|
||||||
templateId = vmTemplate.getId();
|
|
||||||
}
|
}
|
||||||
return templateId;
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String fetchTemplatesPath() {
|
protected static String getHypervisorArchKey(Hypervisor.HypervisorType hypervisorType, CPU.CPUArch arch) {
|
||||||
String filePath = RELATIVE_TEMPLATE_PATH + METADATA_FILE_NAME;
|
if (Hypervisor.HypervisorType.KVM.equals(hypervisorType)) {
|
||||||
LOGGER.debug(String.format("Looking for file [ %s ] in the classpath.", filePath));
|
return String.format("%s-%s", hypervisorType.name().toLowerCase(),
|
||||||
File metaFile = new File(filePath);
|
arch == null ? CPU.CPUArch.amd64.getType() : arch.getType());
|
||||||
String templatePath = null;
|
|
||||||
if (metaFile.exists()) {
|
|
||||||
templatePath = RELATIVE_TEMPLATE_PATH;
|
|
||||||
}
|
}
|
||||||
if (templatePath == null) {
|
return hypervisorType.name().toLowerCase();
|
||||||
filePath = ABSOLUTE_TEMPLATE_PATH + METADATA_FILE_NAME;
|
}
|
||||||
metaFile = new File(filePath);
|
|
||||||
templatePath = ABSOLUTE_TEMPLATE_PATH;
|
protected static MetadataTemplateDetails getMetadataTemplateDetails(Hypervisor.HypervisorType hypervisorType,
|
||||||
LOGGER.debug(String.format("Looking for file [ %s ] in the classpath.", filePath));
|
CPU.CPUArch arch) {
|
||||||
if (!metaFile.exists()) {
|
return NewTemplateMap.get(getHypervisorArchKey(hypervisorType, arch));
|
||||||
String errMsg = String.format("Unable to locate metadata file in your setup at %s", filePath.toString());
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String errMsg = String.format("Unable to locate metadata file in your setup at %s", StringUtils.join(paths));
|
||||||
LOGGER.error(errMsg);
|
LOGGER.error(errMsg);
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Long> getEligibleZoneIds() {
|
private List<Long> getEligibleZoneIds() {
|
||||||
List<Long> zoneIds = new ArrayList<>();
|
List<Long> zoneIds = new ArrayList<>();
|
||||||
@ -430,28 +467,28 @@ public class SystemVmTemplateRegistration {
|
|||||||
return zoneIds;
|
return zoneIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<String, Long> getNfsStoreInZone(Long zoneId) {
|
protected Pair<String, Long> getNfsStoreInZone(Long zoneId) {
|
||||||
String url = null;
|
|
||||||
Long storeId = null;
|
|
||||||
ImageStoreVO storeVO = imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
|
ImageStoreVO storeVO = imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
|
||||||
if (storeVO == null) {
|
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);
|
LOGGER.error(errMsg);
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
url = storeVO.getUrl();
|
String url = storeVO.getUrl();
|
||||||
storeId = storeVO.getId();
|
Long storeId = storeVO.getId();
|
||||||
return new Pair<>(url, storeId);
|
return new Pair<>(url, storeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void mountStore(String storeUrl, String path, String nfsVersion) {
|
public static void mountStore(String storeUrl, String path, String nfsVersion) {
|
||||||
try {
|
try {
|
||||||
if (storeUrl != null) {
|
if (storeUrl == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
URI uri = new URI(UriUtils.encodeURIComponent(storeUrl));
|
URI uri = new URI(UriUtils.encodeURIComponent(storeUrl));
|
||||||
String host = uri.getHost();
|
String host = uri.getHost();
|
||||||
String mountPath = uri.getPath();
|
String mountPath = uri.getPath();
|
||||||
Script.runSimpleBashScript(getMountCommand(nfsVersion, host + ":" + mountPath, path));
|
Script.runSimpleBashScript(getMountCommand(nfsVersion, host + ":" + mountPath, path));
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String msg = "NFS Store URL is not in the correct format";
|
String msg = "NFS Store URL is not in the correct format";
|
||||||
LOGGER.error(msg, e);
|
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) {
|
private VMTemplateVO createTemplateObjectInDB(SystemVMTemplateDetails details) {
|
||||||
Long templateId = vmTemplateDao.getNextInSequence(Long.class, "id");
|
Long templateId = vmTemplateDao.getNextInSequence(Long.class, "id");
|
||||||
VMTemplateVO template = new VMTemplateVO();
|
VMTemplateVO template = new VMTemplateVO();
|
||||||
@ -486,6 +516,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
template.setGuestOSId(details.getGuestOsId());
|
template.setGuestOSId(details.getGuestOsId());
|
||||||
template.setCrossZones(true);
|
template.setCrossZones(true);
|
||||||
template.setHypervisorType(details.getHypervisorType());
|
template.setHypervisorType(details.getHypervisorType());
|
||||||
|
template.setArch(details.getArch());
|
||||||
template.setState(VirtualMachineTemplate.State.Inactive);
|
template.setState(VirtualMachineTemplate.State.Inactive);
|
||||||
template.setDeployAsIs(false);
|
template.setDeployAsIs(false);
|
||||||
template = vmTemplateDao.persist(template);
|
template = vmTemplateDao.persist(template);
|
||||||
@ -627,7 +658,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupTemplate(String templateName, Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
|
private void setupTemplate(String templateName, Hypervisor.HypervisorType hypervisor, CPU.CPUArch arch,
|
||||||
String destTempFolder) throws CloudRuntimeException {
|
String destTempFolder) throws CloudRuntimeException {
|
||||||
String setupTmpltScript = Script.findScript(storageScriptsDir, "setup-sysvm-tmplt");
|
String setupTmpltScript = Script.findScript(storageScriptsDir, "setup-sysvm-tmplt");
|
||||||
if (setupTmpltScript == null) {
|
if (setupTmpltScript == null) {
|
||||||
@ -635,8 +666,12 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
Script scr = new Script(setupTmpltScript, SCRIPT_TIMEOUT, LOGGER);
|
Script scr = new Script(setupTmpltScript, SCRIPT_TIMEOUT, LOGGER);
|
||||||
scr.add("-u", templateName);
|
scr.add("-u", templateName);
|
||||||
scr.add("-f", TEMPLATES_PATH + FileNames.get(hypervisorAndTemplateName.first()));
|
MetadataTemplateDetails templateDetails = NewTemplateMap.get(getHypervisorArchKey(hypervisor, arch));
|
||||||
scr.add("-h", hypervisorAndTemplateName.first().name().toLowerCase(Locale.ROOT));
|
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);
|
scr.add("-d", destTempFolder);
|
||||||
String result = scr.execute();
|
String result = scr.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -644,17 +679,15 @@ public class SystemVmTemplateRegistration {
|
|||||||
LOGGER.error(errMsg);
|
LOGGER.error(errMsg);
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long performTemplateRegistrationOperations(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
|
private Long performTemplateRegistrationOperations(Hypervisor.HypervisorType hypervisor,
|
||||||
String url, String checksum, ImageFormat format, long guestOsId,
|
String name, CPU.CPUArch arch, String url, String checksum, ImageFormat format, long guestOsId,
|
||||||
Long storeId, Long templateId, String filePath, TemplateDataStoreVO templateDataStoreVO) {
|
Long storeId, Long templateId, String filePath, TemplateDataStoreVO templateDataStoreVO) {
|
||||||
Hypervisor.HypervisorType hypervisor = hypervisorAndTemplateName.first();
|
|
||||||
String templateName = UUID.randomUUID().toString();
|
String templateName = UUID.randomUUID().toString();
|
||||||
Date created = new Date(DateUtil.currentGMTTime().getTime());
|
Date created = new Date(DateUtil.currentGMTTime().getTime());
|
||||||
SystemVMTemplateDetails details = new SystemVMTemplateDetails(templateName, hypervisorAndTemplateName.second(), created,
|
SystemVMTemplateDetails details = new SystemVMTemplateDetails(templateName, name, created,
|
||||||
url, checksum, format, (int) guestOsId, hypervisor, storeId);
|
url, checksum, format, (int) guestOsId, hypervisor, arch, storeId);
|
||||||
if (templateId == null) {
|
if (templateId == null) {
|
||||||
VMTemplateVO template = createTemplateObjectInDB(details);
|
VMTemplateVO template = createTemplateObjectInDB(details);
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
@ -671,23 +704,44 @@ public class SystemVmTemplateRegistration {
|
|||||||
if (templateDataStoreVO == null) {
|
if (templateDataStoreVO == null) {
|
||||||
createTemplateStoreRefEntry(details);
|
createTemplateStoreRefEntry(details);
|
||||||
}
|
}
|
||||||
setupTemplate(templateName, hypervisorAndTemplateName, destTempFolder);
|
setupTemplate(templateName, hypervisor, arch, destTempFolder);
|
||||||
readTemplateProperties(destTempFolder + "/template.properties", details);
|
readTemplateProperties(destTempFolder + "/template.properties", details);
|
||||||
details.setUpdated(new Date(DateUtil.currentGMTTime().getTime()));
|
details.setUpdated(new Date(DateUtil.currentGMTTime().getTime()));
|
||||||
updateTemplateDetails(details);
|
updateTemplateDetails(details);
|
||||||
return templateId;
|
return templateId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerTemplate(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName,
|
public void registerTemplate(Hypervisor.HypervisorType hypervisor, String name, Long storeId,
|
||||||
Pair<String, Long> storeUrlAndId, VMTemplateVO templateVO,
|
VMTemplateVO templateVO, TemplateDataStoreVO templateDataStoreVO, String filePath) {
|
||||||
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;
|
Long templateId = null;
|
||||||
try {
|
try {
|
||||||
templateId = templateVO.getId();
|
MetadataTemplateDetails templateDetails = getMetadataTemplateDetails(hypervisor, arch);
|
||||||
performTemplateRegistrationOperations(hypervisorAndTemplateName, templateVO.getUrl(), templateVO.getChecksum(),
|
templateId = performTemplateRegistrationOperations(hypervisor, name,
|
||||||
templateVO.getFormat(), templateVO.getGuestOSId(), storeUrlAndId.second(), templateId, filePath, templateDataStoreVO);
|
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) {
|
} 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);
|
LOGGER.error(errMsg, e);
|
||||||
if (templateId != null) {
|
if (templateId != null) {
|
||||||
updateTemplateTablesOnFailure(templateId);
|
updateTemplateTablesOnFailure(templateId);
|
||||||
@ -697,28 +751,33 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerTemplate(Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName, Pair<String, Long> storeUrlAndId, String filePath) {
|
protected void validateTemplateFileForHypervisorAndArch(Hypervisor.HypervisorType hypervisor, CPU.CPUArch arch) {
|
||||||
Long templateId = null;
|
MetadataTemplateDetails templateDetails = getMetadataTemplateDetails(hypervisor, arch);
|
||||||
try {
|
File templateFile = getTemplateFile(templateDetails);
|
||||||
Hypervisor.HypervisorType hypervisor = hypervisorAndTemplateName.first();
|
if (templateFile == null) {
|
||||||
templateId = performTemplateRegistrationOperations(hypervisorAndTemplateName, NewTemplateUrl.get(hypervisor), NewTemplateChecksum.get(hypervisor),
|
throw new CloudRuntimeException("Failed to find local template file");
|
||||||
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);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method parses the metadata file consisting of the systemVM templates information
|
* This method parses the metadata file consisting of the systemVM templates information
|
||||||
* @return the version of the systemvm template that is to be used. This is done in order
|
* @return the version of the systemvm template that is to be used. This is done in order
|
||||||
@ -726,25 +785,40 @@ public class SystemVmTemplateRegistration {
|
|||||||
* exist a template corresponding to the current code version.
|
* exist a template corresponding to the current code version.
|
||||||
*/
|
*/
|
||||||
public static String parseMetadataFile() {
|
public static String parseMetadataFile() {
|
||||||
try {
|
String metadataFilePath = getMetadataFilePath();
|
||||||
Ini ini = new Ini();
|
String errMsg = String.format("Failed to parse systemVM template metadata file: %s", metadataFilePath);
|
||||||
ini.load(new FileReader(METADATA_FILE));
|
final Ini ini = new Ini();
|
||||||
for (Hypervisor.HypervisorType hypervisorType : hypervisorList) {
|
try (FileReader reader = new FileReader(metadataFilePath)) {
|
||||||
String hypervisor = hypervisorType.name().toLowerCase(Locale.ROOT);
|
ini.load(reader);
|
||||||
Ini.Section section = ini.get(hypervisor);
|
} catch (IOException e) {
|
||||||
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);
|
|
||||||
LOGGER.error(errMsg, e);
|
LOGGER.error(errMsg, e);
|
||||||
throw new CloudRuntimeException(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) {
|
private static void cleanupStore(Long templateId, String filePath) {
|
||||||
String destTempFolder = filePath + PARTIAL_TEMPLATE_FOLDER + String.valueOf(templateId);
|
String destTempFolder = filePath + PARTIAL_TEMPLATE_FOLDER + String.valueOf(templateId);
|
||||||
@ -755,31 +829,60 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateTemplates(Set<Hypervisor.HypervisorType> hypervisorsInUse) {
|
protected File getTemplateFile(MetadataTemplateDetails templateDetails) {
|
||||||
Set<String> hypervisors = hypervisorsInUse.stream().
|
File templateFile = new File(templateDetails.getDefaultFilePath());
|
||||||
map(Hypervisor.HypervisorType::name).map(name -> name.toLowerCase(Locale.ROOT)).map(this::getHypervisorName).collect(Collectors.toSet());
|
if (templateFile.exists()) {
|
||||||
List<String> templates = new ArrayList<>();
|
return templateFile;
|
||||||
for (Hypervisor.HypervisorType hypervisorType : hypervisorsInUse) {
|
}
|
||||||
templates.add(FileNames.get(hypervisorType));
|
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;
|
boolean templatesFound = true;
|
||||||
for (String hypervisor : hypervisors) {
|
for (Pair<Hypervisor.HypervisorType, CPU.CPUArch> hypervisorArch : hypervisorsArchInUse) {
|
||||||
String matchedTemplate = templates.stream().filter(x -> x.contains(hypervisor)).findAny().orElse(null);
|
MetadataTemplateDetails matchedTemplate = getMetadataTemplateDetails(hypervisorArch.first(),
|
||||||
|
hypervisorArch.second());
|
||||||
if (matchedTemplate == null) {
|
if (matchedTemplate == null) {
|
||||||
templatesFound = false;
|
templatesFound = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
File tempFile = getTemplateFile(matchedTemplate);
|
||||||
File tempFile = new File(TEMPLATES_PATH + matchedTemplate);
|
if (tempFile == null) {
|
||||||
String templateChecksum = DigestHelper.calculateChecksum(tempFile);
|
LOGGER.warn("Failed to download template for {}, moving ahead",
|
||||||
if (!templateChecksum.equals(NewTemplateChecksum.get(getHypervisorType(hypervisor)))) {
|
matchedTemplate.getHypervisorArchLog());
|
||||||
LOGGER.error(String.format("Checksum mismatch: %s != %s ", templateChecksum, NewTemplateChecksum.get(getHypervisorType(hypervisor))));
|
continue;
|
||||||
|
}
|
||||||
|
if (isTemplateFileChecksumDifferent(matchedTemplate, tempFile)) {
|
||||||
templatesFound = false;
|
templatesFound = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!templatesFound) {
|
if (!templatesFound) {
|
||||||
String errMsg = "SystemVm template not found. Cannot upgrade system Vms";
|
String errMsg = "SystemVm template not found. Cannot upgrade system Vms";
|
||||||
LOGGER.error(errMsg);
|
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");
|
GlobalLock lock = GlobalLock.getInternLock("UpgradeDatabase-Lock");
|
||||||
try {
|
try {
|
||||||
LOGGER.info("Grabbing lock to register templates.");
|
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.");
|
throw new CloudRuntimeException("Unable to acquire lock to register SystemVM template.");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
validateTemplates(hypervisorsInUse);
|
validateTemplates(hypervisorsArchInUse);
|
||||||
// Perform Registration if templates not already registered
|
// Perform Registration if templates not already registered
|
||||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||||
@Override
|
@Override
|
||||||
@ -808,32 +944,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
if (filePath == null) {
|
if (filePath == null) {
|
||||||
throw new CloudRuntimeException("Failed to create temporary file path to mount the store");
|
throw new CloudRuntimeException("Failed to create temporary file path to mount the store");
|
||||||
}
|
}
|
||||||
Pair<String, Long> storeUrlAndId = getNfsStoreInZone(zoneId);
|
registerTemplatesForZone(zoneId, filePath);
|
||||||
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);
|
|
||||||
}
|
|
||||||
unmountStore(filePath);
|
unmountStore(filePath);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
unmountStore(filePath);
|
unmountStore(filePath);
|
||||||
@ -851,12 +962,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRegisteredTemplateDetails(Long templateId, Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
private void updateRegisteredTemplateDetails(Long templateId, MetadataTemplateDetails templateDetails) {
|
||||||
Pair<Hypervisor.HypervisorType, String> entry = new Pair<>(hypervisorAndTemplateName.getKey(), hypervisorAndTemplateName.getValue());
|
|
||||||
updateRegisteredTemplateDetails(templateId, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateRegisteredTemplateDetails(Long templateId, Pair<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
|
||||||
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
|
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
|
||||||
templateVO.setTemplateType(Storage.TemplateType.SYSTEM);
|
templateVO.setTemplateType(Storage.TemplateType.SYSTEM);
|
||||||
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
|
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
|
||||||
@ -865,68 +971,81 @@ public class SystemVmTemplateRegistration {
|
|||||||
LOGGER.error(errMsg);
|
LOGGER.error(errMsg);
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
Hypervisor.HypervisorType hypervisorType = templateDetails.getHypervisorType();
|
||||||
updateSystemVMEntries(templateId, hypervisorAndTemplateName.first());
|
updateSystemVMEntries(templateId, hypervisorType);
|
||||||
|
|
||||||
// Change value of global configuration parameter router.template.* for the corresponding hypervisor and minreq.sysvmtemplate.version for the ACS version
|
// 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<>();
|
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());
|
configParams.put("minreq.sysvmtemplate.version", getSystemVmTemplateVersion());
|
||||||
updateConfigurationParams(configParams);
|
updateConfigurationParams(configParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTemplateUrlAndChecksum(VMTemplateVO templateVO, Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName) {
|
private void updateTemplateUrlAndChecksum(VMTemplateVO templateVO, MetadataTemplateDetails templateDetails) {
|
||||||
templateVO.setUrl(NewTemplateUrl.get(hypervisorAndTemplateName.getKey()));
|
templateVO.setUrl(templateDetails.getUrl());
|
||||||
templateVO.setChecksum(NewTemplateChecksum.get(hypervisorAndTemplateName.getKey()));
|
templateVO.setChecksum(templateDetails.getChecksum());
|
||||||
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
|
boolean updated = vmTemplateDao.update(templateVO.getId(), templateVO);
|
||||||
if (!updated) {
|
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);
|
LOGGER.error(errMsg);
|
||||||
throw new CloudRuntimeException(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) {
|
public void updateSystemVmTemplates(final Connection conn) {
|
||||||
LOGGER.debug("Updating System Vm template IDs");
|
LOGGER.debug("Updating System Vm template IDs");
|
||||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||||
@Override
|
@Override
|
||||||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||||
Set<Hypervisor.HypervisorType> hypervisorsListInUse = new HashSet<Hypervisor.HypervisorType>();
|
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsInUse;
|
||||||
try {
|
try {
|
||||||
hypervisorsListInUse = clusterDao.getDistinctAvailableHypervisorsAcrossClusters();
|
hypervisorsInUse = clusterDao.listDistinctHypervisorsArchAcrossClusters(null);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
LOGGER.error("updateSystemVmTemplates: Exception caught while getting hypervisor types from clusters: " + e.getMessage());
|
throw new CloudRuntimeException("Exception while getting hypervisor types from clusters", e);
|
||||||
throw new CloudRuntimeException("updateSystemVmTemplates:Exception while getting hypervisor types from clusters", e);
|
|
||||||
}
|
}
|
||||||
|
Collection<MetadataTemplateDetails> templateEntries = NewTemplateMap.values();
|
||||||
for (final Map.Entry<Hypervisor.HypervisorType, String> hypervisorAndTemplateName : NewTemplateNameList.entrySet()) {
|
for (MetadataTemplateDetails templateDetails : templateEntries) {
|
||||||
LOGGER.debug("Updating " + hypervisorAndTemplateName.getKey() + " System Vms");
|
|
||||||
Long templateId = getRegisteredTemplateId(new Pair<>(hypervisorAndTemplateName.getKey(), hypervisorAndTemplateName.getValue()));
|
|
||||||
try {
|
try {
|
||||||
// change template type to SYSTEM
|
if (registerOrUpdateSystemVmTemplate(templateDetails, hypervisorsInUse)) {
|
||||||
if (templateId != null) {
|
|
||||||
updateRegisteredTemplateDetails(templateId, hypervisorAndTemplateName);
|
|
||||||
} else {
|
|
||||||
if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())) {
|
|
||||||
try {
|
|
||||||
registerTemplates(hypervisorsListInUse);
|
|
||||||
break;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} 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);
|
LOGGER.error(errMsg, e);
|
||||||
throw new CloudRuntimeException(errMsg, e);
|
throw new CloudRuntimeException(errMsg, e);
|
||||||
}
|
}
|
||||||
@ -948,4 +1067,64 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
return null;
|
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 {
|
try {
|
||||||
systemVmTemplateRegistration.updateSystemVmTemplates(conn);
|
systemVmTemplateRegistration.updateSystemVmTemplates(conn);
|
||||||
} catch (Exception e) {
|
} 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> 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);
|
List<ImageStoreVO> findByProtocol(String protocol);
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
|
|||||||
private SearchBuilder<ImageStoreVO> nameSearch;
|
private SearchBuilder<ImageStoreVO> nameSearch;
|
||||||
private SearchBuilder<ImageStoreVO> providerSearch;
|
private SearchBuilder<ImageStoreVO> providerSearch;
|
||||||
private SearchBuilder<ImageStoreVO> regionSearch;
|
private SearchBuilder<ImageStoreVO> regionSearch;
|
||||||
private SearchBuilder<ImageStoreVO> storeSearch;
|
private SearchBuilder<ImageStoreVO> storesExceptIdSearch;
|
||||||
private SearchBuilder<ImageStoreVO> protocolSearch;
|
private SearchBuilder<ImageStoreVO> protocolSearch;
|
||||||
private SearchBuilder<ImageStoreVO> zoneProtocolSearch;
|
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.and("role", regionSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||||
regionSearch.done();
|
regionSearch.done();
|
||||||
|
|
||||||
storeSearch = createSearchBuilder();
|
storesExceptIdSearch = createSearchBuilder();
|
||||||
storeSearch.and("providerName", storeSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
|
storesExceptIdSearch.and("providerName", storesExceptIdSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
|
||||||
storeSearch.and("role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
storesExceptIdSearch.and("role", storesExceptIdSearch.entity().getRole(), SearchCriteria.Op.EQ);
|
||||||
storeSearch.and("dataCenterId", storeSearch.entity().getDcId(), SearchCriteria.Op.EQ);
|
storesExceptIdSearch.and("dataCenterId", storesExceptIdSearch.entity().getDcId(), SearchCriteria.Op.EQ);
|
||||||
storeSearch.done();
|
storesExceptIdSearch.and("id", storesExceptIdSearch.entity().getId(), SearchCriteria.Op.NEQ);
|
||||||
|
storesExceptIdSearch.done();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -113,11 +114,12 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ImageStoreVO> listAllStoresInZone(Long zoneId, String provider, DataStoreRole role) {
|
public List<ImageStoreVO> listAllStoresInZoneExceptId(Long zoneId, String provider, DataStoreRole role, long id) {
|
||||||
SearchCriteria<ImageStoreVO> sc = storeSearch.create();
|
SearchCriteria<ImageStoreVO> sc = storesExceptIdSearch.create();
|
||||||
sc.setParameters("providerName", provider);
|
sc.setParameters("providerName", provider);
|
||||||
sc.setParameters("role", role);
|
sc.setParameters("role", role);
|
||||||
sc.setParameters("dataCenterId", zoneId);
|
sc.setParameters("dataCenterId", zoneId);
|
||||||
|
sc.setParameters("id", id);
|
||||||
return listBy(sc);
|
return listBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import com.cloud.cpu.CPU;
|
|||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
import javax.persistence.Converter;
|
import javax.persistence.Converter;
|
||||||
|
|
||||||
@Converter
|
@Converter(autoApply = true)
|
||||||
public class CPUArchConverter implements AttributeConverter<CPU.CPUArch, String> {
|
public class CPUArchConverter implements AttributeConverter<CPU.CPUArch, String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -19,6 +19,12 @@
|
|||||||
-- Schema upgrade from 4.20.0.0 to 4.20.1.0
|
-- 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
|
-- 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.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" ');
|
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,
|
host.resource_state host_resource_state,
|
||||||
vm_template.id template_id,
|
vm_template.id template_id,
|
||||||
vm_template.uuid template_uuid,
|
vm_template.uuid template_uuid,
|
||||||
|
vm_template.arch arch,
|
||||||
service_offering.id service_offering_id,
|
service_offering.id service_offering_id,
|
||||||
service_offering.uuid service_offering_uuid,
|
service_offering.uuid service_offering_uuid,
|
||||||
service_offering.name service_offering_name,
|
service_offering.name service_offering_name,
|
||||||
|
|||||||
@ -83,6 +83,7 @@ SELECT
|
|||||||
`iso`.`uuid` AS `iso_uuid`,
|
`iso`.`uuid` AS `iso_uuid`,
|
||||||
`iso`.`name` AS `iso_name`,
|
`iso`.`name` AS `iso_name`,
|
||||||
`iso`.`display_text` AS `iso_display_text`,
|
`iso`.`display_text` AS `iso_display_text`,
|
||||||
|
`vm_template`.`arch` AS `arch`,
|
||||||
`service_offering`.`id` AS `service_offering_id`,
|
`service_offering`.`id` AS `service_offering_id`,
|
||||||
`service_offering`.`uuid` AS `service_offering_uuid`,
|
`service_offering`.`uuid` AS `service_offering_uuid`,
|
||||||
`disk_offering`.`uuid` AS `disk_offering_uuid`,
|
`disk_offering`.`uuid` AS `disk_offering_uuid`,
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
package com.cloud.dc.dao;
|
package com.cloud.dc.dao;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
@ -36,9 +37,13 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.ClusterVO;
|
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.GenericSearchBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class ClusterDaoImplTest {
|
public class ClusterDaoImplTest {
|
||||||
@ -75,4 +80,39 @@ public class ClusterDaoImplTest {
|
|||||||
verify(clusterDao).customSearch(genericSearchBuilder.create(), null);
|
verify(clusterDao).customSearch(genericSearchBuilder.create(), null);
|
||||||
assertTrue(result.isEmpty());
|
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.
|
// under the License.
|
||||||
package com.cloud.host.dao;
|
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.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -26,6 +37,7 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.Status;
|
import com.cloud.host.Status;
|
||||||
@ -52,10 +64,10 @@ public class HostDaoImplTest {
|
|||||||
public void testCountUpAndEnabledHostsInZone() {
|
public void testCountUpAndEnabledHostsInZone() {
|
||||||
long testZoneId = 100L;
|
long testZoneId = 100L;
|
||||||
hostDao.HostTypeCountSearch = mockSearchBuilder;
|
hostDao.HostTypeCountSearch = mockSearchBuilder;
|
||||||
Mockito.when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||||
Mockito.doNothing().when(mockSearchCriteria).setParameters(Mockito.anyString(), Mockito.any());
|
Mockito.doNothing().when(mockSearchCriteria).setParameters(Mockito.anyString(), any());
|
||||||
int expected = 5;
|
int expected = 5;
|
||||||
Mockito.doReturn(expected).when(hostDao).getCount(mockSearchCriteria);
|
doReturn(expected).when(hostDao).getCount(mockSearchCriteria);
|
||||||
Integer count = hostDao.countUpAndEnabledHostsInZone(testZoneId);
|
Integer count = hostDao.countUpAndEnabledHostsInZone(testZoneId);
|
||||||
Assert.assertSame(expected, count);
|
Assert.assertSame(expected, count);
|
||||||
Mockito.verify(mockSearchCriteria).setParameters("type", Host.Type.Routing);
|
Mockito.verify(mockSearchCriteria).setParameters("type", Host.Type.Routing);
|
||||||
@ -70,16 +82,16 @@ public class HostDaoImplTest {
|
|||||||
GenericDaoBase.SumCount mockSumCount = new GenericDaoBase.SumCount();
|
GenericDaoBase.SumCount mockSumCount = new GenericDaoBase.SumCount();
|
||||||
mockSumCount.count = 10;
|
mockSumCount.count = 10;
|
||||||
mockSumCount.sum = 20;
|
mockSumCount.sum = 20;
|
||||||
HostVO host = Mockito.mock(HostVO.class);
|
HostVO host = mock(HostVO.class);
|
||||||
GenericSearchBuilder<HostVO, GenericDaoBase.SumCount> sb = Mockito.mock(GenericSearchBuilder.class);
|
GenericSearchBuilder<HostVO, GenericDaoBase.SumCount> sb = mock(GenericSearchBuilder.class);
|
||||||
Mockito.when(sb.entity()).thenReturn(host);
|
when(sb.entity()).thenReturn(host);
|
||||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(GenericDaoBase.SumCount.class);
|
doReturn(sb).when(hostDao).createSearchBuilder(GenericDaoBase.SumCount.class);
|
||||||
SearchCriteria<GenericDaoBase.SumCount> sc = Mockito.mock(SearchCriteria.class);
|
SearchCriteria<GenericDaoBase.SumCount> sc = mock(SearchCriteria.class);
|
||||||
Mockito.when(sb.create()).thenReturn(sc);
|
when(sb.create()).thenReturn(sc);
|
||||||
Mockito.doReturn(List.of(mockSumCount)).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
doReturn(List.of(mockSumCount)).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||||
Pair<Integer, Integer> result = hostDao.countAllHostsAndCPUSocketsByType(type);
|
Pair<Integer, Integer> result = hostDao.countAllHostsAndCPUSocketsByType(type);
|
||||||
Assert.assertEquals(10, result.first().intValue());
|
assertEquals(10, result.first().intValue());
|
||||||
Assert.assertEquals(20, result.second().intValue());
|
assertEquals(20, result.second().intValue());
|
||||||
Mockito.verify(sc).setParameters("type", type);
|
Mockito.verify(sc).setParameters("type", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +99,13 @@ public class HostDaoImplTest {
|
|||||||
public void testIsHostUp() {
|
public void testIsHostUp() {
|
||||||
long testHostId = 101L;
|
long testHostId = 101L;
|
||||||
List<Status> statuses = List.of(Status.Up);
|
List<Status> statuses = List.of(Status.Up);
|
||||||
HostVO host = Mockito.mock(HostVO.class);
|
HostVO host = mock(HostVO.class);
|
||||||
GenericSearchBuilder<HostVO, Status> sb = Mockito.mock(GenericSearchBuilder.class);
|
GenericSearchBuilder<HostVO, Status> sb = mock(GenericSearchBuilder.class);
|
||||||
Mockito.when(sb.entity()).thenReturn(host);
|
when(sb.entity()).thenReturn(host);
|
||||||
SearchCriteria<Status> sc = Mockito.mock(SearchCriteria.class);
|
SearchCriteria<Status> sc = mock(SearchCriteria.class);
|
||||||
Mockito.when(sb.create()).thenReturn(sc);
|
when(sb.create()).thenReturn(sc);
|
||||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Status.class);
|
doReturn(sb).when(hostDao).createSearchBuilder(Status.class);
|
||||||
Mockito.doReturn(statuses).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
doReturn(statuses).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||||
boolean result = hostDao.isHostUp(testHostId);
|
boolean result = hostDao.isHostUp(testHostId);
|
||||||
Assert.assertTrue("Host should be up", result);
|
Assert.assertTrue("Host should be up", result);
|
||||||
Mockito.verify(sc).setParameters("id", testHostId);
|
Mockito.verify(sc).setParameters("id", testHostId);
|
||||||
@ -109,17 +121,17 @@ public class HostDaoImplTest {
|
|||||||
List<Host.Type> types = List.of(Host.Type.Routing);
|
List<Host.Type> types = List.of(Host.Type.Routing);
|
||||||
List<Hypervisor.HypervisorType> hypervisorTypes = List.of(Hypervisor.HypervisorType.KVM);
|
List<Hypervisor.HypervisorType> hypervisorTypes = List.of(Hypervisor.HypervisorType.KVM);
|
||||||
List<Long> mockResults = List.of(1001L, 1002L); // Mocked result
|
List<Long> mockResults = List.of(1001L, 1002L); // Mocked result
|
||||||
HostVO host = Mockito.mock(HostVO.class);
|
HostVO host = mock(HostVO.class);
|
||||||
GenericSearchBuilder<HostVO, Long> sb = Mockito.mock(GenericSearchBuilder.class);
|
GenericSearchBuilder<HostVO, Long> sb = mock(GenericSearchBuilder.class);
|
||||||
Mockito.when(sb.entity()).thenReturn(host);
|
when(sb.entity()).thenReturn(host);
|
||||||
SearchCriteria<Long> sc = Mockito.mock(SearchCriteria.class);
|
SearchCriteria<Long> sc = mock(SearchCriteria.class);
|
||||||
Mockito.when(sb.create()).thenReturn(sc);
|
when(sb.create()).thenReturn(sc);
|
||||||
Mockito.when(sb.and()).thenReturn(sb);
|
when(sb.and()).thenReturn(sb);
|
||||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
||||||
Mockito.doReturn(mockResults).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
doReturn(mockResults).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||||
List<Long> hostIds = hostDao.findHostIdsByZoneClusterResourceStateTypeAndHypervisorType(
|
List<Long> hostIds = hostDao.findHostIdsByZoneClusterResourceStateTypeAndHypervisorType(
|
||||||
zoneId, clusterId, msId, resourceStates, types, hypervisorTypes);
|
zoneId, clusterId, msId, resourceStates, types, hypervisorTypes);
|
||||||
Assert.assertEquals(mockResults, hostIds);
|
assertEquals(mockResults, hostIds);
|
||||||
Mockito.verify(sc).setParameters("zoneId", zoneId);
|
Mockito.verify(sc).setParameters("zoneId", zoneId);
|
||||||
Mockito.verify(sc).setParameters("clusterId", clusterId);
|
Mockito.verify(sc).setParameters("clusterId", clusterId);
|
||||||
Mockito.verify(sc).setParameters("msId", msId);
|
Mockito.verify(sc).setParameters("msId", msId);
|
||||||
@ -132,15 +144,16 @@ public class HostDaoImplTest {
|
|||||||
public void testListDistinctHypervisorTypes() {
|
public void testListDistinctHypervisorTypes() {
|
||||||
Long zoneId = 1L;
|
Long zoneId = 1L;
|
||||||
List<Hypervisor.HypervisorType> mockResults = List.of(Hypervisor.HypervisorType.KVM, Hypervisor.HypervisorType.XenServer);
|
List<Hypervisor.HypervisorType> mockResults = List.of(Hypervisor.HypervisorType.KVM, Hypervisor.HypervisorType.XenServer);
|
||||||
HostVO host = Mockito.mock(HostVO.class);
|
HostVO host = mock(HostVO.class);
|
||||||
GenericSearchBuilder<HostVO, Hypervisor.HypervisorType> sb = Mockito.mock(GenericSearchBuilder.class);
|
GenericSearchBuilder<HostVO, String> sb = mock(GenericSearchBuilder.class);
|
||||||
Mockito.when(sb.entity()).thenReturn(host);
|
when(sb.entity()).thenReturn(host);
|
||||||
SearchCriteria<Hypervisor.HypervisorType> sc = Mockito.mock(SearchCriteria.class);
|
SearchCriteria<String> sc = mock(SearchCriteria.class);
|
||||||
Mockito.when(sb.create()).thenReturn(sc);
|
when(sb.create()).thenReturn(sc);
|
||||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Hypervisor.HypervisorType.class);
|
doReturn(sb).when(hostDao).createSearchBuilder(String.class);
|
||||||
Mockito.doReturn(mockResults).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
doReturn(mockResults.stream().map(h -> h.name()).collect(Collectors.toList())).when(hostDao)
|
||||||
|
.customSearch(any(SearchCriteria.class), any());
|
||||||
List<Hypervisor.HypervisorType> hypervisorTypes = hostDao.listDistinctHypervisorTypes(zoneId);
|
List<Hypervisor.HypervisorType> hypervisorTypes = hostDao.listDistinctHypervisorTypes(zoneId);
|
||||||
Assert.assertEquals(mockResults, hypervisorTypes);
|
assertEquals(mockResults, hypervisorTypes);
|
||||||
Mockito.verify(sc).setParameters("zoneId", zoneId);
|
Mockito.verify(sc).setParameters("zoneId", zoneId);
|
||||||
Mockito.verify(sc).setParameters("type", Host.Type.Routing);
|
Mockito.verify(sc).setParameters("type", Host.Type.Routing);
|
||||||
}
|
}
|
||||||
@ -148,12 +161,12 @@ public class HostDaoImplTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testListByIds() {
|
public void testListByIds() {
|
||||||
List<Long> ids = List.of(101L, 102L);
|
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;
|
hostDao.IdsSearch = mockSearchBuilder;
|
||||||
Mockito.when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||||
Mockito.doReturn(mockResults).when(hostDao).search(Mockito.any(SearchCriteria.class), Mockito.any());
|
doReturn(mockResults).when(hostDao).search(any(SearchCriteria.class), any());
|
||||||
List<HostVO> hosts = hostDao.listByIds(ids);
|
List<HostVO> hosts = hostDao.listByIds(ids);
|
||||||
Assert.assertEquals(mockResults, hosts);
|
assertEquals(mockResults, hosts);
|
||||||
Mockito.verify(mockSearchCriteria).setParameters("id", ids.toArray());
|
Mockito.verify(mockSearchCriteria).setParameters("id", ids.toArray());
|
||||||
Mockito.verify(hostDao).search(mockSearchCriteria, null);
|
Mockito.verify(hostDao).search(mockSearchCriteria, null);
|
||||||
}
|
}
|
||||||
@ -166,15 +179,15 @@ public class HostDaoImplTest {
|
|||||||
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
|
||||||
Long zoneId = 1L, podId = 2L, clusterId = 3L;
|
Long zoneId = 1L, podId = 2L, clusterId = 3L;
|
||||||
List<Long> mockResults = List.of(1001L, 1002L);
|
List<Long> mockResults = List.of(1001L, 1002L);
|
||||||
HostVO host = Mockito.mock(HostVO.class);
|
HostVO host = mock(HostVO.class);
|
||||||
GenericSearchBuilder<HostVO, Long> sb = Mockito.mock(GenericSearchBuilder.class);
|
GenericSearchBuilder<HostVO, Long> sb = mock(GenericSearchBuilder.class);
|
||||||
Mockito.when(sb.entity()).thenReturn(host);
|
when(sb.entity()).thenReturn(host);
|
||||||
SearchCriteria<Long> sc = Mockito.mock(SearchCriteria.class);
|
SearchCriteria<Long> sc = mock(SearchCriteria.class);
|
||||||
Mockito.when(sb.create()).thenReturn(sc);
|
when(sb.create()).thenReturn(sc);
|
||||||
Mockito.doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
doReturn(sb).when(hostDao).createSearchBuilder(Long.class);
|
||||||
Mockito.doReturn(mockResults).when(hostDao).customSearch(Mockito.any(SearchCriteria.class), Mockito.any());
|
doReturn(mockResults).when(hostDao).customSearch(any(SearchCriteria.class), any());
|
||||||
List<Long> hostIds = hostDao.listIdsBy(type, status, resourceState, hypervisorType, zoneId, podId, clusterId);
|
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("type", type);
|
||||||
Mockito.verify(sc).setParameters("status", status);
|
Mockito.verify(sc).setParameters("status", status);
|
||||||
Mockito.verify(sc).setParameters("resourceState", resourceState);
|
Mockito.verify(sc).setParameters("resourceState", resourceState);
|
||||||
@ -183,4 +196,57 @@ public class HostDaoImplTest {
|
|||||||
Mockito.verify(sc).setParameters("podId", podId);
|
Mockito.verify(sc).setParameters("podId", podId);
|
||||||
Mockito.verify(sc).setParameters("clusterId", clusterId);
|
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[@]}"
|
for template in "${templates[@]}"
|
||||||
do
|
do
|
||||||
section="${template%%:*}"
|
section="${template%%:*}"
|
||||||
hvName=$(getGenericName $section)
|
sectionHv="${section%%-*}"
|
||||||
|
hvName=$(getGenericName $sectionHv)
|
||||||
|
|
||||||
downloadurl="${template#*:}"
|
downloadurl="${template#*:}"
|
||||||
arch=$(echo ${downloadurl#*"/systemvmtemplate-$VERSION-"} | cut -d'-' -f 1)
|
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")
|
checksum=$(getChecksum "$fileData" "$VERSION-${arch}-$hvName")
|
||||||
filename=$(echo ${downloadurl##*'/'})
|
filename=$(echo ${downloadurl##*'/'})
|
||||||
echo -e "["$section"]\ntemplatename = $templatename\nchecksum = $checksum\ndownloadurl = $downloadurl\nfilename = $filename\narch = $arch\n" >> $METADATAFILE
|
echo -e "["$section"]\ntemplatename = $templatename\nchecksum = $checksum\ndownloadurl = $downloadurl\nfilename = $filename\narch = $arch\n" >> $METADATAFILE
|
||||||
@ -71,7 +72,8 @@ function createMetadataFile() {
|
|||||||
|
|
||||||
declare -a templates
|
declare -a templates
|
||||||
getTemplateVersion $1
|
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"
|
"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"
|
"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"
|
"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 {
|
} else {
|
||||||
field.set(entity, rs.getLong(index));
|
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()) {
|
} else if (type.isEnum()) {
|
||||||
final Enumerated enumerated = field.getAnnotation(Enumerated.class);
|
final Enumerated enumerated = field.getAnnotation(Enumerated.class);
|
||||||
final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
|
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) {
|
} else if (type == byte[].class) {
|
||||||
field.set(entity, rs.getBytes(index));
|
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 {
|
} else {
|
||||||
field.set(entity, rs.getObject(index));
|
field.set(entity, rs.getObject(index));
|
||||||
}
|
}
|
||||||
@ -949,7 +949,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DB()
|
@DB()
|
||||||
protected List<T> listBy(SearchCriteria<T> sc, final Filter filter) {
|
public List<T> listBy(SearchCriteria<T> sc, final Filter filter) {
|
||||||
sc = checkAndSetRemovedIsNull(sc);
|
sc = checkAndSetRemovedIsNull(sc);
|
||||||
return listIncludingRemovedBy(sc, filter);
|
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.Factory;
|
||||||
import net.sf.cglib.proxy.MethodInterceptor;
|
import net.sf.cglib.proxy.MethodInterceptor;
|
||||||
import net.sf.cglib.proxy.MethodProxy;
|
import net.sf.cglib.proxy.MethodProxy;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,7 +124,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
|||||||
if (_entity == null) {
|
if (_entity == null) {
|
||||||
throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
|
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");
|
throw new RuntimeException("You can't specify more than one field to search on");
|
||||||
}
|
}
|
||||||
if (func.getCount() != -1 && (func.getCount() != (params.length + 1))) {
|
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);
|
_selects.add(select);
|
||||||
|
|
||||||
_specifiedAttrs.clear();
|
_specifiedAttrs.clear();
|
||||||
@ -185,7 +187,7 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
|||||||
} catch (final SecurityException e) {
|
} catch (final SecurityException e) {
|
||||||
} catch (final NoSuchFieldException 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();
|
_specifiedAttrs.clear();
|
||||||
@ -531,16 +533,18 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, T, K> {
|
|||||||
|
|
||||||
protected static class Select {
|
protected static class Select {
|
||||||
public Func func;
|
public Func func;
|
||||||
public Attribute attr;
|
public List<Attribute> attributes = new ArrayList<>();
|
||||||
public Object[] params;
|
public Object[] params;
|
||||||
public Field field;
|
public Field field;
|
||||||
|
|
||||||
protected Select() {
|
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.func = func;
|
||||||
this.attr = attr;
|
if (CollectionUtils.isNotEmpty(attributes)) {
|
||||||
|
this.attributes.addAll(attributes);
|
||||||
|
}
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.field = field;
|
this.field = field;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
@ -59,7 +60,7 @@ public class SearchCriteria<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum Func {
|
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 String func;
|
||||||
private int count;
|
private int count;
|
||||||
@ -135,10 +136,12 @@ public class SearchCriteria<K> {
|
|||||||
|
|
||||||
for (Select select : _selects) {
|
for (Select select : _selects) {
|
||||||
String func = select.func.toString() + ",";
|
String func = select.func.toString() + ",";
|
||||||
if (select.attr == null) {
|
if (CollectionUtils.isEmpty(select.attributes)) {
|
||||||
func = func.replace("@", "*");
|
func = func.replace("@", "*");
|
||||||
} else {
|
} 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);
|
str.insert(insertAt, func);
|
||||||
insertAt += func.length();
|
insertAt += func.length();
|
||||||
|
|||||||
@ -470,6 +470,8 @@ if [ -f %{_sysconfdir}/sysconfig/%{name}-management ] ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
chown -R cloud:cloud /var/log/cloudstack/management
|
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
|
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/*.sh
|
||||||
%{_datadir}/%{name}-management/setup/server-setup.xml
|
%{_datadir}/%{name}-management/setup/server-setup.xml
|
||||||
%{_datadir}/%{name}-management/webapp/*
|
%{_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) %{_bindir}/%{name}-external-ipallocator.py
|
||||||
%attr(0755,root,root) %{_initrddir}/%{name}-ipallocator
|
%attr(0755,root,root) %{_initrddir}/%{name}-ipallocator
|
||||||
%dir %attr(0770,root,root) %{_localstatedir}/log/%{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 RoleService roleService;
|
||||||
|
|
||||||
private List<PluggableService> services;
|
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, Account> accountCache;
|
||||||
private LazyCache<Long, Pair<Role, List<RolePermission>>> rolePermissionsCache;
|
private LazyCache<Long, Pair<Role, List<RolePermission>>> rolePermissionsCache;
|
||||||
@ -56,7 +56,7 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
|||||||
protected DynamicRoleBasedAPIAccessChecker() {
|
protected DynamicRoleBasedAPIAccessChecker() {
|
||||||
super();
|
super();
|
||||||
for (RoleType roleType : RoleType.values()) {
|
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.SCSIDef;
|
||||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
|
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
|
||||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy;
|
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.VideoDef;
|
||||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
|
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
|
||||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
|
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(createVideoDef(vmTO));
|
||||||
devices.addDevice(createConsoleDef());
|
devices.addDevice(createConsoleDef());
|
||||||
devices.addDevice(createGraphicDef(vmTO));
|
devices.addDevice(createGraphicDef(vmTO));
|
||||||
|
|
||||||
if (!isGuestS390x()) {
|
if (!isGuestS390x()) {
|
||||||
devices.addDevice(createTabletInputDef());
|
devices.addDevice(createTabletInputDef());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TpmDef tpmDef = createTpmDef(vmTO);
|
||||||
|
if (tpmDef != null) {
|
||||||
|
devices.addDevice(tpmDef);
|
||||||
|
}
|
||||||
|
|
||||||
if (isGuestAarch64()) {
|
if (isGuestAarch64()) {
|
||||||
createArm64UsbDef(devices);
|
createArm64UsbDef(devices);
|
||||||
}
|
}
|
||||||
@ -2856,8 +2864,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
|
|
||||||
private CpuModeDef createCpuModeDef(VirtualMachineTO vmTO, int vcpus) {
|
private CpuModeDef createCpuModeDef(VirtualMachineTO vmTO, int vcpus) {
|
||||||
final CpuModeDef cmd = new CpuModeDef();
|
final CpuModeDef cmd = new CpuModeDef();
|
||||||
cmd.setMode(guestCpuMode);
|
Map<String, String> details = vmTO.getDetails();
|
||||||
cmd.setModel(guestCpuModel);
|
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())) {
|
if (VirtualMachine.Type.User.equals(vmTO.getType())) {
|
||||||
cmd.setFeatures(cpuFeatures);
|
cmd.setFeatures(cpuFeatures);
|
||||||
}
|
}
|
||||||
@ -2866,6 +2877,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
return cmd;
|
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) {
|
private void configureGuestIfUefiEnabled(boolean isSecureBoot, String bootMode, GuestDef guest) {
|
||||||
setGuestLoader(bootMode, SECURE, guest, GuestDef.GUEST_LOADER_SECURE);
|
setGuestLoader(bootMode, SECURE, guest, GuestDef.GUEST_LOADER_SECURE);
|
||||||
setGuestLoader(bootMode, LEGACY, guest, GuestDef.GUEST_LOADER_LEGACY);
|
setGuestLoader(bootMode, LEGACY, guest, GuestDef.GUEST_LOADER_LEGACY);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ package com.cloud.hypervisor.kvm.resource;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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) {
|
public void setHvsType(String hvs) {
|
||||||
_hvsType = hvs;
|
_hvsType = hvs;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6541,4 +6541,28 @@ public class LibvirtComputingResourceTest {
|
|||||||
DiskDef.DiskBus diskBus = libvirtComputingResourceSpy.getDiskModelFromVMDetail(virtualMachineTO);
|
DiskDef.DiskBus diskBus = libvirtComputingResourceSpy.getDiskModelFromVMDetail(virtualMachineTO);
|
||||||
assertEquals(DiskDef.DiskBus.VIRTIOBLK, diskBus);
|
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());
|
assertEquals("<cpu><topology sockets='4' cores='2' threads='1' /></cpu>", cpuModeDef.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTopologyNoInfo() {
|
public void testTopologyNoInfo() {
|
||||||
LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef();
|
LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef();
|
||||||
cpuModeDef.setTopology(-1, -1, 4);
|
cpuModeDef.setTopology(-1, -1, 4);
|
||||||
assertEquals("<cpu></cpu>", cpuModeDef.toString());
|
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 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_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 int DEFAULT_HOST_SPEED_MHZ = 8000; // 1 GHz CPUs
|
||||||
|
public static final String DEFAULT_HOST_ARCH = "x86_64";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
|
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 cpuSpeed = Long.parseLong((String)params.get("cpuspeed"));
|
||||||
long memory = Long.parseLong((String)params.get("memory"));
|
long memory = Long.parseLong((String)params.get("memory"));
|
||||||
long localStorageSize = Long.parseLong((String)params.get("localstorage"));
|
long localStorageSize = Long.parseLong((String)params.get("localstorage"));
|
||||||
|
String arch = (String)params.get("arch");
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
long dataCenterId = Long.parseLong((String)params.get("zone"));
|
long dataCenterId = Long.parseLong((String)params.get("zone"));
|
||||||
long podId = Long.parseLong((String)params.get("pod"));
|
long podId = Long.parseLong((String)params.get("pod"));
|
||||||
@ -170,6 +171,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage
|
|||||||
mockHost.setCpuCount(cpuCore);
|
mockHost.setCpuCount(cpuCore);
|
||||||
mockHost.setCpuSpeed(cpuSpeed);
|
mockHost.setCpuSpeed(cpuSpeed);
|
||||||
mockHost.setMemorySize(memory);
|
mockHost.setMemorySize(memory);
|
||||||
|
mockHost.setArch(arch);
|
||||||
String guid = UUID.randomUUID().toString();
|
String guid = UUID.randomUUID().toString();
|
||||||
mockHost.setGuid(guid);
|
mockHost.setGuid(guid);
|
||||||
mockHost.setName("SimulatedAgent." + guid);
|
mockHost.setName("SimulatedAgent." + guid);
|
||||||
|
|||||||
@ -177,6 +177,7 @@ public class AgentRoutingResource extends AgentStorageResource {
|
|||||||
StartupRoutingCommand cmd =
|
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,
|
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);
|
RouterPrivateIpStrategy.HostLocal);
|
||||||
|
cmd.setCpuArch((String)info.get(5));
|
||||||
|
|
||||||
Map<String, String> hostDetails = new HashMap<String, String>();
|
Map<String, String> hostDetails = new HashMap<String, String>();
|
||||||
hostDetails.put(RouterPrivateIpStrategy.class.getCanonicalName(), RouterPrivateIpStrategy.DcGlobal.toString());
|
hostDetails.put(RouterPrivateIpStrategy.class.getCanonicalName(), RouterPrivateIpStrategy.DcGlobal.toString());
|
||||||
@ -274,12 +275,14 @@ public class AgentRoutingResource extends AgentStorageResource {
|
|||||||
long cpus = agentHost.getCpuCount();
|
long cpus = agentHost.getCpuCount();
|
||||||
long ram = agentHost.getMemorySize();
|
long ram = agentHost.getMemorySize();
|
||||||
long dom0Ram = agentHost.getMemorySize() / 10;
|
long dom0Ram = agentHost.getMemorySize() / 10;
|
||||||
|
String arch = agentHost.getArch();
|
||||||
|
|
||||||
info.add((int)cpus);
|
info.add((int)cpus);
|
||||||
info.add(speed);
|
info.add(speed);
|
||||||
info.add(ram);
|
info.add(ram);
|
||||||
info.add(agentHost.getCapabilities());
|
info.add(agentHost.getCapabilities());
|
||||||
info.add(dom0Ram);
|
info.add(dom0Ram);
|
||||||
|
info.add(arch);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,6 +87,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L
|
|||||||
long cpuCores = MockAgentManager.DEFAULT_HOST_CPU_CORES;
|
long cpuCores = MockAgentManager.DEFAULT_HOST_CPU_CORES;
|
||||||
long memory = MockAgentManager.DEFAULT_HOST_MEM_SIZE;
|
long memory = MockAgentManager.DEFAULT_HOST_MEM_SIZE;
|
||||||
long localstorageSize = MockStorageManager.DEFAULT_HOST_STORAGE_SIZE;
|
long localstorageSize = MockStorageManager.DEFAULT_HOST_STORAGE_SIZE;
|
||||||
|
String arch = MockAgentManager.DEFAULT_HOST_ARCH;
|
||||||
if (scheme.equals("http")) {
|
if (scheme.equals("http")) {
|
||||||
if (host == null || !host.startsWith("sim")) {
|
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;
|
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]);
|
memory = Long.parseLong(parameter[1]);
|
||||||
} else if (parameter[0].equalsIgnoreCase("localstorage") && parameter[1] != null) {
|
} else if (parameter[0].equalsIgnoreCase("localstorage") && parameter[1] != null) {
|
||||||
localstorageSize = Long.parseLong(parameter[1]);
|
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("cpucore", Long.toString(cpuCores));
|
||||||
params.put("memory", Long.toString(memory));
|
params.put("memory", Long.toString(memory));
|
||||||
params.put("localstorage", Long.toString(localstorageSize));
|
params.put("localstorage", Long.toString(localstorageSize));
|
||||||
|
params.put("arch", arch);
|
||||||
|
|
||||||
resources = createAgentResources(params);
|
resources = createAgentResources(params);
|
||||||
return resources;
|
return resources;
|
||||||
|
|||||||
@ -23,6 +23,8 @@ public interface MockHost {
|
|||||||
|
|
||||||
public long getMemorySize();
|
public long getMemorySize();
|
||||||
|
|
||||||
|
String getArch();
|
||||||
|
|
||||||
public String getCapabilities();
|
public String getCapabilities();
|
||||||
|
|
||||||
public long getId();
|
public long getId();
|
||||||
|
|||||||
@ -87,6 +87,9 @@ public class MockHostVO implements MockHost, InternalIdentity {
|
|||||||
@Column(name = "ram")
|
@Column(name = "ram")
|
||||||
private long memorySize;
|
private long memorySize;
|
||||||
|
|
||||||
|
@Column(name = "arch")
|
||||||
|
private String arch;
|
||||||
|
|
||||||
@Column(name = "capabilities")
|
@Column(name = "capabilities")
|
||||||
private String capabilities;
|
private String capabilities;
|
||||||
|
|
||||||
@ -143,6 +146,14 @@ public class MockHostVO implements MockHost, InternalIdentity {
|
|||||||
this.memorySize = memorySize;
|
this.memorySize = memorySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getArch() {
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArch(String arch) {
|
||||||
|
this.arch = arch;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCapabilities() {
|
public String getCapabilities() {
|
||||||
return this.capabilities;
|
return this.capabilities;
|
||||||
|
|||||||
@ -22,15 +22,12 @@ import com.cloud.dc.VmwareDatacenterVO;
|
|||||||
import com.cloud.dc.VsphereStoragePolicy;
|
import com.cloud.dc.VsphereStoragePolicy;
|
||||||
import com.cloud.exception.DiscoveryException;
|
import com.cloud.exception.DiscoveryException;
|
||||||
import com.cloud.exception.ResourceInUseException;
|
import com.cloud.exception.ResourceInUseException;
|
||||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
|
||||||
import com.cloud.storage.StoragePool;
|
import com.cloud.storage.StoragePool;
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import com.cloud.utils.component.PluggableService;
|
import com.cloud.utils.component.PluggableService;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
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.ImportVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
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.ListVmwareDcsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
||||||
@ -56,7 +53,5 @@ public interface VmwareDatacenterService extends PluggableService {
|
|||||||
|
|
||||||
List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
|
List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
|
||||||
|
|
||||||
List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd);
|
List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
|
||||||
|
|
||||||
Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,10 @@ package com.cloud.hypervisor.vmware.manager;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -45,11 +43,10 @@ import javax.inject.Inject;
|
|||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
import javax.persistence.EntityExistsException;
|
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.AddVmwareDcCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
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.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.ListVmwareDcsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
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.ClusterVO;
|
||||||
import com.cloud.dc.ClusterVSMMapVO;
|
import com.cloud.dc.ClusterVSMMapVO;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.VmwareDatacenter;
|
|
||||||
import com.cloud.dc.VsphereStoragePolicy;
|
import com.cloud.dc.VsphereStoragePolicy;
|
||||||
import com.cloud.dc.VsphereStoragePolicyVO;
|
import com.cloud.dc.VsphereStoragePolicyVO;
|
||||||
import com.cloud.dc.dao.ClusterDao;
|
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.dao.HypervisorCapabilitiesDao;
|
||||||
import com.cloud.hypervisor.vmware.LegacyZoneVO;
|
import com.cloud.hypervisor.vmware.LegacyZoneVO;
|
||||||
import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
|
import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
import com.cloud.dc.VmwareDatacenter;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareClientException;
|
|
||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.dc.VmwareDatacenterVO;
|
import com.cloud.dc.VmwareDatacenterVO;
|
||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
|
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.DomainRouterVO;
|
||||||
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
|
||||||
// TODO move these items upstream?
|
|
||||||
import com.vmware.pbm.PbmProfile;
|
import com.vmware.pbm.PbmProfile;
|
||||||
import com.vmware.vim25.AboutInfo;
|
import com.vmware.vim25.AboutInfo;
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
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 {
|
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 StorageLayer _storage;
|
||||||
private final String _privateNetworkVSwitchName = "vSwitch0";
|
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 _fullCloneFlag;
|
||||||
private boolean _instanceNameFlag;
|
private boolean _instanceNameFlag;
|
||||||
private String _serviceConsoleName;
|
private String _serviceConsoleName;
|
||||||
private String _managementPortGroupName;
|
private String _managemetPortGroupName;
|
||||||
private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
||||||
private String _recycleHungWorker = "false";
|
private String _recycleHungWorker = "false";
|
||||||
private int _additionalPortRangeStart;
|
private int _additionalPortRangeStart;
|
||||||
@ -275,7 +263,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
private final Random _rand = new Random(System.currentTimeMillis());
|
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 VmwareStorageManager _storageMgr;
|
||||||
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
||||||
@ -359,9 +347,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
_serviceConsoleName = "Service Console";
|
_serviceConsoleName = "Service Console";
|
||||||
}
|
}
|
||||||
|
|
||||||
_managementPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
|
_managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
|
||||||
if (_managementPortGroupName == null) {
|
if (_managemetPortGroupName == null) {
|
||||||
_managementPortGroupName = "Management Network";
|
_managemetPortGroupName = "Management Network";
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
|
_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);
|
logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
|
||||||
VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
|
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) {
|
if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
|
||||||
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
|
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();
|
AboutInfo about = hostMo.getHostAboutInfo();
|
||||||
if (about != null) {
|
if (about != null) {
|
||||||
String version = about.getApiVersion();
|
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;
|
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()));
|
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) {
|
if (morSrcHost == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -508,18 +496,19 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
throw new CloudRuntimeException("Invalid serviceContext");
|
throw new CloudRuntimeException("Invalid serviceContext");
|
||||||
}
|
}
|
||||||
ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
|
ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
|
||||||
String privateTrafficLabel;
|
String privateTrafficLabel = null;
|
||||||
privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
|
privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
|
||||||
if (privateTrafficLabel == null) {
|
if (privateTrafficLabel == null) {
|
||||||
privateTrafficLabel = _privateNetworkVSwitchName;
|
privateTrafficLabel = _privateNetworkVSwitchName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mor != null) {
|
if (mor != null) {
|
||||||
List<ManagedObjectReference> returnedHostList = new ArrayList<>();
|
List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>();
|
||||||
|
|
||||||
if (mor.getType().equals("ComputeResource")) {
|
if (mor.getType().equals("ComputeResource")) {
|
||||||
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
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
|
// For ESX host, we need to enable host firewall to allow VNC access
|
||||||
HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
|
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");
|
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
||||||
assert (hosts != null);
|
assert (hosts != null);
|
||||||
|
|
||||||
if (!hosts.isEmpty()) {
|
if (hosts.size() > 0) {
|
||||||
AboutInfo about = serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product");
|
AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"));
|
||||||
String version = about.getApiVersion();
|
String version = about.getApiVersion();
|
||||||
int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
|
int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
|
||||||
if (hosts.size() > maxHostsPerCluster) {
|
if (hosts.size() > maxHostsPerCluster) {
|
||||||
@ -625,13 +614,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getManagementPortGroupName() {
|
public String getManagementPortGroupName() {
|
||||||
return _managementPortGroupName;
|
return _managemetPortGroupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
|
public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
|
||||||
if (hostMo.getHostType() == VmwareHostType.ESXi) {
|
if (hostMo.getHostType() == VmwareHostType.ESXi) {
|
||||||
return _managementPortGroupName;
|
return _managemetPortGroupName;
|
||||||
}
|
}
|
||||||
return _serviceConsoleName;
|
return _serviceConsoleName;
|
||||||
}
|
}
|
||||||
@ -641,7 +630,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
params.put("vmware.create.full.clone", _fullCloneFlag);
|
params.put("vmware.create.full.clone", _fullCloneFlag);
|
||||||
params.put("vm.instancename.flag", _instanceNameFlag);
|
params.put("vm.instancename.flag", _instanceNameFlag);
|
||||||
params.put("service.console.name", _serviceConsoleName);
|
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.root.disk.controller", _rootDiskController);
|
||||||
params.put("vmware.data.disk.controller", _dataDiskController);
|
params.put("vmware.data.disk.controller", _dataDiskController);
|
||||||
params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
|
params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
|
||||||
@ -668,23 +657,23 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] tokens = workerTag.split("-");
|
String tokens[] = workerTag.split("-");
|
||||||
if (tokens.length != 3) {
|
if (tokens.length != 3) {
|
||||||
logger.error("Invalid worker VM tag " + workerTag);
|
logger.error("Invalid worker VM tag " + workerTag);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long startTick = Long.parseLong(tokens[0]);
|
long startTick = Long.parseLong(tokens[0]);
|
||||||
long msId = Long.parseLong(tokens[1]);
|
long msid = Long.parseLong(tokens[1]);
|
||||||
long runId = Long.parseLong(tokens[2]);
|
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())
|
if (logger.isInfoEnabled())
|
||||||
logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
|
logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runId != clusterManager.getManagementRunId(msId)) {
|
if (runid != clusterManager.getManagementRunId(msid)) {
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isInfoEnabled())
|
||||||
logger.info("Worker VM's owner management server has changed runid, recycle it");
|
logger.info("Worker VM's owner management server has changed runid, recycle it");
|
||||||
return true;
|
return true;
|
||||||
@ -782,6 +771,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
|
isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert (isoFile != null);
|
||||||
if (!isoFile.exists()) {
|
if (!isoFile.exists()) {
|
||||||
logger.error("Unable to locate systemvm.iso in your setup at " + isoFile);
|
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()) {
|
if (keyFile == null || !keyFile.exists()) {
|
||||||
keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
|
keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
|
||||||
}
|
}
|
||||||
|
assert (keyFile != null);
|
||||||
if (!keyFile.exists()) {
|
if (!keyFile.exists()) {
|
||||||
logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile);
|
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
|
@Override
|
||||||
public String getMountPoint(String storageUrl, String nfsVersion) {
|
public String getMountPoint(String storageUrl, String nfsVersion) {
|
||||||
String mountPoint;
|
String mountPoint = null;
|
||||||
synchronized (_storageMounts) {
|
synchronized (_storageMounts) {
|
||||||
mountPoint = _storageMounts.get(storageUrl);
|
mountPoint = _storageMounts.get(storageUrl);
|
||||||
if (mountPoint != null) {
|
if (mountPoint != null) {
|
||||||
@ -837,7 +827,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String mountPoint = null;
|
String mountPoint = null;
|
||||||
long mshostId = ManagementServerNode.getManagementServerId();
|
long mshostId = ManagementServerNode.getManagementServerId();
|
||||||
for (int i = 0; i < 10; i++) {
|
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);
|
File file = new File(mntPt);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
if (_storage.mkdir(mntPt)) {
|
if (_storage.mkdir(mntPt)) {
|
||||||
@ -862,9 +852,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
for (String mountPoint : mounts) {
|
for (String mountPoint : mounts) {
|
||||||
logger.info("umount NFS mount from previous session: " + mountPoint);
|
logger.info("umount NFS mount from previous session: " + mountPoint);
|
||||||
|
|
||||||
|
String result = null;
|
||||||
Script command = new Script(true, "umount", _timeout, logger);
|
Script command = new Script(true, "umount", _timeout, logger);
|
||||||
command.add(mountPoint);
|
command.add(mountPoint);
|
||||||
String result = command.execute();
|
result = command.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
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()) {
|
for (String mountPoint : _storageMounts.values()) {
|
||||||
logger.info("umount NFS mount: " + mountPoint);
|
logger.info("umount NFS mount: " + mountPoint);
|
||||||
|
|
||||||
|
String result = null;
|
||||||
Script command = new Script(true, "umount", _timeout, logger);
|
Script command = new Script(true, "umount", _timeout, logger);
|
||||||
command.add(mountPoint);
|
command.add(mountPoint);
|
||||||
String result = command.execute();
|
result = command.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
||||||
}
|
}
|
||||||
@ -902,8 +894,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Script script;
|
Script script = null;
|
||||||
String result;
|
String result = null;
|
||||||
Script command = new Script(true, "mount", _timeout, logger);
|
Script command = new Script(true, "mount", _timeout, logger);
|
||||||
command.add("-t", "nfs");
|
command.add("-t", "nfs");
|
||||||
if (nfsVersion != null){
|
if (nfsVersion != null){
|
||||||
@ -990,9 +982,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
|
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
|
||||||
if (cmd != null) {
|
if (cmd instanceof StartupCommand) {
|
||||||
if (host.getHypervisorType() == HypervisorType.VMware) {
|
if (host.getHypervisorType() == HypervisorType.VMware) {
|
||||||
updateClusterNativeHAState(host, cmd);
|
updateClusterNativeHAState(host, cmd);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1062,16 +1056,16 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<Integer, Integer> getAddiionalVncPortRange() {
|
public Pair<Integer, Integer> getAddiionalVncPortRange() {
|
||||||
return new Pair<>(_additionalPortRangeStart, _additionalPortRangeSize);
|
return new Pair<Integer, Integer>(_additionalPortRangeStart, _additionalPortRangeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
|
public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
|
||||||
CiscoNexusVSMDeviceVO nexusVSM;
|
CiscoNexusVSMDeviceVO nexusVSM = null;
|
||||||
ClusterVSMMapVO vsmMapVO;
|
ClusterVSMMapVO vsmMapVO = null;
|
||||||
|
|
||||||
vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
|
vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
|
||||||
long vsmId;
|
long vsmId = 0;
|
||||||
if (vsmMapVO != null) {
|
if (vsmMapVO != null) {
|
||||||
vsmId = vsmMapVO.getVsmId();
|
vsmId = vsmMapVO.getVsmId();
|
||||||
logger.info("vsmId is " + vsmId);
|
logger.info("vsmId is " + vsmId);
|
||||||
@ -1082,7 +1076,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> nexusVSMCredentials = new HashMap<>();
|
Map<String, String> nexusVSMCredentials = new HashMap<String, String>();
|
||||||
if (nexusVSM != null) {
|
if (nexusVSM != null) {
|
||||||
nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
|
nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
|
||||||
nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
|
nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
|
||||||
@ -1109,7 +1103,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Class<?>> getCommands() {
|
public List<Class<?>> getCommands() {
|
||||||
List<Class<?>> cmdList = new ArrayList<>();
|
List<Class<?>> cmdList = new ArrayList<Class<?>>();
|
||||||
cmdList.add(AddVmwareDcCmd.class);
|
cmdList.add(AddVmwareDcCmd.class);
|
||||||
cmdList.add(UpdateVmwareDcCmd.class);
|
cmdList.add(UpdateVmwareDcCmd.class);
|
||||||
cmdList.add(RemoveVmwareDcCmd.class);
|
cmdList.add(RemoveVmwareDcCmd.class);
|
||||||
@ -1118,14 +1112,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
cmdList.add(ListVsphereStoragePoliciesCmd.class);
|
cmdList.add(ListVsphereStoragePoliciesCmd.class);
|
||||||
cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
|
cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
|
||||||
cmdList.add(ListVmwareDcVmsCmd.class);
|
cmdList.add(ListVmwareDcVmsCmd.class);
|
||||||
cmdList.add(ListVmwareDcHostsCmd.class);
|
|
||||||
return cmdList;
|
return cmdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
|
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
|
||||||
VmwareDatacenterVO vmwareDc;
|
VmwareDatacenterVO vmwareDc = null;
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
String userName = cmd.getUsername();
|
String userName = cmd.getUsername();
|
||||||
String password = cmd.getPassword();
|
String password = cmd.getPassword();
|
||||||
@ -1181,10 +1174,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId);
|
checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId);
|
||||||
|
|
||||||
VmwareContext context = null;
|
VmwareContext context = null;
|
||||||
DatacenterMO dcMo;
|
DatacenterMO dcMo = null;
|
||||||
String dcCustomFieldValue;
|
String dcCustomFieldValue;
|
||||||
boolean addDcCustomFieldDef = false;
|
boolean addDcCustomFieldDef = false;
|
||||||
boolean dcInUse;
|
boolean dcInUse = false;
|
||||||
String guid;
|
String guid;
|
||||||
ManagedObjectReference dcMor;
|
ManagedObjectReference dcMor;
|
||||||
try {
|
try {
|
||||||
@ -1217,7 +1210,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
// Map zone with vmware datacenter
|
// Map zone with vmware datacenter
|
||||||
vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
|
vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
|
||||||
|
|
||||||
vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
|
vmwareDcZoneMap = vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
|
||||||
|
|
||||||
// Set custom field for this DC
|
// Set custom field for this DC
|
||||||
if (addDcCustomFieldDef) {
|
if (addDcCustomFieldDef) {
|
||||||
@ -1237,6 +1230,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
context = null;
|
||||||
}
|
}
|
||||||
importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
|
importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
|
||||||
return vmwareDc;
|
return vmwareDc;
|
||||||
@ -1261,9 +1255,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
* Check if DC is already part of zone
|
* 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
|
* 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 vCenterHost
|
||||||
* @param vmwareDcName the name of the vmware DC
|
* @param vmwareDcName
|
||||||
* @param zoneId zone that the DC should be connected to
|
* @param zoneId
|
||||||
* @throws ResourceInUseException if the DC can not be used.
|
* @throws ResourceInUseException if the DC can not be used.
|
||||||
*/
|
*/
|
||||||
private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneId) throws ResourceInUseException {
|
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);
|
vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
|
||||||
if (vmwareDc != null) {
|
if (vmwareDc != null) {
|
||||||
VmwareDatacenterZoneMapVO mapping = vmwareDatacenterZoneMapDao.findByVmwareDcId(vmwareDc.getId());
|
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));
|
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
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
|
@ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
|
||||||
public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
|
public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
|
||||||
final long zoneId = cmd.getZoneId();
|
final Long zoneId = cmd.getZoneId();
|
||||||
final String userName = cmd.getUsername();
|
final String userName = cmd.getUsername();
|
||||||
final String password = cmd.getPassword();
|
final String password = cmd.getPassword();
|
||||||
final String vCenterHost = cmd.getVcenter();
|
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()));
|
vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost()));
|
||||||
|
|
||||||
return Transaction.execute(new TransactionCallback<>() {
|
return Transaction.execute(new TransactionCallback<VmwareDatacenter>() {
|
||||||
@Override
|
@Override
|
||||||
public VmwareDatacenter doInTransaction(TransactionStatus status) {
|
public VmwareDatacenter doInTransaction(TransactionStatus status) {
|
||||||
if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
|
if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
|
||||||
@ -1357,7 +1351,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String vCenterHost;
|
String vCenterHost;
|
||||||
String userName;
|
String userName;
|
||||||
String password;
|
String password;
|
||||||
DatacenterMO dcMo;
|
DatacenterMO dcMo = null;
|
||||||
final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
|
final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
|
||||||
// Check if zone is associated with VMware DC
|
// Check if zone is associated with VMware DC
|
||||||
if (vmwareDcZoneMap == null) {
|
if (vmwareDcZoneMap == null) {
|
||||||
@ -1394,9 +1388,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
throw new DiscoveryException(msg);
|
throw new DiscoveryException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert (dcMo != null);
|
||||||
|
|
||||||
// Reset custom field property cloud.zone over this DC
|
// Reset custom field property cloud.zone over this DC
|
||||||
dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
|
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) {
|
} catch (Exception e) {
|
||||||
String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
|
String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
@ -1405,6 +1401,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
context = null;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1425,7 +1422,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
|
private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
|
||||||
// Check if zone has resources? - For now look for clusters
|
// Check if zone has resources? - For now look for clusters
|
||||||
List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
|
List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
|
||||||
if (!CollectionUtils.isNullOrEmpty(clusters)) {
|
if (clusters != null && clusters.size() > 0) {
|
||||||
// Look for VMware hypervisor.
|
// Look for VMware hypervisor.
|
||||||
for (ClusterVO cluster : clusters) {
|
for (ClusterVO cluster : clusters) {
|
||||||
if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
|
if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
|
||||||
@ -1446,9 +1443,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException {
|
public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException {
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
List<VmwareDatacenterVO> vmwareDcList = new ArrayList<>();
|
List<VmwareDatacenterVO> vmwareDcList = new ArrayList<VmwareDatacenterVO>();
|
||||||
VmwareDatacenterZoneMapVO vmwareDcZoneMap;
|
VmwareDatacenterZoneMapVO vmwareDcZoneMap;
|
||||||
VmwareDatacenterVO vmwareDatacenter;
|
VmwareDatacenterVO vmwareDatacenter;
|
||||||
long vmwareDcId;
|
long vmwareDcId;
|
||||||
@ -1506,7 +1503,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String vCenterHost = vmwareDatacenter.getVcenterHost();
|
String vCenterHost = vmwareDatacenter.getVcenterHost();
|
||||||
String userName = vmwareDatacenter.getUser();
|
String userName = vmwareDatacenter.getUser();
|
||||||
String password = vmwareDatacenter.getPassword();
|
String password = vmwareDatacenter.getPassword();
|
||||||
List<PbmProfile> storageProfiles;
|
List<PbmProfile> storageProfiles = null;
|
||||||
try {
|
try {
|
||||||
logger.debug(String.format("Importing vSphere Storage Policies for the vmware DC %d in zone %d", vmwareDcId, zoneId));
|
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);
|
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<VsphereStoragePolicyVO> allStoragePolicies = vsphereStoragePolicyDao.listAll();
|
||||||
List<PbmProfile> finalStorageProfiles = storageProfiles;
|
List<PbmProfile> finalStorageProfiles = storageProfiles;
|
||||||
List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
|
List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
|
||||||
.filter(existingPolicy -> finalStorageProfiles.stream()
|
.filter(existingPolicy -> !finalStorageProfiles.stream()
|
||||||
.noneMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
|
.anyMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
|
for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
|
||||||
vsphereStoragePolicyDao.remove(storagePolicy.getId());
|
vsphereStoragePolicyDao.remove(storagePolicy.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return vsphereStoragePolicyDao.listAll();
|
List<VsphereStoragePolicyVO> storagePolicies = vsphereStoragePolicyDao.listAll();
|
||||||
|
return storagePolicies;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1588,87 +1586,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd) {
|
public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd 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) {
|
|
||||||
String vcenter = cmd.getVcenter();
|
String vcenter = cmd.getVcenter();
|
||||||
String datacenterName = cmd.getDatacenterName();
|
String datacenterName = cmd.getDatacenterName();
|
||||||
String username = cmd.getUsername();
|
String username = cmd.getUsername();
|
||||||
String password = cmd.getPassword();
|
String password = cmd.getPassword();
|
||||||
Long existingVcenterId = cmd.getExistingVcenterId();
|
Long existingVcenterId = cmd.getExistingVcenterId();
|
||||||
|
String keyword = cmd.getKeyword();
|
||||||
|
|
||||||
if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
|
if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
|
||||||
(existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
|
(existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
|
||||||
@ -1689,27 +1613,37 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
username = vmwareDc.getUser();
|
username = vmwareDc.getUser();
|
||||||
password = vmwareDc.getPassword();
|
password = vmwareDc.getPassword();
|
||||||
}
|
}
|
||||||
VcenterData vmwaredc = new VcenterData(vcenter, datacenterName, username, password);
|
|
||||||
return vmwaredc;
|
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);
|
||||||
|
|
||||||
|
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();
|
||||||
private static class VcenterData {
|
return StringUtils.isBlank(keyword) ? instances :
|
||||||
public final String vcenter;
|
instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList());
|
||||||
public final String datacenterName;
|
} catch (Exception e) {
|
||||||
public final String username;
|
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
||||||
public final String password;
|
vcenter, datacenterName, e.getMessage());
|
||||||
|
logger.error(errorMsg, e);
|
||||||
public VcenterData(String vcenter, String datacenterName, String username, String password) {
|
throw new CloudRuntimeException(errorMsg);
|
||||||
this.vcenter = vcenter;
|
|
||||||
this.datacenterName = datacenterName;
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNexusVSM(Long clusterId) {
|
public boolean hasNexusVSM(Long clusterId) {
|
||||||
ClusterVSMMapVO vsmMapVo;
|
ClusterVSMMapVO vsmMapVo = null;
|
||||||
|
|
||||||
vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
|
vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
|
||||||
if (vsmMapVo == null) {
|
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 is called at regular intervals when storage.template.cleanup.enabled == true
|
||||||
* It collect all templates that
|
* It collect all templates that
|
||||||
* - are deleted from cloudstack
|
* - are deleted from cloudstack
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import javax.xml.datatype.XMLGregorianCalendar;
|
|||||||
|
|
||||||
import com.cloud.capacity.CapacityManager;
|
import com.cloud.capacity.CapacityManager;
|
||||||
import com.cloud.hypervisor.vmware.mo.HostDatastoreBrowserMO;
|
import com.cloud.hypervisor.vmware.mo.HostDatastoreBrowserMO;
|
||||||
|
import com.vmware.vim25.Description;
|
||||||
import com.vmware.vim25.FileInfo;
|
import com.vmware.vim25.FileInfo;
|
||||||
import com.vmware.vim25.FileQueryFlags;
|
import com.vmware.vim25.FileQueryFlags;
|
||||||
import com.vmware.vim25.FolderFileInfo;
|
import com.vmware.vim25.FolderFileInfo;
|
||||||
@ -58,6 +59,7 @@ import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
|||||||
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
||||||
import com.vmware.vim25.VirtualCdromIsoBackingInfo;
|
import com.vmware.vim25.VirtualCdromIsoBackingInfo;
|
||||||
import com.vmware.vim25.VirtualMachineConfigSummary;
|
import com.vmware.vim25.VirtualMachineConfigSummary;
|
||||||
|
import com.vmware.vim25.VirtualTPM;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.backup.PrepareForBackupRestorationCommand;
|
import org.apache.cloudstack.backup.PrepareForBackupRestorationCommand;
|
||||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||||
@ -2597,12 +2599,16 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
|
|
||||||
setBootOptions(vmSpec, bootMode, vmConfigSpec);
|
setBootOptions(vmSpec, bootMode, vmConfigSpec);
|
||||||
|
|
||||||
|
// Config vTPM
|
||||||
|
configureVirtualTPM(vmMo, vmSpec, vmConfigSpec);
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(vmStoragePolicyId)) {
|
if (StringUtils.isNotEmpty(vmStoragePolicyId)) {
|
||||||
vmConfigSpec.getVmProfile().add(vmProfileSpec);
|
vmConfigSpec.getVmProfile().add(vmProfileSpec);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Configuring the VM %s with storage policy: %s", vmInternalCSName, vmStoragePolicyId));
|
logger.trace(String.format("Configuring the VM %s with storage policy: %s", vmInternalCSName, vmStoragePolicyId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Configure VM
|
// Configure VM
|
||||||
//
|
//
|
||||||
@ -3203,6 +3209,57 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
vmConfigSpec.getDeviceChange().add(arrayVideoCardConfigSpecs);
|
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 {
|
private void tearDownVm(VirtualMachineMO vmMo) throws Exception {
|
||||||
|
|
||||||
if (vmMo == null)
|
if (vmMo == null)
|
||||||
|
|||||||
@ -36,8 +36,8 @@ import com.cloud.dc.VmwareDatacenterVO;
|
|||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@APICommand(name = "addVmwareDc", description = "Adds a Vmware datacenter to specified zone",
|
@APICommand(name = "addVmwareDc", description = "Adds a VMware datacenter to specified zone", responseObject = VmwareDatacenterResponse.class,
|
||||||
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
|
||||||
public class AddVmwareDcCmd extends BaseCmd {
|
public class AddVmwareDcCmd extends BaseCmd {
|
||||||
|
|
||||||
@Inject
|
@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;
|
private String name;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.VCENTER,
|
@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.")
|
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;
|
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;
|
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;
|
private String password;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID.")
|
@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.setResponseName(getCommandName());
|
||||||
response.setObjectName("vmwaredc");
|
response.setObjectName("vmwaredc");
|
||||||
} else {
|
} 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);
|
this.setResponseObject(response);
|
||||||
} catch (DiscoveryException ex) {
|
} catch (DiscoveryException ex) {
|
||||||
|
|||||||
@ -72,13 +72,6 @@ public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
|
|
||||||
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
|
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
|
||||||
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
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<>();
|
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
||||||
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
||||||
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
||||||
@ -91,7 +84,9 @@ public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
|
|
||||||
storagePoliciesResponseList.add(storagePoliciesResponse);
|
storagePoliciesResponseList.add(storagePoliciesResponse);
|
||||||
}
|
}
|
||||||
return storagePoliciesResponseList;
|
responseList.setResponses(storagePoliciesResponseList);
|
||||||
|
responseList.setResponseName(getCommandName());
|
||||||
|
setResponseObject(responseList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.exception.ResourceUnavailableException;
|
||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.ApiErrorCode;
|
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.BaseResponse;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
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.UnmanagedInstanceResponse;
|
||||||
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
||||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||||
@ -42,10 +42,10 @@ import javax.inject.Inject;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestResponse.class,
|
@APICommand(name = "listVmwareDcVms", responseObject = UnmanagedInstanceResponse.class,
|
||||||
description = "Lists the VMs in a Vmware Datacenter",
|
description = "Lists the VMs in a VMware Datacenter",
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
public class ListVmwareDcVmsCmd extends BaseListCmd {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VmwareDatacenterService _vmwareDatacenterService;
|
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.")
|
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;
|
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;
|
private String datacenterName;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
@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.")
|
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||||
private String password;
|
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() {
|
public String getVcenter() {
|
||||||
return vcenter;
|
return vcenter;
|
||||||
}
|
}
|
||||||
@ -94,18 +82,6 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
|||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getBatchSize() {
|
|
||||||
return batchSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getToken() {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDatacenterName() {
|
public String getDatacenterName() {
|
||||||
return datacenterName;
|
return datacenterName;
|
||||||
}
|
}
|
||||||
@ -118,8 +94,7 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
|||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||||
checkParameters();
|
checkParameters();
|
||||||
try {
|
try {
|
||||||
Pair<String, List<UnmanagedInstanceTO>> results = _vmwareDatacenterService.listVMsInDatacenter(this);
|
List<UnmanagedInstanceTO> vms = _vmwareDatacenterService.listVMsInDatacenter(this);
|
||||||
List<UnmanagedInstanceTO> vms = results.second();
|
|
||||||
List<BaseResponse> baseResponseList = new ArrayList<>();
|
List<BaseResponse> baseResponseList = new ArrayList<>();
|
||||||
if (CollectionUtils.isNotEmpty(vms)) {
|
if (CollectionUtils.isNotEmpty(vms)) {
|
||||||
for (UnmanagedInstanceTO vmwareVm : vms) {
|
for (UnmanagedInstanceTO vmwareVm : vms) {
|
||||||
@ -127,13 +102,16 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
|||||||
baseResponseList.add(resp);
|
baseResponseList.add(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
|
List<BaseResponse> pagingList = com.cloud.utils.StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal());
|
||||||
response.setResponses(baseResponseList, baseResponseList.size());
|
if (CollectionUtils.isEmpty(pagingList)) {
|
||||||
|
pagingList = baseResponseList;
|
||||||
|
}
|
||||||
|
ListResponse<BaseResponse> response = new ListResponse<>();
|
||||||
|
response.setResponses(pagingList, baseResponseList.size());
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
response.setToken(results.first());
|
|
||||||
setResponseObject(response);
|
setResponseObject(response);
|
||||||
} catch (CloudRuntimeException e) {
|
} 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);
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,6 +134,6 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCommandName() {
|
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.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.user.Account;
|
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)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class ListVmwareDcsCmd extends BaseListCmd {
|
public class ListVmwareDcsCmd extends BaseListCmd {
|
||||||
|
|
||||||
@ -50,6 +50,7 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
|||||||
public VmwareDatacenterService _vmwareDatacenterService;
|
public VmwareDatacenterService _vmwareDatacenterService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//////////////// API parameters /////////////////////
|
//////////////// API parameters /////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -72,27 +73,20 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||||
ResourceAllocationException {
|
ResourceAllocationException {
|
||||||
List<? extends VmwareDatacenter> vmwareDcList;
|
List<? extends VmwareDatacenter> vmwareDcList = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
|
vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
|
||||||
} catch (InvalidParameterValueException ie) {
|
} catch (InvalidParameterValueException ie) {
|
||||||
throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
|
throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
|
||||||
} catch (Exception e) {
|
} 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<>();
|
ListResponse<VmwareDatacenterResponse> response = new ListResponse<VmwareDatacenterResponse>();
|
||||||
List<VmwareDatacenterResponse> vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList);
|
List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<VmwareDatacenterResponse>();
|
||||||
response.setResponses(vmwareDcResponses);
|
|
||||||
response.setResponseName(getCommandName());
|
|
||||||
setResponseObject(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? extends VmwareDatacenter> vmwareDcList) {
|
if (vmwareDcList != null && vmwareDcList.size() > 0) {
|
||||||
List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<>();
|
|
||||||
|
|
||||||
if (vmwareDcList != null && !vmwareDcList.isEmpty()) {
|
|
||||||
for (VmwareDatacenter vmwareDc : vmwareDcList) {
|
for (VmwareDatacenter vmwareDc : vmwareDcList) {
|
||||||
VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
|
VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
|
||||||
|
|
||||||
@ -100,12 +94,14 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
|||||||
vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
|
vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
|
||||||
vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
|
vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
|
||||||
vmwareDcResponse.setZoneId(getZoneId());
|
vmwareDcResponse.setZoneId(getZoneId());
|
||||||
vmwareDcResponse.setObjectName(ApiConstants.VMWARE_DC);
|
vmwareDcResponse.setObjectName("VMwareDC");
|
||||||
|
|
||||||
vmwareDcResponses.add(vmwareDcResponse);
|
vmwareDcResponses.add(vmwareDcResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vmwareDcResponses;
|
response.setResponses(vmwareDcResponses);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -71,13 +71,6 @@ public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
|
|
||||||
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
|
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
|
||||||
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
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<>();
|
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
||||||
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
||||||
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
||||||
@ -86,11 +79,13 @@ public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
storagePoliciesResponse.setName(storagePolicy.getName());
|
storagePoliciesResponse.setName(storagePolicy.getName());
|
||||||
storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
|
storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
|
||||||
storagePoliciesResponse.setDescription(storagePolicy.getDescription());
|
storagePoliciesResponse.setDescription(storagePolicy.getDescription());
|
||||||
storagePoliciesResponse.setObjectName(ApiConstants.STORAGE_POLICY);
|
storagePoliciesResponse.setObjectName("StoragePolicy");
|
||||||
|
|
||||||
storagePoliciesResponseList.add(storagePoliciesResponse);
|
storagePoliciesResponseList.add(storagePoliciesResponse);
|
||||||
}
|
}
|
||||||
return storagePoliciesResponseList;
|
responseList.setResponses(storagePoliciesResponseList);
|
||||||
|
responseList.setResponseName(getCommandName());
|
||||||
|
setResponseObject(responseList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -68,7 +68,7 @@ public class ListVsphereStoragePolicyCompatiblePoolsCmd extends BaseListCmd {
|
|||||||
List<StoragePoolResponse> poolResponses = new ArrayList<>();
|
List<StoragePoolResponse> poolResponses = new ArrayList<>();
|
||||||
for (StoragePool pool : pools) {
|
for (StoragePool pool : pools) {
|
||||||
StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
|
StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
|
||||||
poolResponse.setObjectName(ApiConstants.STORAGE_POOL);
|
poolResponse.setObjectName("storagepool");
|
||||||
poolResponses.add(poolResponse);
|
poolResponses.add(poolResponse);
|
||||||
}
|
}
|
||||||
response.setResponses(poolResponses);
|
response.setResponses(poolResponses);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
|||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
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)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class RemoveVmwareDcCmd extends BaseCmd {
|
public class RemoveVmwareDcCmd extends BaseCmd {
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
|
|||||||
type = CommandType.UUID,
|
type = CommandType.UUID,
|
||||||
entityType = ZoneResponse.class,
|
entityType = ZoneResponse.class,
|
||||||
required = true,
|
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;
|
private Long zoneId;
|
||||||
|
|
||||||
public Long getZoneId() {
|
public Long getZoneId() {
|
||||||
@ -63,7 +63,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
|
|||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
setResponseObject(response);
|
setResponseObject(response);
|
||||||
} else {
|
} 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) {
|
} catch (ResourceInUseException ex) {
|
||||||
logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone."
|
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.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.user.Account;
|
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,
|
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false,
|
||||||
since = "4.12.0", authorized = {RoleType.Admin})
|
since = "4.12.0", authorized = {RoleType.Admin})
|
||||||
public class UpdateVmwareDcCmd extends BaseCmd {
|
public class UpdateVmwareDcCmd extends BaseCmd {
|
||||||
@ -50,7 +50,7 @@ public class UpdateVmwareDcCmd extends BaseCmd {
|
|||||||
private Long zoneId;
|
private Long zoneId;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
|
||||||
description = "Vmware datacenter name.")
|
description = "VMware datacenter name.")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
|
@Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
|
||||||
@ -105,13 +105,13 @@ public class UpdateVmwareDcCmd extends BaseCmd {
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
|
final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
|
||||||
if (vmwareDatacenter == null) {
|
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();
|
final VmwareDatacenterResponse response = new VmwareDatacenterResponse();
|
||||||
response.setId(vmwareDatacenter.getUuid());
|
response.setId(vmwareDatacenter.getUuid());
|
||||||
response.setName(vmwareDatacenter.getVmwareDatacenterName());
|
response.setName(vmwareDatacenter.getVmwareDatacenterName());
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
response.setObjectName(ApiConstants.VMWARE_DC);
|
response.setObjectName("vmwaredc");
|
||||||
setResponseObject(response);
|
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.FileInfo;
|
||||||
import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
import com.vmware.vim25.HostDatastoreBrowserSearchResults;
|
||||||
import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
|
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.CopyCommand;
|
||||||
import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsAnswer;
|
import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsAnswer;
|
||||||
import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsCommand;
|
import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsCommand;
|
||||||
@ -835,4 +837,41 @@ public class VmwareResourceTest {
|
|||||||
assertEquals(Collections.singletonList(1L), answer.getSizes());
|
assertEquals(Collections.singletonList(1L), answer.getSizes());
|
||||||
assertEquals(Collections.singletonList(date.getTime()), answer.getLastModified());
|
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 javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.cpu.CPU;
|
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
|
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.dao.TemplateJoinDao;
|
||||||
import com.cloud.api.query.vo.TemplateJoinVO;
|
import com.cloud.api.query.vo.TemplateJoinVO;
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.dao.DataCenterDao;
|
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.ComponentContext;
|
||||||
import com.cloud.utils.component.ManagerBase;
|
import com.cloud.utils.component.ManagerBase;
|
||||||
import com.cloud.utils.db.Filter;
|
import com.cloud.utils.db.Filter;
|
||||||
|
import com.cloud.utils.db.JoinBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
@ -94,6 +95,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
|||||||
if (template.getState() != null) {
|
if (template.getState() != null) {
|
||||||
response.setIsoState(template.getState().toString());
|
response.setIsoState(template.getState().toString());
|
||||||
}
|
}
|
||||||
|
response.setIsoArch(template.getArch().getType());
|
||||||
response.setDirectDownload(template.isDirectDownload());
|
response.setDirectDownload(template.isDirectDownload());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,6 +269,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
|||||||
final Long zoneId = cmd.getZoneId();
|
final Long zoneId = cmd.getZoneId();
|
||||||
String minimumSemanticVersion = cmd.getMinimumSemanticVersion();
|
String minimumSemanticVersion = cmd.getMinimumSemanticVersion();
|
||||||
final Long minimumKubernetesVersionId = cmd.getMinimumKubernetesVersionId();
|
final Long minimumKubernetesVersionId = cmd.getMinimumKubernetesVersionId();
|
||||||
|
final String arch = cmd.getArch();
|
||||||
if (StringUtils.isNotEmpty(minimumSemanticVersion) && minimumKubernetesVersionId != null) {
|
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));
|
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();
|
SearchBuilder<KubernetesSupportedVersionVO> sb = kubernetesSupportedVersionDao.createSearchBuilder();
|
||||||
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||||
sb.and("keyword", sb.entity().getName(), SearchCriteria.Op.LIKE);
|
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();
|
SearchCriteria<KubernetesSupportedVersionVO> sc = sb.create();
|
||||||
String keyword = cmd.getKeyword();
|
String keyword = cmd.getKeyword();
|
||||||
if (versionId != null) {
|
if (versionId != null) {
|
||||||
@ -295,6 +305,9 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
|||||||
if(keyword != null){
|
if(keyword != null){
|
||||||
sc.setParameters("keyword", "%" + keyword + "%");
|
sc.setParameters("keyword", "%" + keyword + "%");
|
||||||
}
|
}
|
||||||
|
if (StringUtils.isNotBlank(arch)) {
|
||||||
|
sc.setJoinParameters("isoSearch", "arch", arch);
|
||||||
|
}
|
||||||
Pair<List<KubernetesSupportedVersionVO>, Integer> versionsAndCount =
|
Pair<List<KubernetesSupportedVersionVO>, Integer> versionsAndCount =
|
||||||
kubernetesSupportedVersionDao.searchAndCount(sc, searchFilter);
|
kubernetesSupportedVersionDao.searchAndCount(sc, searchFilter);
|
||||||
List<KubernetesSupportedVersionVO> versions =
|
List<KubernetesSupportedVersionVO> versions =
|
||||||
|
|||||||
@ -66,6 +66,11 @@ public class ListKubernetesSupportedVersionsCmd extends BaseListCmd {
|
|||||||
description = "the ID of the minimum Kubernetes supported version")
|
description = "the ID of the minimum Kubernetes supported version")
|
||||||
private Long minimumKubernetesVersionId;
|
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 ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -85,6 +90,10 @@ public class ListKubernetesSupportedVersionsCmd extends BaseListCmd {
|
|||||||
return minimumSemanticVersion;
|
return minimumSemanticVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getArch() {
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getMinimumKubernetesVersionId() {
|
public Long getMinimumKubernetesVersionId() {
|
||||||
return minimumKubernetesVersionId;
|
return minimumKubernetesVersionId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,10 @@ public class KubernetesSupportedVersionResponse extends BaseResponse {
|
|||||||
@Param(description = "the state of the binaries ISO for Kubernetes supported version")
|
@Param(description = "the state of the binaries ISO for Kubernetes supported version")
|
||||||
private String isoState;
|
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)
|
@SerializedName(ApiConstants.ZONE_ID)
|
||||||
@Param(description = "the id of the zone in which Kubernetes supported version is available")
|
@Param(description = "the id of the zone in which Kubernetes supported version is available")
|
||||||
private String zoneId;
|
private String zoneId;
|
||||||
@ -138,6 +142,14 @@ public class KubernetesSupportedVersionResponse extends BaseResponse {
|
|||||||
this.isoState = isoState;
|
this.isoState = isoState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getIsoArch() {
|
||||||
|
return isoArch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsoArch(String isoArch) {
|
||||||
|
this.isoArch = isoArch;
|
||||||
|
}
|
||||||
|
|
||||||
public String getZoneId() {
|
public String getZoneId() {
|
||||||
return zoneId;
|
return zoneId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import org.springframework.test.util.ReflectionTestUtils;
|
|||||||
|
|
||||||
import com.cloud.api.query.dao.TemplateJoinDao;
|
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||||
import com.cloud.api.query.vo.TemplateJoinVO;
|
import com.cloud.api.query.vo.TemplateJoinVO;
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class KubernetesVersionManagerImplTest {
|
public class KubernetesVersionManagerImplTest {
|
||||||
@ -57,6 +58,7 @@ public class KubernetesVersionManagerImplTest {
|
|||||||
Mockito.when(kubernetesSupportedVersion.getIsoId()).thenReturn(1L);
|
Mockito.when(kubernetesSupportedVersion.getIsoId()).thenReturn(1L);
|
||||||
KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse();
|
KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse();
|
||||||
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
||||||
|
Mockito.when(templateJoinVO.getArch()).thenReturn(CPU.CPUArch.getDefault());
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
Mockito.when(templateJoinVO.getUuid()).thenReturn(uuid);
|
Mockito.when(templateJoinVO.getUuid()).thenReturn(uuid);
|
||||||
Mockito.when(templateJoinDao.findById(1L)).thenReturn(templateJoinVO);
|
Mockito.when(templateJoinDao.findById(1L)).thenReturn(templateJoinVO);
|
||||||
|
|||||||
@ -125,6 +125,7 @@ public class KubernetesVersionServiceTest {
|
|||||||
|
|
||||||
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
||||||
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
|
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
|
||||||
|
when(templateJoinVO.getArch()).thenReturn(CPU.CPUArch.getDefault());
|
||||||
when(templateJoinDao.findById(Mockito.anyLong())).thenReturn(templateJoinVO);
|
when(templateJoinDao.findById(Mockito.anyLong())).thenReturn(templateJoinVO);
|
||||||
|
|
||||||
KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class);
|
KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class);
|
||||||
|
|||||||
@ -16,6 +16,12 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.network.lb;
|
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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
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.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
|
import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
|
||||||
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
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.DomainRouterDao;
|
||||||
import com.cloud.vm.dao.NicDao;
|
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 {
|
public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements InternalLoadBalancerVMManager, InternalLoadBalancerVMService, VirtualMachineGuru {
|
||||||
static final private String InternalLbVmNamePrefix = "b";
|
static final private String InternalLbVmNamePrefix = "b";
|
||||||
|
|
||||||
@ -732,6 +733,70 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
|||||||
return internalLbVms;
|
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,
|
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,
|
final long svcOffId, final Long vpcId, final LinkedHashMap<Network, List<? extends NicProfile>> networks, final boolean startVm) throws ConcurrentOperationException,
|
||||||
InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException,
|
InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException,
|
||||||
@ -743,35 +808,6 @@ 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
|
// 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);
|
final List<HypervisorType> hypervisors = getHypervisors(dest, plan, null);
|
||||||
|
|
||||||
int allocateRetry = 0;
|
|
||||||
int startRetry = 0;
|
|
||||||
DomainRouterVO internalLbVm = null;
|
|
||||||
for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
|
|
||||||
final HypervisorType hType = iter.next();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
long userId = CallContext.current().getCallingUserId();
|
long userId = CallContext.current().getCallingUserId();
|
||||||
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
|
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
|
||||||
List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
|
List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
|
||||||
@ -780,16 +816,31 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internalLbVm =
|
int allocateRetry = 0;
|
||||||
new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId, VirtualMachineName.getSystemVmName(id, _instance, InternalLbVmNamePrefix),
|
int startRetry = 0;
|
||||||
template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN, false, false, VirtualMachine.Type.InternalLoadBalancerVm, vpcId);
|
DomainRouterVO internalLbVm = null;
|
||||||
internalLbVm.setRole(Role.INTERNAL_LB_VM);
|
for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
|
||||||
internalLbVm = _internalLbVmDao.persist(internalLbVm);
|
final HypervisorType hType = iter.next();
|
||||||
_itMgr.allocate(internalLbVm.getInstanceName(), template, routerOffering, networks, plan, null);
|
try {
|
||||||
internalLbVm = _internalLbVmDao.findById(internalLbVm.getId());
|
final long id = _internalLbVmDao.getNextInSequence(Long.class, "id");
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Creating the internal lb vm {} in datacenter {} with hypervisor type {}",
|
||||||
|
id, dest.getDataCenter(), hType);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
internalLbVm = deployInternalLbVmWithTemplates(internalLbVm, id, plan, internalLbProviderId, owner,
|
||||||
|
userId, vpcId, routerOffering, networks, templates);
|
||||||
} catch (final InsufficientCapacityException ex) {
|
} catch (final InsufficientCapacityException ex) {
|
||||||
if (allocateRetry < 2 && iter.hasNext()) {
|
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;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
throw ex;
|
throw ex;
|
||||||
@ -804,8 +855,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In
|
|||||||
break;
|
break;
|
||||||
} catch (final InsufficientCapacityException ex) {
|
} catch (final InsufficientCapacityException ex) {
|
||||||
if (startRetry < 2 && iter.hasNext()) {
|
if (startRetry < 2 && iter.hasNext()) {
|
||||||
logger.debug("Failed to start the Internal lb vm " + internalLbVm + " with hypervisor type " + hType + ", " +
|
logger.debug("Failed to start the Internal lb vm {} with hypervisor type {}, destroying it and recreating one more time", internalLbVm, hType);
|
||||||
"destroying it and recreating one more time");
|
|
||||||
// destroy the internal lb vm
|
// destroy the internal lb vm
|
||||||
destroyInternalLbVm(internalLbVm.getId(), _accountMgr.getSystemAccount(), User.UID_SYSTEM);
|
destroyInternalLbVm(internalLbVm.getId(), _accountMgr.getSystemAccount(), User.UID_SYSTEM);
|
||||||
continue;
|
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) {
|
if (template != null) {
|
||||||
vmResponse.setTemplateId(template.getUuid());
|
vmResponse.setTemplateId(template.getUuid());
|
||||||
vmResponse.setTemplateName(template.getName());
|
vmResponse.setTemplateName(template.getName());
|
||||||
|
vmResponse.setArch(template.getArch().getType());
|
||||||
}
|
}
|
||||||
vmResponse.setCreated(vm.getCreated());
|
vmResponse.setCreated(vm.getCreated());
|
||||||
vmResponse.setHypervisor(vm.getHypervisorType().getHypervisorDisplayName());
|
vmResponse.setHypervisor(vm.getHypervisorType().getHypervisorDisplayName());
|
||||||
|
|||||||
@ -1308,6 +1308,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Long userId = cmd.getUserId();
|
Long userId = cmd.getUserId();
|
||||||
Long userdataId = cmd.getUserdataId();
|
Long userdataId = cmd.getUserdataId();
|
||||||
Map<String, String> tags = cmd.getTags();
|
Map<String, String> tags = cmd.getTags();
|
||||||
|
final CPU.CPUArch arch = cmd.getArch();
|
||||||
|
|
||||||
boolean isAdmin = false;
|
boolean isAdmin = false;
|
||||||
boolean isRootAdmin = false;
|
boolean isRootAdmin = false;
|
||||||
@ -1535,8 +1536,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
|
|
||||||
Boolean isVnf = cmd.getVnf();
|
Boolean isVnf = cmd.getVnf();
|
||||||
if (isVnf != null) {
|
boolean templateJoinNeeded = isVnf != null || arch != null;
|
||||||
|
if (templateJoinNeeded) {
|
||||||
SearchBuilder<VMTemplateVO> templateSearch = _templateDao.createSearchBuilder();
|
SearchBuilder<VMTemplateVO> templateSearch = _templateDao.createSearchBuilder();
|
||||||
|
templateSearch.and("templateArch", templateSearch.entity().getArch(), Op.EQ);
|
||||||
templateSearch.and("templateTypeEQ", templateSearch.entity().getTemplateType(), Op.EQ);
|
templateSearch.and("templateTypeEQ", templateSearch.entity().getTemplateType(), Op.EQ);
|
||||||
templateSearch.and("templateTypeNEQ", templateSearch.entity().getTemplateType(), Op.NEQ);
|
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);
|
userVmSearchCriteria.setJoinParameters("vmTemplate", "templateTypeNEQ", TemplateType.VNF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (arch != null) {
|
||||||
|
userVmSearchCriteria.setJoinParameters("vmTemplate", "templateArch", arch);
|
||||||
|
}
|
||||||
|
|
||||||
if (isRootAdmin) {
|
if (isRootAdmin) {
|
||||||
if (podId != null) {
|
if (podId != null) {
|
||||||
@ -2366,6 +2372,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Long pageSize = cmd.getPageSizeVal();
|
Long pageSize = cmd.getPageSizeVal();
|
||||||
Hypervisor.HypervisorType hypervisorType = cmd.getHypervisor();
|
Hypervisor.HypervisorType hypervisorType = cmd.getHypervisor();
|
||||||
Long msId = cmd.getManagementServerId();
|
Long msId = cmd.getManagementServerId();
|
||||||
|
final CPU.CPUArch arch = cmd.getArch();
|
||||||
|
|
||||||
Filter searchFilter = new Filter(HostVO.class, "id", Boolean.TRUE, startIndex, pageSize);
|
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("resourceState", hostSearchBuilder.entity().getResourceState(), SearchCriteria.Op.EQ);
|
||||||
hostSearchBuilder.and("hypervisor_type", hostSearchBuilder.entity().getHypervisorType(), 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("mgmt_server_id", hostSearchBuilder.entity().getManagementServerId(), SearchCriteria.Op.EQ);
|
||||||
|
hostSearchBuilder.and("arch", hostSearchBuilder.entity().getArch(), SearchCriteria.Op.EQ);
|
||||||
|
|
||||||
if (keyword != null) {
|
if (keyword != null) {
|
||||||
hostSearchBuilder.and().op("keywordName", hostSearchBuilder.entity().getName(), SearchCriteria.Op.LIKE);
|
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);
|
Pair<List<HostVO>, Integer> uniqueHostPair = hostDao.searchAndCount(sc, searchFilter);
|
||||||
Integer count = uniqueHostPair.second();
|
Integer count = uniqueHostPair.second();
|
||||||
List<Long> hostIds = uniqueHostPair.first().stream().map(HostVO::getId).collect(Collectors.toList());
|
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(","))
|
final List<String> userDenyListedSettings = Stream.of(QueryService.UserVMDeniedDetails.value().split(","))
|
||||||
.map(item -> (item).trim())
|
.map(item -> (item).trim())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
userDenyListedSettings.addAll(QueryService.RootAdminOnlyVmSettings);
|
||||||
for (final String detail : userDenyListedSettings) {
|
for (final String detail : userDenyListedSettings) {
|
||||||
if (options.containsKey(detail)) {
|
if (options.containsKey(detail)) {
|
||||||
options.remove(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.IOTHREADS, Arrays.asList("enabled"));
|
||||||
options.put(VmDetailConstants.NIC_MULTIQUEUE_NUMBER, Collections.emptyList());
|
options.put(VmDetailConstants.NIC_MULTIQUEUE_NUMBER, Collections.emptyList());
|
||||||
options.put(VmDetailConstants.NIC_PACKED_VIRTQUEUES_ENABLED, Arrays.asList("true", "false"));
|
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)) {
|
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.NESTED_VIRTUALIZATION_FLAG, Arrays.asList("true", "false"));
|
||||||
options.put(VmDetailConstants.SVGA_VRAM_SIZE, Collections.emptyList());
|
options.put(VmDetailConstants.SVGA_VRAM_SIZE, Collections.emptyList());
|
||||||
options.put(VmDetailConstants.RAM_RESERVATION, 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.setZoneId(router.getDataCenterUuid());
|
||||||
routerResponse.setName(router.getName());
|
routerResponse.setName(router.getName());
|
||||||
routerResponse.setTemplateId(router.getTemplateUuid());
|
routerResponse.setTemplateId(router.getTemplateUuid());
|
||||||
|
routerResponse.setArch(router.getArch().getType());
|
||||||
VMTemplateVO template = ApiDBUtils.findTemplateById(router.getTemplateId());
|
VMTemplateVO template = ApiDBUtils.findTemplateById(router.getTemplateId());
|
||||||
if (template != null) {
|
if (template != null) {
|
||||||
routerResponse.setTemplateName(template.getName());
|
routerResponse.setTemplateName(template.getName());
|
||||||
|
|||||||
@ -188,6 +188,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||||||
userVmResponse.setInstanceName(userVm.getInstanceName());
|
userVmResponse.setInstanceName(userVm.getInstanceName());
|
||||||
userVmResponse.setHostId(userVm.getHostUuid());
|
userVmResponse.setHostId(userVm.getHostUuid());
|
||||||
userVmResponse.setHostName(userVm.getHostName());
|
userVmResponse.setHostName(userVm.getHostName());
|
||||||
|
userVmResponse.setArch(userVm.getArch());
|
||||||
}
|
}
|
||||||
if (userVm.getHostStatus() != null) {
|
if (userVm.getHostStatus() != null) {
|
||||||
userVmResponse.setHostControlState(ControlState.getControlState(userVm.getHostStatus(), userVm.getHostResourceState()).toString());
|
userVmResponse.setHostControlState(ControlState.getControlState(userVm.getHostStatus(), userVm.getHostResourceState()).toString());
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import javax.persistence.Enumerated;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.host.Status;
|
import com.cloud.host.Status;
|
||||||
import com.cloud.hypervisor.Hypervisor;
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
import com.cloud.network.Network.GuestType;
|
import com.cloud.network.Network.GuestType;
|
||||||
@ -38,6 +39,8 @@ import com.cloud.user.Account;
|
|||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.cloud.vm.VirtualMachine.State;
|
import com.cloud.vm.VirtualMachine.State;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.util.CPUArchConverter;
|
||||||
import org.apache.cloudstack.util.HypervisorTypeConverter;
|
import org.apache.cloudstack.util.HypervisorTypeConverter;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -143,6 +146,10 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
|
|||||||
@Convert(converter = HypervisorTypeConverter.class)
|
@Convert(converter = HypervisorTypeConverter.class)
|
||||||
private Hypervisor.HypervisorType hypervisorType;
|
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)
|
@Column(name = "template_id", updatable = true, nullable = true, length = 17)
|
||||||
private long templateId;
|
private long templateId;
|
||||||
|
|
||||||
@ -376,6 +383,10 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
|
|||||||
return hypervisorType;
|
return hypervisorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPU.CPUArch getArch() {
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getClusterId() {
|
public Long getClusterId() {
|
||||||
return clusterId;
|
return clusterId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -439,6 +439,9 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||||||
@Column(name = "delete_protection")
|
@Column(name = "delete_protection")
|
||||||
protected Boolean deleteProtection;
|
protected Boolean deleteProtection;
|
||||||
|
|
||||||
|
@Column(name = "arch")
|
||||||
|
protected String arch;
|
||||||
|
|
||||||
|
|
||||||
public UserVmJoinVO() {
|
public UserVmJoinVO() {
|
||||||
// Empty constructor
|
// Empty constructor
|
||||||
@ -977,4 +980,8 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
|
|||||||
public String getUserDataDetails() {
|
public String getUserDataDetails() {
|
||||||
return userDataDetails;
|
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.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
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.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
|
||||||
@ -82,9 +81,9 @@ import com.cloud.exception.InsufficientAddressCapacityException;
|
|||||||
import com.cloud.exception.InsufficientCapacityException;
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
import com.cloud.exception.OperationTimedoutException;
|
import com.cloud.exception.OperationTimedoutException;
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
import com.cloud.host.Host;
|
|
||||||
import com.cloud.host.Host.Type;
|
import com.cloud.host.Host.Type;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
|
import com.cloud.host.Status;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.info.ConsoleProxyConnectionInfo;
|
import com.cloud.info.ConsoleProxyConnectionInfo;
|
||||||
@ -111,10 +110,8 @@ import com.cloud.resource.ServerResource;
|
|||||||
import com.cloud.resource.UnableDeleteHostException;
|
import com.cloud.resource.UnableDeleteHostException;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.DataStoreRole;
|
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.storage.StoragePoolStatus;
|
import com.cloud.storage.StoragePoolStatus;
|
||||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
@ -281,9 +278,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
HostVO host = _hostDao.findById(agentId);
|
||||||
if (host.getType() == Type.ConsoleProxy) {
|
if (host.getType() == Type.ConsoleProxy) {
|
||||||
String name = host.getName();
|
String name = host.getName();
|
||||||
@ -465,7 +462,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
|
public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
|
||||||
try {
|
try {
|
||||||
ConsoleProxyVO proxy = consoleProxyDao.findById(proxyVmId);
|
ConsoleProxyVO proxy = consoleProxyDao.findById(proxyVmId);
|
||||||
if (proxy.getState() == VirtualMachine.State.Running) {
|
if (proxy.getState() == State.Running) {
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,7 +471,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy.getState() == VirtualMachine.State.Stopped) {
|
if (proxy.getState() == State.Stopped) {
|
||||||
virtualMachineManager.advanceStart(proxy.getUuid(), null, null);
|
virtualMachineManager.advanceStart(proxy.getUuid(), null, null);
|
||||||
proxy = consoleProxyDao.findById(proxy.getId());
|
proxy = consoleProxyDao.findById(proxy.getId());
|
||||||
return proxy;
|
return proxy;
|
||||||
@ -575,12 +572,13 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
}
|
}
|
||||||
|
|
||||||
HypervisorType availableHypervisor = resourceManager.getAvailableHypervisor(dataCenterId);
|
HypervisorType availableHypervisor = resourceManager.getAvailableHypervisor(dataCenterId);
|
||||||
VMTemplateVO template = vmTemplateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
|
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenterId, availableHypervisor,
|
||||||
if (template == null) {
|
ResourceManager.SystemVmPreferredArchitecture.valueIn(dataCenterId));
|
||||||
|
if (CollectionUtils.isEmpty(templates)) {
|
||||||
throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
|
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");
|
long proxyVmId = (Long)context.get("proxyVmId");
|
||||||
if (proxyVmId == 0) {
|
if (proxyVmId == 0) {
|
||||||
@ -673,7 +671,26 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
return defaultNetworks.get(0);
|
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");
|
long id = consoleProxyDao.getNextInSequence(Long.class, "id");
|
||||||
String name = VirtualMachineName.getConsoleProxyName(id, instance);
|
String name = VirtualMachineName.getConsoleProxyName(id, instance);
|
||||||
@ -702,18 +719,23 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
if (serviceOffering == null) {
|
if (serviceOffering == null) {
|
||||||
serviceOffering = serviceOfferingDao.findDefaultSystemOffering(ServiceOffering.consoleProxyDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
serviceOffering = serviceOfferingDao.findDefaultSystemOffering(ServiceOffering.consoleProxyDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
||||||
}
|
}
|
||||||
ConsoleProxyVO proxy =
|
ConsoleProxyVO proxy = null;
|
||||||
new ConsoleProxyVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
|
for (final Iterator<VMTemplateVO> templateIterator = templates.iterator(); templateIterator.hasNext();) {
|
||||||
systemAcct.getDomainId(), systemAcct.getId(), accountManager.getSystemUser().getId(), 0, serviceOffering.isOfferHA());
|
VMTemplateVO template = templateIterator.next();
|
||||||
proxy.setDynamicallyScalable(template.isDynamicallyScalable());
|
proxy = createOrUpdateConsoleProxy(proxy, dataCenterId, id, name, serviceOffering, template, systemAcct);
|
||||||
proxy.setLimitCpuUse(serviceOffering.getLimitCpuUse());
|
|
||||||
proxy = consoleProxyDao.persist(proxy);
|
|
||||||
try {
|
try {
|
||||||
virtualMachineManager.allocate(name, template, serviceOffering, networks, plan, null);
|
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) {
|
} catch (InsufficientCapacityException e) {
|
||||||
String message = String.format("Unable to allocate proxy [%s] on zone [%s] due to [%s].", proxy.toString(), dataCenterId, e.getMessage());
|
if (templateIterator.hasNext()) {
|
||||||
logger.warn(message, e);
|
logger.debug("Unable to allocate proxy {} with {} in {} due to [{}]. Retrying with another template", proxy, template, dc, e.getMessage(), e);
|
||||||
throw new CloudRuntimeException(message, e);
|
continue;
|
||||||
|
}
|
||||||
|
throw new CloudRuntimeException("Failed to allocate proxy [%s] in zone [%s] with available templates", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> context = new HashMap<>();
|
Map<String, Object> context = new HashMap<>();
|
||||||
@ -737,8 +759,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
updateConsoleProxyStatus(answer.getDetails(), answer.getProxyVmId());
|
updateConsoleProxyStatus(answer.getDetails(), answer.getProxyVmId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
|
public void handleAgentDisconnect(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);
|
HostVO host = hostDao.findById(agentId);
|
||||||
if (host.getType() == Type.ConsoleProxy) {
|
if (host.getType() == Type.ConsoleProxy) {
|
||||||
String name = host.getName();
|
String name = host.getName();
|
||||||
@ -789,8 +811,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<ConsoleProxyVO> l =
|
List<ConsoleProxyVO> l =
|
||||||
consoleProxyDao.getProxyListInStates(dcId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Stopping,
|
consoleProxyDao.getProxyListInStates(dcId, State.Starting, State.Running, State.Stopping,
|
||||||
VirtualMachine.State.Stopped, VirtualMachine.State.Migrating, VirtualMachine.State.Shutdown, VirtualMachine.State.Unknown);
|
State.Stopped, State.Migrating, State.Shutdown, State.Unknown);
|
||||||
|
|
||||||
String value = configurationDao.getValue(Config.ConsoleProxyLaunchMax.key());
|
String value = configurationDao.getValue(Config.ConsoleProxyLaunchMax.key());
|
||||||
int launchLimit = NumbersUtil.parseInt(value, 10);
|
int launchLimit = NumbersUtil.parseInt(value, 10);
|
||||||
@ -876,22 +898,15 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
}
|
}
|
||||||
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenter.getId());
|
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenter.getId());
|
||||||
if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
|
if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
|
||||||
VMTemplateVO template = vmTemplateDao.findSystemVMReadyTemplate(dataCenter.getId(), HypervisorType.Any);
|
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenter.getId(),
|
||||||
if (template == null) {
|
HypervisorType.Any, null);
|
||||||
|
if (CollectionUtils.isEmpty(templates)) {
|
||||||
if (logger.isDebugEnabled()) {
|
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);
|
logger.debug("System vm template is not ready at data center {}, wait until it is ready to launch console proxy vm", dataCenter);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TemplateDataStoreVO templateHostRef;
|
boolean useLocalStorage = BooleanUtils.toBoolean(ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenter.getId()));
|
||||||
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);
|
boolean hasDatacenterStoragePoolHostInfo = consoleProxyDao.hasDatacenterStoragePoolHostInfo(dataCenter.getId(), !useLocalStorage);
|
||||||
if (hasDatacenterStoragePoolHostInfo) {
|
if (hasDatacenterStoragePoolHostInfo) {
|
||||||
return true;
|
return true;
|
||||||
@ -900,11 +915,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
logger.debug("Primary storage is not ready, wait until it is ready to launch console proxy");
|
logger.debug("Primary storage is not ready, wait until it is ready to launch console proxy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Zone [{}] is ready, but console proxy template [{}] is not ready on secondary storage.", dataCenter, template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -912,9 +922,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
private boolean isZoneHostReady(ZoneHostInfo zoneHostInfo) {
|
private boolean isZoneHostReady(ZoneHostInfo zoneHostInfo) {
|
||||||
int expectedFlags;
|
int expectedFlags;
|
||||||
if (useStorageVm) {
|
if (useStorageVm) {
|
||||||
expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK;
|
expectedFlags = ZoneHostInfo.ROUTING_HOST_MASK;
|
||||||
} else {
|
} else {
|
||||||
expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ALL_HOST_MASK;
|
expectedFlags = ZoneHostInfo.ALL_HOST_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (zoneHostInfo.getFlags() & expectedFlags) == expectedFlags;
|
return (zoneHostInfo.getFlags() & expectedFlags) == expectedFlags;
|
||||||
@ -1093,7 +1103,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
proxy.setPrivateIpAddress(null);
|
proxy.setPrivateIpAddress(null);
|
||||||
consoleProxyDao.update(proxy.getId(), proxy);
|
consoleProxyDao.update(proxy.getId(), proxy);
|
||||||
consoleProxyDao.remove(vmId);
|
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) {
|
if (host != null) {
|
||||||
logger.debug("Removing host [{}] entry for proxy [{}].", host, proxy);
|
logger.debug("Removing host [{}] entry for proxy [{}].", host, proxy);
|
||||||
return hostDao.remove(host.getId());
|
return hostDao.remove(host.getId());
|
||||||
@ -1511,7 +1521,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
return false;
|
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 (l.size() > 0) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Zone {} has {} console proxy VM(s) in transition state", zone, l.size());
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
host.setType(com.cloud.host.Host.Type.ConsoleProxy);
|
host.setType(Type.ConsoleProxy);
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,7 +1594,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||||||
|
|
||||||
protected HostVO findConsoleProxyHostByName(String name) {
|
protected HostVO findConsoleProxyHostByName(String name) {
|
||||||
QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
|
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);
|
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||||
return sc.find();
|
return sc.find();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1788,8 +1788,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
if (ipv4 && Objects.isNull(startIP)) {
|
if (ipv4 && Objects.isNull(startIP)) {
|
||||||
throw new CloudRuntimeException("IPv4 address range needs to be provided");
|
throw new CloudRuntimeException("IPv4 address range needs to be provided");
|
||||||
}
|
}
|
||||||
if (ipv6 && Objects.isNull(startIPv6)) {
|
if (ipv6) {
|
||||||
throw new CloudRuntimeException("IPv6 address range needs to be provided");
|
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());
|
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) {
|
if (implementedNetwork == null || implementedNetwork.first() == null) {
|
||||||
logger.warn("Failed to provision the network " + network);
|
logger.warn("Failed to provision the network " + network);
|
||||||
}
|
}
|
||||||
Network implemented = implementedNetwork.second();
|
return 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;
|
|
||||||
} catch (ResourceUnavailableException ex) {
|
} catch (ResourceUnavailableException ex) {
|
||||||
logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
|
logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
|
||||||
CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network");
|
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());
|
Network updatedNetwork = getNetwork(network.getId());
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_UPDATE, updatedNetwork.getAccountId(), updatedNetwork.getDataCenterId(), updatedNetwork.getId(),
|
UsageEventUtils.publishNetworkUpdate(updatedNetwork);
|
||||||
updatedNetwork.getName(), updatedNetwork.getNetworkOfferingId(), null, updatedNetwork.getState().name(), Network.class.getName(), updatedNetwork.getUuid(), true);
|
|
||||||
return updatedNetwork;
|
return updatedNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,6 @@ import java.util.Map;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
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.api.ApiConstants;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
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.network.router.deployment.RouterDeploymentDefinition;
|
||||||
import org.apache.cloudstack.utils.CloudStackVersion;
|
import org.apache.cloudstack.utils.CloudStackVersion;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
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.RedundantState;
|
||||||
import com.cloud.network.router.VirtualRouter.Role;
|
import com.cloud.network.router.VirtualRouter.Role;
|
||||||
import com.cloud.network.rules.LbStickinessMethod;
|
import com.cloud.network.rules.LbStickinessMethod;
|
||||||
|
import com.cloud.network.vpc.dao.VpcDao;
|
||||||
import com.cloud.network.vpn.Site2SiteVpnManager;
|
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||||
import com.cloud.offering.NetworkOffering;
|
import com.cloud.offering.NetworkOffering;
|
||||||
import com.cloud.resource.ResourceManager;
|
import com.cloud.resource.ResourceManager;
|
||||||
@ -104,6 +103,7 @@ import com.cloud.user.dao.UserDao;
|
|||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.utils.net.NetUtils;
|
import com.cloud.utils.net.NetUtils;
|
||||||
|
import com.cloud.utils.validation.ChecksumUtil;
|
||||||
import com.cloud.vm.DomainRouterVO;
|
import com.cloud.vm.DomainRouterVO;
|
||||||
import com.cloud.vm.Nic;
|
import com.cloud.vm.Nic;
|
||||||
import com.cloud.vm.NicProfile;
|
import com.cloud.vm.NicProfile;
|
||||||
@ -498,18 +498,77 @@ public class NetworkHelperImpl implements NetworkHelper {
|
|||||||
return templateName;
|
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
|
@Override
|
||||||
public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
|
public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
|
||||||
throws InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {
|
throws InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {
|
||||||
|
|
||||||
final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
|
final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
|
||||||
|
final boolean offerHA = routerOffering.isOfferHA();
|
||||||
final Account owner = routerDeploymentDefinition.getOwner();
|
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.
|
// Router is the network element, we don't know the hypervisor type yet.
|
||||||
// Try to allocate the domR twice using diff hypervisors, and when
|
// Try to allocate the domR twice using diff hypervisors, and when
|
||||||
// failed both times, throw the exception up
|
// failed both times, throw the exception up
|
||||||
final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);
|
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;
|
DomainRouterVO router = null;
|
||||||
for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
|
for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
|
||||||
final HypervisorType hType = iter.next();
|
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()
|
logger.debug(String.format("Allocating the VR with id=%s in datacenter %s with the hypervisor type %s", id, routerDeploymentDefinition.getDest()
|
||||||
.getDataCenter(), hType));
|
.getDataCenter(), hType));
|
||||||
}
|
}
|
||||||
|
final long zoneId = routerDeploymentDefinition.getDest().getDataCenter().getId();
|
||||||
final String templateName = retrieveTemplateName(hType, routerDeploymentDefinition.getDest().getDataCenter().getId());
|
final String templateName = retrieveTemplateName(hType, zoneId);
|
||||||
final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);
|
final String preferredArch = ResourceManager.SystemVmPreferredArchitecture.valueIn(zoneId);
|
||||||
|
final List<VMTemplateVO> templates = _templateDao.findRoutingTemplates(hType, templateName,
|
||||||
if (template == null) {
|
preferredArch);
|
||||||
logger.debug(hType + " won't support system vm, skip it");
|
if (CollectionUtils.isEmpty(templates)) {
|
||||||
|
logger.debug("{} won't support system vm, skip it", hType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
router = deployRouterWithTemplates(router, id, routerDeploymentDefinition, owner, userId,
|
||||||
final boolean offerHA = routerOffering.isOfferHA();
|
routerOffering, offerHA, vpcId, templates);
|
||||||
|
|
||||||
// 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());
|
|
||||||
} catch (final InsufficientCapacityException ex) {
|
} catch (final InsufficientCapacityException ex) {
|
||||||
if (iter.hasNext()) {
|
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;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
throw ex;
|
throw ex;
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
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.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||||
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang.ObjectUtils;
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
@ -175,6 +172,7 @@ import com.cloud.storage.dao.VMTemplateDao;
|
|||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
|
import com.cloud.utils.StringUtils;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.UriUtils;
|
import com.cloud.utils.UriUtils;
|
||||||
import com.cloud.utils.component.Manager;
|
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.SSHCmdHelper;
|
||||||
import com.cloud.utils.ssh.SshException;
|
import com.cloud.utils.ssh.SshException;
|
||||||
import com.cloud.vm.UserVmManager;
|
import com.cloud.vm.UserVmManager;
|
||||||
import com.cloud.utils.StringUtils;
|
|
||||||
import com.cloud.vm.VMInstanceVO;
|
import com.cloud.vm.VMInstanceVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.cloud.vm.VirtualMachine.State;
|
import com.cloud.vm.VirtualMachine.State;
|
||||||
@ -1204,6 +1201,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arch != null) {
|
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());
|
cluster.setArch(arch.getType());
|
||||||
doUpdate = true;
|
doUpdate = true;
|
||||||
}
|
}
|
||||||
@ -3276,12 +3279,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HypervisorType> listAvailHypervisorInZone(final Long zoneId) {
|
public List<HypervisorType> listAvailHypervisorInZone(final Long zoneId) {
|
||||||
List<VMTemplateVO> systemVMTemplates = _templateDao.listAllReadySystemVMTemplates(zoneId);
|
final SearchCriteria<String> sc = _hypervisorsInDC.create();
|
||||||
final Set<HypervisorType> hypervisors = new HashSet<>();
|
if (zoneId != null) {
|
||||||
for (final VMTemplateVO systemVMTemplate : systemVMTemplates) {
|
sc.setParameters("dataCenter", zoneId);
|
||||||
hypervisors.add(systemVMTemplate.getHypervisorType());
|
|
||||||
}
|
}
|
||||||
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
|
@Override
|
||||||
@ -3546,6 +3553,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
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.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import com.cloud.cpu.CPU;
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||||
@ -674,6 +673,7 @@ import com.cloud.configuration.Config;
|
|||||||
import com.cloud.configuration.ConfigurationManagerImpl;
|
import com.cloud.configuration.ConfigurationManagerImpl;
|
||||||
import com.cloud.consoleproxy.ConsoleProxyManagementState;
|
import com.cloud.consoleproxy.ConsoleProxyManagementState;
|
||||||
import com.cloud.consoleproxy.ConsoleProxyManager;
|
import com.cloud.consoleproxy.ConsoleProxyManager;
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.AccountVlanMapVO;
|
import com.cloud.dc.AccountVlanMapVO;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
@ -1274,6 +1274,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
final Object clusterType = cmd.getClusterType();
|
final Object clusterType = cmd.getClusterType();
|
||||||
final Object allocationState = cmd.getAllocationState();
|
final Object allocationState = cmd.getAllocationState();
|
||||||
final String keyword = cmd.getKeyword();
|
final String keyword = cmd.getKeyword();
|
||||||
|
final CPU.CPUArch arch = cmd.getArch();
|
||||||
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
|
||||||
|
|
||||||
final Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
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("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||||
sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ);
|
sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ);
|
||||||
sb.and("allocationState", sb.entity().getAllocationState(), 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();
|
final SearchCriteria<ClusterVO> sc = sb.create();
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
@ -1325,6 +1327,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arch != null) {
|
||||||
|
sc.setParameters("arch", arch);
|
||||||
|
}
|
||||||
|
|
||||||
final Pair<List<ClusterVO>, Integer> result = _clusterDao.searchAndCount(sc, searchFilter);
|
final Pair<List<ClusterVO>, Integer> result = _clusterDao.searchAndCount(sc, searchFilter);
|
||||||
return new Pair<>(result.first(), result.second());
|
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 podId = cmd.getPodId();
|
||||||
final Long hostId = cmd.getHostId();
|
final Long hostId = cmd.getHostId();
|
||||||
final Long storageId = cmd.getStorageId();
|
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 Filter searchFilter = new Filter(VMInstanceVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||||
final SearchBuilder<VMInstanceVO> sb = _vmInstanceDao.createSearchBuilder();
|
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();
|
final SearchCriteria<VMInstanceVO> sc = sb.create();
|
||||||
|
|
||||||
if (keyword != null) {
|
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);
|
final Pair<List<VMInstanceVO>, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter);
|
||||||
return new Pair<>(result.first(), result.second());
|
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.ConfigurationManager;
|
||||||
import com.cloud.configuration.ConfigurationManagerImpl;
|
import com.cloud.configuration.ConfigurationManagerImpl;
|
||||||
import com.cloud.configuration.Resource.ResourceType;
|
import com.cloud.configuration.Resource.ResourceType;
|
||||||
|
import com.cloud.cpu.CPU;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.VsphereStoragePolicyVO;
|
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);
|
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) {
|
private void registerSystemVmTemplateOnFirstNfsStore(Long zoneId, String providerName, String url, DataStore store) {
|
||||||
if (DataStoreProvider.NFS_IMAGE.equals(providerName) && zoneId != null) {
|
if (DataStoreProvider.NFS_IMAGE.equals(providerName) && zoneId != null) {
|
||||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||||
@Override
|
@Override
|
||||||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||||
List<ImageStoreVO> stores = _imageStoreDao.listAllStoresInZone(zoneId, providerName, DataStoreRole.Image);
|
List<ImageStoreVO> stores = _imageStoreDao.listAllStoresInZoneExceptId(zoneId, providerName,
|
||||||
stores = stores.stream().filter(str -> str.getId() != store.getId()).collect(Collectors.toList());
|
DataStoreRole.Image, store.getId());
|
||||||
// Check if it's the only/first store in the zone
|
if (CollectionUtils.isEmpty(stores)) {
|
||||||
if (stores.size() == 0) {
|
List<Pair<HypervisorType, CPU.CPUArch>> hypervisorTypes =
|
||||||
List<HypervisorType> hypervisorTypes = _clusterDao.getAvailableHypervisorInZone(zoneId);
|
_clusterDao.listDistinctHypervisorsArchAcrossClusters(zoneId);
|
||||||
Set<HypervisorType> hypSet = new HashSet<>(hypervisorTypes);
|
|
||||||
TransactionLegacy txn = TransactionLegacy.open("AutomaticTemplateRegister");
|
TransactionLegacy txn = TransactionLegacy.open("AutomaticTemplateRegister");
|
||||||
SystemVmTemplateRegistration systemVmTemplateRegistration = new SystemVmTemplateRegistration();
|
SystemVmTemplateRegistration systemVmTemplateRegistration = new SystemVmTemplateRegistration();
|
||||||
String filePath = null;
|
String filePath = null;
|
||||||
@ -3606,40 +3639,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
Pair<String, Long> storeUrlAndId = new Pair<>(url, store.getId());
|
Pair<String, Long> storeUrlAndId = new Pair<>(url, store.getId());
|
||||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId());
|
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId());
|
||||||
for (HypervisorType hypervisorType : hypSet) {
|
for (Pair<HypervisorType, CPU.CPUArch> hypervisorArchType : hypervisorTypes) {
|
||||||
try {
|
try {
|
||||||
if (HypervisorType.Simulator == hypervisorType) {
|
registerSystemVmTemplateForHypervisorArch(hypervisorArchType.first(),
|
||||||
continue;
|
hypervisorArchType.second(), zoneId, url, store,
|
||||||
}
|
systemVmTemplateRegistration, filePath, storeUrlAndId, nfsVersion);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} catch (CloudRuntimeException e) {
|
} catch (CloudRuntimeException e) {
|
||||||
SystemVmTemplateRegistration.unmountStore(filePath);
|
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) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -243,7 +244,11 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||||||
|
|
||||||
List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
|
List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
|
||||||
for (VMTemplateVO template : systemvmTmplts) {
|
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");
|
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(","))
|
final List<String> userDenyListedSettings = Stream.of(QueryService.UserVMDeniedDetails.value().split(","))
|
||||||
.map(item -> (item).trim())
|
.map(item -> (item).trim())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
userDenyListedSettings.addAll(QueryService.RootAdminOnlyVmSettings);
|
||||||
final List<String> userReadOnlySettings = Stream.of(QueryService.UserVMReadOnlyDetails.value().split(","))
|
final List<String> userReadOnlySettings = Stream.of(QueryService.UserVMReadOnlyDetails.value().split(","))
|
||||||
.map(item -> (item).trim())
|
.map(item -> (item).trim())
|
||||||
.collect(Collectors.toList());
|
.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.
|
// under the License.
|
||||||
package com.cloud.network.router;
|
package com.cloud.network.router;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import static org.junit.Assert.assertEquals;
|
||||||
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.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.lenient;
|
import static org.mockito.Mockito.lenient;
|
||||||
import static org.mockito.Mockito.mock;
|
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.verify;
|
||||||
import static org.mockito.Mockito.when;
|
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)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class NetworkHelperImplTest {
|
public class NetworkHelperImplTest {
|
||||||
@ -54,6 +66,9 @@ public class NetworkHelperImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
protected AgentManager agentManager;
|
protected AgentManager agentManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
DomainRouterDao routerDao;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
protected NetworkHelperImpl nwHelper = new NetworkHelperImpl();
|
protected NetworkHelperImpl nwHelper = new NetworkHelperImpl();
|
||||||
@Mock
|
@Mock
|
||||||
@ -65,10 +80,27 @@ public class NetworkHelperImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
NicDao nicDao;
|
NicDao nicDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RouterDeploymentDefinition routerDeploymentDefinition;
|
||||||
|
@Mock
|
||||||
|
private VirtualRouterProvider virtualProvider;
|
||||||
|
@Mock
|
||||||
|
private Account owner;
|
||||||
|
@Mock
|
||||||
|
private ServiceOfferingVO routerOffering;
|
||||||
|
@Mock
|
||||||
|
private VMTemplateVO template;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
nwHelper._networkDao = networkDao;
|
nwHelper._networkDao = networkDao;
|
||||||
nwHelper._networkModel = networkModel;
|
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)
|
@Test(expected=ResourceUnavailableException.class)
|
||||||
@ -83,7 +115,7 @@ public class NetworkHelperImplTest {
|
|||||||
nwHelperUT.sendCommandsToRouter(vr, null);
|
nwHelperUT.sendCommandsToRouter(vr, null);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
verify(this.agentManager, times(0)).send((Long) ArgumentMatchers.any(), (Command) ArgumentMatchers.any());
|
verify(this.agentManager, times(0)).send((Long) any(), (Command) any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -187,4 +219,53 @@ public class NetworkHelperImplTest {
|
|||||||
verify(answer1, times(0)).getResult();
|
verify(answer1, times(0)).getResult();
|
||||||
assertFalse(result);
|
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.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -618,6 +619,25 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
|||||||
return defaultNetworks.get(0);
|
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) {
|
protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
|
||||||
DataStore secStore = _dataStoreMgr.getImageStoreWithFreeCapacity(dataCenterId);
|
DataStore secStore = _dataStoreMgr.getImageStoreWithFreeCapacity(dataCenterId);
|
||||||
if (secStore == null) {
|
if (secStore == null) {
|
||||||
@ -657,28 +677,33 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
|||||||
}
|
}
|
||||||
|
|
||||||
HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
|
HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
|
||||||
VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
|
List<VMTemplateVO> templates = _templateDao.findSystemVMReadyTemplates(dataCenterId, availableHypervisor,
|
||||||
if (template == null) {
|
ResourceManager.SystemVmPreferredArchitecture.valueIn(dataCenterId));
|
||||||
throw new CloudRuntimeException(String.format("Unable to find the system templates or it was not downloaded in %s.", dc.toString()));
|
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;
|
ServiceOfferingVO serviceOffering = _serviceOffering;
|
||||||
if (serviceOffering == null) {
|
if (serviceOffering == null) {
|
||||||
serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.ssvmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.ssvmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
||||||
}
|
}
|
||||||
SecondaryStorageVmVO secStorageVm =
|
SecondaryStorageVmVO secStorageVm = null;
|
||||||
new SecondaryStorageVmVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
|
for (final Iterator<VMTemplateVO> templateIterator = templates.iterator(); templateIterator.hasNext();) {
|
||||||
systemAcct.getDomainId(), systemAcct.getId(), _accountMgr.getSystemUser().getId(), role, serviceOffering.isOfferHA());
|
VMTemplateVO template = templateIterator.next();
|
||||||
secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
|
secStorageVm = createOrUpdateSecondaryStorageVm(secStorageVm, dataCenterId, id, name, serviceOffering,
|
||||||
secStorageVm.setLimitCpuUse(serviceOffering.getLimitCpuUse());
|
template, systemAcct, role);
|
||||||
secStorageVm = _secStorageVmDao.persist(secStorageVm);
|
|
||||||
try {
|
try {
|
||||||
_itMgr.allocate(name, template, serviceOffering, networks, plan, null);
|
_itMgr.allocate(name, template, serviceOffering, networks, plan, template.getHypervisorType());
|
||||||
secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
|
secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
|
||||||
|
_itMgr.checkDeploymentPlan(secStorageVm, template, serviceOffering, systemAcct, plan);
|
||||||
|
break;
|
||||||
} catch (InsufficientCapacityException e) {
|
} catch (InsufficientCapacityException e) {
|
||||||
String errorMessage = String.format("Unable to allocate secondary storage VM [%s] due to [%s].", name, e.getMessage());
|
if (templateIterator.hasNext()) {
|
||||||
logger.warn(errorMessage, e);
|
logger.debug("Unable to allocate secondary storage {} with {} due to [{}]. Retrying with another template", secStorageVm, template, e.getMessage(), e);
|
||||||
throw new CloudRuntimeException(errorMessage, 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<>();
|
Map<String, Object> context = new HashMap<>();
|
||||||
@ -820,8 +845,9 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
|||||||
}
|
}
|
||||||
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
|
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
|
||||||
if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
|
if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
|
||||||
VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
|
List<VMTemplateVO> templates = _templateDao.findSystemVMReadyTemplates(dataCenterId,
|
||||||
if (template == null) {
|
HypervisorType.Any, null);
|
||||||
|
if (CollectionUtils.isEmpty(templates)) {
|
||||||
if (logger.isDebugEnabled()) {
|
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));
|
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;
|
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 useLocalStorage = BooleanUtils.toBoolean(ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
|
||||||
boolean hasStoragePoolHostInfo = _storagePoolHostDao.hasDatacenterStoragePoolHostInfo(dataCenterId, !useLocalStorage);
|
boolean hasStoragePoolHostInfo = _storagePoolHostDao.hasDatacenterStoragePoolHostInfo(dataCenterId, !useLocalStorage);
|
||||||
if (hasStoragePoolHostInfo) {
|
if (hasStoragePoolHostInfo) {
|
||||||
|
|||||||
@ -16,39 +16,69 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.secondarystorage;
|
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.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
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.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;
|
import com.google.common.net.InetAddresses;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class SecondaryStorageManagerImplTest {
|
public class SecondaryStorageManagerImplTest {
|
||||||
private final SecureRandom secureRandom = new SecureRandom();
|
private final SecureRandom secureRandom = new SecureRandom();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private SecondaryStorageVmDao secStorageVmDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AccountManager accountManager;
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private SecondaryStorageManagerImpl secondaryStorageManager;
|
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) {
|
private List<DataStore> mockDataStoresForTestAddSecondaryStorageServerAddressToBuffer(List<String> addresses) {
|
||||||
List<DataStore> dataStores = new ArrayList<>();
|
List<DataStore> dataStores = new ArrayList<>();
|
||||||
for (String address: addresses) {
|
for (String address: addresses) {
|
||||||
DataStore dataStore = Mockito.mock(DataStore.class);
|
DataStore dataStore = Mockito.mock(DataStore.class);
|
||||||
DataStoreTO dataStoreTO = Mockito.mock(DataStoreTO.class);
|
DataStoreTO dataStoreTO = Mockito.mock(DataStoreTO.class);
|
||||||
Mockito.when(dataStoreTO.getUrl()).thenReturn(NetUtils.isValidIp4(address) ? String.format("http://%s", address) : address);
|
when(dataStoreTO.getUrl()).thenReturn(NetUtils.isValidIp4(address) ? String.format("http://%s", address) : address);
|
||||||
Mockito.when(dataStore.getTO()).thenReturn(dataStoreTO);
|
when(dataStore.getTO()).thenReturn(dataStoreTO);
|
||||||
dataStores.add(dataStore);
|
dataStores.add(dataStore);
|
||||||
}
|
}
|
||||||
return dataStores;
|
return dataStores;
|
||||||
@ -60,7 +90,7 @@ public class SecondaryStorageManagerImplTest {
|
|||||||
secondaryStorageManager.addSecondaryStorageServerAddressToBuffer(builder, dataStores, "VM");
|
secondaryStorageManager.addSecondaryStorageServerAddressToBuffer(builder, dataStores, "VM");
|
||||||
String result = builder.toString();
|
String result = builder.toString();
|
||||||
result = result.contains("=") ? result.split("=")[1] : null;
|
result = result.contains("=") ? result.split("=")[1] : null;
|
||||||
Assert.assertEquals(expected, result);
|
assertEquals(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -86,4 +116,55 @@ public class SecondaryStorageManagerImplTest {
|
|||||||
List<String> addresses = List.of(randomIp1, "garbage", randomIp2);
|
List<String> addresses = List.of(randomIp1, "garbage", randomIp2);
|
||||||
runAddSecondaryStorageServerAddressToBufferTest(addresses, StringUtils.join(List.of(randomIp1, 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,
|
`cpus` int(10) unsigned,
|
||||||
`speed` int(10) unsigned,
|
`speed` int(10) unsigned,
|
||||||
`ram` bigint 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',
|
`capabilities` varchar(255) COMMENT 'host capabilities in comma separated list',
|
||||||
`vm_id` bigint unsigned,
|
`vm_id` bigint unsigned,
|
||||||
`resource` varchar(255) DEFAULT NULL COMMENT 'If it is a local resource, this is the class name',
|
`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 import x509
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
from OpenSSL.crypto import FILETYPE_PEM, verify, X509
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
|
|
||||||
PUBKEY_VERIFY=True
|
|
||||||
try:
|
|
||||||
from OpenSSL.crypto import load_publickey
|
|
||||||
except ImportError:
|
|
||||||
PUBKEY_VERIFY=False
|
|
||||||
|
|
||||||
|
|
||||||
class TestCARootProvider(cloudstackTestCase):
|
class TestCARootProvider(cloudstackTestCase):
|
||||||
@ -52,6 +46,20 @@ class TestCARootProvider(cloudstackTestCase):
|
|||||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
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):
|
def setUp(self):
|
||||||
self.apiclient = self.testClient.getApiClient()
|
self.apiclient = self.testClient.getApiClient()
|
||||||
self.dbclient = self.testClient.getDbConnection()
|
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)])
|
self.assertTrue(address in [str(x) for x in altNames.value.get_values_for_type(x509.IPAddress)])
|
||||||
|
|
||||||
# Validate certificate against CA public key
|
# 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())
|
caCert = x509.load_pem_x509_certificate(self.getCaCertificate().encode(), default_backend())
|
||||||
x = X509()
|
self.verifySignature(caCert, cert)
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
|
@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')
|
self.assertEqual(cert.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[0].value, 'v-1-VM')
|
||||||
|
|
||||||
# Validate certificate against CA public key
|
# 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())
|
caCert = x509.load_pem_x509_certificate(self.getCaCertificate().encode(), default_backend())
|
||||||
x = X509()
|
self.verifySignature(caCert, cert)
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
|
@attr(tags=['advanced', 'simulator', 'basic', 'sg'], required_hardware=False)
|
||||||
|
|||||||
@ -23,11 +23,12 @@ import logging
|
|||||||
import time
|
import time
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
|
|
||||||
|
from marvin.codes import FAILED
|
||||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||||
from marvin.cloudstackAPI import (migrateSystemVm, listRouters, listSystemVms)
|
from marvin.cloudstackAPI import (migrateSystemVm, listRouters, listSystemVms)
|
||||||
from marvin.lib.base import (Cluster, Configurations, Host, Network, NetworkOffering, ServiceOffering, VirtualMachine,
|
from marvin.lib.base import (Cluster, Configurations, Host, Network, NetworkOffering, ServiceOffering, VirtualMachine,
|
||||||
Zone)
|
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.lib.utils import wait_until
|
||||||
from marvin import jsonHelper
|
from marvin import jsonHelper
|
||||||
from nose.plugins.attrib import attr
|
from nose.plugins.attrib import attr
|
||||||
@ -43,7 +44,15 @@ class TestClusterDRS(cloudstackTestCase):
|
|||||||
|
|
||||||
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||||
cls.zone = Zone(zone.__dict__)
|
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._cleanup = []
|
||||||
|
|
||||||
cls.logger = logging.getLogger("TestClusterDRS")
|
cls.logger = logging.getLogger("TestClusterDRS")
|
||||||
|
|||||||
@ -74,7 +74,6 @@ class TestData(object):
|
|||||||
"listApis": "allow",
|
"listApis": "allow",
|
||||||
"listAccounts": "allow",
|
"listAccounts": "allow",
|
||||||
"listClusters": "deny",
|
"listClusters": "deny",
|
||||||
"*VmwareDc*": "allow",
|
|
||||||
"*VM*": "allow",
|
"*VM*": "allow",
|
||||||
"*Host*": "deny"
|
"*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