You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/02/21 22:45:20 UTC

[13/51] [abbrv] git commit: refs/heads/ui-quick-view-v2 - CLOUDSTACK-667: VM's base image update facility

CLOUDSTACK-667: VM's base image update facility


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/6c01b62c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/6c01b62c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/6c01b62c

Branch: refs/heads/ui-quick-view-v2
Commit: 6c01b62cdc2fe068d50b4e37739721dbc722cc41
Parents: 59db01c
Author: Harikrishna Patnala <ha...@citrix.com>
Authored: Thu Feb 21 15:03:18 2013 +0530
Committer: Abhinandan Prateek <ap...@apache.org>
Committed: Thu Feb 21 15:04:29 2013 +0530

----------------------------------------------------------------------
 .../api/command/user/vm/RestoreVMCmd.java          |   10 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java     |   51 ++++--
 server/test/com/cloud/vm/UserVmManagerTest.java    |  131 +++++++++------
 3 files changed, 126 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6c01b62c/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
index e98c2f2..9c33f97 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
@@ -22,6 +22,7 @@ import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseAsyncCmd;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.log4j.Logger;
 
@@ -34,7 +35,7 @@ import com.cloud.user.Account;
 import com.cloud.user.UserContext;
 import com.cloud.uservm.UserVm;
 
-@APICommand(name = "restoreVirtualMachine", description="Restore a VM to original template or specific snapshot", responseObject=UserVmResponse.class, since="3.0.0")
+@APICommand(name = "restoreVirtualMachine", description="Restore a VM to original template or new template", responseObject=UserVmResponse.class, since="3.0.0")
 public class RestoreVMCmd extends BaseAsyncCmd {
     public static final Logger s_logger = Logger.getLogger(RestoreVMCmd.class);
     private static final String s_name = "restorevmresponse";
@@ -43,6 +44,9 @@ public class RestoreVMCmd extends BaseAsyncCmd {
             required=true, description="Virtual Machine ID")
     private Long vmId;
 
+    @Parameter(name=ApiConstants.TEMPLATE_ID, type=CommandType.UUID, entityType = TemplateResponse.class, description="an optional template Id to restore vm from the new template")
+    private Long templateId;
+
     @Override
     public String getEventType() {
         return EventTypes.EVENT_VM_RESTORE;
@@ -85,4 +89,8 @@ public class RestoreVMCmd extends BaseAsyncCmd {
     public long getVmId() {
         return vmId;
     }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6c01b62c/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index ea25c66..ed8cd36 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2675,8 +2675,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
         // If the VM is Volatile in nature, on reboot discard the VM's root disk and create a new root disk for it: by calling restoreVM
         long serviceOfferingId = vmInstance.getServiceOfferingId();
         ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOfferingId);
-        if(offering.getVolatileVm()){
-            return restoreVMInternal(caller, vmInstance);
+        if(offering != null && offering.getRemoved() == null) {
+            if(offering.getVolatileVm()){
+                return restoreVMInternal(caller, vmInstance, null);
+            }
+        } else {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId + " corresponding to the vm");
         }
 
         return rebootVirtualMachine(UserContext.current().getCallerUserId(),
@@ -4795,9 +4799,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
     public UserVm restoreVM(RestoreVMCmd cmd) {
         // Input validation
         Account caller = UserContext.current().getCaller();
-        Long userId = UserContext.current().getCallerUserId();
 
         long vmId = cmd.getVmId();
+        Long newTemplateId = cmd.getTemplateId();
         UserVmVO vm = _vmDao.findById(vmId);
         if (vm == null) {
             InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find VM with ID " + vmId);
@@ -4805,10 +4809,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
             throw ex;
         }
 
-        return restoreVMInternal(caller, vm);
+        _accountMgr.checkAccess(caller, null, true, vm);
+
+        return restoreVMInternal(caller, vm, newTemplateId);
     }
 
-    public UserVm restoreVMInternal(Account caller, UserVmVO vm){
+    public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId){
 
         Long userId = caller.getId();
         Account owner = _accountDao.findById(vm.getAccountId());
@@ -4857,13 +4863,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
             throw ex;
         }
 
-        VMTemplateVO template = _templateDao.findById(templateId);
-        if (template == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException(
-                    "Cannot find template for specified volumeid and vmId");
-            ex.addProxyObject(vm, vmId, "vmId");
-            ex.addProxyObject(root, root.getId(), "volumeId");
-            throw ex;
+        VMTemplateVO template = null;
+        if(newTemplateId != null) {
+            template = _templateDao.findById(newTemplateId);
+            _accountMgr.checkAccess(caller, null, true, template);
+        } else {
+            template = _templateDao.findById(templateId);
+            if (template == null) {
+                InvalidParameterValueException ex = new InvalidParameterValueException(
+                        "Cannot find template for specified volumeid and vmId");
+                ex.addProxyObject(vm, vmId, "vmId");
+                ex.addProxyObject(root, root.getId(), "volumeId");
+                throw ex;
+            }
         }
 
         if (needRestart) {
@@ -4878,8 +4890,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
             }
         }
 
-        /* allocate a new volume from original template */
-        VolumeVO newVol = _storageMgr.allocateDuplicateVolume(root, null);
+        /* If new template is provided allocate a new volume from new template otherwise allocate new volume from original template */
+        VolumeVO newVol = null;
+        if (newTemplateId != null){
+            newVol = _storageMgr.allocateDuplicateVolume(root, newTemplateId);
+            vm.setGuestOSId(template.getGuestOSId());
+            vm.setTemplateId(newTemplateId);
+            _vmDao.update(vmId, vm);
+        } else newVol = _storageMgr.allocateDuplicateVolume(root, null);
+
         _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId());
 
         /* Detach and destory the old root volume */
@@ -4903,8 +4922,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
             }
         }
 
-        s_logger.debug("Restore VM " + vm.getUuid() + " with template "
-                + root.getTemplateId() + " successfully");
+        s_logger.debug("Restore VM " + vmId + " with template "
+                + template.getUuid() + " done successfully");
         return vm;
 
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6c01b62c/server/test/com/cloud/vm/UserVmManagerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java
index 46069ed..07cad47 100755
--- a/server/test/com/cloud/vm/UserVmManagerTest.java
+++ b/server/test/com/cloud/vm/UserVmManagerTest.java
@@ -54,20 +54,20 @@ public class UserVmManagerTest {
     @Spy UserVmManagerImpl _userVmMgr = new UserVmManagerImpl();
     @Mock VirtualMachineManager _itMgr;
     @Mock StorageManager _storageMgr;
-    @Mock Account account;
+    @Mock Account _account;
     @Mock AccountManager _accountMgr;
     @Mock AccountDao _accountDao;
     @Mock UserDao _userDao;
     @Mock UserVmDao _vmDao;
     @Mock VMTemplateDao _templateDao;
     @Mock VolumeDao _volsDao;
-    @Mock RestoreVMCmd restoreVMCmd;
-    @Mock AccountVO accountMock;
-    @Mock UserVO userMock;
-    @Mock UserVmVO vmMock;
-    @Mock VMTemplateVO templateMock;
-    @Mock VolumeVO volumeMock;
-    @Mock List<VolumeVO> rootVols;
+    @Mock RestoreVMCmd _restoreVMCmd;
+    @Mock AccountVO _accountMock;
+    @Mock UserVO _userMock;
+    @Mock UserVmVO _vmMock;
+    @Mock VMTemplateVO _templateMock;
+    @Mock VolumeVO _volumeMock;
+    @Mock List<VolumeVO> _rootVols;
     @Before
     public void setup(){
         MockitoAnnotations.initMocks(this);
@@ -79,69 +79,102 @@ public class UserVmManagerTest {
         _userVmMgr._storageMgr = _storageMgr;
         _userVmMgr._accountDao = _accountDao;
         _userVmMgr._userDao = _userDao;
+        _userVmMgr._accountMgr = _accountMgr;
 
-        doReturn(3L).when(account).getId();
-        doReturn(8L).when(vmMock).getAccountId();
-        when(_accountDao.findById(anyLong())).thenReturn(accountMock);
-        when(_userDao.findById(anyLong())).thenReturn(userMock);
-        doReturn(Account.State.enabled).when(account).getState();
-        when(vmMock.getId()).thenReturn(314L);
+        doReturn(3L).when(_account).getId();
+        doReturn(8L).when(_vmMock).getAccountId();
+        when(_accountDao.findById(anyLong())).thenReturn(_accountMock);
+        when(_userDao.findById(anyLong())).thenReturn(_userMock);
+        doReturn(Account.State.enabled).when(_account).getState();
+        when(_vmMock.getId()).thenReturn(314L);
 
     }
 
-    // VM state not in running/stopped case
+    // Test restoreVm when VM state not in running/stopped case
     @Test(expected=CloudRuntimeException.class)
     public void testRestoreVMF1() throws ResourceAllocationException {
 
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(_templateDao.findById(anyLong())).thenReturn(templateMock);
-        doReturn(VirtualMachine.State.Error).when(vmMock).getState();
-        _userVmMgr.restoreVMInternal(account, vmMock);
+        when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
+        when(_templateDao.findById(anyLong())).thenReturn(_templateMock);
+        doReturn(VirtualMachine.State.Error).when(_vmMock).getState();
+        _userVmMgr.restoreVMInternal(_account, _vmMock, null);
     }
 
-    // when VM is in stopped state
+    // Test restoreVm when VM is in stopped state
     @Test
     public void testRestoreVMF2()  throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
-    ConcurrentOperationException, ResourceAllocationException {
-
-        doReturn(VirtualMachine.State.Stopped).when(vmMock).getState();
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(_volsDao.findByInstance(anyLong())).thenReturn(rootVols);
-        doReturn(false).when(rootVols).isEmpty();
-        when(rootVols.get(eq(0))).thenReturn(volumeMock);
-        doReturn(3L).when(volumeMock).getTemplateId();
-        when(_templateDao.findById(anyLong())).thenReturn(templateMock);
-        when(_storageMgr.allocateDuplicateVolume(volumeMock, null)).thenReturn(volumeMock);
+        ConcurrentOperationException, ResourceAllocationException {
+
+        doReturn(VirtualMachine.State.Stopped).when(_vmMock).getState();
+        when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
+        when(_volsDao.findByInstance(anyLong())).thenReturn(_rootVols);
+        doReturn(false).when(_rootVols).isEmpty();
+        when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
+        doReturn(3L).when(_volumeMock).getTemplateId();
+        when(_templateDao.findById(anyLong())).thenReturn(_templateMock);
+        when(_storageMgr.allocateDuplicateVolume(_volumeMock, null)).thenReturn(_volumeMock);
         doNothing().when(_volsDao).attachVolume(anyLong(), anyLong(), anyLong());
-        when(volumeMock.getId()).thenReturn(3L);
+        when(_volumeMock.getId()).thenReturn(3L);
         doNothing().when(_volsDao).detachVolume(anyLong());
-        when(_storageMgr.destroyVolume(volumeMock)).thenReturn(true);
+        when(_storageMgr.destroyVolume(_volumeMock)).thenReturn(true);
+        when(_templateMock.getUuid()).thenReturn("e0552266-7060-11e2-bbaa-d55f5db67735");
 
-        _userVmMgr.restoreVMInternal(account, vmMock);
+        _userVmMgr.restoreVMInternal(_account, _vmMock, null);
 
     }
 
-    // when VM is in running state
+    // Test restoreVM when VM is in running state
     @Test
     public void testRestoreVMF3()  throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
-    ConcurrentOperationException, ResourceAllocationException {
-
-        doReturn(VirtualMachine.State.Running).when(vmMock).getState();
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(_volsDao.findByInstance(anyLong())).thenReturn(rootVols);
-        doReturn(false).when(rootVols).isEmpty();
-        when(rootVols.get(eq(0))).thenReturn(volumeMock);
-        doReturn(3L).when(volumeMock).getTemplateId();
-        when(_templateDao.findById(anyLong())).thenReturn(templateMock);
-        when(_itMgr.stop(vmMock, userMock, account)).thenReturn(true);
-        when(_itMgr.start(vmMock, null, userMock, account)).thenReturn(vmMock);
-        when(_storageMgr.allocateDuplicateVolume(volumeMock, null)).thenReturn(volumeMock);
+        ConcurrentOperationException, ResourceAllocationException {
+
+        doReturn(VirtualMachine.State.Running).when(_vmMock).getState();
+        when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
+        when(_volsDao.findByInstance(anyLong())).thenReturn(_rootVols);
+        doReturn(false).when(_rootVols).isEmpty();
+        when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
+        doReturn(3L).when(_volumeMock).getTemplateId();
+        when(_templateDao.findById(anyLong())).thenReturn(_templateMock);
+        when(_itMgr.stop(_vmMock, _userMock, _account)).thenReturn(true);
+        when(_itMgr.start(_vmMock, null, _userMock, _account)).thenReturn(_vmMock);
+        when(_storageMgr.allocateDuplicateVolume(_volumeMock, null)).thenReturn(_volumeMock);
         doNothing().when(_volsDao).attachVolume(anyLong(), anyLong(), anyLong());
-        when(volumeMock.getId()).thenReturn(3L);
+        when(_volumeMock.getId()).thenReturn(3L);
         doNothing().when(_volsDao).detachVolume(anyLong());
-        when(_storageMgr.destroyVolume(volumeMock)).thenReturn(true);
+        when(_storageMgr.destroyVolume(_volumeMock)).thenReturn(true);
+        when(_templateMock.getUuid()).thenReturn("e0552266-7060-11e2-bbaa-d55f5db67735");
 
-        _userVmMgr.restoreVMInternal(account, vmMock);
+        _userVmMgr.restoreVMInternal(_account, _vmMock, null);
+
+    }
+
+    // Test restoreVM on providing new template Id, when VM is in running state
+    @Test
+    public void testRestoreVMF4()  throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
+            ConcurrentOperationException, ResourceAllocationException {
+        doReturn(VirtualMachine.State.Running).when(_vmMock).getState();
+        when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
+        when(_volsDao.findByInstance(anyLong())).thenReturn(_rootVols);
+        doReturn(false).when(_rootVols).isEmpty();
+        when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
+        doReturn(3L).when(_volumeMock).getTemplateId();
+        when(_templateDao.findById(anyLong())).thenReturn(_templateMock);
+        doNothing().when(_accountMgr).checkAccess(_account, null, true, _templateMock);
+        when(_itMgr.stop(_vmMock, _userMock, _account)).thenReturn(true);
+        when(_storageMgr.allocateDuplicateVolume(_volumeMock, 14L)).thenReturn(_volumeMock);
+        when(_templateMock.getGuestOSId()).thenReturn(5L);
+        doNothing().when(_vmMock).setGuestOSId(anyLong());
+        doNothing().when(_vmMock).setTemplateId(3L);
+        when(_vmDao.update(314L, _vmMock)).thenReturn(true);
+        when(_itMgr.start(_vmMock, null, _userMock, _account)).thenReturn(_vmMock);
+        when(_storageMgr.allocateDuplicateVolume(_volumeMock, null)).thenReturn(_volumeMock);
+        doNothing().when(_volsDao).attachVolume(anyLong(), anyLong(), anyLong());
+        when(_volumeMock.getId()).thenReturn(3L);
+        doNothing().when(_volsDao).detachVolume(anyLong());
+        when(_storageMgr.destroyVolume(_volumeMock)).thenReturn(true);
+        when(_templateMock.getUuid()).thenReturn("b1a3626e-72e0-4697-8c7c-a110940cc55d");
+
+        _userVmMgr.restoreVMInternal(_account, _vmMock, 14L);
 
     }