CLOUDSTACK-728 Get the framework in place the support the removal of the portgroup that is created for a nic connected to an lswitch.

Add a command to tell a hypervisor guru to take some action when
expunging a nic
This commit is contained in:
Hugo Trippaers 2013-07-10 17:48:33 +02:00
parent 7dc3d3bae5
commit 2691970f28
6 changed files with 550 additions and 380 deletions

View File

@ -59,11 +59,18 @@ public interface HypervisorGuru extends Adapter {
* @return
*/
NicTO toNicTO(NicProfile profile);
/**
* Give hypervisor guru opportunity to decide if certain command needs to be done after expunge VM from DB
* @param vm
* @return a list of Commands
*/
List<Command> finalizeExpunge(VirtualMachine vm);
/**
* Give the hypervisor guru the opportinity to decide if additional clean is
* required for nics before expunging the VM
*
*/
List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics);
}

View File

@ -0,0 +1,55 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.agent.api;
import java.util.UUID;
/**
* This command will tell the hypervisor to cleanup any resources dedicated for
* this particular nic. Orginally implemented to cleanup dedicated portgroups
* from a vmware standard switch
*
*/
public class UnregisterNicCommand extends Command {
private String vmName;
private String trafficLabel;
private UUID nicUuid;
public UnregisterNicCommand(String vmName, String trafficLabel, UUID nicUuid) {
this.nicUuid = nicUuid;
this.vmName = vmName;
this.trafficLabel = trafficLabel;
}
public UUID getNicUuid() {
return nicUuid;
}
public String getVmName() {
return vmName;
}
public String getTrafficLabel() {
return trafficLabel;
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -12,7 +12,7 @@
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.guru;
@ -23,20 +23,19 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.UnregisterNicCommand;
import com.cloud.agent.api.UnregisterVMCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
@ -60,11 +59,15 @@ import com.cloud.hypervisor.HypervisorGuruBase;
import com.cloud.hypervisor.vmware.manager.VmwareManager;
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
import com.cloud.network.Network.Provider;
import com.cloud.network.NetworkModel;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.secstorage.CommandExecLogDao;
import com.cloud.secstorage.CommandExecLogVO;
import com.cloud.storage.DataStoreRole;
@ -79,10 +82,14 @@ import com.cloud.utils.net.NetUtils;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.NicDao;
import org.apache.cloudstack.storage.command.CopyCommand;
@Local(value=HypervisorGuru.class)
public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
@ -98,6 +105,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject SecondaryStorageVmManager _secStorageMgr;
@Inject NetworkModel _networkMgr;
@Inject ConfigurationDao _configDao;
@Inject
NicDao _nicDao;
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
protected VMwareGuru() {
super();
@ -118,7 +131,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
details = new HashMap<String, String>();
String nicDeviceType = details.get(VmDetailConstants.NIC_ADAPTER);
if(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
if(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
|| vm.getVirtualMachine() instanceof SecondaryStorageVmVO) {
if(nicDeviceType == null) {
@ -144,13 +157,13 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
}
}
}
String diskDeviceType = details.get(VmDetailConstants.ROOK_DISK_CONTROLLER);
if (!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
|| vm.getVirtualMachine() instanceof SecondaryStorageVmVO)){
if (!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
|| vm.getVirtualMachine() instanceof SecondaryStorageVmVO)){
// user vm
if (diskDeviceType == null){
details.put(VmDetailConstants.ROOK_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
details.put(VmDetailConstants.ROOK_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
}
}
@ -236,19 +249,19 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
String bootArgs = to.getBootArgs();
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
}
// Don't do this if the virtual machine is one of the special types
// Should only be done on user machines
if(!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
if(!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
|| vm.getVirtualMachine() instanceof SecondaryStorageVmVO)) {
String nestedVirt = _configDao.getValue(Config.VmwareEnableNestedVirtualization.key());
if (nestedVirt != null) {
s_logger.debug("Nested virtualization requested, adding flag to vm configuration");
details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, nestedVirt);
to.setDetails(details);
}
}
// Determine the VM's OS description
@ -284,7 +297,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
public long getCommandHostDelegation(long hostId, Command cmd) {
boolean needDelegation = false;
if(cmd instanceof PrimaryStorageDownloadCommand ||
if(cmd instanceof PrimaryStorageDownloadCommand ||
cmd instanceof BackupSnapshotCommand ||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
@ -299,7 +312,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
DataStoreTO srcStoreTO = srcData.getDataStore();
DataTO destData = cpyCommand.getDestTO();
DataStoreTO destStoreTO = destData.getDataStore();
if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
needDelegation = false;
@ -309,14 +322,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
} else {
needDelegation = true;
}
}
/* Fang: remove this before checking in */
// needDelegation = false;
if (cmd instanceof PrepareOVAPackingCommand ||
cmd instanceof CreateVolumeOVACommand ) {
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
}
if(needDelegation) {
HostVO host = _hostDao.findById(hostId);
@ -339,8 +352,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
_cmdExecLogDao.persist(execLog);
cmd.setContextParam("execid", String.valueOf(execLog.getId()));
if(cmd instanceof BackupSnapshotCommand ||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
if(cmd instanceof BackupSnapshotCommand ||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
cmd instanceof CopyVolumeCommand ||
cmd instanceof CreateVolumeOVACommand ||
@ -349,14 +362,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
String workerName = _vmwareMgr.composeWorkerName();
long checkPointId = 1;
// FIXME: Fix long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
// FIXME: Fix long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
cmd.setContextParam("worker", workerName);
cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
// some commands use 2 workers
String workerName2 = _vmwareMgr.composeWorkerName();
long checkPointId2 = 1;
// FIXME: Fix long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
// FIXME: Fix long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
cmd.setContextParam("worker2", workerName2);
cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2));
}
@ -388,7 +401,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
return tokens[0] + "@" + vCenterIp;
}
@Override
public List<Command> finalizeExpunge(VirtualMachine vm) {
UnregisterVMCommand unregisterVMCommand = new UnregisterVMCommand(vm.getInstanceName());
@ -396,4 +409,25 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
commands.add(unregisterVMCommand);
return commands;
}
@Override
public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
List<Command> commands = new ArrayList<Command>();
List<NicVO> nicVOs = _nicDao.listByVmId(vm.getId());
for (NicVO nic : nicVOs) {
NetworkVO network = _networkDao.findById(nic.getNetworkId());
if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch) {
s_logger.debug("Nic " + nic.toString() + " is connected to an lswitch, cleanup required");
NetworkVO networkVO = _networkDao.findById(nic.getNetworkId());
// We need the traffic label to figure out which vSwitch has the
// portgroup
PhysicalNetworkTrafficTypeVO trafficTypeVO = _physicalNetworkTrafficTypeDao.findBy(
networkVO.getPhysicalNetworkId(), networkVO.getTrafficType());
UnregisterNicCommand unregisterNicCommand = new UnregisterNicCommand(vm.getInstanceName(),
trafficTypeVO.getVmwareNetworkLabel(), UUID.fromString(nic.getUuid()));
commands.add(unregisterNicCommand);
}
}
return commands;
}
}

View File

@ -193,6 +193,7 @@ import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.agent.api.UnPlugNicAnswer;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.UnregisterNicCommand;
import com.cloud.agent.api.UnregisterVMCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.ValidateSnapshotAnswer;
@ -391,7 +392,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
public Gson getGson() {
return _gson;
return _gson;
}
public VmwareResource() {
@ -545,12 +546,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
} else if (clz == SetNetworkACLCommand.class) {
answer = execute((SetNetworkACLCommand) cmd);
} else if (cmd instanceof CreateVMSnapshotCommand) {
return execute((CreateVMSnapshotCommand)cmd);
return execute((CreateVMSnapshotCommand)cmd);
} else if(cmd instanceof DeleteVMSnapshotCommand){
return execute((DeleteVMSnapshotCommand)cmd);
return execute((DeleteVMSnapshotCommand)cmd);
} else if(cmd instanceof RevertToVMSnapshotCommand){
return execute((RevertToVMSnapshotCommand)cmd);
}else if (clz == SetPortForwardingRulesVpcCommand.class) {
return execute((RevertToVMSnapshotCommand)cmd);
}else if (clz == SetPortForwardingRulesVpcCommand.class) {
answer = execute((SetPortForwardingRulesVpcCommand) cmd);
} else if (clz == Site2SiteVpnCfgCommand.class) {
answer = execute((Site2SiteVpnCfgCommand) cmd);
@ -561,13 +562,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
} else if (clz == UnregisterVMCommand.class) {
return execute((UnregisterVMCommand) cmd);
} else if (cmd instanceof StorageSubSystemCommand) {
return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
} else if (clz == ScaleVmCommand.class) {
return execute((ScaleVmCommand) cmd);
} else if (clz == PvlanSetupCommand.class) {
return execute((PvlanSetupCommand) cmd);
} else if (clz == SetStaticRouteCommand.class) {
answer = execute((SetStaticRouteCommand) cmd);
} else if (clz == UnregisterNicCommand.class) {
answer = execute((UnregisterNicCommand) cmd);
} else {
answer = Answer.createUnsupportedCommandAnswer(cmd);
}
@ -873,8 +876,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
null, "/root/firewallRule_egress.sh " + args);
} else {
result = SshHelper.sshExecute(controlIp,
DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(),
null, "/root/firewall_rule.sh " + args);
DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(),
null, "/root/firewall_rule.sh " + args);
}
if (s_logger.isDebugEnabled()) {
@ -882,10 +885,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
s_logger.debug("Executing script on domain router " + controlIp
+ ": /root/firewallRule_egress.sh " + args);
} else {
s_logger.debug("Executing script on domain router " + controlIp
+ ": /root/firewall_rule.sh " + args);
}
}
s_logger.debug("Executing script on domain router " + controlIp
+ ": /root/firewall_rule.sh " + args);
}
}
if (!result.first()) {
@ -1126,21 +1129,21 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return -1;
}
//
// find mac address of a specified ethx device
// ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2
// returns
// eth0:xx.xx.xx.xx
//
// find mac address of a specified ethx device
// ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2
// returns
// eth0:xx.xx.xx.xx
//
// list IP with eth devices
// ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
// | awk -F: '{ print $1 ": " $3 }'
//
// returns
// eth0:xx.xx.xx.xx
//
//
//
// list IP with eth devices
// ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
// | awk -F: '{ print $1 ": " $3 }'
//
// returns
// eth0:xx.xx.xx.xx
//
//
private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception {
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
@ -1982,7 +1985,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
String args = " -m " + cmd.getVmMac();
if (cmd.getVmIpAddress() != null) {
args += " -4 " + cmd.getVmIpAddress();
args += " -4 " + cmd.getVmIpAddress();
}
args += " -h " + cmd.getVmName();
@ -1999,12 +2002,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
if (cmd.getVmIp6Address() != null) {
args += " -6 " + cmd.getVmIp6Address();
args += " -u " + cmd.getDuid();
args += " -6 " + cmd.getVmIp6Address();
args += " -u " + cmd.getDuid();
}
if (!cmd.isDefault()) {
args += " -N";
args += " -N";
}
if (s_logger.isDebugEnabled()) {
@ -2413,16 +2416,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
for (DiskTO vol : disks) {
if (vol.getType() != Volume.Type.ISO) {
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
if (primaryStore.getUuid() != null && !primaryStore.getUuid().isEmpty()) {
validatedDisks.add(vol);
}
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
if (primaryStore.getUuid() != null && !primaryStore.getUuid().isEmpty()) {
validatedDisks.add(vol);
}
} else if (vol.getType() == Volume.Type.ISO) {
TemplateObjectTO templateTO = (TemplateObjectTO)vol.getData();
if (templateTO.getPath() != null && !templateTO.getPath().isEmpty()) {
validatedDisks.add(vol);
}
TemplateObjectTO templateTO = (TemplateObjectTO)vol.getData();
if (templateTO.getPath() != null && !templateTO.getPath().isEmpty()) {
validatedDisks.add(vol);
}
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Drop invalid disk option, volumeTO: " + _gson.toJson(vol));
@ -2468,7 +2471,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// Check if license supports the feature
VmwareHelper.isFeatureLicensed(hyperHost, FeatureKeyConstants.HOTPLUG);
VmwareHelper
.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(), (int)requestedMaxMemoryInMb, ramMb, vmSpec.getLimitCpuUse());
.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(), (int)requestedMaxMemoryInMb, ramMb, vmSpec.getLimitCpuUse());
if(!vmMo.configureVm(vmConfigSpec)) {
throw new Exception("Unable to execute ScaleVmCommand");
@ -2543,15 +2546,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
for (DiskTO vol : disks) {
if (vol.getType() == Volume.Type.ROOT) {
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getData().getDataStore();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getData().getDataStore();
rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
}
}
assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
if (!hyperHost.createBlankVm(vmName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(),
vmSpec.getMinSpeed(), vmSpec.getLimitCpuUse(),(int)(vmSpec.getMaxRam()/(1024*1024)), ramMb,
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) {
vmSpec.getMinSpeed(), vmSpec.getLimitCpuUse(),(int)(vmSpec.getMaxRam()/(1024*1024)), ramMb,
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) {
throw new Exception("Failed to create VM. vmName: " + vmName);
}
}
@ -2582,8 +2585,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
int ramMb = (int) (vmSpec.getMinRam() / (1024 * 1024));
VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(),
vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb,
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse());
vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb,
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse());
String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value();
// Check for hotadd settings
vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId));
@ -2601,8 +2604,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
vmConfigSpec.setNestedHVEnabled(true);
}
else {
s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " +vmSpec.getName());
vmConfigSpec.setNestedHVEnabled(false);
s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " +vmSpec.getName());
vmConfigSpec.setNestedHVEnabled(false);
}
}
@ -2650,33 +2653,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// we will always plugin a CDROM device
if (volIso != null) {
TemplateObjectTO iso = (TemplateObjectTO)volIso.getData();
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);
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);
}
}
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);
@ -2718,8 +2721,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
if (vol.getType() != Volume.Type.ISO) {
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid());
assert (volumeDsDetails != null);
VirtualDevice device;
@ -2731,7 +2734,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (diskChain == null || diskChain.length < 1) {
s_logger.warn("Empty previously-saved chain info, fall back to the original");
device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, new String[] { datastoreDiskPath }, volumeDsDetails.first(),
(controllerKey==ideControllerKey)?ideUnitNumber++:scsiUnitNumber++, i + 1);
(controllerKey==ideControllerKey)?ideUnitNumber++:scsiUnitNumber++, i + 1);
} else {
s_logger.info("Attach the disk with stored chain info: " + chainInfo);
for (int j = 0; j < diskChain.length; j++) {
@ -2739,11 +2742,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, diskChain, volumeDsDetails.first(),
(controllerKey==ideControllerKey)?ideUnitNumber++:scsiUnitNumber++, i + 1);
(controllerKey==ideControllerKey)?ideUnitNumber++:scsiUnitNumber++, i + 1);
}
} else {
device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, new String[] { datastoreDiskPath }, volumeDsDetails.first(),
(controllerKey==ideControllerKey)?ideUnitNumber++:scsiUnitNumber++, i + 1);
(controllerKey==ideControllerKey)?ideUnitNumber++:scsiUnitNumber++, i + 1);
}
deviceConfigSpecArray[i].setDevice(device);
deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
@ -2807,7 +2810,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
newVal.setKey("devices.hotplug");
newVal.setValue("true");
extraOptions.add(newVal);
/**
* Extra Config : nvp.vm-uuid = uuid
* - Required for Nicira NVP integration
@ -2816,7 +2819,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
newVal.setKey("nvp.vm-uuid");
newVal.setValue(vmSpec.getUuid());
extraOptions.add(newVal);
/**
* Extra Config : nvp.iface-id.<num> = uuid
* - Required for Nicira NVP integration
@ -2829,7 +2832,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
extraOptions.add(newVal);
nicNum++;
}
for(Map.Entry<String, String> entry : validateVmDetails(vmSpec.getDetails()).entrySet()) {
newVal = new OptionValue();
newVal.setKey(entry.getKey());
@ -2848,49 +2851,71 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMask));
/**
* We need to configure the port on the DV switch after the host is
* connected. So make this happen between the configure and start of
* the VM
*/
int nicIndex = 0;
for (NicTO nicTo : sortNicsByDeviceId(nics)) {
s_logger.debug("Checking for port configuration on NIC device : " + nicTo.toString());
if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
// We need to create a port with a unique vlan and pass the key to the nic device
s_logger.debug("Nic " + nicTo.toString() + " needs to be configured for NVP");
s_logger.trace("Nic " + nicTo.toString() + " is connected to an NVP logicalswitch");
VirtualDevice nicVirtualDevice = vmMo.getNicDeviceByIndex(nicIndex);
if (nicVirtualDevice == null) {
throw new Exception("Failed to find a VirtualDevice for nic " + nicIndex); //FIXME Generic exceptions are bad
}
VirtualDeviceBackingInfo backing = nicVirtualDevice.getBacking();
if (backing instanceof VirtualEthernetCardDistributedVirtualPortBackingInfo) {
// This NIC is connected to a Distributed Virtual Switch
VirtualEthernetCardDistributedVirtualPortBackingInfo portInfo = (VirtualEthernetCardDistributedVirtualPortBackingInfo) backing;
DistributedVirtualSwitchPortConnection port = portInfo.getPort();
String portKey = port.getPortKey();
String portGroupKey = port.getPortgroupKey();
String dvSwitchUuid = port.getSwitchUuid();
s_logger.debug("NIC " + nicTo.toString() + " is connected to dvSwitch " + dvSwitchUuid + " pg " + portGroupKey + " port " + portKey);
ManagedObjectReference dvSwitchManager = vmMo.getContext().getVimClient().getServiceContent().getDvSwitchManager();
ManagedObjectReference dvSwitch = vmMo.getContext().getVimClient().getService().queryDvsByUuid(dvSwitchManager, dvSwitchUuid);
// Get all ports
DistributedVirtualSwitchPortCriteria criteria = new DistributedVirtualSwitchPortCriteria();
criteria.setInside(true);
criteria.getPortgroupKey().add(portGroupKey);
criteria.getPortKey().add(portKey);
List<DistributedVirtualPort> dvPorts = vmMo.getContext().getVimClient().getService().fetchDVPorts(dvSwitch, criteria);
if (dvPorts.isEmpty()) {
throw new Exception("Empty port list from dvSwitch for nic " + nicTo.toString());
} else if (dvPorts.size() > 1) {
throw new Exception("Expected only one port in the list from dvSwitch for nic " + nicTo.toString());
DistributedVirtualPort vmDvPort = null;
List<Integer> usedVlans = new ArrayList<Integer>();
for (DistributedVirtualPort dvPort : dvPorts) {
// Find the port for this NIC by portkey
if (portKey.equals(dvPort.getKey())) {
vmDvPort = dvPort;
}
VMwareDVSPortSetting settings = (VMwareDVSPortSetting) dvPort
.getConfig().getSetting();
VmwareDistributedVirtualSwitchVlanIdSpec vlanId = (VmwareDistributedVirtualSwitchVlanIdSpec) settings
.getVlan();
s_logger.trace("Found port " + dvPort.getKey()
+ " with vlan " + vlanId.getVlanId());
if (vlanId.getVlanId() > 0
&& vlanId.getVlanId() < 4095) {
usedVlans.add(vlanId.getVlanId());
}
}
DistributedVirtualPort dvPort = dvPorts.get(0);
DVPortConfigInfo dvPortConfigInfo = dvPort.getConfig();
if (vmDvPort == null) {
throw new Exception("Empty port list from dvSwitch for nic " + nicTo.toString());
}
DVPortConfigInfo dvPortConfigInfo = vmDvPort
.getConfig();
VMwareDVSPortSetting settings = (VMwareDVSPortSetting) dvPortConfigInfo.getSetting();
VmwareDistributedVirtualSwitchVlanIdSpec vlanId = (VmwareDistributedVirtualSwitchVlanIdSpec) settings.getVlan();
BoolPolicy blocked = settings.getBlocked();
if (blocked.isValue() == Boolean.TRUE) {
s_logger.debug("Port is blocked, we need to set a vlanid and unblock");
s_logger.trace("Port is blocked, set a vlanid and unblock");
DVPortConfigSpec dvPortConfigSpec = new DVPortConfigSpec();
VMwareDVSPortSetting edittedSettings = new VMwareDVSPortSetting();
// Unblock
@ -2898,10 +2923,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
blocked.setInherited(Boolean.FALSE);
edittedSettings.setBlocked(blocked);
// Set vlan
vlanId.setVlanId(100); //FIXME should be a determined based on usage
for (i = 1; i < 4095; i++) {
if (!usedVlans.contains(i))
break;
}
vlanId.setVlanId(i); // FIXME should be a determined
// based on usage
vlanId.setInherited(false);
edittedSettings.setVlan(vlanId);
dvPortConfigSpec.setSetting(edittedSettings);
dvPortConfigSpec.setOperation("edit");
dvPortConfigSpec.setKey(portKey);
@ -2909,11 +2939,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
dvPortConfigSpecs.add(dvPortConfigSpec);
ManagedObjectReference task = vmMo.getContext().getVimClient().getService().reconfigureDVPortTask(dvSwitch, dvPortConfigSpecs);
if (!vmMo.getContext().getVimClient().waitForTask(task)) {
s_logger.error("Failed to configure the dvSwitch port for nic " + nicTo.toString());
throw new Exception(
"Failed to configure the dvSwitch port for nic "
+ nicTo.toString());
}
s_logger.debug("NIC " + nicTo.toString()
+ " connected to vlan " + i);
} else {
s_logger.trace("Port already configured and set to vlan " + vlanId.getVlanId());
}
} else if (backing instanceof VirtualEthernetCardNetworkBackingInfo) {
// This NIC is connected to a Virtual Switch
// Nothing to do
}
else {
s_logger.error("nic device backing is of type " + backing.getClass().getName());
@ -2926,8 +2963,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (!vmMo.powerOn()) {
throw new Exception("Failed to start VM. vmName: " + vmName);
}
state = State.Running;
return new StartAnswer(cmd);
@ -3030,8 +3065,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
assert (hyperHost != null) && (context != null);
for (DiskTO vol : disks) {
if (vol.getType() != Volume.Type.ISO) {
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore();
String poolUuid = primaryStore.getUuid();
if(poolMors.get(poolUuid) == null) {
ManagedObjectReference morDataStore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid);
@ -3063,7 +3098,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (nicTo.getBroadcastUri() != null) {
if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan)
// For vlan, the broadcast uri is of the form vlan://<vlanid>
return nicTo.getBroadcastUri().getHost();
return nicTo.getBroadcastUri().getHost();
else
// for pvlan, the broacast uri will be of the form pvlan://<vlanid>-i<pvlanid>
return NetUtils.getPrimaryPvlanFromUri(nicTo.getBroadcastUri());
@ -3120,7 +3155,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
svlanId = getPvlanInfo(nicTo);
}
networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, vlanId, svlanId,
nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout, switchType,
nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout, switchType,
_portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType());
}
@ -4038,9 +4073,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (cmd.getAttach()) {
morDs = createVmfsDatastore(hyperHost, iqn,
cmd.getStorageHost(), cmd.getStoragePort(), iqn,
cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(),
cmd.getChapTargetUsername(), cmd.getChapTargetPassword());
cmd.getStorageHost(), cmd.getStoragePort(), iqn,
cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(),
cmd.getChapTargetUsername(), cmd.getChapTargetPassword());
DatastoreMO dsMo = new DatastoreMO(context, morDs);
@ -4056,15 +4091,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
vmMo.createDisk(volumeDatastorePath, getMBsFromBytes(dsMo.getSummary().getFreeSpace()),
morDs, vmMo.getScsiDeviceControllerKey());
morDs, vmMo.getScsiDeviceControllerKey());
vmMo.detachDisk(volumeDatastorePath, false);
}
}
}
else {
deleteVmfsDatastore(hyperHost, iqn, cmd.getStorageHost(), cmd.getStoragePort(), iqn);
deleteVmfsDatastore(hyperHost, iqn, cmd.getStorageHost(), cmd.getStoragePort(), iqn);
}
return morDs;
return morDs;
}
protected Answer execute(AttachVolumeCommand cmd) {
@ -4089,10 +4124,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
ManagedObjectReference morDs = null;
if (cmd.getAttach() && cmd.isManaged()) {
morDs = handleDatastoreAndVmdk(cmd);
morDs = handleDatastoreAndVmdk(cmd);
}
else {
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid());
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid());
}
if (morDs == null) {
@ -4115,7 +4150,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
vmMo.detachDisk(datastoreVolumePath, false);
if (cmd.isManaged()) {
handleDatastoreAndVmdk(cmd);
handleDatastoreAndVmdk(cmd);
}
}
@ -4515,14 +4550,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
protected Answer execute(RevertToVMSnapshotCommand cmd){
try{
VmwareContext context = getServiceContext();
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
return mgr.getStorageManager().execute(this, cmd);
}catch (Exception e){
e.printStackTrace();
return new RevertToVMSnapshotAnswer(cmd,false,"");
}
try{
VmwareContext context = getServiceContext();
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
return mgr.getStorageManager().execute(this, cmd);
}catch (Exception e){
e.printStackTrace();
return new RevertToVMSnapshotAnswer(cmd,false,"");
}
}
protected Answer execute(CreateVolumeFromSnapshotCommand cmd) {
if (s_logger.isInfoEnabled()) {
@ -4814,6 +4849,36 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
}
/**
* UnregisterNicCommand is used to remove a portgroup created for this
* specific nic. The portgroup will have the name set to the UUID of the
* nic. Introduced to cleanup the portgroups created for each nic that is
* plugged into an lswitch (Nicira NVP plugin)
*
* @param cmd
* @return
*/
protected Answer execute(UnregisterNicCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource UnregisterNicCommand: " + _gson.toJson(cmd));
}
VmwareContext context = getServiceContext();
getHyperHost(context);
try {
return new Answer(cmd, true, "Not implemented yet");
} catch (Exception e) {
if (e instanceof RemoteException) {
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
invalidateServiceContext();
}
String msg = "UnregisterVMCommand failed due to " + VmwareHelper.getExceptionMessage(e);
s_logger.error(msg);
return new Answer(cmd, false, msg);
}
}
public Answer execute(DeleteCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd));
@ -4889,9 +4954,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true);
} else {
if (s_logger.isInfoEnabled()) {
s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-delta.vmdk");
s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-delta.vmdk");
}
dsMo.deleteFile(vol.getPath() + "-delta.vmdk", morDc, true);
dsMo.deleteFile(vol.getPath() + "-delta.vmdk", morDc, true);
}
return new Answer(cmd, true, "Success");
}
@ -6051,10 +6116,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager());
cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch ||
_guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
_guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
}
cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC);
cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC);
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
@ -6063,7 +6128,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
Map<String, String> vsmCredentials;
if (_guestTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch ||
_publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) {
_publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) {
vsmCredentials = mgr.getNexusVSMCredentialsByClusterId(Long.parseLong(_cluster));
if (vsmCredentials != null) {
s_logger.info("Stocking credentials while configuring resource.");
@ -6118,8 +6183,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
int timeout = NumbersUtil.parseInt(value, 1440) * 1000;
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr,
timeout, this, _shutdown_waitMs
);
timeout, this, _shutdown_waitMs
);
storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor);
return true;
@ -6216,41 +6281,41 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return vmName;
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
@Override
public void setName(String name) {
// TODO Auto-generated method stub
}
}
@Override
public void setConfigParams(Map<String, Object> params) {
// TODO Auto-generated method stub
@Override
public void setConfigParams(Map<String, Object> params) {
// TODO Auto-generated method stub
}
}
@Override
public Map<String, Object> getConfigParams() {
// TODO Auto-generated method stub
return null;
}
@Override
public Map<String, Object> getConfigParams() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getRunLevel() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getRunLevel() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setRunLevel(int level) {
// TODO Auto-generated method stub
@Override
public void setRunLevel(int level) {
// TODO Auto-generated method stub
}
}
@Override
public Answer execute(DestroyCommand cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
public Answer execute(DestroyCommand cmd) {
// TODO Auto-generated method stub
return null;
}
private boolean isVMWareToolsInstalled(VirtualMachineMO vmMo) throws Exception{
GuestInfo guestInfo = vmMo.getVmGuestInfo();
return (guestInfo != null && guestInfo.getGuestState() != null && guestInfo.getGuestState().equalsIgnoreCase("running"));

View File

@ -5,7 +5,7 @@
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
@ -22,17 +22,13 @@ import java.util.Map;
import javax.inject.Inject;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.configuration.Config;
import com.cloud.offering.ServiceOffering;
import com.cloud.server.ConfigurationServer;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.VMTemplateVO;
import com.cloud.utils.component.AdapterBase;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
@ -41,12 +37,11 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
@Inject VMTemplateDetailsDao _templateDetailsDao;
@Inject VMTemplateDetailsDao _templateDetailsDao;
@Inject NicDao _nicDao;
@Inject VMInstanceDao _virtualMachineDao;
@Inject NicSecondaryIpDao _nicSecIpDao;
@ -74,7 +69,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setNetworkRateMbps(profile.getNetworkRate());
to.setName(profile.getName());
to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
// Workaround to make sure the TO has the UUID we need for Niciri integration
NicVO nicVO = _nicDao.findById(profile.getId());
to.setUuid(nicVO.getUuid());
@ -92,7 +87,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
protected <T extends VirtualMachine> VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile<T> vmProfile) {
ServiceOffering offering = vmProfile.getServiceOffering();
ServiceOffering offering = vmProfile.getServiceOffering();
VirtualMachine vm = vmProfile.getVirtualMachine();
Long minMemory = (long) (offering.getRamSize() / vmProfile.getMemoryOvercommitRatio());
int minspeed = (int) (offering.getSpeed() / vmProfile.getCpuOvercommitRatio());
@ -116,13 +111,13 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
} else {
to.setArch("x86_64");
}
long templateId = vm.getTemplateId();
Map<String, String> details = _templateDetailsDao.findDetails(templateId);
assert(details != null);
Map<String, String> detailsInVm = vm.getDetails();
if(detailsInVm != null) {
details.putAll(detailsInVm);
details.putAll(detailsInVm);
}
if (details.get(VirtualMachine.IsDynamicScalingEnabled) == null || details.get(VirtualMachine.IsDynamicScalingEnabled).isEmpty()) {
to. setEnableDynamicallyScaleVm(false);
@ -134,7 +129,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
// Workaround to make sure the TO has the UUID we need for Niciri integration
VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId());
to.setUuid(vmInstance.getUuid());
//
return to;
}
@ -143,9 +138,14 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
public long getCommandHostDelegation(long hostId, Command cmd) {
return hostId;
}
@Override
public List<Command> finalizeExpunge(VirtualMachine vm) {
return null;
}
@Override
public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
return null;
}
}

View File

@ -36,12 +36,6 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -168,7 +162,6 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.ItWorkVO.Step;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
@ -181,6 +174,13 @@ import com.cloud.vm.snapshot.VMSnapshotManager;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
@Local(value = VirtualMachineManager.class)
public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener {
private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class);
@ -266,19 +266,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
protected List<DeploymentPlanner> _planners;
public List<DeploymentPlanner> getPlanners() {
return _planners;
}
public void setPlanners(List<DeploymentPlanner> _planners) {
this._planners = _planners;
}
return _planners;
}
public void setPlanners(List<DeploymentPlanner> _planners) {
this._planners = _planners;
}
protected List<HostAllocator> _hostAllocators;
public List<HostAllocator> getHostAllocators() {
return _hostAllocators;
}
public void setHostAllocators(List<HostAllocator> _hostAllocators) {
this._hostAllocators = _hostAllocators;
}
return _hostAllocators;
}
public void setHostAllocators(List<HostAllocator> _hostAllocators) {
this._hostAllocators = _hostAllocators;
}
@Inject
protected List<StoragePoolAllocator> _storagePoolAllocators;
@ -369,15 +369,15 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
if (template.getFormat() == ImageFormat.ISO) {
this.volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner);
volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner);
} else if (template.getFormat() == ImageFormat.BAREMETAL) {
// Do nothing
} else {
this.volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner);
volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner);
}
for (Pair<DiskOfferingVO, Long> offering : dataDiskOfferings) {
this.volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner);
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner);
}
txn.commit();
@ -457,11 +457,16 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
VirtualMachineProfile<T> profile = new VirtualMachineProfileImpl<T>(vm);
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
s_logger.debug("Cleaning up NICS");
List<Command> nicExpungeCommands = hvGuru.finalizeExpungeNics(vm, profile.getNics());
_networkMgr.cleanupNics(profile);
// Clean up volumes based on the vm's instance id
List<VolumeVO> rootVol = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
this.volumeMgr.cleanupVolumes(vm.getId());
volumeMgr.cleanupVolumes(vm.getId());
VirtualMachineGuru<T> guru = getVmGuru(vm);
guru.finalizeExpunge(vm);
@ -469,7 +474,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
_uservmDetailsDao.deleteDetails(vm.getId());
// send hypervisor-dependent commands before removing
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
List<Command> finalizeExpungeCommands = hvGuru.finalizeExpunge(vm);
if(finalizeExpungeCommands != null && finalizeExpungeCommands.size() > 0){
Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
@ -478,6 +482,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
for (Command command : finalizeExpungeCommands) {
cmds.addCommand(command);
}
if (nicExpungeCommands != null) {
for (Command command : nicExpungeCommands) {
cmds.addCommand(command);
}
}
_agentMgr.send(hostId, cmds);
if(!cmds.isSuccessful()){
for (Answer answer : cmds.getAnswers()){
@ -849,7 +858,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
_networkMgr.prepare(vmProfile, dest, ctx);
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
this.volumeMgr.prepare(vmProfile, dest);
volumeMgr.prepare(vmProfile, dest);
}
//since StorageMgr succeeded in volume creation, reuse Volume for further tries until current cluster has capacity
if(!reuseVolume){
@ -972,7 +981,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
if (startedVm == null) {
throw new CloudRuntimeException("Unable to start instance '" + vm.getHostName()
+ "' (" + vm.getUuid() + "), see management server log for details");
+ "' (" + vm.getUuid() + "), see management server log for details");
}
return startedVm;
@ -1071,7 +1080,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.warn("Unable to release some network resources.", e);
}
this.volumeMgr.release(profile);
volumeMgr.release(profile);
s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state");
return true;
}
@ -1231,7 +1240,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
try {
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
this.volumeMgr.release(profile);
volumeMgr.release(profile);
s_logger.debug("Successfully released storage resources for the vm " + vm);
}
} catch (Exception e) {
@ -1350,7 +1359,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
boolean migrationResult = false;
try {
migrationResult = this.volumeMgr.storageMigration(profile, destPool);
migrationResult = volumeMgr.storageMigration(profile, destPool);
if (migrationResult) {
//if the vm is migrated to different pod in basic mode, need to reallocate ip
@ -1437,10 +1446,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
for(NicProfile nic: _networkMgr.getNicProfiles(vm)){
vmSrc.addNic(nic);
}
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
_networkMgr.prepareNicForMigration(profile, dest);
this.volumeMgr.prepareForMigration(profile, dest);
volumeMgr.prepareForMigration(profile, dest);
VirtualMachineTO to = toVmTO(profile);
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
@ -1675,7 +1684,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
_networkMgr.prepareNicForMigration(profile, destination);
this.volumeMgr.prepareForMigration(profile, destination);
volumeMgr.prepareForMigration(profile, destination);
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
VirtualMachineTO to = hvGuru.implement(profile);
@ -1692,7 +1701,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
boolean migrated = false;
try {
// Migrate the vm and its volume.
this.volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPool);
volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPool);
// Put the vm back to running state.
moveVmOutofMigratingStateOnSuccess(vm, destHost.getId(), work);
@ -2105,7 +2114,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting ))
|| (info != null && (info.state == State.Running && vm.getState() == State.Starting)))
|| (info != null && (info.state == State.Running && vm.getState() == State.Starting)))
{
s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + " on agent");
info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped);
@ -2625,7 +2634,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
HashMap<String, Pair<String, State>> allStates = startup.getClusterVMStateChanges();
if (allStates != null){
this.fullSync(clusterId, allStates);
fullSync(clusterId, allStates);
}
// initiate the cron job
@ -2713,7 +2722,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
this.state = state;
this.vm = vm;
this.guru = (VirtualMachineGuru<VMInstanceVO>) guru;
this.hostUuid = host;
hostUuid = host;
}
public AgentVmInfo(String name, VirtualMachineGuru<? extends VMInstanceVO> guru, VMInstanceVO vm, State state) {
@ -2846,7 +2855,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
VirtualMachineGuru<VMInstanceVO> vmGuru = getVmGuru(vmVO);
s_logger.debug("Plugging nic for vm " + vm + " in network " + network);
boolean result = false;
try{
result = vmGuru.plugNic(network, nicTO, vmTO, context, dest);
@ -2856,17 +2865,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
// insert nic's Id into DB as resource_name
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmVO.getAccountId(),
vmVO.getDataCenterId(), vmVO.getId(), Long.toString(nic.getId()), network.getNetworkOfferingId(),
null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid());
null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid());
return nic;
} else {
s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network);
return null;
}
}
}finally{
if(!result){
_networkMgr.removeNic(vmProfile, _nicsDao.findById(nic.getId()));
}
}
}
} else if (vm.getState() == State.Stopped) {
//1) allocate nic
return _networkMgr.createNicForVm(network, requested, context, vmProfile, false);
@ -2907,10 +2916,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
}
// if specified nic is associated with PF/LB/Static NAT
if(rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0){
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network
+ ", nic has associated Port forwarding or Load balancer or Static NAT rules.");
}
@ -2928,7 +2937,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network );
long isDefault = (nic.isDefaultNic()) ? 1 : 0;
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(),
vm.getId(), Long.toString(nic.getId()), network.getNetworkOfferingId(), null,
vm.getId(), Long.toString(nic.getId()), network.getNetworkOfferingId(), null,
isDefault, VirtualMachine.class.getName(), vm.getUuid());
} else {
s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
@ -3081,160 +3090,160 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
@Override
public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, DeployDestination dest, Long oldSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
VirtualMachineMigrationException {
s_logger.info("Migrating " + vm + " to " + dest);
@Override
public <T extends VMInstanceVO> T migrateForScale(T vm, long srcHostId, DeployDestination dest, Long oldSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
VirtualMachineMigrationException {
s_logger.info("Migrating " + vm + " to " + dest);
Long newSvcOfferingId = vm.getServiceOfferingId();
long dstHostId = dest.getHost().getId();
Host fromHost = _hostDao.findById(srcHostId);
if (fromHost == null) {
s_logger.info("Unable to find the host to migrate from: " + srcHostId);
throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
vm.getServiceOfferingId();
long dstHostId = dest.getHost().getId();
Host fromHost = _hostDao.findById(srcHostId);
if (fromHost == null) {
s_logger.info("Unable to find the host to migrate from: " + srcHostId);
throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
}
if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
}
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
long vmId = vm.getId();
vm = vmGuru.findById(vmId);
if (vm == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find the vm " + vm);
}
throw new ManagementServerException("Unable to find a virtual machine with id " + vmId);
}
if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
if (vm.getState() != State.Running) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
}
throw new VirtualMachineMigrationException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
}
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE;
if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
} else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
}
long vmId = vm.getId();
vm = vmGuru.findById(vmId);
if (vm == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find the vm " + vm);
}
throw new ManagementServerException("Unable to find a virtual machine with id " + vmId);
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
_networkMgr.prepareNicForMigration(profile, dest);
volumeMgr.prepareForMigration(profile, dest);
VirtualMachineTO to = toVmTO(profile);
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
work.setStep(Step.Prepare);
work.setResourceType(ItWorkVO.ResourceType.Host);
work.setResourceId(dstHostId);
work = _workDao.persist(work);
PrepareForMigrationAnswer pfma = null;
try {
pfma = (PrepareForMigrationAnswer) _agentMgr.send(dstHostId, pfmc);
if (!pfma.getResult()) {
String msg = "Unable to prepare for migration due to " + pfma.getDetails();
pfma = null;
throw new AgentUnavailableException(msg, dstHostId);
}
if (vm.getState() != State.Running) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
}
throw new VirtualMachineMigrationException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
}
short alertType = AlertManager.ALERT_TYPE_USERVM_MIGRATE;
if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
alertType = AlertManager.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
} else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
alertType = AlertManager.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
}
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
_networkMgr.prepareNicForMigration(profile, dest);
this.volumeMgr.prepareForMigration(profile, dest);
VirtualMachineTO to = toVmTO(profile);
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
work.setStep(Step.Prepare);
work.setResourceType(ItWorkVO.ResourceType.Host);
work.setResourceId(dstHostId);
work = _workDao.persist(work);
PrepareForMigrationAnswer pfma = null;
try {
pfma = (PrepareForMigrationAnswer) _agentMgr.send(dstHostId, pfmc);
if (!pfma.getResult()) {
String msg = "Unable to prepare for migration due to " + pfma.getDetails();
pfma = null;
throw new AgentUnavailableException(msg, dstHostId);
}
} catch (OperationTimedoutException e1) {
throw new AgentUnavailableException("Operation timed out", dstHostId);
} finally {
if (pfma == null) {
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
}
}
vm.setLastHostId(srcHostId);
try {
if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
s_logger.info("Migration cancelled because state has changed: " + vm);
throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
}
} catch (NoTransitionException e1) {
s_logger.info("Migration cancelled because " + e1.getMessage());
throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
}
boolean migrated = false;
try {
boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows);
mc.setHostGuid(dest.getHost().getGuid());
try {
MigrateAnswer ma = (MigrateAnswer) _agentMgr.send(vm.getLastHostId(), mc);
if (!ma.getResult()) {
s_logger.error("Unable to migrate due to " + ma.getDetails());
return null;
}
} catch (OperationTimedoutException e) {
if (e.isActive()) {
s_logger.warn("Active migration command so scheduling a restart for " + vm);
_haMgr.scheduleRestart(vm, true);
}
throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
}
try {
long newServiceOfferingId = vm.getServiceOfferingId();
vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only
if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
throw new ConcurrentOperationException("Unable to change the state for " + vm);
}
vm.setServiceOfferingId(newServiceOfferingId);
} catch (NoTransitionException e1) {
throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
}
try {
if (!checkVmOnHost(vm, dstHostId)) {
s_logger.error("Unable to complete migration for " + vm);
try {
_agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
} catch (AgentUnavailableException e) {
s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
}
cleanup(vmGuru, new VirtualMachineProfileImpl<T>(vm), work, Event.AgentReportStopped, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
return null;
}
} catch (OperationTimedoutException e) {
}
migrated = true;
return vm;
} finally {
if (!migrated) {
s_logger.info("Migration was unsuccessful. Cleaning up: " + vm);
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone "
+ dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs.");
try {
_agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
} catch (AgentUnavailableException ae) {
s_logger.info("Looks like the destination Host is unavailable for cleanup");
}
try {
stateTransitTo(vm, Event.OperationFailed, srcHostId);
} catch (NoTransitionException e) {
s_logger.warn(e.getMessage());
}
}
} catch (OperationTimedoutException e1) {
throw new AgentUnavailableException("Operation timed out", dstHostId);
} finally {
if (pfma == null) {
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
}
}
vm.setLastHostId(srcHostId);
try {
if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
s_logger.info("Migration cancelled because state has changed: " + vm);
throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
}
} catch (NoTransitionException e1) {
s_logger.info("Migration cancelled because " + e1.getMessage());
throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
}
boolean migrated = false;
try {
boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows);
mc.setHostGuid(dest.getHost().getGuid());
try {
MigrateAnswer ma = (MigrateAnswer) _agentMgr.send(vm.getLastHostId(), mc);
if (!ma.getResult()) {
s_logger.error("Unable to migrate due to " + ma.getDetails());
return null;
}
} catch (OperationTimedoutException e) {
if (e.isActive()) {
s_logger.warn("Active migration command so scheduling a restart for " + vm);
_haMgr.scheduleRestart(vm, true);
}
throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
}
try {
long newServiceOfferingId = vm.getServiceOfferingId();
vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only
if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
throw new ConcurrentOperationException("Unable to change the state for " + vm);
}
vm.setServiceOfferingId(newServiceOfferingId);
} catch (NoTransitionException e1) {
throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
}
try {
if (!checkVmOnHost(vm, dstHostId)) {
s_logger.error("Unable to complete migration for " + vm);
try {
_agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
} catch (AgentUnavailableException e) {
s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
}
cleanup(vmGuru, new VirtualMachineProfileImpl<T>(vm), work, Event.AgentReportStopped, true, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
return null;
}
} catch (OperationTimedoutException e) {
}
migrated = true;
return vm;
} finally {
if (!migrated) {
s_logger.info("Migration was unsuccessful. Cleaning up: " + vm);
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone "
+ dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs.");
try {
_agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
} catch (AgentUnavailableException ae) {
s_logger.info("Looks like the destination Host is unavailable for cleanup");
}
try {
stateTransitTo(vm, Event.OperationFailed, srcHostId);
} catch (NoTransitionException e) {
s_logger.warn(e.getMessage());
}
}
work.setStep(Step.Done);
_workDao.update(work.getId(), work);
}
}
@Override
public VMInstanceVO reConfigureVm(VMInstanceVO vm , ServiceOffering oldServiceOffering, boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, ConcurrentOperationException {
@ -3283,7 +3292,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
} catch (AgentUnavailableException e) {
throw e;
} finally{
// work.setStep(Step.Done);
// work.setStep(Step.Done);
//_workDao.update(work.getId(), work);
if(!success){
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); // release the new capacity
@ -3297,4 +3306,4 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
}