mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-5178: DeployVm from ISO fails. Fixed the creation of root
volume and made sure the iso is attached when a vm is deployed.
This commit is contained in:
parent
f37057a215
commit
13740ac135
@ -176,6 +176,7 @@ namespace HypervResource
|
||||
public string format;
|
||||
public string name;
|
||||
public string uuid;
|
||||
public ulong size;
|
||||
public PrimaryDataStoreTO primaryDataStore;
|
||||
|
||||
public static VolumeObjectTO ParseJson(dynamic json)
|
||||
@ -195,7 +196,8 @@ namespace HypervResource
|
||||
dataStore = volumeObjectTOJson.dataStore,
|
||||
format = ((string)volumeObjectTOJson.format),
|
||||
name = (string)volumeObjectTOJson.name,
|
||||
uuid = (string)volumeObjectTOJson.uuid
|
||||
uuid = (string)volumeObjectTOJson.uuid,
|
||||
size = (ulong)volumeObjectTOJson.size
|
||||
};
|
||||
result.primaryDataStore = PrimaryDataStoreTO.ParseJson(volumeObjectTOJson.dataStore);
|
||||
|
||||
@ -312,20 +314,23 @@ namespace HypervResource
|
||||
public static S3TO ParseJson(dynamic json)
|
||||
{
|
||||
S3TO result = null;
|
||||
dynamic s3TOJson = json[CloudStackTypes.S3TO];
|
||||
if (s3TOJson != null)
|
||||
if (json != null)
|
||||
{
|
||||
result = new S3TO()
|
||||
dynamic s3TOJson = json[CloudStackTypes.S3TO];
|
||||
if (s3TOJson != null)
|
||||
{
|
||||
bucketName = (string)s3TOJson.bucketName,
|
||||
secretKey = (string)s3TOJson.secretKey,
|
||||
accessKey = (string)s3TOJson.accessKey,
|
||||
endpoint = (string)s3TOJson.endPoint,
|
||||
httpsFlag = (bool)s3TOJson.httpsFlag
|
||||
};
|
||||
// Delete security credentials in original command. Prevents logger from spilling the beans, as it were.
|
||||
s3TOJson.secretKey = string.Empty;
|
||||
s3TOJson.accessKey = string.Empty;
|
||||
result = new S3TO()
|
||||
{
|
||||
bucketName = (string)s3TOJson.bucketName,
|
||||
secretKey = (string)s3TOJson.secretKey,
|
||||
accessKey = (string)s3TOJson.accessKey,
|
||||
endpoint = (string)s3TOJson.endPoint,
|
||||
httpsFlag = (bool)s3TOJson.httpsFlag
|
||||
};
|
||||
// Delete security credentials in original command. Prevents logger from spilling the beans, as it were.
|
||||
s3TOJson.secretKey = string.Empty;
|
||||
s3TOJson.accessKey = string.Empty;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -380,16 +385,19 @@ namespace HypervResource
|
||||
public static NFSTO ParseJson(dynamic json)
|
||||
{
|
||||
NFSTO result = null;
|
||||
dynamic nfsTOJson = json[CloudStackTypes.NFSTO];
|
||||
if (nfsTOJson != null)
|
||||
if (json != null)
|
||||
{
|
||||
result = new NFSTO()
|
||||
dynamic nfsTOJson = json[CloudStackTypes.NFSTO];
|
||||
if (nfsTOJson != null)
|
||||
{
|
||||
_role = (string)nfsTOJson._role,
|
||||
};
|
||||
// Delete security credentials in original command. Prevents logger from spilling the beans, as it were.
|
||||
String uriStr = (String)nfsTOJson._url;
|
||||
result.uri = new Uri(uriStr);
|
||||
result = new NFSTO()
|
||||
{
|
||||
_role = (string)nfsTOJson._role,
|
||||
};
|
||||
// Delete security credentials in original command. Prevents logger from spilling the beans, as it were.
|
||||
String uriStr = (String)nfsTOJson._url;
|
||||
result.uri = new Uri(uriStr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1010,6 +1010,66 @@ namespace HypervResource
|
||||
}
|
||||
}
|
||||
|
||||
// POST api/HypervResource/CreateObjectCommand
|
||||
[HttpPost]
|
||||
[ActionName(CloudStackTypes.CreateObjectCommand)]
|
||||
public JContainer CreateObjectCommand([FromBody]dynamic cmd)
|
||||
{
|
||||
using (log4net.NDC.Push(Guid.NewGuid().ToString()))
|
||||
{
|
||||
logger.Info(CloudStackTypes.CreateObjectCommand + cmd.ToString());
|
||||
|
||||
bool result = false;
|
||||
string details = null;
|
||||
|
||||
try
|
||||
{
|
||||
VolumeObjectTO volume = VolumeObjectTO.ParseJson(cmd.data);
|
||||
PrimaryDataStoreTO primary = volume.primaryDataStore;
|
||||
ulong volumeSize = volume.size;
|
||||
string volumeName = volume.name + ".vhdx";
|
||||
string volumePath = null;
|
||||
|
||||
if (primary.isLocal)
|
||||
{
|
||||
volumePath = Path.Combine(primary.Path, volumeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
volumePath = @"\\" + primary.uri.Host + primary.uri.LocalPath + @"\" + volumeName;
|
||||
volumePath = volumePath.Replace('/', '\\');
|
||||
Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password);
|
||||
}
|
||||
|
||||
wmiCallsV2.CreateDynamicVirtualHardDisk(volumeSize, volumePath);
|
||||
if (File.Exists(volumePath))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
details = "Failed to create disk with name " + volumePath;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Test by providing wrong key
|
||||
details = CloudStackTypes.CreateObjectCommand + " failed on exception, " + ex.Message;
|
||||
logger.Error(details, ex);
|
||||
}
|
||||
|
||||
object ansContent = new
|
||||
{
|
||||
result = result,
|
||||
details = details,
|
||||
data = cmd.data,
|
||||
contextMap = contextMap
|
||||
};
|
||||
|
||||
return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateObjectAnswer);
|
||||
}
|
||||
}
|
||||
|
||||
// POST api/HypervResource/MaintainCommand
|
||||
// TODO: should this be a NOP?
|
||||
[HttpPost]
|
||||
@ -1085,7 +1145,6 @@ namespace HypervResource
|
||||
{
|
||||
logger.Info(CloudStackTypes.GetVmStatsCommand + cmd.ToString());
|
||||
bool result = false;
|
||||
string details = null;
|
||||
JArray vmNamesJson = cmd.vmNames;
|
||||
string[] vmNames = vmNamesJson.ToObject<string[]>();
|
||||
Dictionary<string, VmStatsEntry> vmProcessorInfo = new Dictionary<string, VmStatsEntry>(vmNames.Length);
|
||||
|
||||
@ -286,7 +286,10 @@ namespace HypervResource
|
||||
{
|
||||
string vhdFile = null;
|
||||
string diskName = null;
|
||||
string isoPath = null;
|
||||
VolumeObjectTO volInfo = VolumeObjectTO.ParseJson(diskDrive.data);
|
||||
TemplateObjectTO templateInfo = TemplateObjectTO.ParseJson(diskDrive.data);
|
||||
|
||||
if (volInfo != null)
|
||||
{
|
||||
// assert
|
||||
@ -327,6 +330,13 @@ namespace HypervResource
|
||||
}
|
||||
logger.Debug("Going to create " + vmName + " with attached voluem " + diskName + " at " + vhdFile);
|
||||
}
|
||||
else if (templateInfo != null && templateInfo.nfsDataStoreTO != null)
|
||||
{
|
||||
NFSTO share = templateInfo.nfsDataStoreTO;
|
||||
Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
|
||||
// The share is mapped, now attach the iso
|
||||
isoPath = Path.Combine(share.UncPath.Replace('/', Path.DirectorySeparatorChar), templateInfo.path);
|
||||
}
|
||||
|
||||
string driveType = diskDrive.type;
|
||||
|
||||
@ -353,6 +363,10 @@ namespace HypervResource
|
||||
logger.DebugFormat("Create disk type {1} (Named: {0}), on vm {2} {3}", diskName, driveResourceType, vmName,
|
||||
string.IsNullOrEmpty(vhdFile) ? " no disk to insert" : ", inserting disk" +vhdFile );
|
||||
AddDiskDriveToVm(newVm, vhdFile, ideCtrllr, driveResourceType);
|
||||
if (isoPath != null)
|
||||
{
|
||||
AttachIso(vmName, isoPath);
|
||||
}
|
||||
}
|
||||
|
||||
String publicIpAddress = "";
|
||||
@ -1484,7 +1498,7 @@ namespace HypervResource
|
||||
// If the Job is done asynchronously
|
||||
if (ret_val == ReturnCode.Started)
|
||||
{
|
||||
JobCompleted(jobPath);
|
||||
StorageJobCompleted(jobPath);
|
||||
}
|
||||
else if (ret_val != ReturnCode.Completed)
|
||||
{
|
||||
@ -1608,6 +1622,32 @@ namespace HypervResource
|
||||
}
|
||||
}
|
||||
|
||||
private static void StorageJobCompleted(ManagementPath jobPath)
|
||||
{
|
||||
StorageJob jobObj = null;
|
||||
for (; ; )
|
||||
{
|
||||
jobObj = new StorageJob(jobPath);
|
||||
if (jobObj.JobState != JobState.Starting && jobObj.JobState != JobState.Running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
logger.InfoFormat("In progress... {0}% completed.", jobObj.PercentComplete);
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
if (jobObj.JobState != JobState.Completed)
|
||||
{
|
||||
var errMsg = string.Format(
|
||||
"Hyper-V Job failed, Error Code:{0}, Description: {1}",
|
||||
jobObj.ErrorCode,
|
||||
jobObj.ErrorDescription);
|
||||
var ex = new WmiException(errMsg);
|
||||
logger.Error(errMsg, ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetProcessorResources(out uint cores, out uint mhz)
|
||||
{
|
||||
// Processor processors
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -135,6 +135,9 @@
|
||||
<Compile Include="ROOT.virtualization.v2.Msvm_StorageAllocationSettingData.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ROOT.virtualization.v2.Msvm_StorageJob.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ROOT.virtualization.v2.Msvm_SummaryInformation.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user