StoragePoolVO pool = null;
HostVO secondaryStorageHost = null;
Long zoneId = null;
Long accountId = null;
SnapshotVO snapshot = null;
String secondaryStorageURL = null;
try {
if (snapshotId != null) { // create template from snapshot
snapshot = _snapshotDao.findById(snapshotId);
if (snapshot == null) {
throw new CloudRuntimeException("Unable to find Snapshot for Id " + snapshotId);
}
zoneId = snapshot.getDataCenterId();
secondaryStorageHost = _snapshotMgr.getSecondaryStorageHost(snapshot);
secondaryStorageURL = _snapshotMgr.getSecondaryStorageURL(snapshot);
String name = command.getTemplateName();
String backupSnapshotUUID = snapshot.getBackupSnapshotId();
if (backupSnapshotUUID == null) {
throw new CloudRuntimeException("Unable to create private template from snapshot " + snapshotId + " due to there is no backupSnapshotUUID for this snapshot");
}
Long dcId = snapshot.getDataCenterId();
accountId = snapshot.getAccountId();
volumeId = snapshot.getVolumeId();
String origTemplateInstallPath = null;
List<StoragePoolVO> pools = _storageMgr.ListByDataCenterHypervisor(zoneId, snapshot.getHypervisorType());
if (pools == null || pools.size() == 0 ) {
throw new CloudRuntimeException("Unable to find storage pools in zone " + zoneId);
}
pool = pools.get(0);
if (snapshot.getVersion() != null && snapshot.getVersion().equalsIgnoreCase("2.1")) {
VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId);
if (volume == null) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unable to find orignal volume:" + volumeId + ", try it later ");
}
if ( volume.getTemplateId() == null ) {
_snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
} else {
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
if (template == null) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unalbe to find orignal template :" + volume.getTemplateId() + ", try it later ");
}
Long origTemplateId = template.getId();
Long origTmpltAccountId = template.getAccountId();
if (!_volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to volume:" + volumeId + " is being used, try it later ");
}
cmd = new UpgradeSnapshotCommand(null, secondaryStorageURL, dcId, accountId, volumeId, origTemplateId, origTmpltAccountId, null, snapshot.getBackupSnapshotId(),
snapshot.getName(), "2.1");
if (!_volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
}
Answer answer = null;
try {
answer = _storageMgr.sendToPool(pool, cmd);
cmd = null;
} catch (StorageUnavailableException e) {
} finally {
_volsDao.unlockFromLockTable(volumeId.toString());
}
if ((answer != null) && answer.getResult()) {
_snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
} else {
throw new CloudRuntimeException("Unable to upgrade snapshot");
}
}
}
if( snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0 ) {
_snapshotMgr.downloadSnapshotsFromSwift(snapshot);
}
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(), secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
origTemplateInstallPath, templateId, name, _createprivatetemplatefromsnapshotwait);
} else if (volumeId != null) {
VolumeVO volume = _volsDao.findById(volumeId);
if (volume == null) {
throw new CloudRuntimeException("Unable to find volume for Id " + volumeId);
}
accountId = volume.getAccountId();
if (volume.getPoolId() == null) {
_templateDao.remove(templateId);
throw new CloudRuntimeException("Volume " + volumeId + " is empty, can't create template on it");
}
String vmName = _storageMgr.getVmNameOnVolume(volume);
zoneId = volume.getDataCenterId();
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
if (secondaryStorageHost == null) {
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
}
secondaryStorageURL = secondaryStorageHost.getStorageUrl();
pool = _storagePoolDao.findById(volume.getPoolId());
cmd = new CreatePrivateTemplateFromVolumeCommand(pool.getUuid(), secondaryStorageURL, templateId, accountId, command.getTemplateName(), uniqueName, volume.getPath(), vmName, _createprivatetemplatefromvolumewait);
} else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
}
// FIXME: before sending the command, check if there's enough capacity
// on the storage server to create the template
// This can be sent to a KVM host too.
CreatePrivateTemplateAnswer answer = null;
if (snapshotId != null) {
if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
throw new CloudRuntimeException("Creating template from snapshot failed due to snapshot:" + snapshotId + " is being used, try it later ");
}
} else {
if (!_volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("Creating template from volume failed due to volume:" + volumeId + " is being used, try it later ");
}
}
try {
answer = (CreatePrivateTemplateAnswer) _storageMgr.sendToPool(pool, cmd);
} catch (StorageUnavailableException e) {
} finally {
if (snapshotId != null) {
_snapshotDao.unlockFromLockTable(snapshotId.toString());
} else {
_volsDao.unlockFromLockTable(volumeId.toString());
}
}
if ((answer != null) && answer.getResult()) {
privateTemplate = _templateDao.findById(templateId);
String answerUniqueName = answer.getUniqueName();
if (answerUniqueName != null) {
privateTemplate.setUniqueName(answerUniqueName);
} else {
privateTemplate.setUniqueName(uniqueName);
}
ImageFormat format = answer.getImageFormat();
if (format != null) {
privateTemplate.setFormat(format);
} else {
// This never occurs.
// Specify RAW format makes it unusable for snapshots.
privateTemplate.setFormat(ImageFormat.RAW);
}
String checkSum = getChecksum(secondaryStorageHost.getId(), answer.getPath());
Transaction txn = Transaction.currentTxn();
txn.start();
privateTemplate.setChecksum(checkSum);
_templateDao.update(templateId, privateTemplate);
// add template zone ref for this template
_templateDao.addTemplateToZone(privateTemplate, zoneId);
VMTemplateHostVO templateHostVO = new VMTemplateHostVO(secondaryStorageHost.getId(), templateId);
templateHostVO.setDownloadPercent(100);
templateHostVO.setDownloadState(Status.DOWNLOADED);
templateHostVO.setInstallPath(answer.getPath());
templateHostVO.setLastUpdated(new Date());
templateHostVO.setSize(answer.getVirtualSize());
templateHostVO.setPhysicalSize(answer.getphysicalSize());
_templateHostDao.persist(templateHostVO);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), secondaryStorageHost.getDataCenterId(), privateTemplate.getId(),
privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), templateHostVO.getSize());
_usageEventDao.persist(usageEvent);
txn.commit();
}
} finally {
if (snapshot != null && snapshot.getSwiftId() != null && secondaryStorageURL != null && zoneId != null && accountId != null && volumeId != null) {
_snapshotMgr.deleteSnapshotsForVolume (secondaryStorageURL, zoneId, accountId, volumeId);
}
if (privateTemplate == null) {
Transaction txn = Transaction.currentTxn();
txn.start();