|
23 | 23 |
|
24 | 24 | import javax.inject.Inject; |
25 | 25 |
|
| 26 | +import com.cloud.storage.StoragePool; |
26 | 27 | import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; |
27 | 28 | import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; |
28 | 29 | import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; |
29 | 30 | import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; |
30 | 31 | import org.apache.cloudstack.storage.configdrive.ConfigDrive; |
31 | 32 | import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder; |
32 | 33 | import org.apache.cloudstack.storage.to.TemplateObjectTO; |
| 34 | +import org.apache.commons.collections.CollectionUtils; |
| 35 | +import org.apache.commons.collections.MapUtils; |
33 | 36 | import org.apache.log4j.Logger; |
34 | 37 |
|
35 | 38 | import com.cloud.agent.AgentManager; |
|
56 | 59 | import com.cloud.service.dao.ServiceOfferingDao; |
57 | 60 | import com.cloud.storage.DataStoreRole; |
58 | 61 | import com.cloud.storage.Storage; |
59 | | -import com.cloud.storage.StoragePool; |
60 | 62 | import com.cloud.storage.Volume; |
61 | 63 | import com.cloud.storage.VolumeVO; |
62 | 64 | import com.cloud.storage.dao.GuestOSCategoryDao; |
@@ -322,27 +324,78 @@ public void commitMigration(NicProfile nic, Network network, VirtualMachineProfi |
322 | 324 | private DataStore findDataStore(VirtualMachineProfile profile, DeployDestination dest) { |
323 | 325 | DataStore dataStore = null; |
324 | 326 | if (VirtualMachineManager.VmConfigDriveOnPrimaryPool.value()) { |
325 | | - if (dest.getStorageForDisks() != null) { |
326 | | - for (final Volume volume : dest.getStorageForDisks().keySet()) { |
327 | | - if (volume.getVolumeType() == Volume.Type.ROOT) { |
328 | | - final StoragePool primaryPool = dest.getStorageForDisks().get(volume); |
329 | | - dataStore = _dataStoreMgr.getDataStore(primaryPool.getId(), DataStoreRole.Primary); |
330 | | - break; |
331 | | - } |
332 | | - } |
| 327 | + if(MapUtils.isNotEmpty(dest.getStorageForDisks())) { |
| 328 | + dataStore = getPlannedDataStore(dest, dataStore); |
333 | 329 | } |
334 | 330 | if (dataStore == null) { |
335 | | - final List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(profile.getVirtualMachine().getId(), Volume.Type.ROOT); |
336 | | - if (volumes != null && volumes.size() > 0) { |
337 | | - dataStore = _dataStoreMgr.getDataStore(volumes.get(0).getPoolId(), DataStoreRole.Primary); |
338 | | - } |
| 331 | + dataStore = pickExistingRootVolumeFromDataStore(profile, dataStore); |
339 | 332 | } |
340 | 333 | } else { |
341 | 334 | dataStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId()); |
342 | 335 | } |
343 | 336 | return dataStore; |
344 | 337 | } |
345 | 338 |
|
| 339 | + private DataStore getPlannedDataStore(DeployDestination dest, DataStore dataStore) { |
| 340 | + for (final Volume volume : dest.getStorageForDisks().keySet()) { |
| 341 | + if (volume.getVolumeType() == Volume.Type.ROOT) { |
| 342 | + final StoragePool primaryPool = dest.getStorageForDisks().get(volume); |
| 343 | + dataStore = _dataStoreMgr.getDataStore(primaryPool.getId(), DataStoreRole.Primary); |
| 344 | + break; |
| 345 | + } |
| 346 | + } |
| 347 | + return dataStore; |
| 348 | + } |
| 349 | + |
| 350 | + private DataStore pickExistingRootVolumeFromDataStore(VirtualMachineProfile profile, DataStore dataStore) { |
| 351 | + final List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(profile.getVirtualMachine().getId(), Volume.Type.ROOT); |
| 352 | + if (CollectionUtils.isNotEmpty(volumes)) { |
| 353 | + dataStore = pickDataStoreFromVolumes(volumes); |
| 354 | + } |
| 355 | + return dataStore; |
| 356 | + } |
| 357 | + |
| 358 | + private DataStore pickDataStoreFromVolumes(List<VolumeVO> volumes) { |
| 359 | + DataStore dataStore = null; |
| 360 | + for (Volume vol : volumes) { |
| 361 | + if (doesVolumeStateCheckout(vol)) { |
| 362 | + dataStore = _dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary); |
| 363 | + if (dataStore != null) { |
| 364 | + return dataStore; |
| 365 | + } |
| 366 | + } |
| 367 | + } |
| 368 | + return dataStore; |
| 369 | + } |
| 370 | + |
| 371 | + private boolean doesVolumeStateCheckout(Volume vol) { |
| 372 | + switch (vol.getState()) { |
| 373 | + case Allocated: |
| 374 | + case Creating: |
| 375 | + case Ready: |
| 376 | + case Snapshotting: |
| 377 | + case RevertSnapshotting: |
| 378 | + case Resizing: |
| 379 | + case Copying: |
| 380 | + case Attaching: |
| 381 | + return true; |
| 382 | + case Migrating: |
| 383 | + case Expunging: |
| 384 | + case Expunged: |
| 385 | + case Destroy: |
| 386 | + case Destroying: |
| 387 | + case UploadOp: |
| 388 | + case Uploaded: |
| 389 | + case NotUploaded: |
| 390 | + case UploadInProgress: |
| 391 | + case UploadError: |
| 392 | + case UploadAbandoned: |
| 393 | + return false; |
| 394 | + default: |
| 395 | + throw new IllegalArgumentException("volume has a state that does not compute: " +vol.getState()); |
| 396 | + } |
| 397 | + } |
| 398 | + |
346 | 399 | private Long findAgentIdForImageStore(final DataStore dataStore) throws ResourceUnavailableException { |
347 | 400 | EndPoint endpoint = _ep.select(dataStore); |
348 | 401 | if (endpoint == null) { |
|
0 commit comments