|
25 | 25 | import java.util.ArrayList; |
26 | 26 | import java.util.List; |
27 | 27 | import java.util.Map; |
| 28 | +import java.util.concurrent.ExecutorService; |
| 29 | +import java.util.concurrent.Executors; |
28 | 30 |
|
29 | 31 | import javax.ejb.Local; |
30 | 32 | import javax.naming.ConfigurationException; |
|
43 | 45 | import com.cloud.api.commands.DetachIsoCmd; |
44 | 46 | import com.cloud.api.commands.ExtractIsoCmd; |
45 | 47 | import com.cloud.api.commands.ExtractTemplateCmd; |
| 48 | +import com.cloud.api.commands.PrepareTemplateCmd; |
46 | 49 | import com.cloud.api.commands.RegisterIsoCmd; |
47 | 50 | import com.cloud.api.commands.RegisterTemplateCmd; |
48 | 51 | import com.cloud.async.AsyncJobManager; |
49 | 52 | import com.cloud.async.AsyncJobVO; |
| 53 | +import com.cloud.configuration.Config; |
50 | 54 | import com.cloud.configuration.ResourceCount.ResourceType; |
51 | 55 | import com.cloud.configuration.dao.ConfigurationDao; |
52 | 56 | import com.cloud.dc.DataCenter; |
|
74 | 78 | import com.cloud.storage.StorageManager; |
75 | 79 | import com.cloud.storage.StoragePool; |
76 | 80 | import com.cloud.storage.StoragePoolHostVO; |
| 81 | +import com.cloud.storage.StoragePoolStatus; |
77 | 82 | import com.cloud.storage.StoragePoolVO; |
78 | 83 | import com.cloud.storage.Upload; |
79 | 84 | import com.cloud.storage.Upload.Type; |
|
111 | 116 | import com.cloud.utils.component.ComponentLocator; |
112 | 117 | import com.cloud.utils.component.Inject; |
113 | 118 | import com.cloud.utils.component.Manager; |
| 119 | +import com.cloud.utils.concurrency.NamedThreadFactory; |
114 | 120 | import com.cloud.utils.db.DB; |
115 | 121 | import com.cloud.utils.db.JoinBuilder; |
116 | 122 | import com.cloud.utils.db.SearchBuilder; |
@@ -160,6 +166,9 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe |
160 | 166 | @Inject HypervisorGuruManager _hvGuruMgr; |
161 | 167 | protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch; |
162 | 168 |
|
| 169 | + int _storagePoolMaxWaitSeconds = 3600; |
| 170 | + ExecutorService _preloadExecutor; |
| 171 | + |
163 | 172 | @Inject (adapter=TemplateAdapter.class) |
164 | 173 | protected Adapters<TemplateAdapter> _adapters; |
165 | 174 |
|
@@ -220,6 +229,17 @@ public Long extract(ExtractTemplateCmd cmd) { |
220 | 229 | // FIXME: async job needs fixing |
221 | 230 | return extract(account, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr); |
222 | 231 | } |
| 232 | + |
| 233 | + @Override |
| 234 | + public VirtualMachineTemplate prepareTemplate(PrepareTemplateCmd cmd) { |
| 235 | + |
| 236 | + VMTemplateVO vmTemplate = _tmpltDao.findById(cmd.getTemplateId()); |
| 237 | + if(vmTemplate == null) |
| 238 | + throw new InvalidParameterValueException("Unable to find template " + cmd.getTemplateId()); |
| 239 | + |
| 240 | + prepareTemplateInAllStoragePools(vmTemplate, cmd.getZoneId()); |
| 241 | + return vmTemplate; |
| 242 | + } |
223 | 243 |
|
224 | 244 | private Long extract(Account account, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) { |
225 | 245 | String desc = "template"; |
@@ -328,7 +348,33 @@ private Long extract(Account account, Long templateId, String url, Long zoneId, |
328 | 348 | }else{ |
329 | 349 | return null; |
330 | 350 | } |
331 | | - } |
| 351 | + } |
| 352 | + |
| 353 | + public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) { |
| 354 | + List<StoragePoolVO> pools = _poolDao.listPoolsByStatus(StoragePoolStatus.Up); |
| 355 | + for(final StoragePoolVO pool : pools) { |
| 356 | + if(pool.getDataCenterId() == zoneId) { |
| 357 | + s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); |
| 358 | + this._preloadExecutor.execute(new Runnable() { |
| 359 | + public void run() { |
| 360 | + try { |
| 361 | + reallyRun(); |
| 362 | + } catch(Throwable e) { |
| 363 | + s_logger.warn("Unexpected exception ", e); |
| 364 | + } |
| 365 | + } |
| 366 | + |
| 367 | + private void reallyRun() { |
| 368 | + s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId()); |
| 369 | + prepareTemplateForCreate(template, pool); |
| 370 | + s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId()); |
| 371 | + } |
| 372 | + }); |
| 373 | + } else { |
| 374 | + s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + pool.getDataCenterId() + " is "); |
| 375 | + } |
| 376 | + } |
| 377 | + } |
332 | 378 |
|
333 | 379 | @Override @DB |
334 | 380 | public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO template, StoragePool pool) { |
@@ -391,7 +437,7 @@ public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO template, S |
391 | 437 |
|
392 | 438 | List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up); |
393 | 439 |
|
394 | | - templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200); |
| 440 | + templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds); |
395 | 441 | if (templateStoragePoolRef == null) { |
396 | 442 | throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId); |
397 | 443 | } |
@@ -699,6 +745,8 @@ public boolean configure(String name, Map<String, Object> params) throws Configu |
699 | 745 | HostSearch.done(); |
700 | 746 | HostTemplateStatesSearch.done(); |
701 | 747 |
|
| 748 | + _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); |
| 749 | + _preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader")); |
702 | 750 | return false; |
703 | 751 | } |
704 | 752 |
|
|
0 commit comments