DaanHoogland commented on a change in pull request #5216:
URL: https://github.com/apache/cloudstack/pull/5216#discussion_r692794263
##########
File path: server/src/main/java/com/cloud/template/TemplateManagerImpl.java
##########
@@ -1742,6 +1744,272 @@ public void
doInTransactionWithoutResult(TransactionStatus status) {
}
}
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE,
eventDescription = "creating actual private template", create = true)
+ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd, long
snapshotId, long templateId) throws CloudRuntimeException {
+ UserVm curVm = cmd.getTargetVM();
+ final Long accountId = curVm.getAccountId();
+ Account caller = CallContext.current().getCallingAccount();
+ List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(cmd.getId(),
Volume.Type.ROOT);
+ VolumeVO targetVolume = volumes.get(0);
+ long volumeId = targetVolume.getId();
+ VMTemplateVO finalTmpProduct = null;
+ SnapshotVO snapshot = null;
+ try {
+ TemplateInfo cloneTempalateInfp =
_tmplFactory.getTemplate(templateId, DataStoreRole.Image);
+ long zoneId = curVm.getDataCenterId();
+ AsyncCallFuture<TemplateApiResult> future = null;
+ VolumeInfo vInfo = _volFactory.getVolume(volumeId);
+ DataStore store =
_dataStoreMgr.getImageStoreWithFreeCapacity(zoneId);
+ snapshot = _snapshotDao.findById(snapshotId);
+// future = _tmpltSvr.createTemplateFromVolumeAsync(vInfo,
cloneTempalateInfp, store);
+ // create template from snapshot
+ DataStoreRole dataStoreRole =
ApiResponseHelper.getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
+ SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId,
dataStoreRole);
+ if (dataStoreRole == DataStoreRole.Image) {
+ if (snapInfo == null) {
+ snapInfo = _snapshotFactory.getSnapshot(snapshotId,
DataStoreRole.Primary);
+ if(snapInfo == null) {
+ throw new CloudRuntimeException("Cannot find snapshot
"+snapshotId);
+ }
+ // We need to copy the snapshot onto secondary.
+ SnapshotStrategy snapshotStrategy =
_storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
+ snapshotStrategy.backupSnapshot(snapInfo);
+
+ // Attempt to grab it again.
+ snapInfo = _snapshotFactory.getSnapshot(snapshotId,
dataStoreRole);
+ if(snapInfo == null) {
+ throw new CloudRuntimeException("Cannot find snapshot
" + snapshotId + " on secondary and could not create backup");
+ }
+ }
+ _accountMgr.checkAccess(caller, null, true, snapInfo);
+ DataStore snapStore = snapInfo.getDataStore();
+
+ if (snapStore != null) {
+ store = snapStore; // pick snapshot image store to create
template
+ }
+ }
+ future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo,
cloneTempalateInfp, store);
+ // wait for the result to converge
+ CommandResult result = null;
+ try {
+ result = future.get();
+
+ if (result.isFailed()) {
+ finalTmpProduct = null;
+ s_logger.warn("Failed to create template: " +
result.getResult());
+ throw new CloudRuntimeException("Failed to create
template: " + result.getResult());
+ }
+ if (_dataStoreMgr.isRegionStore(store)) {
+ _tmpltSvr.associateTemplateToZone(templateId, null);
+ } else {
+ // Already done in the record to db step
+ VMTemplateZoneVO templateZone = new
VMTemplateZoneVO(zoneId, templateId, new Date());
+ _tmpltZoneDao.persist(templateZone);
+ }
+ s_logger.info("successfully created the template with Id: " +
templateId);
+ finalTmpProduct = _tmpltDao.findById(templateId);
+ TemplateDataStoreVO srcTmpltStore =
_tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
+ try {
+ srcTmpltStore.getSize();
+ } catch (NullPointerException e) {
+ srcTmpltStore.setSize(0L);
+ _tmplStoreDao.update(srcTmpltStore.getId(), srcTmpltStore);
+ }
+ UsageEventVO usageEvent =
+ new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE,
finalTmpProduct.getAccountId(), zoneId, finalTmpProduct.getId(),
finalTmpProduct.getName(), null,
+ finalTmpProduct.getSourceTemplateId(),
srcTmpltStore.getPhysicalSize(), finalTmpProduct.getSize());
+ _usageEventDao.persist(usageEvent);
+ } catch (InterruptedException e) {
+ s_logger.debug("Failed to create template for id: " +
templateId, e);
+ throw new CloudRuntimeException("Failed to create template" ,
e);
+ } catch (ExecutionException e) {
+ s_logger.debug("Failed to create template for id: " +
templateId, e);
+ throw new CloudRuntimeException("Failed to create template ",
e);
+ }
+
+ } finally {
+ finalTmpProduct = _tmpltDao.findById(templateId);
+ if (finalTmpProduct == null) {
+ final VolumeVO volumeFinal = targetVolume;
+ 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()));
+ }
+ }
+ });
+
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Snapshot createSnapshotFromTemplateOwner(long vmId, UserVm curVm,
Account templateOwner, VolumeApiService volumeService) throws
ResourceAllocationException {
+ Account caller = CallContext.current().getCallingAccount();
+ _accountMgr.checkAccess(caller, null, true, templateOwner);
+// UserVm curVm = cmd.getTargetVM();
+ Long nextSnapId = _tmpltDao.getNextInSequence(Long.class, "id");
+ Long volumeId = _volumeDao.findByInstanceAndType(vmId,
Volume.Type.ROOT).get(0).getId();
+ VolumeVO volume = _volumeDao.findById(volumeId);
+ if (volume == null) {
+ throw new InvalidParameterValueException("Failed to create private
template record, unable to find root volume " + volumeId);
+ }
+
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, volume);
+ s_logger.info("Creating snapshot for the tempalte creation");
+ SnapshotVO snapshot = (SnapshotVO)
volumeService.allocSnapshot(volumeId, Snapshot.INTERNAL_POLICY_ID,
curVm.getDisplayName() + "-Clone-" + nextSnapId, null);
+ if (snapshot == null) {
+ throw new CloudRuntimeException("Unable to create a snapshot
during the template creation recording");
+ }
+ Snapshot snapshotEntity = volumeService.takeSnapshot(volumeId,
Snapshot.INTERNAL_POLICY_ID, snapshot.getId(), caller, false, null, false, new
HashMap<>());
+ if (snapshotEntity == null) {
+ throw new CloudRuntimeException("Error when creating the snapshot
entity");
+ }
+ if (snapshotEntity.getState() != Snapshot.State.BackedUp) {
+ throw new CloudRuntimeException("Async backup of snapshot happens
during the clone for snapshot id: " + snapshot.getId());
+ }
+ return snapshot;
+ }
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE,
eventDescription = "creating template from clone", create = true)
+ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account
templateOwner, VolumeApiService volumeService, Snapshot snapshot) throws
ResourceAllocationException {
+ Account caller = CallContext.current().getCallingAccount();
+ _accountMgr.checkAccess(caller, null, true, templateOwner);
+ String name = cmd.getTemplateName();
+ if (name.length() > 32) {
+
+ name = name.substring(5) + "-QA-Clone";
+ }
+
+ boolean featured = false;
+ boolean isPublic = cmd.isPublic();
+ UserVm curVm = cmd.getTargetVM();
+ long zoneId = curVm.getDataCenterId();
+ Long volumeId = _volumeDao.findByInstanceAndType(cmd.getId(),
Volume.Type.ROOT).get(0).getId();
+ HypervisorType hyperType = null;
+ VolumeVO volume = _volumeDao.findById(volumeId);
+ if (volume == null) {
+ throw new InvalidParameterValueException("Failed to create private
template record, unable to find root volume " + volumeId);
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, volume);
+
+ // If private template is created from Volume, check that the volume
+ // will not be active when the private template is
+ // created
+// if (!_volumeMgr.volumeInactive(volume)) {
+// String msg = "Unable to create private template for volume: " +
volume.getName() + "; volume is attached to a non-stopped VM, please stop the
VM first";
+// if (s_logger.isInfoEnabled()) {
+// s_logger.info(msg);
+// }
+// / throw new CloudRuntimeException(msg);
+// }
+
Review comment:
```suggestion
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]