use of com.cloud.legacymodel.to.SnapshotObjectTO in project cosmic by MissionCriticalCloud.
the class Xenserver625StorageProcessor method createTemplateFromSnapshot.
@Override
public Answer createTemplateFromSnapshot(final CopyCommand cmd) {
final Connection conn = hypervisorResource.getConnection();
final DataTO srcData = cmd.getSrcTO();
final DataTO destData = cmd.getDestTO();
if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof NfsTO) {
return createTemplateFromSnapshot2(cmd);
}
final int wait = cmd.getWait();
final SnapshotObjectTO srcObj = (SnapshotObjectTO) srcData;
final TemplateObjectTO destObj = (TemplateObjectTO) destData;
final NfsTO srcStore = (NfsTO) srcObj.getDataStore();
final NfsTO destStore = (NfsTO) destObj.getDataStore();
URI srcUri = null;
URI destUri = null;
try {
srcUri = new URI(srcStore.getUrl());
destUri = new URI(destStore.getUrl());
} catch (final Exception e) {
s_logger.debug("incorrect url", e);
return new CopyCmdAnswer("incorrect url" + e.toString());
}
final String srcPath = srcObj.getPath();
final int index = srcPath.lastIndexOf("/");
final String srcDir = srcPath.substring(0, index);
final String destDir = destObj.getPath();
SR srcSr = null;
SR destSr = null;
VDI destVdi = null;
boolean result = false;
try {
srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir);
final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir);
makeDirectory(conn, localDir + "/" + destDir);
destSr = createFileSR(conn, localDir + "/" + destDir);
final String nameLabel = "cloud-" + UUID.randomUUID().toString();
final String[] parents = srcObj.getParents();
final List<VDI> snapshotChains = new ArrayList<>();
if (parents != null) {
for (int i = 0; i < parents.length; i++) {
final String snChainPath = parents[i];
final String uuid = getSnapshotUuid(snChainPath);
final VDI chain = VDI.getByUuid(conn, uuid);
snapshotChains.add(chain);
}
}
final String snapshotUuid = getSnapshotUuid(srcPath);
final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
snapshotChains.add(snapshotVdi);
final long templateVirtualSize = snapshotChains.get(0).getVirtualSize(conn);
destVdi = createVdi(conn, nameLabel, destSr, templateVirtualSize);
final String destVdiUuid = destVdi.getUuid(conn);
for (final VDI snapChain : snapshotChains) {
final Task task = snapChain.copyAsync(conn, null, null, destVdi);
// poll every 1 seconds ,
hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
hypervisorResource.checkForSuccess(conn, task);
task.destroy(conn);
}
destVdi = VDI.getByUuid(conn, destVdiUuid);
// scan makes XenServer pick up VDI physicalSize
destSr.scan(conn);
final String templateUuid = destVdi.getUuid(conn);
final String templateFilename = templateUuid + ".vhd";
final long virtualSize = destVdi.getVirtualSize(conn);
final long physicalSize = destVdi.getPhysicalUtilisation(conn);
String templatePath = destNfsPath + "/" + destDir;
templatePath = templatePath.replaceAll("//", "/");
result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, destObj.getId());
if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
}
final TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(destDir + "/" + templateFilename);
newTemplate.setFormat(ImageFormat.VHD);
newTemplate.setSize(destVdi.getVirtualSize(conn));
newTemplate.setPhysicalSize(destVdi.getPhysicalUtilisation(conn));
newTemplate.setName(destVdiUuid);
result = true;
return new CopyCmdAnswer(newTemplate);
} catch (final Exception e) {
s_logger.error("Failed create template from snapshot", e);
return new CopyCmdAnswer("Failed create template from snapshot " + e.toString());
} finally {
if (!result) {
if (destVdi != null) {
try {
destVdi.destroy(conn);
} catch (final Exception e) {
s_logger.debug("Clean up left over on dest storage failed: ", e);
}
}
}
if (srcSr != null) {
hypervisorResource.removeSR(conn, srcSr);
}
if (destSr != null) {
hypervisorResource.removeSR(conn, destSr);
}
}
}
use of com.cloud.legacymodel.to.SnapshotObjectTO in project cosmic by MissionCriticalCloud.
the class Xenserver625StorageProcessor method createVolumeFromSnapshot.
@Override
public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
final Connection conn = hypervisorResource.getConnection();
final DataTO srcData = cmd.getSrcTO();
final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
final DataTO destData = cmd.getDestTO();
final PrimaryDataStoreTO pool = (PrimaryDataStoreTO) destData.getDataStore();
final VolumeObjectTO volume = (VolumeObjectTO) destData;
final DataStoreTO imageStore = srcData.getDataStore();
if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof PrimaryDataStoreTO) {
return createVolumeFromSnapshot2(cmd);
}
if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
}
final NfsTO nfsImageStore = (NfsTO) imageStore;
final String primaryStorageNameLabel = pool.getUuid();
final String secondaryStorageUrl = nfsImageStore.getUrl();
final int wait = cmd.getWait();
boolean result = false;
// Generic error message.
String details = null;
String volumeUUID = null;
if (secondaryStorageUrl == null) {
details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
return new CopyCmdAnswer(details);
}
SR srcSr = null;
VDI destVdi = null;
try {
final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
if (primaryStorageSR == null) {
throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel);
}
final String nameLabel = "cloud-" + UUID.randomUUID().toString();
destVdi = createVdi(conn, nameLabel, primaryStorageSR, volume.getSize());
volumeUUID = destVdi.getUuid(conn);
final String snapshotInstallPath = snapshot.getPath();
final int index = snapshotInstallPath.lastIndexOf(File.separator);
final String snapshotDirectory = snapshotInstallPath.substring(0, index);
final String snapshotUuid = getSnapshotUuid(snapshotInstallPath);
final URI uri = new URI(secondaryStorageUrl);
srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory);
final String[] parents = snapshot.getParents();
final List<VDI> snapshotChains = new ArrayList<>();
if (parents != null) {
for (int i = 0; i < parents.length; i++) {
final String snChainPath = parents[i];
final String uuid = getSnapshotUuid(snChainPath);
final VDI chain = VDI.getByUuid(conn, uuid);
snapshotChains.add(chain);
}
}
final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
snapshotChains.add(snapshotVdi);
for (final VDI snapChain : snapshotChains) {
final Task task = snapChain.copyAsync(conn, null, null, destVdi);
// poll every 1 seconds ,
hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
hypervisorResource.checkForSuccess(conn, task);
task.destroy(conn);
}
result = true;
destVdi = VDI.getByUuid(conn, volumeUUID);
final VDI.Record vdir = destVdi.getRecord(conn);
final VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(volumeUUID);
newVol.setSize(vdir.virtualSize);
return new CopyCmdAnswer(newVol);
} catch (final Types.XenAPIException e) {
details += " due to " + e.toString();
s_logger.warn(details, e);
} catch (final Exception e) {
details += " due to " + e.getMessage();
s_logger.warn(details, e);
} finally {
if (srcSr != null) {
hypervisorResource.removeSR(conn, srcSr);
}
if (!result && destVdi != null) {
try {
destVdi.destroy(conn);
} catch (final Exception e) {
s_logger.debug("destroy dest vdi failed", e);
}
}
}
if (!result) {
// Is this logged at a higher level?
s_logger.error(details);
}
// In all cases return something.
return new CopyCmdAnswer(details);
}
use of com.cloud.legacymodel.to.SnapshotObjectTO in project cosmic by MissionCriticalCloud.
the class Xenserver625StorageProcessor method createTemplateFromSnapshot2.
public Answer createTemplateFromSnapshot2(final CopyCommand cmd) {
final Connection conn = hypervisorResource.getConnection();
final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO) cmd.getSrcTO();
final TemplateObjectTO templateObjTO = (TemplateObjectTO) cmd.getDestTO();
if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) {
return null;
}
NfsTO destStore = null;
URI destUri = null;
try {
destStore = (NfsTO) templateObjTO.getDataStore();
destUri = new URI(destStore.getUrl());
} catch (final Exception ex) {
s_logger.debug("Invalid URI", ex);
return new CopyCmdAnswer("Invalid URI: " + ex.toString());
}
SR srcSr = null;
SR destSr = null;
final String destDir = templateObjTO.getPath();
VDI destVdi = null;
boolean result = false;
try {
final Map<String, String> srcDetails = cmd.getOptions();
final String iScsiName = srcDetails.get(DiskTO.IQN);
final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true);
final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
mountNfs(conn, destNfsPath, localDir);
makeDirectory(conn, localDir + "/" + destDir);
destSr = createFileSR(conn, localDir + "/" + destDir);
// there should only be one VDI in this SR
final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
destVdi = srcVdi.copy(conn, destSr);
final String nameLabel = "cloud-" + UUID.randomUUID().toString();
destVdi.setNameLabel(conn, nameLabel);
// scan makes XenServer pick up VDI physicalSize
destSr.scan(conn);
final String templateUuid = destVdi.getUuid(conn);
final String templateFilename = templateUuid + ".vhd";
final long virtualSize = destVdi.getVirtualSize(conn);
final long physicalSize = destVdi.getPhysicalUtilisation(conn);
// create the template.properties file
String templatePath = destNfsPath + "/" + destDir;
templatePath = templatePath.replaceAll("//", "/");
result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, templateObjTO.getId());
if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
}
final TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(destDir + "/" + templateFilename);
newTemplate.setFormat(ImageFormat.VHD);
newTemplate.setHypervisorType(HypervisorType.XenServer);
newTemplate.setSize(virtualSize);
newTemplate.setPhysicalSize(physicalSize);
newTemplate.setName(templateUuid);
result = true;
return new CopyCmdAnswer(newTemplate);
// } catch (Exception ex) {
// s_logger.error("Failed to create a template from a snapshot",
// ex);
//
// return new
// CopyCmdAnswer("Failed to create a template from a snapshot: " +
// ex.toString());
} catch (final BadServerResponse e) {
s_logger.error("Failed to create a template from a snapshot due to incomprehensible server response", e);
return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
} catch (final XenAPIException e) {
s_logger.error("Failed to create a template from a snapshot due to xenapi error", e);
return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
} catch (final XmlRpcException e) {
s_logger.error("Failed to create a template from a snapshot due to rpc error", e);
return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
} finally {
if (!result) {
if (destVdi != null) {
try {
destVdi.destroy(conn);
} catch (final Exception e) {
s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e);
}
}
}
if (srcSr != null) {
hypervisorResource.removeSR(conn, srcSr);
}
if (destSr != null) {
hypervisorResource.removeSR(conn, destSr);
}
}
}
use of com.cloud.legacymodel.to.SnapshotObjectTO in project cosmic by MissionCriticalCloud.
the class XenserverSnapshotStrategy method backupSnapshot.
@Override
public SnapshotInfo backupSnapshot(final SnapshotInfo snapshot) {
final SnapshotInfo parentSnapshot = snapshot.getParent();
if (parentSnapshot != null && snapshot.getPath().equalsIgnoreCase(parentSnapshot.getPath())) {
s_logger.debug("backup an empty snapshot");
// don't need to backup this snapshot
final SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
if (parentSnapshotOnBackupStore != null && parentSnapshotOnBackupStore.getState() == State.Ready) {
final DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), parentSnapshotOnBackupStore.getRole());
final SnapshotInfo snapshotOnImageStore = (SnapshotInfo) store.create(snapshot);
snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
final SnapshotObjectTO snapTO = new SnapshotObjectTO();
snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath());
final CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO);
snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer);
final SnapshotObject snapObj = (SnapshotObject) snapshot;
try {
snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
} catch (final NoTransitionException e) {
s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString());
throw new CloudRuntimeException(e.toString());
}
return snapshotDataFactory.getSnapshot(snapObj.getId(), store);
} else {
s_logger.debug("parent snapshot hasn't been backed up yet");
}
}
// determine full snapshot backup or not
boolean fullBackup = true;
SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Image);
final SnapshotDataStoreVO parentSnapshotOnPrimaryStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
final HypervisorType hypervisorType = snapshot.getBaseVolume().getHypervisorType();
if (parentSnapshotOnPrimaryStore != null && parentSnapshotOnBackupStore != null && hypervisorType == HypervisorType.XenServer) {
// CS does incremental backup
// only for XenServer
// In case of volume migration from one pool to other pool, CS should take full snapshot to avoid any issues with delta chain,
// to check if this is a migrated volume, compare the current pool id of volume and store_id of oldest snapshot on primary for this volume.
// Why oldest? Because at this point CS has two snapshot on primary entries for same volume, one with old pool_id and other one with
// current pool id. So, verify and if volume found to be migrated, delete snapshot entry with previous pool store_id.
final SnapshotDataStoreVO oldestSnapshotOnPrimary = snapshotStoreDao.findOldestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
final VolumeVO volume = volumeDao.findById(snapshot.getVolumeId());
if (oldestSnapshotOnPrimary != null) {
if (oldestSnapshotOnPrimary.getDataStoreId() == volume.getPoolId()) {
final int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
final int deltaSnap = _deltaSnapshotMax;
int i;
for (i = 1; i < deltaSnap; i++) {
final Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId();
if (prevBackupId == 0) {
break;
}
parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image);
if (parentSnapshotOnBackupStore == null) {
break;
}
}
if (i >= deltaSnap) {
fullBackup = true;
} else {
fullBackup = false;
}
} else {
// if there is an snapshot entry for previousPool(primary storage) of migrated volume, delete it becasue CS created one more snapshot entry for current pool
snapshotStoreDao.remove(oldestSnapshotOnPrimary.getId());
}
}
}
snapshot.addPayload(fullBackup);
return snapshotSvr.backupSnapshot(snapshot);
}
Aggregations