mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-8324: Added config drive support for xenserver
This commit is contained in:
parent
7984ae5283
commit
e407986183
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package com.cloud.agent.api.to;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
|
|
@ -62,6 +63,12 @@ public class VirtualMachineTO {
|
|||
NicTO[] nics;
|
||||
GPUDeviceTO gpuDevice;
|
||||
Integer vcpuMaxLimit;
|
||||
List<String[]> vmData = null;
|
||||
|
||||
String configDriveLabel = null;
|
||||
String configDriveIsoRootFolder = null;
|
||||
String configDriveIsoFile = null;
|
||||
|
||||
|
||||
public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
|
||||
String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
|
||||
|
|
@ -292,4 +299,36 @@ public class VirtualMachineTO {
|
|||
this.vcpuMaxLimit = vcpuMaxLimit;
|
||||
}
|
||||
|
||||
public List<String[]> getVmData() {
|
||||
return vmData;
|
||||
}
|
||||
|
||||
public void setVmData(List<String[]> vmData) {
|
||||
this.vmData = vmData;
|
||||
}
|
||||
|
||||
public String getConfigDriveLabel() {
|
||||
return configDriveLabel;
|
||||
}
|
||||
|
||||
public void setConfigDriveLabel(String configDriveLabel) {
|
||||
this.configDriveLabel = configDriveLabel;
|
||||
}
|
||||
|
||||
public String getConfigDriveIsoRootFolder() {
|
||||
return configDriveIsoRootFolder;
|
||||
}
|
||||
|
||||
public void setConfigDriveIsoRootFolder(String configDriveIsoRootFolder) {
|
||||
this.configDriveIsoRootFolder = configDriveIsoRootFolder;
|
||||
}
|
||||
|
||||
public String getConfigDriveIsoFile() {
|
||||
return configDriveIsoFile;
|
||||
}
|
||||
|
||||
public void setConfigDriveIsoFile(String configDriveIsoFile) {
|
||||
this.configDriveIsoFile = configDriveIsoFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,4 +277,8 @@ public interface NetworkModel {
|
|||
boolean isNetworkReadyForGc(long networkId);
|
||||
|
||||
boolean getNetworkEgressDefaultPolicy(Long networkId);
|
||||
|
||||
List<String[]> generateVmData(String userData, String serviceOffering, String zoneName,
|
||||
String vmName, long vmId, String publicKey, String password, Boolean isWindows);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,13 @@ import com.cloud.template.VirtualMachineTemplate;
|
|||
import com.cloud.user.Account;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.exception.ExecutionException;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
public interface UserVmService {
|
||||
|
||||
static final ConfigKey<String> VmConfigDriveLabel = new ConfigKey<String>("Hidden", String.class, "vm.configdrive.label", "config",
|
||||
"The default lable name for the config drive", false);
|
||||
|
||||
/**
|
||||
* Destroys one virtual machine
|
||||
*
|
||||
|
|
|
|||
|
|
@ -34,9 +34,24 @@ import com.cloud.user.Account;
|
|||
*/
|
||||
public interface VirtualMachineProfile {
|
||||
|
||||
List<String[]> getVmData();
|
||||
|
||||
void setVmData(List<String[]> vmData);
|
||||
|
||||
void setConfigDriveLabel(String configDriveLabel);
|
||||
|
||||
String getConfigDriveIsoRootFolder();
|
||||
|
||||
void setConfigDriveIsoRootFolder(String configDriveIsoRootFolder);
|
||||
|
||||
String getConfigDriveIsoFile();
|
||||
|
||||
void setConfigDriveIsoFile(String isoFile);
|
||||
|
||||
public static class Param {
|
||||
|
||||
public static final Param VmPassword = new Param("VmPassword");
|
||||
public static final Param VmSshPubKey = new Param("VmSshPubKey");
|
||||
public static final Param ControlNic = new Param("ControlNic");
|
||||
public static final Param ReProgramGuestNetworks = new Param("RestartNetwork");
|
||||
public static final Param PxeSeverType = new Param("PxeSeverType");
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile {
|
|||
|
||||
VirtualMachine.Type _type;
|
||||
|
||||
List<String[]> vmData = null;
|
||||
|
||||
String configDriveLabel = null;
|
||||
String configDriveIsoBaseLocation = "/tmp/"; //TODO: Make this location configurable.
|
||||
String configDriveIsoRootFolder = null;
|
||||
String configDriveIsoFile = null;
|
||||
|
||||
public VirtualMachineProfileImpl(VirtualMachine vm, VirtualMachineTemplate template, ServiceOffering offering, Account owner, Map<Param, Object> params) {
|
||||
_vm = vm;
|
||||
_template = template;
|
||||
|
|
@ -255,4 +262,47 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile {
|
|||
public Float getMemoryOvercommitRatio() {
|
||||
return memoryOvercommitRatio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String[]> getVmData() {
|
||||
return vmData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVmData(List<String[]> vmData) {
|
||||
this.vmData = vmData;
|
||||
}
|
||||
|
||||
public String getConfigDriveLabel() {
|
||||
return configDriveLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigDriveLabel(String configDriveLabel) {
|
||||
this.configDriveLabel = configDriveLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigDriveIsoRootFolder() {
|
||||
return configDriveIsoRootFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigDriveIsoRootFolder(String configDriveIsoRootFolder) {
|
||||
this.configDriveIsoRootFolder = configDriveIsoRootFolder;
|
||||
}
|
||||
|
||||
public String getConfigDriveIsoBaseLocation() {
|
||||
return configDriveIsoBaseLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigDriveIsoFile() {
|
||||
return configDriveIsoFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigDriveIsoFile(String isoFile) {
|
||||
this.configDriveIsoFile = isoFile;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
package com.cloud.hypervisor.xenserver.resource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
|
|
@ -48,6 +50,7 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||
|
||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xmlrpc.XmlRpcException;
|
||||
import org.w3c.dom.Document;
|
||||
|
|
@ -251,6 +254,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
|
||||
protected VirtualRoutingResource _vrResource;
|
||||
|
||||
protected String _configDriveIsopath = "/opt/xensource/packages/configdrive_iso/";
|
||||
protected String _configDriveSRName = "ConfigDriveISOs";
|
||||
protected String _attachIsoDeviceNum = "3";
|
||||
|
||||
protected int _wait;
|
||||
// Hypervisor specific params with generic value, may need to be overridden
|
||||
// for specific versions
|
||||
|
|
@ -4940,4 +4947,317 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean createAndAttachConfigDriveIsoForVM(Connection conn, VM vm, List<String[]> vmDataList, String configDriveLabel) throws XenAPIException, XmlRpcException {
|
||||
|
||||
String vmName = vm.getNameLabel(conn);
|
||||
|
||||
// create SR
|
||||
SR sr = createLocalIsoSR(conn, _configDriveSRName+_host.getIp());
|
||||
if (sr == null) {
|
||||
s_logger.debug("Failed to create local SR for the config drive");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_logger.debug("Creating vm data files in config drive for vm "+vmName);
|
||||
// 1. create vm data files
|
||||
if (!createVmdataFiles(vmName, vmDataList, configDriveLabel)) {
|
||||
s_logger.debug("Failed to create vm data files in config drive for vm "+vmName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. copy config drive iso to host
|
||||
if (!copyConfigDriveIsoToHost(conn, sr, vmName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. attachIsoToVM
|
||||
if (!attachConfigDriveIsoToVm(conn, vm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean createVmdataFiles(String vmName, List<String[]> vmDataList, String configDriveLabel) {
|
||||
|
||||
// add vm iso to the isolibrary
|
||||
String isoPath = "/tmp/"+vmName+"/configDrive/";
|
||||
String configDriveName = "cloudstack/";
|
||||
|
||||
//create folder for the VM
|
||||
//Remove the folder before creating it.
|
||||
|
||||
try {
|
||||
deleteLocalFolder("/tmp/"+isoPath);
|
||||
} catch (IOException e) {
|
||||
s_logger.debug("Failed to delete the exiting config drive for vm "+vmName+ " "+ e.getMessage());
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to delete the exiting config drive for vm "+vmName+ " "+ e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
if (vmDataList != null) {
|
||||
for (String[] item : vmDataList) {
|
||||
String dataType = item[0];
|
||||
String fileName = item[1];
|
||||
String content = item[2];
|
||||
|
||||
// create file with content in folder
|
||||
|
||||
if (dataType != null && !dataType.isEmpty()) {
|
||||
//create folder
|
||||
String folder = isoPath+configDriveName+dataType;
|
||||
if (folder != null && !folder.isEmpty()) {
|
||||
File dir = new File(folder);
|
||||
boolean result = true;
|
||||
|
||||
try {
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
}catch (SecurityException ex) {
|
||||
s_logger.debug("Failed to create dir "+ ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result && content != null && !content.isEmpty()) {
|
||||
try {
|
||||
File file = new File(folder+"/"+fileName+".txt");
|
||||
FileWriter fw = new FileWriter(file.getAbsoluteFile());
|
||||
BufferedWriter bw = new BufferedWriter(fw);
|
||||
bw.write(content);
|
||||
bw.close();
|
||||
s_logger.debug("created file: "+ file + " in folder:"+folder);
|
||||
} catch (IOException ex) {
|
||||
s_logger.debug("Failed to create file "+ ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
s_logger.debug("Created the vm data in "+ isoPath);
|
||||
}
|
||||
|
||||
String s = null;
|
||||
try {
|
||||
|
||||
String cmd = "mkisofs -iso-level 3 -V "+ configDriveLabel +" -o "+ isoPath+vmName +".iso " + isoPath;
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
|
||||
BufferedReader stdInput = new BufferedReader(new
|
||||
InputStreamReader(p.getInputStream()));
|
||||
|
||||
BufferedReader stdError = new BufferedReader(new
|
||||
InputStreamReader(p.getErrorStream()));
|
||||
|
||||
// read the output from the command
|
||||
while ((s = stdInput.readLine()) != null) {
|
||||
s_logger.debug(s);
|
||||
}
|
||||
|
||||
// read any errors from the attempted command
|
||||
while ((s = stdError.readLine()) != null) {
|
||||
s_logger.debug(s);
|
||||
}
|
||||
s_logger.debug(" Created config drive ISO using the command " + cmd +" in the host "+ _host.getIp());
|
||||
} catch (IOException e) {
|
||||
s_logger.debug(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean copyConfigDriveIsoToHost(Connection conn, SR sr, String vmName) {
|
||||
|
||||
String vmIso = "/tmp/"+vmName+"/configDrive/"+vmName+".iso";
|
||||
//scp file into the host
|
||||
com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
|
||||
|
||||
try {
|
||||
sshConnection.connect(null, 60000, 60000);
|
||||
if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
|
||||
throw new CloudRuntimeException("Unable to authenticate");
|
||||
}
|
||||
|
||||
s_logger.debug("scp config drive iso file "+vmIso +" to host " + _host.getIp() +" path "+_configDriveIsopath);
|
||||
SCPClient scp = new SCPClient(sshConnection);
|
||||
String p = "0755";
|
||||
|
||||
scp.put(vmIso, _configDriveIsopath, p);
|
||||
sr.scan(conn);
|
||||
s_logger.debug("copied config drive iso to host " + _host);
|
||||
} catch (IOException e) {
|
||||
s_logger.debug("failed to copy configdrive iso " + vmIso + " to host " + _host, e);
|
||||
return false;
|
||||
} catch (XmlRpcException e) {
|
||||
s_logger.debug("Failed to scan config drive iso SR "+ _configDriveSRName+_host.getIp() + " in host "+ _host, e);
|
||||
return false;
|
||||
} finally {
|
||||
sshConnection.close();
|
||||
//clean up the config drive files
|
||||
|
||||
String configDir = "/tmp/"+vmName;
|
||||
try {
|
||||
deleteLocalFolder(configDir);
|
||||
s_logger.debug("Successfully cleaned up config drive directory " + configDir
|
||||
+ " after copying it to host ");
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to delete config drive folder :" + configDir + " for VM " + vmName + " "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean attachConfigDriveIsoToVm(Connection conn, VM vm) throws XenAPIException, XmlRpcException {
|
||||
|
||||
String vmName = vm.getNameLabel(conn);
|
||||
String isoURL = _configDriveIsopath + vmName+".iso";
|
||||
VDI srVdi;
|
||||
|
||||
//1. find the vdi of the iso
|
||||
//2. find the vbd for the vdi
|
||||
//3. attach iso to vm
|
||||
|
||||
try {
|
||||
Set<VDI> vdis = VDI.getByNameLabel(conn, vmName+".iso");
|
||||
if (vdis.isEmpty()) {
|
||||
throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL);
|
||||
}
|
||||
srVdi = vdis.iterator().next();
|
||||
|
||||
} catch (XenAPIException e) {
|
||||
s_logger.debug("Unable to get config drive iso: " + isoURL + " due to " + e.toString());
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Unable to get config drive iso: " + isoURL + " due to " + e.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
VBD isoVBD = null;
|
||||
|
||||
// Find the VM's CD-ROM VBD
|
||||
Set<VBD> vbds = vm.getVBDs(conn);
|
||||
for (VBD vbd : vbds) {
|
||||
Types.VbdType type = vbd.getType(conn);
|
||||
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
|
||||
// if the device exists then attach it
|
||||
if (!vbdr.userdevice.equals(_attachIsoDeviceNum) && type == Types.VbdType.CD) {
|
||||
isoVBD = vbd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isoVBD == null) {
|
||||
//create vbd
|
||||
VBD.Record cfgDriveVbdr = new VBD.Record();
|
||||
cfgDriveVbdr.VM = vm;
|
||||
cfgDriveVbdr.empty = true;
|
||||
cfgDriveVbdr.bootable = false;
|
||||
cfgDriveVbdr.userdevice = "autodetect";
|
||||
cfgDriveVbdr.mode = Types.VbdMode.RO;
|
||||
cfgDriveVbdr.type = Types.VbdType.CD;
|
||||
VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr);
|
||||
isoVBD = cfgDriveVBD;
|
||||
|
||||
s_logger.debug("Created CD-ROM VBD for VM: " + vm);
|
||||
}
|
||||
|
||||
if (isoVBD != null) {
|
||||
// If an ISO is already inserted, eject it
|
||||
if (isoVBD.getEmpty(conn) == false) {
|
||||
isoVBD.eject(conn);
|
||||
}
|
||||
|
||||
try {
|
||||
// Insert the new ISO
|
||||
isoVBD.insert(conn, srVdi);
|
||||
s_logger.debug("Attached config drive iso to vm " + vmName);
|
||||
}catch (XmlRpcException ex) {
|
||||
s_logger.debug("Failed to attach config drive iso to vm " + vmName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public SR createLocalIsoSR(Connection conn, String srName) throws XenAPIException, XmlRpcException {
|
||||
|
||||
// if config drive sr already exists then return
|
||||
SR sr = getSRByNameLabelandHost(conn, _configDriveSRName+_host.getIp());
|
||||
|
||||
if (sr != null) {
|
||||
s_logger.debug("Config drive SR already exist, returing it");
|
||||
return sr;
|
||||
}
|
||||
|
||||
try{
|
||||
Map<String, String> deviceConfig = new HashMap<String, String>();
|
||||
|
||||
com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
|
||||
try {
|
||||
sshConnection.connect(null, 60000, 60000);
|
||||
if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
|
||||
throw new CloudRuntimeException("Unable to authenticate");
|
||||
}
|
||||
|
||||
String cmd = "mkdir -p " + _configDriveIsopath;
|
||||
if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
|
||||
throw new CloudRuntimeException("Cannot create directory configdrive_iso on XenServer hosts");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CloudRuntimeException("Unable to create iso folder", e);
|
||||
} finally {
|
||||
sshConnection.close();
|
||||
}
|
||||
s_logger.debug("Created the config drive SR " + srName +" folder path "+ _configDriveIsopath);
|
||||
|
||||
deviceConfig.put("location", _configDriveIsopath);
|
||||
deviceConfig.put("legacy_mode", "true");
|
||||
Host host = Host.getByUuid(conn, _host.getUuid());
|
||||
String type = SRType.ISO.toString();
|
||||
sr = SR.create(conn, host, deviceConfig, new Long(0), _configDriveIsopath, "iso", type, "iso", false, new HashMap<String, String>());
|
||||
|
||||
sr.setNameLabel(conn, srName);
|
||||
sr.setNameDescription(conn, deviceConfig.get("location"));
|
||||
|
||||
sr.scan(conn);
|
||||
s_logger.debug("Config drive ISO SR at the path " + _configDriveIsopath +" got created in host " + _host);
|
||||
return sr;
|
||||
} catch (XenAPIException e) {
|
||||
String msg = "createLocalIsoSR failed! mountpoint " + e.toString();
|
||||
s_logger.warn(msg, e);
|
||||
throw new CloudRuntimeException(msg, e);
|
||||
} catch (Exception e) {
|
||||
String msg = "createLocalIsoSR failed! mountpoint: due to " + e.getMessage();
|
||||
s_logger.warn(msg, e);
|
||||
throw new CloudRuntimeException(msg, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void deleteLocalFolder(String directory) throws Exception {
|
||||
if (directory == null || directory.isEmpty()) {
|
||||
String msg = "Invalid directory path (null/empty) detected. Cannot delete specified directory.";
|
||||
s_logger.debug(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
try {
|
||||
FileUtils.deleteDirectory(new File(directory));
|
||||
} catch (IOException e) {
|
||||
// IOException here means failure to delete. Not swallowing it here to
|
||||
// let the caller handle with appropriate contextual log message.
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package com.cloud.network;
|
|||
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -32,6 +34,8 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
|
|
@ -2281,4 +2285,55 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String[]> generateVmData(String userData, String serviceOffering, String zoneName,
|
||||
String vmName, long vmId, String publicKey, String password, Boolean isWindows) {
|
||||
final List<String[]> vmData = new ArrayList<String[]>();
|
||||
|
||||
if (userData != null) {
|
||||
vmData.add(new String[]{"userdata", "user-data", new String(Base64.decodeBase64(userData.getBytes()))});
|
||||
}
|
||||
vmData.add(new String[]{"metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)});
|
||||
vmData.add(new String[]{"metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)});
|
||||
vmData.add(new String[]{"metadata", "local-hostname", StringUtils.unicodeEscape(vmName)});
|
||||
vmData.add(new String[]{"metadata", "instance-id", vmName});
|
||||
vmData.add(new String[]{"metadata", "vm-id", String.valueOf(vmId)});
|
||||
vmData.add(new String[]{"metadata", "public-keys", publicKey});
|
||||
|
||||
String cloudIdentifier = _configDao.getValue("cloud.identifier");
|
||||
if (cloudIdentifier == null) {
|
||||
cloudIdentifier = "";
|
||||
} else {
|
||||
cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
|
||||
}
|
||||
vmData.add(new String[]{"metadata", "cloud-identifier", cloudIdentifier});
|
||||
|
||||
if (password != null && !password.isEmpty() && !password.equals("saved_password")) {
|
||||
|
||||
// Here we are calculating MD5 checksum to reduce the over head of calculating MD5 checksum
|
||||
// in windows VM in password reset script.
|
||||
|
||||
if (isWindows) {
|
||||
MessageDigest md5 = null;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
s_logger.error("Unexpected exception " + e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Unable to get MD5 MessageDigest", e);
|
||||
}
|
||||
md5.reset();
|
||||
md5.update(password.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
BigInteger bigInt = new BigInteger(1, digest);
|
||||
String hashtext = bigInt.toString(16);
|
||||
|
||||
vmData.add(new String[]{"password", "vm-password-md5checksum", hashtext});
|
||||
}
|
||||
|
||||
vmData.add(new String[]{"password", "vm-password", password});
|
||||
}
|
||||
|
||||
return vmData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3501,6 +3501,31 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
UserVmVO vm = _vmDao.findById(profile.getId());
|
||||
Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||
vm.setDetails(details);
|
||||
|
||||
|
||||
// add userdata info into vm profile
|
||||
Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
|
||||
if(defaultNic != null) {
|
||||
Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
|
||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
||||
final String zoneName = _dcDao.findById(vm.getDataCenterId()).getName();
|
||||
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
||||
|
||||
List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, zoneName, vm.getInstanceName(), vm.getId(),
|
||||
(String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
||||
String vmName = vm.getInstanceName();
|
||||
String configDriveIsoRootFolder = "/tmp";
|
||||
String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
|
||||
profile.setVmData(vmData);
|
||||
profile.setConfigDriveLabel(VmConfigDriveLabel.value());
|
||||
profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder);
|
||||
profile.setConfigDriveIsoFile(isoFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
_templateMgr.prepareIsoForVmProfile(profile);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5268,7 +5293,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax};
|
||||
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax, VmConfigDriveLabel};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in New Issue