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]


Reply via email to