use of com.cloud.agent.api.StartAnswer in project CloudStack-archive by CloudStack-extras.
the class MockVmManagerImpl method startVM.
@Override
public Answer startVM(StartCommand cmd, SimulatorInfo info) {
VirtualMachineTO vm = cmd.getVirtualMachine();
String result = startVM(vm.getName(), vm.getNics(), vm.getCpus() * vm.getSpeed(), vm.getMaxRam(), vm.getBootArgs(), info.getHostUuid());
if (result != null) {
return new StartAnswer(cmd, result);
} else {
return new StartAnswer(cmd);
}
}
use of com.cloud.agent.api.StartAnswer in project cloudstack by apache.
the class UserVmManagerImpl method finalizeStart.
@Override
public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
UserVmVO vm = _vmDao.findById(profile.getId());
Answer[] answersToCmds = cmds.getAnswers();
if (answersToCmds == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Returning from finalizeStart() since there are no answers to read");
}
return true;
}
Answer startAnswer = cmds.getAnswer(StartAnswer.class);
String returnedIp = null;
String originalIp = null;
if (startAnswer != null) {
StartAnswer startAns = (StartAnswer) startAnswer;
VirtualMachineTO vmTO = startAns.getVirtualMachine();
for (NicTO nicTO : vmTO.getNics()) {
if (nicTO.getType() == TrafficType.Guest) {
returnedIp = nicTO.getIp();
}
}
}
List<NicVO> nics = _nicDao.listByVmId(vm.getId());
NicVO guestNic = null;
NetworkVO guestNetwork = null;
for (NicVO nic : nics) {
NetworkVO network = _networkDao.findById(nic.getNetworkId());
long isDefault = (nic.isDefaultNic()) ? 1 : 0;
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
if (network.getTrafficType() == TrafficType.Guest) {
originalIp = nic.getIPv4Address();
guestNic = nic;
guestNetwork = network;
// In vmware, we will be effecting pvlan settings in portgroups in StartCommand.
if (profile.getHypervisorType() != HypervisorType.VMware) {
if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
if (!setupVmForPvlan(true, hostId, nicProfile)) {
return false;
}
}
}
}
}
boolean ipChanged = false;
if (originalIp != null && !originalIp.equalsIgnoreCase(returnedIp)) {
if (returnedIp != null && guestNic != null) {
guestNic.setIPv4Address(returnedIp);
ipChanged = true;
}
}
if (returnedIp != null && !returnedIp.equalsIgnoreCase(originalIp)) {
if (guestNic != null) {
guestNic.setIPv4Address(returnedIp);
ipChanged = true;
}
}
if (ipChanged) {
_dcDao.findById(vm.getDataCenterId());
UserVmVO userVm = _vmDao.findById(profile.getId());
// dc.getDhcpProvider().equalsIgnoreCase(Provider.ExternalDhcpServer.getName())
if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestNetwork.getId(), Service.Dhcp, Provider.ExternalDhcpServer)) {
_nicDao.update(guestNic.getId(), guestNic);
userVm.setPrivateIpAddress(guestNic.getIPv4Address());
_vmDao.update(userVm.getId(), userVm);
s_logger.info("Detected that ip changed in the answer, updated nic in the db with new ip " + returnedIp);
}
}
// get system ip and create static nat rule for the vm
try {
_rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
} catch (Exception ex) {
s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
return false;
}
Answer answer = cmds.getAnswer("restoreVMSnapshot");
if (answer != null && answer instanceof RestoreVMSnapshotAnswer) {
RestoreVMSnapshotAnswer restoreVMSnapshotAnswer = (RestoreVMSnapshotAnswer) answer;
if (restoreVMSnapshotAnswer == null || !restoreVMSnapshotAnswer.getResult()) {
s_logger.warn("Unable to restore the vm snapshot from image file to the VM: " + restoreVMSnapshotAnswer.getDetails());
}
}
final VirtualMachineProfile vmProfile = profile;
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
final UserVmVO vm = _vmDao.findById(vmProfile.getId());
final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
for (NicVO nic : nics) {
Network network = _networkModel.getNetwork(nic.getNetworkId());
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
}
}
}
});
return true;
}
use of com.cloud.agent.api.StartAnswer in project cloudstack by apache.
the class VmwareResource method execute.
protected StartAnswer execute(StartCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd));
}
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
boolean vmAlreadyExistsInVcenter = false;
String existingVmName = null;
VirtualMachineFileInfo existingVmFileInfo = null;
VirtualMachineFileLayoutEx existingVmFileLayout = null;
Pair<String, String> names = composeVmNames(vmSpec);
String vmInternalCSName = names.first();
String vmNameOnVcenter = names.second();
String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
DiskTO rootDiskTO = null;
// This helps avoid mix of different scsi subtype controllers in instance.
if (DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) {
dataDiskController = DiskControllerType.scsi.toString();
}
// Validate the controller types
dataDiskController = DiskControllerType.getType(dataDiskController).toString();
rootDiskController = DiskControllerType.getType(rootDiskController).toString();
if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) {
throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController);
}
if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) {
throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController);
}
Pair<String, String> controllerInfo = new Pair<String, String>(rootDiskController, dataDiskController);
Boolean systemVm = vmSpec.getType().isUsedBySystem();
// Thus, vmInternalCSName always holds i-x-y, the cloudstack generated internal VM name.
VmwareContext context = getServiceContext();
DatacenterMO dcMo = null;
try {
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
VmwareHypervisorHost hyperHost = getHyperHost(context);
dcMo = new DatacenterMO(hyperHost.getContext(), hyperHost.getHyperHostDatacenter());
// Validate VM name is unique in Datacenter
VirtualMachineMO vmInVcenter = dcMo.checkIfVmAlreadyExistsInVcenter(vmNameOnVcenter, vmInternalCSName);
if (vmInVcenter != null) {
vmAlreadyExistsInVcenter = true;
String msg = "VM with name: " + vmNameOnVcenter + " already exists in vCenter.";
s_logger.error(msg);
throw new Exception(msg);
}
String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
DiskTO[] disks = validateDisks(vmSpec.getDisks());
assert (disks.length > 0);
NicTO[] nics = vmSpec.getNics();
HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails = inferDatastoreDetailsFromDiskInfo(hyperHost, context, disks, cmd);
if ((dataStoresDetails == null) || (dataStoresDetails.isEmpty())) {
String msg = "Unable to locate datastore details of the volumes to be attached";
s_logger.error(msg);
throw new Exception(msg);
}
DatastoreMO dsRootVolumeIsOn = getDatastoreThatRootDiskIsOn(dataStoresDetails, disks);
if (dsRootVolumeIsOn == null) {
String msg = "Unable to locate datastore details of root volume";
s_logger.error(msg);
throw new Exception(msg);
}
VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
int firstScsiControllerBusNum = 0;
int numScsiControllerForSystemVm = 1;
boolean hasSnapshot = false;
if (vmMo != null) {
s_logger.info("VM " + vmInternalCSName + " already exists, tear down devices for reconfiguration");
if (getVmPowerState(vmMo) != PowerState.PowerOff)
vmMo.safePowerOff(_shutdownWaitMs);
// retrieve disk information before we tear down
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
if (!hasSnapshot)
vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
else
vmMo.tearDownDevices(new Class<?>[] { VirtualEthernetCard.class });
if (systemVm) {
ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
} else {
ensureDiskControllers(vmMo, controllerInfo);
}
} else {
ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
assert (morDc != null);
vmMo = hyperHost.findVmOnPeerHyperHost(vmInternalCSName);
if (vmMo != null) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Found vm " + vmInternalCSName + " at other host, relocate to " + hyperHost.getHyperHostName());
}
takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
if (getVmPowerState(vmMo) != PowerState.PowerOff)
vmMo.safePowerOff(_shutdownWaitMs);
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
if (!hasSnapshot)
vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
else
vmMo.tearDownDevices(new Class<?>[] { VirtualEthernetCard.class });
if (systemVm) {
// System volumes doesn't require more than 1 SCSI controller as there is no requirement for data volumes.
ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
} else {
ensureDiskControllers(vmMo, controllerInfo);
}
} else {
// If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
if (existingVmInDc != null) {
s_logger.debug("Found VM: " + vmInternalCSName + " on a host in a different cluster. Unregistering the exisitng VM.");
existingVmName = existingVmInDc.getName();
existingVmFileInfo = existingVmInDc.getFileInfo();
existingVmFileLayout = existingVmInDc.getFileLayout();
existingVmInDc.unregisterVm();
}
Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
for (DiskTO vol : disks) {
if (vol.getType() == Volume.Type.ROOT) {
Map<String, String> details = vol.getDetails();
boolean managed = false;
if (details != null) {
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
}
if (managed) {
String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
} else {
DataStoreTO primaryStore = vol.getData().getDataStore();
rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
}
}
}
assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
boolean vmFolderExists = rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter);
String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false);
if (vmFolderExists && vmxFileFullPath != null) {
// VM can be registered only if .vmx is present.
registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
if (vmMo != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName());
}
}
tearDownVm(vmMo);
} else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int) (vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), guestOsId, rootDiskDataStoreDetails.first(), false, controllerInfo, systemVm)) {
throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
}
}
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
if (vmMo == null) {
throw new Exception("Failed to find the newly create or relocated VM. vmName: " + vmInternalCSName);
}
}
int totalChangeDevices = disks.length + nics.length;
DiskTO volIso = null;
if (vmSpec.getType() != VirtualMachine.Type.User) {
// system VM needs a patch ISO
totalChangeDevices++;
} else {
volIso = getIsoDiskTO(disks);
if (volIso == null)
totalChangeDevices++;
}
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), getReservedCpuMHZ(vmSpec), (int) (vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse());
// Check for multi-cores per socket settings
int numCoresPerSocket = 1;
String coresPerSocket = vmSpec.getDetails().get("cpu.corespersocket");
if (coresPerSocket != null) {
String apiVersion = HypervisorHostHelper.getVcenterApiVersion(vmMo.getContext());
// Property 'numCoresPerSocket' is supported since vSphere API 5.0
if (apiVersion.compareTo("5.0") >= 0) {
numCoresPerSocket = NumbersUtil.parseInt(coresPerSocket, 1);
vmConfigSpec.setNumCoresPerSocket(numCoresPerSocket);
}
}
// Check for hotadd settings
vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId));
String hostApiVersion = ((HostMO) hyperHost).getHostAboutInfo().getApiVersion();
if (numCoresPerSocket > 1 && hostApiVersion.compareTo("5.0") < 0) {
s_logger.warn("Dynamic scaling of CPU is not supported for Virtual Machines with multi-core vCPUs in case of ESXi hosts 4.1 and prior. Hence CpuHotAdd will not be" + " enabled for Virtual Machine: " + vmInternalCSName);
vmConfigSpec.setCpuHotAddEnabled(false);
} else {
vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId));
}
configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
int i = 0;
int ideUnitNumber = 0;
int scsiUnitNumber = 0;
int nicUnitNumber = 0;
int ideControllerKey = vmMo.getIDEDeviceControllerKey();
int scsiControllerKey = vmMo.getGenericScsiDeviceControllerKeyNoException();
int controllerKey;
// prepare systemvm patch ISO
if (vmSpec.getType() != VirtualMachine.Type.User) {
// attach ISO (for patching of system VM)
Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
String secStoreUrl = secStoreUrlAndId.first();
Long secStoreId = secStoreUrlAndId.second();
if (secStoreUrl == null) {
String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
throw new Exception(msg);
}
mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
if (morSecDs == null) {
String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
throw new Exception(msg);
}
DatastoreMO secDsMo = new DatastoreMO(hyperHost.getContext(), morSecDs);
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, String.format("[%s] systemvm/%s", secDsMo.getName(), mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), true, true, ideUnitNumber++, i + 1);
deviceConfigSpecArray[i].setDevice(isoInfo.first());
if (isoInfo.second()) {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
} else {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
}
} else {
// Note: we will always plug a CDROM device
if (volIso != null) {
TemplateObjectTO iso = (TemplateObjectTO) volIso.getData();
if (iso.getPath() != null && !iso.getPath().isEmpty()) {
DataStoreTO imageStore = iso.getDataStore();
if (!(imageStore instanceof NfsTO)) {
s_logger.debug("unsupported protocol");
throw new Exception("unsupported protocol");
}
NfsTO nfsImageStore = (NfsTO) imageStore;
String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath();
Pair<String, ManagedObjectReference> isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath);
assert (isoDatastoreInfo != null);
assert (isoDatastoreInfo.second() != null);
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1);
deviceConfigSpecArray[i].setDevice(isoInfo.first());
if (isoInfo.second()) {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
} else {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
}
}
} else {
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, null, null, true, true, ideUnitNumber++, i + 1);
deviceConfigSpecArray[i].setDevice(isoInfo.first());
if (isoInfo.second()) {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
} else {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
}
}
}
i++;
//
// Setup ROOT/DATA disk devices
//
DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
for (DiskTO vol : sortedDisks) {
if (vol.getType() == Volume.Type.ISO)
continue;
VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
controllerKey = getDiskController(matchingExistingDisk, vol, vmSpec, ideControllerKey, scsiControllerKey);
String diskController = getDiskController(vmMo, matchingExistingDisk, vol, new Pair<String, String>(rootDiskController, dataDiskController));
if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
diskController = vmMo.getRecommendedDiskController(null);
}
if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
controllerKey = vmMo.getIDEControllerKey(ideUnitNumber);
if (vol.getType() == Volume.Type.DATADISK) {
// Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume
if (vmMo.getNumberOfVirtualDisks() > 3) {
throw new CloudRuntimeException("Found more than 3 virtual disks attached to this VM [" + vmMo.getVmName() + "]. Unable to implement the disks over " + diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device.");
}
}
} else {
controllerKey = vmMo.getScsiDiskControllerKeyNoException(diskController);
if (controllerKey == -1) {
// This may happen for ROOT legacy VMs which doesn't have recommended disk controller when global configuration parameter 'vmware.root.disk.controller' is set to "osdefault"
// Retrieve existing controller and use.
Ternary<Integer, Integer, DiskControllerType> vmScsiControllerInfo = vmMo.getScsiControllerInfo();
DiskControllerType existingControllerType = vmScsiControllerInfo.third();
controllerKey = vmMo.getScsiDiskControllerKeyNoException(existingControllerType.toString());
}
}
if (!hasSnapshot) {
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
DataStoreTO primaryStore = volumeTO.getDataStore();
Map<String, String> details = vol.getDetails();
boolean managed = false;
String iScsiName = null;
if (details != null) {
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
iScsiName = details.get(DiskTO.IQN);
}
// if the storage is managed, iScsiName should not be null
String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
assert (volumeDsDetails != null);
String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails);
if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
scsiUnitNumber++;
VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber)) ? ((ideUnitNumber++) % VmwareHelper.MAX_IDE_CONTROLLER_COUNT) : scsiUnitNumber++, i + 1);
if (vol.getType() == Volume.Type.ROOT)
rootDiskTO = vol;
deviceConfigSpecArray[i].setDevice(device);
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare volume at new device " + _gson.toJson(device));
i++;
} else {
if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
scsiUnitNumber++;
if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber))
ideUnitNumber++;
else
scsiUnitNumber++;
}
}
//
if (guestOsId.startsWith("darwin")) {
//Mac OS
VirtualDevice[] devices = vmMo.getMatchedDevices(new Class<?>[] { VirtualUSBController.class });
if (devices.length == 0) {
s_logger.debug("No USB Controller device on VM Start. Add USB Controller device for Mac OS VM " + vmInternalCSName);
//For Mac OS X systems, the EHCI+UHCI controller is enabled by default and is required for USB mouse and keyboard access.
VirtualDevice usbControllerDevice = VmwareHelper.prepareUSBControllerDevice();
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
deviceConfigSpecArray[i].setDevice(usbControllerDevice);
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare USB controller at new device " + _gson.toJson(deviceConfigSpecArray[i]));
i++;
} else {
s_logger.debug("USB Controller device exists on VM Start for Mac OS VM " + vmInternalCSName);
}
}
//
// Setup NIC devices
//
VirtualDevice nic;
int nicMask = 0;
int nicCount = 0;
VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.valueOf(vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER));
if (s_logger.isDebugEnabled())
s_logger.debug("VM " + vmInternalCSName + " will be started with NIC device type: " + nicDeviceType);
NiciraNvpApiVersion.logNiciraApiVersion();
Map<String, String> nicUuidToDvSwitchUuid = new HashMap<String, String>();
for (NicTO nicTo : sortNicsByDeviceId(nics)) {
s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
if ((nicTo.getBroadcastType() != BroadcastDomainType.Lswitch) || (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch && NiciraNvpApiVersion.isApiVersionLowerThan("4.2"))) {
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
String dvSwitchUuid;
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), nicUnitNumber++, i + 1, true, true);
if (nicTo.getUuid() != null) {
nicUuidToDvSwitchUuid.put(nicTo.getUuid(), dvSwitchUuid);
}
} else {
s_logger.info("Preparing NIC device on network " + networkInfo.second());
nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), nicUnitNumber++, i + 1, true, true);
}
} else {
//if NSX API VERSION >= 4.2, connect to br-int (nsx.network), do not create portgroup else previous behaviour
nic = VmwareHelper.prepareNicOpaque(vmMo, nicDeviceType, networkInfo.second(), nicTo.getMac(), nicUnitNumber++, i + 1, true, true);
}
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
deviceConfigSpecArray[i].setDevice(nic);
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i]));
// this is really a hacking for DomR, upon DomR startup, we will reset all the NIC allocation after eth3
if (nicCount < 3)
nicMask |= (1 << nicCount);
i++;
nicCount++;
}
for (int j = 0; j < i; j++) vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[j]);
//
// Setup VM options
//
// pass boot arguments through machine.id & perform customized options to VMX
ArrayList<OptionValue> extraOptions = new ArrayList<OptionValue>();
configBasicExtraOption(extraOptions, vmSpec);
configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
configCustomExtraOption(extraOptions, vmSpec);
// config VNC
String keyboardLayout = null;
if (vmSpec.getDetails() != null)
keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD);
vmConfigSpec.getExtraConfig().addAll(Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout)));
// config video card
configureVideoCard(vmMo, vmSpec, vmConfigSpec);
//
if (!vmMo.configureVm(vmConfigSpec)) {
throw new Exception("Failed to configure VM before start. vmName: " + vmInternalCSName);
}
if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
hyperHost.setRestartPriorityForVM(vmMo, DasVmPriority.HIGH.value());
}
//For resizing root disk.
if (rootDiskTO != null && !hasSnapshot) {
resizeRootDisk(vmMo, rootDiskTO, hyperHost, context);
}
//
// Post Configuration
//
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMask));
postNvpConfigBeforeStart(vmMo, vmSpec);
Map<String, String> iqnToPath = new HashMap<String, String>();
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToPath, hyperHost, context);
//
if (!vmMo.powerOn()) {
throw new Exception("Failed to start VM. vmName: " + vmInternalCSName + " with hostname " + vmNameOnVcenter);
}
StartAnswer startAnswer = new StartAnswer(cmd);
startAnswer.setIqnToPath(iqnToPath);
// Since VM was successfully powered-on, if there was an existing VM in a different cluster that was unregistered, delete all the files associated with it.
if (existingVmName != null && existingVmFileLayout != null) {
deleteUnregisteredVmFiles(existingVmFileLayout, dcMo, true);
}
return startAnswer;
} catch (Throwable e) {
if (e instanceof RemoteException) {
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
invalidateServiceContext();
}
String msg = "StartCommand failed due to " + VmwareHelper.getExceptionMessage(e);
s_logger.warn(msg, e);
StartAnswer startAnswer = new StartAnswer(cmd, msg);
if (vmAlreadyExistsInVcenter) {
startAnswer.setContextParam("stopRetry", "true");
}
// Since VM start failed, if there was an existing VM in a different cluster that was unregistered, register it back.
if (existingVmName != null && existingVmFileInfo != null) {
s_logger.debug("Since VM start failed, registering back an existing VM: " + existingVmName + " that was unregistered");
try {
DatastoreFile fileInDatastore = new DatastoreFile(existingVmFileInfo.getVmPathName());
DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
registerVm(existingVmName, existingVmDsMo);
} catch (Exception ex) {
String message = "Failed to register an existing VM: " + existingVmName + " due to " + VmwareHelper.getExceptionMessage(ex);
s_logger.warn(message, ex);
}
}
return startAnswer;
} finally {
}
}
use of com.cloud.agent.api.StartAnswer in project cloudstack by apache.
the class CitrixStartCommandWrapper method execute.
@Override
public Answer execute(final StartCommand command, final CitrixResourceBase citrixResourceBase) {
final Connection conn = citrixResourceBase.getConnection();
final VirtualMachineTO vmSpec = command.getVirtualMachine();
final String vmName = vmSpec.getName();
VmPowerState state = VmPowerState.HALTED;
VM vm = null;
// if a VDI is created, record its UUID to send back to the CS MS
final Map<String, String> iqnToPath = new HashMap<String, String>();
try {
final Set<VM> vms = VM.getByNameLabel(conn, vmName);
if (vms != null) {
for (final VM v : vms) {
final VM.Record vRec = v.getRecord(conn);
if (vRec.powerState == VmPowerState.HALTED) {
v.destroy(conn);
} else if (vRec.powerState == VmPowerState.RUNNING) {
final String host = vRec.residentOn.getUuid(conn);
final String msg = "VM " + vmName + " is runing on host " + host;
s_logger.debug(msg);
return new StartAnswer(command, msg, host);
} else {
final String msg = "There is already a VM having the same name " + vmName + " vm record " + vRec.toString();
s_logger.warn(msg);
return new StartAnswer(command, msg);
}
}
}
s_logger.debug("1. The VM " + vmName + " is in Starting state.");
final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid());
vm = citrixResourceBase.createVmFromTemplate(conn, vmSpec, host);
final GPUDeviceTO gpuDevice = vmSpec.getGpuDevice();
if (gpuDevice != null) {
s_logger.debug("Creating VGPU for of VGPU type: " + gpuDevice.getVgpuType() + " in GPU group " + gpuDevice.getGpuGroup() + " for VM " + vmName);
citrixResourceBase.createVGPU(conn, command, vm, gpuDevice);
}
if (vmSpec.getType() != VirtualMachine.Type.User) {
citrixResourceBase.createPatchVbd(conn, vmName, vm);
}
// put cdrom at the first place in the list
List<DiskTO> disks = new ArrayList<DiskTO>(vmSpec.getDisks().length);
int index = 0;
for (final DiskTO disk : vmSpec.getDisks()) {
if (Volume.Type.ISO.equals(disk.getType())) {
disks.add(0, disk);
} else {
disks.add(index, disk);
}
index++;
}
for (DiskTO disk : disks) {
final VDI newVdi = citrixResourceBase.prepareManagedDisk(conn, disk, vmSpec.getId(), vmSpec.getName());
if (newVdi != null) {
final String path = newVdi.getUuid(conn);
iqnToPath.put(disk.getDetails().get(DiskTO.IQN), path);
}
citrixResourceBase.createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi);
}
for (final NicTO nic : vmSpec.getNics()) {
citrixResourceBase.createVif(conn, vmName, vm, vmSpec, nic);
}
citrixResourceBase.startVM(conn, host, vm, vmName);
if (citrixResourceBase.isOvs()) {
// TODO(Salvatore-orlando): This code should go
for (final NicTO nic : vmSpec.getNics()) {
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) {
final HashMap<String, String> args = citrixResourceBase.parseDefaultOvsRuleComamnd(BroadcastDomainType.getValue(nic.getBroadcastUri()));
final OvsSetTagAndFlowCommand flowCmd = new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId")));
final CitrixRequestWrapper citrixRequestWrapper = CitrixRequestWrapper.getInstance();
final OvsSetTagAndFlowAnswer r = (OvsSetTagAndFlowAnswer) citrixRequestWrapper.execute(flowCmd, citrixResourceBase);
if (!r.getResult()) {
s_logger.warn("Failed to set flow for VM " + r.getVmId());
} else {
s_logger.info("Success to set flow for VM " + r.getVmId());
}
}
}
}
if (citrixResourceBase.canBridgeFirewall()) {
String result = null;
if (vmSpec.getType() != VirtualMachine.Type.User) {
final NicTO[] nics = vmSpec.getNics();
boolean secGrpEnabled = false;
for (final NicTO nic : nics) {
if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
secGrpEnabled = true;
break;
}
}
if (secGrpEnabled) {
result = citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", vmName);
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
s_logger.warn("Failed to program default network rules for " + vmName);
} else {
s_logger.info("Programmed default network rules for " + vmName);
}
}
} else {
// For user vm, program the rules for each nic if the
// isolation uri scheme is ec2
final NicTO[] nics = vmSpec.getNics();
for (final NicTO nic : nics) {
if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
final List<String> nicSecIps = nic.getNicSecIps();
String secIpsStr;
final StringBuilder sb = new StringBuilder();
if (nicSecIps != null) {
for (final String ip : nicSecIps) {
sb.append(ip).append(":");
}
secIpsStr = sb.toString();
} else {
secIpsStr = "0:";
}
result = citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", Long.toString(vmSpec.getId()), "secIps", secIpsStr);
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
s_logger.warn("Failed to program default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac());
} else {
s_logger.info("Programmed default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac());
}
}
}
}
}
state = VmPowerState.RUNNING;
final StartAnswer startAnswer = new StartAnswer(command);
startAnswer.setIqnToPath(iqnToPath);
return startAnswer;
} catch (final Exception e) {
s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e);
final String msg = citrixResourceBase.handleVmStartFailure(conn, vmName, vm, "", e);
final StartAnswer startAnswer = new StartAnswer(command, msg);
startAnswer.setIqnToPath(iqnToPath);
return startAnswer;
} finally {
if (state != VmPowerState.HALTED) {
s_logger.debug("2. The VM " + vmName + " is in " + state + " state.");
} else {
s_logger.debug("The VM is in stopped state, detected problem during startup : " + vmName);
}
}
}
use of com.cloud.agent.api.StartAnswer in project cloudstack by apache.
the class BareMetalResourceBase method execute.
protected StartAnswer execute(StartCommand cmd) {
VirtualMachineTO vm = cmd.getVirtualMachine();
OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
if (!doScript(_getStatusCommand, interpreter)) {
return new StartAnswer(cmd, "Cannot get current power status of " + getName());
}
if (isPowerOn(interpreter.getLines())) {
if (!doScript(_rebootCommand)) {
return new StartAnswer(cmd, "IPMI reboot failed");
}
} else {
if (!doScript(_powerOnCommand)) {
return new StartAnswer(cmd, "IPMI power on failed");
}
}
if (_isEchoScAgent) {
SecurityGroupHttpClient hc = new SecurityGroupHttpClient();
boolean echoRet = hc.echo(vm.getNics()[0].getIp(), TimeUnit.MINUTES.toMillis(30), TimeUnit.MINUTES.toMillis(1));
if (!echoRet) {
return new StartAnswer(cmd, String.format("Call security group agent on vm[%s] timeout", vm.getNics()[0].getIp()));
}
}
if (provisionDoneNotificationOn) {
QueryBuilder<VMInstanceVO> q = QueryBuilder.create(VMInstanceVO.class);
q.and(q.entity().getInstanceName(), SearchCriteria.Op.EQ, vm.getName());
VMInstanceVO vmvo = q.find();
if (vmvo.getLastHostId() == null) {
// this is new created vm
long timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(isProvisionDoneNotificationTimeout);
while (timeout > System.currentTimeMillis()) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
s_logger.warn(e.getMessage(), e);
}
q = QueryBuilder.create(VMInstanceVO.class);
q.and(q.entity().getInstanceName(), SearchCriteria.Op.EQ, vm.getName());
vmvo = q.find();
if (vmvo == null) {
return new StartAnswer(cmd, String.format("cannot find vm[name:%s] while waiting for baremtal provision done notification", vm.getName()));
}
if (VirtualMachine.State.Running == vmvo.getState()) {
return new StartAnswer(cmd);
}
s_logger.debug(String.format("still wait for baremetal provision done notification for vm[name:%s], current vm state is %s", vmvo.getInstanceName(), vmvo.getState()));
}
return new StartAnswer(cmd, String.format("timeout after %s seconds, no baremetal provision done notification received. vm[name:%s] failed to start", isProvisionDoneNotificationTimeout, vm.getName()));
}
}
s_logger.debug("Start bare metal vm " + vm.getName() + "successfully");
_vmName = vm.getName();
return new StartAnswer(cmd);
}
Aggregations