Updated Branches: refs/heads/pluggable_vm_snapshot d73f75a2d -> 5731d48e6
fix compile Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c231af67 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c231af67 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c231af67 Branch: refs/heads/pluggable_vm_snapshot Commit: c231af678f8d136f092da7cf7be2766ce5c02e60 Parents: d73f75a Author: Edison Su <[email protected]> Authored: Mon Oct 14 14:44:43 2013 -0700 Committer: Edison Su <[email protected]> Committed: Mon Oct 14 14:44:43 2013 -0700 ---------------------------------------------------------------------- .../agent/api/CreateVMSnapshotCommand.java | 4 +- .../agent/api/DeleteVMSnapshotCommand.java | 3 +- .../cloud/agent/api/VMSnapshotBaseCommand.java | 10 +- .../vmsnapshot/DefaultVMSnapshotStrategy.java | 149 +++++++++---------- .../storage/vmsnapshot/VMSnapshotHelper.java | 11 ++ .../vmsnapshot/VMSnapshotHelperImpl.java | 108 ++++++++++++++ .../vm/snapshot/VMSnapshotManagerImpl.java | 34 ----- 7 files changed, 203 insertions(+), 116 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java index 478987d..bfbc21d 100644 --- a/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java +++ b/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java @@ -18,12 +18,14 @@ package com.cloud.agent.api; import java.util.List; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.vm.VirtualMachine; +import org.apache.cloudstack.storage.to.VolumeObjectTO; public class CreateVMSnapshotCommand extends VMSnapshotBaseCommand { - public CreateVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) { + public CreateVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) { super(vmName, snapshot, volumeTOs, guestOSType); this.vmState = vmState; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java b/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java index c213448..1c64a2b 100644 --- a/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java +++ b/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java @@ -19,10 +19,11 @@ package com.cloud.agent.api; import java.util.List; import com.cloud.agent.api.to.VolumeTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; public class DeleteVMSnapshotCommand extends VMSnapshotBaseCommand { - public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) { + public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType) { super( vmName, snapshot, volumeTOs, guestOSType); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java index 2120f2f..b2c5241 100644 --- a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java +++ b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java @@ -19,27 +19,29 @@ package com.cloud.agent.api; import java.util.List; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.VolumeTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; public class VMSnapshotBaseCommand extends Command{ - protected List<VolumeTO> volumeTOs; + protected List<VolumeObjectTO> volumeTOs; protected VMSnapshotTO target; protected String vmName; protected String guestOSType; - public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) { + public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType) { this.vmName = vmName; this.target = snapshot; this.volumeTOs = volumeTOs; this.guestOSType = guestOSType; } - public List<VolumeTO> getVolumeTOs() { + public List<VolumeObjectTO> getVolumeTOs() { return volumeTOs; } - public void setVolumeTOs(List<VolumeTO> volumeTOs) { + public void setVolumeTOs(List<VolumeObjectTO> volumeTOs) { this.volumeTOs = volumeTOs; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java ---------------------------------------------------------------------- diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java index 054f28c..476baf9 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.vmsnapshot; +import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CreateVMSnapshotAnswer; import com.cloud.agent.api.CreateVMSnapshotCommand; @@ -26,6 +27,7 @@ import com.cloud.agent.api.DeleteVMSnapshotCommand; import com.cloud.agent.api.RevertToVMSnapshotAnswer; import com.cloud.agent.api.RevertToVMSnapshotCommand; import com.cloud.agent.api.VMSnapshotTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; @@ -36,73 +38,102 @@ import com.cloud.host.HostVO; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.GuestOSDao; import com.cloud.uservm.UserVm; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotVO; +import com.cloud.vm.snapshot.dao.VMSnapshotDao; import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; import javax.inject.Inject; +import javax.naming.ConfigurationException; import java.util.List; +import java.util.Map; -public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { +public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshotStrategy { + private static final Logger s_logger = Logger.getLogger(DefaultVMSnapshotStrategy.class); @Inject VMSnapshotHelper vmSnapshotHelper; + @Inject + GuestOSDao guestOSDao; + @Inject + UserVmDao userVmDao; + @Inject + VMSnapshotDao vmSnapshotDao; + int _wait; + @Inject + ConfigurationDao configurationDao; + @Inject + AgentManager agentMgr; @Override + public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { + String value = configurationDao.getValue("vmsnapshot.create.wait"); + _wait = NumbersUtil.parseInt(value, 1800); + return true; + } + public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) { - Long hostId = pickRunningHost(vmId); + Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId()); + UserVm userVm = userVmDao.findById(vmSnapshot.getVmId()); + VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot; try { - vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.CreateRequested); + vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.CreateRequested); } catch (NoTransitionException e) { throw new CloudRuntimeException(e.getMessage()); } CreateVMSnapshotAnswer answer = null; try { - GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId()); + GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId()); // prepare snapshotVolumeTos - List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId()); + List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId()); // prepare target snapshotTO and its parent snapshot (current snapshot) VMSnapshotTO current = null; - VMSnapshotVO currentSnapshot = _vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId()); + VMSnapshotVO currentSnapshot = vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId()); if (currentSnapshot != null) - current = getSnapshotWithParents(currentSnapshot); + current = vmSnapshotHelper.getSnapshotWithParents(currentSnapshot); VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(), null, vmSnapshot.getDescription(), false, current); if (current == null) - vmSnapshot.setParent(null); + vmSnapshotVO.setParent(null); else - vmSnapshot.setParent(current.getId()); + vmSnapshotVO.setParent(current.getId()); CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target ,volumeTOs, guestOS.getDisplayName(),userVm.getState()); ccmd.setWait(_wait); - answer = (CreateVMSnapshotAnswer) sendToPool(hostId, ccmd); + answer = (CreateVMSnapshotAnswer)agentMgr.send(hostId, ccmd); if (answer != null && answer.getResult()) { - processAnswer(vmSnapshot, userVm, answer, hostId); + processAnswer(vmSnapshotVO, userVm, answer, hostId); s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName()); }else{ - String errMsg = "Creating VM snapshot: " + vmSnapshot.getName() + " failed"; if(answer != null && answer.getDetails() != null) errMsg = errMsg + " due to " + answer.getDetails(); s_logger.error(errMsg); - vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed); + vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed); throw new CloudRuntimeException(errMsg); } return vmSnapshot; } catch (Exception e) { if(e instanceof AgentUnavailableException){ try { - vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed); + vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed); } catch (NoTransitionException e1) { s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage()); } @@ -113,7 +144,7 @@ public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { } finally{ if(vmSnapshot.getState() == VMSnapshot.State.Allocated){ s_logger.warn("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName()); - _vmSnapshotDao.remove(vmSnapshot.getId()); + vmSnapshotDao.remove(vmSnapshot.getId()); } if(vmSnapshot.getState() == VMSnapshot.State.Ready && answer != null){ for (VolumeTO volumeTo : answer.getVolumeTOs()){ @@ -125,27 +156,28 @@ public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { @Override public boolean deleteVMSnapshot(VMSnapshot vmSnapshot) { - UserVmVO userVm = _userVMDao.findById(vmSnapshot.getVmId()); + UserVmVO userVm = userVmDao.findById(vmSnapshot.getVmId()); + VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot; DeleteVMSnapshotAnswer answer = null; try { - vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested); - Long hostId = pickRunningHost(vmSnapshot.getVmId()); + vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested); + Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId()); // prepare snapshotVolumeTos - List<VolumeTO> volumeTOs = getVolumeTOList(vmSnapshot.getVmId()); + List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(vmSnapshot.getVmId()); // prepare DeleteVMSnapshotCommand String vmInstanceName = userVm.getInstanceName(); - VMSnapshotTO parent = getSnapshotWithParents(vmSnapshot).getParent(); + VMSnapshotTO parent = vmSnapshotHelper.getSnapshotWithParents(vmSnapshotVO).getParent(); VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(), vmSnapshot.getCreated().getTime(), vmSnapshot.getDescription(), vmSnapshot.getCurrent(), parent); - GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId()); + GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId()); DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs,guestOS.getDisplayName()); - answer = (DeleteVMSnapshotAnswer) sendToPool(hostId, deleteSnapshotCommand); + answer = (DeleteVMSnapshotAnswer) agentMgr.send(hostId, deleteSnapshotCommand); if (answer != null && answer.getResult()) { - processAnswer(vmSnapshot, userVm, answer, hostId); + processAnswer(vmSnapshotVO, userVm, answer, hostId); s_logger.debug("Delete VM snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName()); return true; } else { @@ -166,22 +198,22 @@ public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { } @DB - protected void processAnswer(VMSnapshotVO vmSnapshot, UserVmVO userVm, Answer as, Long hostId) { + protected void processAnswer(VMSnapshotVO vmSnapshot, UserVm userVm, Answer as, Long hostId) { final Transaction txn = Transaction.currentTxn(); try { txn.start(); if (as instanceof CreateVMSnapshotAnswer) { CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as; finalizeCreate(vmSnapshot, answer.getVolumeTOs()); - vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); + vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); } else if (as instanceof RevertToVMSnapshotAnswer) { RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as; finalizeRevert(vmSnapshot, answer.getVolumeTOs()); - vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); + vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded); } else if (as instanceof DeleteVMSnapshotAnswer) { DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as; finalizeDelete(vmSnapshot, answer.getVolumeTOs()); - _vmSnapshotDao.remove(vmSnapshot.getId()); + vmSnapshotDao.remove(vmSnapshot.getId()); } txn.commit(); } catch (Exception e) { @@ -199,21 +231,21 @@ public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { updateVolumePath(VolumeTOs); // update children's parent snapshots - List<VMSnapshotVO> children= _vmSnapshotDao.listByParent(vmSnapshot.getId()); + List<VMSnapshotVO> children= vmSnapshotDao.listByParent(vmSnapshot.getId()); for (VMSnapshotVO child : children) { child.setParent(vmSnapshot.getParent()); - _vmSnapshotDao.persist(child); + vmSnapshotDao.persist(child); } // update current snapshot - VMSnapshotVO current = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId()); + VMSnapshotVO current = vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId()); if(current != null && current.getId() == vmSnapshot.getId() && vmSnapshot.getParent() != null){ - VMSnapshotVO parent = _vmSnapshotDao.findById(vmSnapshot.getParent()); + VMSnapshotVO parent = vmSnapshotDao.findById(vmSnapshot.getParent()); parent.setCurrent(true); - _vmSnapshotDao.persist(parent); + vmSnapshotDao.persist(parent); } vmSnapshot.setCurrent(false); - _vmSnapshotDao.persist(vmSnapshot); + vmSnapshotDao.persist(vmSnapshot); } protected void finalizeCreate(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) { @@ -224,11 +256,11 @@ public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { // change current snapshot if (vmSnapshot.getParent() != null) { - VMSnapshotVO previousCurrent = _vmSnapshotDao.findById(vmSnapshot.getParent()); + VMSnapshotVO previousCurrent = vmSnapshotDao.findById(vmSnapshot.getParent()); previousCurrent.setCurrent(false); - _vmSnapshotDao.persist(previousCurrent); + vmSnapshotDao.persist(previousCurrent); } - _vmSnapshotDao.persist(vmSnapshot); + vmSnapshotDao.persist(vmSnapshot); } protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeTO> volumeToList) { @@ -236,61 +268,26 @@ public class DefaultVMSnapshotStrategy implements VMSnapshotStrategy { updateVolumePath(volumeToList); // update current snapshot, current snapshot is the one reverted to - VMSnapshotVO previousCurrent = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId()); + VMSnapshotVO previousCurrent = vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId()); if(previousCurrent != null){ previousCurrent.setCurrent(false); - _vmSnapshotDao.persist(previousCurrent); + vmSnapshotDao.persist(previousCurrent); } vmSnapshot.setCurrent(true); - _vmSnapshotDao.persist(vmSnapshot); + vmSnapshotDao.persist(vmSnapshot); } private void updateVolumePath(List<VolumeTO> volumeTOs) { for (VolumeTO volume : volumeTOs) { if (volume.getPath() != null) { - VolumeVO volumeVO = _volumeDao.findById(volume.getId()); + VolumeVO volumeVO = volumeDao.findById(volume.getId()); volumeVO.setPath(volume.getPath()); volumeVO.setVmSnapshotChainSize(volume.getChainSize()); - _volumeDao.persist(volumeVO); + volumeDao.persist(volumeVO); } } } - protected Long pickRunningHost(Long vmId) { - UserVmVO vm = _userVMDao.findById(vmId); - // use VM's host if VM is running - if(vm.getState() == VirtualMachine.State.Running) - return vm.getHostId(); - - // check if lastHostId is available - if(vm.getLastHostId() != null){ - HostVO lastHost = _hostDao.findById(vm.getLastHostId()); - if(lastHost.getStatus() == com.cloud.host.Status.Up && !lastHost.isInMaintenanceStates()) - return lastHost.getId(); - } - - List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId); - if (listVolumes == null || listVolumes.size() == 0) { - throw new InvalidParameterValueException("vmInstance has no volumes"); - } - VolumeVO volume = listVolumes.get(0); - Long poolId = volume.getPoolId(); - if (poolId == null) { - throw new InvalidParameterValueException("pool id is not found"); - } - StoragePoolVO storagePool = _storagePoolDao.findById(poolId); - if (storagePool == null) { - throw new InvalidParameterValueException("storage pool is not found"); - } - List<HostVO> listHost = _hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, storagePool.getClusterId(), storagePool.getPodId(), - storagePool.getDataCenterId(), null); - if (listHost == null || listHost.size() == 0) { - throw new InvalidParameterValueException("no host in up state is found"); - } - return listHost.get(0).getId(); - } - - private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeTO volumeTo){ VolumeVO volume = _volumeDao.findById(volumeTo.getId()); Long diskOfferingId = volume.getDiskOfferingId(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java ---------------------------------------------------------------------- diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java index 4330498..1437f80 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java @@ -18,10 +18,21 @@ */ package org.apache.cloudstack.storage.vmsnapshot; +import com.cloud.agent.api.VMSnapshotTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotVO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; + +import java.util.List; public interface VMSnapshotHelper { boolean vmSnapshotStateTransitTo(VMSnapshot vsnp, VMSnapshot.Event event) throws NoTransitionException; + + Long pickRunningHost(Long vmId); + + List<VolumeObjectTO> getVolumeTOList(Long vmId); + + VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java index c96b8ef..320a59c 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelperImpl.java @@ -18,17 +18,50 @@ */ package org.apache.cloudstack.storage.vmsnapshot; +import com.cloud.agent.api.VMSnapshotTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import javax.inject.Inject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class VMSnapshotHelperImpl implements VMSnapshotHelper { @Inject VMSnapshotDao _vmSnapshotDao; + @Inject + UserVmDao userVmDao; + @Inject + HostDao hostDao; + @Inject + VolumeDao volumeDao; + @Inject + PrimaryDataStoreDao primaryDataStoreDao; + @Inject + VolumeDataFactory volumeDataFactory; + StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ; public VMSnapshotHelperImpl() { _vmSnapshottateMachine = VMSnapshot.State.getStateMachine(); @@ -37,4 +70,79 @@ public class VMSnapshotHelperImpl implements VMSnapshotHelper { public boolean vmSnapshotStateTransitTo(VMSnapshot vsnp, VMSnapshot.Event event) throws NoTransitionException { return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao); } + + @Override + public Long pickRunningHost(Long vmId) { + UserVmVO vm = userVmDao.findById(vmId); + // use VM's host if VM is running + if(vm.getState() == VirtualMachine.State.Running) + return vm.getHostId(); + + // check if lastHostId is available + if(vm.getLastHostId() != null){ + HostVO lastHost = hostDao.findById(vm.getLastHostId()); + if(lastHost.getStatus() == com.cloud.host.Status.Up && !lastHost.isInMaintenanceStates()) + return lastHost.getId(); + } + + List<VolumeVO> listVolumes = volumeDao.findByInstance(vmId); + if (listVolumes == null || listVolumes.size() == 0) { + throw new InvalidParameterValueException("vmInstance has no volumes"); + } + VolumeVO volume = listVolumes.get(0); + Long poolId = volume.getPoolId(); + if (poolId == null) { + throw new InvalidParameterValueException("pool id is not found"); + } + StoragePoolVO storagePool = primaryDataStoreDao.findById(poolId); + if (storagePool == null) { + throw new InvalidParameterValueException("storage pool is not found"); + } + List<HostVO> listHost = hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, storagePool.getClusterId(), storagePool.getPodId(), + storagePool.getDataCenterId(), null); + if (listHost == null || listHost.size() == 0) { + throw new InvalidParameterValueException("no host in up state is found"); + } + return listHost.get(0).getId(); + } + + @Override + public List<VolumeObjectTO> getVolumeTOList(Long vmId) { + List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>(); + List<VolumeVO> volumeVos = volumeDao.findByInstance(vmId); + VolumeInfo volumeInfo = null; + for (VolumeVO volume : volumeVos) { + volumeInfo = volumeDataFactory.getVolume(volume.getId()); + + volumeTOs.add((VolumeObjectTO)volumeInfo.getTO()); + } + return volumeTOs; + } + + + private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) { + return new VMSnapshotTO(vo.getId(), vo.getName(), vo.getType(), vo.getCreated().getTime(), vo.getDescription(), + vo.getCurrent(), null); + } + + @Override + public VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) { + Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>(); + List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId()); + for (VMSnapshotVO vmSnapshotVO : allSnapshots) { + snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO); + } + + VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot); + VMSnapshotTO result = currentTO; + VMSnapshotVO current = snapshot; + while (current.getParent() != null) { + VMSnapshotVO parent = snapshotMap.get(current.getParent()); + currentTO.setParent(convert2VMSnapshotTO(parent)); + current = snapshotMap.get(current.getParent()); + currentTO = currentTO.getParent(); + } + return result; + } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c231af67/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index dc5d9ed..e241391 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -380,42 +380,8 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana return snapshot; } - protected List<VolumeTO> getVolumeTOList(Long vmId) { - List<VolumeTO> volumeTOs = new ArrayList<VolumeTO>(); - List<VolumeVO> volumeVos = _volumeDao.findByInstance(vmId); - - for (VolumeVO volume : volumeVos) { - StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); - VolumeTO volumeTO = new VolumeTO(volume, pool); - volumeTOs.add(volumeTO); - } - return volumeTOs; - } - // get snapshot and its parents recursively - private VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) { - Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>(); - List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId()); - for (VMSnapshotVO vmSnapshotVO : allSnapshots) { - snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO); - } - VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot); - VMSnapshotTO result = currentTO; - VMSnapshotVO current = snapshot; - while (current.getParent() != null) { - VMSnapshotVO parent = snapshotMap.get(current.getParent()); - currentTO.setParent(convert2VMSnapshotTO(parent)); - current = snapshotMap.get(current.getParent()); - currentTO = currentTO.getParent(); - } - return result; - } - - private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) { - return new VMSnapshotTO(vo.getId(), vo.getName(), vo.getType(), vo.getCreated().getTime(), vo.getDescription(), - vo.getCurrent(), null); - } public VMSnapshotManagerImpl() {
