diff --git a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java index 0469c706094..f7bb87a57fe 100644 --- a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -109,7 +109,7 @@ public class ListSnapshotsCmd extends BaseListCmd { @Override public void execute(){ - List result = _mgr.listSnapshots(this); + List result = _snapshotMgr.listSnapshots(this); ListResponse response = new ListResponse(); List snapshotResponses = new ArrayList(); for (Snapshot snapshot : result) { diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 5199962fdd1..4ebb4769926 100644 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -344,15 +344,6 @@ public interface ManagementService { */ List listCapacities(ListCapacityCmd cmd); - /** - * List all snapshots of a disk volume. Optionaly lists snapshots created by specified interval - * @param cmd the command containing the search criteria (order by, limit, etc.) - * @return list of snapshots - * @throws InvalidParameterValueException - * @throws PermissionDeniedException - */ - List listSnapshots(ListSnapshotsCmd cmd); - /** * List the permissions on a template. This will return a list of account names that have been granted permission to launch instances from the template. * @param cmd the command wrapping the search criteria (template id) diff --git a/api/src/com/cloud/storage/snapshot/SnapshotService.java b/api/src/com/cloud/storage/snapshot/SnapshotService.java index 52f7b43c089..dcf51fc4602 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotService.java @@ -26,7 +26,9 @@ import com.cloud.api.commands.DeleteSnapshotCmd; import com.cloud.api.commands.DeleteSnapshotPoliciesCmd; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; import com.cloud.api.commands.ListSnapshotPoliciesCmd; +import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.Snapshot; @@ -46,6 +48,15 @@ public interface SnapshotService { */ Snapshot createSnapshotInternal(CreateSnapshotInternalCmd cmd) throws ResourceAllocationException; + /** + * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval + * @param cmd the command containing the search criteria (order by, limit, etc.) + * @return list of snapshots + * @throws InvalidParameterValueException + * @throws PermissionDeniedException + */ + List listSnapshots(ListSnapshotsCmd cmd); + /** * Delete specified snapshot from the specified. * If no other policies are assigned it calls destroy snapshot. diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index a7f9b141e46..c5a0034b556 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -503,13 +503,6 @@ public interface ManagementServer extends ManagementService { public long getMemoryUsagebyHost(Long hostId); - /** - * Destroy a snapshot - * @param snapshotId the id of the snapshot to destroy - * @return true if snapshot successfully destroyed, false otherwise - */ - boolean destroyTemplateSnapshot(Long userId, long snapshotId); - /** * Finds a diskOffering by the specified ID. * @param diskOfferingId @@ -547,8 +540,6 @@ public interface ManagementServer extends ManagementService { StoragePoolVO findPoolById(Long id); List searchForStoragePools(Criteria c); - SnapshotPolicyVO findSnapshotPolicyById(Long policyId); - /** * Return whether a domain is a child domain of a given domain. * @param parentId diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 5435eb3692b..573153e2b2f 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -107,7 +107,6 @@ import com.cloud.api.commands.ListPublicIpAddressesCmd; import com.cloud.api.commands.ListRemoteAccessVpnsCmd; import com.cloud.api.commands.ListRoutersCmd; import com.cloud.api.commands.ListServiceOfferingsCmd; -import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.api.commands.ListStoragePoolsCmd; import com.cloud.api.commands.ListSystemVMsCmd; import com.cloud.api.commands.ListTemplateOrIsoPermissionsCmd; @@ -218,10 +217,6 @@ import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.LaunchPermissionVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Snapshot.Type; -import com.cloud.storage.SnapshotPolicyVO; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; @@ -234,15 +229,12 @@ import com.cloud.storage.Upload.Mode; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; -import com.cloud.storage.Volume.VolumeType; import com.cloud.storage.VolumeStats; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.LaunchPermissionDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.UploadDao; @@ -346,8 +338,6 @@ public class ManagementServerImpl implements ManagementServer { private final UserAccountDao _userAccountDao; private final AlertDao _alertDao; private final CapacityDao _capacityDao; - private final SnapshotDao _snapshotDao; - private final SnapshotPolicyDao _snapshotPolicyDao; private final GuestOSDao _guestOSDao; private final GuestOSCategoryDao _guestOSCategoryDao; private final StoragePoolDao _poolDao; @@ -443,8 +433,6 @@ public class ManagementServerImpl implements ManagementServer { _userAccountDao = locator.getDao(UserAccountDao.class); _alertDao = locator.getDao(AlertDao.class); _capacityDao = locator.getDao(CapacityDao.class); - _snapshotDao = locator.getDao(SnapshotDao.class); - _snapshotPolicyDao = locator.getDao(SnapshotPolicyDao.class); _guestOSDao = locator.getDao(GuestOSDao.class); _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); _poolDao = locator.getDao(StoragePoolDao.class); @@ -4121,117 +4109,6 @@ public class ManagementServerImpl implements ManagementServer { return mem; } - @Override - public boolean destroyTemplateSnapshot(Long userId, long snapshotId) { - return _vmMgr.destroyTemplateSnapshot(userId, snapshotId); - } - - @Override - public List listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { - Long volumeId = cmd.getVolumeId(); - - // Verify parameters - if(volumeId != null){ - VolumeVO volume = _volumeDao.findById(volumeId); - if (volume == null) { - throw new InvalidParameterValueException("unable to find a volume with id " + volumeId); - } - checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId); - } - - Account account = UserContext.current().getAccount(); - Long domainId = cmd.getDomainId(); - String accountName = cmd.getAccountName(); - Long accountId = null; - if ((account == null) || isAdmin(account.getType())) { - if (domainId != null) { - if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { - throw new PermissionDeniedException("Unable to list templates for domain " + domainId + ", permission denied."); - } - } else if ((account != null) && (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) { - domainId = account.getDomainId(); - } - - if (domainId != null && accountName != null) { - Account userAccount = _accountDao.findActiveAccount(accountName, domainId); - if (userAccount != null) { - accountId = userAccount.getId(); - } - } - } else { - accountId = account.getId(); - } - - Object name = cmd.getSnapshotName(); - Object id = cmd.getId(); - Object keyword = cmd.getKeyword(); - Object snapshotTypeStr = cmd.getSnapshotType(); - - Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchBuilder sb = _snapshotDao.createSearchBuilder(); - sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); - sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); - sb.and("snapshotTypeEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.EQ); - sb.and("snapshotTypeNEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.NEQ); - - if ((accountId == null) && (domainId != null)) { - // if accountId isn't specified, we can do a domain match for the admin case - SearchBuilder accountSearch = _accountDao.createSearchBuilder(); - sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinType.INNER); - - SearchBuilder domainSearch = _domainDao.createSearchBuilder(); - domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - accountSearch.join("domainSearch", domainSearch, accountSearch.entity().getDomainId(), domainSearch.entity().getId(), JoinType.INNER); - } - - SearchCriteria sc = sb.create(); - - sc.setParameters("status", Snapshot.Status.BackedUp); - - if (volumeId != null) { - sc.setParameters("volumeId", volumeId); - } - - if (name != null) { - sc.setParameters("name", "%" + name + "%"); - } - - if (id != null) { - sc.setParameters("id", id); - } - - if (keyword != null) { - SearchCriteria ssc = _snapshotDao.createSearchCriteria(); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (accountId != null) { - sc.setParameters("accountId", accountId); - } else if (domainId != null) { - DomainVO domain = _domainDao.findById(domainId); - SearchCriteria joinSearch = sc.getJoin("accountSearch"); - joinSearch.setJoinParameters("domainSearch", "path", domain.getPath() + "%"); - } - - if (snapshotTypeStr != null) { - Type snapshotType = SnapshotVO.getSnapshotType((String)snapshotTypeStr); - if (snapshotType == null) { - throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr); - } - sc.setParameters("snapshotTypeEQ", snapshotType.ordinal()); - } else { - // Show only MANUAL and RECURRING snapshot types - sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal()); - } - - return _snapshotDao.search(sc, searchFilter); - } - @Override public DiskOfferingVO findDiskOfferingById(long diskOfferingId) { return _diskOfferingDao.findById(diskOfferingId); @@ -5082,11 +4959,6 @@ public class ManagementServerImpl implements ManagementServer { return _jobDao.search(sc, searchFilter); } - @Override - public SnapshotPolicyVO findSnapshotPolicyById(Long policyId) { - return _snapshotPolicyDao.findById(policyId); - } - @Override public boolean isChildDomain(Long parentId, Long childId) { return _domainDao.isChildDomain(parentId, childId); @@ -5261,25 +5133,6 @@ public class ManagementServerImpl implements ManagementServer { return stopSecondaryStorageVm(vmId, eventId); } } - - private void checkIfStoragePoolAvailable(Long id) throws StorageUnavailableException { - //check if the sp is up before starting - List rootVolList = _volumeDao.findByInstanceAndType(id, VolumeType.ROOT); - if(rootVolList == null || rootVolList.size() == 0){ - throw new StorageUnavailableException("Could not find the root disk for this vm to verify if the pool on which it exists is Up or not"); - }else{ - Long poolId = rootVolList.get(0).getPoolId();//each vm has 1 root vol - StoragePoolVO sp = _poolDao.findById(poolId); - if(sp == null){ - throw new StorageUnavailableException("Could not find the pool for the root disk of vm"+id+", to confirm if it is Up or not"); - }else{ - //found pool - if(!sp.getStatus().equals(com.cloud.host.Status.Up)){ - throw new StorageUnavailableException("Could not start the vm; the associated storage pool is in:"+sp.getStatus().toString()+" state"); - } - } - } - } @Override public VMInstanceVO stopSystemVM(StopSystemVmCmd cmd) { @@ -5963,25 +5816,7 @@ public class ManagementServerImpl implements ManagementServer { return hypers.split(","); } - private Long checkAccountPermissions(long targetAccountId, long targetDomainId, String targetDesc, long targetId) throws ServerApiException { - Long accountId = null; - - Account account = UserContext.current().getAccount(); - if (account != null) { - if (!isAdmin(account.getType())) { - if (account.getId() != targetAccountId) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find a " + targetDesc + " with id " + targetId + " for this account"); - } - } else if (!_domainDao.isChildDomain(account.getDomainId(), targetDomainId)) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to perform operation for " + targetDesc + " with id " + targetId + ", permission denied."); - } - accountId = account.getId(); - } - - return accountId; - } - - @Override + @Override public List searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { // do some parameter validation diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 19f5b64fde8..d50f5fc43ec 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -49,7 +49,6 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public List listByVolumeIdType(long volumeId, String type ) { return listByVolumeIdType(null, volumeId, type); } - @Override public List listByVolumeId(long volumeId) { diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index e3353074b56..24eb041c038 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -19,6 +19,9 @@ package com.cloud.storage.snapshot; import java.util.List; +import com.cloud.api.commands.ListSnapshotsCmd; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotVO; diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 63a889a69ae..77ebdfdf437 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -47,11 +47,13 @@ import com.cloud.api.commands.DeleteSnapshotCmd; import com.cloud.api.commands.DeleteSnapshotPoliciesCmd; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; import com.cloud.api.commands.ListSnapshotPoliciesCmd; +import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.async.AsyncInstanceCreateStatus; import com.cloud.async.AsyncJobManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; @@ -84,6 +86,7 @@ import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -95,8 +98,11 @@ import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; +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.JoinBuilder.JoinType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.UserVmDao; @@ -143,7 +149,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (volume.getInstanceId() == null) { long lastSnapId = _snapshotDao.getLastSnapshot(volumeId, 0); - SnapshotVO lastSnap = _snapshotDao.findById(lastSnapId); + SnapshotVO lastSnap = _snapshotDao.findByIdIncludingRemoved(lastSnapId); if (lastSnap != null) { Date lastSnapTime = lastSnap.getCreated(); if (lastSnapTime.after(volume.getUpdated())){ @@ -154,7 +160,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } else if (_storageMgr.volumeInactive(volume)) { // Volume is attached to a VM which is in Stopped state. long lastSnapId = _snapshotDao.getLastSnapshot(volumeId, 0); - SnapshotVO lastSnap = _snapshotDao.findById(lastSnapId); + SnapshotVO lastSnap = _snapshotDao.findByIdIncludingRemoved(lastSnapId); if (lastSnap != null) { Date lastSnapTime = lastSnap.getCreated(); VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId()); @@ -236,7 +242,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma SnapshotVO preSnapshotVO = null; if( preId != 0) { - preSnapshotVO = _snapshotDao.findById(preId); + preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId); if (preSnapshotVO != null) { preSnapshotPath = preSnapshotVO.getPath(); } @@ -252,7 +258,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if( preSnapshotPath != null && preSnapshotPath == answer.getSnapshotPath() ){ //empty snapshot s_logger.debug("CreateSnapshot: this is empty snapshot, remove it "); - createdSnapshot = _snapshotDao.findById(id); + createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); // delete from the snapshots table _snapshotDao.expunge(id); throw new CloudRuntimeException("There is no change for volume " + volumeId + " since last snapshot, please use last snapshot instead."); @@ -276,7 +282,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (preSSId == 0) { break; } - preSnapshotVO = _snapshotDao.findById(preSSId); + preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId); } if (i >= deltaSnap) { preSnapshotId = 0; @@ -298,7 +304,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma s_logger.error(answer.getDetails()); } // The snapshot was not successfully created - createdSnapshot = _snapshotDao.findById(id); + createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); // delete from the snapshots table _snapshotDao.expunge(id); throw new CloudRuntimeException("Creating snapshot for volume " + volumeId + " on primary storage failed."); @@ -365,7 +371,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } private SnapshotVO updateDBOnCreate(Long id, String snapshotPath, long preSnapshotId) { - SnapshotVO createdSnapshot = _snapshotDao.findById(id); + SnapshotVO createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); createdSnapshot.setPath(snapshotPath); createdSnapshot.setStatus(Snapshot.Status.CreatedOnPrimary); createdSnapshot.setPrevSnapshotId(preSnapshotId); @@ -433,7 +439,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma long prevSnapshotId = snapshot.getPrevSnapshotId(); if (prevSnapshotId > 0) { - prevSnapshot = _snapshotDao.findById(prevSnapshotId); + prevSnapshot = _snapshotDao.findByIdIncludingRemoved(prevSnapshotId); prevSnapshotUuid = prevSnapshot.getPath(); prevBackupUuid = prevSnapshot.getBackupSnapshotId(); } @@ -539,7 +545,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma // This is a manual create, so increment the count of snapshots for // this account if (policyId == Snapshot.MANUAL_POLICY_ID) { - Snapshot snapshot = _snapshotDao.findById(snapshotId); + Snapshot snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId); _accountMgr.incrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); } } @@ -601,7 +607,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma Long snapshotId = cmd.getId(); //Verify parameters - Snapshot snapshotCheck = _snapshotDao.findById(snapshotId.longValue()); + Snapshot snapshotCheck = _snapshotDao.findByIdIncludingRemoved(snapshotId.longValue()); if (snapshotCheck == null) { throw new ServerApiException (BaseCmd.PARAM_ERROR, "unable to find a snapshot with id " + snapshotId); } @@ -641,20 +647,19 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (s_logger.isDebugEnabled()) { s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId + " and policyId " + policyId); } - SnapshotVO lastSnapshot = null; _snapshotDao.remove(snapshotId); long lastId = snapshotId; boolean destroy = false; while( true ) { lastSnapshot = _snapshotDao.findNextSnapshot(lastId); - // prevsnapshotId equal 0, means it is a full snapshot if( lastSnapshot == null ) { - break; + // if all snapshots after this snapshot in this chain are removed, remove those snapshots. + destroy = true; + break; } - if( lastSnapshot.getPrevSnapshotId() == 0) { - // have another full snapshot, then we may delete previous delta snapshots - destroy = true; + if( lastSnapshot.getRemoved() == null ) { + // if there is one child not removed, then can not remove back up snapshot. break; } lastId = lastSnapshot.getId(); @@ -676,7 +681,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (lastId == 0) { break; } - lastSnapshot = _snapshotDao.findById(lastId); + lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); } } return true; @@ -693,7 +698,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma String details = null; SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId); - VolumeVO volume = _volsDao.findById(snapshot.getVolumeId()); + VolumeVO volume = _volsDao.findByIdIncludingRemoved(snapshot.getVolumeId()); + if ( volume == null ) { + throw new CloudRuntimeException("Destroying snapshot " + snapshotId + " backup failed due to unable to find volume " + snapshot.getVolumeId()); + } String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume); String secondaryStoragePoolUrl = _storageMgr.getSecondaryStorageURL(volume.getDataCenterId()); Long dcId = volume.getDataCenterId(); @@ -747,7 +755,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma txn.start(); SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId); - _snapshotDao.expunge(snapshotId); // If this is a manual delete, decrement the count of snapshots for this account if (policyId == Snapshot.MANUAL_POLICY_ID) { _accountMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); @@ -755,6 +762,114 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma txn.commit(); } + + + @Override + public List listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { + Long volumeId = cmd.getVolumeId(); + + // Verify parameters + if(volumeId != null){ + VolumeVO volume = _volsDao.findById(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("unable to find a volume with id " + volumeId); + } + checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId); + } + + Account account = UserContext.current().getAccount(); + Long domainId = cmd.getDomainId(); + String accountName = cmd.getAccountName(); + Long accountId = null; + if ((account == null) || isAdmin(account.getType())) { + if (domainId != null) { + if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { + throw new PermissionDeniedException("Unable to list templates for domain " + domainId + ", permission denied."); + } + } else if ((account != null) && (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) { + domainId = account.getDomainId(); + } + + if (domainId != null && accountName != null) { + Account userAccount = _accountDao.findActiveAccount(accountName, domainId); + if (userAccount != null) { + accountId = userAccount.getId(); + } + } + } else { + accountId = account.getId(); + } + + Object name = cmd.getSnapshotName(); + Object id = cmd.getId(); + Object keyword = cmd.getKeyword(); + Object snapshotTypeStr = cmd.getSnapshotType(); + + Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _snapshotDao.createSearchBuilder(); + sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); + sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ); + sb.and("snapshotTypeEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.EQ); + sb.and("snapshotTypeNEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.NEQ); + + if ((accountId == null) && (domainId != null)) { + // if accountId isn't specified, we can do a domain match for the admin case + SearchBuilder accountSearch = _accountDao.createSearchBuilder(); + sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinType.INNER); + + SearchBuilder domainSearch = _domainDao.createSearchBuilder(); + domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); + accountSearch.join("domainSearch", domainSearch, accountSearch.entity().getDomainId(), domainSearch.entity().getId(), JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + + sc.setParameters("status", Snapshot.Status.BackedUp); + + if (volumeId != null) { + sc.setParameters("volumeId", volumeId); + } + + if (name != null) { + sc.setParameters("name", "%" + name + "%"); + } + + if (id != null) { + sc.setParameters("id", id); + } + + if (keyword != null) { + SearchCriteria ssc = _snapshotDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (accountId != null) { + sc.setParameters("accountId", accountId); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + SearchCriteria joinSearch = sc.getJoin("accountSearch"); + joinSearch.setJoinParameters("domainSearch", "path", domain.getPath() + "%"); + } + + if (snapshotTypeStr != null) { + Type snapshotType = SnapshotVO.getSnapshotType((String)snapshotTypeStr); + if (snapshotType == null) { + throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr); + } + sc.setParameters("snapshotTypeEQ", snapshotType.ordinal()); + } else { + // Show only MANUAL and RECURRING snapshot types + sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal()); + } + + return _snapshotDao.search(sc, searchFilter); + } + @Override public boolean deleteSnapshotDirsForAccount(long accountId) { @@ -777,7 +892,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma // This volume doesn't have any snapshots. Nothing do delete. continue; } - SnapshotVO mostRecentSnapshot = _snapshotDao.findById(mostRecentSnapshotId); + SnapshotVO mostRecentSnapshot = _snapshotDao.findByIdIncludingRemoved(mostRecentSnapshotId); if (mostRecentSnapshot == null) { // Huh. The code should never reach here. s_logger.error("Volume Id's mostRecentSnapshot with id: " + mostRecentSnapshotId + " turns out to be null"); diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index bea52d38ab6..0d28e60a492 100644 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -133,8 +133,6 @@ public interface UserVmManager extends VirtualMachineManager { */ HashMap getVirtualMachineStatistics(long hostId, String hostName, List vmIds); - boolean destroyTemplateSnapshot(Long userId, long snapshotId); - /** * Clean the network rules for the given VM * @param userId diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c76667263b5..c68285901b7 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -51,7 +51,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.GetVmStatsAnswer; import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootAnswer; @@ -2317,34 +2316,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM return false; } } - - @Override - public boolean destroyTemplateSnapshot(Long userId, long snapshotId) { - boolean success = false; - SnapshotVO snapshot = _snapshotDao.findById(Long.valueOf(snapshotId)); - if (snapshot != null) { - VolumeVO volume = _volsDao.findById(snapshot.getVolumeId()); - ManageSnapshotCommand cmd = new ManageSnapshotCommand(snapshotId, snapshot.getPath()); - - Answer answer = null; - String basicErrMsg = "Failed to destroy template snapshot: " + snapshot.getName(); - Long storagePoolId = volume.getPoolId(); - answer = _storageMgr.sendToHostsOnStoragePool(storagePoolId, cmd, basicErrMsg); - - if ((answer != null) && answer.getResult()) { - // delete the snapshot from the database - _snapshotDao.expunge(snapshotId); - success = true; - } - if (answer != null) { - s_logger.error(answer.getDetails()); - } - } - - return success; - } - - + @Override public void cleanNetworkRules(long userId, long instanceId) { UserVmVO vm = _vmDao.findById(instanceId);