Skip to content

Commit 3e7f21a

Browse files
shwstppryadvr
andauthored
vm-import: fix stopped managed vms listing in unmanaged instances (#7606)
Signed-off-by: Abhishek Kumar <[email protected]> Co-authored-by: Rohit Yadav <[email protected]>
1 parent fb3a2ec commit 3e7f21a

File tree

4 files changed

+80
-78
lines changed

4 files changed

+80
-78
lines changed

engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,5 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
164164

165165
void updateSystemVmTemplateId(long templateId, Hypervisor.HypervisorType hypervisorType);
166166

167-
List<VMInstanceVO> listByHostOrLastHostOrHostPod(long hostId, long podId);
167+
List<VMInstanceVO> listByHostOrLastHostOrHostPod(List<Long> hostIds, long podId);
168168
}

engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -989,19 +989,19 @@ public void updateSystemVmTemplateId(long templateId, Hypervisor.HypervisorType
989989
}
990990

991991
@Override
992-
public List<VMInstanceVO> listByHostOrLastHostOrHostPod(long hostId, long podId) {
992+
public List<VMInstanceVO> listByHostOrLastHostOrHostPod(List<Long> hostIds, long podId) {
993993
SearchBuilder<VMInstanceVO> sb = createSearchBuilder();
994-
sb.or().op("hostId", sb.entity().getHostId(), Op.EQ);
995-
sb.or("lastHostId", sb.entity().getLastHostId(), Op.EQ);
996-
sb.and().op("hostIdNull", sb.entity().getHostId(), SearchCriteria.Op.NULL);
994+
sb.and().op("hostId", sb.entity().getHostId(), Op.IN);
995+
sb.or("lastHostId", sb.entity().getLastHostId(), Op.IN);
996+
sb.or().op("hostIdNull", sb.entity().getHostId(), SearchCriteria.Op.NULL);
997997
sb.and("lastHostIdNull", sb.entity().getHostId(), SearchCriteria.Op.NULL);
998998
sb.and("podId", sb.entity().getPodIdToDeployIn(), Op.EQ);
999999
sb.cp();
10001000
sb.cp();
10011001
sb.done();
10021002
SearchCriteria<VMInstanceVO> sc = sb.create();
1003-
sc.setParameters("hostId", String.valueOf(hostId));
1004-
sc.setParameters("lastHostId", String.valueOf(hostId));
1003+
sc.setParameters("hostId", hostIds.toArray());
1004+
sc.setParameters("lastHostId", hostIds.toArray());
10051005
sc.setParameters("podId", String.valueOf(podId));
10061006
return listBy(sc);
10071007
}

server/src/main/java/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
import com.cloud.exception.InvalidParameterValueException;
196196
import com.cloud.exception.PermissionDeniedException;
197197
import com.cloud.ha.HighAvailabilityManager;
198+
import com.cloud.host.Host;
198199
import com.cloud.hypervisor.Hypervisor;
199200
import com.cloud.hypervisor.Hypervisor.HypervisorType;
200201
import com.cloud.network.RouterHealthCheckResult;
@@ -1076,7 +1077,12 @@ private Pair<List<UserVmJoinVO>, Integer> searchForUserVMsInternal(ListVMsCmd cm
10761077
sb.and("stateNIN", sb.entity().getState(), SearchCriteria.Op.NIN);
10771078
sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
10781079
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
1079-
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
1080+
if (clusterId != null) {
1081+
sb.and().op("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
1082+
sb.or("clusterHostId", sb.entity().getHostId(), Op.IN);
1083+
sb.or("clusterLastHostId", sb.entity().getLastHostId(), Op.IN);
1084+
sb.cp();
1085+
}
10801086
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
10811087
sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ);
10821088
sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
@@ -1272,6 +1278,10 @@ private Pair<List<UserVmJoinVO>, Integer> searchForUserVMsInternal(ListVMsCmd cm
12721278

12731279
if (clusterId != null) {
12741280
sc.setParameters("clusterId", clusterId);
1281+
List<HostJoinVO> hosts = _hostJoinDao.findByClusterId((Long)clusterId, Host.Type.Routing);
1282+
List<Long> hostIds = hosts.stream().map(HostJoinVO::getId).collect(Collectors.toList());
1283+
sc.setParameters("clusterHostId", hostIds.toArray());
1284+
sc.setParameters("clusterLastHostId", hostIds.toArray());
12751285
}
12761286

12771287
if (hostId != null) {

server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java

Lines changed: 62 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,11 @@ private List<String> getAdditionalNameFilters(Cluster cluster) {
363363
return additionalNameFilter;
364364
}
365365

366-
private List<String> getHostManagedVms(Host host) {
367-
List<VMInstanceVO> instances = vmDao.listByHostOrLastHostOrHostPod(host.getId(), host.getPodId());
366+
private List<String> getHostsManagedVms(List<HostVO> hosts) {
367+
if (CollectionUtils.isEmpty(hosts)) {
368+
return new ArrayList<>();
369+
}
370+
List<VMInstanceVO> instances = vmDao.listByHostOrLastHostOrHostPod(hosts.stream().map(HostVO::getId).collect(Collectors.toList()), hosts.get(0).getPodId());
368371
List<String> managedVms = instances.stream().map(VMInstanceVO::getInstanceName).collect(Collectors.toList());
369372
return managedVms;
370373
}
@@ -1035,6 +1038,24 @@ private UserVm importVirtualMachineInternal(final UnmanagedInstanceTO unmanagedI
10351038
return userVm;
10361039
}
10371040

1041+
private HashMap<String, UnmanagedInstanceTO> getUnmanagedInstancesForHost(HostVO host, String instanceName, List<String> managedVms) {
1042+
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>();
1043+
if (host.isInMaintenanceStates()) {
1044+
return unmanagedInstances;
1045+
}
1046+
1047+
GetUnmanagedInstancesCommand command = new GetUnmanagedInstancesCommand();
1048+
command.setInstanceName(instanceName);
1049+
command.setManagedInstancesNames(managedVms);
1050+
Answer answer = agentManager.easySend(host.getId(), command);
1051+
if (!(answer instanceof GetUnmanagedInstancesAnswer)) {
1052+
return unmanagedInstances;
1053+
}
1054+
GetUnmanagedInstancesAnswer unmanagedInstancesAnswer = (GetUnmanagedInstancesAnswer) answer;
1055+
unmanagedInstances = unmanagedInstancesAnswer.getUnmanagedInstances();
1056+
return unmanagedInstances;
1057+
}
1058+
10381059
@Override
10391060
public ListResponse<UnmanagedInstanceResponse> listUnmanagedInstances(ListUnmanagedInstancesCmd cmd) {
10401061
final Account caller = CallContext.current().getCallingAccount();
@@ -1058,24 +1079,11 @@ public ListResponse<UnmanagedInstanceResponse> listUnmanagedInstances(ListUnmana
10581079
}
10591080
List<HostVO> hosts = resourceManager.listHostsInClusterByStatus(clusterId, Status.Up);
10601081
List<String> additionalNameFilters = getAdditionalNameFilters(cluster);
1082+
List<String> managedVms = new ArrayList<>(additionalNameFilters);
1083+
managedVms.addAll(getHostsManagedVms(hosts));
10611084
List<UnmanagedInstanceResponse> responses = new ArrayList<>();
10621085
for (HostVO host : hosts) {
1063-
if (host.isInMaintenanceStates()) {
1064-
continue;
1065-
}
1066-
List<String> managedVms = new ArrayList<>();
1067-
managedVms.addAll(additionalNameFilters);
1068-
managedVms.addAll(getHostManagedVms(host));
1069-
1070-
GetUnmanagedInstancesCommand command = new GetUnmanagedInstancesCommand();
1071-
command.setInstanceName(cmd.getName());
1072-
command.setManagedInstancesNames(managedVms);
1073-
Answer answer = agentManager.easySend(host.getId(), command);
1074-
if (!(answer instanceof GetUnmanagedInstancesAnswer)) {
1075-
continue;
1076-
}
1077-
GetUnmanagedInstancesAnswer unmanagedInstancesAnswer = (GetUnmanagedInstancesAnswer) answer;
1078-
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>(unmanagedInstancesAnswer.getUnmanagedInstances());
1086+
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = getUnmanagedInstancesForHost(host, cmd.getName(), managedVms);
10791087
Set<String> keys = unmanagedInstances.keySet();
10801088
for (String key : keys) {
10811089
UnmanagedInstanceTO instance = unmanagedInstances.get(key);
@@ -1098,9 +1106,6 @@ public UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd) {
10981106
throw new PermissionDeniedException(String.format("Cannot perform this operation, Calling account is not root admin: %s", caller.getUuid()));
10991107
}
11001108
final Long clusterId = cmd.getClusterId();
1101-
if (clusterId == null) {
1102-
throw new InvalidParameterValueException(String.format("Cluster ID cannot be null"));
1103-
}
11041109
final Cluster cluster = clusterDao.findById(clusterId);
11051110
if (cluster == null) {
11061111
throw new InvalidParameterValueException(String.format("Cluster ID: %d cannot be found", clusterId));
@@ -1111,18 +1116,18 @@ public UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd) {
11111116
final DataCenter zone = dataCenterDao.findById(cluster.getDataCenterId());
11121117
final String instanceName = cmd.getName();
11131118
if (StringUtils.isEmpty(instanceName)) {
1114-
throw new InvalidParameterValueException(String.format("Instance name cannot be empty"));
1119+
throw new InvalidParameterValueException("Instance name cannot be empty");
11151120
}
11161121
if (cmd.getDomainId() != null && StringUtils.isEmpty(cmd.getAccountName())) {
1117-
throw new InvalidParameterValueException("domainid parameter must be specified with account parameter");
1122+
throw new InvalidParameterValueException(String.format("%s parameter must be specified with %s parameter", ApiConstants.DOMAIN_ID, ApiConstants.ACCOUNT));
11181123
}
11191124
final Account owner = accountService.getActiveAccountById(cmd.getEntityOwnerId());
11201125
long userId = CallContext.current().getCallingUserId();
11211126
List<UserVO> userVOs = userDao.listByAccount(owner.getAccountId());
11221127
if (CollectionUtils.isNotEmpty(userVOs)) {
11231128
userId = userVOs.get(0).getId();
11241129
}
1125-
VMTemplateVO template = null;
1130+
VMTemplateVO template;
11261131
final Long templateId = cmd.getTemplateId();
11271132
if (templateId == null) {
11281133
template = templateDao.findByName(VM_IMPORT_DEFAULT_TEMPLATE_NAME);
@@ -1139,9 +1144,6 @@ public UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd) {
11391144
throw new InvalidParameterValueException(String.format("Template ID: %d cannot be found", templateId));
11401145
}
11411146
final Long serviceOfferingId = cmd.getServiceOfferingId();
1142-
if (serviceOfferingId == null) {
1143-
throw new InvalidParameterValueException(String.format("Service offering ID cannot be null"));
1144-
}
11451147
final ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(serviceOfferingId);
11461148
if (serviceOffering == null) {
11471149
throw new InvalidParameterValueException(String.format("Service offering ID: %d cannot be found", serviceOfferingId));
@@ -1160,7 +1162,7 @@ public UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd) {
11601162
String hostName = cmd.getHostName();
11611163
if (StringUtils.isEmpty(hostName)) {
11621164
if (!NetUtils.verifyDomainNameLabel(instanceName, true)) {
1163-
throw new InvalidParameterValueException(String.format("Please provide hostname for the VM. VM name contains unsupported characters for it to be used as hostname"));
1165+
throw new InvalidParameterValueException("Please provide hostname for the VM. VM name contains unsupported characters for it to be used as hostname");
11641166
}
11651167
hostName = instanceName;
11661168
}
@@ -1185,59 +1187,49 @@ public UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd) {
11851187
List<HostVO> hosts = resourceManager.listHostsInClusterByStatus(clusterId, Status.Up);
11861188
UserVm userVm = null;
11871189
List<String> additionalNameFilters = getAdditionalNameFilters(cluster);
1190+
List<String> managedVms = new ArrayList<>(additionalNameFilters);
1191+
managedVms.addAll(getHostsManagedVms(hosts));
11881192
for (HostVO host : hosts) {
1189-
if (host.isInMaintenanceStates()) {
1190-
continue;
1191-
}
1192-
List<String> managedVms = new ArrayList<>();
1193-
managedVms.addAll(additionalNameFilters);
1194-
managedVms.addAll(getHostManagedVms(host));
1195-
GetUnmanagedInstancesCommand command = new GetUnmanagedInstancesCommand(instanceName);
1196-
command.setManagedInstancesNames(managedVms);
1197-
Answer answer = agentManager.easySend(host.getId(), command);
1198-
if (!(answer instanceof GetUnmanagedInstancesAnswer)) {
1199-
continue;
1200-
}
1201-
GetUnmanagedInstancesAnswer unmanagedInstancesAnswer = (GetUnmanagedInstancesAnswer) answer;
1202-
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = unmanagedInstancesAnswer.getUnmanagedInstances();
1193+
HashMap<String, UnmanagedInstanceTO> unmanagedInstances = getUnmanagedInstancesForHost(host, cmd.getName(), managedVms);
12031194
if (MapUtils.isEmpty(unmanagedInstances)) {
12041195
continue;
12051196
}
12061197
Set<String> names = unmanagedInstances.keySet();
12071198
for (String name : names) {
1208-
if (instanceName.equals(name)) {
1209-
UnmanagedInstanceTO unmanagedInstance = unmanagedInstances.get(name);
1210-
if (unmanagedInstance == null) {
1211-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Unable to retrieve details for unmanaged VM: %s", name));
1199+
if (!instanceName.equals(name)) {
1200+
continue;
1201+
}
1202+
UnmanagedInstanceTO unmanagedInstance = unmanagedInstances.get(name);
1203+
if (unmanagedInstance == null) {
1204+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Unable to retrieve details for unmanaged VM: %s", name));
1205+
}
1206+
if (template.getName().equals(VM_IMPORT_DEFAULT_TEMPLATE_NAME)) {
1207+
String osName = unmanagedInstance.getOperatingSystem();
1208+
GuestOS guestOS = null;
1209+
if (StringUtils.isNotEmpty(osName)) {
1210+
guestOS = guestOSDao.findOneByDisplayName(osName);
12121211
}
1213-
if (template.getName().equals(VM_IMPORT_DEFAULT_TEMPLATE_NAME)) {
1214-
String osName = unmanagedInstance.getOperatingSystem();
1215-
GuestOS guestOS = null;
1216-
if (StringUtils.isNotEmpty(osName)) {
1217-
guestOS = guestOSDao.findOneByDisplayName(osName);
1218-
}
1219-
GuestOSHypervisor guestOSHypervisor = null;
1212+
GuestOSHypervisor guestOSHypervisor = null;
1213+
if (guestOS != null) {
1214+
guestOSHypervisor = guestOSHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion());
1215+
}
1216+
if (guestOSHypervisor == null && StringUtils.isNotEmpty(unmanagedInstance.getOperatingSystemId())) {
1217+
guestOSHypervisor = guestOSHypervisorDao.findByOsNameAndHypervisor(unmanagedInstance.getOperatingSystemId(), host.getHypervisorType().toString(), host.getHypervisorVersion());
1218+
}
1219+
if (guestOSHypervisor == null) {
12201220
if (guestOS != null) {
1221-
guestOSHypervisor = guestOSHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), host.getHypervisorType().toString(), host.getHypervisorVersion());
1221+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Unable to find hypervisor guest OS ID: %s details for unmanaged VM: %s for hypervisor: %s version: %s. templateid parameter can be used to assign template for VM", guestOS.getUuid(), name, host.getHypervisorType().toString(), host.getHypervisorVersion()));
12221222
}
1223-
if (guestOSHypervisor == null && StringUtils.isNotEmpty(unmanagedInstance.getOperatingSystemId())) {
1224-
guestOSHypervisor = guestOSHypervisorDao.findByOsNameAndHypervisor(unmanagedInstance.getOperatingSystemId(), host.getHypervisorType().toString(), host.getHypervisorVersion());
1225-
}
1226-
if (guestOSHypervisor == null) {
1227-
if (guestOS != null) {
1228-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Unable to find hypervisor guest OS ID: %s details for unmanaged VM: %s for hypervisor: %s version: %s. templateid parameter can be used to assign template for VM", guestOS.getUuid(), name, host.getHypervisorType().toString(), host.getHypervisorVersion()));
1229-
}
1230-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Unable to retrieve guest OS details for unmanaged VM: %s with OS name: %s, OS ID: %s for hypervisor: %s version: %s. templateid parameter can be used to assign template for VM", name, osName, unmanagedInstance.getOperatingSystemId(), host.getHypervisorType().toString(), host.getHypervisorVersion()));
1231-
}
1232-
template.setGuestOSId(guestOSHypervisor.getGuestOsId());
1223+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Unable to retrieve guest OS details for unmanaged VM: %s with OS name: %s, OS ID: %s for hypervisor: %s version: %s. templateid parameter can be used to assign template for VM", name, osName, unmanagedInstance.getOperatingSystemId(), host.getHypervisorType().toString(), host.getHypervisorVersion()));
12331224
}
1234-
userVm = importVirtualMachineInternal(unmanagedInstance, instanceName, zone, cluster, host,
1235-
template, displayName, hostName, caller, owner, userId,
1236-
serviceOffering, dataDiskOfferingMap,
1237-
nicNetworkMap, nicIpAddressMap,
1238-
details, cmd.getMigrateAllowed(), forced);
1239-
break;
1225+
template.setGuestOSId(guestOSHypervisor.getGuestOsId());
12401226
}
1227+
userVm = importVirtualMachineInternal(unmanagedInstance, instanceName, zone, cluster, host,
1228+
template, displayName, hostName, caller, owner, userId,
1229+
serviceOffering, dataDiskOfferingMap,
1230+
nicNetworkMap, nicIpAddressMap,
1231+
details, cmd.getMigrateAllowed(), forced);
1232+
break;
12411233
}
12421234
if (userVm != null) {
12431235
break;

0 commit comments

Comments
 (0)