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, 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, 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);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(),
secondaryStorageHost.getDataCenterId(), privateTemplate.getId(),
privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(),
templateHostVO.getSize(), VirtualMachineTemplate.class.getName(), privateTemplate.getUuid());
txn.commit();
}
} finally {
if (snapshot != null && snapshot.getSwiftId() != null
&& secondaryStorageURL != null && zoneId != null
&& accountId != null && volumeId != null) {
_snapshotMgr.deleteSnapshotsForVolume(secondaryStorageURL,
zoneId, accountId, volumeId);
}