176176import org .apache .commons .collections .CollectionUtils ;
177177import org .apache .commons .collections .MapUtils ;
178178import org .apache .commons .lang3 .BooleanUtils ;
179+ import org .apache .commons .lang3 .ObjectUtils ;
179180import org .apache .commons .lang3 .StringUtils ;
180181import org .apache .logging .log4j .LogManager ;
181182import org .apache .logging .log4j .Logger ;
182183
183184import javax .inject .Inject ;
184185import java .util .ArrayList ;
185186import java .util .Arrays ;
187+ import java .util .Collections ;
186188import java .util .HashMap ;
187189import java .util .HashSet ;
188190import java .util .LinkedHashMap ;
@@ -1689,8 +1691,9 @@ protected UserVm importUnmanagedInstanceFromVmwareToKvm(DataCenter zone, Cluster
16891691 "instance {} from VMware to KVM " , convertHost , sourceVMName );
16901692
16911693 temporaryConvertLocation = selectInstanceConversionTemporaryLocation (
1692- destinationCluster , convertHost , convertStoragePoolId , forceConvertToPool );
1693- List <StoragePoolVO > convertStoragePools = findInstanceConversionStoragePoolsInCluster (destinationCluster , serviceOffering , dataDiskOfferingMap );
1694+ destinationCluster , convertHost , importHost , convertStoragePoolId , forceConvertToPool );
1695+ List <StoragePoolVO > convertStoragePools = findInstanceConversionDestinationStoragePoolsInCluster (destinationCluster , serviceOffering , dataDiskOfferingMap , temporaryConvertLocation , forceConvertToPool );
1696+
16941697 long importStartTime = System .currentTimeMillis ();
16951698 importVMTask = importVmTasksManager .createImportVMTaskRecord (zone , owner , userId , displayName , vcenter , datacenterName , sourceVMName ,
16961699 convertHost , importHost );
@@ -2119,17 +2122,23 @@ private UnmanagedInstanceTO convertAndImportToKVM(ConvertInstanceCommand convert
21192122 return ((ImportConvertedInstanceAnswer ) importAnswer ).getConvertedInstance ();
21202123 }
21212124
2122- private List <StoragePoolVO > findInstanceConversionStoragePoolsInCluster (
2125+ private List <StoragePoolVO > findInstanceConversionDestinationStoragePoolsInCluster (
21232126 Cluster destinationCluster , ServiceOfferingVO serviceOffering ,
2124- Map <String , Long > dataDiskOfferingMap
2125- ) {
2126- List <StoragePoolVO > pools = new ArrayList <>();
2127- pools .addAll (primaryDataStoreDao .findClusterWideStoragePoolsByHypervisorAndPoolType (destinationCluster .getId (), Hypervisor .HypervisorType .KVM , Storage .StoragePoolType .NetworkFilesystem ));
2128- pools .addAll (primaryDataStoreDao .findZoneWideStoragePoolsByHypervisorAndPoolType (destinationCluster .getDataCenterId (), Hypervisor .HypervisorType .KVM , Storage .StoragePoolType .NetworkFilesystem ));
2129- if (pools .isEmpty ()) {
2130- String msg = String .format ("Cannot find suitable storage pools in the cluster %s for the conversion" , destinationCluster .getName ());
2131- logger .error (msg );
2132- throw new CloudRuntimeException (msg );
2127+ Map <String , Long > dataDiskOfferingMap ,
2128+ DataStoreTO temporaryConvertLocation , boolean forceConvertToPool ) {
2129+ List <StoragePoolVO > poolsList ;
2130+ if (!forceConvertToPool ) {
2131+ Set <StoragePoolVO > pools = new HashSet <>(primaryDataStoreDao .findClusterWideStoragePoolsByHypervisorAndPoolType (destinationCluster .getId (), Hypervisor .HypervisorType .KVM , Storage .StoragePoolType .NetworkFilesystem ));
2132+ pools .addAll (primaryDataStoreDao .findZoneWideStoragePoolsByHypervisorAndPoolType (destinationCluster .getDataCenterId (), Hypervisor .HypervisorType .KVM , Storage .StoragePoolType .NetworkFilesystem ));
2133+ if (pools .isEmpty ()) {
2134+ String msg = String .format ("Cannot find suitable storage pools in the cluster %s for the conversion" , destinationCluster .getName ());
2135+ logger .error (msg );
2136+ throw new CloudRuntimeException (msg );
2137+ }
2138+ poolsList = new ArrayList <>(pools );
2139+ } else {
2140+ DataStore dataStore = dataStoreManager .getDataStore (temporaryConvertLocation .getUuid (), temporaryConvertLocation .getRole ());
2141+ poolsList = Collections .singletonList (primaryDataStoreDao .findById (dataStore .getId ()));
21332142 }
21342143
21352144 if (serviceOffering .getDiskOfferingId () != null ) {
@@ -2139,7 +2148,7 @@ private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
21392148 logger .error (msg );
21402149 throw new CloudRuntimeException (msg );
21412150 }
2142- if (getStoragePoolWithTags (pools , diskOffering .getTags ()) == null ) {
2151+ if (getStoragePoolWithTags (poolsList , diskOffering .getTags ()) == null ) {
21432152 String msg = String .format ("Cannot find suitable storage pool for disk offering %s that belongs to the service offering %s" , diskOffering .getName (), serviceOffering .getName ());
21442153 logger .error (msg );
21452154 throw new CloudRuntimeException (msg );
@@ -2152,14 +2161,14 @@ private List<StoragePoolVO> findInstanceConversionStoragePoolsInCluster(
21522161 logger .error (msg );
21532162 throw new CloudRuntimeException (msg );
21542163 }
2155- if (getStoragePoolWithTags (pools , diskOffering .getTags ()) == null ) {
2164+ if (getStoragePoolWithTags (poolsList , diskOffering .getTags ()) == null ) {
21562165 String msg = String .format ("Cannot find suitable storage pool for disk offering %s" , diskOffering .getName ());
21572166 logger .error (msg );
21582167 throw new CloudRuntimeException (msg );
21592168 }
21602169 }
21612170
2162- return pools ;
2171+ return poolsList ;
21632172 }
21642173
21652174 private StoragePoolVO getStoragePoolWithTags (List <StoragePoolVO > pools , String tags ) {
@@ -2205,41 +2214,63 @@ private void logFailureAndThrowException(String msg) {
22052214 throw new CloudRuntimeException (msg );
22062215 }
22072216
2217+ private void checkBeforeSelectingTemporaryConversionStoragePool (StoragePoolVO selectedStoragePool , Long convertStoragePoolId , Cluster destinationCluster , HostVO convertHost ) {
2218+ if (selectedStoragePool == null ) {
2219+ logFailureAndThrowException (String .format ("Cannot find a storage pool with ID %s" , convertStoragePoolId ));
2220+ }
2221+ if ((selectedStoragePool .getScope () == ScopeType .CLUSTER && selectedStoragePool .getClusterId () != destinationCluster .getId ()) ||
2222+ (selectedStoragePool .getScope () == ScopeType .ZONE && selectedStoragePool .getDataCenterId () != destinationCluster .getDataCenterId ())) {
2223+ logFailureAndThrowException (String .format ("Cannot use the storage pool %s for the instance conversion as " +
2224+ "it is not in the scope of the cluster %s" , selectedStoragePool .getName (), destinationCluster .getName ()));
2225+ }
2226+ if (convertHost != null && selectedStoragePool .getScope () == ScopeType .CLUSTER && !selectedStoragePool .getClusterId ().equals (convertHost .getClusterId ())) {
2227+ logFailureAndThrowException (String .format ("Cannot use the storage pool %s for the instance conversion as " +
2228+ "the host %s for conversion is in a different cluster" , selectedStoragePool .getName (), convertHost .getName ()));
2229+ }
2230+ }
2231+
2232+ private DataStoreTO getImageStoreOnDestinationZoneForTemporaryConversion (Cluster destinationCluster , boolean forceConvertToPool ) {
2233+ if (forceConvertToPool ) {
2234+ logFailureAndThrowException ("Please select a primary storage pool when the parameter forceconverttopool is set to true" );
2235+ }
2236+ long zoneId = destinationCluster .getDataCenterId ();
2237+ ImageStoreVO imageStore = imageStoreDao .findOneByZoneAndProtocol (zoneId , "nfs" );
2238+ if (imageStore == null ) {
2239+ logFailureAndThrowException (String .format ("Could not find an NFS secondary storage pool on zone %s to use as a temporary location " +
2240+ "for instance conversion" , zoneId ));
2241+ }
2242+ DataStore dataStore = dataStoreManager .getDataStore (imageStore .getId (), DataStoreRole .Image );
2243+ return dataStore .getTO ();
2244+ }
2245+
2246+ private void checkDestinationOrTemporaryStoragePoolForConversion (StoragePoolVO selectedStoragePool , boolean forceConvertToPool , HostVO convertHost , HostVO importHost ) {
2247+ if (selectedStoragePool .getScope () == ScopeType .HOST && (ObjectUtils .anyNull (convertHost , importHost ) ||
2248+ ObjectUtils .allNotNull (convertHost , importHost ) && convertHost .getId () != importHost .getId () ||
2249+ !forceConvertToPool ) ) {
2250+ logFailureAndThrowException ("Please select the same host as convert and importing host and " +
2251+ "set forceconvertopool to true to use a local storage pool for conversion" );
2252+ }
2253+ if (!forceConvertToPool && selectedStoragePool .getPoolType () != Storage .StoragePoolType .NetworkFilesystem ) {
2254+ logFailureAndThrowException (String .format ("The storage pool %s is not supported for temporary conversion location," +
2255+ "only NFS storage pools are supported when forceconverttopool is set to false" , selectedStoragePool .getName ()));
2256+ }
2257+ }
2258+
22082259 protected DataStoreTO selectInstanceConversionTemporaryLocation (Cluster destinationCluster ,
2209- HostVO convertHost ,
2260+ HostVO convertHost , HostVO importHost ,
22102261 Long convertStoragePoolId , boolean forceConvertToPool ) {
2211- if (convertStoragePoolId != null ) {
2212- StoragePoolVO selectedStoragePool = primaryDataStoreDao .findById (convertStoragePoolId );
2213- if (selectedStoragePool == null ) {
2214- logFailureAndThrowException (String .format ("Cannot find a storage pool with ID %s" , convertStoragePoolId ));
2215- }
2216- if ((selectedStoragePool .getScope () == ScopeType .CLUSTER && selectedStoragePool .getClusterId () != destinationCluster .getId ()) ||
2217- (selectedStoragePool .getScope () == ScopeType .ZONE && selectedStoragePool .getDataCenterId () != destinationCluster .getDataCenterId ())) {
2218- logFailureAndThrowException (String .format ("Cannot use the storage pool %s for the instance conversion as " +
2219- "it is not in the scope of the cluster %s" , selectedStoragePool .getName (), destinationCluster .getName ()));
2220- }
2221- if (convertHost != null && selectedStoragePool .getScope () == ScopeType .CLUSTER && !selectedStoragePool .getClusterId ().equals (convertHost .getClusterId ())) {
2222- logFailureAndThrowException (String .format ("Cannot use the storage pool %s for the instance conversion as " +
2223- "the host %s for conversion is in a different cluster" , selectedStoragePool .getName (), convertHost .getName ()));
2224- }
2225- if (!forceConvertToPool ) {
2226- if (selectedStoragePool .getScope () == ScopeType .HOST ) {
2227- logFailureAndThrowException (String .format ("The storage pool %s is a local storage pool and not supported for temporary conversion location, cluster and zone wide NFS storage pools are supported" , selectedStoragePool .getName ()));
2228- } else if (selectedStoragePool .getPoolType () != Storage .StoragePoolType .NetworkFilesystem ) {
2229- logFailureAndThrowException (String .format ("The storage pool %s is not supported for temporary conversion location, only NFS storage pools are supported" , selectedStoragePool .getName ()));
2230- }
2231- }
2232- return dataStoreManager .getPrimaryDataStore (convertStoragePoolId ).getTO ();
2233- } else {
2234- long zoneId = destinationCluster .getDataCenterId ();
2235- ImageStoreVO imageStore = imageStoreDao .findOneByZoneAndProtocol (zoneId , "nfs" );
2236- if (imageStore == null ) {
2237- logFailureAndThrowException (String .format ("Could not find an NFS secondary storage pool on zone %s to use as a temporary location " +
2238- "for instance conversion" , zoneId ));
2239- }
2240- DataStore dataStore = dataStoreManager .getDataStore (imageStore .getId (), DataStoreRole .Image );
2241- return dataStore .getTO ();
2262+ if (convertStoragePoolId == null ) {
2263+ String msg = String .format ("No convert storage pool has been provided, " +
2264+ "selecting an NFS secondary storage pool from the destination cluster (%s) zone" , destinationCluster .getName ());
2265+ logger .debug (msg );
2266+ return getImageStoreOnDestinationZoneForTemporaryConversion (destinationCluster , forceConvertToPool );
22422267 }
2268+
2269+ StoragePoolVO selectedStoragePool = primaryDataStoreDao .findById (convertStoragePoolId );
2270+ checkBeforeSelectingTemporaryConversionStoragePool (selectedStoragePool , convertStoragePoolId , destinationCluster , convertHost );
2271+ checkDestinationOrTemporaryStoragePoolForConversion (selectedStoragePool , forceConvertToPool , convertHost , importHost );
2272+
2273+ return dataStoreManager .getPrimaryDataStore (convertStoragePoolId ).getTO ();
22432274 }
22442275
22452276 protected Map <String , String > createParamsForTemplateFromVmwareVmMigration (String vcenterHost , String datacenterName ,
0 commit comments