use of org.apache.cloudstack.storage.command.DeleteCommand in project cloudstack by apache.
the class VmwareStorageSubsystemCommandHandler method execute.
@Override
protected Answer execute(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
DataStoreTO srcDataStore = srcData.getDataStore();
DataStoreTO destDataStore = destData.getDataStore();
int timeout = NumbersUtil.parseInt(cmd.getContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key()), Integer.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.defaultValue()) * VmwareManager.s_vmwareOVAPackageTimeout.multiplier());
// if copied between s3 and nfs cache, go to resource
boolean needDelegation = false;
if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
if (srcDataStore instanceof S3TO || srcDataStore instanceof SwiftTO) {
needDelegation = true;
}
}
if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
// need to take extra processing for vmware, such as packing to ova, before sending to S3
if (srcData.getObjectType() == DataObjectType.VOLUME) {
NfsTO cacheStore = (NfsTO) srcDataStore;
String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion);
VolumeObjectTO vol = (VolumeObjectTO) srcData;
String path = vol.getPath();
int index = path.lastIndexOf(File.separator);
String name = path.substring(index + 1);
storageManager.createOva(parentPath + File.separator + path, name, timeout);
vol.setPath(path + File.separator + name + ".ova");
} else if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
// sync template from NFS cache to S3 in NFS migration to S3 case
storageManager.createOvaForTemplate((TemplateObjectTO) srcData, timeout);
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT) {
// pack ova first
// sync snapshot from NFS cache to S3 in NFS migration to S3 case
String parentPath = storageResource.getRootDir(srcDataStore.getUrl(), _nfsVersion);
SnapshotObjectTO snap = (SnapshotObjectTO) srcData;
String path = snap.getPath();
int index = path.lastIndexOf(File.separator);
String name = path.substring(index + 1);
String snapDir = path.substring(0, index);
storageManager.createOva(parentPath + File.separator + snapDir, name, timeout);
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
// create template from snapshot on src at first, then copy it to s3
TemplateObjectTO cacheTemplate = (TemplateObjectTO) destData;
cacheTemplate.setDataStore(srcDataStore);
CopyCmdAnswer answer = (CopyCmdAnswer) processor.createTemplateFromSnapshot(cmd);
if (!answer.getResult()) {
return answer;
}
cacheTemplate.setDataStore(destDataStore);
TemplateObjectTO template = (TemplateObjectTO) answer.getNewData();
template.setDataStore(srcDataStore);
CopyCommand newCmd = new CopyCommand(template, destData, cmd.getWait(), cmd.executeInSequence());
Answer result = storageResource.defaultAction(newCmd);
// clean up template data on staging area
try {
DeleteCommand deleteCommand = new DeleteCommand(template);
storageResource.defaultAction(deleteCommand);
} catch (Exception e) {
s_logger.debug("Failed to clean up staging area:", e);
}
return result;
}
}
needDelegation = true;
}
if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
// for back up snapshot, we need to do backup to cache, then to object store if object store is used.
if (cmd.getCacheTO() != null) {
cmd.setDestTO(cmd.getCacheTO());
CopyCmdAnswer answer = (CopyCmdAnswer) processor.backupSnapshot(cmd);
if (!answer.getResult()) {
return answer;
}
NfsTO cacheStore = (NfsTO) cmd.getCacheTO().getDataStore();
String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion);
SnapshotObjectTO newSnapshot = (SnapshotObjectTO) answer.getNewData();
String path = newSnapshot.getPath();
int index = path.lastIndexOf(File.separator);
String name = path.substring(index + 1);
String dir = path.substring(0, index);
storageManager.createOva(parentPath + File.separator + dir, name, timeout);
newSnapshot.setPath(newSnapshot.getPath() + ".ova");
newSnapshot.setDataStore(cmd.getCacheTO().getDataStore());
CopyCommand newCmd = new CopyCommand(newSnapshot, destData, cmd.getWait(), cmd.executeInSequence());
Answer result = storageResource.defaultAction(newCmd);
// clean up data on staging area
try {
newSnapshot.setPath(path);
DeleteCommand deleteCommand = new DeleteCommand(newSnapshot);
storageResource.defaultAction(deleteCommand);
} catch (Exception e) {
s_logger.debug("Failed to clean up staging area:", e);
}
return result;
}
}
if (needDelegation) {
return storageResource.defaultAction(cmd);
} else {
return super.execute(cmd);
}
}
use of org.apache.cloudstack.storage.command.DeleteCommand in project cloudstack by apache.
the class BaseImageStoreDriverImpl method deleteAsync.
@Override
public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
CommandResult result = new CommandResult();
try {
DeleteCommand cmd = new DeleteCommand(data.getTO());
EndPoint ep = _epSelector.select(data);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
LOGGER.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if (answer != null && !answer.getResult()) {
result.setResult(answer.getDetails());
}
} catch (Exception ex) {
LOGGER.debug("Unable to destoy " + data.getType().toString() + ": " + data.getId(), ex);
result.setResult(ex.toString());
}
callback.complete(result);
}
use of org.apache.cloudstack.storage.command.DeleteCommand in project cloudstack by apache.
the class Ovm3StorageProcessorTest method deleteCommandTest.
/**
* Delete an object
*
* @throws ConfigurationException
*/
@Test
public void deleteCommandTest() throws ConfigurationException {
con = prepare();
VolumeObjectTO vol = volume(ovmObject.newUuid(), ovmObject.newUuid(), linux.getRepoId(), linux.getVirtualDisksDir());
DeleteCommand delete = new DeleteCommand(vol);
Answer ra = hypervisor.executeRequest(delete);
results.basicBooleanTest(ra.getResult());
TemplateObjectTO template = template(ovmObject.newUuid(), ovmObject.newUuid(), ovmObject.newUuid(linux.getRemote()), linux.getRemote());
delete = new DeleteCommand(template);
ra = hypervisor.executeRequest(delete);
results.basicBooleanTest(ra.getResult(), false);
SnapshotObjectTO snap = snapshot(ovmObject.newUuid(), ovmObject.newUuid(), ovmObject.newUuid(linux.getRemote()), linux.getRemote());
delete = new DeleteCommand(snap);
ra = hypervisor.executeRequest(delete);
results.basicBooleanTest(ra.getResult(), false);
}
use of org.apache.cloudstack.storage.command.DeleteCommand in project cloudstack by apache.
the class VolumeServiceImpl method handleVolumeSync.
@Override
public void handleVolumeSync(DataStore store) {
if (store == null) {
s_logger.warn("Huh? image store is null");
return;
}
long storeId = store.getId();
// add lock to make template sync for a data store only be done once
String lockString = "volumesync.storeId:" + storeId;
GlobalLock syncLock = GlobalLock.getInternLock(lockString);
try {
if (syncLock.lock(3)) {
try {
Map<Long, TemplateProp> volumeInfos = listVolume(store);
if (volumeInfos == null) {
return;
}
// find all the db volumes including those with NULL url column to avoid accidentally deleting volumes on image store later.
List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
for (VolumeDataStoreVO volumeStore : dbVolumes) {
VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
if (volume == null) {
s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
volumeStore.setDestroyed(true);
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
continue;
}
// Exists then don't download
if (volumeInfos.containsKey(volume.getId())) {
TemplateProp volInfo = volumeInfos.remove(volume.getId());
toBeDownloaded.remove(volumeStore);
s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
volumeStore.setErrorString("");
}
if (volInfo.isCorrupted()) {
volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
volumeStore.setErrorString(msg);
s_logger.info(msg);
if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
s_logger.info("Volume Sync found " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + " as corrupted, marking it as failed");
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
// mark volume as failed, so that storage GC will clean it up
VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
volObj.processEvent(Event.OperationFailed);
} else if (volumeStore.getDownloadUrl() == null) {
msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: " + volumeStore.getDataStoreId();
s_logger.warn(msg);
} else {
s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
_volumeStoreDao.remove(volumeStore.getId());
toBeDownloaded.add(volumeStore);
}
} else {
// Put them in right status
volumeStore.setDownloadPercent(100);
volumeStore.setDownloadState(Status.DOWNLOADED);
volumeStore.setState(ObjectInDataStoreStateMachine.State.Ready);
volumeStore.setInstallPath(volInfo.getInstallPath());
volumeStore.setSize(volInfo.getSize());
volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
volumeStore.setLastUpdated(new Date());
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
if (volume.getSize() == 0) {
// Set volume size in volumes table
volume.setSize(volInfo.getSize());
volDao.update(volumeStore.getVolumeId(), volume);
}
if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
volObj.processEvent(Event.OperationSuccessed);
}
if (volInfo.getSize() > 0) {
try {
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize());
} catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage());
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
} finally {
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
}
}
}
continue;
} else if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
// failed uploads through SSVM
s_logger.info("Volume Sync did not find " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + ", marking it as failed");
toBeDownloaded.remove(volumeStore);
volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
volumeStore.setErrorString(msg);
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
// mark volume as failed, so that storage GC will clean it up
VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
volObj.processEvent(Event.OperationFailed);
continue;
}
// Volume is not on secondary but we should download.
if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
}
}
// Download volumes which haven't been downloaded yet.
if (toBeDownloaded.size() > 0) {
for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
if (volumeHost.getDownloadUrl() == null) {
// If url is null, skip downloading
s_logger.info("Skip downloading volume " + volumeHost.getVolumeId() + " since no download url is specified.");
continue;
}
// means that this is a duplicate entry from migration of previous NFS to staging.
if (store.getScope().getScopeType() == ScopeType.REGION) {
if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED && volumeHost.getInstallPath() == null) {
s_logger.info("Skip sync volume for migration of previous NFS to object store");
continue;
}
}
s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
// reset volume status back to Allocated
VolumeObject vol = (VolumeObject) volFactory.getVolume(volumeHost.getVolumeId());
// reset back volume status
vol.processEvent(Event.OperationFailed);
// remove leftover volume_store_ref entry since re-download will create it again
_volumeStoreDao.remove(volumeHost.getId());
// get an updated volumeVO
vol = (VolumeObject) volFactory.getVolume(volumeHost.getVolumeId());
RegisterVolumePayload payload = new RegisterVolumePayload(volumeHost.getDownloadUrl(), volumeHost.getChecksum(), vol.getFormat().toString());
vol.addPayload(payload);
createVolumeAsync(vol, store);
}
}
// Delete volumes which are not present on DB.
for (Map.Entry<Long, TemplateProp> entry : volumeInfos.entrySet()) {
Long uniqueName = entry.getKey();
TemplateProp tInfo = entry.getValue();
// we cannot directly call expungeVolumeAsync here to reuse delete logic since in this case db does not have this volume at all.
VolumeObjectTO tmplTO = new VolumeObjectTO();
tmplTO.setDataStore(store.getTO());
tmplTO.setPath(tInfo.getInstallPath());
tmplTO.setId(tInfo.getId());
DeleteCommand dtCommand = new DeleteCommand(tmplTO);
EndPoint ep = _epSelector.select(store);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(dtCommand, false, errMsg);
} else {
answer = ep.sendMessage(dtCommand);
}
if (answer == null || !answer.getResult()) {
s_logger.info("Failed to deleted volume at store: " + store.getName());
} else {
String description = "Deleted volume " + tInfo.getTemplateName() + " on secondary storage " + storeId;
s_logger.info(description);
}
}
} finally {
syncLock.unlock();
}
} else {
s_logger.info("Couldn't get global lock on " + lockString + ", another thread may be doing volume sync on data store " + storeId + " now.");
}
} finally {
syncLock.releaseRef();
}
}
use of org.apache.cloudstack.storage.command.DeleteCommand in project cloudstack by apache.
the class CloudStackPrimaryDataStoreDriverImpl method deleteAsync.
@Override
public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
DeleteCommand cmd = new DeleteCommand(data.getTO());
cmd.setBypassHostMaintenance(commandCanBypassHostMaintenance(data));
CommandResult result = new CommandResult();
try {
EndPoint ep = null;
if (data.getType() == DataObjectType.VOLUME) {
ep = epSelector.select(data, StorageAction.DELETEVOLUME);
} else {
ep = epSelector.select(data);
}
if (ep == null) {
String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?";
s_logger.error(errMsg);
result.setResult(errMsg);
} else {
Answer answer = ep.sendMessage(cmd);
if (answer != null && !answer.getResult()) {
result.setResult(answer.getDetails());
}
}
} catch (Exception ex) {
s_logger.debug("Unable to destoy volume" + data.getId(), ex);
result.setResult(ex.toString());
}
callback.complete(result);
}
Aggregations