Skip to content

Commit 8d3ae3e

Browse files
nvazquezDaanHooglandsureshanaparti
authored
[Vmware] Improve listing of Vmware Datacenter VMs for migration to KVM (#10770)
Co-authored-by: dahn <[email protected]> Co-authored-by: Suresh Kumar Anaparti <[email protected]>
1 parent 88ce639 commit 8d3ae3e

File tree

10 files changed

+289
-44
lines changed

10 files changed

+289
-44
lines changed

api/src/main/java/org/apache/cloudstack/api/response/UnmanagedInstanceResponse.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ public class UnmanagedInstanceResponse extends BaseResponse {
7979
@Param(description = "the operating system of the virtual machine")
8080
private String operatingSystem;
8181

82+
@SerializedName(ApiConstants.BOOT_MODE)
83+
@Param(description = "indicates the boot mode")
84+
private String bootMode;
85+
86+
@SerializedName(ApiConstants.BOOT_TYPE)
87+
@Param(description = "indicates the boot type")
88+
private String bootType;
89+
8290
@SerializedName(ApiConstants.DISK)
8391
@Param(description = "the list of disks associated with the virtual machine", responseObject = UnmanagedInstanceDiskResponse.class)
8492
private Set<UnmanagedInstanceDiskResponse> disks;
@@ -211,4 +219,20 @@ public void setNics(Set<NicResponse> nics) {
211219
public void addNic(NicResponse nic) {
212220
this.nics.add(nic);
213221
}
222+
223+
public String getBootMode() {
224+
return bootMode;
225+
}
226+
227+
public void setBootMode(String bootMode) {
228+
this.bootMode = bootMode;
229+
}
230+
231+
public String getBootType() {
232+
return bootType;
233+
}
234+
235+
public void setBootType(String bootType) {
236+
this.bootType = bootType;
237+
}
214238
}

api/src/main/java/org/apache/cloudstack/vm/UnmanagedInstanceTO.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public enum PowerState {
6161

6262
private String vncPassword;
6363

64+
private String bootType;
65+
private String bootMode;
66+
6467
public String getName() {
6568
return name;
6669
}
@@ -189,6 +192,22 @@ public void setVncPassword(String vncPassword) {
189192
this.vncPassword = vncPassword;
190193
}
191194

195+
public String getBootType() {
196+
return bootType;
197+
}
198+
199+
public void setBootType(String bootType) {
200+
this.bootType = bootType;
201+
}
202+
203+
public String getBootMode() {
204+
return bootMode;
205+
}
206+
207+
public void setBootMode(String bootMode) {
208+
this.bootMode = bootMode;
209+
}
210+
192211
public static class Disk {
193212
private String diskId;
194213

plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import javax.naming.ConfigurationException;
4444
import javax.persistence.EntityExistsException;
4545

46+
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
4647
import com.cloud.hypervisor.vmware.util.VmwareClient;
4748
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
4849
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
@@ -1587,14 +1588,26 @@ public List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsph
15871588
return compatiblePools;
15881589
}
15891590

1590-
@Override
1591-
public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
1591+
private static class VcenterData {
1592+
public final String vcenter;
1593+
public final String datacenterName;
1594+
public final String username;
1595+
public final String password;
1596+
1597+
public VcenterData(String vcenter, String datacenterName, String username, String password) {
1598+
this.vcenter = vcenter;
1599+
this.datacenterName = datacenterName;
1600+
this.username = username;
1601+
this.password = password;
1602+
}
1603+
}
1604+
1605+
private VcenterData getVcenterData(ListVmwareDcVmsCmd cmd) {
15921606
String vcenter = cmd.getVcenter();
15931607
String datacenterName = cmd.getDatacenterName();
15941608
String username = cmd.getUsername();
15951609
String password = cmd.getPassword();
15961610
Long existingVcenterId = cmd.getExistingVcenterId();
1597-
String keyword = cmd.getKeyword();
15981611

15991612
if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
16001613
(existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
@@ -1615,34 +1628,67 @@ public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
16151628
username = vmwareDc.getUser();
16161629
password = vmwareDc.getPassword();
16171630
}
1631+
VcenterData vmwaredc = new VcenterData(vcenter, datacenterName, username, password);
1632+
return vmwaredc;
1633+
}
1634+
1635+
private static VmwareContext getVmwareContext(String vcenter, String username, String password) throws Exception {
1636+
s_logger.debug(String.format("Connecting to the VMware vCenter %s", vcenter));
1637+
String serviceUrl = String.format("https://%s/sdk/vimService", vcenter);
1638+
VmwareClient vimClient = new VmwareClient(vcenter);
1639+
vimClient.connect(serviceUrl, username, password);
1640+
return new VmwareContext(vimClient, vcenter);
1641+
}
1642+
1643+
@Override
1644+
public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
1645+
VcenterData vmwareDC = getVcenterData(cmd);
1646+
String vcenter = vmwareDC.vcenter;
1647+
String username = vmwareDC.username;
1648+
String password = vmwareDC.password;
1649+
String datacenterName = vmwareDC.datacenterName;
1650+
String keyword = cmd.getKeyword();
1651+
String esxiHostName = cmd.getHostName();
1652+
String virtualMachineName = cmd.getInstanceName();
16181653

16191654
try {
1620-
s_logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
1621-
datacenterName, vcenter));
1622-
String serviceUrl = String.format("https://%s/sdk/vimService", vcenter);
1623-
VmwareClient vimClient = new VmwareClient(vcenter);
1624-
vimClient.connect(serviceUrl, username, password);
1625-
VmwareContext context = new VmwareContext(vimClient, vcenter);
1626-
1627-
DatacenterMO dcMo = new DatacenterMO(context, datacenterName);
1628-
ManagedObjectReference dcMor = dcMo.getMor();
1629-
if (dcMor == null) {
1630-
String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
1631-
datacenterName, vcenter);
1632-
s_logger.error(msg);
1633-
throw new InvalidParameterValueException(msg);
1655+
VmwareContext context = getVmwareContext(vcenter, username, password);
1656+
DatacenterMO dcMo = getDatacenterMO(context, vcenter, datacenterName);
1657+
1658+
List<UnmanagedInstanceTO> instances;
1659+
if (StringUtils.isNotBlank(esxiHostName) && StringUtils.isNotBlank(virtualMachineName)) {
1660+
ManagedObjectReference hostMor = dcMo.findHost(esxiHostName);
1661+
if (hostMor == null) {
1662+
String errorMsg = String.format("Cannot find a host with name %s on vcenter %s", esxiHostName, vcenter);
1663+
s_logger.error(errorMsg);
1664+
throw new CloudRuntimeException(errorMsg);
1665+
}
1666+
HostMO hostMO = new HostMO(context, hostMor);
1667+
VirtualMachineMO vmMo = hostMO.findVmOnHyperHost(virtualMachineName);
1668+
instances = Collections.singletonList(VmwareHelper.getUnmanagedInstance(hostMO, vmMo));
1669+
} else {
1670+
instances = dcMo.getAllVmsOnDatacenter(keyword);
16341671
}
1635-
List<UnmanagedInstanceTO> instances = dcMo.getAllVmsOnDatacenter();
1636-
return StringUtils.isBlank(keyword) ? instances :
1637-
instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList());
1672+
return instances;
16381673
} catch (Exception e) {
1639-
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
1674+
String errorMsg = String.format("Error retrieving VMs from the VMware VC %s datacenter %s: %s",
16401675
vcenter, datacenterName, e.getMessage());
16411676
s_logger.error(errorMsg, e);
16421677
throw new CloudRuntimeException(errorMsg);
16431678
}
16441679
}
16451680

1681+
private static DatacenterMO getDatacenterMO(VmwareContext context, String vcenter, String datacenterName) throws Exception {
1682+
DatacenterMO dcMo = new DatacenterMO(context, datacenterName);
1683+
ManagedObjectReference dcMor = dcMo.getMor();
1684+
if (dcMor == null) {
1685+
String msg = String.format("Unable to find VMware datacenter %s in vCenter %s", datacenterName, vcenter);
1686+
s_logger.error(msg);
1687+
throw new InvalidParameterValueException(msg);
1688+
}
1689+
return dcMo;
1690+
}
1691+
16461692
@Override
16471693
public boolean hasNexusVSM(Long clusterId) {
16481694
ClusterVSMMapVO vsmMapVo = null;

plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
7070
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
7171
private String password;
7272

73+
@Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, description = "Name of the host on vCenter. Must be set along with the instancename parameter")
74+
private String hostName;
75+
76+
@Parameter(name = ApiConstants.INSTANCE_NAME, type = CommandType.STRING, description = "Name of the VM on vCenter. Must be set along with the hostname parameter")
77+
private String instanceName;
78+
7379
public String getVcenter() {
7480
return vcenter;
7581
}
@@ -86,10 +92,18 @@ public String getDatacenterName() {
8692
return datacenterName;
8793
}
8894

95+
public String getHostName() {
96+
return hostName;
97+
}
98+
8999
public Long getExistingVcenterId() {
90100
return existingVcenterId;
91101
}
92102

103+
public String getInstanceName() {
104+
return instanceName;
105+
}
106+
93107
@Override
94108
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
95109
checkParameters();
@@ -125,6 +139,11 @@ private void checkParameters() {
125139
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
126140
"Please set all the information for a vCenter IP/Name, datacenter, username and password");
127141
}
142+
if ((StringUtils.isNotBlank(instanceName) && StringUtils.isBlank(hostName)) ||
143+
(StringUtils.isBlank(instanceName) && StringUtils.isNotBlank(hostName))) {
144+
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
145+
"Please set the hostname parameter along with the instancename parameter");
146+
}
128147
}
129148

130149
@Override

server/src/main/java/com/cloud/api/ApiResponseHelper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5145,6 +5145,8 @@ public UnmanagedInstanceResponse createUnmanagedInstanceResponse(UnmanagedInstan
51455145
response.setMemory(instance.getMemory());
51465146
response.setOperatingSystemId(instance.getOperatingSystemId());
51475147
response.setOperatingSystem(instance.getOperatingSystem());
5148+
response.setBootMode(instance.getBootMode());
5149+
response.setBootType(instance.getBootType());
51485150
response.setObjectName("unmanagedinstance");
51495151

51505152
if (instance.getDisks() != null) {

ui/src/views/tools/ManageInstances.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,31 @@ export default {
13021302
this.fetchInstances()
13031303
}
13041304
},
1305+
fetchVmwareInstanceForKVMMigration (vmname, hostname) {
1306+
const params = {}
1307+
if (this.isMigrateFromVmware && this.selectedVmwareVcenter) {
1308+
if (this.selectedVmwareVcenter.vcenter) {
1309+
params.datacentername = this.selectedVmwareVcenter.datacentername
1310+
params.vcenter = this.selectedVmwareVcenter.vcenter
1311+
params.username = this.selectedVmwareVcenter.username
1312+
params.password = this.selectedVmwareVcenter.password
1313+
} else {
1314+
params.existingvcenterid = this.selectedVmwareVcenter.existingvcenterid
1315+
}
1316+
params.instancename = vmname
1317+
params.hostname = hostname
1318+
}
1319+
api('listVmwareDcVms', params).then(json => {
1320+
const response = json.listvmwaredcvmsresponse
1321+
this.selectedUnmanagedInstance = response.unmanagedinstance[0]
1322+
this.selectedUnmanagedInstance.ostypename = this.selectedUnmanagedInstance.osdisplayname
1323+
this.selectedUnmanagedInstance.state = this.selectedUnmanagedInstance.powerstate
1324+
}).catch(error => {
1325+
this.$notifyError(error)
1326+
}).finally(() => {
1327+
this.loading = false
1328+
})
1329+
},
13051330
onManageInstanceAction () {
13061331
this.selectedUnmanagedInstance = {}
13071332
if (this.unmanagedInstances.length > 0 &&
@@ -1319,6 +1344,9 @@ export default {
13191344
}
13201345
})
13211346
this.showUnmanageForm = false
1347+
} else if (this.isMigrateFromVmware) {
1348+
this.fetchVmwareInstanceForKVMMigration(this.selectedUnmanagedInstance.name, this.selectedUnmanagedInstance.hostname)
1349+
this.showUnmanageForm = true
13221350
} else {
13231351
this.showUnmanageForm = true
13241352
}

ui/src/views/tools/SelectVmwareVcenter.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ export default {
227227
} else {
228228
params.existingvcenterid = this.selectedExistingVcenterId
229229
}
230+
params.page = 1
231+
params.pagesize = 10
230232
api('listVmwareDcVms', params).then(json => {
231233
const obj = {
232234
params: params,
@@ -265,6 +267,11 @@ export default {
265267
this.loading = false
266268
})
267269
},
270+
onSelectExternalVmwareDatacenter (value) {
271+
if (this.vcenterSelectedOption === 'new' && !(this.vcenter === '' || this.datacentername === '' || this.username === '' || this.password === '')) {
272+
this.listVmwareDatacenterVms()
273+
}
274+
},
268275
onSelectExistingVmwareDatacenter (value) {
269276
this.selectedExistingVcenterId = value
270277
},

0 commit comments

Comments
 (0)