mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-4659: Add the missing feature back for GC VMware worker VMs
This commit is contained in:
parent
2b4e994a4d
commit
5820b071b8
@ -112,6 +112,7 @@ public class ConsoleProxyResource extends ServerResourceBase implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Answer execute(StartConsoleProxyAgentHttpHandlerCommand cmd) {
|
private Answer execute(StartConsoleProxyAgentHttpHandlerCommand cmd) {
|
||||||
|
s_logger.info("Invoke launchConsoleProxy() in responding to StartConsoleProxyAgentHttpHandlerCommand");
|
||||||
launchConsoleProxy(cmd.getKeystoreBits(), cmd.getKeystorePassword(), cmd.getEncryptorPassword());
|
launchConsoleProxy(cmd.getKeystoreBits(), cmd.getKeystorePassword(), cmd.getEncryptorPassword());
|
||||||
return new Answer(cmd);
|
return new Answer(cmd);
|
||||||
}
|
}
|
||||||
@ -361,29 +362,31 @@ public class ConsoleProxyResource extends ServerResourceBase implements
|
|||||||
try {
|
try {
|
||||||
Class<?> consoleProxyClazz = Class.forName("com.cloud.consoleproxy.ConsoleProxy");
|
Class<?> consoleProxyClazz = Class.forName("com.cloud.consoleproxy.ConsoleProxy");
|
||||||
try {
|
try {
|
||||||
|
s_logger.info("Invoke setEncryptorPassword(), ecnryptorPassword: " + encryptorPassword);
|
||||||
Method methodSetup = consoleProxyClazz.getMethod(
|
Method methodSetup = consoleProxyClazz.getMethod(
|
||||||
"setEncryptorPassword", String.class);
|
"setEncryptorPassword", String.class);
|
||||||
methodSetup.invoke(null, encryptorPassword);
|
methodSetup.invoke(null, encryptorPassword);
|
||||||
|
|
||||||
|
s_logger.info("Invoke startWithContext()");
|
||||||
Method method = consoleProxyClazz.getMethod(
|
Method method = consoleProxyClazz.getMethod(
|
||||||
"startWithContext", Properties.class,
|
"startWithContext", Properties.class,
|
||||||
Object.class, byte[].class, String.class);
|
Object.class, byte[].class, String.class);
|
||||||
method.invoke(null, _properties, resource, ksBits,
|
method.invoke(null, _properties, resource, ksBits,
|
||||||
ksPassword);
|
ksPassword);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to SecurityException");
|
s_logger.error("Unable to launch console proxy due to SecurityException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to NoSuchMethodException");
|
s_logger.error("Unable to launch console proxy due to NoSuchMethodException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to IllegalArgumentException");
|
s_logger.error("Unable to launch console proxy due to IllegalArgumentException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to IllegalAccessException");
|
s_logger.error("Unable to launch console proxy due to IllegalAccessException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to InvocationTargetException");
|
s_logger.error("Unable to launch console proxy due to InvocationTargetException " + e.getTargetException().toString(), e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
}
|
}
|
||||||
} catch (final ClassNotFoundException e) {
|
} catch (final ClassNotFoundException e) {
|
||||||
@ -402,22 +405,22 @@ public class ConsoleProxyResource extends ServerResourceBase implements
|
|||||||
Method methodSetup = consoleProxyClazz.getMethod("setEncryptorPassword", String.class);
|
Method methodSetup = consoleProxyClazz.getMethod("setEncryptorPassword", String.class);
|
||||||
methodSetup.invoke(null, encryptorPassword);
|
methodSetup.invoke(null, encryptorPassword);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to SecurityException");
|
s_logger.error("Unable to launch console proxy due to SecurityException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to NoSuchMethodException");
|
s_logger.error("Unable to launch console proxy due to NoSuchMethodException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to IllegalArgumentException");
|
s_logger.error("Unable to launch console proxy due to IllegalArgumentException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to IllegalAccessException");
|
s_logger.error("Unable to launch console proxy due to IllegalAccessException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to InvocationTargetException");
|
s_logger.error("Unable to launch console proxy due to InvocationTargetException " + e.getTargetException().toString(), e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
} catch (final ClassNotFoundException e) {
|
} catch (final ClassNotFoundException e) {
|
||||||
s_logger.error("Unable to launch console proxy due to ClassNotFoundException");
|
s_logger.error("Unable to launch console proxy due to ClassNotFoundException", e);
|
||||||
System.exit(ExitStatus.Error.value());
|
System.exit(ExitStatus.Error.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,8 @@ public interface ClusterManager extends Manager {
|
|||||||
ManagementServerHost getPeer(String peerName);
|
ManagementServerHost getPeer(String peerName);
|
||||||
|
|
||||||
String getSelfPeerName();
|
String getSelfPeerName();
|
||||||
|
long getManagementNodeId();
|
||||||
|
long getCurrentRunId();
|
||||||
|
|
||||||
public interface Dispatcher {
|
public interface Dispatcher {
|
||||||
String getName();
|
String getName();
|
||||||
|
|||||||
@ -1077,6 +1077,10 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getManagementNodeId() {
|
||||||
|
return _msId;
|
||||||
|
}
|
||||||
|
|
||||||
public long getCurrentRunId() {
|
public long getCurrentRunId() {
|
||||||
return _runId;
|
return _runId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,7 @@ import com.cloud.agent.api.to.DataStoreTO;
|
|||||||
import com.cloud.agent.api.to.DataTO;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
import com.cloud.agent.api.to.NicTO;
|
import com.cloud.agent.api.to.NicTO;
|
||||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||||
|
import com.cloud.cluster.ClusterManager;
|
||||||
import com.cloud.configuration.Config;
|
import com.cloud.configuration.Config;
|
||||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
@ -115,6 +116,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||||||
PhysicalNetworkDao _physicalNetworkDao;
|
PhysicalNetworkDao _physicalNetworkDao;
|
||||||
@Inject
|
@Inject
|
||||||
PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
|
PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
|
||||||
|
@Inject ClusterManager _clusterMgr;
|
||||||
|
|
||||||
protected VMwareGuru() {
|
protected VMwareGuru() {
|
||||||
super();
|
super();
|
||||||
@ -365,6 +367,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||||||
CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
|
CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
|
||||||
_cmdExecLogDao.persist(execLog);
|
_cmdExecLogDao.persist(execLog);
|
||||||
cmd.setContextParam("execid", String.valueOf(execLog.getId()));
|
cmd.setContextParam("execid", String.valueOf(execLog.getId()));
|
||||||
|
cmd.setContextParam("noderuninfo", String.format("%d-%d", _clusterMgr.getManagementNodeId(), _clusterMgr.getCurrentRunId()));
|
||||||
|
|
||||||
if(cmd instanceof BackupSnapshotCommand ||
|
if(cmd instanceof BackupSnapshotCommand ||
|
||||||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||||
|
|||||||
@ -52,6 +52,7 @@ public interface VmwareManager {
|
|||||||
|
|
||||||
VmwareStorageManager getStorageManager();
|
VmwareStorageManager getStorageManager();
|
||||||
void gcLeftOverVMs(VmwareContext context);
|
void gcLeftOverVMs(VmwareContext context);
|
||||||
|
boolean needRecycle(String workerTag);
|
||||||
|
|
||||||
Pair<Integer, Integer> getAddiionalVncPortRange();
|
Pair<Integer, Integer> getAddiionalVncPortRange();
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,9 @@ import com.cloud.agent.api.Answer;
|
|||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
import com.cloud.agent.api.StartupCommand;
|
import com.cloud.agent.api.StartupCommand;
|
||||||
import com.cloud.agent.api.StartupRoutingCommand;
|
import com.cloud.agent.api.StartupRoutingCommand;
|
||||||
|
import com.cloud.cluster.ClusterManager;
|
||||||
|
import com.cloud.cluster.ManagementServerHost;
|
||||||
|
import com.cloud.cluster.dao.ManagementServerHostPeerDao;
|
||||||
import com.cloud.configuration.Config;
|
import com.cloud.configuration.Config;
|
||||||
import com.cloud.dc.ClusterDetailsDao;
|
import com.cloud.dc.ClusterDetailsDao;
|
||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
@ -153,6 +156,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
@Inject VmwareDatacenterDao _vmwareDcDao;
|
@Inject VmwareDatacenterDao _vmwareDcDao;
|
||||||
@Inject VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
|
@Inject VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
|
||||||
@Inject LegacyZoneDao _legacyZoneDao;
|
@Inject LegacyZoneDao _legacyZoneDao;
|
||||||
|
@Inject ManagementServerHostPeerDao _mshostPeerDao;
|
||||||
|
@Inject ClusterManager _clusterMgr;
|
||||||
|
|
||||||
String _mountParent;
|
String _mountParent;
|
||||||
StorageLayer _storage;
|
StorageLayer _storage;
|
||||||
@ -166,6 +171,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String _managemetPortGroupName;
|
String _managemetPortGroupName;
|
||||||
String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
||||||
String _recycleHungWorker = "false";
|
String _recycleHungWorker = "false";
|
||||||
|
long _hungWorkerTimeout = 7200000; // 2 hour
|
||||||
int _additionalPortRangeStart;
|
int _additionalPortRangeStart;
|
||||||
int _additionalPortRangeSize;
|
int _additionalPortRangeSize;
|
||||||
int _routerExtraPublicNics = 2;
|
int _routerExtraPublicNics = 2;
|
||||||
@ -285,6 +291,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
_recycleHungWorker = "false";
|
_recycleHungWorker = "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = _configDao.getValue(Config.VmwareHungWorkerTimeout.key());
|
||||||
|
if(value != null)
|
||||||
|
_hungWorkerTimeout = Long.parseLong(value) * 1000;
|
||||||
|
|
||||||
_rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
|
_rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
|
||||||
if(_rootDiskController == null || _rootDiskController.isEmpty()) {
|
if(_rootDiskController == null || _rootDiskController.isEmpty()) {
|
||||||
_rootDiskController = DiskControllerType.ide.toString();
|
_rootDiskController = DiskControllerType.ide.toString();
|
||||||
@ -529,12 +539,51 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return _storageMgr;
|
return _storageMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void gcLeftOverVMs(VmwareContext context) {
|
public void gcLeftOverVMs(VmwareContext context) {
|
||||||
VmwareCleanupMaid.gcLeftOverVMs(context);
|
VmwareCleanupMaid.gcLeftOverVMs(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needRecycle(String workerTag) {
|
||||||
|
if(s_logger.isInfoEnabled())
|
||||||
|
s_logger.info("Check to see if a worker VM with tag " + workerTag + " needs to be recycled");
|
||||||
|
|
||||||
|
if(workerTag == null || workerTag.isEmpty()) {
|
||||||
|
s_logger.error("Invalid worker VM tag " + workerTag);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String tokens[] = workerTag.split("-");
|
||||||
|
if(tokens.length != 3) {
|
||||||
|
s_logger.error("Invalid worker VM tag " + workerTag);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
long startTick = Long.parseLong(tokens[0]);
|
||||||
|
long msid = Long.parseLong(tokens[1]);
|
||||||
|
long runid = Long.parseLong(tokens[2]);
|
||||||
|
|
||||||
|
if(_mshostPeerDao.countStateSeenInPeers(msid, runid, ManagementServerHost.State.Down) > 0) {
|
||||||
|
if(s_logger.isInfoEnabled())
|
||||||
|
s_logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msid == _clusterMgr.getManagementNodeId() && runid != _clusterMgr.getCurrentRunId()) {
|
||||||
|
if(s_logger.isInfoEnabled())
|
||||||
|
s_logger.info("Worker VM's owner management server has changed runid, recycle it");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(System.currentTimeMillis() - startTick > _hungWorkerTimeout) {
|
||||||
|
if(s_logger.isInfoEnabled())
|
||||||
|
s_logger.info("Worker VM expired, seconds elapsed: " + (System.currentTimeMillis() - startTick) / 1000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepareSecondaryStorageStore(String storageUrl) {
|
public void prepareSecondaryStorageStore(String storageUrl) {
|
||||||
String mountPoint = getMountPoint(storageUrl);
|
String mountPoint = getMountPoint(storageUrl);
|
||||||
|
|||||||
@ -333,22 +333,17 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||||||
try {
|
try {
|
||||||
vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
|
vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
if(s_logger.isDebugEnabled())
|
if(s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
|
s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
|
||||||
|
}
|
||||||
|
|
||||||
vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName());
|
vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName());
|
||||||
if(vmMo == null) {
|
if(vmMo == null) {
|
||||||
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
||||||
|
|
||||||
workerVMName = hostService.getWorkerName(context, cmd, 0);
|
workerVMName = hostService.getWorkerName(context, cmd, 0);
|
||||||
|
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
|
||||||
|
|
||||||
// attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup
|
|
||||||
if (!hyperHost.createBlankVm(workerVMName, null, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier.OTHER_GUEST.value(), morDs, false)) {
|
|
||||||
String msg = "Unable to create worker VM to execute BackupSnapshotCommand";
|
|
||||||
s_logger.error(msg);
|
|
||||||
throw new Exception(msg);
|
|
||||||
}
|
|
||||||
vmMo = hyperHost.findVmOnHyperHost(workerVMName);
|
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName);
|
throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName);
|
||||||
}
|
}
|
||||||
@ -1071,28 +1066,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
|||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
// create a dummy worker vm for attaching the volume
|
// create a dummy worker vm for attaching the volume
|
||||||
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
||||||
//restrict VM name to 32 chars, (else snapshot descriptor file name will be truncated to 32 chars of vm name)
|
workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName);
|
||||||
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
|
|
||||||
vmConfig.setName(workerVmName);
|
|
||||||
vmConfig.setMemoryMB((long) 4);
|
|
||||||
vmConfig.setNumCPUs(1);
|
|
||||||
vmConfig.setGuestId(VirtualMachineGuestOsIdentifier.OTHER_GUEST.value());
|
|
||||||
VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
|
|
||||||
fileInfo.setVmPathName(String.format("[%s]", dsMo.getName()));
|
|
||||||
vmConfig.setFiles(fileInfo);
|
|
||||||
|
|
||||||
// Scsi controller
|
|
||||||
VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
|
|
||||||
scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
|
|
||||||
scsiController.setBusNumber(0);
|
|
||||||
scsiController.setKey(1);
|
|
||||||
VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
|
|
||||||
scsiControllerSpec.setDevice(scsiController);
|
|
||||||
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
|
||||||
vmConfig.getDeviceChange().add(scsiControllerSpec);
|
|
||||||
|
|
||||||
hyperHost.createVm(vmConfig);
|
|
||||||
workerVm = hyperHost.findVmOnHyperHost(workerVmName);
|
|
||||||
if (workerVm == null) {
|
if (workerVm == null) {
|
||||||
String msg = "Unable to create worker VM to execute CopyVolumeCommand";
|
String msg = "Unable to create worker VM to execute CopyVolumeCommand";
|
||||||
s_logger.error(msg);
|
s_logger.error(msg);
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import javax.inject.Inject;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.cloud.cluster.ClusterManager;
|
||||||
import com.cloud.hypervisor.vmware.manager.VmwareManager;
|
import com.cloud.hypervisor.vmware.manager.VmwareManager;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
@ -34,9 +35,11 @@ public class VmwareContextFactory {
|
|||||||
|
|
||||||
private static volatile int s_seq = 1;
|
private static volatile int s_seq = 1;
|
||||||
private static VmwareManager s_vmwareMgr;
|
private static VmwareManager s_vmwareMgr;
|
||||||
|
private static ClusterManager s_clusterMgr;
|
||||||
private static VmwareContextPool s_pool;
|
private static VmwareContextPool s_pool;
|
||||||
|
|
||||||
@Inject VmwareManager _vmwareMgr;
|
@Inject VmwareManager _vmwareMgr;
|
||||||
|
@Inject ClusterManager _clusterMgr;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// skip certificate check
|
// skip certificate check
|
||||||
@ -47,6 +50,7 @@ public class VmwareContextFactory {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
s_vmwareMgr = _vmwareMgr;
|
s_vmwareMgr = _vmwareMgr;
|
||||||
|
s_clusterMgr = _clusterMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VmwareContext create(String vCenterAddress, String vCenterUserName, String vCenterPassword) throws Exception {
|
public static VmwareContext create(String vCenterAddress, String vCenterUserName, String vCenterPassword) throws Exception {
|
||||||
@ -66,6 +70,7 @@ public class VmwareContextFactory {
|
|||||||
|
|
||||||
context.registerStockObject("serviceconsole", s_vmwareMgr.getServiceConsolePortGroupName());
|
context.registerStockObject("serviceconsole", s_vmwareMgr.getServiceConsolePortGroupName());
|
||||||
context.registerStockObject("manageportgroup", s_vmwareMgr.getManagementPortGroupName());
|
context.registerStockObject("manageportgroup", s_vmwareMgr.getManagementPortGroupName());
|
||||||
|
context.registerStockObject("noderuninfo", String.format("%d-%d", s_clusterMgr.getManagementNodeId(), s_clusterMgr.getCurrentRunId()));
|
||||||
|
|
||||||
context.setPoolInfo(s_pool, VmwareContextPool.composePoolKey(vCenterAddress, vCenterUserName));
|
context.setPoolInfo(s_pool, VmwareContextPool.composePoolKey(vCenterAddress, vCenterUserName));
|
||||||
s_pool.registerOutstandingContext(context);
|
s_pool.registerOutstandingContext(context);
|
||||||
@ -83,6 +88,7 @@ public class VmwareContextFactory {
|
|||||||
|
|
||||||
context.registerStockObject("serviceconsole", s_vmwareMgr.getServiceConsolePortGroupName());
|
context.registerStockObject("serviceconsole", s_vmwareMgr.getServiceConsolePortGroupName());
|
||||||
context.registerStockObject("manageportgroup", s_vmwareMgr.getManagementPortGroupName());
|
context.registerStockObject("manageportgroup", s_vmwareMgr.getManagementPortGroupName());
|
||||||
|
context.registerStockObject("noderuninfo", String.format("%d-%d", s_clusterMgr.getManagementNodeId(), s_clusterMgr.getCurrentRunId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -284,7 +283,6 @@ import com.cloud.hypervisor.vmware.mo.DatastoreMO;
|
|||||||
import com.cloud.hypervisor.vmware.mo.DiskControllerType;
|
import com.cloud.hypervisor.vmware.mo.DiskControllerType;
|
||||||
import com.cloud.hypervisor.vmware.mo.FeatureKeyConstants;
|
import com.cloud.hypervisor.vmware.mo.FeatureKeyConstants;
|
||||||
import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
|
import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
|
||||||
import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO;
|
|
||||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||||
import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
|
import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
|
||||||
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
|
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
|
||||||
@ -322,7 +320,6 @@ import com.cloud.utils.DateUtil;
|
|||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.StringUtils;
|
import com.cloud.utils.StringUtils;
|
||||||
import com.cloud.utils.component.ComponentContext;
|
|
||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.utils.exception.ExceptionUtil;
|
import com.cloud.utils.exception.ExceptionUtil;
|
||||||
@ -4462,7 +4459,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
if (!dsMo.fileExists(volumeDatastorePath)) {
|
if (!dsMo.fileExists(volumeDatastorePath)) {
|
||||||
String dummyVmName = getWorkerName(context, cmd, 0);
|
String dummyVmName = getWorkerName(context, cmd, 0);
|
||||||
|
|
||||||
VirtualMachineMO vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName);
|
VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
|
||||||
|
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
throw new Exception("Unable to create a dummy VM for volume creation");
|
throw new Exception("Unable to create a dummy VM for volume creation");
|
||||||
@ -5621,7 +5618,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
VirtualMachineMO vmMo = null;
|
VirtualMachineMO vmMo = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName);
|
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
throw new Exception("Unable to create a dummy VM for volume creation");
|
throw new Exception("Unable to create a dummy VM for volume creation");
|
||||||
}
|
}
|
||||||
@ -5678,7 +5675,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeUuid);
|
String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeUuid);
|
||||||
String dummyVmName = getWorkerName(context, cmd, 0);
|
String dummyVmName = getWorkerName(context, cmd, 0);
|
||||||
try {
|
try {
|
||||||
vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName);
|
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
|
||||||
if (vmMo == null) {
|
if (vmMo == null) {
|
||||||
throw new Exception("Unable to create a dummy VM for volume creation");
|
throw new Exception("Unable to create a dummy VM for volume creation");
|
||||||
}
|
}
|
||||||
@ -5713,34 +5710,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
return (int)(bytes / (1024L * 1024L));
|
return (int)(bytes / (1024L * 1024L));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected VirtualMachineMO prepareVolumeHostDummyVm(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName) throws Exception {
|
|
||||||
assert (hyperHost != null);
|
|
||||||
|
|
||||||
VirtualMachineMO vmMo = null;
|
|
||||||
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
|
|
||||||
vmConfig.setName(vmName);
|
|
||||||
vmConfig.setMemoryMB((long) 4); // vmware request minimum of 4 MB
|
|
||||||
vmConfig.setNumCPUs(1);
|
|
||||||
vmConfig.setGuestId(VirtualMachineGuestOsIdentifier.OTHER_GUEST.value());
|
|
||||||
VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
|
|
||||||
fileInfo.setVmPathName(String.format("[%s]", dsMo.getName()));
|
|
||||||
vmConfig.setFiles(fileInfo);
|
|
||||||
|
|
||||||
// Scsi controller
|
|
||||||
VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
|
|
||||||
scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
|
|
||||||
scsiController.setBusNumber(0);
|
|
||||||
scsiController.setKey(1);
|
|
||||||
VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
|
|
||||||
scsiControllerSpec.setDevice(scsiController);
|
|
||||||
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
|
||||||
|
|
||||||
vmConfig.getDeviceChange().add(scsiControllerSpec );
|
|
||||||
hyperHost.createVm(vmConfig);
|
|
||||||
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
|
||||||
return vmMo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnected() {
|
public void disconnected() {
|
||||||
}
|
}
|
||||||
@ -5767,62 +5736,46 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
if(hyperHost.isHyperHostConnected()) {
|
if(hyperHost.isHyperHostConnected()) {
|
||||||
mgr.gcLeftOverVMs(context);
|
mgr.gcLeftOverVMs(context);
|
||||||
|
|
||||||
if(_recycleHungWorker) {
|
|
||||||
s_logger.info("Scan hung worker VM to recycle");
|
s_logger.info("Scan hung worker VM to recycle");
|
||||||
|
|
||||||
int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
|
int workerKey = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
|
||||||
if(key == 0) {
|
int workerTagKey = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
|
||||||
s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
|
String workerPropName = String.format("value[%d]", workerKey);
|
||||||
}
|
String workerTagPropName = String.format("value[%d]", workerTagKey);
|
||||||
String instanceNameCustomField = "value[" + key + "]";
|
|
||||||
|
|
||||||
// GC worker that has been running for too long
|
// GC worker that has been running for too long
|
||||||
ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(
|
ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(
|
||||||
new String[] {"name", "config.template", "runtime.powerState", "runtime.bootTime", instanceNameCustomField });
|
new String[] {"name", "config.template", workerPropName, workerTagPropName,
|
||||||
|
});
|
||||||
if(ocs != null) {
|
if(ocs != null) {
|
||||||
for(ObjectContent oc : ocs) {
|
for(ObjectContent oc : ocs) {
|
||||||
List<DynamicProperty> props = oc.getPropSet();
|
List<DynamicProperty> props = oc.getPropSet();
|
||||||
if(props != null) {
|
if(props != null) {
|
||||||
String vmName = null;
|
|
||||||
String internalName = null;
|
|
||||||
boolean template = false;
|
boolean template = false;
|
||||||
VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
|
boolean isWorker = false;
|
||||||
GregorianCalendar bootTime = null;
|
String workerTag = null;
|
||||||
|
|
||||||
for(DynamicProperty prop : props) {
|
for(DynamicProperty prop : props) {
|
||||||
if (prop.getName().equals("name"))
|
if(prop.getName().equals("config.template")) {
|
||||||
vmName = prop.getVal().toString();
|
|
||||||
else if(prop.getName().startsWith("value[")) {
|
|
||||||
if(prop.getVal() != null)
|
|
||||||
internalName = ((CustomFieldStringValue)prop.getVal()).getValue();
|
|
||||||
}
|
|
||||||
else if(prop.getName().equals("config.template"))
|
|
||||||
template = (Boolean)prop.getVal();
|
template = (Boolean)prop.getVal();
|
||||||
else if(prop.getName().equals("runtime.powerState"))
|
} else if(prop.getName().equals(workerPropName)) {
|
||||||
powerState = (VirtualMachinePowerState)prop.getVal();
|
CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
|
||||||
else if(prop.getName().equals("runtime.bootTime"))
|
if(val != null && val.getValue() != null && val.getValue().equalsIgnoreCase("true"))
|
||||||
bootTime = (GregorianCalendar)prop.getVal();
|
isWorker = true;
|
||||||
|
}
|
||||||
|
else if(prop.getName().equals(workerTagPropName)) {
|
||||||
|
CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
|
||||||
|
workerTag = val.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualMachineMO vmMo = new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
|
VirtualMachineMO vmMo = new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
|
||||||
String name = null;
|
if(!template && isWorker) {
|
||||||
if (internalName != null) {
|
|
||||||
name = internalName;
|
|
||||||
} else {
|
|
||||||
name = vmName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!template && name.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) {
|
|
||||||
boolean recycle = false;
|
boolean recycle = false;
|
||||||
|
recycle = mgr.needRecycle(workerTag);
|
||||||
// recycle stopped worker VM and VM that has been running for too long (hard-coded 10 hours for now)
|
|
||||||
if(powerState == VirtualMachinePowerState.POWERED_OFF)
|
|
||||||
recycle = true;
|
|
||||||
else if(bootTime != null && (new Date().getTime() - bootTime.getTimeInMillis() > 10*3600*1000))
|
|
||||||
recycle = true;
|
|
||||||
|
|
||||||
if(recycle) {
|
if(recycle) {
|
||||||
s_logger.info("Recycle pending worker VM: " + name);
|
s_logger.info("Recycle pending worker VM: " + vmMo.getName());
|
||||||
|
|
||||||
vmMo.powerOff();
|
vmMo.powerOff();
|
||||||
vmMo.destroy();
|
vmMo.destroy();
|
||||||
@ -5831,7 +5784,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
s_logger.error("Host is no longer connected.");
|
s_logger.error("Host is no longer connected.");
|
||||||
return null;
|
return null;
|
||||||
@ -6613,6 +6565,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
|
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
|
||||||
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
|
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
|
||||||
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
|
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
|
||||||
|
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
|
||||||
|
cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
|
||||||
|
|
||||||
VmwareHypervisorHost hostMo = this.getHyperHost(context);
|
VmwareHypervisorHost hostMo = this.getHyperHost(context);
|
||||||
_hostName = hostMo.getHyperHostName();
|
_hostName = hostMo.getHyperHostName();
|
||||||
|
|||||||
@ -218,6 +218,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
|||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.registerStockObject("serviceconsole", cmd.getContextParam("serviceconsole"));
|
context.registerStockObject("serviceconsole", cmd.getContextParam("serviceconsole"));
|
||||||
context.registerStockObject("manageportgroup", cmd.getContextParam("manageportgroup"));
|
context.registerStockObject("manageportgroup", cmd.getContextParam("manageportgroup"));
|
||||||
|
context.registerStockObject("noderuninfo", cmd.getContextParam("noderuninfo"));
|
||||||
}
|
}
|
||||||
currentContext.set(context);
|
currentContext.set(context);
|
||||||
return context;
|
return context;
|
||||||
|
|||||||
@ -178,7 +178,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) {
|
if(vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) {
|
||||||
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateUuid);
|
// the same template may be deployed with multiple copies at per-datastore per-host basis,
|
||||||
|
// save the original template name from CloudStack DB as the UUID to associate them.
|
||||||
|
vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateName);
|
||||||
vmMo.markAsTemplate();
|
vmMo.markAsTemplate();
|
||||||
} else {
|
} else {
|
||||||
vmMo.destroy();
|
vmMo.destroy();
|
||||||
|
|||||||
@ -260,6 +260,7 @@ public enum Config {
|
|||||||
VmwareRootDiskControllerType("Advanced", ManagementServer.class, String.class, "vmware.root.disk.controller", "ide", "Specify the default disk controller for root volumes, valid values are scsi, ide", null),
|
VmwareRootDiskControllerType("Advanced", ManagementServer.class, String.class, "vmware.root.disk.controller", "ide", "Specify the default disk controller for root volumes, valid values are scsi, ide", null),
|
||||||
VmwareSystemVmNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.systemvm.nic.device.type", "E1000", "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null),
|
VmwareSystemVmNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.systemvm.nic.device.type", "E1000", "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null),
|
||||||
VmwareRecycleHungWorker("Advanced", ManagementServer.class, Boolean.class, "vmware.recycle.hung.wokervm", "false", "Specify whether or not to recycle hung worker VMs", null),
|
VmwareRecycleHungWorker("Advanced", ManagementServer.class, Boolean.class, "vmware.recycle.hung.wokervm", "false", "Specify whether or not to recycle hung worker VMs", null),
|
||||||
|
VmwareHungWorkerTimeout("Advanced", ManagementServer.class, Long.class, "vmware.hung.wokervm.timeout", "7200", "Worker VM timeout in seconds", null),
|
||||||
VmwareEnableNestedVirtualization("Advanced", ManagementServer.class, Boolean.class, "vmware.nested.virtualization", "false", "When set to true this will enable nested virtualization when this is supported by the hypervisor", null),
|
VmwareEnableNestedVirtualization("Advanced", ManagementServer.class, Boolean.class, "vmware.nested.virtualization", "false", "When set to true this will enable nested virtualization when this is supported by the hypervisor", null),
|
||||||
|
|
||||||
// Midonet
|
// Midonet
|
||||||
|
|||||||
@ -23,4 +23,6 @@ public interface CustomFieldConstants {
|
|||||||
public final static String CLOUD_NIC_MASK = "cloud.nic.mask";
|
public final static String CLOUD_NIC_MASK = "cloud.nic.mask";
|
||||||
public final static String CLOUD_ZONE = "cloud.zone";
|
public final static String CLOUD_ZONE = "cloud.zone";
|
||||||
public final static String CLOUD_VM_INTERNAL_NAME = "cloud.vm.internal.name";
|
public final static String CLOUD_VM_INTERNAL_NAME = "cloud.vm.internal.name";
|
||||||
|
public final static String CLOUD_WORKER = "cloud.vm.worker";
|
||||||
|
public final static String CLOUD_WORKER_TAG = "cloud.vm.worker.tag";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1233,8 +1233,24 @@ public class HypervisorHostHelper {
|
|||||||
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
||||||
|
|
||||||
vmConfig.getDeviceChange().add(scsiControllerSpec);
|
vmConfig.getDeviceChange().add(scsiControllerSpec);
|
||||||
hyperHost.createVm(vmConfig);
|
if(hyperHost.createVm(vmConfig)) {
|
||||||
|
// Ugly work-around, it takes time for newly created VM to appear
|
||||||
|
for(int i = 0; i < 10 && workingVM == null; i++) {
|
||||||
workingVM = hyperHost.findVmOnHyperHost(vmName);
|
workingVM = hyperHost.findVmOnHyperHost(vmName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(workingVM != null) {
|
||||||
|
workingVM.setCustomFieldValue(CustomFieldConstants.CLOUD_WORKER, "true");
|
||||||
|
String workerTag = String.format("%d-%s", System.currentTimeMillis(),
|
||||||
|
hyperHost.getContext().getStockObject("noderuninfo"));
|
||||||
|
workingVM.setCustomFieldValue(CustomFieldConstants.CLOUD_WORKER_TAG, workerTag);
|
||||||
|
}
|
||||||
return workingVM;
|
return workingVM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1559,12 +1559,8 @@ public class VirtualMachineMO extends BaseMO {
|
|||||||
assert(disks.length >= 1);
|
assert(disks.length >= 1);
|
||||||
|
|
||||||
HostMO hostMo = getRunningHost();
|
HostMO hostMo = getRunningHost();
|
||||||
VirtualMachineConfigInfo vmConfigInfo = getConfigInfo();
|
|
||||||
|
|
||||||
if(!hostMo.createBlankVm(clonedVmName, null, 1, cpuSpeedMHz, 0, false, memoryMb, 0, vmConfigInfo.getGuestId(), morDs, false))
|
VirtualMachineMO clonedVmMo = HypervisorHostHelper.createWorkerVM(hostMo, new DatastoreMO(hostMo.getContext(), morDs), clonedVmName);
|
||||||
throw new Exception("Unable to create a blank VM");
|
|
||||||
|
|
||||||
VirtualMachineMO clonedVmMo = hostMo.findVmOnHyperHost(clonedVmName);
|
|
||||||
if(clonedVmMo == null)
|
if(clonedVmMo == null)
|
||||||
throw new Exception("Unable to find just-created blank VM");
|
throw new Exception("Unable to find just-created blank VM");
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user