mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
stop vm is now formalized
This commit is contained in:
parent
d5d1808488
commit
1fe446002b
@ -23,7 +23,6 @@ import com.cloud.agent.api.to.VolumeTO;
|
|||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.template.VirtualMachineTemplate;
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
|
|
||||||
|
|
||||||
@ -66,11 +65,6 @@ public interface VirtualMachineProfile<T extends VirtualMachine> {
|
|||||||
*/
|
*/
|
||||||
HypervisorType getHypervisorType();
|
HypervisorType getHypervisorType();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return os to be run on the virtual machine.
|
|
||||||
*/
|
|
||||||
String getGuestOs();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return template the virtual machine is based on.
|
* @return template the virtual machine is based on.
|
||||||
*/
|
*/
|
||||||
@ -109,11 +103,6 @@ public interface VirtualMachineProfile<T extends VirtualMachine> {
|
|||||||
|
|
||||||
void addDisk(VolumeTO disk);
|
void addDisk(VolumeTO disk);
|
||||||
|
|
||||||
void setBootloader(BootloaderType type);
|
|
||||||
BootloaderType getBootloader();
|
|
||||||
|
|
||||||
String getOs();
|
|
||||||
|
|
||||||
VirtualMachine.Type getType();
|
VirtualMachine.Type getType();
|
||||||
|
|
||||||
void setParameter(String name, Object value);
|
void setParameter(String name, Object value);
|
||||||
|
|||||||
@ -134,6 +134,9 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||||||
@Column(name="service_offering_id")
|
@Column(name="service_offering_id")
|
||||||
long serviceOfferingId;
|
long serviceOfferingId;
|
||||||
|
|
||||||
|
@Column(name="reservation_id")
|
||||||
|
String reservationId;
|
||||||
|
|
||||||
public VMInstanceVO(long id,
|
public VMInstanceVO(long id,
|
||||||
long serviceOfferingId,
|
long serviceOfferingId,
|
||||||
String name,
|
String name,
|
||||||
@ -412,8 +415,20 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||||||
this.mirroredVols = mirroredVols;
|
this.mirroredVols = mirroredVols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setReservationId(String reservationId) {
|
||||||
|
this.reservationId = reservationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReservationId() {
|
||||||
|
return this.reservationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
transient String toString;
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder("[").append(type.toString()).append("|").append(instanceName).append("]").toString();
|
if (toString == null) {
|
||||||
|
toString = new StringBuilder("VM[").append(type.toString()).append("|").append(instanceName).append("]").toString();
|
||||||
|
}
|
||||||
|
return toString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2443,7 +2443,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processDeploymentResult(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
|
public boolean finalizeStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
|
||||||
CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
|
CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
|
||||||
if (!answer.getResult()) {
|
if (!answer.getResult()) {
|
||||||
s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
|
s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
|
||||||
@ -2521,4 +2521,8 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
}
|
}
|
||||||
return findById(VirtualMachineName.getConsoleProxyId(name));
|
return findById(VirtualMachineName.getConsoleProxyId(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, String reservationId) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||||
VirtualMachine vm = vmProfile.getVirtualMachine();
|
VirtualMachine vm = vmProfile.getVirtualMachine();
|
||||||
|
|
||||||
VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), offering.getSpeed(), offering.getRamSize() * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, vmProfile.getOs());
|
VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), offering.getSpeed(), offering.getRamSize() * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, null);
|
||||||
to.setBootArgs(vmProfile.getBootArgs());
|
to.setBootArgs(vmProfile.getBootArgs());
|
||||||
|
|
||||||
List<NicProfile> nicProfiles = vmProfile.getNics();
|
List<NicProfile> nicProfiles = vmProfile.getNics();
|
||||||
|
|||||||
@ -21,14 +21,18 @@ import javax.ejb.Local;
|
|||||||
|
|
||||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
|
import com.cloud.storage.GuestOSVO;
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
import com.cloud.template.VirtualMachineTemplate;
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||||
|
import com.cloud.utils.component.Inject;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.cloud.vm.VirtualMachineProfile;
|
import com.cloud.vm.VirtualMachineProfile;
|
||||||
|
|
||||||
@Local(value=HypervisorGuru.class)
|
@Local(value=HypervisorGuru.class)
|
||||||
public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru {
|
public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru {
|
||||||
|
@Inject GuestOSDao _guestOsDao;
|
||||||
|
|
||||||
protected XenServerGuru() {
|
protected XenServerGuru() {
|
||||||
super();
|
super();
|
||||||
@ -51,6 +55,10 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru
|
|||||||
VirtualMachineTO to = toVirtualMachineTO(vm);
|
VirtualMachineTO to = toVirtualMachineTO(vm);
|
||||||
to.setBootloader(bt);
|
to.setBootloader(bt);
|
||||||
|
|
||||||
|
// Determine the VM's OS description
|
||||||
|
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
|
||||||
|
to.setOs(guestOS.getDisplayName());
|
||||||
|
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2132,7 +2132,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, VirtualMach
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processDeploymentResult(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest, ReservationContext context) {
|
public boolean finalizeStart(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest, ReservationContext context) {
|
||||||
CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
|
CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
|
||||||
if (!answer.getResult()) {
|
if (!answer.getResult()) {
|
||||||
s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
|
s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
|
||||||
@ -2141,6 +2141,10 @@ public class DomainRouterManagerImpl implements DomainRouterManager, VirtualMach
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finalizeStop(VirtualMachineProfile<DomainRouterVO> profile, long hostId, String reservationId) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RemoteAccessVpnVO startRemoteAccessVpn(RemoteAccessVpnVO vpnVO) throws ResourceUnavailableException {
|
public RemoteAccessVpnVO startRemoteAccessVpn(RemoteAccessVpnVO vpnVO) throws ResourceUnavailableException {
|
||||||
DomainRouterVO router = getRouter(vpnVO.getAccountId(), vpnVO.getZoneId());
|
DomainRouterVO router = getRouter(vpnVO.getAccountId(), vpnVO.getZoneId());
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import javax.ejb.Local;
|
|||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
|
|
||||||
@Local(value=ItWorkDao.class)
|
@Local(value=ItWorkDao.class)
|
||||||
public class ItWorkDaoImpl extends GenericDaoBase<ItWorkVO, Long> implements ItWorkDao {
|
public class ItWorkDaoImpl extends GenericDaoBase<ItWorkVO, String> implements ItWorkDao {
|
||||||
protected ItWorkDaoImpl() {
|
protected ItWorkDaoImpl() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,8 @@ import com.cloud.utils.db.GenericDao;
|
|||||||
@Table(name="op_it_work")
|
@Table(name="op_it_work")
|
||||||
public class ItWorkVO {
|
public class ItWorkVO {
|
||||||
enum Type {
|
enum Type {
|
||||||
Start;
|
Start,
|
||||||
|
Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
@ -90,6 +91,10 @@ public class ItWorkVO {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
public String getThreadName() {
|
public String getThreadName() {
|
||||||
return threadName;
|
return threadName;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,8 @@ import com.cloud.agent.AgentManager;
|
|||||||
import com.cloud.agent.AgentManager.OnError;
|
import com.cloud.agent.AgentManager.OnError;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Start2Command;
|
import com.cloud.agent.api.Start2Command;
|
||||||
|
import com.cloud.agent.api.StopAnswer;
|
||||||
|
import com.cloud.agent.api.StopCommand;
|
||||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||||
import com.cloud.agent.manager.Commands;
|
import com.cloud.agent.manager.Commands;
|
||||||
import com.cloud.cluster.ClusterManager;
|
import com.cloud.cluster.ClusterManager;
|
||||||
@ -45,6 +47,8 @@ import com.cloud.deploy.DeploymentPlan;
|
|||||||
import com.cloud.deploy.DeploymentPlanner;
|
import com.cloud.deploy.DeploymentPlanner;
|
||||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||||
import com.cloud.domain.dao.DomainDao;
|
import com.cloud.domain.dao.DomainDao;
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.event.EventVO;
|
||||||
import com.cloud.exception.AgentUnavailableException;
|
import com.cloud.exception.AgentUnavailableException;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.exception.InsufficientCapacityException;
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
@ -59,12 +63,10 @@ import com.cloud.network.NetworkManager;
|
|||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.GuestOSVO;
|
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.StorageManager;
|
import com.cloud.storage.StorageManager;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.Volume.VolumeType;
|
import com.cloud.storage.Volume.VolumeType;
|
||||||
import com.cloud.storage.dao.GuestOSDao;
|
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.User;
|
import com.cloud.user.User;
|
||||||
@ -79,6 +81,7 @@ import com.cloud.utils.component.Inject;
|
|||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.vm.ItWorkVO.Type;
|
||||||
import com.cloud.vm.VirtualMachine.Event;
|
import com.cloud.vm.VirtualMachine.Event;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
|
||||||
@ -92,7 +95,6 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
@Inject private AgentManager _agentMgr;
|
@Inject private AgentManager _agentMgr;
|
||||||
@Inject private VMInstanceDao _vmDao;
|
@Inject private VMInstanceDao _vmDao;
|
||||||
@Inject private ServiceOfferingDao _offeringDao;
|
@Inject private ServiceOfferingDao _offeringDao;
|
||||||
@Inject private GuestOSDao _guestOsDao;
|
|
||||||
@Inject private VMTemplateDao _templateDao;
|
@Inject private VMTemplateDao _templateDao;
|
||||||
@Inject private UserDao _userDao;
|
@Inject private UserDao _userDao;
|
||||||
@Inject private AccountDao _accountDao;
|
@Inject private AccountDao _accountDao;
|
||||||
@ -130,9 +132,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
s_logger.debug("Allocating entries for VM: " + vm);
|
s_logger.debug("Allocating entries for VM: " + vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the VM's OS description
|
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, template, serviceOffering, owner, params);
|
||||||
GuestOSVO guestOS = _guestOsDao.findById(vm.getGuestOSId());
|
|
||||||
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, guestOS.getDisplayName(), template, serviceOffering, owner, params);
|
|
||||||
|
|
||||||
vm.setDataCenterId(plan.getDataCenterId());
|
vm.setDataCenterId(plan.getDataCenterId());
|
||||||
if (plan.getPodId() != null) {
|
if (plan.getPodId() != null) {
|
||||||
@ -286,8 +286,8 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
VirtualMachineGuru<T> vmGuru = (VirtualMachineGuru<T>)_vmGurus.get(vm.getType());
|
VirtualMachineGuru<T> vmGuru = (VirtualMachineGuru<T>)_vmGurus.get(vm.getType());
|
||||||
|
|
||||||
|
|
||||||
// Determine the VM's OS description
|
vm.setReservationId(work.getId());
|
||||||
GuestOSVO guestOS = _guestOsDao.findById(vm.getGuestOSId());
|
|
||||||
if (!_vmDao.updateIf(vm, Event.StartRequested, null)) {
|
if (!_vmDao.updateIf(vm, Event.StartRequested, null)) {
|
||||||
throw new ConcurrentOperationException("Unable to start vm " + vm + " due to concurrent operations");
|
throw new ConcurrentOperationException("Unable to start vm " + vm + " due to concurrent operations");
|
||||||
}
|
}
|
||||||
@ -295,7 +295,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
ExcludeList avoids = new ExcludeList();
|
ExcludeList avoids = new ExcludeList();
|
||||||
int retry = _retry;
|
int retry = _retry;
|
||||||
while (retry-- != 0) { // It's != so that it can match -1.
|
while (retry-- != 0) { // It's != so that it can match -1.
|
||||||
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, guestOS.getDisplayName(), template, offering, null, params);
|
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(vm, template, offering, null, params);
|
||||||
DeployDestination dest = null;
|
DeployDestination dest = null;
|
||||||
for (DeploymentPlanner planner : _planners) {
|
for (DeploymentPlanner planner : _planners) {
|
||||||
dest = planner.plan(vmProfile, plan, avoids);
|
dest = planner.plan(vmProfile, plan, avoids);
|
||||||
@ -334,7 +334,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
vmGuru.finalizeDeployment(cmds, vmProfile, dest, context);
|
vmGuru.finalizeDeployment(cmds, vmProfile, dest, context);
|
||||||
try {
|
try {
|
||||||
Answer[] answers = _agentMgr.send(dest.getHost().getId(), cmds);
|
Answer[] answers = _agentMgr.send(dest.getHost().getId(), cmds);
|
||||||
if (answers[0].getResult() && vmGuru.processDeploymentResult(cmds, vmProfile, dest, context)) {
|
if (answers[0].getResult() && vmGuru.finalizeStart(cmds, vmProfile, dest, context)) {
|
||||||
if (!_vmDao.updateIf(vm, Event.OperationSucceeded, dest.getHost().getId())) {
|
if (!_vmDao.updateIf(vm, Event.OperationSucceeded, dest.getHost().getId())) {
|
||||||
throw new CloudRuntimeException("Unable to transition to a new state.");
|
throw new CloudRuntimeException("Unable to transition to a new state.");
|
||||||
}
|
}
|
||||||
@ -358,9 +358,93 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends VMInstanceVO> T stop(T vm, User user, Account account) throws AgentUnavailableException {
|
public <T extends VMInstanceVO> boolean stop(T vm, User user, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
|
||||||
// TODO Auto-generated method stub
|
State state = vm.getState();
|
||||||
return null;
|
if (state == State.Stopped) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("VM is already stopped: " + vm);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == State.Creating || state == State.Destroyed || state == State.Expunging) {
|
||||||
|
s_logger.warn("Stopped called on " + vm.toString() + " but the state is " + state.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_vmDao.updateIf(vm, Event.StopRequested, vm.getHostId())) {
|
||||||
|
throw new ConcurrentOperationException("VM is being operated on by someone else.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm.getHostId() == null) {
|
||||||
|
s_logger.debug("Host id is null so we can't stop it. How did we get into here?");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String reservationId = vm.getReservationId();
|
||||||
|
|
||||||
|
EventVO event = new EventVO();
|
||||||
|
event.setUserId(user.getId());
|
||||||
|
event.setAccountId(vm.getAccountId());
|
||||||
|
event.setType(EventTypes.EVENT_VM_STOP);
|
||||||
|
event.setStartId(1); // FIXME:
|
||||||
|
event.setParameters("id="+vm.getId() + "\n" + "vmName=" + vm.getHostName() + "\nsoId=" + vm.getServiceOfferingId() + "\ntId=" + vm.getTemplateId() + "\ndcId=" + vm.getDataCenterId());
|
||||||
|
|
||||||
|
StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null);
|
||||||
|
|
||||||
|
boolean stopped = false;
|
||||||
|
try {
|
||||||
|
StopAnswer answer = (StopAnswer)_agentMgr.send(vm.getHostId(), stop);
|
||||||
|
stopped = answer.getResult();
|
||||||
|
if (!stopped) {
|
||||||
|
throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (!stopped) {
|
||||||
|
_vmDao.updateIf(vm, Event.OperationFailed, vm.getHostId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug(vm + " is stopped on the host. Proceeding to release resource held.");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean cleanup = false;
|
||||||
|
|
||||||
|
VirtualMachineProfile<T> profile = new VirtualMachineProfileImpl<T>(vm);
|
||||||
|
try {
|
||||||
|
_networkMgr.release(profile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.warn("Unable to release some network resources.", e);
|
||||||
|
cleanup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_storageMgr.release(profile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.warn("Unable to release storage resources.", e);
|
||||||
|
cleanup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
VirtualMachineGuru<T> guru = (VirtualMachineGuru<T>)_vmGurus.get(vm.getType());
|
||||||
|
try {
|
||||||
|
guru.finalizeStop(profile, vm.getHostId(), vm.getReservationId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.warn("Guru " + guru.getClass() + " has trouble processing stop ");
|
||||||
|
cleanup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.setReservationId(null);
|
||||||
|
vm.setHostId(null);
|
||||||
|
_vmDao.updateIf(vm, Event.OperationSucceeded, null);
|
||||||
|
|
||||||
|
if (cleanup) {
|
||||||
|
ItWorkVO work = new ItWorkVO(reservationId, _nodeId, Type.Cleanup);
|
||||||
|
_workDao.persist(work);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -77,6 +77,7 @@ import com.cloud.api.commands.RecoverVMCmd;
|
|||||||
import com.cloud.api.commands.ResetVMPasswordCmd;
|
import com.cloud.api.commands.ResetVMPasswordCmd;
|
||||||
import com.cloud.api.commands.StartVMCmd;
|
import com.cloud.api.commands.StartVMCmd;
|
||||||
import com.cloud.api.commands.StopVMCmd;
|
import com.cloud.api.commands.StopVMCmd;
|
||||||
|
import com.cloud.api.commands.StopVm2Cmd;
|
||||||
import com.cloud.api.commands.UpdateVMCmd;
|
import com.cloud.api.commands.UpdateVMCmd;
|
||||||
import com.cloud.api.commands.UpgradeVMCmd;
|
import com.cloud.api.commands.UpgradeVMCmd;
|
||||||
import com.cloud.async.AsyncJobExecutor;
|
import com.cloud.async.AsyncJobExecutor;
|
||||||
@ -3745,7 +3746,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processDeploymentResult(Commands cmds, VirtualMachineProfile<UserVmVO> profile, DeployDestination dest, ReservationContext context) {
|
public boolean finalizeStart(Commands cmds, VirtualMachineProfile<UserVmVO> profile, DeployDestination dest, ReservationContext context) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3766,4 +3767,41 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM
|
|||||||
}
|
}
|
||||||
return findById(VirtualMachineName.getVmId(name));
|
return findById(VirtualMachineName.getVmId(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserVm stopVirtualMachine(StopVm2Cmd cmd) throws ConcurrentOperationException {
|
||||||
|
//Input validation
|
||||||
|
Account caller = UserContext.current().getAccount();
|
||||||
|
Long userId = UserContext.current().getUserId();
|
||||||
|
long id = cmd.getId();
|
||||||
|
|
||||||
|
//if account is removed, return error
|
||||||
|
if (caller != null && caller.getRemoved() != null)
|
||||||
|
throw new PermissionDeniedException("The account " + caller.getId()+" is removed");
|
||||||
|
|
||||||
|
UserVmVO vmInstance = _vmDao.findById(id);
|
||||||
|
if (vmInstance == null) {
|
||||||
|
throw new InvalidParameterValueException("unable to find a virtual machine with id " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
long eventId = EventUtils.saveScheduledEvent(userId, vmInstance.getAccountId(), EventTypes.EVENT_VM_STOP, "stopping Vm with Id: "+id);
|
||||||
|
|
||||||
|
userId = accountAndUserValidation(id, caller, userId, vmInstance);
|
||||||
|
UserVO user = _userDao.findById(userId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
_itMgr.stop(vmInstance, user, caller);
|
||||||
|
} catch (AgentUnavailableException e) {
|
||||||
|
throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vmInstance, e);
|
||||||
|
} catch (OperationTimedoutException e) {
|
||||||
|
throw new CloudRuntimeException("Waiting too long for agent to stop the virtual machine " + vmInstance, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _vmDao.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finalizeStop(VirtualMachineProfile<UserVmVO> profile, long hostId, String reservationId) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import com.cloud.api.commands.RecoverVMCmd;
|
|||||||
import com.cloud.api.commands.ResetVMPasswordCmd;
|
import com.cloud.api.commands.ResetVMPasswordCmd;
|
||||||
import com.cloud.api.commands.StartVMCmd;
|
import com.cloud.api.commands.StartVMCmd;
|
||||||
import com.cloud.api.commands.StopVMCmd;
|
import com.cloud.api.commands.StopVMCmd;
|
||||||
|
import com.cloud.api.commands.StopVm2Cmd;
|
||||||
import com.cloud.api.commands.UpdateVMCmd;
|
import com.cloud.api.commands.UpdateVMCmd;
|
||||||
import com.cloud.api.commands.UpgradeVMCmd;
|
import com.cloud.api.commands.UpgradeVMCmd;
|
||||||
import com.cloud.async.executor.OperationResponse;
|
import com.cloud.async.executor.OperationResponse;
|
||||||
@ -145,4 +146,6 @@ public interface UserVmService extends Manager {
|
|||||||
* @throws InvalidParameterValueException
|
* @throws InvalidParameterValueException
|
||||||
*/
|
*/
|
||||||
UserVm upgradeVirtualMachine(UpgradeVMCmd cmd);
|
UserVm upgradeVirtualMachine(UpgradeVMCmd cmd);
|
||||||
|
|
||||||
|
UserVm stopVirtualMachine(StopVm2Cmd cmd) throws ConcurrentOperationException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,6 @@ public interface VirtualMachineGuru<T extends VirtualMachine> {
|
|||||||
*/
|
*/
|
||||||
boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<T> profile, DeployDestination dest, ReservationContext context);
|
boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<T> profile, DeployDestination dest, ReservationContext context);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the deployment results.
|
* Check the deployment results.
|
||||||
* @param cmds commands and answers that were sent.
|
* @param cmds commands and answers that were sent.
|
||||||
@ -55,5 +54,7 @@ public interface VirtualMachineGuru<T extends VirtualMachine> {
|
|||||||
* @param dest destination it was sent to.
|
* @param dest destination it was sent to.
|
||||||
* @return true if deployment was fine; false if it didn't go well.
|
* @return true if deployment was fine; false if it didn't go well.
|
||||||
*/
|
*/
|
||||||
boolean processDeploymentResult(Commands cmds, VirtualMachineProfile<T> profile, DeployDestination dest, ReservationContext context);
|
boolean finalizeStart(Commands cmds, VirtualMachineProfile<T> profile, DeployDestination dest, ReservationContext context);
|
||||||
|
|
||||||
|
void finalizeStop(VirtualMachineProfile<T> profile, long hostId, String reservationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,13 +47,12 @@ public class VirtualMachineProfileImpl<T extends VMInstanceVO> implements Virtua
|
|||||||
List<NicProfile> _nics = new ArrayList<NicProfile>();
|
List<NicProfile> _nics = new ArrayList<NicProfile>();
|
||||||
List<VolumeTO> _disks = new ArrayList<VolumeTO>();
|
List<VolumeTO> _disks = new ArrayList<VolumeTO>();
|
||||||
StringBuilder _bootArgs = new StringBuilder();
|
StringBuilder _bootArgs = new StringBuilder();
|
||||||
String _guestOs;
|
|
||||||
Account _owner;
|
Account _owner;
|
||||||
BootloaderType _bootloader;
|
BootloaderType _bootloader;
|
||||||
|
|
||||||
VirtualMachine.Type _type;
|
VirtualMachine.Type _type;
|
||||||
|
|
||||||
public VirtualMachineProfileImpl(T vm, String guestOs, VMTemplateVO template, ServiceOfferingVO offering, Account owner, Map<String, Object> params) {
|
public VirtualMachineProfileImpl(T vm, VMTemplateVO template, ServiceOfferingVO offering, Account owner, Map<String, Object> params) {
|
||||||
_vm = vm;
|
_vm = vm;
|
||||||
_template = template;
|
_template = template;
|
||||||
_offering = offering;
|
_offering = offering;
|
||||||
@ -62,29 +61,17 @@ public class VirtualMachineProfileImpl<T extends VMInstanceVO> implements Virtua
|
|||||||
if (_params == null) {
|
if (_params == null) {
|
||||||
_params = new HashMap<String, Object>();
|
_params = new HashMap<String, Object>();
|
||||||
}
|
}
|
||||||
_guestOs = guestOs;
|
|
||||||
_type = vm.getType();
|
_type = vm.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VirtualMachineProfileImpl(T vm) {
|
||||||
|
this(vm, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public VirtualMachineProfileImpl(VirtualMachine.Type type) {
|
public VirtualMachineProfileImpl(VirtualMachine.Type type) {
|
||||||
_type = type;
|
_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getOs() {
|
|
||||||
return _guestOs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBootloader(BootloaderType bootloader) {
|
|
||||||
_bootloader = bootloader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BootloaderType getBootloader() {
|
|
||||||
return _bootloader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return _vm.toString();
|
return _vm.toString();
|
||||||
@ -108,11 +95,6 @@ public class VirtualMachineProfileImpl<T extends VMInstanceVO> implements Virtua
|
|||||||
_params.put(name, value);
|
_params.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getGuestOs() {
|
|
||||||
return _guestOs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VirtualMachineTemplate getTemplate() {
|
public VirtualMachineTemplate getTemplate() {
|
||||||
if (_template == null) {
|
if (_template == null) {
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import com.cloud.deploy.DeploymentPlan;
|
|||||||
import com.cloud.exception.AgentUnavailableException;
|
import com.cloud.exception.AgentUnavailableException;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.exception.InsufficientCapacityException;
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
|
import com.cloud.exception.OperationTimedoutException;
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
import com.cloud.exception.StorageUnavailableException;
|
import com.cloud.exception.StorageUnavailableException;
|
||||||
import com.cloud.network.NetworkConfigurationVO;
|
import com.cloud.network.NetworkConfigurationVO;
|
||||||
@ -68,7 +69,7 @@ public interface VmManager extends Manager {
|
|||||||
|
|
||||||
<T extends VMInstanceVO> T start(T vm, Map<String, Object> params, User caller, Account account) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException;
|
<T extends VMInstanceVO> T start(T vm, Map<String, Object> params, User caller, Account account) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException;
|
||||||
|
|
||||||
<T extends VMInstanceVO> T stop(T vm, User caller, Account account) throws AgentUnavailableException, ConcurrentOperationException;
|
<T extends VMInstanceVO> boolean stop(T vm, User caller, Account account) throws AgentUnavailableException, ConcurrentOperationException, OperationTimedoutException;
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
|||||||
@ -616,6 +616,7 @@ CREATE TABLE `cloud`.`vm_instance` (
|
|||||||
`account_id` bigint unsigned NOT NULL COMMENT 'user id of owner',
|
`account_id` bigint unsigned NOT NULL COMMENT 'user id of owner',
|
||||||
`domain_id` bigint unsigned NOT NULL,
|
`domain_id` bigint unsigned NOT NULL,
|
||||||
`service_offering_id` bigint unsigned NOT NULL COMMENT 'service offering id',
|
`service_offering_id` bigint unsigned NOT NULL COMMENT 'service offering id',
|
||||||
|
`reservation_id` char(40) COMMENT 'reservation id',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user