use hypervisor capabilities to control if vm snapshot is enabled for hypervisors
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/b646e43a Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/b646e43a Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/b646e43a Branch: refs/heads/internallb Commit: b646e43a1a7fb3c668a7160823c3740aeaf3ac8c Parents: bd7a389 Author: Mice Xia <[email protected]> Authored: Wed Apr 10 11:34:39 2013 +0800 Committer: Mice Xia <[email protected]> Committed: Wed Apr 10 12:36:42 2013 +0800 ---------------------------------------------------------------------- .../cloud/hypervisor/HypervisorCapabilitiesVO.java | 13 +++++++++- .../hypervisor/dao/HypervisorCapabilitiesDao.java | 2 + .../dao/HypervisorCapabilitiesDaoImpl.java | 7 +++++ .../cloud/vm/snapshot/VMSnapshotManagerImpl.java | 8 +++++- .../cloud/vm/snapshot/VMSnapshotManagerTest.java | 20 +++++++++++++- setup/db/db/schema-410to420.sql | 4 +++ 6 files changed, 50 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b646e43a/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java ---------------------------------------------------------------------- diff --git a/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java b/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java index b525a2d..fafc0a3 100644 --- a/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java +++ b/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java @@ -62,6 +62,9 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities { @Column(name="max_hosts_per_cluster") private Integer maxHostsPerCluster; + @Column(name="vm_snapshot_enabled") + private Boolean vmSnapshotEnabled; + protected HypervisorCapabilitiesVO() { this.uuid = UUID.randomUUID().toString(); } @@ -169,7 +172,15 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities { this.maxHostsPerCluster = maxHostsPerCluster; } - @Override + public Boolean getVmSnapshotEnabled() { + return vmSnapshotEnabled; + } + + public void setVmSnapshotEnabled(Boolean vmSnapshotEnabled) { + this.vmSnapshotEnabled = vmSnapshotEnabled; + } + + @Override public boolean equals(Object obj) { if (obj instanceof HypervisorCapabilitiesVO) { return ((HypervisorCapabilitiesVO)obj).getId() == this.getId(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b646e43a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java b/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java index 0fe0b53..1fdc03a 100644 --- a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java +++ b/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java @@ -33,4 +33,6 @@ public interface HypervisorCapabilitiesDao extends GenericDao<HypervisorCapabili Integer getMaxDataVolumesLimit(HypervisorType hypervisorType, String hypervisorVersion); Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion); + + Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b646e43a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java b/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java index 759803e..b5e17ee 100644 --- a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java +++ b/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java @@ -95,4 +95,11 @@ public class HypervisorCapabilitiesDaoImpl extends GenericDaoBase<HypervisorCapa HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); return result.getMaxHostsPerCluster(); } + + @Override + public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, + String hypervisorVersion) { + HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion); + return result.getVmSnapshotEnabled(); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b646e43a/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 ffbbb82..8687163 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -59,6 +59,7 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.storage.GuestOSVO; @@ -119,6 +120,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana @Inject VirtualMachineManager _itMgr; @Inject DataStoreManager dataStoreMgr; @Inject ConfigurationDao _configDao; + @Inject HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; int _vmSnapshotMax; int _wait; StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ; @@ -244,7 +246,11 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana if (userVmVo == null) { throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist"); } - + + // check hypervisor capabilities + if(!_hypervisorCapabilitiesDao.isVmSnapshotEnabled(userVmVo.getHypervisorType(), "default")) + throw new InvalidParameterValueException("VM snapshot is not enabled for hypervisor type: " + userVmVo.getHypervisorType()); + // parameter length check if(vsDisplayName != null && vsDisplayName.length()>255) throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDisplayName should not exceed 255"); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b646e43a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java index 576c95b..41c9d12 100644 --- a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java +++ b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java @@ -27,6 +27,8 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -36,6 +38,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; +import com.amazonaws.services.ec2.model.HypervisorType; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CreateVMSnapshotAnswer; @@ -47,7 +50,9 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.HypervisorGuruManager; +import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.storage.GuestOSVO; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; @@ -88,6 +93,7 @@ public class VMSnapshotManagerTest { @Mock SnapshotDao _snapshotDao; @Mock VirtualMachineManager _itMgr; @Mock ConfigurationDao _configDao; + @Mock HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; int _vmSnapshotMax = 10; private static long TEST_VM_ID = 3L; @@ -105,6 +111,7 @@ public class VMSnapshotManagerTest { _vmSnapshotMgr._accountMgr = _accountMgr; _vmSnapshotMgr._snapshotDao = _snapshotDao; _vmSnapshotMgr._guestOSDao = _guestOSDao; + _vmSnapshotMgr._hypervisorCapabilitiesDao = _hypervisorCapabilitiesDao; doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); @@ -114,7 +121,8 @@ public class VMSnapshotManagerTest { when(_userVMDao.findById(anyLong())).thenReturn(vmMock); when(_vmSnapshotDao.findByName(anyLong(), anyString())).thenReturn(null); when(_vmSnapshotDao.findByVm(anyLong())).thenReturn(new ArrayList<VMSnapshotVO>()); - + when(_hypervisorCapabilitiesDao.isVmSnapshotEnabled(Hypervisor.HypervisorType.XenServer, "default")).thenReturn(true); + List<VolumeVO> mockVolumeList = new ArrayList<VolumeVO>(); mockVolumeList.add(volumeMock); when(volumeMock.getInstanceId()).thenReturn(TEST_VM_ID); @@ -122,7 +130,7 @@ public class VMSnapshotManagerTest { when(vmMock.getInstanceName()).thenReturn("i-3-VM-TEST"); when(vmMock.getState()).thenReturn(State.Running); - + when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer); when(_guestOSDao.findById(anyLong())).thenReturn(mock(GuestOSVO.class)); } @@ -133,6 +141,14 @@ public class VMSnapshotManagerTest { _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true); } + // hypervisorCapabilities not expected case + @Test(expected=InvalidParameterValueException.class) + public void testAllocVMSnapshotF6() throws ResourceAllocationException{ + when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.Ovm); + when(_hypervisorCapabilitiesDao.isVmSnapshotEnabled(Hypervisor.HypervisorType.Ovm, "default")).thenReturn(false); + _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true); + } + // vm state not in [running, stopped] case @Test(expected=InvalidParameterValueException.class) public void testAllocVMSnapshotF2() throws ResourceAllocationException{ http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b646e43a/setup/db/db/schema-410to420.sql ---------------------------------------------------------------------- diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ff9ca1d..c7c8b5b 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -444,3 +444,7 @@ CREATE TABLE `cloud`.`vm_snapshots` ( CONSTRAINT `fk_vm_snapshots_account_id__account_id` FOREIGN KEY `fk_vm_snapshots_account_id__account_id` (`account_id`) REFERENCES `account` (`id`), CONSTRAINT `fk_vm_snapshots_domain_id__domain_id` FOREIGN KEY `fk_vm_snapshots_domain_id__domain_id` (`domain_id`) REFERENCES `domain` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `cloud`.`hypervisor_capabilities` ADD COLUMN `vm_snapshot_enabled` tinyint(1) DEFAULT 0 NOT NULL COMMENT 'Whether VM snapshot is supported by hypervisor'; +UPDATE `cloud`.`hypervisor_capabilities` SET `vm_snapshot_enabled`=1 WHERE `hypervisor_type` in ('VMware', 'XenServer'); +
