Skip to content

Commit f2efbce

Browse files
[CLOUDSTACK-10240] ACS cannot migrate a local volume to shared storage (#2425)
* [CLOUDSTACK-10240] ACS cannot migrate a volume from local to shared storage. CloudStack is logically restricting the migration of local storages to shared storage and vice versa. This restriction is a logical one and can be removed for XenServer deployments. Therefore, we will enable migration of volumes between local-shared storages in XenServers independently of their service offering. This will work as an override mechanism to the disk offering used by volumes. If administrators want to migrate local volumes to a shared storage, they should be able to do so (the hypervisor already allows that). The same the other way around. * Cleanups implemented while working on [CLOUDSTACK-10240] * Fix test case test_03_migrate_options_storage_tags The changes applied were: - When loading hypervisors capabilities we must use "default" instead of nulls - "Enable" storage migration for simulator hypervisor - Remove restriction on "ClusterScopeStoragePoolAllocator" to find shared pools
1 parent 4412563 commit f2efbce

File tree

14 files changed

+671
-1014
lines changed

14 files changed

+671
-1014
lines changed

.travis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ env:
7070
smoke/test_password_server
7171
smoke/test_portable_publicip
7272
smoke/test_portforwardingrules"
73-
74-
- TESTS="smoke/test_primary_storage
75-
smoke/test_privategw_acl
73+
74+
- TESTS="smoke/test_primary_storage"
75+
76+
- TESTS="smoke/test_privategw_acl
7677
smoke/test_projects
7778
smoke/test_public_ip_range
7879
smoke/test_pvlan

api/src/main/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
package org.apache.cloudstack.api.command.admin.storage;
1818

1919
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.Comparator;
2022
import java.util.List;
2123

22-
import org.apache.log4j.Logger;
23-
2424
import org.apache.cloudstack.api.APICommand;
2525
import org.apache.cloudstack.api.ApiCommandJobType;
2626
import org.apache.cloudstack.api.ApiConstants;
@@ -29,12 +29,14 @@
2929
import org.apache.cloudstack.api.response.ListResponse;
3030
import org.apache.cloudstack.api.response.StoragePoolResponse;
3131
import org.apache.cloudstack.api.response.VolumeResponse;
32+
import org.apache.commons.lang3.StringUtils;
33+
import org.apache.log4j.Logger;
3234

3335
import com.cloud.storage.StoragePool;
3436
import com.cloud.utils.Pair;
3537

3638
@APICommand(name = "findStoragePoolsForMigration", description = "Lists storage pools available for migration of a volume.", responseObject = StoragePoolResponse.class,
37-
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
39+
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
3840
public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
3941
public static final Logger s_logger = Logger.getLogger(FindStoragePoolsForMigrationCmd.class.getName());
4042

@@ -81,7 +83,7 @@ public void execute() {
8183
StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
8284
Boolean suitableForMigration = false;
8385
for (StoragePool suitablePool : suitablePoolList) {
84-
if (suitablePool.getId() == pool.getId()) {
86+
if (StringUtils.equals(suitablePool.getUuid(), pool.getUuid())) {
8587
suitableForMigration = true;
8688
break;
8789
}
@@ -90,9 +92,27 @@ public void execute() {
9092
poolResponse.setObjectName("storagepool");
9193
poolResponses.add(poolResponse);
9294
}
93-
95+
sortPoolsBySuitabilityAndName(poolResponses);
9496
response.setResponses(poolResponses);
9597
response.setResponseName(getCommandName());
9698
this.setResponseObject(response);
9799
}
100+
101+
protected void sortPoolsBySuitabilityAndName(List<StoragePoolResponse> poolResponses) {
102+
Collections.sort(poolResponses, new Comparator<StoragePoolResponse>() {
103+
@Override
104+
public int compare(StoragePoolResponse o1, StoragePoolResponse o2) {
105+
if (o1.getSuitableForMigration() && o2.getSuitableForMigration()) {
106+
return o1.getName().compareTo(o2.getName());
107+
}
108+
if (o1.getSuitableForMigration()) {
109+
return -1;
110+
}
111+
if (o2.getSuitableForMigration()) {
112+
return 1;
113+
}
114+
return 0;
115+
}
116+
});
117+
}
98118
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.admin.storage;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.apache.cloudstack.api.response.StoragePoolResponse;
23+
import org.junit.Assert;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
import org.mockito.runners.MockitoJUnitRunner;
27+
28+
@RunWith(MockitoJUnitRunner.class)
29+
public class FindStoragePoolsForMigrationCmdTest {
30+
31+
private FindStoragePoolsForMigrationCmd findStoragePoolsForMigrationCmd = new FindStoragePoolsForMigrationCmd();
32+
33+
@Test
34+
public void sortPoolsBySuitability() {
35+
List<StoragePoolResponse> storagePoolsResponse = new ArrayList<>();
36+
StoragePoolResponse storagePoolResponse1 = new StoragePoolResponse();
37+
storagePoolResponse1.setSuitableForMigration(true);
38+
storagePoolResponse1.setId("1");
39+
storagePoolResponse1.setName("1");
40+
41+
StoragePoolResponse storagePoolResponse2 = new StoragePoolResponse();
42+
storagePoolResponse2.setSuitableForMigration(false);
43+
storagePoolResponse2.setId("2");
44+
storagePoolResponse2.setName("2");
45+
46+
StoragePoolResponse storagePoolResponse3 = new StoragePoolResponse();
47+
storagePoolResponse3.setSuitableForMigration(true);
48+
storagePoolResponse3.setId("3");
49+
storagePoolResponse3.setName("3");
50+
51+
storagePoolsResponse.add(storagePoolResponse3);
52+
storagePoolsResponse.add(storagePoolResponse2);
53+
storagePoolsResponse.add(storagePoolResponse1);
54+
55+
findStoragePoolsForMigrationCmd.sortPoolsBySuitabilityAndName(storagePoolsResponse);
56+
57+
Assert.assertEquals("1", storagePoolsResponse.get(0).getId());
58+
Assert.assertEquals("3", storagePoolsResponse.get(1).getId());
59+
Assert.assertEquals("2", storagePoolsResponse.get(2).getId());
60+
61+
}
62+
63+
}

0 commit comments

Comments
 (0)