Skip to content

Commit 5836a2d

Browse files
committed
handle upload todo, move common methods from HypervisorTemplateAdapter
to TemplateAdapterBase Signed-off-by: Abhishek Kumar <[email protected]>
1 parent 840c1c1 commit 5836a2d

File tree

3 files changed

+176
-136
lines changed

3 files changed

+176
-136
lines changed

plugins/hypervisors/external/src/main/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapter.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import java.util.Arrays;
2626
import java.util.Date;
27+
import java.util.LinkedList;
2728
import java.util.List;
2829
import java.util.Map;
2930

@@ -32,6 +33,7 @@
3233
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
3334
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
3435
import org.apache.cloudstack.context.CallContext;
36+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
3537
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
3638
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
3739
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
@@ -55,6 +57,8 @@
5557
import com.cloud.template.VirtualMachineTemplate;
5658
import com.cloud.user.Account;
5759
import com.cloud.utils.db.DB;
60+
import com.cloud.utils.db.Transaction;
61+
import com.cloud.utils.db.TransactionCallback;
5862
import com.cloud.utils.exception.CloudRuntimeException;
5963

6064
public class ExternalTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
@@ -147,8 +151,40 @@ public VMTemplateVO create(TemplateProfile profile) {
147151

148152
@Override
149153
public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(TemplateProfile profile) {
150-
// TODO: support External hypervisor for postupload
151-
return null;
154+
return Transaction.execute((TransactionCallback<List<TemplateOrVolumePostUploadCommand>>) status -> {
155+
if (Storage.ImageFormat.ISO.equals(profile.getFormat())) {
156+
throw new CloudRuntimeException("ISO upload is not supported for External hypervisor");
157+
}
158+
List<Long> zoneIdList = profile.getZoneIdList();
159+
if (zoneIdList == null) {
160+
throw new CloudRuntimeException("Zone ID is null, cannot upload template.");
161+
}
162+
if (zoneIdList.size() > 1) {
163+
throw new CloudRuntimeException("Operation is not supported for more than one zone id at a time.");
164+
}
165+
VMTemplateVO template = persistTemplate(profile, VirtualMachineTemplate.State.NotUploaded);
166+
if (template == null) {
167+
throw new CloudRuntimeException("Unable to persist the template " + profile.getTemplate());
168+
}
169+
// Set Event Details for Template/ISO Upload
170+
String eventResourceId = template.getUuid();
171+
CallContext.current().setEventDetails(String.format("Template Id: %s", eventResourceId));
172+
CallContext.current().putContextParameter(VirtualMachineTemplate.class, eventResourceId);
173+
Long zoneId = zoneIdList.get(0);
174+
DataStore imageStore = verifyHeuristicRulesForZone(template, zoneId);
175+
List<TemplateOrVolumePostUploadCommand> payloads = new LinkedList<>();
176+
if (imageStore == null) {
177+
List<DataStore> imageStores = getImageStoresThrowsExceptionIfNotFound(zoneId, profile);
178+
postUploadAllocation(imageStores, template, payloads);
179+
} else {
180+
postUploadAllocation(List.of(imageStore), template, payloads);
181+
}
182+
if (payloads.isEmpty()) {
183+
throw new CloudRuntimeException("Unable to find zone or an image store with enough capacity");
184+
}
185+
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), Resource.ResourceType.template);
186+
return payloads;
187+
});
152188
}
153189

154190
@Override

server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java

Lines changed: 2 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
import javax.inject.Inject;
3030

31-
import com.cloud.domain.Domain;
32-
import com.cloud.vm.VMInstanceVO;
33-
import com.cloud.vm.dao.VMInstanceDao;
3431
import org.apache.cloudstack.agent.directdownload.CheckUrlAnswer;
3532
import org.apache.cloudstack.agent.directdownload.CheckUrlCommand;
3633
import org.apache.cloudstack.annotation.AnnotationService;
@@ -44,13 +41,8 @@
4441
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
4542
import org.apache.cloudstack.context.CallContext;
4643
import org.apache.cloudstack.direct.download.DirectDownloadManager;
47-
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
4844
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
49-
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
50-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
51-
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
5245
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
53-
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
5446
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
5547
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
5648
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
@@ -61,19 +53,16 @@
6153
import org.apache.cloudstack.framework.async.AsyncRpcContext;
6254
import org.apache.cloudstack.framework.messagebus.MessageBus;
6355
import org.apache.cloudstack.framework.messagebus.PublishScope;
64-
import org.apache.cloudstack.secstorage.heuristics.HeuristicType;
6556
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
6657
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
6758
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
68-
import org.apache.cloudstack.storage.heuristics.HeuristicRuleHelper;
6959
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
7060
import org.apache.cloudstack.utils.security.DigestHelper;
7161
import org.apache.commons.collections.CollectionUtils;
7262

7363
import com.cloud.agent.AgentManager;
7464
import com.cloud.agent.api.Answer;
7565
import com.cloud.alert.AlertManager;
76-
import com.cloud.configuration.Config;
7766
import com.cloud.configuration.Resource.ResourceType;
7867
import com.cloud.dc.DataCenterVO;
7968
import com.cloud.dc.dao.DataCenterDao;
@@ -84,9 +73,7 @@
8473
import com.cloud.exception.ResourceAllocationException;
8574
import com.cloud.host.HostVO;
8675
import com.cloud.hypervisor.Hypervisor;
87-
import com.cloud.org.Grouping;
8876
import com.cloud.resource.ResourceManager;
89-
import com.cloud.server.StatsCollector;
9077
import com.cloud.storage.ScopeType;
9178
import com.cloud.storage.Storage.ImageFormat;
9279
import com.cloud.storage.Storage.TemplateType;
@@ -109,31 +96,25 @@
10996
import com.cloud.utils.db.TransactionCallback;
11097
import com.cloud.utils.db.TransactionStatus;
11198
import com.cloud.utils.exception.CloudRuntimeException;
99+
import com.cloud.vm.VMInstanceVO;
100+
import com.cloud.vm.dao.VMInstanceDao;
112101

113102
public class HypervisorTemplateAdapter extends TemplateAdapterBase {
114103
@Inject
115104
DownloadMonitor _downloadMonitor;
116105
@Inject
117106
AgentManager _agentMgr;
118107
@Inject
119-
StatsCollector _statsCollector;
120-
@Inject
121108
TemplateDataStoreDao templateDataStoreDao;
122109
@Inject
123-
DataStoreManager storeMgr;
124-
@Inject
125110
TemplateService imageService;
126111
@Inject
127-
TemplateDataFactory imageFactory;
128-
@Inject
129112
TemplateManager templateMgr;
130113
@Inject
131114
AlertManager alertMgr;
132115
@Inject
133116
VMTemplateZoneDao templateZoneDao;
134117
@Inject
135-
EndPointSelector _epSelector;
136-
@Inject
137118
DataCenterDao _dcDao;
138119
@Inject
139120
MessageBus _messageBus;
@@ -148,8 +129,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
148129
@Inject
149130
private AnnotationDao annotationDao;
150131
@Inject
151-
private HeuristicRuleHelper heuristicRuleHelper;
152-
@Inject
153132
VMInstanceDao _vmInstanceDao;
154133

155134
@Override
@@ -320,24 +299,6 @@ protected void createTemplateWithinZones(TemplateProfile profile, VMTemplateVO t
320299
}
321300
}
322301

323-
protected List<DataStore> getImageStoresThrowsExceptionIfNotFound(long zoneId, TemplateProfile profile) {
324-
List<DataStore> imageStores = storeMgr.getImageStoresByZoneIds(zoneId);
325-
if (imageStores == null || imageStores.size() == 0) {
326-
throw new CloudRuntimeException(String.format("Unable to find image store to download the template [%s].", profile.getTemplate()));
327-
}
328-
return imageStores;
329-
}
330-
331-
protected DataStore verifyHeuristicRulesForZone(VMTemplateVO template, Long zoneId) {
332-
HeuristicType heuristicType;
333-
if (ImageFormat.ISO.equals(template.getFormat())) {
334-
heuristicType = HeuristicType.ISO;
335-
} else {
336-
heuristicType = HeuristicType.TEMPLATE;
337-
}
338-
return heuristicRuleHelper.getImageStoreIfThereIsHeuristicRule(zoneId, heuristicType, template);
339-
}
340-
341302
protected void standardImageStoreAllocation(List<DataStore> imageStores, VMTemplateVO template) {
342303
Set<Long> zoneSet = new HashSet<Long>();
343304
Collections.shuffle(imageStores);
@@ -361,44 +322,6 @@ protected void validateSecondaryStorageAndCreateTemplate(List<DataStore> imageSt
361322
}
362323
}
363324

364-
protected boolean isZoneAndImageStoreAvailable(DataStore imageStore, Long zoneId, Set<Long> zoneSet, boolean isTemplatePrivate) {
365-
if (zoneId == null) {
366-
logger.warn(String.format("Zone ID is null, cannot allocate ISO/template in image store [%s].", imageStore));
367-
return false;
368-
}
369-
370-
DataCenterVO zone = _dcDao.findById(zoneId);
371-
if (zone == null) {
372-
logger.warn("Unable to find zone by id [{}], so skip downloading template to its image store [{}].", zoneId, imageStore);
373-
return false;
374-
}
375-
376-
if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
377-
logger.info("Zone [{}] is disabled. Skip downloading template to its image store [{}].", zone, imageStore);
378-
return false;
379-
}
380-
381-
if (!_statsCollector.imageStoreHasEnoughCapacity(imageStore)) {
382-
logger.info("Image store doesn't have enough capacity. Skip downloading template to this image store [{}].", imageStore);
383-
return false;
384-
}
385-
386-
if (zoneSet == null) {
387-
logger.info(String.format("Zone set is null; therefore, the ISO/template should be allocated in every secondary storage of zone [%s].", zone));
388-
return true;
389-
}
390-
391-
if (isTemplatePrivate && zoneSet.contains(zoneId)) {
392-
logger.info(String.format("The template is private and it is already allocated in a secondary storage in zone [%s]; therefore, image store [%s] will be skipped.",
393-
zone, imageStore));
394-
return false;
395-
}
396-
397-
logger.info(String.format("Private template will be allocated in image store [%s] in zone [%s].", imageStore, zone));
398-
zoneSet.add(zoneId);
399-
return true;
400-
}
401-
402325
@Override
403326
public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(final TemplateProfile profile) {
404327
// persist entry in vm_template, vm_template_details and template_zone_ref tables, not that entry at template_store_ref is not created here, and created in createTemplateAsync.
@@ -452,61 +375,6 @@ public List<TemplateOrVolumePostUploadCommand> doInTransaction(TransactionStatus
452375
});
453376
}
454377

455-
/**
456-
* If the template/ISO is marked as private, then it is allocated to a random secondary storage; otherwise, allocates to every storage pool in every zone given by the
457-
* {@link TemplateProfile#getZoneIdList()}.
458-
*/
459-
private void postUploadAllocation(List<DataStore> imageStores, VMTemplateVO template, List<TemplateOrVolumePostUploadCommand> payloads) {
460-
Set<Long> zoneSet = new HashSet<>();
461-
Collections.shuffle(imageStores);
462-
for (DataStore imageStore : imageStores) {
463-
Long zoneId_is = imageStore.getScope().getScopeId();
464-
465-
if (!isZoneAndImageStoreAvailable(imageStore, zoneId_is, zoneSet, isPrivateTemplate(template))) {
466-
continue;
467-
}
468-
469-
TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
470-
471-
// persist template_store_ref entry
472-
DataObject templateOnStore = imageStore.create(tmpl);
473-
474-
// update template_store_ref and template state
475-
EndPoint ep = _epSelector.select(templateOnStore);
476-
if (ep == null) {
477-
String errMsg = String.format("There is no secondary storage VM for downloading template to image store %s", imageStore);
478-
logger.warn(errMsg);
479-
throw new CloudRuntimeException(errMsg);
480-
}
481-
482-
TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(template.getId(), template.getUuid(), tmpl.getInstallPath(), tmpl
483-
.getChecksum(), tmpl.getType().toString(), template.getUniqueName(), template.getFormat().toString(), templateOnStore.getDataStore().getUri(),
484-
templateOnStore.getDataStore().getRole().toString());
485-
//using the existing max template size configuration
486-
payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
487-
488-
Long accountId = template.getAccountId();
489-
Account account = _accountDao.findById(accountId);
490-
Domain domain = _domainDao.findById(account.getDomainId());
491-
492-
payload.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage, null));
493-
payload.setAccountId(accountId);
494-
payload.setRemoteEndPoint(ep.getPublicAddr());
495-
payload.setRequiresHvm(template.requiresHvm());
496-
payload.setDescription(template.getDisplayText());
497-
payloads.add(payload);
498-
}
499-
}
500-
501-
private boolean isPrivateTemplate(VMTemplateVO template){
502-
503-
// if public OR featured OR system template
504-
if(template.isPublicTemplate() || template.isFeatured() || template.getTemplateType() == TemplateType.SYSTEM)
505-
return false;
506-
else
507-
return true;
508-
}
509-
510378
private class CreateTemplateContext<T> extends AsyncRpcContext<T> {
511379
final TemplateInfo template;
512380

0 commit comments

Comments
 (0)