migration code

This commit is contained in:
Alex Huang 2011-01-14 08:55:43 -08:00
parent 5810e809da
commit 19edfdfcdb
11 changed files with 748 additions and 643 deletions

View File

@ -81,4 +81,9 @@ public class DeployDestination {
}
return this._host.getId() == that._host.getId();
}
@Override
public String toString() {
return new StringBuilder("Dest[").append(_dc.getId()).append("-").append(_pod.getId()).append("-").append(_cluster.getId()).append("-").append(_host.getId()).append("]").toString();
}
}

View File

@ -43,7 +43,6 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.HostVO;
@ -283,11 +282,6 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu
return new StopCommand(vm, vmName, null);
}
@Override
public boolean completeMigration(ConsoleProxyVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
return false;
}
@Override
public void completeStartCommand(ConsoleProxyVO vm) {
}
@ -304,21 +298,6 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu
return VirtualMachineName.getConsoleProxyId(vmName);
}
@Override
public ConsoleProxyVO get(long id) {
return null;
}
@Override
public boolean migrate(ConsoleProxyVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
return false;
}
@Override
public HostVO prepareForMigration(ConsoleProxyVO vm) throws InsufficientCapacityException, StorageUnavailableException {
return null;
}
@Override
public ConsoleProxyVO start(long vmId) throws InsufficientCapacityException, StorageUnavailableException,
ConcurrentOperationException {

View File

@ -26,7 +26,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
@ -42,14 +41,10 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
@ -91,7 +86,6 @@ import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
@ -115,7 +109,6 @@ import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.servlet.ConsoleProxyServlet;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
@ -1464,11 +1457,6 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx
}
}
@Override
public ConsoleProxyVO get(long id) {
return _consoleProxyDao.findById(id);
}
@Override
public Long convertToId(String vmName) {
if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
@ -1649,100 +1637,100 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx
}
}
@Override
public boolean migrate(ConsoleProxyVO proxy, HostVO host) {
HostVO fromHost = _hostDao.findById(proxy.getId());
if (! _itMgr.stateTransitTo(proxy, VirtualMachine.Event.MigrationRequested, proxy.getHostId())) {
s_logger.debug("State for " + proxy.toString() + " has changed so migration can not take place.");
return false;
}
MigrateCommand cmd = new MigrateCommand(proxy.getInstanceName(), host.getPrivateIpAddress(), false);
Answer answer = _agentMgr.easySend(fromHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
return false;
}
_storageMgr.unshare(proxy, fromHost);
return true;
}
@Override
public boolean completeMigration(ConsoleProxyVO proxy, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(proxy.getInstanceName());
CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm);
if (!answer.getResult()) {
s_logger.debug("Unable to complete migration for " + proxy.getId());
_itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
State state = answer.getState();
if (state == State.Stopped) {
s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId());
_itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
_itMgr.stateTransitTo(proxy, VirtualMachine.Event.OperationSucceeded, host.getId());
return true;
}
@Override
public HostVO prepareForMigration(ConsoleProxyVO proxy) throws StorageUnavailableException {
VMTemplateVO template = _templateDao.findById(proxy.getTemplateId());
long routerId = proxy.getId();
boolean mirroredVols = proxy.isMirroredVols();
DataCenterVO dc = _dcDao.findById(proxy.getDataCenterId());
HostPodVO pod = _podDao.findById(proxy.getPodId());
StoragePoolVO sp = _storageMgr.getStoragePoolForVm(proxy.getId());
List<VolumeVO> vols = _volsDao.findCreatedByInstance(routerId);
String[] storageIps = new String[2];
VolumeVO vol = vols.get(0);
storageIps[0] = vol.getHostIp();
if (mirroredVols && (vols.size() == 2)) {
storageIps[1] = vols.get(1).getHostIp();
}
PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(proxy.getName(), null, storageIps, vols, mirroredVols);
HostVO routingHost = null;
HashSet<Host> avoid = new HashSet<Host>();
HostVO fromHost = _hostDao.findById(proxy.getHostId());
if (fromHost.getClusterId() == null) {
s_logger.debug("The host is not in a cluster");
return null;
}
avoid.add(fromHost);
while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, _serviceOffering, template, proxy, fromHost, avoid)) != null) {
avoid.add(routingHost);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Trying to migrate router to host " + routingHost.getName());
}
if (!_storageMgr.share(proxy, vols, routingHost, false)) {
s_logger.warn("Can not share " + proxy.getName());
throw new StorageUnavailableException("Can not share " + proxy.getName(), vol.getPoolId());
}
Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
if (answer != null && answer.getResult()) {
return routingHost;
}
_storageMgr.unshare(proxy, vols, routingHost);
}
return null;
}
// @Override
// public boolean migrate(ConsoleProxyVO proxy, HostVO host) {
// HostVO fromHost = _hostDao.findById(proxy.getId());
//
// if (! _itMgr.stateTransitTo(proxy, VirtualMachine.Event.MigrationRequested, proxy.getHostId())) {
// s_logger.debug("State for " + proxy.toString() + " has changed so migration can not take place.");
// return false;
// }
//
// MigrateCommand cmd = new MigrateCommand(proxy.getInstanceName(), host.getPrivateIpAddress(), false);
// Answer answer = _agentMgr.easySend(fromHost.getId(), cmd);
// if (answer == null || !answer.getResult()) {
// return false;
// }
//
// _storageMgr.unshare(proxy, fromHost);
//
// return true;
// }
//
// @Override
// public boolean completeMigration(ConsoleProxyVO proxy, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
//
// CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(proxy.getInstanceName());
// CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm);
// if (!answer.getResult()) {
// s_logger.debug("Unable to complete migration for " + proxy.getId());
// _itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// State state = answer.getState();
// if (state == State.Stopped) {
// s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId());
// _itMgr.stateTransitTo(proxy, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// _itMgr.stateTransitTo(proxy, VirtualMachine.Event.OperationSucceeded, host.getId());
// return true;
// }
//
// @Override
// public HostVO prepareForMigration(ConsoleProxyVO proxy) throws StorageUnavailableException {
//
// VMTemplateVO template = _templateDao.findById(proxy.getTemplateId());
// long routerId = proxy.getId();
// boolean mirroredVols = proxy.isMirroredVols();
// DataCenterVO dc = _dcDao.findById(proxy.getDataCenterId());
// HostPodVO pod = _podDao.findById(proxy.getPodId());
// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(proxy.getId());
//
// List<VolumeVO> vols = _volsDao.findCreatedByInstance(routerId);
//
// String[] storageIps = new String[2];
// VolumeVO vol = vols.get(0);
// storageIps[0] = vol.getHostIp();
// if (mirroredVols && (vols.size() == 2)) {
// storageIps[1] = vols.get(1).getHostIp();
// }
//
// PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(proxy.getName(), null, storageIps, vols, mirroredVols);
//
// HostVO routingHost = null;
// HashSet<Host> avoid = new HashSet<Host>();
//
// HostVO fromHost = _hostDao.findById(proxy.getHostId());
// if (fromHost.getClusterId() == null) {
// s_logger.debug("The host is not in a cluster");
// return null;
// }
// avoid.add(fromHost);
//
// while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, _serviceOffering, template, proxy, fromHost, avoid)) != null) {
// avoid.add(routingHost);
//
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Trying to migrate router to host " + routingHost.getName());
// }
//
// if (!_storageMgr.share(proxy, vols, routingHost, false)) {
// s_logger.warn("Can not share " + proxy.getName());
// throw new StorageUnavailableException("Can not share " + proxy.getName(), vol.getPoolId());
// }
//
// Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
// if (answer != null && answer.getResult()) {
// return routingHost;
// }
// _storageMgr.unshare(proxy, vols, routingHost);
// }
//
// return null;
// }
private String getCapacityScanLockName() {
// to improve security, it may be better to return a unique mashed

View File

@ -29,7 +29,6 @@ import com.cloud.host.HostVO;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.ConsoleProxyDao;
@ -67,9 +66,4 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp
return true;
}
@Override
public ConsoleProxyVO get(long id) {
return _proxyDao.findById(id);
}
}

View File

@ -36,7 +36,6 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.alert.AlertManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
@ -46,9 +45,9 @@ import com.cloud.dc.dao.HostPodDao;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HaWorkVO.WorkType;
import com.cloud.ha.dao.HighAvailabilityDao;
import com.cloud.host.Host;
@ -272,7 +271,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
public void scheduleRestart(VMInstanceVO vm, final boolean investigate) {
Long hostId = vm.getHostId();
VirtualMachineGuru<VMInstanceVO> mgr = findManager(vm.getType());
vm = mgr.get(vm.getId());
vm = mgr.findById(vm.getId());
if (!investigate) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("VM does not require investigation so I'm marking it as Stopped: " + vm.toString());
@ -334,7 +333,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
return null;
}
VMInstanceVO vm = mgr.get(vmId);
VMInstanceVO vm = mgr.findById(vmId);
if (vm == null) {
s_logger.info("Unable to find vm: " + vmId);
return null;
@ -422,7 +421,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
+ hostDesc, "Virtual Machine " + vm.getName() + " (id: "
+ vm.getId() + ") running on host [" + hostDesc + "] stopped unexpectedly.");
vm = mgr.get(vm.getId());
vm = mgr.findById(vm.getId());
if (!_forceHA && !vm.isHaEnabled()) {
if (s_logger.isDebugEnabled()) {
@ -453,7 +452,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval);
}
vm = mgr.get(vm.getId());
vm = mgr.findById(vm.getId());
work.setUpdateTime(vm.getUpdated());
work.setPreviousState(vm.getState());
return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
@ -540,13 +539,13 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
// to ensure there's cleanup.
if (serverState == State.Running ) {
// Our records showed that it should be running so let's restart it.
vm = info.mgr.get(vm.getId());
vm = info.mgr.findById(vm.getId());
scheduleRestart(vm, false);
command = info.mgr.cleanup(vm, agentName);
} else if (serverState == State.Stopping) {
if (fullSync) {
s_logger.debug("VM is in stopping state on full sync. Updating the status to stopped");
vm = info.mgr.get(vm.getId());
vm = info.mgr.findById(vm.getId());
info.mgr.completeStopCommand(vm);
command = info.mgr.cleanup(vm, agentName);
} else {
@ -563,13 +562,13 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
if (serverState == State.Starting) {
if (fullSync) {
s_logger.debug("VM state is starting on full sync so updating it to running");
vm = info.mgr.get(vm.getId());
vm = info.mgr.findById(vm.getId());
info.mgr.completeStartCommand(vm);
}
} else if (serverState == State.Stopping) {
if (fullSync) {
s_logger.debug("VM state is in stopping on fullsync so resend stop.");
vm = info.mgr.get(vm.getId());
vm = info.mgr.findById(vm.getId());
info.mgr.completeStopCommand(vm);
command = info.mgr.cleanup(vm, agentName);
} else {
@ -577,7 +576,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
}
} else if (serverState == State.Destroyed || serverState == State.Stopped || serverState == State.Expunging) {
s_logger.debug("VM state is in stopped so stopping it on the agent");
vm = info.mgr.get(vm.getId());
vm = info.mgr.findById(vm.getId());
command = info.mgr.cleanup(vm, agentName);
} else {
_itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportRunning, vm.getHostId());
@ -619,7 +618,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
assert info.mgr != null : "How can the manager be null for " + vm.getType();
VMInstanceVO vmCasted = info.mgr.get(vm.getId());
VMInstanceVO vmCasted = info.mgr.findById(vm.getId());
final Command command = compareState(vmCasted, info, true);
if (command != null) {
commands.add(command);
@ -666,7 +665,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
for (final Map.Entry<Long, AgentVmInfo> entry : states.entrySet()) {
final AgentVmInfo info = entry.getValue();
final VMInstanceVO vm = info.mgr.get(entry.getKey());
final VMInstanceVO vm = info.mgr.findById(entry.getKey());
Command command = null;
if (vm != null && vm.getHostId() != null && vm.getHostId() == hostId) {
@ -685,136 +684,151 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
}
public Long migrate(final HaWorkVO work) {
final long vmId = work.getInstanceId();
final VirtualMachineGuru<VMInstanceVO> mgr = findManager(work.getType());
VMInstanceVO vm = mgr.get(vmId);
if (vm == null || vm.getRemoved() != null) {
s_logger.debug("Unable to find the vm " + vmId);
return null;
}
s_logger.info("Migrating vm: " + vm.toString());
if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) {
s_logger.info("VM is not longer running on the current hostId");
return null;
}
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;
}
HostVO fromHost = _hostDao.findById(vm.getHostId());
String fromHostName = ((fromHost == null) ? "unknown" : fromHost.getName());
HostVO toHost = null;
if (work.getStep() == Step.Scheduled) {
if (vm.getState() != State.Running) {
s_logger.info("VM's state is not ready for migration. " + vm.toString() + " State is " + vm.getState().toString());
return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
}
DataCenterVO dcVO = _dcDao.findById(fromHost.getDataCenterId());
HostPodVO podVO = _podDao.findById(fromHost.getPodId());
try {
toHost = mgr.prepareForMigration(vm);
if (toHost == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find a host for migrating vm " + vmId);
}
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Unable to find a suitable host");
}
} catch(final InsufficientCapacityException e) {
s_logger.warn("Unable to mgirate due to insufficient capacity " + vm.toString());
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Insufficient capacity");
} catch(final StorageUnavailableException e) {
s_logger.warn("Storage is unavailable: " + vm.toString());
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Storage is gone.");
}
if (toHost == null) {
_agentMgr.maintenanceFailed(vm.getHostId());
return null;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Migrating from " + work.getHostId() + " to " + toHost.getId());
}
work.setStep(Step.Migrating);
work.setHostId(toHost.getId());
_haDao.update(work.getId(), work);
}
if (work.getStep() == Step.Migrating) {
vm = mgr.get(vmId); // let's see if anything has changed.
boolean migrated = false;
if (vm == null || vm.getRemoved() != null || vm.getHostId() == null || !_itMgr.stateTransitTo(vm, Event.MigrationRequested, vm.getHostId())) {
s_logger.info("Migration cancelled because state has changed: " + vm.toString());
} else {
try {
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), toHost.getPrivateIpAddress(), isWindows);
Answer answer = _agentMgr.send(fromHost.getId(), cmd);
if (answer != null && answer.getResult()) {
migrated = true;
_storageMgr.unshare(vm, fromHost);
work.setStep(Step.Investigating);
_haDao.update(work.getId(), work);
}
} catch (final AgentUnavailableException e) {
s_logger.debug("host became unavailable");
} catch (final OperationTimedoutException e) {
s_logger.debug("operation timed out");
if (e.isActive()) {
scheduleRestart(vm, true);
}
}
}
if (!migrated) {
s_logger.info("Migration was unsuccessful. Cleaning up: " + vm.toString());
DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterId());
HostPodVO podVO = _podDao.findById(vm.getPodId());
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migrate Command failed. Please check logs.");
_itMgr.stateTransitTo(vm, Event.MigrationFailedOnSource, toHost.getId());
_agentMgr.maintenanceFailed(vm.getHostId());
Command cleanup = mgr.cleanup(vm, null);
_agentMgr.easySend(toHost.getId(), cleanup);
_storageMgr.unshare(vm, toHost);
return null;
}
}
if (toHost == null) {
toHost = _hostDao.findById(work.getHostId());
}
DataCenterVO dcVO = _dcDao.findById(toHost.getDataCenterId());
HostPodVO podVO = _podDao.findById(toHost.getPodId());
long vmId = work.getInstanceId();
long srcHostId = work.getHostId();
try {
if (!mgr.completeMigration(vm, toHost)) {
_alertMgr.sendAlert(alertType, toHost.getDataCenterId(), toHost.getPodId(), "Unable to migrate " + vmId + " to host " + toHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migration not completed");
s_logger.warn("Unable to complete migration: " + vm.toString());
} else {
s_logger.info("Migration is complete: " + vm.toString());
if (!_itMgr.migrate(work.getType(), vmId, srcHostId)) {
s_logger.warn("Unable to migrate vm from " + srcHostId);
_agentMgr.maintenanceFailed(srcHostId);
}
return null;
} catch (final AgentUnavailableException e) {
s_logger.warn("Agent is unavailable for " + vm.toString());
} catch (final OperationTimedoutException e) {
s_logger.warn("Operation timed outfor " + vm.toString());
} catch (InsufficientServerCapacityException e) {
s_logger.warn("Insufficient capacity for migrating a VM.");
_agentMgr.maintenanceFailed(srcHostId);
return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
}
_itMgr.stateTransitTo(vm, Event.MigrationFailedOnDest, toHost.getId());
return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
}
// public Long migrate(final HaWorkVO work) {
// final long vmId = work.getInstanceId();
//
// final VirtualMachineGuru<VMInstanceVO> mgr = findManager(work.getType());
//
// VMInstanceVO vm = mgr.findById(vmId);
// if (vm == null || vm.getRemoved() != null) {
// s_logger.debug("Unable to find the vm " + vmId);
// return null;
// }
//
// s_logger.info("Migrating vm: " + vm.toString());
// if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) {
// s_logger.info("VM is not longer running on the current hostId");
// return null;
// }
//
// 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;
// }
//
// HostVO fromHost = _hostDao.findById(vm.getHostId());
// String fromHostName = ((fromHost == null) ? "unknown" : fromHost.getName());
// HostVO toHost = null;
// if (work.getStep() == Step.Scheduled) {
// if (vm.getState() != State.Running) {
// s_logger.info("VM's state is not ready for migration. " + vm.toString() + " State is " + vm.getState().toString());
// return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
// }
//
// DataCenterVO dcVO = _dcDao.findById(fromHost.getDataCenterId());
// HostPodVO podVO = _podDao.findById(fromHost.getPodId());
//
// try {
// toHost = mgr.prepareForMigration(vm);
// if (toHost == null) {
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Unable to find a host for migrating vm " + vmId);
// }
// _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Unable to find a suitable host");
// }
// } catch(final InsufficientCapacityException e) {
// s_logger.warn("Unable to mgirate due to insufficient capacity " + vm.toString());
// _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Insufficient capacity");
// } catch(final StorageUnavailableException e) {
// s_logger.warn("Storage is unavailable: " + vm.toString());
// _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHostName + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Storage is gone.");
// }
//
// if (toHost == null) {
// _agentMgr.maintenanceFailed(vm.getHostId());
// return null;
// }
//
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Migrating from " + work.getHostId() + " to " + toHost.getId());
// }
// work.setStep(Step.Migrating);
// work.setHostId(toHost.getId());
// _haDao.update(work.getId(), work);
// }
//
// if (work.getStep() == Step.Migrating) {
// vm = mgr.findById(vmId); // let's see if anything has changed.
// boolean migrated = false;
// if (vm == null || vm.getRemoved() != null || vm.getHostId() == null || !_itMgr.stateTransitTo(vm, Event.MigrationRequested, vm.getHostId())) {
// s_logger.info("Migration cancelled because state has changed: " + vm.toString());
// } else {
// try {
// boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
// MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), toHost.getPrivateIpAddress(), isWindows);
// Answer answer = _agentMgr.send(fromHost.getId(), cmd);
// if (answer != null && answer.getResult()) {
// migrated = true;
// _storageMgr.unshare(vm, fromHost);
// work.setStep(Step.Investigating);
// _haDao.update(work.getId(), work);
// }
// } catch (final AgentUnavailableException e) {
// s_logger.debug("host became unavailable");
// } catch (final OperationTimedoutException e) {
// s_logger.debug("operation timed out");
// if (e.isActive()) {
// scheduleRestart(vm, true);
// }
// }
// }
//
// if (!migrated) {
// s_logger.info("Migration was unsuccessful. Cleaning up: " + vm.toString());
//
// DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterId());
// HostPodVO podVO = _podDao.findById(vm.getPodId());
// _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migrate Command failed. Please check logs.");
//
// _itMgr.stateTransitTo(vm, Event.MigrationFailedOnSource, toHost.getId());
// _agentMgr.maintenanceFailed(vm.getHostId());
//
// Command cleanup = mgr.cleanup(vm, null);
// _agentMgr.easySend(toHost.getId(), cleanup);
// _storageMgr.unshare(vm, toHost);
//
// return null;
// }
// }
//
// if (toHost == null) {
// toHost = _hostDao.findById(work.getHostId());
// }
// DataCenterVO dcVO = _dcDao.findById(toHost.getDataCenterId());
// HostPodVO podVO = _podDao.findById(toHost.getPodId());
//
// try {
// if (!mgr.completeMigration(vm, toHost)) {
// _alertMgr.sendAlert(alertType, toHost.getDataCenterId(), toHost.getPodId(), "Unable to migrate " + vmId + " to host " + toHost.getName() + " in zone " + dcVO.getName() + " and pod " + podVO.getName(), "Migration not completed");
// s_logger.warn("Unable to complete migration: " + vm.toString());
// } else {
// s_logger.info("Migration is complete: " + vm.toString());
// }
// return null;
// } catch (final AgentUnavailableException e) {
// s_logger.warn("Agent is unavailable for " + vm.toString());
// } catch (final OperationTimedoutException e) {
// s_logger.warn("Operation timed outfor " + vm.toString());
// }
// _itMgr.stateTransitTo(vm, Event.MigrationFailedOnDest, toHost.getId());
// return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
// }
@Override
public void scheduleDestroy(VMInstanceVO vm, long hostId) {
@ -833,7 +847,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
protected Long destroyVM(HaWorkVO work) {
final VirtualMachineGuru<VMInstanceVO> mgr = findManager(work.getType());
final VMInstanceVO vm = mgr.get(work.getInstanceId());
final VMInstanceVO vm = mgr.findById(work.getInstanceId());
s_logger.info("Destroying " + vm.toString());
try {
if (vm.getState() != State.Destroyed) {
@ -867,7 +881,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
protected Long stopVM(final HaWorkVO work) {
final VirtualMachineGuru<VMInstanceVO> mgr = findManager(work.getType());
final VMInstanceVO vm = mgr.get(work.getInstanceId());
final VMInstanceVO vm = mgr.findById(work.getInstanceId());
s_logger.info("Stopping " + vm.toString());
try {
if (work.getWorkType() == WorkType.Stop) {

View File

@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
@ -36,14 +35,10 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.AgentManager.OnError;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.NetworkUsageAnswer;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.check.CheckSshAnswer;
@ -73,8 +68,6 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
@ -95,8 +88,6 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@ -141,9 +132,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.VMTemplateDao;
@ -740,11 +729,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
}
@Override
public DomainRouterVO get(final long id) {
return findById(id);
}
@Override
public Long convertToId(final String vmName) {
if (!VirtualMachineName.isValidRouterName(vmName, _instance)) {
@ -754,105 +738,105 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
return VirtualMachineName.getRouterId(vmName);
}
@Override
public HostVO prepareForMigration(final DomainRouterVO router) throws StorageUnavailableException {
final long routerId = router.getId();
final boolean mirroredVols = router.isMirroredVols();
final DataCenterVO dc = _dcDao.findById(router.getDataCenterId());
final HostPodVO pod = _podDao.findById(router.getPodId());
final ServiceOfferingVO offering = _serviceOfferingDao.findById(router.getServiceOfferingId());
StoragePoolVO sp = _storageMgr.getStoragePoolForVm(router.getId());
final List<VolumeVO> vols = _volsDao.findCreatedByInstance(routerId);
final String[] storageIps = new String[2];
final VolumeVO vol = vols.get(0);
storageIps[0] = vol.getHostIp();
if (mirroredVols && (vols.size() == 2)) {
storageIps[1] = vols.get(1).getHostIp();
}
final PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(router.getInstanceName(), router.getVnet(), storageIps, vols,
mirroredVols);
HostVO routingHost = null;
final HashSet<Host> avoid = new HashSet<Host>();
final HostVO fromHost = _hostDao.findById(router.getHostId());
if (fromHost.getHypervisorType() != HypervisorType.KVM && fromHost.getClusterId() == null) {
s_logger.debug("The host is not in a cluster");
return null;
}
avoid.add(fromHost);
while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, _template, router, fromHost, avoid)) != null) {
avoid.add(routingHost);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Trying to migrate router to host " + routingHost.getName());
}
if (!_storageMgr.share(router, vols, routingHost, false)) {
s_logger.warn("Can not share " + vol.getPath() + " to " + router.getName());
throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + router.getName(), sp.getId());
}
final Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
if (answer != null && answer.getResult()) {
return routingHost;
}
_storageMgr.unshare(router, vols, routingHost);
}
return null;
}
@Override
public boolean migrate(final DomainRouterVO router, final HostVO host) {
final HostVO fromHost = _hostDao.findById(router.getHostId());
if (!_itMgr.stateTransitTo(router, VirtualMachine.Event.MigrationRequested, router.getHostId())) {
s_logger.debug("State for " + router.toString() + " has changed so migration can not take place.");
return false;
}
final MigrateCommand cmd = new MigrateCommand(router.getInstanceName(), host.getPrivateIpAddress(), false);
final Answer answer = _agentMgr.easySend(fromHost.getId(), cmd);
if (answer == null) {
return false;
}
final List<VolumeVO> vols = _volsDao.findCreatedByInstance(router.getId());
if (vols.size() == 0) {
return true;
}
_storageMgr.unshare(router, vols, fromHost);
return true;
}
@Override
public boolean completeMigration(final DomainRouterVO router, final HostVO host) throws OperationTimedoutException, AgentUnavailableException {
final CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(router.getInstanceName());
final CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm);
if (answer == null || !answer.getResult()) {
s_logger.debug("Unable to complete migration for " + router.getId());
_itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
final State state = answer.getState();
if (state == State.Stopped) {
s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId());
_itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
_itMgr.stateTransitTo(router, VirtualMachine.Event.OperationSucceeded, host.getId());
return true;
}
// @Override
// public HostVO prepareForMigration(final DomainRouterVO router) throws StorageUnavailableException {
// final long routerId = router.getId();
// final boolean mirroredVols = router.isMirroredVols();
// final DataCenterVO dc = _dcDao.findById(router.getDataCenterId());
// final HostPodVO pod = _podDao.findById(router.getPodId());
// final ServiceOfferingVO offering = _serviceOfferingDao.findById(router.getServiceOfferingId());
// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(router.getId());
//
// final List<VolumeVO> vols = _volsDao.findCreatedByInstance(routerId);
//
// final String[] storageIps = new String[2];
// final VolumeVO vol = vols.get(0);
// storageIps[0] = vol.getHostIp();
// if (mirroredVols && (vols.size() == 2)) {
// storageIps[1] = vols.get(1).getHostIp();
// }
//
// final PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(router.getInstanceName(), router.getVnet(), storageIps, vols,
// mirroredVols);
//
// HostVO routingHost = null;
// final HashSet<Host> avoid = new HashSet<Host>();
//
// final HostVO fromHost = _hostDao.findById(router.getHostId());
// if (fromHost.getHypervisorType() != HypervisorType.KVM && fromHost.getClusterId() == null) {
// s_logger.debug("The host is not in a cluster");
// return null;
// }
// avoid.add(fromHost);
//
// while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, _template, router, fromHost, avoid)) != null) {
// avoid.add(routingHost);
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Trying to migrate router to host " + routingHost.getName());
// }
//
// if (!_storageMgr.share(router, vols, routingHost, false)) {
// s_logger.warn("Can not share " + vol.getPath() + " to " + router.getName());
// throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + router.getName(), sp.getId());
// }
//
// final Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
// if (answer != null && answer.getResult()) {
// return routingHost;
// }
//
// _storageMgr.unshare(router, vols, routingHost);
// }
//
// return null;
// }
//
// @Override
// public boolean migrate(final DomainRouterVO router, final HostVO host) {
// final HostVO fromHost = _hostDao.findById(router.getHostId());
//
// if (!_itMgr.stateTransitTo(router, VirtualMachine.Event.MigrationRequested, router.getHostId())) {
// s_logger.debug("State for " + router.toString() + " has changed so migration can not take place.");
// return false;
// }
//
// final MigrateCommand cmd = new MigrateCommand(router.getInstanceName(), host.getPrivateIpAddress(), false);
// final Answer answer = _agentMgr.easySend(fromHost.getId(), cmd);
// if (answer == null) {
// return false;
// }
//
// final List<VolumeVO> vols = _volsDao.findCreatedByInstance(router.getId());
// if (vols.size() == 0) {
// return true;
// }
//
// _storageMgr.unshare(router, vols, fromHost);
//
// return true;
// }
//
// @Override
// public boolean completeMigration(final DomainRouterVO router, final HostVO host) throws OperationTimedoutException, AgentUnavailableException {
// final CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(router.getInstanceName());
// final CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm);
// if (answer == null || !answer.getResult()) {
// s_logger.debug("Unable to complete migration for " + router.getId());
// _itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// final State state = answer.getState();
// if (state == State.Stopped) {
// s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId());
// _itMgr.stateTransitTo(router, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// _itMgr.stateTransitTo(router, VirtualMachine.Event.OperationSucceeded, host.getId());
//
// return true;
// }
protected class RouterCleanupTask implements Runnable {

View File

@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
@ -35,11 +34,7 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.SecStorageFirewallCfgCommand;
import com.cloud.agent.api.SecStorageSetupCommand;
@ -92,7 +87,6 @@ import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
@ -1017,11 +1011,6 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
}
}
@Override
public SecondaryStorageVmVO get(long id) {
return _secStorageVmDao.findById(id);
}
@Override
public Long convertToId(String vmName) {
if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, "s")) {
@ -1210,100 +1199,100 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
return true;
}
@Override
public boolean migrate(SecondaryStorageVmVO secStorageVm, HostVO host) {
HostVO fromHost = _hostDao.findById(secStorageVm.getId());
if (! _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.MigrationRequested, secStorageVm.getHostId())) {
s_logger.debug("State for " + secStorageVm.toString() + " has changed so migration can not take place.");
return false;
}
MigrateCommand cmd = new MigrateCommand(secStorageVm.getInstanceName(), host.getPrivateIpAddress(), false);
Answer answer = _agentMgr.easySend(fromHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
return false;
}
_storageMgr.unshare(secStorageVm, fromHost);
return true;
}
@Override
public boolean completeMigration(SecondaryStorageVmVO secStorageVm, HostVO host)
throws AgentUnavailableException, OperationTimedoutException {
CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(secStorageVm.getInstanceName());
CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm);
if (!answer.getResult()) {
s_logger.debug("Unable to complete migration for " + secStorageVm.getId());
_itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
State state = answer.getState();
if (state == State.Stopped) {
s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId());
_itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
_itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.OperationSucceeded, host.getId());
return true;
}
@Override
public HostVO prepareForMigration(SecondaryStorageVmVO secStorageVm) throws StorageUnavailableException {
VMTemplateVO template = _templateDao.findById(secStorageVm.getTemplateId());
long routerId = secStorageVm.getId();
boolean mirroredVols = secStorageVm.isMirroredVols();
DataCenterVO dc = _dcDao.findById(secStorageVm.getDataCenterId());
HostPodVO pod = _podDao.findById(secStorageVm.getPodId());
StoragePoolVO sp = _storageMgr.getStoragePoolForVm(secStorageVm.getId());
List<VolumeVO> vols = _volsDao.findCreatedByInstance(routerId);
String[] storageIps = new String[2];
VolumeVO vol = vols.get(0);
storageIps[0] = vol.getHostIp();
if (mirroredVols && (vols.size() == 2)) {
storageIps[1] = vols.get(1).getHostIp();
}
PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(secStorageVm.getName(), null, storageIps, vols, mirroredVols);
HostVO routingHost = null;
HashSet<Host> avoid = new HashSet<Host>();
HostVO fromHost = _hostDao.findById(secStorageVm.getHostId());
if (fromHost.getClusterId() == null) {
s_logger.debug("The host is not in a cluster");
return null;
}
avoid.add(fromHost);
while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing,
dc, pod, sp, _serviceOffering, template, secStorageVm, fromHost, avoid)) != null) {
avoid.add(routingHost);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Trying to migrate router to host " + routingHost.getName());
}
if( !_storageMgr.share(secStorageVm, vols, routingHost, false) ) {
s_logger.warn("Can not share " + vol.getPath() + " to " + secStorageVm.getName());
throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + secStorageVm.getName(), vol.getPoolId());
}
Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
if (answer != null && answer.getResult()) {
return routingHost;
}
_storageMgr.unshare(secStorageVm, vols, routingHost);
}
return null;
}
// @Override
// public boolean migrate(SecondaryStorageVmVO secStorageVm, HostVO host) {
// HostVO fromHost = _hostDao.findById(secStorageVm.getId());
//
// if (! _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.MigrationRequested, secStorageVm.getHostId())) {
// s_logger.debug("State for " + secStorageVm.toString() + " has changed so migration can not take place.");
// return false;
// }
//
// MigrateCommand cmd = new MigrateCommand(secStorageVm.getInstanceName(), host.getPrivateIpAddress(), false);
// Answer answer = _agentMgr.easySend(fromHost.getId(), cmd);
// if (answer == null || !answer.getResult()) {
// return false;
// }
//
// _storageMgr.unshare(secStorageVm, fromHost);
//
// return true;
// }
//
// @Override
// public boolean completeMigration(SecondaryStorageVmVO secStorageVm, HostVO host)
// throws AgentUnavailableException, OperationTimedoutException {
// CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(secStorageVm.getInstanceName());
// CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm);
// if (!answer.getResult()) {
// s_logger.debug("Unable to complete migration for " + secStorageVm.getId());
// _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// State state = answer.getState();
// if (state == State.Stopped) {
// s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId());
// _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// _itMgr.stateTransitTo(secStorageVm, VirtualMachine.Event.OperationSucceeded, host.getId());
// return true;
// }
//
// @Override
// public HostVO prepareForMigration(SecondaryStorageVmVO secStorageVm) throws StorageUnavailableException {
//
// VMTemplateVO template = _templateDao.findById(secStorageVm.getTemplateId());
// long routerId = secStorageVm.getId();
// boolean mirroredVols = secStorageVm.isMirroredVols();
// DataCenterVO dc = _dcDao.findById(secStorageVm.getDataCenterId());
// HostPodVO pod = _podDao.findById(secStorageVm.getPodId());
// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(secStorageVm.getId());
//
// List<VolumeVO> vols = _volsDao.findCreatedByInstance(routerId);
//
// String[] storageIps = new String[2];
// VolumeVO vol = vols.get(0);
// storageIps[0] = vol.getHostIp();
// if (mirroredVols && (vols.size() == 2)) {
// storageIps[1] = vols.get(1).getHostIp();
// }
//
// PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(secStorageVm.getName(), null, storageIps, vols, mirroredVols);
//
// HostVO routingHost = null;
// HashSet<Host> avoid = new HashSet<Host>();
//
// HostVO fromHost = _hostDao.findById(secStorageVm.getHostId());
// if (fromHost.getClusterId() == null) {
// s_logger.debug("The host is not in a cluster");
// return null;
// }
// avoid.add(fromHost);
//
// while ((routingHost = (HostVO) _agentMgr.findHost(Host.Type.Routing,
// dc, pod, sp, _serviceOffering, template, secStorageVm, fromHost, avoid)) != null) {
// avoid.add(routingHost);
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Trying to migrate router to host " + routingHost.getName());
// }
//
// if( !_storageMgr.share(secStorageVm, vols, routingHost, false) ) {
// s_logger.warn("Can not share " + vol.getPath() + " to " + secStorageVm.getName());
// throw new StorageUnavailableException("Can not share " + vol.getPath() + " to " + secStorageVm.getName(), vol.getPoolId());
// }
//
// Answer answer = _agentMgr.easySend(routingHost.getId(), cmd);
// if (answer != null && answer.getResult()) {
// return routingHost;
// }
// _storageMgr.unshare(secStorageVm, vols, routingHost);
// }
//
// return null;
// }
@Override
public void onAgentConnect(Long dcId, StartupCommand cmd){

View File

@ -22,7 +22,6 @@ import java.util.Date;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -41,15 +40,11 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeAnswer;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.SnapshotCommand;
@ -113,7 +108,6 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.DetailsDao;
import com.cloud.host.dao.HostDao;
@ -1177,11 +1171,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
@Override
public UserVmVO get(long id) {
return getVirtualMachine(id);
}
public String getRandomPrivateTemplateName() {
return UUID.randomUUID().toString();
}
@ -1260,82 +1249,82 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return stopped;
}
@Override
public HostVO prepareForMigration(UserVmVO vm) throws StorageUnavailableException {
long vmId = vm.getId();
boolean mirroredVols = vm.isMirroredVols();
DataCenterVO dc = _dcDao.findById(vm.getDataCenterId());
HostPodVO pod = _podDao.findById(vm.getPodId());
ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId());
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
StoragePoolVO sp = _storageMgr.getStoragePoolForVm(vm.getId());
List<VolumeVO> vols = _volsDao.findCreatedByInstance(vmId);
String [] storageIps = new String[2];
VolumeVO vol = vols.get(0);
storageIps[0] = vol.getHostIp();
if (mirroredVols && (vols.size() == 2)) {
storageIps[1] = vols.get(1).getHostIp();
}
PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(vm.getInstanceName(), vm.getVnet(), storageIps, vols, mirroredVols);
HostVO vmHost = null;
HashSet<Host> avoid = new HashSet<Host>();
HostVO fromHost = _hostDao.findById(vm.getHostId());
if (fromHost.getClusterId() == null) {
s_logger.debug("The host is not in a cluster");
return null;
}
avoid.add(fromHost);
while ((vmHost = (HostVO)_agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, template, vm, null, avoid)) != null) {
avoid.add(vmHost);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Trying to migrate router to host " + vmHost.getName());
}
_storageMgr.share(vm, vols, vmHost, false);
Answer answer = _agentMgr.easySend(vmHost.getId(), cmd);
if (answer != null && answer.getResult()) {
return vmHost;
}
_storageMgr.unshare(vm, vols, vmHost);
}
return null;
}
@Override
public boolean migrate(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
HostVO fromHost = _hostDao.findById(vm.getHostId());
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.MigrationRequested, vm.getHostId())) {
s_logger.debug("State for " + vm.toString() + " has changed so migration can not take place.");
return false;
}
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), host.getPrivateIpAddress(), isWindows);
Answer answer = _agentMgr.send(fromHost.getId(), cmd);
if (answer == null) {
return false;
}
List<VolumeVO> vols = _volsDao.findCreatedByInstance(vm.getId());
if (vols.size() == 0) {
return true;
}
_storageMgr.unshare(vm, vols, fromHost);
return true;
}
// @Override
// public HostVO prepareForMigration(UserVmVO vm) throws StorageUnavailableException {
// long vmId = vm.getId();
// boolean mirroredVols = vm.isMirroredVols();
// DataCenterVO dc = _dcDao.findById(vm.getDataCenterId());
// HostPodVO pod = _podDao.findById(vm.getPodId());
// ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId());
// VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
// StoragePoolVO sp = _storageMgr.getStoragePoolForVm(vm.getId());
//
// List<VolumeVO> vols = _volsDao.findCreatedByInstance(vmId);
//
// String [] storageIps = new String[2];
// VolumeVO vol = vols.get(0);
// storageIps[0] = vol.getHostIp();
// if (mirroredVols && (vols.size() == 2)) {
// storageIps[1] = vols.get(1).getHostIp();
// }
//
// PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(vm.getInstanceName(), vm.getVnet(), storageIps, vols, mirroredVols);
//
// HostVO vmHost = null;
// HashSet<Host> avoid = new HashSet<Host>();
//
// HostVO fromHost = _hostDao.findById(vm.getHostId());
// if (fromHost.getClusterId() == null) {
// s_logger.debug("The host is not in a cluster");
// return null;
// }
// avoid.add(fromHost);
//
// while ((vmHost = (HostVO)_agentMgr.findHost(Host.Type.Routing, dc, pod, sp, offering, template, vm, null, avoid)) != null) {
// avoid.add(vmHost);
//
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Trying to migrate router to host " + vmHost.getName());
// }
//
// _storageMgr.share(vm, vols, vmHost, false);
//
// Answer answer = _agentMgr.easySend(vmHost.getId(), cmd);
// if (answer != null && answer.getResult()) {
// return vmHost;
// }
//
// _storageMgr.unshare(vm, vols, vmHost);
//
// }
//
// return null;
// }
//
// @Override
// public boolean migrate(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
// HostVO fromHost = _hostDao.findById(vm.getHostId());
//
// if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.MigrationRequested, vm.getHostId())) {
// s_logger.debug("State for " + vm.toString() + " has changed so migration can not take place.");
// return false;
// }
// boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
// MigrateCommand cmd = new MigrateCommand(vm.getInstanceName(), host.getPrivateIpAddress(), isWindows);
// Answer answer = _agentMgr.send(fromHost.getId(), cmd);
// if (answer == null) {
// return false;
// }
//
// List<VolumeVO> vols = _volsDao.findCreatedByInstance(vm.getId());
// if (vols.size() == 0) {
// return true;
// }
//
// _storageMgr.unshare(vm, vols, fromHost);
//
// return true;
// }
@Override
public boolean expunge(UserVmVO vm, long callerUserId, Account caller) {
@ -1413,39 +1402,39 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
// _storageMgr.destroy(null, destroyedVolumes);
}
@Override @DB
public boolean completeMigration(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName());
CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(host.getId(), cvm);
if (!answer.getResult()) {
s_logger.debug("Unable to complete migration for " + vm.toString());
_itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
State state = answer.getState();
if (state == State.Stopped) {
s_logger.warn("Unable to complete migration as we can not detect it on " + host.toString());
_itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
return false;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Marking port " + answer.getVncPort() + " on " + host.getId());
}
Transaction txn = Transaction.currentTxn();
try {
txn.start();
_itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, host.getId());
txn.commit();
_networkGroupMgr.handleVmStateTransition(vm, State.Running);
return true;
} catch(Exception e) {
s_logger.warn("Exception during completion of migration process " + vm.toString());
return false;
}
}
// @Override @DB
// public boolean completeMigration(UserVmVO vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException {
// CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName());
// CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(host.getId(), cvm);
// if (!answer.getResult()) {
// s_logger.debug("Unable to complete migration for " + vm.toString());
// _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// State state = answer.getState();
// if (state == State.Stopped) {
// s_logger.warn("Unable to complete migration as we can not detect it on " + host.toString());
// _itMgr.stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
// return false;
// }
//
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Marking port " + answer.getVncPort() + " on " + host.getId());
// }
//
// Transaction txn = Transaction.currentTxn();
// try {
// txn.start();
// _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, host.getId());
// txn.commit();
// _networkGroupMgr.handleVmStateTransition(vm, State.Running);
// return true;
// } catch(Exception e) {
// s_logger.warn("Exception during completion of migration process " + vm.toString());
// return false;
// }
// }
@Override
public void deletePrivateTemplateRecord(Long templateId){
@ -2240,8 +2229,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
if (cmd.getSSHKeyPairName() != null && !cmd.getSSHKeyPairName().equals("")) {
Account account = UserContext.current().getCaller();
SSHKeyPair pair = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getSSHKeyPairName());
if (pair == null)
throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found.");
if (pair == null) {
throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found.");
}
sshPublicKey = pair.getPublicKey();
}
@ -2323,8 +2313,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(), template.getId(), hypervisorType,
template.getGuestOSId(), offering.getOfferHA(), domainId, owner.getId(), offering.getId(), userData, hostName);
if (sshPublicKey != null)
vm.setDetail("SSH.PublicKey", sshPublicKey);
if (sshPublicKey != null) {
vm.setDetail("SSH.PublicKey", sshPublicKey);
}
if (_itMgr.allocate(vm, template, offering, rootDiskOffering, dataDiskOfferings, networks, null, plan, cmd.getHypervisor(), owner) == null) {
return null;
@ -2378,8 +2369,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
String sshPublicKey = vm.getDetail("SSH.PublicKey");
if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password") ) {
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
if (encryptedPasswd == null)
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error encrypting password");
if (encryptedPasswd == null) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error encrypting password");
}
vm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(vm);

View File

@ -24,10 +24,8 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.HostVO;
import com.cloud.utils.exception.ExecutionException;
/**
@ -77,14 +75,6 @@ public interface VirtualMachineGuru<T extends VirtualMachine> {
*/
Long convertToId(String vmName);
/**
* Retrieves the vm based on the id given.
*
* @param id id of the vm.
* @return VMInstanceVO
*/
T get(long id);
/**
* Complete the start command. HA calls this when it determines that
* a vm was starting but the state was not complete.
@ -138,12 +128,12 @@ public interface VirtualMachineGuru<T extends VirtualMachine> {
* @param vm vm to migrate.
* @return HostVO if a host is found.
*/
HostVO prepareForMigration(T vm) throws InsufficientCapacityException, StorageUnavailableException;
// HostVO prepareForMigration(T vm) throws InsufficientCapacityException, StorageUnavailableException;
/**
* Migrate the vm.
*/
boolean migrate(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException;
boolean completeMigration(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException;
// /**
// * Migrate the vm.
// */
// boolean migrate(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException;
//
// boolean completeMigration(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException;
}

View File

@ -20,10 +20,12 @@ package com.cloud.vm;
import java.util.List;
import java.util.Map;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@ -89,4 +91,8 @@ public interface VirtualMachineManager extends Manager {
<T extends VMInstanceVO> boolean remove(T vm, User caller, Account account);
<T extends VMInstanceVO> boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
boolean migrate(VirtualMachine.Type type, long vmid, long hostId) throws InsufficientServerCapacityException;
<T extends VMInstanceVO> T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException;
}

View File

@ -34,12 +34,20 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.AgentManager.OnError;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.cluster.ClusterManager;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
@ -59,6 +67,8 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.network.NetworkManager;
@ -71,6 +81,8 @@ import com.cloud.storage.StorageManager;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.Volume.VolumeType;
import com.cloud.storage.dao.GuestOSCategoryDao;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@ -123,6 +135,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
@Inject protected UsageEventDao _usageEventDao;
@Inject protected NicDao _nicsDao;
@Inject protected AccountManager _accountMgr;
@Inject protected HostDao _hostDao;
@Inject protected AlertManager _alertMgr;
@Inject protected GuestOSCategoryDao _guestOsCategoryDao;
@Inject protected GuestOSDao _guestOsDao;
@Inject(adapter=DeploymentPlanner.class)
protected Adapters<DeploymentPlanner> _planners;
@ -349,6 +365,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
//Clean up volumes based on the vm's instance id
_storageMgr.cleanupVolumes(vm.getId());
_vmDao.remove(vm.getId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Expunged " + vm);
}
@ -744,12 +762,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
private void setStateMachine() {
_stateMachine = new StateMachine2<State, VirtualMachine.Event, VMInstanceVO>();
_stateMachine.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating);
_stateMachine.addTransition(State.Creating, VirtualMachine.Event.OperationSucceeded, State.Stopped);
_stateMachine.addTransition(State.Creating, VirtualMachine.Event.OperationFailed, State.Error);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting);
_stateMachine.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
_stateMachine.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped);
@ -764,7 +777,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
_stateMachine.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped);
_stateMachine.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging);
_stateMachine.addTransition(State.Creating, VirtualMachine.Event.MigrationRequested, State.Destroyed);
_stateMachine.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating);
_stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running);
_stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped);
@ -777,8 +789,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnDest, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped);
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running);
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running);
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped);
@ -786,6 +798,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging);
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
_stateMachine.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
_stateMachine.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
_stateMachine.registerListeners(_stateListner);
}
@ -850,6 +864,156 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
return true;
}
@Override
public <T extends VMInstanceVO> T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException {
s_logger.info("Migrating " + vm + " to " + dest);
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);
return null;
}
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
vm = vmGuru.findById(vm.getId());
if (vm == null || vm.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find the vm " + vm);
}
return null;
}
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);
HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType());
VirtualMachineTO to = hvGuru.implement(profile);
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
PrepareForMigrationAnswer pfma;
try {
pfma = (PrepareForMigrationAnswer)_agentMgr.send(dstHostId, pfmc);
} catch (OperationTimedoutException e1) {
throw new AgentUnavailableException("Operation timed out", dstHostId);
}
if (!pfma.getResult()) {
throw new AgentUnavailableException(pfma.getDetails(), dstHostId);
}
boolean migrated = false;
try {
vm.setLastHostId(srcHostId);
if (vm == null || vm.getRemoved() != null || vm.getHostId() == null || vm.getHostId() != srcHostId || !stateTransitTo(vm, Event.MigrationRequested, dstHostId)) {
s_logger.info("Migration cancelled because state has changed: " + vm);
return null;
}
boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows);
MigrateAnswer ma = (MigrateAnswer)_agentMgr.send(vm.getHostId(), mc);
if (!ma.getResult()) {
return null;
}
CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName());
CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(dstHostId, cvm);
if (!answer.getResult()) {
s_logger.debug("Unable to complete migration for " + vm.toString());
stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
return null;
}
State state = answer.getState();
if (state == State.Stopped) {
s_logger.warn("Unable to complete migration as we can not detect it on " + dest.getHost());
stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
return null;
}
// FIXME: _networkGroupMgr.handleVmStateTransition(vm, State.Running);
stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, dstHostId);
migrated = true;
return vm;
} catch (final OperationTimedoutException e) {
s_logger.debug("operation timed out");
if (e.isActive()) {
// FIXME: scheduleRestart(vm, true);
}
throw new AgentUnavailableException("Operation timed out: ", dstHostId);
} finally {
if (!migrated) {
s_logger.info("Migration was unsuccessful. Cleaning up: " + vm.toString());
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs.");
stateTransitTo(vm, Event.MigrationFailedOnSource, srcHostId);
Command cleanup = vmGuru.cleanup(vm, null);
_agentMgr.easySend(dstHostId, cleanup);
}
}
}
@Override
public boolean migrate(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException {
VirtualMachineGuru<? extends VMInstanceVO> vmGuru = _vmGurus.get(vmType);
VMInstanceVO vm = vmGuru.findById(vmId);
if (vm == null) {
s_logger.debug("Unable to find a VM for " + vmId);
return true;
}
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
Long hostId = vm.getHostId();
if (hostId == null) {
s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm);
}
Host host = _hostDao.findById(hostId);
DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null);
ExcludeList excludes = new ExcludeList();
excludes.addHost(hostId);
DeployDestination dest = null;
while (true) {
for (DeploymentPlanner planner : _planners) {
dest = planner.plan(profile, plan, excludes);
if (dest != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Planner " + planner + " found " + dest + " for migrating to.");
}
break;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Planner " + planner + " was unable to find anything.");
}
}
if (dest == null) {
throw new InsufficientServerCapacityException("Unable to find a server to migrate to.", host.getClusterId());
}
excludes.addHost(dest.getHost().getId());
try {
vm = migrate(vm, srcHostId, dest);
} catch (ResourceUnavailableException e) {
s_logger.debug("Unable to migrate to unavailable " + dest);
}
if (vm != null) {
return true;
}
}
}
protected class CleanupTask implements Runnable {
@Override