diff --git a/api/src/main/java/com/cloud/storage/MigrationOptions.java b/api/src/main/java/com/cloud/storage/MigrationOptions.java
index a39a2a7c827..8b642d09e29 100644
--- a/api/src/main/java/com/cloud/storage/MigrationOptions.java
+++ b/api/src/main/java/com/cloud/storage/MigrationOptions.java
@@ -24,6 +24,7 @@ public class MigrationOptions implements Serializable {
private String srcPoolUuid;
private Storage.StoragePoolType srcPoolType;
+ private Long srcPoolClusterId;
private Type type;
private ScopeType scopeType;
private String srcBackingFilePath;
@@ -38,21 +39,23 @@ public class MigrationOptions implements Serializable {
public MigrationOptions() {
}
- public MigrationOptions(String srcPoolUuid, Storage.StoragePoolType srcPoolType, String srcBackingFilePath, boolean copySrcTemplate, ScopeType scopeType) {
+ public MigrationOptions(String srcPoolUuid, Storage.StoragePoolType srcPoolType, String srcBackingFilePath, boolean copySrcTemplate, ScopeType scopeType, Long srcPoolClusterId) {
this.srcPoolUuid = srcPoolUuid;
this.srcPoolType = srcPoolType;
this.type = Type.LinkedClone;
this.scopeType = scopeType;
this.srcBackingFilePath = srcBackingFilePath;
this.copySrcTemplate = copySrcTemplate;
+ this.srcPoolClusterId = srcPoolClusterId;
}
- public MigrationOptions(String srcPoolUuid, Storage.StoragePoolType srcPoolType, String srcVolumeUuid, ScopeType scopeType) {
+ public MigrationOptions(String srcPoolUuid, Storage.StoragePoolType srcPoolType, String srcVolumeUuid, ScopeType scopeType, Long srcPoolClusterId) {
this.srcPoolUuid = srcPoolUuid;
this.srcPoolType = srcPoolType;
this.type = Type.FullClone;
this.scopeType = scopeType;
this.srcVolumeUuid = srcVolumeUuid;
+ this.srcPoolClusterId = srcPoolClusterId;
}
public String getSrcPoolUuid() {
@@ -63,6 +66,10 @@ public class MigrationOptions implements Serializable {
return srcPoolType;
}
+ public Long getSrcPoolClusterId() {
+ return srcPoolClusterId;
+ }
+
public ScopeType getScopeType() { return scopeType; }
public String getSrcBackingFilePath() {
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
index 1212bc66fd7..947b4af8f69 100644
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
@@ -215,7 +215,7 @@ public class KvmNonManagedStorageDataMotionStrategy extends StorageSystemDataMot
}
VMTemplateStoragePoolVO sourceVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(destStoragePool.getId(), srcVolumeInfo.getTemplateId(), null);
- if (sourceVolumeTemplateStoragePoolVO == null && (isStoragePoolTypeInList(destStoragePool.getPoolType(), StoragePoolType.Filesystem, StoragePoolType.SharedMountPoint))) {
+ if (sourceVolumeTemplateStoragePoolVO == null && (isStoragePoolTypeInList(destStoragePool.getPoolType(), StoragePoolType.NetworkFilesystem, StoragePoolType.Filesystem, StoragePoolType.SharedMountPoint))) {
DataStore sourceTemplateDataStore = dataStoreManagerImpl.getRandomImageStore(srcVolumeInfo.getDataCenterId());
if (sourceTemplateDataStore != null) {
TemplateInfo sourceTemplateInfo = templateDataFactory.getTemplate(srcVolumeInfo.getTemplateId(), sourceTemplateDataStore);
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
index 2f1227a91a5..cdf823eaf5b 100644
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
@@ -1949,18 +1949,26 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
/**
* Return expected MigrationOptions for a linked clone volume live storage migration
*/
- protected MigrationOptions createLinkedCloneMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, String srcVolumeBackingFile, String srcPoolUuid, Storage.StoragePoolType srcPoolType) {
+ protected MigrationOptions createLinkedCloneMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, String srcVolumeBackingFile, StoragePoolVO srcPool) {
+ String srcPoolUuid = srcPool.getUuid();
+ Storage.StoragePoolType srcPoolType = srcPool.getPoolType();
+ Long srcPoolClusterId = srcPool.getClusterId();
VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(destVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId(), null);
boolean updateBackingFileReference = ref == null;
String backingFile = !updateBackingFileReference ? ref.getInstallPath() : srcVolumeBackingFile;
- return new MigrationOptions(srcPoolUuid, srcPoolType, backingFile, updateBackingFileReference, srcVolumeInfo.getDataStore().getScope().getScopeType());
+ ScopeType scopeType = srcVolumeInfo.getDataStore().getScope().getScopeType();
+ return new MigrationOptions(srcPoolUuid, srcPoolType, backingFile, updateBackingFileReference, scopeType, srcPoolClusterId);
}
/**
* Return expected MigrationOptions for a full clone volume live storage migration
*/
- protected MigrationOptions createFullCloneMigrationOptions(VolumeInfo srcVolumeInfo, VirtualMachineTO vmTO, Host srcHost, String srcPoolUuid, Storage.StoragePoolType srcPoolType) {
- return new MigrationOptions(srcPoolUuid, srcPoolType, srcVolumeInfo.getPath(), srcVolumeInfo.getDataStore().getScope().getScopeType());
+ protected MigrationOptions createFullCloneMigrationOptions(VolumeInfo srcVolumeInfo, VirtualMachineTO vmTO, Host srcHost, StoragePoolVO srcPool) {
+ String srcPoolUuid = srcPool.getUuid();
+ Storage.StoragePoolType srcPoolType = srcPool.getPoolType();
+ Long srcPoolClusterId = srcPool.getClusterId();
+ ScopeType scopeType = srcVolumeInfo.getDataStore().getScope().getScopeType();
+ return new MigrationOptions(srcPoolUuid, srcPoolType, srcVolumeInfo.getPath(), scopeType, srcPoolClusterId);
}
/**
@@ -1983,9 +1991,9 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
MigrationOptions migrationOptions;
if (MigrationOptions.Type.LinkedClone.equals(migrationType)) {
- migrationOptions = createLinkedCloneMigrationOptions(srcVolumeInfo, destVolumeInfo, srcVolumeBackingFile, srcPoolUuid, srcPoolType);
+ migrationOptions = createLinkedCloneMigrationOptions(srcVolumeInfo, destVolumeInfo, srcVolumeBackingFile, srcPool);
} else {
- migrationOptions = createFullCloneMigrationOptions(srcVolumeInfo, vmTO, srcHost, srcPoolUuid, srcPoolType);
+ migrationOptions = createFullCloneMigrationOptions(srcVolumeInfo, vmTO, srcHost, srcPool);
}
migrationOptions.setTimeout(StorageManager.KvmStorageOnlineMigrationWait.value());
destVolumeInfo.setMigrationOptions(migrationOptions);
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 7e62d672a84..ce40dd4b681 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -639,6 +639,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return libvirtUtilitiesHelper;
}
+ public String getClusterId() {
+ return clusterId;
+ }
+
public CPUStat getCPUStat() {
return cpuStat;
}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 0a2621b7bd4..cdb523a50fd 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -2660,6 +2660,12 @@ public class KVMStorageProcessor implements StorageProcessor {
return localPool;
}
+ if (migrationOptions.getScopeType().equals(ScopeType.CLUSTER)
+ && migrationOptions.getSrcPoolClusterId() != null
+ && !migrationOptions.getSrcPoolClusterId().toString().equals(resource.getClusterId())) {
+ return localPool;
+ }
+
return storagePoolMgr.getStoragePool(migrationOptions.getSrcPoolType(), migrationOptions.getSrcPoolUuid());
}
}
diff --git a/ui/src/components/view/InfoCard.vue b/ui/src/components/view/InfoCard.vue
index e19456ecd5c..d8b37e3c6e4 100644
--- a/ui/src/components/view/InfoCard.vue
+++ b/ui/src/components/view/InfoCard.vue
@@ -1208,6 +1208,11 @@ export default {
if (item.value) {
query[item.param] = this.resource[item.value]
} else {
+ if (item.name === 'template') {
+ query.templatefilter = 'self'
+ query.filter = 'self'
+ }
+
if (item.param === 'account') {
query[item.param] = this.resource.name
query.domainid = this.resource.domainid
diff --git a/ui/src/components/view/ListView.vue b/ui/src/components/view/ListView.vue
index 9b5d226289b..060e09488f3 100644
--- a/ui/src/components/view/ListView.vue
+++ b/ui/src/components/view/ListView.vue
@@ -160,6 +160,10 @@
static-nat
+
+
+ system
+
{{ ipV6Address(text, record) }}
@@ -412,8 +416,8 @@
{{ record.enabled ? 'Enabled' : 'Disabled' }}
-
- {{ $toLocaleDate(text) }}
+
+ {{ text && $toLocaleDate(text) }}
{{ getDateAtTimeZone(text, record.timezone) }}
diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js
index 1e09c318b01..fc0a1f7dee6 100644
--- a/ui/src/config/section/network.js
+++ b/ui/src/config/section/network.js
@@ -840,10 +840,13 @@ export default {
message: 'message.action.release.ip',
docHelp: 'adminguide/networking_and_traffic.html#releasing-an-ip-address-alloted-to-a-vpc',
dataView: true,
- show: (record) => { return record.state === 'Allocated' && !record.issourcenat },
+ show: (record) => { return record.state === 'Allocated' && !record.issourcenat && !record.issystem },
groupAction: true,
popup: true,
- groupMap: (selection) => { return selection.map(x => { return { id: x } }) }
+ groupMap: (selection) => { return selection.map(x => { return { id: x } }) },
+ groupShow: (selectedIps) => {
+ return selectedIps.every((ip) => ip.state === 'Allocated' && !ip.issourcenat && !ip.issystem)
+ }
},
{
api: 'reserveIpAddress',
@@ -863,7 +866,10 @@ export default {
show: (record) => { return record.state === 'Reserved' },
groupAction: true,
popup: true,
- groupMap: (selection) => { return selection.map(x => { return { id: x } }) }
+ groupMap: (selection) => { return selection.map(x => { return { id: x } }) },
+ groupShow: (selectedIps) => {
+ return selectedIps.every((ip) => ip.state === 'Reserved')
+ }
}
]
},