Long volumeId = command.getVolumeId();
Long snapshotId = command.getSnapshotId();
VMTemplateVO privateTemplate = null;
final Long accountId = null;
SnapshotVO snapshot = null;
VolumeVO volume = null;
try {
TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
long zoneId = 0;
if (snapshotId != null) {
snapshot = _snapshotDao.findById(snapshotId);
zoneId = snapshot.getDataCenterId();
} else if (volumeId != null) {
volume = _volumeDao.findById(volumeId);
zoneId = volume.getDataCenterId();
}
DataStore store = _dataStoreMgr.getImageStore(zoneId);
if (store == null) {
throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
}
AsyncCallFuture<TemplateApiResult> future = null;
if (snapshotId != null) {
SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
DataStore snapStore = snapInfo.getDataStore();
if (snapStore != null) {
store = snapStore; // pick snapshot image store to create template
}
future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store);
} else if (volumeId != null) {
VolumeInfo volInfo = _volFactory.getVolume(volumeId);
future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
} else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
}
CommandResult result = null;
try {
result = future.get();
if (result.isFailed()) {
privateTemplate = null;
s_logger.debug("Failed to create template" + result.getResult());
throw new CloudRuntimeException("Failed to create template" + result.getResult());
}
// create entries in template_zone_ref table
if (_dataStoreMgr.isRegionStore(store)) {
// template created on region store
_tmpltSvr.associateTemplateToZone(templateId, null);
} else {
VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
_tmpltZoneDao.persist(templateZone);
}
privateTemplate = _tmpltDao.findById(templateId);
if (snapshotId != null) {
//getting the prent volume
long parentVolumeId=_snapshotDao.findById(snapshotId).getVolumeId();
VolumeVO parentVolume = _volumeDao.findById(parentVolumeId);
if (parentVolume != null && parentVolume.getIsoId() != null && parentVolume.getIsoId() != 0) {
privateTemplate.setSourceTemplateId(parentVolume.getIsoId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
} else if (parentVolume != null && parentVolume.getTemplateId() != null) {
privateTemplate.setSourceTemplateId(parentVolume.getTemplateId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
}
}
else if (volumeId != null) {
VolumeVO parentVolume = _volumeDao.findById(volumeId);
if (parentVolume.getIsoId() != null && parentVolume.getIsoId() != 0) {
privateTemplate.setSourceTemplateId(parentVolume.getIsoId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
} else if (parentVolume.getTemplateId() != null) {
privateTemplate.setSourceTemplateId(parentVolume.getTemplateId());
_tmpltDao.update(privateTemplate.getId(), privateTemplate);
}
}
TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId,
privateTemplate.getId(), privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize());
_usageEventDao.persist(usageEvent);
} catch (InterruptedException e) {
s_logger.debug("Failed to create template", e);
throw new CloudRuntimeException("Failed to create template", e);
} catch (ExecutionException e) {
s_logger.debug("Failed to create template", e);
throw new CloudRuntimeException("Failed to create template", e);
}
} finally {
/*if (snapshot != null && snapshot.getSwiftId() != null
&& secondaryStorageURL != null && zoneId != null
&& accountId != null && volumeId != null) {
_snapshotMgr.deleteSnapshotsForVolume(secondaryStorageURL,
zoneId, accountId, volumeId);
}*/
if (privateTemplate == null) {
final VolumeVO volumeFinal = volume;
final SnapshotVO snapshotFinal = snapshot;
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
// template_store_ref entries should have been removed using our
// DataObject.processEvent command in case of failure, but clean
// it up here to avoid
// some leftovers which will cause removing template from
// vm_template table fail.
_tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
// Remove the template_zone_ref record
_tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
// Remove the template record
_tmpltDao.expunge(templateId);
// decrement resource count
if (accountId != null) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize()
: snapshotFinal.getSize()));
}
}
});