use of com.cloud.engine.subsystem.api.storage.DataStore in project cosmic by MissionCriticalCloud.
the class TemplateManagerImpl method copyTemplate.
@Override
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
public VirtualMachineTemplate copyTemplate(final CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
final Long templateId = cmd.getId();
final Long userId = CallContext.current().getCallingUserId();
final Long sourceZoneId = cmd.getSourceZoneId();
final Long destZoneId = cmd.getDestinationZoneId();
final Account caller = CallContext.current().getCallingAccount();
// Verify parameters
final VMTemplateVO template = _tmpltDao.findById(templateId);
if (template == null || template.getRemoved() != null) {
throw new InvalidParameterValueException("Unable to find template with id");
}
final DataStore srcSecStore;
if (sourceZoneId != null) {
// template is on zone-wide secondary storage
srcSecStore = getImageStore(sourceZoneId, templateId);
} else {
// template is on region store
srcSecStore = getImageStore(templateId);
}
if (srcSecStore == null) {
throw new InvalidParameterValueException("There is no template " + templateId + " ready on image store.");
}
if (template.isCrossZones()) {
// sync template from cache store to region store if it is not there, for cases where we are going to migrate existing NFS to S3.
_tmpltSvr.syncTemplateToRegionStore(templateId, srcSecStore);
s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
return template;
}
if (sourceZoneId != null) {
if (sourceZoneId.equals(destZoneId)) {
throw new InvalidParameterValueException("Please specify different source and destination zones.");
}
final DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
if (sourceZone == null) {
throw new InvalidParameterValueException("Please specify a valid source zone.");
}
}
final DataCenterVO dstZone = _dcDao.findById(destZoneId);
if (dstZone == null) {
throw new InvalidParameterValueException("Please specify a valid destination zone.");
}
final DataStore dstSecStore = getImageStore(destZoneId, templateId);
if (dstSecStore != null) {
s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId + " , don't need to copy");
return template;
}
_accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
final boolean success = copy(userId, template, srcSecStore, dstZone);
if (success) {
// increase resource count
final long accountId = template.getAccountId();
if (template.getSize() != null) {
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize());
}
return template;
} else {
throw new CloudRuntimeException("Failed to copy template");
}
}
use of com.cloud.engine.subsystem.api.storage.DataStore in project cosmic by MissionCriticalCloud.
the class TemplateManagerImpl method extract.
private String extract(final Account caller, final Long templateId, final String url, final Long zoneId, final String mode, final Long eventId, final boolean isISO) {
String desc = Upload.Type.TEMPLATE.toString();
if (isISO) {
desc = Upload.Type.ISO.toString();
}
if (!_accountMgr.isRootAdmin(caller.getId()) && _disableExtraction) {
throw new PermissionDeniedException("Extraction has been disabled by admin");
}
final VMTemplateVO template = _tmpltDao.findById(templateId);
if (template == null || template.getRemoved() != null) {
throw new InvalidParameterValueException("Unable to find " + desc + " with id " + templateId);
}
if (template.getTemplateType() == Storage.TemplateType.SYSTEM) {
throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template");
} else if (template.getTemplateType() == Storage.TemplateType.PERHOST) {
throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM");
}
if (isISO) {
if (template.getFormat() != ImageFormat.ISO) {
throw new InvalidParameterValueException("Unsupported format, could not extract the ISO");
}
} else {
if (template.getFormat() == ImageFormat.ISO) {
throw new InvalidParameterValueException("Unsupported format, could not extract the template");
}
}
if (zoneId != null && _dcDao.findById(zoneId) == null) {
throw new IllegalArgumentException("Please specify a valid zone.");
}
if (!_accountMgr.isRootAdmin(caller.getId()) && !template.isExtractable()) {
throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable");
}
_accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
final List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
TemplateDataStoreVO tmpltStoreRef = null;
ImageStoreEntity tmpltStore = null;
if (ssStores != null) {
for (final DataStore store : ssStores) {
tmpltStoreRef = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
if (tmpltStoreRef != null) {
if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
tmpltStore = (ImageStoreEntity) store;
break;
}
}
}
}
if (tmpltStore == null) {
throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
}
// Check if the url already exists
if (tmpltStoreRef.getExtractUrl() != null) {
return tmpltStoreRef.getExtractUrl();
}
// Handle NFS to S3 object store migration case, we trigger template sync from NFS to S3 during extract template or copy template
_tmpltSvr.syncTemplateToRegionStore(templateId, tmpltStore);
final TemplateInfo templateObject = _tmplFactory.getTemplate(templateId, tmpltStore);
final String extractUrl = tmpltStore.createEntityExtractUrl(templateObject.getInstallPath(), template.getFormat(), templateObject);
tmpltStoreRef.setExtractUrl(extractUrl);
tmpltStoreRef.setExtractUrlCreated(DateUtil.now());
_tmplStoreDao.update(tmpltStoreRef.getId(), tmpltStoreRef);
return extractUrl;
}
use of com.cloud.engine.subsystem.api.storage.DataStore in project cosmic by MissionCriticalCloud.
the class SnapshotManagerImpl method deleteSnapshotDirsForAccount.
@Override
public boolean deleteSnapshotDirsForAccount(final long accountId) {
final List<VolumeVO> volumes = _volsDao.findIncludingRemovedByAccount(accountId);
// The above call will list only non-destroyed volumes.
// So call this method before marking the volumes as destroyed.
// i.e Call them before the VMs for those volumes are destroyed.
boolean success = true;
for (final VolumeVO volume : volumes) {
if (volume.getPoolId() == null) {
continue;
}
final Long volumeId = volume.getId();
final Long dcId = volume.getDataCenterId();
if (_snapshotDao.listByVolumeIdIncludingRemoved(volumeId).isEmpty()) {
// This volume doesn't have any snapshots. Nothing do delete.
continue;
}
final List<DataStore> ssHosts = dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId));
for (final DataStore ssHost : ssHosts) {
final String snapshotDir = TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId + "/" + volumeId;
final DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(ssHost.getTO(), snapshotDir);
final EndPoint ep = _epSelector.select(ssHost);
final Answer answer;
if (ep == null) {
final String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer != null && answer.getResult()) {
s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId);
} else {
success = false;
if (answer != null) {
s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on secondary storage " + ssHost.getUri());
s_logger.error(answer.getDetails());
}
}
}
// Either way delete the snapshots for this volume.
final List<SnapshotVO> snapshots = listSnapsforVolume(volumeId);
for (final SnapshotVO snapshot : snapshots) {
final SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.DELETE);
if (snapshotStrategy == null) {
s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshot.getId() + "'");
continue;
}
final SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image);
if (snapshotStrategy.deleteSnapshot(snapshot.getId())) {
if (Type.MANUAL == snapshot.getRecurringType()) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot);
if (snapshotStoreRef != null) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(snapshotStoreRef.getPhysicalSize()));
}
}
}
}
}
// Returns true if snapshotsDir has been deleted for all volumes.
return success;
}
use of com.cloud.engine.subsystem.api.storage.DataStore in project cosmic by MissionCriticalCloud.
the class SnapshotManagerImpl method backupSnapshotFromVmSnapshot.
@Override
public Snapshot backupSnapshotFromVmSnapshot(final Long snapshotId, final Long vmId, final Long volumeId, final Long vmSnapshotId) {
final VMInstanceVO vm = _vmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("Creating snapshot failed due to vm:" + vmId + " doesn't exist");
}
if (!HypervisorType.KVM.equals(vm.getHypervisorType())) {
throw new InvalidParameterValueException("Unsupported hypervisor type " + vm.getHypervisorType() + ". This supports KVM only");
}
final VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
if (vmSnapshot == null) {
throw new InvalidParameterValueException("Creating snapshot failed due to vmSnapshot:" + vmSnapshotId + " doesn't exist");
}
// check vmsnapshot permissions
final Account caller = CallContext.current().getCallingAccount();
_accountMgr.checkAccess(caller, null, true, vmSnapshot);
final SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
if (snapshot == null) {
throw new InvalidParameterValueException("Creating snapshot failed due to snapshot:" + snapshotId + " doesn't exist");
}
final VolumeInfo volume = volFactory.getVolume(volumeId);
if (volume == null) {
throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
}
if (volume.getState() != Volume.State.Ready) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
}
final DataStore store = volume.getDataStore();
final SnapshotDataStoreVO parentSnapshotDataStoreVO = _snapshotStoreDao.findParent(store.getRole(), store.getId(), volumeId);
if (parentSnapshotDataStoreVO != null) {
// Double check the snapshot is removed or not
final SnapshotVO parentSnap = _snapshotDao.findById(parentSnapshotDataStoreVO.getSnapshotId());
if (parentSnap != null && parentSnapshotDataStoreVO.getInstallPath() != null && parentSnapshotDataStoreVO.getInstallPath().equals(vmSnapshot.getName())) {
throw new InvalidParameterValueException("Creating snapshot failed due to snapshot : " + parentSnap.getUuid() + " is created from the same vm snapshot");
}
}
SnapshotInfo snapshotInfo = this.snapshotFactory.getSnapshot(snapshotId, store);
snapshotInfo = (SnapshotInfo) store.create(snapshotInfo);
final SnapshotDataStoreVO snapshotOnPrimaryStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), store.getRole());
snapshotOnPrimaryStore.setState(ObjectInDataStoreStateMachine.State.Ready);
snapshotOnPrimaryStore.setInstallPath(vmSnapshot.getName());
_snapshotStoreDao.update(snapshotOnPrimaryStore.getId(), snapshotOnPrimaryStore);
snapshot.setState(Snapshot.State.CreatedOnPrimary);
_snapshotDao.update(snapshot.getId(), snapshot);
snapshotInfo = this.snapshotFactory.getSnapshot(snapshotId, store);
final Long snapshotOwnerId = vm.getAccountId();
try {
final SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
if (snapshotStrategy == null) {
throw new CloudRuntimeException("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
}
snapshotInfo = snapshotStrategy.backupSnapshot(snapshotInfo);
} catch (final Exception e) {
s_logger.debug("Failed to backup snapshot from vm snapshot", e);
_resourceLimitMgr.decrementResourceCount(snapshotOwnerId, ResourceType.snapshot);
_resourceLimitMgr.decrementResourceCount(snapshotOwnerId, ResourceType.secondary_storage, volume.getSize());
throw new CloudRuntimeException("Failed to backup snapshot from vm snapshot", e);
}
return snapshotInfo;
}
use of com.cloud.engine.subsystem.api.storage.DataStore in project cosmic by MissionCriticalCloud.
the class UploadMonitorImpl method createEntityDownloadURL.
@Override
public UploadVO createEntityDownloadURL(final VMTemplateVO template, final TemplateDataStoreVO vmTemplateHost, final Long dataCenterId, final long eventId) {
String errorString = "";
boolean success = false;
final Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE;
// find an endpoint to send command
final DataStore store = storeMgr.getDataStore(vmTemplateHost.getDataStoreId(), DataStoreRole.Image);
final EndPoint ep = _epSelector.select(store);
if (ep == null) {
final String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
return null;
}
// Check if it already exists.
final List<UploadVO> extractURLList = _uploadDao.listByTypeUploadStatus(template.getId(), type, UploadVO.Status.DOWNLOAD_URL_CREATED);
if (extractURLList.size() > 0) {
// do some check here
final UploadVO upload = extractURLList.get(0);
String uploadUrl = extractURLList.get(0).getUploadUrl();
final String[] token = uploadUrl.split("/");
// example: uploadUrl = https://10-11-101-112.realhostip.com/userdata/2fdd9a70-9c4a-4a04-b1d5-1e41c221a1f9.iso
// then token[2] = 10-11-101-112.realhostip.com, token[4] = 2fdd9a70-9c4a-4a04-b1d5-1e41c221a1f9.iso
final String hostname = ep.getPublicAddr().replace(".", "-") + ".";
if (// ssvm publicip and domain suffix not changed
(token != null) && (token.length == 5) && (token[2].equals(hostname + _ssvmUrlDomain))) {
return extractURLList.get(0);
} else if ((token != null) && (token.length == 5) && (token[2].startsWith(hostname))) {
// domain suffix changed
final String uuid = token[4];
uploadUrl = generateCopyUrl(ep.getPublicAddr(), uuid);
final UploadVO vo = _uploadDao.createForUpdate();
vo.setLastUpdated(new Date());
vo.setUploadUrl(uploadUrl);
_uploadDao.update(upload.getId(), vo);
return _uploadDao.findById(upload.getId(), true);
} else {
// ssvm publicip changed
return null;
}
}
// It doesn't exist so create a DB entry.
final UploadVO uploadTemplateObj = new UploadVO(vmTemplateHost.getDataStoreId(), template.getId(), new Date(), Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD);
uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath());
_uploadDao.persist(uploadTemplateObj);
try {
// Create Symlink at ssvm
final String path = vmTemplateHost.getInstallPath();
// adding "." + vhd/ova... etc.
final String uuid = UUID.randomUUID().toString() + "." + template.getFormat().getFileExtension();
final CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity) store).getMountPoint(), path, uuid, null);
final Answer ans = ep.sendMessage(cmd);
if (ans == null || !ans.getResult()) {
errorString = "Unable to create a link for " + type + " id:" + template.getId() + "," + (ans == null ? "" : ans.getDetails());
s_logger.error(errorString);
throw new CloudRuntimeException(errorString);
}
// Construct actual URL locally now that the symlink exists at SSVM
final String extractURL = generateCopyUrl(ep.getPublicAddr(), uuid);
final UploadVO vo = _uploadDao.createForUpdate();
vo.setLastUpdated(new Date());
vo.setUploadUrl(extractURL);
vo.setUploadState(Status.DOWNLOAD_URL_CREATED);
_uploadDao.update(uploadTemplateObj.getId(), vo);
success = true;
return _uploadDao.findById(uploadTemplateObj.getId(), true);
} finally {
if (!success) {
final UploadVO uploadJob = _uploadDao.createForUpdate(uploadTemplateObj.getId());
uploadJob.setLastUpdated(new Date());
uploadJob.setErrorString(errorString);
uploadJob.setUploadState(Status.ERROR);
_uploadDao.update(uploadTemplateObj.getId(), uploadJob);
}
}
}
Aggregations