use of com.cloud.legacymodel.to.DataTO in project cosmic by MissionCriticalCloud.
the class KvmStorageProcessor method backupSnapshot.
@Override
public Answer backupSnapshot(final CopyCommand cmd) {
final DataTO srcData = cmd.getSrcTO();
final DataTO destData = cmd.getDestTO();
final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshot.getDataStore();
final SnapshotObjectTO destSnapshot = (SnapshotObjectTO) destData;
final DataStoreTO imageStore = destData.getDataStore();
final NfsTO nfsImageStore = (NfsTO) imageStore;
final String secondaryStoragePoolUrl = nfsImageStore.getUrl();
// NOTE: snapshot name is encoded in snapshot path
final int index = snapshot.getPath().lastIndexOf("/");
// -1 means the snapshot is created from existing vm snapshot
final boolean isCreatedFromVmSnapshot = index == -1;
final String snapshotName = snapshot.getPath().substring(index + 1);
String descName = snapshotName;
final String volumePath = snapshot.getVolume().getPath();
final String snapshotDestPath;
final String snapshotRelPath;
final String vmName = snapshot.getVmName();
KvmStoragePool secondaryStoragePool = null;
Connect conn = null;
KvmPhysicalDisk snapshotDisk = null;
KvmStoragePool primaryPool = null;
try {
conn = LibvirtConnection.getConnectionByVmName(vmName);
secondaryStoragePool = this.storagePoolMgr.getStoragePoolByUri(secondaryStoragePoolUrl);
final String ssPmountPath = secondaryStoragePool.getLocalPath();
snapshotRelPath = destSnapshot.getPath();
snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath;
snapshotDisk = this.storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volumePath);
primaryPool = snapshotDisk.getPool();
long size = 0;
if (primaryPool.getType() == StoragePoolType.RBD) {
final String rbdSnapshot = snapshotDisk.getPath() + "@" + snapshotName;
final String snapshotFile = snapshotDestPath + "/" + snapshotName;
try {
this.logger.debug("Attempting to backup RBD snapshot " + rbdSnapshot);
final File snapDir = new File(snapshotDestPath);
this.logger.debug("Attempting to create " + snapDir.getAbsolutePath() + " recursively for snapshot storage");
FileUtils.forceMkdir(snapDir);
final QemuImgFile srcFile = new QemuImgFile(KvmPhysicalDisk.rbdStringBuilder(primaryPool.getSourceHost(), primaryPool.getSourcePort(), primaryPool.getAuthUserName(), primaryPool.getAuthSecret(), rbdSnapshot));
srcFile.setFormat(snapshotDisk.getFormat());
final QemuImgFile destFile = new QemuImgFile(snapshotFile);
destFile.setFormat(PhysicalDiskFormat.QCOW2);
this.logger.debug("Backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile);
final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
q.convert(srcFile, destFile);
final File snapFile = new File(snapshotFile);
if (snapFile.exists()) {
size = snapFile.length();
}
this.logger.debug("Finished backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile + " Snapshot size: " + size);
} catch (final FileNotFoundException e) {
this.logger.error("Failed to open " + snapshotDestPath + ". The error was: " + e.getMessage());
return new CopyCmdAnswer(e.toString());
} catch (final IOException e) {
this.logger.error("Failed to create " + snapshotDestPath + ". The error was: " + e.getMessage());
return new CopyCmdAnswer(e.toString());
} catch (final QemuImgException e) {
this.logger.error("Failed to backup the RBD snapshot from " + rbdSnapshot + " to " + snapshotFile + " the error was: " + e.getMessage());
return new CopyCmdAnswer(e.toString());
}
} else {
final Script command = new Script(this.manageSnapshotPath, cmd.getWaitInMillSeconds(), this.logger);
command.add("-b", snapshotDisk.getPath());
command.add("-n", snapshotName);
command.add("-p", snapshotDestPath);
if (isCreatedFromVmSnapshot) {
descName = UUID.randomUUID().toString();
}
command.add("-t", descName);
final String result = command.execute();
if (result != null) {
this.logger.debug("Failed to backup snaptshot: " + result);
return new CopyCmdAnswer(result);
}
final File snapFile = new File(snapshotDestPath + "/" + descName);
if (snapFile.exists()) {
size = snapFile.length();
}
}
final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
newSnapshot.setPath(snapshotRelPath + File.separator + descName);
newSnapshot.setPhysicalSize(size);
return new CopyCmdAnswer(newSnapshot);
} catch (final LibvirtException | CloudRuntimeException e) {
this.logger.debug("Failed to backup snapshot: ", e);
return new CopyCmdAnswer(e.toString());
} finally {
if (isCreatedFromVmSnapshot) {
this.logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
} else {
try {
/* Delete the snapshot on primary */
DomainState state = null;
Domain vm = null;
if (vmName != null) {
try {
vm = this.resource.getDomain(conn, vmName);
state = vm.getInfo().state;
} catch (final LibvirtException e) {
this.logger.trace("Ignoring libvirt error.", e);
}
}
final KvmStoragePool primaryStorage = this.storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
/*
* libvirt on RHEL6 doesn't handle resume event emitted from
* qemu
*/
vm = this.resource.getDomain(conn, vmName);
state = vm.getInfo().state;
if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
if (primaryPool.getType() != StoragePoolType.RBD) {
final Script command = new Script(this.manageSnapshotPath, this.cmdsTimeout, this.logger);
command.add("-d", snapshotDisk.getPath());
command.add("-n", snapshotName);
final String result = command.execute();
if (result != null) {
this.logger.debug("Failed to delete snapshot on primary: " + result);
// return new CopyCmdAnswer("Failed to backup snapshot: " + result);
}
}
}
} catch (final Exception ex) {
this.logger.debug("Failed to delete snapshots on primary", ex);
}
}
try {
if (secondaryStoragePool != null) {
secondaryStoragePool.delete();
}
} catch (final Exception ex) {
this.logger.debug("Failed to delete secondary storage", ex);
}
}
}
use of com.cloud.legacymodel.to.DataTO in project cosmic by MissionCriticalCloud.
the class KvmStorageProcessor method copyTemplateToPrimaryStorage.
@Override
public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
final DataTO srcData = cmd.getSrcTO();
final DataTO destData = cmd.getDestTO();
final TemplateObjectTO template = (TemplateObjectTO) srcData;
final DataStoreTO imageStore = template.getDataStore();
final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destData.getDataStore();
if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
}
final NfsTO nfsImageStore = (NfsTO) imageStore;
final String tmplturl = nfsImageStore.getUrl() + File.separator + template.getPath();
final int index = tmplturl.lastIndexOf("/");
final String mountpoint = tmplturl.substring(0, index);
String tmpltname = null;
if (index < tmplturl.length() - 1) {
tmpltname = tmplturl.substring(index + 1);
}
KvmPhysicalDisk tmplVol = null;
KvmStoragePool secondaryPool = null;
try {
secondaryPool = this.storagePoolMgr.getStoragePoolByUri(mountpoint);
/* Get template vol */
if (tmpltname == null) {
secondaryPool.refresh();
final List<KvmPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
if (disks == null || disks.isEmpty()) {
return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid());
}
for (final KvmPhysicalDisk disk : disks) {
if (disk.getName().endsWith("qcow2")) {
tmplVol = disk;
break;
}
}
} else {
tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
}
if (tmplVol == null) {
return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
}
/* Copy volume to primary storage */
this.logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat());
final KvmStoragePool primaryPool = this.storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
final KvmPhysicalDisk primaryVol;
if (destData instanceof VolumeObjectTO) {
final VolumeObjectTO volume = (VolumeObjectTO) destData;
// rather than cloning on deploy
if (volume.getSize() != null && volume.getSize() > tmplVol.getVirtualSize()) {
this.logger.debug("Using configured size of " + volume.getSize());
tmplVol.setSize(volume.getSize());
tmplVol.setVirtualSize(volume.getSize());
} else {
this.logger.debug("Using template's size of " + tmplVol.getVirtualSize());
}
primaryVol = this.storagePoolMgr.copyPhysicalDisk(tmplVol, volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
} else if (destData instanceof TemplateObjectTO) {
final TemplateObjectTO destTempl = (TemplateObjectTO) destData;
primaryVol = this.storagePoolMgr.copyPhysicalDisk(tmplVol, destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
} else {
primaryVol = this.storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, cmd.getWaitInMillSeconds());
}
DataTO data = null;
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
final TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(primaryVol.getName());
newTemplate.setSize(primaryVol.getSize());
if (primaryPool.getType() == StoragePoolType.RBD) {
newTemplate.setFormat(ImageFormat.RAW);
} else {
newTemplate.setFormat(ImageFormat.QCOW2);
}
data = newTemplate;
} else if (destData.getObjectType() == DataObjectType.VOLUME) {
final VolumeObjectTO volumeObjectTo = new VolumeObjectTO();
volumeObjectTo.setPath(primaryVol.getName());
volumeObjectTo.setSize(primaryVol.getSize());
if (primaryVol.getFormat() == PhysicalDiskFormat.RAW) {
volumeObjectTo.setFormat(ImageFormat.RAW);
} else if (primaryVol.getFormat() == PhysicalDiskFormat.QCOW2) {
volumeObjectTo.setFormat(ImageFormat.QCOW2);
}
data = volumeObjectTo;
}
return new CopyCmdAnswer(data);
} catch (final CloudRuntimeException e) {
return new CopyCmdAnswer(e.toString());
} finally {
try {
if (secondaryPool != null) {
secondaryPool.delete();
}
} catch (final Exception e) {
this.logger.debug("Failed to clean up secondary storage", e);
}
}
}
use of com.cloud.legacymodel.to.DataTO in project cosmic by MissionCriticalCloud.
the class NfsSecondaryStorageResource method deleteTemplate.
protected Answer deleteTemplate(final DeleteCommand cmd) {
final DataTO obj = cmd.getData();
final DataStoreTO dstore = obj.getDataStore();
if (dstore instanceof NfsTO) {
final NfsTO nfs = (NfsTO) dstore;
String relativeTemplatePath = obj.getPath();
String parent = getRootDir(nfs.getUrl());
if (relativeTemplatePath.startsWith(File.separator)) {
relativeTemplatePath = relativeTemplatePath.substring(1);
}
if (!parent.endsWith(File.separator)) {
parent += File.separator;
}
final String absoluteTemplatePath = parent + relativeTemplatePath;
final File tmpltPath = new File(absoluteTemplatePath);
File tmpltParent = null;
if (tmpltPath.exists() && tmpltPath.isDirectory()) {
tmpltParent = tmpltPath;
} else {
tmpltParent = tmpltPath.getParentFile();
}
String details = null;
if (!tmpltParent.exists()) {
details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
s_logger.debug(details);
return new Answer(cmd, true, details);
}
final File[] tmpltFiles = tmpltParent.listFiles();
if (tmpltFiles == null || tmpltFiles.length == 0) {
details = "No files under template parent directory " + tmpltParent.getName();
s_logger.debug(details);
} else {
boolean found = false;
for (final File f : tmpltFiles) {
if (!found && f.getName().equals("template.properties")) {
found = true;
}
// Don't let this stop us from cleaning up the template
if (f.isDirectory() && f.getName().equals("KVMHA")) {
s_logger.debug("Deleting KVMHA directory contents from template location");
final File[] haFiles = f.listFiles();
for (final File haFile : haFiles) {
haFile.delete();
}
}
if (!f.delete()) {
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath);
}
}
if (!found) {
details = "Can not find template.properties under " + tmpltParent.getName();
s_logger.debug(details);
}
}
if (!tmpltParent.delete()) {
details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath;
s_logger.debug(details);
return new Answer(cmd, false, details);
}
return new Answer(cmd, true, null);
} else {
return new Answer(cmd, false, "Unsupported image data store: " + dstore);
}
}
use of com.cloud.legacymodel.to.DataTO in project cosmic by MissionCriticalCloud.
the class StorageSubsystemCommandHandlerBase method execute.
protected Answer execute(final DeleteCommand cmd) {
final DataTO data = cmd.getData();
Answer answer = null;
if (data.getObjectType() == DataObjectType.VOLUME) {
answer = processor.deleteVolume(cmd);
} else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
answer = processor.deleteSnapshot(cmd);
} else {
answer = new Answer(cmd, false, "unsupported type");
}
return answer;
}
use of com.cloud.legacymodel.to.DataTO in project cosmic by MissionCriticalCloud.
the class StorageSubsystemCommandHandlerBase method execute.
protected Answer execute(final CopyCommand cmd) {
final DataTO srcData = cmd.getSrcTO();
final DataTO destData = cmd.getDestTO();
final DataStoreTO srcDataStore = srcData.getDataStore();
final DataStoreTO destDataStore = destData.getDataStore();
if (srcData.getObjectType() == DataObjectType.TEMPLATE && (srcData.getDataStore().getRole() == DataStoreRole.Image || srcData.getDataStore().getRole() == DataStoreRole.ImageCache) && destData.getDataStore().getRole() == DataStoreRole.Primary) {
// copy template to primary storage
return processor.copyTemplateToPrimaryStorage(cmd);
} else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) {
// clone template to a volume
return processor.cloneVolumeFromBaseTemplate(cmd);
} else if (srcData.getObjectType() == DataObjectType.VOLUME && (srcData.getDataStore().getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Image)) {
// copy volume from image cache to primary
return processor.copyVolumeFromImageCacheToPrimary(cmd);
} else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
if (destData.getObjectType() == DataObjectType.VOLUME) {
return processor.copyVolumeFromPrimaryToSecondary(cmd);
} else if (destData.getObjectType() == DataObjectType.TEMPLATE) {
return processor.createTemplateFromVolume(cmd);
}
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
return processor.backupSnapshot(cmd);
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.VOLUME) {
return processor.createVolumeFromSnapshot(cmd);
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
return processor.createTemplateFromSnapshot(cmd);
}
return new Answer(cmd, false, "not implemented yet");
}
Aggregations