You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by wi...@apache.org on 2013/05/24 16:01:30 UTC
[06/11] git commit: updated refs/heads/rbd-snap-clone to bef3a2e
CLOUDSTACK-1453: support restore for VM created from ISO
This is to support restore a vm to a new/currently_attached ISO.
In the restorevm API we have an optional parameter templateId to restore the vm to the new template/ISO ID.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a34e577d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a34e577d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a34e577d
Branch: refs/heads/rbd-snap-clone
Commit: a34e577d1be5a25d7eb884147212ab51786b55e2
Parents: 23baacb
Author: Harikrishna Patnala <ha...@citrix.com>
Authored: Fri May 24 16:38:55 2013 +0530
Committer: Koushik Das <ko...@citrix.com>
Committed: Fri May 24 16:41:03 2013 +0530
----------------------------------------------------------------------
.../api/command/user/vm/RestoreVMCmd.java | 5 +-
server/src/com/cloud/vm/UserVmManagerImpl.java | 43 +++++++++++----
server/test/com/cloud/vm/UserVmManagerTest.java | 42 +++++++++++++--
3 files changed, 74 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a34e577d/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 9c33f97..2f7d8e1 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
@@ -35,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 new template", responseObject=UserVmResponse.class, since="3.0.0")
+@APICommand(name = "restoreVirtualMachine", description="Restore a VM to original template/ISO or new template/ISO", 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";
@@ -44,9 +44,10 @@ 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")
+ @Parameter(name=ApiConstants.TEMPLATE_ID, type=CommandType.UUID, entityType = TemplateResponse.class, description="an optional template Id to restore vm from the new template. This can be an ISO id in case of restore vm deployed using ISO")
private Long templateId;
+
@Override
public String getEventType() {
return EventTypes.EVENT_VM_RESTORE;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a34e577d/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 c10a9d8..96b9529 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -4237,6 +4237,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
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);
@@ -4292,21 +4293,35 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
VolumeVO root = rootVols.get(0);
Long templateId = root.getTemplateId();
+ boolean isISO = false;
if(templateId == null) {
- InvalidParameterValueException ex = new InvalidParameterValueException("Currently there is no support to reset a vm that is deployed using ISO " + vm.getUuid());
- ex.addProxyObject(vm, vmId, "vmId");
- throw ex;
+ // Assuming that for a vm deployed using ISO, template ID is set to NULL
+ isISO = true;
+ templateId = vm.getIsoId();
}
VMTemplateVO template = null;
+ //newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
if(newTemplateId != null) {
template = _templateDao.findById(newTemplateId);
_accountMgr.checkAccess(caller, null, true, template);
+ if (isISO) {
+ if (!template.getFormat().equals(ImageFormat.ISO)) {
+ throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
+ }
+ } else {
+ if (template.getFormat().equals(ImageFormat.ISO)) {
+ throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
+ }
+ }
} else {
+ if (isISO && templateId == null) {
+ throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
+ }
template = _templateDao.findById(templateId);
if (template == null) {
InvalidParameterValueException ex = new InvalidParameterValueException(
- "Cannot find template for specified volumeid and vmId");
+ "Cannot find template/ISO for specified volumeid and vmId");
ex.addProxyObject(vm, vmId, "vmId");
ex.addProxyObject(root, root.getId(), "volumeId");
throw ex;
@@ -4325,13 +4340,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
}
}
- /* If new template is provided allocate a new volume from new template otherwise allocate new volume from original template */
+ /* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
VolumeVO newVol = null;
- if (newTemplateId != null){
- newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
- vm.setGuestOSId(template.getGuestOSId());
- vm.setTemplateId(newTemplateId);
- _vmDao.update(vmId, vm);
+ if (newTemplateId != null) {
+ if (isISO) {
+ newVol = volumeMgr.allocateDuplicateVolume(root, null);
+ vm.setIsoId(newTemplateId);
+ vm.setGuestOSId(template.getGuestOSId());
+ vm.setTemplateId(newTemplateId);
+ _vmDao.update(vmId, vm);
+ } else {
+ newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
+ vm.setGuestOSId(template.getGuestOSId());
+ vm.setTemplateId(newTemplateId);
+ _vmDao.update(vmId, vm);
+ }
} else {
newVol = volumeMgr.allocateDuplicateVolume(root, null);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a34e577d/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 6a97114..5eedfa5 100755
--- a/server/test/com/cloud/vm/UserVmManagerTest.java
+++ b/server/test/com/cloud/vm/UserVmManagerTest.java
@@ -24,10 +24,8 @@ import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
import java.lang.reflect.Field;
import java.util.List;
@@ -64,6 +62,7 @@ import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.Storage.ImageFormat;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountService;
@@ -200,6 +199,7 @@ public class UserVmManagerTest {
doReturn(false).when(_rootVols).isEmpty();
when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
doReturn(3L).when(_volumeMock).getTemplateId();
+ doReturn(ImageFormat.VHD).when(_templateMock).getFormat();
when(_templateDao.findById(anyLong())).thenReturn(_templateMock);
doNothing().when(_accountMgr).checkAccess(_account, null, true, _templateMock);
when(_itMgr.stop(_vmMock, _userMock, _account)).thenReturn(true);
@@ -220,6 +220,40 @@ public class UserVmManagerTest {
}
+ // Test restoreVM on providing new ISO Id, when VM(deployed using ISO) is in running state
+ @Test
+ public void testRestoreVMF5() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
+ ConcurrentOperationException, ResourceAllocationException {
+ doReturn(VirtualMachine.State.Running).when(_vmMock).getState();
+ when(_vmDao.findById(anyLong())).thenReturn(_vmMock);
+ when(_volsDao.findByInstanceAndType(314L, Volume.Type.ROOT)).thenReturn(_rootVols);
+ doReturn(false).when(_rootVols).isEmpty();
+ when(_rootVols.get(eq(0))).thenReturn(_volumeMock);
+ doReturn(null).when(_volumeMock).getTemplateId();
+ doReturn(3L).when(_vmMock).getIsoId();
+ doReturn(ImageFormat.ISO).when(_templateMock).getFormat();
+ 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, null)).thenReturn(_volumeMock);
+ doNothing().when(_vmMock).setIsoId(14L);
+ 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(_templateMock.getUuid()).thenReturn("b1a3626e-72e0-4697-8c7c-a110940cc55d");
+
+ _userVmMgr.restoreVMInternal(_account, _vmMock, 14L);
+
+ verify(_vmMock, times(1)).setIsoId(14L);
+
+ }
// Test scaleVm on incompatible HV.
@Test(expected=InvalidParameterValueException.class)
public void testScaleVMF1() throws Exception {