Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/src/main/java/com/cloud/vm/VmDetailConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public interface VmDetailConstants {
String KVM_VNC_PORT = "kvm.vnc.port";
String KVM_VNC_ADDRESS = "kvm.vnc.address";

String KVM_VNC_PASSWORD = "kvm.vnc.password";

// KVM specific, custom virtual GPU hardware
String VIDEO_HARDWARE = "video.hardware";
String VIDEO_RAM = "video.ram";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,16 @@ public class ImportUnmanagedInstanceCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.NAME,
type = CommandType.STRING,
required = true,
description = "the hypervisor name of the instance")
description = "the name of the instance as it is known to the hypervisor")
private String name;

@Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
type = CommandType.UUID,
entityType = ServiceOfferingResponse.class,
required = true,
description = "the ID of the service offering for the virtual machine")
private Long serviceOfferingId;

Comment on lines +90 to +96
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this refactoring needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it was a harmless refactoring as it moves all required params together. I can change back if you think it doesn't add value?

@Parameter(name = ApiConstants.DISPLAY_NAME,
type = CommandType.STRING,
description = "the display name of the instance")
Expand Down Expand Up @@ -120,13 +127,6 @@ public class ImportUnmanagedInstanceCmd extends BaseAsyncCmd {
description = "the ID of the template for the virtual machine")
private Long templateId;

@Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
type = CommandType.UUID,
entityType = ServiceOfferingResponse.class,
required = true,
description = "the ID of the service offering for the virtual machine")
private Long serviceOfferingId;

@Parameter(name = ApiConstants.NIC_NETWORK_LIST,
type = CommandType.MAP,
description = "VM nic to network id mapping using keys nic and network")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public enum PowerState {
private List<Disk> disks;

private List<Nic> nics;
private String vncPassword;

public String getName() {
return name;
Expand Down Expand Up @@ -137,6 +138,15 @@ public void setNics(List<Nic> nics) {
this.nics = nics;
}

public String getVncPassword() {
return vncPassword;
}

public void setVncPassword(String vncPassword) {
this.vncPassword = vncPassword;
}


public static class Disk {
private String diskId;

Expand All @@ -160,6 +170,8 @@ public static class Disk {

private String datastoreHost;

private int datastorePort;

private String datastorePath;

private String datastoreType;
Expand Down Expand Up @@ -267,6 +279,14 @@ public String getDatastoreType() {
public void setDatastoreType(String datastoreType) {
this.datastoreType = datastoreType;
}

public void setDatastorePort(int datastorePort) {
this.datastorePort = datastorePort;
}

public int getDatastorePort() {
return datastorePort;
}
}

public static class Nic {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@

package org.apache.cloudstack.vm;

import com.cloud.hypervisor.Hypervisor;
import com.cloud.utils.component.PluggableService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import static com.cloud.hypervisor.Hypervisor.HypervisorType.KVM;
import static com.cloud.hypervisor.Hypervisor.HypervisorType.VMware;

public interface UnmanagedVMsManager extends VmImportService, UnmanageVMService, PluggableService, Configurable {

ConfigKey<Boolean> UnmanageVMPreserveNic = new ConfigKey<>("Advanced", Boolean.class, "unmanage.vm.preserve.nics", "false",
"If set to true, do not remove VM nics (and its MAC addresses) when unmanaging a VM, leaving them allocated but not reserved. " +
"If set to false, nics are removed and MAC addresses can be reassigned", true, ConfigKey.Scope.Zone);

static boolean isSupported(Hypervisor.HypervisorType hypervisorType) {
return hypervisorType == VMware || hypervisorType == KVM;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package org.apache.cloudstack.vm;

import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import org.apache.cloudstack.api.command.admin.vm.ImportUnmanagedInstanceCmd;
import org.apache.cloudstack.api.command.admin.vm.ListUnmanagedInstancesCmd;
import org.apache.cloudstack.api.response.ListResponse;
Expand All @@ -25,5 +28,5 @@

public interface VmImportService {
ListResponse<UnmanagedInstanceResponse> listUnmanagedInstances(ListUnmanagedInstancesCmd cmd);
UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd);
UserVmResponse importUnmanagedInstance(ImportUnmanagedInstanceCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3696,7 +3696,32 @@ private String getIqn() {
}
}

protected List<String> getAllVmNames(final Connect conn) {
/**
* Given a disk path on KVM host, attempts to find source host and path using mount command
* @param diskPath KVM host path for virtual disk
* @return Pair with IP of host and path
*/
public Pair<String, String> getSourceHostPath(String diskPath) {
String sourceHostIp = null, sourcePath = null;
try {
String mountResult = Script.runSimpleBashScript("mount | grep \"" + diskPath + "\"");
s_logger.debug("Got mount result for " + diskPath + "\n\n" + mountResult);
if (StringUtils.isNotEmpty(mountResult)) {
String[] res = mountResult.strip().split(" ");
res = res[0].split(":");
sourceHostIp = res[0].strip();
sourcePath = res[1].strip();
}
if (StringUtils.isNotEmpty(sourceHostIp) && StringUtils.isNotEmpty(sourcePath)) {
return new Pair<>(sourceHostIp, sourcePath);
}
} catch (Exception ex) {
s_logger.warn("Failed to list source host and IP for " + diskPath + ex.toString());
}
return null;
}

public List<String> getAllVmNames(final Connect conn) {
final ArrayList<String> la = new ArrayList<String>();
try {
final String names[] = conn.listDefinedDomains();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.xml.sax.SAXException;

import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuModeDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.NicModel;
Expand All @@ -57,8 +59,13 @@ public class LibvirtDomainXMLParser {
private final List<ChannelDef> channels = new ArrayList<ChannelDef>();
private final List<WatchDogDef> watchDogDefs = new ArrayList<WatchDogDef>();
private Integer vncPort;
private String vncPasswd;
private String desc;

private CpuTuneDef cpuTuneDef;

private CpuModeDef cpuModeDef;

public boolean parseDomainXML(String domXML) {
DocumentBuilder builder;
try {
Expand Down Expand Up @@ -302,6 +309,12 @@ public boolean parseDomainXML(String domXML) {
vncPort = null;
}
}

String passwd = graphic.getAttribute("passwd");
if (passwd != null) {
vncPasswd = passwd;
}

}

NodeList rngs = devices.getElementsByTagName("rng");
Expand Down Expand Up @@ -343,7 +356,8 @@ public boolean parseDomainXML(String domXML) {

watchDogDefs.add(def);
}

cpuTuneDef = extractCpuTuneDef(rootElement);
cpuModeDef = extractCpuModeDef(rootElement);
return true;
} catch (ParserConfigurationException e) {
s_logger.debug(e.toString());
Expand Down Expand Up @@ -400,6 +414,10 @@ public Integer getVncPort() {
return vncPort;
}

public String getVncPasswd() {
return vncPasswd;
}

public List<InterfaceDef> getInterfaces() {
return interfaces;
}
Expand Down Expand Up @@ -427,4 +445,69 @@ public List<WatchDogDef> getWatchDogs() {
public String getDescription() {
return desc;
}

public CpuTuneDef getCpuTuneDef() {
return cpuTuneDef;
}

public CpuModeDef getCpuModeDef() {
return cpuModeDef;
}

private static CpuTuneDef extractCpuTuneDef(final Element rootElement) {
NodeList cpuTunesList = rootElement.getElementsByTagName("cputune");
CpuTuneDef def = null;
if (cpuTunesList.getLength() > 0) {
def = new CpuTuneDef();
final Element cpuTuneDefElement = (Element) cpuTunesList.item(0);
final String cpuShares = getTagValue("shares", cpuTuneDefElement);
if (StringUtils.isNotBlank(cpuShares)) {
def.setShares((Integer.parseInt(cpuShares)));
}

final String quota = getTagValue("quota", cpuTuneDefElement);
if (StringUtils.isNotBlank(quota)) {
def.setQuota((Integer.parseInt(quota)));
}

final String period = getTagValue("period", cpuTuneDefElement);
if (StringUtils.isNotBlank(period)) {
def.setPeriod((Integer.parseInt(period)));
}
}
return def;
}

private static CpuModeDef extractCpuModeDef(final Element rootElement){
NodeList cpuModeList = rootElement.getElementsByTagName("cpu");
CpuModeDef def = null;
if (cpuModeList.getLength() > 0){
def = new CpuModeDef();
final Element cpuModeDefElement = (Element) cpuModeList.item(0);
final String cpuModel = getTagValue("model", cpuModeDefElement);
if (StringUtils.isNotBlank(cpuModel)){
def.setModel(cpuModel);
}
NodeList cpuFeatures = cpuModeDefElement.getElementsByTagName("features");
if (cpuFeatures.getLength() > 0) {
final ArrayList<String> features = new ArrayList<>(cpuFeatures.getLength());
for (int i = 0; i < cpuFeatures.getLength(); i++) {
final Element feature = (Element)cpuFeatures.item(i);
final String policy = feature.getAttribute("policy");
String featureName = feature.getAttribute("name");
if ("disable".equals(policy)) {
featureName = "-" + featureName;
}
features.add(featureName);
}
def.setFeatures(features);
}
final String sockets = getAttrValue("topology", "sockets", cpuModeDefElement);
final String cores = getAttrValue("topology", "cores", cpuModeDefElement);
if (StringUtils.isNotBlank(sockets) && StringUtils.isNotBlank(cores)) {
def.setTopology(Integer.parseInt(cores), Integer.parseInt(sockets));
}
}
return def;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,9 @@ public String toString() {
}
}

enum DiskType {
public enum DiskType {
FILE("file"), BLOCK("block"), DIRECTROY("dir"), NETWORK("network");
String _diskType;

DiskType(String type) {
_diskType = type;
}
Expand Down Expand Up @@ -1072,6 +1071,18 @@ public void setSerial(String serial) {

public LibvirtDiskEncryptDetails getLibvirtDiskEncryptDetails() { return this.encryptDetails; }

public String getSourceHost() {
return _sourceHost;
}

public int getSourceHostPort() {
return _sourcePort;
}

public String getSourcePath() {
return _sourcePath;
}

@Override
public String toString() {
StringBuilder diskBuilder = new StringBuilder();
Expand Down Expand Up @@ -1394,6 +1405,7 @@ public void defEthernet(String targetName, String macAddr, NicModel model) {
defEthernet(targetName, macAddr, model, null);
}


public void setHostNetType(HostNicType hostNetType) {
_hostNetType = hostNetType;
}
Expand Down Expand Up @@ -1737,6 +1749,10 @@ public String toString() {
modeBuilder.append("</cpu>");
return modeBuilder.toString();
}

public int getCoresPerSocket() {
return _coresPerSocket;
}
}

public static class SerialDef {
Expand Down
Loading