cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mc...@apache.org
Subject [13/50] [abbrv] git commit: updated refs/heads/object_store_migration to 5ec2a44
Date Tue, 29 Oct 2013 03:53:03 GMT
Merge branch 'pluggable_vm_snapshot'

Conflicts:
	client/tomcatconf/applicationContext.xml.in
	engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
	engine/storage/integration-test/test/resources/storageContext.xml
	server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
	server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java


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

Branch: refs/heads/object_store_migration
Commit: 51a8086cf6d1cdf7db3f89468e210020a179a57c
Parents: 56f1277 a6ce66e
Author: Edison Su <sudison@gmail.com>
Authored: Fri Oct 25 16:47:17 2013 -0700
Committer: Edison Su <sudison@gmail.com>
Committed: Fri Oct 25 16:47:17 2013 -0700

----------------------------------------------------------------------
 .../cloud/agent/api/CreateVMSnapshotAnswer.java |  12 +-
 .../agent/api/CreateVMSnapshotCommand.java      |   4 +-
 .../cloud/agent/api/DeleteVMSnapshotAnswer.java |  12 +-
 .../agent/api/DeleteVMSnapshotCommand.java      |   3 +-
 .../agent/api/RevertToVMSnapshotAnswer.java     |  14 +-
 .../agent/api/RevertToVMSnapshotCommand.java    |   3 +-
 .../cloud/agent/api/VMSnapshotBaseCommand.java  |  10 +-
 .../cloudstack/storage/to/VolumeObjectTO.java   |  12 +
 .../api/storage/VMSnapshotStrategy.java         |  28 ++
 .../cloud/vm/snapshot/VMSnapshotDetailsVO.java  |  87 ++++
 .../src/com/cloud/vm/snapshot/VMSnapshotVO.java |   2 +-
 .../vm/snapshot/dao/VMSnapshotDetailsDao.java   |  28 ++
 .../snapshot/dao/VMSnapshotDetailsDaoImpl.java  |  52 +++
 .../motion/AncientDataMotionStrategy.java       |  26 --
 .../vm/snapshot/dao/VmSnapshotDaoTest.java      |  46 ++
 .../storage/test/ChildTestConfiguration.java    |  47 +-
 .../cloudstack/storage/test/SnapshotTest.java   |  89 ++--
 .../test/resources/storageContext.xml           |   5 +
 engine/storage/snapshot/pom.xml                 |  32 ++
 .../storage/snapshot/SnapshotServiceImpl.java   |  44 +-
 .../snapshot/XenserverSnapshotStrategy.java     |  27 +-
 .../vmsnapshot/DefaultVMSnapshotStrategy.java   | 370 +++++++++++++++
 .../storage/vmsnapshot/VMSnapshotHelper.java    |  38 ++
 .../vmsnapshot/VMSnapshotHelperImpl.java        | 148 ++++++
 .../test/src/VMSnapshotStrategyTest.java        | 256 +++++++++++
 .../storage/volume/VolumeServiceImpl.java       |  85 ++--
 .../manager/VmwareStorageManagerImpl.java       |  87 ++--
 .../xen/resource/CitrixResourceBase.java        |  28 +-
 .../storage/snapshot/SnapshotManagerImpl.java   |  93 ----
 .../vm/snapshot/VMSnapshotManagerImpl.java      | 455 +++----------------
 .../vm/snapshot/VMSnapshotManagerTest.java      |   7 -
 setup/db/db/schema-421to430.sql                 |   9 +
 32 files changed, 1390 insertions(+), 769 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
----------------------------------------------------------------------
diff --cc engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
index 1407707,36bc912..550a6bf
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
@@@ -406,10 -399,13 +403,11 @@@ public class SnapshotTest extends Cloud
          SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
          boolean result = false;
  
 -        StrategyPriority.sortStrategies(snapshotStrategies, snapshot);
+ 
 -        for (SnapshotStrategy strategy : this.snapshotStrategies) {
 -            if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
 -                snapshot = strategy.takeSnapshot(snapshot);
 -                result = true;
 -            }
 +        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot,
SnapshotOperation.TAKE);
 +        if (snapshotStrategy != null) {
 +            snapshot = snapshotStrategy.takeSnapshot(snapshot);
 +            result = true;
          }
  
          AssertJUnit.assertTrue(result);
@@@ -428,9 -424,12 +426,11 @@@
          SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
          SnapshotInfo newSnapshot = null;
  
 -        StrategyPriority.sortStrategies(snapshotStrategies, newSnapshot);
+ 
 -        for (SnapshotStrategy strategy : this.snapshotStrategies) {
 -            if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
 -                newSnapshot = strategy.takeSnapshot(snapshot);
 -            }
 +        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot,
SnapshotOperation.TAKE);
 +        if (snapshotStrategy != null) {
 +            newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
++
          }
          AssertJUnit.assertNotNull(newSnapshot);
  
@@@ -480,11 -482,13 +480,12 @@@
          SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
          SnapshotInfo newSnapshot = null;
  
 -        StrategyPriority.sortStrategies(snapshotStrategies, newSnapshot);
+ 
 -        for (SnapshotStrategy strategy : this.snapshotStrategies) {
 -            if (strategy.canHandle(snapshot) != StrategyPriority.Priority.CANT_HANDLE) {
 -                newSnapshot = strategy.takeSnapshot(snapshot);
 -            }
 +        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot,
SnapshotOperation.TAKE);
 +        if (snapshotStrategy != null) {
 +            newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
          }
 +
          AssertJUnit.assertNotNull(newSnapshot);
  
          LocalHostEndpoint ep = new MockLocalHostEndPoint();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/integration-test/test/resources/storageContext.xml
----------------------------------------------------------------------
diff --cc engine/storage/integration-test/test/resources/storageContext.xml
index e4b8274,884e813..0dcd6a8
--- a/engine/storage/integration-test/test/resources/storageContext.xml
+++ b/engine/storage/integration-test/test/resources/storageContext.xml
@@@ -85,5 -85,6 +85,10 @@@
    <bean id="AccountGuestVlanMapDaoImpl" class="com.cloud.network.dao.AccountGuestVlanMapDaoImpl"
/>
    <bean id="StorageCacheReplacementAlgorithm" class="org.apache.cloudstack.storage.cache.manager.StorageCacheReplacementAlgorithmLRU"
/>
    <bean id="ServiceOfferingDetailsDao" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl"
/>
++<<<<<<< HEAD
 +  <bean id="storageStrategyFactoryImpl" class="org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl"
/>
++=======
+   <bean id="vmsnapshotDetailsDao" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl"
/>
+   <bean id="snapshotManager" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
++>>>>>>> pluggable_vm_snapshot
  </beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
----------------------------------------------------------------------
diff --cc engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
index 0000000,6b5e5fb..0ef8ebb
mode 000000,100644..100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
@@@ -1,0 -1,369 +1,370 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *   http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied.  See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  */
+ package org.apache.cloudstack.storage.vmsnapshot;
+ 
+ import java.util.List;
+ import java.util.Map;
+ 
+ import javax.inject.Inject;
+ import javax.naming.ConfigurationException;
+ 
+ import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
+ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+ import org.apache.cloudstack.storage.to.VolumeObjectTO;
+ import org.apache.log4j.Logger;
+ 
+ import com.cloud.agent.AgentManager;
+ import com.cloud.agent.api.Answer;
+ import com.cloud.agent.api.CreateVMSnapshotAnswer;
+ import com.cloud.agent.api.CreateVMSnapshotCommand;
+ import com.cloud.agent.api.DeleteVMSnapshotAnswer;
+ import com.cloud.agent.api.DeleteVMSnapshotCommand;
+ import com.cloud.agent.api.RevertToVMSnapshotAnswer;
+ import com.cloud.agent.api.RevertToVMSnapshotCommand;
+ import com.cloud.agent.api.VMSnapshotTO;
+ import com.cloud.event.EventTypes;
+ import com.cloud.event.UsageEventUtils;
+ import com.cloud.exception.AgentUnavailableException;
+ import com.cloud.exception.OperationTimedoutException;
+ import com.cloud.storage.DiskOfferingVO;
+ import com.cloud.storage.GuestOSVO;
+ import com.cloud.storage.VolumeVO;
+ import com.cloud.storage.dao.DiskOfferingDao;
+ import com.cloud.storage.dao.GuestOSDao;
+ import com.cloud.storage.dao.VolumeDao;
+ import com.cloud.uservm.UserVm;
+ import com.cloud.utils.NumbersUtil;
+ import com.cloud.utils.component.ManagerBase;
+ import com.cloud.utils.db.DB;
+ import com.cloud.utils.db.Transaction;
++import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
++import com.cloud.utils.db.TransactionStatus;
+ import com.cloud.utils.exception.CloudRuntimeException;
+ import com.cloud.utils.fsm.NoTransitionException;
+ import com.cloud.vm.UserVmVO;
+ import com.cloud.vm.dao.UserVmDao;
+ import com.cloud.vm.snapshot.VMSnapshot;
+ import com.cloud.vm.snapshot.VMSnapshotVO;
+ import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+ 
+ public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshotStrategy
{
+     private static final Logger s_logger = Logger.getLogger(DefaultVMSnapshotStrategy.class);
+     @Inject
+     VMSnapshotHelper vmSnapshotHelper;
+     @Inject
+     GuestOSDao guestOSDao;
+     @Inject
+     UserVmDao userVmDao;
+     @Inject
+     VMSnapshotDao vmSnapshotDao;
+     int _wait;
+     @Inject
+     ConfigurationDao configurationDao;
+     @Inject
+     AgentManager agentMgr;
+     @Inject
+     VolumeDao volumeDao;
+     @Inject
+     DiskOfferingDao diskOfferingDao;
+     @Override
+     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException
{
+         String value = configurationDao.getValue("vmsnapshot.create.wait");
+         _wait = NumbersUtil.parseInt(value, 1800);
+         return true;
+     }
+ 
+     public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
+         Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId());
+         UserVm userVm = userVmDao.findById(vmSnapshot.getVmId());
+         VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot;
+         try {
+             vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.CreateRequested);
+         } catch (NoTransitionException e) {
+             throw new CloudRuntimeException(e.getMessage());
+         }
+ 
+         CreateVMSnapshotAnswer answer = null;
+         boolean result = false;
+         try {
+             GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId());
+ 
+             List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId());
+ 
+             VMSnapshotTO current = null;
+             VMSnapshotVO currentSnapshot = vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
+             if (currentSnapshot != null)
+                 current = vmSnapshotHelper.getSnapshotWithParents(currentSnapshot);
+             VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(),  vmSnapshot.getName(),
vmSnapshot.getType(), null, vmSnapshot.getDescription(), false,
+                     current);
+             if (current == null)
+                 vmSnapshotVO.setParent(null);
+             else
+                 vmSnapshotVO.setParent(current.getId());
+ 
+             CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target
,volumeTOs, guestOS.getDisplayName(),userVm.getState());
+             ccmd.setWait(_wait);
+ 
+             answer = (CreateVMSnapshotAnswer)agentMgr.send(hostId, ccmd);
+             if (answer != null && answer.getResult()) {
+                 processAnswer(vmSnapshotVO, userVm, answer, hostId);
+                 s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded
for vm: " + userVm.getInstanceName());
+                 result = true;
+ 
+                 for (VolumeObjectTO volumeTo : answer.getVolumeTOs()){
+                     publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE,vmSnapshot,userVm,volumeTo);
+                 }
+                 return vmSnapshot;
+             } else {
+                 String errMsg = "Creating VM snapshot: " + vmSnapshot.getName() + " failed";
+                 if(answer != null && answer.getDetails() != null)
+                     errMsg = errMsg + " due to " + answer.getDetails();
+                 s_logger.error(errMsg);
+                 throw new CloudRuntimeException(errMsg);
+             }
+         } catch (OperationTimedoutException e) {
+             s_logger.debug("Creating VM snapshot: " + vmSnapshot.getName() + " failed: "
+ e.toString());
+             throw new CloudRuntimeException("Creating VM snapshot: " + vmSnapshot.getName()
+ " failed: " + e.toString());
+         } catch (AgentUnavailableException e) {
+             s_logger.debug("Creating VM snapshot: " + vmSnapshot.getName() + " failed",
e);
+             throw new CloudRuntimeException("Creating VM snapshot: " + vmSnapshot.getName()
+ " failed: " + e.toString());
+         } finally{
+             if (!result) {
+                 try {
+                     vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
+                 } catch (NoTransitionException e1) {
+                     s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
+                 }
+             }
+         }
+     }
+ 
+     @Override
+     public boolean deleteVMSnapshot(VMSnapshot vmSnapshot) {
+         UserVmVO userVm = userVmDao.findById(vmSnapshot.getVmId());
+         VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot;
+         try {
+             vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested);
+         } catch (NoTransitionException e) {
+             s_logger.debug("Failed to change vm snapshot state with event ExpungeRequested");
+             throw new CloudRuntimeException("Failed to change vm snapshot state with event
ExpungeRequested: " + e.getMessage());
+         }
+ 
+         try {
+             Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId());
+ 
+             List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(vmSnapshot.getVmId());
+ 
+             String vmInstanceName = userVm.getInstanceName();
+             VMSnapshotTO parent = vmSnapshotHelper.getSnapshotWithParents(vmSnapshotVO).getParent();
+             VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(),
vmSnapshot.getType(),
+                     vmSnapshot.getCreated().getTime(), vmSnapshot.getDescription(), vmSnapshot.getCurrent(),
parent);
+             GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId());
+             DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(vmInstanceName,
vmSnapshotTO, volumeTOs,guestOS.getDisplayName());
+ 
+             Answer answer = agentMgr.send(hostId, deleteSnapshotCommand);
+ 
+             if (answer != null && answer.getResult()) {
+                 DeleteVMSnapshotAnswer deleteVMSnapshotAnswer = (DeleteVMSnapshotAnswer)answer;
+                 processAnswer(vmSnapshotVO, userVm, answer, hostId);
+                 for (VolumeObjectTO volumeTo : deleteVMSnapshotAnswer.getVolumeTOs()){
+                     publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_DELETE,vmSnapshot,userVm,volumeTo);
+                 }
+                 return true;
+             } else {
+                 String errMsg = (answer == null) ? null : answer.getDetails();
+                 s_logger.error("Delete vm snapshot " + vmSnapshot.getName() + " of vm "
+ userVm.getInstanceName() + " failed due to " + errMsg);
+                 throw new  CloudRuntimeException("Delete vm snapshot " + vmSnapshot.getName()
+ " of vm " + userVm.getInstanceName() + " failed due to " + errMsg);
+             }
+         } catch (OperationTimedoutException e) {
+             throw new CloudRuntimeException("Delete vm snapshot " + vmSnapshot.getName()
+ " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage());
+         } catch (AgentUnavailableException e) {
+             throw new CloudRuntimeException("Delete vm snapshot " + vmSnapshot.getName()
+ " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage());
+         }
+     }
+ 
+     @DB
 -    protected void processAnswer(VMSnapshotVO vmSnapshot, UserVm userVm, Answer as, Long
hostId) {
 -        final Transaction txn = Transaction.currentTxn();
++    protected void processAnswer(final VMSnapshotVO vmSnapshot, UserVm userVm, final Answer
as, Long hostId) {
+         try {
 -            txn.start();
 -            if (as instanceof CreateVMSnapshotAnswer) {
 -                CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
 -                finalizeCreate(vmSnapshot, answer.getVolumeTOs());
 -                vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
 -            } else if (as instanceof RevertToVMSnapshotAnswer) {
 -                RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
 -                finalizeRevert(vmSnapshot, answer.getVolumeTOs());
 -                vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
 -            } else if (as instanceof DeleteVMSnapshotAnswer) {
 -                DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
 -                finalizeDelete(vmSnapshot, answer.getVolumeTOs());
 -                vmSnapshotDao.remove(vmSnapshot.getId());
 -            }
 -            txn.commit();
++            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<NoTransitionException>()
{
++                @Override
++                public void doInTransactionWithoutResult(TransactionStatus status) throws
NoTransitionException {
++                    if (as instanceof CreateVMSnapshotAnswer) {
++                        CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
++                        finalizeCreate(vmSnapshot, answer.getVolumeTOs());
++                        vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
++                    } else if (as instanceof RevertToVMSnapshotAnswer) {
++                        RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
++                        finalizeRevert(vmSnapshot, answer.getVolumeTOs());
++                        vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
++                    } else if (as instanceof DeleteVMSnapshotAnswer) {
++                        DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
++                        finalizeDelete(vmSnapshot, answer.getVolumeTOs());
++                        vmSnapshotDao.remove(vmSnapshot.getId());
++                    }
++                }
++            });
+         } catch (Exception e) {
+             String errMsg = "Error while process answer: " + as.getClass() + " due to "
+ e.getMessage();
+             s_logger.error(errMsg, e);
 -            txn.rollback();
+             throw new CloudRuntimeException(errMsg);
 -        } finally {
 -            txn.close();
+         }
+     }
+ 
+     protected void finalizeDelete(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> VolumeTOs)
{
+         // update volumes path
+         updateVolumePath(VolumeTOs);
+ 
+         // update children's parent snapshots
+         List<VMSnapshotVO> children= vmSnapshotDao.listByParent(vmSnapshot.getId());
+         for (VMSnapshotVO child : children) {
+             child.setParent(vmSnapshot.getParent());
+             vmSnapshotDao.persist(child);
+         }
+ 
+         // update current snapshot
+         VMSnapshotVO current = vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
+         if(current != null && current.getId() == vmSnapshot.getId() && vmSnapshot.getParent()
!= null){
+             VMSnapshotVO parent = vmSnapshotDao.findById(vmSnapshot.getParent());
+             parent.setCurrent(true);
+             vmSnapshotDao.persist(parent);
+         }
+         vmSnapshot.setCurrent(false);
+         vmSnapshotDao.persist(vmSnapshot);
+     }
+ 
+     protected void finalizeCreate(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> VolumeTOs)
{
+         // update volumes path
+         updateVolumePath(VolumeTOs);
+ 
+         vmSnapshot.setCurrent(true);
+ 
+         // change current snapshot
+         if (vmSnapshot.getParent() != null) {
+             VMSnapshotVO previousCurrent = vmSnapshotDao.findById(vmSnapshot.getParent());
+             previousCurrent.setCurrent(false);
+             vmSnapshotDao.persist(previousCurrent);
+         }
+         vmSnapshotDao.persist(vmSnapshot);
+     }
+ 
+     protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> volumeToList)
{
+         // update volumes path
+         updateVolumePath(volumeToList);
+ 
+         // update current snapshot, current snapshot is the one reverted to
+         VMSnapshotVO previousCurrent = vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
+         if(previousCurrent != null){
+             previousCurrent.setCurrent(false);
+             vmSnapshotDao.persist(previousCurrent);
+         }
+         vmSnapshot.setCurrent(true);
+         vmSnapshotDao.persist(vmSnapshot);
+     }
+ 
+     private void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
+         for (VolumeObjectTO volume : volumeTOs) {
+             if (volume.getPath() != null) {
+                 VolumeVO volumeVO = volumeDao.findById(volume.getId());
+                 volumeVO.setPath(volume.getPath());
+                 volumeVO.setVmSnapshotChainSize(volume.getSize());
+                 volumeDao.persist(volumeVO);
+             }
+         }
+     }
+ 
+     private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeObjectTO
volumeTo){
+         VolumeVO volume = volumeDao.findById(volumeTo.getId());
+         Long diskOfferingId = volume.getDiskOfferingId();
+         Long offeringId = null;
+         if (diskOfferingId != null) {
+             DiskOfferingVO offering = diskOfferingDao.findById(diskOfferingId);
+             if (offering != null
+                     && (offering.getType() == DiskOfferingVO.Type.Disk)) {
+                 offeringId = offering.getId();
+             }
+         }
+         UsageEventUtils.publishUsageEvent(
+                 type,
+                 vmSnapshot.getAccountId(),
+                 userVm.getDataCenterId(),
+                 userVm.getId(),
+                 vmSnapshot.getName(),
+                 offeringId,
+                 volume.getId(), // save volume's id into templateId field
+                 volumeTo.getSize(),
+                 VMSnapshot.class.getName(), vmSnapshot.getUuid());
+     }
+ 
+     @Override
+     public boolean revertVMSnapshot(VMSnapshot vmSnapshot) {
+         VMSnapshotVO vmSnapshotVO = (VMSnapshotVO)vmSnapshot;
+         UserVmVO userVm = userVmDao.findById(vmSnapshot.getVmId());
+         try {
+             vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.RevertRequested);
+         } catch (NoTransitionException e) {
+             throw new CloudRuntimeException(e.getMessage());
+         }
+ 
+         boolean result = false;
+         try {
+             VMSnapshotVO snapshot = vmSnapshotDao.findById(vmSnapshotVO.getId());
+             List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId());
+             String vmInstanceName = userVm.getInstanceName();
+             VMSnapshotTO parent = vmSnapshotHelper.getSnapshotWithParents(snapshot).getParent();
+ 
+             VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(snapshot.getId(), snapshot.getName(),
snapshot.getType(),
+                     snapshot.getCreated().getTime(), snapshot.getDescription(), snapshot.getCurrent(),
parent);
+             Long hostId = vmSnapshotHelper.pickRunningHost(vmSnapshot.getVmId());
+             GuestOSVO guestOS = guestOSDao.findById(userVm.getGuestOSId());
+             RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName,
vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
+ 
+             RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) agentMgr.send(hostId,
revertToSnapshotCommand);
+             if (answer != null && answer.getResult()) {
+                 processAnswer(vmSnapshotVO, userVm, answer, hostId);
+                 result = true;
+             } 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);
+                 throw new CloudRuntimeException(errMsg);
+             }
+         } catch (OperationTimedoutException e) {
+             s_logger.debug("Failed to revert vm snapshot", e);
+             throw new CloudRuntimeException(e.getMessage());
+         } catch (AgentUnavailableException e) {
+             s_logger.debug("Failed to revert vm snapshot", e);
+             throw new CloudRuntimeException(e.getMessage());
+         } finally {
+             if (!result) {
+                 try {
+                     vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
+                 } catch (NoTransitionException e1) {
+                     s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
+                 }
+             }
+         }
+         return result;
+     }
+ 
+     @Override
+     public boolean canHandle(VMSnapshot vmSnapshot) {
+         return true;
+     }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
index cd064f5,7a200ff..3f473bd
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@@ -17,40 -17,8 +17,39 @@@
  
  package com.cloud.vm.snapshot;
  
 +import java.util.ArrayList;
 +import java.util.Date;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +
 +import javax.ejb.Local;
 +import javax.inject.Inject;
 +import javax.naming.ConfigurationException;
 +
 +import org.apache.log4j.Logger;
 +import org.springframework.stereotype.Component;
 +import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
 +import org.apache.cloudstack.context.CallContext;
 +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 +import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 +
 +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.DeleteVMSnapshotAnswer;
 +import com.cloud.agent.api.DeleteVMSnapshotCommand;
 +import com.cloud.agent.api.RevertToVMSnapshotAnswer;
 +import com.cloud.agent.api.RevertToVMSnapshotCommand;
 +import com.cloud.agent.api.VMSnapshotTO;
 +import com.cloud.agent.api.to.VolumeTO;
++
  import com.cloud.event.ActionEvent;
  import com.cloud.event.EventTypes;
- import com.cloud.event.UsageEventUtils;
- import com.cloud.exception.AgentUnavailableException;
  import com.cloud.exception.ConcurrentOperationException;
  import com.cloud.exception.InsufficientCapacityException;
  import com.cloud.exception.InvalidParameterValueException;
@@@ -87,16 -44,7 +75,15 @@@ import com.cloud.utils.component.Manage
  import com.cloud.utils.db.Filter;
  import com.cloud.utils.db.SearchBuilder;
  import com.cloud.utils.db.SearchCriteria;
++
 +import com.cloud.utils.db.Transaction;
 +import com.cloud.utils.db.TransactionCallback;
 +import com.cloud.utils.db.TransactionCallbackNoReturn;
 +import com.cloud.utils.db.TransactionCallbackWithException;
 +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
 +import com.cloud.utils.db.TransactionStatus;
++
  import com.cloud.utils.exception.CloudRuntimeException;
- import com.cloud.utils.fsm.NoTransitionException;
- import com.cloud.utils.fsm.StateMachine2;
  import com.cloud.vm.UserVmVO;
  import com.cloud.vm.VMInstanceVO;
  import com.cloud.vm.VirtualMachine;
@@@ -351,165 -330,14 +369,13 @@@ public class VMSnapshotManagerImpl exte
          if(vmSnapshot == null){
              throw new CloudRuntimeException("VM snapshot id: " + vmSnapshotId + " can not
be found");
          }
-         Long hostId = pickRunningHost(vmId);
-         try {
-             vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.CreateRequested);
-         } catch (NoTransitionException e) {
-             throw new CloudRuntimeException(e.getMessage());
-         }
-         return createVmSnapshotInternal(userVm, vmSnapshot, hostId);
-     }
--
-     protected VMSnapshot createVmSnapshotInternal(UserVmVO userVm, VMSnapshotVO vmSnapshot,
Long hostId) {
-         CreateVMSnapshotAnswer answer = null;
-         try {
-             GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
-             
-             // prepare snapshotVolumeTos
-             List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
-             
-             // prepare target snapshotTO and its parent snapshot (current snapshot)
-             VMSnapshotTO current = null;
-             VMSnapshotVO currentSnapshot = _vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
-             if (currentSnapshot != null)
-                 current = getSnapshotWithParents(currentSnapshot);
-             VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(),  vmSnapshot.getName(),
vmSnapshot.getType(), null, vmSnapshot.getDescription(), false,
-                     current);
-             if (current == null)
-                 vmSnapshot.setParent(null);
-             else
-                 vmSnapshot.setParent(current.getId());
- 
-             CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target
,volumeTOs, guestOS.getDisplayName(),userVm.getState());
-             ccmd.setWait(_wait);
-             
-             answer = (CreateVMSnapshotAnswer) sendToPool(hostId, ccmd);
-             if (answer != null && answer.getResult()) {
-                 processAnswer(vmSnapshot, userVm, answer, hostId);
-                 s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded
for vm: " + userVm.getInstanceName());
-             }else{
-                 
-                 String errMsg = "Creating VM snapshot: " + vmSnapshot.getName() + " failed";
-                 if(answer != null && answer.getDetails() != null)
-                     errMsg = errMsg + " due to " + answer.getDetails();
-                 s_logger.error(errMsg);
-                 vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
-                 throw new CloudRuntimeException(errMsg);
-             }
-             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);
-         } finally{
-             if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
-                 s_logger.warn("Create vm snapshot " + vmSnapshot.getName() + " failed for
vm: " + userVm.getInstanceName());
-                 _vmSnapshotDao.remove(vmSnapshot.getId());
-             }
-             if(vmSnapshot.getState() == VMSnapshot.State.Ready && answer != null){
-                 for (VolumeTO volumeTo : answer.getVolumeTOs()){
-                     publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE,vmSnapshot,userVm,volumeTo);
-                 }
-             }
-         }
-     }
- 
-     private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeTO
volumeTo){
-         VolumeVO volume = _volumeDao.findById(volumeTo.getId());
-         Long diskOfferingId = volume.getDiskOfferingId();
-         Long offeringId = null;
-         if (diskOfferingId != null) {
-             DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
-             if (offering != null
-                     && (offering.getType() == DiskOfferingVO.Type.Disk)) {
-                 offeringId = offering.getId();
-             }
-         }
-         UsageEventUtils.publishUsageEvent(
-                 type,
-                 vmSnapshot.getAccountId(),
-                 userVm.getDataCenterId(),
-                 userVm.getId(),
-                 vmSnapshot.getName(),
-                 offeringId,     
-                 volume.getId(), // save volume's id into templateId field
-                 volumeTo.getChainSize(),
-                 VMSnapshot.class.getName(), vmSnapshot.getUuid());       
-     }
-     
-     protected List<VolumeTO> getVolumeTOList(Long vmId) {
-         List<VolumeTO> volumeTOs = new ArrayList<VolumeTO>();
-         List<VolumeVO> volumeVos = _volumeDao.findByInstance(vmId);
-         
-         for (VolumeVO volume : volumeVos) {
-             StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
-             VolumeTO volumeTO = new VolumeTO(volume, pool);
-             volumeTOs.add(volumeTO);
-         }
-         return volumeTOs;
-     }
- 
-     // get snapshot and its parents recursively
-     private VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) {
-         Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>();
-         List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId());
-         for (VMSnapshotVO vmSnapshotVO : allSnapshots) {
-             snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO);
-         }
- 
-         VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot);
-         VMSnapshotTO result = currentTO;
-         VMSnapshotVO current = snapshot;
-         while (current.getParent() != null) {
-             VMSnapshotVO parent = snapshotMap.get(current.getParent());
-             currentTO.setParent(convert2VMSnapshotTO(parent));
-             current = snapshotMap.get(current.getParent());
-             currentTO = currentTO.getParent();
-         }
-         return result;
-     }
- 
-     private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) {
-         return new VMSnapshotTO(vo.getId(), vo.getName(),  vo.getType(), vo.getCreated().getTime(),
vo.getDescription(),
-                 vo.getCurrent(), null);
-     }
- 
-     protected boolean vmSnapshotStateTransitTo(VMSnapshotVO vsnp, VMSnapshot.Event event)
throws NoTransitionException {
-         return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao);
-     }
-     
-     @DB
-     protected void processAnswer(final VMSnapshotVO vmSnapshot, UserVmVO  userVm, final
Answer as, Long hostId) {
          try {
-             Transaction.execute(new TransactionCallbackWithExceptionNoReturn<NoTransitionException>()
{
-                 @Override
-                 public void doInTransactionWithoutResult(TransactionStatus status) throws
NoTransitionException {
-                     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());
-                         _vmSnapshotDao.remove(vmSnapshot.getId());
-                     }
-                 }
-             });
+             VMSnapshotStrategy strategy = findVMSnapshotStrategy(vmSnapshot);
+             VMSnapshot snapshot = strategy.takeVMSnapshot(vmSnapshot);
+             return snapshot;
          } catch (Exception e) {
-             String errMsg = "Error while process answer: " + as.getClass() + " due to "
+ e.getMessage();
-             s_logger.error(errMsg, e);
-             throw new CloudRuntimeException(errMsg);
+             s_logger.debug("Failed to create vm snapshot: " + vmSnapshotId ,e);
+             return null;
          }
      }
  

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/51a8086c/setup/db/db/schema-421to430.sql
----------------------------------------------------------------------


Mime
View raw message