You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mi...@apache.org on 2013/02/01 17:32:41 UTC
git commit: refs/heads/vm-snapshot - 1) remove snapshoting/reverting
states from VM state machine, 2) change vmsnapshotservice interface
Updated Branches:
refs/heads/vm-snapshot bb7cd90b6 -> ebca6890f
1) remove snapshoting/reverting states from VM state machine,2) change vmsnapshotservice interface
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/ebca6890
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/ebca6890
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/ebca6890
Branch: refs/heads/vm-snapshot
Commit: ebca6890fd54f0ecc147f842b6c1366cf90957f9
Parents: bb7cd90
Author: Mice Xia <mi...@tcloudcomputing.com>
Authored: Sat Feb 2 00:36:21 2013 +0800
Committer: Mice Xia <mi...@tcloudcomputing.com>
Committed: Sat Feb 2 00:36:21 2013 +0800
----------------------------------------------------------------------
api/src/com/cloud/event/EventTypes.java | 2 +-
api/src/com/cloud/vm/VirtualMachine.java | 22 +--
api/src/com/cloud/vm/snapshot/VMSnapshot.java | 1 +
.../com/cloud/vm/snapshot/VMSnapshotService.java | 13 +-
.../user/vmsnapshot/CreateVMSnapshotCmd.java | 6 +-
.../user/vmsnapshot/DeleteVMSnapshotCmd.java | 22 +--
.../command/user/vmsnapshot/ListVMSnapshotCmd.java | 12 -
.../user/vmsnapshot/RevertToSnapshotCmd.java | 20 +-
.../com/cloud/vm/VirtualMachineManagerImpl.java | 43 ++--
.../com/cloud/vm/snapshot/VMSnapshotManager.java | 7 +-
.../cloud/vm/snapshot/VMSnapshotManagerImpl.java | 184 ++++++++-------
.../cloud/vm/snapshot/VMSnapshotManagerTest.java | 60 +++---
ui/scripts/instances.js | 8 -
13 files changed, 173 insertions(+), 227 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index ffd0dd4..07ead20 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -295,7 +295,7 @@ public class EventTypes {
// vm snapshot events
public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
- public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERT";
+ public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERTTO";
// external network device events
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/com/cloud/vm/VirtualMachine.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java
index d7df268..358ab05 100755
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -42,11 +42,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
Migrating(true, "VM is being migrated. host id holds to from host"),
Error(false, "VM is in error"),
Unknown(false, "VM state is unknown."),
- Shutdowned(false, "VM is shutdowned from inside"),
- RunningSnapshotting(true, "VM is taking a snapshot in running state"),
- StoppedSnapshotting(true, "VM is taking a snapshot in stopped state"),
- RevertingToRunning(true, "VM is reverting to snapshot"),
- RevertingToStopped(true, "VM is reverting to snapshot");
+ Shutdowned(false, "VM is shutdowned from inside");
private final boolean _transitional;
String _description;
@@ -114,22 +110,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
s_fsm.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
s_fsm.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
s_fsm.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
-
- s_fsm.addTransition(State.Running, VirtualMachine.Event.SnapshotRequested, State.RunningSnapshotting);
- s_fsm.addTransition(State.Stopped, VirtualMachine.Event.SnapshotRequested, State.StoppedSnapshotting);
- s_fsm.addTransition(State.RunningSnapshotting, VirtualMachine.Event.OperationSucceeded, State.Running);
- s_fsm.addTransition(State.StoppedSnapshotting, VirtualMachine.Event.OperationSucceeded, State.Stopped);
- s_fsm.addTransition(State.RunningSnapshotting, VirtualMachine.Event.OperationFailed, State.Running);
- s_fsm.addTransition(State.StoppedSnapshotting, VirtualMachine.Event.OperationFailed, State.Stopped);
-
- s_fsm.addTransition(State.Running, VirtualMachine.Event.RevertRequested, State.RevertingToRunning);
- s_fsm.addTransition(State.Stopped, VirtualMachine.Event.RevertRequested, State.RevertingToStopped);
- s_fsm.addTransition(State.RevertingToRunning, VirtualMachine.Event.OperationFailed, State.Running);
- s_fsm.addTransition(State.RevertingToStopped, VirtualMachine.Event.OperationFailed, State.Stopped);
- s_fsm.addTransition(State.RevertingToRunning, VirtualMachine.Event.OperationSucceeded, State.Running);
- s_fsm.addTransition(State.RevertingToStopped, VirtualMachine.Event.OperationSucceeded, State.Stopped);
-
-
}
public static boolean isVmStarted(State oldState, Event e, State newState) {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/com/cloud/vm/snapshot/VMSnapshot.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/snapshot/VMSnapshot.java b/api/src/com/cloud/vm/snapshot/VMSnapshot.java
index 7d08a2e..f0ee7ee 100644
--- a/api/src/com/cloud/vm/snapshot/VMSnapshot.java
+++ b/api/src/com/cloud/vm/snapshot/VMSnapshot.java
@@ -61,6 +61,7 @@ public interface VMSnapshot extends ControlledEntity, Identity, InternalIdentity
s_fsm.addTransition(Reverting, Event.OperationFailed, Ready);
s_fsm.addTransition(Ready, Event.ExpungeRequested, Expunging);
s_fsm.addTransition(Error, Event.ExpungeRequested, Expunging);
+ s_fsm.addTransition(Expunging, Event.ExpungeRequested, Expunging);
s_fsm.addTransition(Expunging, Event.OperationSucceeded, Removed);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/com/cloud/vm/snapshot/VMSnapshotService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/snapshot/VMSnapshotService.java b/api/src/com/cloud/vm/snapshot/VMSnapshotService.java
index a1909fa..83f86bc 100644
--- a/api/src/com/cloud/vm/snapshot/VMSnapshotService.java
+++ b/api/src/com/cloud/vm/snapshot/VMSnapshotService.java
@@ -19,10 +19,7 @@ package com.cloud.vm.snapshot;
import java.util.List;
-import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToSnapshotCmd;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@@ -36,16 +33,16 @@ public interface VMSnapshotService {
List<? extends VMSnapshot> listVMSnapshots(ListVMSnapshotCmd cmd);
- VMSnapshot getVMSnapshotById(long id);
+ VMSnapshot getVMSnapshotById(Long id);
- VMSnapshot creatVMSnapshot(CreateVMSnapshotCmd cmd);
+ VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId);
- VMSnapshot allocVMSnapshot(CreateVMSnapshotCmd cmd)
+ VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDescription, Boolean snapshotMemory)
throws ResourceAllocationException;
- boolean deleteVMSnapshot(DeleteVMSnapshotCmd cmd);
+ boolean deleteVMSnapshot(Long vmSnapshotId);
- UserVm revertToSnapshot(RevertToSnapshotCmd cmd) throws InsufficientServerCapacityException, InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
+ UserVm revertToSnapshot(Long vmSnapshotId) throws InsufficientServerCapacityException, InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
VirtualMachine getVMBySnapshotId(Long id);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
index 7ded716..45cc9f1 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
@@ -75,7 +75,7 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
@Override
public void create() throws ResourceAllocationException {
- VMSnapshot vmsnapshot = _vmSnapshotService.allocVMSnapshot(this);
+ VMSnapshot vmsnapshot = _vmSnapshotService.allocVMSnapshot(getVmId(),getDisplayName(),getDescription(),snapshotMemory());
if (vmsnapshot != null) {
this.setEntityId(vmsnapshot.getId());
} else {
@@ -86,7 +86,7 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
@Override
public String getEventDescription() {
- return "creating snapshot for vm: " + getVmId();
+ return "creating snapshot for VM: " + getVmId();
}
@Override
@@ -97,7 +97,7 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
@Override
public void execute() {
UserContext.current().setEventDetails("VM Id: " + getVmId());
- VMSnapshot result = _vmSnapshotService.creatVMSnapshot(this);
+ VMSnapshot result = _vmSnapshotService.creatVMSnapshot(getVmId(),getEntityId());
if (result != null) {
VMSnapshotResponse response = _responseGenerator
.createVMSnapshotResponse(result);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
index 592bc66..a2b2c08 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
@@ -17,30 +17,20 @@
package org.apache.cloudstack.api.command.user.vmsnapshot;
-import org.apache.log4j.Logger;
-
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseCmd.CommandType;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
-
+import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.log4j.Logger;
+
import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;
-//import com.cloud.api.ApiDBUtils;
@APICommand(name="deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class)
public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
@@ -61,10 +51,6 @@ public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
return s_name;
}
- public static String getResultObjectName() {
- return "vm_snapshots";
- }
-
@Override
public long getEntityOwnerId() {
VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getId());
@@ -77,7 +63,7 @@ public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
@Override
public void execute() {
UserContext.current().setEventDetails("vmsnapshot id: " + getId());
- boolean result = _vmSnapshotService.deleteVMSnapshot(this);
+ boolean result = _vmSnapshotService.deleteVMSnapshot(getId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
index 8b18484..3c7052d 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
@@ -39,10 +39,6 @@ public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
private static final String s_name = "listvmsnapshotresponse";
- // ///////////////////////////////////////////////////
- // ////////////// API parameters /////////////////////
- // ///////////////////////////////////////////////////
-
@Parameter(name=ApiConstants.VM_SNAPSHOT_ID, type=CommandType.UUID, entityType=VMSnapshotResponse.class,
description="The ID of the VM snapshot")
private Long id;
@@ -56,10 +52,6 @@ public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists snapshot by snapshot name or display name")
private String vmSnapshotName;
- // ///////////////////////////////////////////////////
- // ///////////////// Accessors ///////////////////////
- // ///////////////////////////////////////////////////
-
public String getState() {
return state;
}
@@ -76,10 +68,6 @@ public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
return id;
}
- // ///////////////////////////////////////////////////
- // ///////////// API Implementation///////////////////
- // ///////////////////////////////////////////////////
-
@Override
public void execute() {
List<? extends VMSnapshot> result = _vmSnapshotService
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToSnapshotCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToSnapshotCmd.java
index 6642a85..d7b4599 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToSnapshotCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToSnapshotCmd.java
@@ -30,9 +30,9 @@ import org.apache.cloudstack.api.response.VMSnapshotResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
import com.cloud.vm.snapshot.VMSnapshot;
@@ -55,33 +55,27 @@ public class RevertToSnapshotCmd extends BaseAsyncCmd {
return s_name;
}
- public static String getResultObjectName() {
- return "vm_snapshots";
- }
-
@Override
public long getEntityOwnerId() {
- VMSnapshot vmSnapshot = _vmSnapshotService.getVMSnapshotById(getVmSnapShotId());
- if (vmSnapshot == null) {
- throw new InvalidParameterValueException(
- "Unable to find the snapshot by id=" + getVmSnapShotId());
+ VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getVmSnapShotId());
+ if (vmSnapshot != null) {
+ return vmSnapshot.getAccountId();
}
- UserVm userVM = _userVmService.getUserVm(vmSnapshot.getVmId());
- return userVM.getAccountId();
+ return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException {
UserContext.current().setEventDetails(
"vmsnapshot id: " + getVmSnapShotId());
- UserVm result = _vmSnapshotService.revertToSnapshot(this);
+ UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId());
if (result != null) {
UserVmResponse response = _responseGenerator.createUserVmResponse(
"virtualmachine", result).get(0);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,"Failed to revert vm snapshot");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,"Failed to revert VM snapshot");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
index a5b7129..8dd63e0 100755
--- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -154,7 +154,6 @@ import com.cloud.utils.fsm.StateMachine2;
import com.cloud.vm.ItWorkVO.Step;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile.Param;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@@ -1162,6 +1161,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
@Override
public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException {
+ // if there are active vm snapshots task, state change is not allowed
+ if(_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())){
+ s_logger.error("State transit with event: " + e + " failed due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
+ return false;
+ }
+
State oldState = vm.getState();
if (oldState == State.Starting) {
if (e == Event.OperationSucceeded) {
@@ -1650,19 +1655,15 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
AgentVmInfo info = infos.remove(vm.getId());
// sync VM Snapshots related transient states
- List<VMSnapshotVO> expungingVMSnapshot = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging);
- if( vm.getState() == State.RevertingToRunning || vm.getState() == State.RevertingToStopped
- || vm.getState() == State.RunningSnapshotting || vm.getState() == State.StoppedSnapshotting
- || expungingVMSnapshot.size() == 1){
- s_logger.info("Found vm " + vm.getInstanceName() + " in state. " + vm.getState() + ", needs to sync VM snapshot state");
- if(!_vmSnapshotMgr.syncVMSnapshot(vm, null, hostId)){
+ List<VMSnapshotVO> vmSnapshotsInTrasientStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging,VMSnapshot.State.Reverting, VMSnapshot.State.Creating);
+ if(vmSnapshotsInTrasientStates.size() > 1){
+ s_logger.info("Found vm " + vm.getInstanceName() + " with VM snapshots in transient states, needs to sync VM snapshot state");
+ if(!_vmSnapshotMgr.syncVMSnapshot(vm, hostId)){
s_logger.warn("Failed to sync VM in a transient snapshot related state: " + vm.getInstanceName());
continue;
}else{
- s_logger.info("Successfully sync VM in a transient snapshot related state: " + vm.getInstanceName() + " to " + vm.getState());
+ s_logger.info("Successfully sync VM with transient snapshot: " + vm.getInstanceName());
}
- if(expungingVMSnapshot.size() == 1)
- _vmSnapshotMgr.syncVMSnapshot(vm, expungingVMSnapshot.get(0), hostId);
}
VMInstanceVO castedVm = null;
@@ -1784,29 +1785,25 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
VMInstanceVO castedVm = null;
// sync VM Snapshots related transient states
- List<VMSnapshotVO> expungingVMSnapshot = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging);
- if( vm.getState() == State.RevertingToRunning || vm.getState() == State.RevertingToStopped
- || vm.getState() == State.RunningSnapshotting || vm.getState() == State.StoppedSnapshotting
- || expungingVMSnapshot.size() == 1){
+ List<VMSnapshotVO> vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Creating,VMSnapshot.State.Reverting);
+ if(vmSnapshotsInExpungingStates.size() > 0){
s_logger.info("Found vm " + vm.getInstanceName() + " in state. " + vm.getState() + ", needs to sync VM snapshot state");
Long hostId = null;
+ Host host = null;
if(info != null && info.getHostUuid() != null){
- Host host = _hostDao.findByGuid(info.getHostUuid());
- hostId = host == null ? (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()) : host.getId();
+ host = _hostDao.findByGuid(info.getHostUuid());
}
- if(!_vmSnapshotMgr.syncVMSnapshot(vm, null, hostId)){
- s_logger.warn("Failed to sync VM in a transient snapshot related state: " + vm.getInstanceName());
+ hostId = host == null ? (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()) : host.getId();
+ if(!_vmSnapshotMgr.syncVMSnapshot(vm, hostId)){
+ s_logger.warn("Failed to sync VM with transient snapshot: " + vm.getInstanceName());
continue;
}else{
- s_logger.info("Successfully sync VM in a transient snapshot related state: " + vm.getInstanceName() + " to " + vm.getState());
+ s_logger.info("Successfully sync VM with transient snapshot: " + vm.getInstanceName());
}
- if(expungingVMSnapshot.size() == 1)
- _vmSnapshotMgr.syncVMSnapshot(vm, expungingVMSnapshot.get(0), hostId);
}
if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting ))
- || (info != null && (info.state == State.Running && vm.getState() == State.Starting))
- || (info != null && (info.state == State.Running && vm.getState() == State.RevertingToRunning)))
+ || (info != null && (info.state == State.Running && vm.getState() == State.Starting)))
{
s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + " on agent");
info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/server/src/com/cloud/vm/snapshot/VMSnapshotManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManager.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManager.java
index 77c3b69..c609005 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManager.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManager.java
@@ -33,14 +33,15 @@ public interface VMSnapshotManager extends VMSnapshotService, Manager {
boolean deleteAllVMSnapshots(long id, VMSnapshot.Type type);
/**
- * Sync VM's state when VM in reverting or snapshotting, or VM snapshot in expunging state
+ * Sync VM snapshot state when VM snapshot in reverting or snapshoting or expunging state
* Used for fullsync after agent connects
*
* @param vm, the VM in question
- * @param vmSnapshot, if this is not null, sync an VM snapshot in expunging state
* @param hostId
* @return true if succeeds, false if fails
*/
- boolean syncVMSnapshot(VMInstanceVO vm, VMSnapshotVO vmSnapshot, Long hostId);
+ boolean syncVMSnapshot(VMInstanceVO vm, Long hostId);
+
+ boolean hasActiveVMSnapshotTasks(Long vmId);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/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 49a4eec..7541e52 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@ -26,10 +26,7 @@ import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
-import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToSnapshotCmd;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@@ -59,7 +56,6 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
@@ -78,7 +74,6 @@ import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
@@ -121,7 +116,6 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
@Inject VirtualMachineManager _itMgr;
@Inject ConfigurationDao _configDao;
int _vmSnapshotMax;
- StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ;
@Override
@@ -133,11 +127,10 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
if (_configDao == null) {
throw new ConfigurationException("Unable to get the configuration dao.");
}
- s_logger.info("Snapshot Manager is configured.");
+ s_logger.info("VM Snapshot Manager is configured.");
_vmSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("vmsnapshot.max"), VMSNAPSHOTMAX);
- _stateMachine = VirtualMachine.State.getStateMachine();
_vmSnapshottateMachine = VMSnapshot.State.getStateMachine();
return true;
}
@@ -236,11 +229,8 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
}
@Override
- public VMSnapshot allocVMSnapshot(CreateVMSnapshotCmd cmd) throws ResourceAllocationException {
- Long vmId = cmd.getVmId();
- String vsDisplayName = cmd.getDisplayName();
- String vsDescription = cmd.getDescription();
- Boolean snapshotMemory = cmd.snapshotMemory();
+ public VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDescription, Boolean snapshotMemory)
+ throws ResourceAllocationException {
Account caller = getCaller();
@@ -250,6 +240,12 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
}
+ // 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");
+ if(vsDescription != null && vsDescription.length()>255)
+ throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDescription should not exceed 255");
+
// VM snapshot display name must be unique for a VM
String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
String vmSnapshotName = userVmVo.getInstanceName() + "_VS_" + timeString;
@@ -265,6 +261,10 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
throw new InvalidParameterValueException("Creating vm snapshot failed due to VM:" + vmId + " is not in the running or Stopped state");
}
+ if(snapshotMemory && userVmVo.getState() == VirtualMachine.State.Stopped){
+ throw new InvalidParameterValueException("Can not snapshot memory when VM is in stopped state");
+ }
+
// for KVM, only allow snapshot with memory when VM is in running state
if(userVmVo.getHypervisorType() == HypervisorType.KVM && userVmVo.getState() == State.Running && !snapshotMemory){
throw new InvalidParameterValueException("KVM VM does not allow to take a disk-only snapshot when VM is in running state");
@@ -291,7 +291,7 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
}
// check if there are other active VM snapshot tasks
- if (checkActiveVMSnapshotTasks(vmId)) {
+ if (hasActiveVMSnapshotTasks(vmId)) {
throw new CloudRuntimeException("There is other active vm snapshot tasks on the instance, please try again later");
}
@@ -320,13 +320,22 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
}
@Override
- @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_CREATE, eventDescription = "creating_vm_snapshot", async = true)
- public VMSnapshot creatVMSnapshot(CreateVMSnapshotCmd cmd) {
- Long vmId = cmd.getVmId();
+ @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_CREATE, eventDescription = "creating VM snapshot", async = true)
+ public VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId) {
UserVmVO userVm = _userVMDao.findById(vmId);
- VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(cmd.getEntityId());
+ if (userVm == null) {
+ throw new InvalidParameterValueException("Create vm to snapshot failed due to vm: " + vmId + " is not found");
+ }
+ VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
+ if(vmSnapshot == null){
+ throw new CloudRuntimeException("VM snapshot id: " + vmSnapshotId + " can not be found");
+ }
Long hostId = pickRunningHost(vmId);
- transitState(vmSnapshot, VMSnapshot.Event.CreateRequested, userVm, VirtualMachine.Event.SnapshotRequested, hostId);
+ try {
+ vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.CreateRequested);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException(e.getMessage());
+ }
return createVmSnapshotInternal(userVm, vmSnapshot, hostId);
}
@@ -355,15 +364,21 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
answer = (CreateVMSnapshotAnswer) sendToPool(hostId, ccmd);
if (answer != null && answer.getResult()) {
processAnswer(vmSnapshot, userVm, answer, hostId);
- transitState(vmSnapshot, VMSnapshot.Event.OperationSucceeded, userVm, VirtualMachine.Event.OperationSucceeded, hostId);
s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
}else{
String errMsg = answer.getDetails();
s_logger.error("Agent reports creating vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName() + " due to " + errMsg);
- transitState(vmSnapshot, VMSnapshot.Event.OperationFailed, userVm, VirtualMachine.Event.OperationFailed, hostId);
+ vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
}
return vmSnapshot;
} catch (Exception e) {
+ if(e instanceof AgentUnavailableException){
+ try {
+ vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
+ } catch (NoTransitionException e1) {
+ s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
+ }
+ }
String msg = e.getMessage();
s_logger.error("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName() + " due to " + msg);
throw new CloudRuntimeException(msg);
@@ -412,27 +427,11 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
vo.getCurrent(), null);
}
- private boolean vmSnapshotStateTransitTo(VMSnapshotVO vsnp, VMSnapshot.Event event) throws NoTransitionException {
+ protected boolean vmSnapshotStateTransitTo(VMSnapshotVO vsnp, VMSnapshot.Event event) throws NoTransitionException {
return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao);
}
@DB
- protected boolean transitState(VMSnapshotVO vsnp, VMSnapshot.Event e1, VMInstanceVO vm, VirtualMachine.Event e2, Long hostId){
- final Transaction txn = Transaction.currentTxn();
- try {
- txn.start();
- vmSnapshotStateTransitTo(vsnp, e1);
- vmStateTransitTo(vm, e2, hostId, null);
- return txn.commit();
- } catch (NoTransitionException e) {
- txn.rollback();
- return false;
- }finally{
- txn.close();
- }
- }
-
- @DB
protected void processAnswer(VMSnapshotVO vmSnapshot, UserVmVO userVm, Answer as, Long hostId) {
final Transaction txn = Transaction.currentTxn();
try {
@@ -440,9 +439,11 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
if (as instanceof CreateVMSnapshotAnswer) {
CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
finalizeCreate(vmSnapshot, answer.getVolumeTOs());
+ vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
} else if (as instanceof RevertToVMSnapshotAnswer) {
RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
finalizeRevert(vmSnapshot, answer.getVolumeTOs());
+ vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
} else if (as instanceof DeleteVMSnapshotAnswer) {
DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
finalizeDelete(vmSnapshot, answer.getVolumeTOs());
@@ -502,9 +503,11 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
// update current snapshot, current snapshot is the one reverted to
VMSnapshotVO previousCurrent = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
- previousCurrent.setCurrent(false);
+ if(previousCurrent != null){
+ previousCurrent.setCurrent(false);
+ _vmSnapshotDao.persist(previousCurrent);
+ }
vmSnapshot.setCurrent(true);
- _vmSnapshotDao.persist(previousCurrent);
_vmSnapshotDao.persist(vmSnapshot);
}
@@ -528,16 +531,16 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
return answer;
}
- private boolean checkActiveVMSnapshotTasks(Long vmId){
+ @Override
+ public boolean hasActiveVMSnapshotTasks(Long vmId){
List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(vmId,
VMSnapshot.State.Creating, VMSnapshot.State.Expunging,VMSnapshot.State.Reverting,VMSnapshot.State.Allocated);
return activeVMSnapshots.size() > 0;
}
@Override
- @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_DELETE, eventDescription = "delete_vm_snapshot", async=true)
- public boolean deleteVMSnapshot(DeleteVMSnapshotCmd cmd) {
- Long vmSnapshotId = cmd.getId();
+ @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_DELETE, eventDescription = "delete vm snapshots", async=true)
+ public boolean deleteVMSnapshot(Long vmSnapshotId) {
Account caller = getCaller();
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
@@ -548,13 +551,17 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
_accountMgr.checkAccess(caller, null, true, vmSnapshot);
// check VM snapshot states, only allow to delete vm snapshots in created and error state
- if (VMSnapshot.State.Ready != vmSnapshot.getState() && VMSnapshot.State.Error != vmSnapshot.getState()) {
- throw new InvalidParameterValueException("Can't delete the vm snapshotshot " + vmSnapshotId + " due to it is not in Created or Error State");
+ if (VMSnapshot.State.Ready != vmSnapshot.getState() && VMSnapshot.State.Expunging != vmSnapshot.getState() && VMSnapshot.State.Error != vmSnapshot.getState()) {
+ throw new InvalidParameterValueException("Can't delete the vm snapshotshot " + vmSnapshotId + " due to it is not in Created or Error, or Expunging State");
}
// check if there are other active VM snapshot tasks
- if (checkActiveVMSnapshotTasks(vmSnapshot.getVmId())) {
- throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
+ if (hasActiveVMSnapshotTasks(vmSnapshot.getVmId())) {
+ List<VMSnapshotVO> expungingSnapshots = _vmSnapshotDao.listByInstanceId(vmSnapshot.getVmId(), VMSnapshot.State.Expunging);
+ if(expungingSnapshots.size() > 0 && expungingSnapshots.get(0).getId() == vmSnapshot.getId())
+ s_logger.debug("Target VM snapshot already in expunging state, go on deleting it: " + vmSnapshot.getDisplayName());
+ else
+ throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
}
if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
@@ -587,6 +594,7 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
if (answer != null && answer.getResult()) {
processAnswer(vmSnapshot, userVm, answer, hostId);
+ s_logger.debug("Delete VM snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
return true;
} else {
s_logger.error("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + answer.getDetails());
@@ -600,11 +608,9 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
}
@Override
- @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_REVERT, eventDescription = "revert_vm", async = true)
- public UserVm revertToSnapshot(RevertToSnapshotCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
+ @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_REVERT, eventDescription = "revert to VM snapshot", async = true)
+ public UserVm revertToSnapshot(Long vmSnapshotId) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
- Long vmSnapshotId = cmd.getVmSnapShotId();
-
// check if VM snapshot exists in DB
VMSnapshotVO vmSnapshotVo = _vmSnapshotDao.findById(vmSnapshotId);
if (vmSnapshotVo == null) {
@@ -621,7 +627,7 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
}
// check if there are other active VM snapshot tasks
- if (checkActiveVMSnapshotTasks(vmId)) {
+ if (hasActiveVMSnapshotTasks(vmId)) {
throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
}
@@ -672,19 +678,21 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
throw new CloudRuntimeException("Can not find any host to revert snapshot " + vmSnapshotVo.getName());
// check if there are other active VM snapshot tasks
- if (checkActiveVMSnapshotTasks(userVm.getId())) {
+ if (hasActiveVMSnapshotTasks(userVm.getId())) {
throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
}
userVm = _userVMDao.findById(userVm.getId());
- transitState(vmSnapshotVo, VMSnapshot.Event.RevertRequested, userVm, VirtualMachine.Event.RevertRequested, hostId);
+ try {
+ vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.RevertRequested);
+ } catch (NoTransitionException e) {
+ throw new CloudRuntimeException(e.getMessage());
+ }
return revertInternal(userVm, vmSnapshotVo, hostId);
}
private UserVm revertInternal(UserVmVO userVm, VMSnapshotVO vmSnapshotVo, Long hostId) {
-
try {
-
VMSnapshotVO snapshot = _vmSnapshotDao.findById(vmSnapshotVo.getId());
// prepare RevertToSnapshotCommand
List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
@@ -697,20 +705,27 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) sendToPool(hostId, revertToSnapshotCommand);
- if (answer.getResult()) {
+ if (answer != null && answer.getResult()) {
processAnswer(vmSnapshotVo, userVm, answer, hostId);
- transitState(vmSnapshotVo, VMSnapshot.Event.OperationSucceeded, userVm, VirtualMachine.Event.OperationSucceeded, hostId);
+ s_logger.debug("RevertTo " + vmSnapshotVo.getName() + " succeeded for vm: " + userVm.getInstanceName());
} else {
String errMsg = "Revert VM: " + userVm.getInstanceName() + " to snapshot: "+ vmSnapshotVo.getName() + " failed";
if(answer != null && answer.getDetails() != null)
errMsg = errMsg + " due to " + answer.getDetails();
s_logger.error(errMsg);
// agent report revert operation fails
- transitState(vmSnapshotVo, VMSnapshot.Event.OperationFailed, userVm, VirtualMachine.Event.OperationFailed, hostId);
+ vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
throw new CloudRuntimeException(errMsg);
}
} catch (Exception e) {
- // for other exceptions, do not change VM state, leave it for snapshotSync
+ if(e instanceof AgentUnavailableException){
+ try {
+ vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
+ } catch (NoTransitionException e1) {
+ s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
+ }
+ }
+ // for other exceptions, do not change VM snapshot state, leave it for snapshotSync
String errMsg = "revert vm: " + userVm.getInstanceName() + " to snapshot " + vmSnapshotVo.getName() + " failed due to " + e.getMessage();
s_logger.error(errMsg);
throw new CloudRuntimeException(e.getMessage());
@@ -718,18 +733,14 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
return userVm;
}
- private boolean vmStateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) throws NoTransitionException {
- vm.setReservationId(reservationId);
- return _stateMachine.transitTo(vm, e, new Pair<Long, Long>(vm.getHostId(), hostId), _vmInstanceDao);
- }
@Override
- public VMSnapshot getVMSnapshotById(long id) {
+ public VMSnapshot getVMSnapshotById(Long id) {
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
return vmSnapshot;
}
- private Long pickRunningHost(Long vmId) {
+ protected Long pickRunningHost(Long vmId) {
UserVmVO vm = _userVMDao.findById(vmId);
// use VM's host if VM is running
if(vm.getState() == State.Running)
@@ -766,6 +777,9 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
@Override
public VirtualMachine getVMBySnapshotId(Long id) {
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
+ if(vmSnapshot == null){
+ throw new InvalidParameterValueException("unable to find the vm snapshot with id " + id);
+ }
Long vmId = vmSnapshot.getVmId();
UserVmVO vm = _userVMDao.findById(vmId);
return vm;
@@ -790,37 +804,29 @@ public class VMSnapshotManagerImpl implements VMSnapshotManager, VMSnapshotServi
}
@Override
- public boolean syncVMSnapshot(VMInstanceVO vm, VMSnapshotVO vmSnapshot, Long hostId) {
+ public boolean syncVMSnapshot(VMInstanceVO vm, Long hostId) {
try{
UserVmVO userVm = _userVMDao.findById(vm.getId());
if(userVm == null)
return false;
- if(userVm.getState() == State.RevertingToRunning || userVm.getState() == State.RevertingToStopped){
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), VMSnapshot.State.Reverting);
- if(vmSnapshots.size() != 1){
- s_logger.error("VM:" + userVm.getInstanceName()+ " expected to have one VM snapshot in reverting state but actually has " + vmSnapshots.size());
- return false;
- }
- // send revert command again
- revertInternal(userVm, vmSnapshots.get(0), hostId);
- return true;
- }else if (userVm.getState() == State.RunningSnapshotting || userVm.getState() == State.StoppedSnapshotting){
- List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), VMSnapshot.State.Creating);
- if(vmSnapshots.size() != 1){
- s_logger.error("VM:" + userVm.getInstanceName()+ " expected to have one VM snapshot in creating state but actually has " + vmSnapshots.size());
- return false;
+
+ List<VMSnapshotVO> vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, VMSnapshot.State.Creating);
+ for (VMSnapshotVO vmSnapshotVO : vmSnapshotsInExpungingStates) {
+ if(vmSnapshotVO.getState() == VMSnapshot.State.Expunging){
+ return deleteSnapshotInternal(vmSnapshotVO);
+ }else if(vmSnapshotVO.getState() == VMSnapshot.State.Creating){
+ return createVmSnapshotInternal(userVm, vmSnapshotVO, hostId) != null;
+ }else if(vmSnapshotVO.getState() == VMSnapshot.State.Reverting){
+ return revertInternal(userVm, vmSnapshotVO, hostId) != null;
}
- // send create vm snapshot command again
- createVmSnapshotInternal(userVm, vmSnapshots.get(0), hostId);
- return true;
-
- }else if (vmSnapshot != null && vmSnapshot.getState() == VMSnapshot.State.Expunging){
- return deleteSnapshotInternal(vmSnapshot);
}
}catch (Exception e) {
s_logger.error(e.getMessage(),e);
- return false;
+ if(_vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging).size() == 0)
+ return true;
+ else
+ return false;
}
return false;
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/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 fe49207..a97e9b9 100644
--- a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
+++ b/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
@@ -16,17 +16,27 @@
// under the License.
package com.cloud.vm.snapshot;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import java.util.ArrayList;
import java.util.List;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateVMSnapshotAnswer;
import com.cloud.agent.api.CreateVMSnapshotCommand;
import com.cloud.agent.api.to.VolumeTO;
@@ -49,25 +59,15 @@ import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
-import com.cloud.uservm.UserVm;
import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-import org.junit.Before;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
public class VMSnapshotManagerTest {
@@ -90,8 +90,6 @@ public class VMSnapshotManagerTest {
@Mock ConfigurationDao _configDao;
int _vmSnapshotMax = 10;
- @Mock CreateVMSnapshotCmd createCmd;
-
private static long TEST_VM_ID = 3L;
@Mock UserVmVO vmMock;
@Mock VolumeVO volumeMock;
@@ -113,9 +111,6 @@ public class VMSnapshotManagerTest {
_vmSnapshotMgr._vmSnapshotMax = _vmSnapshotMax;
- when(createCmd.getVmId()).thenReturn(TEST_VM_ID);
- when(createCmd.getDisplayName()).thenReturn("testName");
-
when(_userVMDao.findById(anyLong())).thenReturn(vmMock);
when(_vmSnapshotDao.findByName(anyLong(), anyString())).thenReturn(null);
when(_vmSnapshotDao.findByVm(anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
@@ -135,48 +130,57 @@ public class VMSnapshotManagerTest {
@Test(expected=InvalidParameterValueException.class)
public void testAllocVMSnapshotF1() throws ResourceAllocationException{
when(_userVMDao.findById(TEST_VM_ID)).thenReturn(null);
- _vmSnapshotMgr.allocVMSnapshot(createCmd);
+ _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
}
// vm state not in [running, stopped] case
@Test(expected=InvalidParameterValueException.class)
public void testAllocVMSnapshotF2() throws ResourceAllocationException{
when(vmMock.getState()).thenReturn(State.Starting);
- _vmSnapshotMgr.allocVMSnapshot(createCmd);
+ _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
+ }
+
+ // VM in stopped state & snapshotmemory case
+ @Test(expected=InvalidParameterValueException.class)
+ public void testCreateVMSnapshotF3() throws AgentUnavailableException, OperationTimedoutException, ResourceAllocationException{
+ when(vmMock.getState()).thenReturn(State.Stopped);
+ _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
}
// max snapshot limit case
@SuppressWarnings("unchecked")
@Test(expected=CloudRuntimeException.class)
- public void testAllocVMSnapshotF3() throws ResourceAllocationException{
+ public void testAllocVMSnapshotF4() throws ResourceAllocationException{
List<VMSnapshotVO> mockList = mock(List.class);
when(mockList.size()).thenReturn(10);
when(_vmSnapshotDao.findByVm(TEST_VM_ID)).thenReturn(mockList);
- _vmSnapshotMgr.allocVMSnapshot(createCmd);
+ _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
}
// active volume snapshots case
@SuppressWarnings("unchecked")
@Test(expected=CloudRuntimeException.class)
- public void testAllocVMSnapshotF4() throws ResourceAllocationException{
+ public void testAllocVMSnapshotF5() throws ResourceAllocationException{
List<SnapshotVO> mockList = mock(List.class);
when(mockList.size()).thenReturn(1);
when(_snapshotDao.listByInstanceId(TEST_VM_ID,Snapshot.Status.Creating,
Snapshot.Status.CreatedOnPrimary, Snapshot.Status.BackingUp)).thenReturn(mockList);
- _vmSnapshotMgr.allocVMSnapshot(createCmd);
+ _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
}
+ // successful creation case
@Test
- public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException{
+ public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException, ResourceAllocationException, NoTransitionException{
+ when(vmMock.getState()).thenReturn(State.Running);
+ _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
+
when(_vmSnapshotDao.findCurrentSnapshotByVmId(anyLong())).thenReturn(null);
doReturn(new ArrayList<VolumeTO>()).when(_vmSnapshotMgr).getVolumeTOList(anyLong());
doReturn(new CreateVMSnapshotAnswer(null,true,"")).when(_vmSnapshotMgr).sendToPool(anyLong(), any(CreateVMSnapshotCommand.class));
- doReturn(true).when(_vmSnapshotMgr).transitState(any(VMSnapshotVO.class),
- any(VMSnapshot.Event.class), any(VMInstanceVO.class), any(VirtualMachine.Event.class), anyLong());
doNothing().when(_vmSnapshotMgr).processAnswer(any(VMSnapshotVO.class),
any(UserVmVO.class), any(Answer.class), anyLong());
+ doReturn(true).when(_vmSnapshotMgr).vmSnapshotStateTransitTo(any(VMSnapshotVO.class),any(VMSnapshot.Event.class));
_vmSnapshotMgr.createVmSnapshotInternal(vmMock, mock(VMSnapshotVO.class), 5L);
-
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ebca6890/ui/scripts/instances.js
----------------------------------------------------------------------
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index d9542a1..264b5a1 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -49,14 +49,6 @@
zonename: { label: 'label.zone.name' },
state: {
label: 'label.state',
- converter: function(data) {
- if(data == 'StoppedSnapshotting' || data == 'RunningSnapshotting')
- return 'Snapshotting';
- if(data == 'RevertingToRunning' || data == 'RevertingToStopped'){
- return 'Reverting';
- }
- return data;
- },
indicator: {
'Running': 'on',
'Stopped': 'off',