Skip to content

Commit aa03bbb

Browse files
authored
KVM Live Storage Migration (#8)
* KVM Live Storage Migration * Adding tests for live migration for KVM and optimisation on the other tests in the file * KDDI-179: FindStoragePoolsForMigration not working when VM is running * KDDI-180: Error message is misleading * KDDI-183: After failed migration duplicate entry left behind in the DB * KDDI-182: Migration of chained clones fails if template is missing on the primary store * KDDI-186: NPE when live storage migration is not enabled * KDDI-187: User is able to migrate to pool which is in Maintenance * Fix KDDI-182 and KDDI-183 issues * Fix KDDI-182 install path on template_spool_ref table * Include missing marvin test from PR1961 - java code already backported * Adding a fix for the kvm-livemigration tests
1 parent 2bcf8ad commit aa03bbb

File tree

47 files changed

+2903
-301
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2903
-301
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package com.cloud.storage;
20+
21+
import java.io.Serializable;
22+
23+
public class MigrationOptions implements Serializable {
24+
25+
private String srcPoolUuid;
26+
private Storage.StoragePoolType srcPoolType;
27+
private Type type;
28+
private String srcBackingFilePath;
29+
private String backingFile;
30+
private boolean copySrcTemplate;
31+
private String snapshotName;
32+
private String srcVolumeUuid;
33+
private int timeout;
34+
35+
public enum Type {
36+
LinkedClone, FullClone
37+
}
38+
39+
public MigrationOptions() {
40+
}
41+
42+
public MigrationOptions(String srcPoolUuid, Storage.StoragePoolType srcPoolType, String srcBackingFilePath, boolean copySrcTemplate,
43+
String backingFile) {
44+
this.srcPoolUuid = srcPoolUuid;
45+
this.srcPoolType = srcPoolType;
46+
this.type = Type.LinkedClone;
47+
this.srcBackingFilePath = srcBackingFilePath;
48+
this.copySrcTemplate = copySrcTemplate;
49+
this.backingFile = backingFile;
50+
}
51+
52+
public MigrationOptions(String srcPoolUuid, Storage.StoragePoolType srcPoolType, String snapshotName, String srcVolumeUuid) {
53+
this.srcPoolUuid = srcPoolUuid;
54+
this.srcPoolType = srcPoolType;
55+
this.type = Type.FullClone;
56+
this.snapshotName = snapshotName;
57+
this.srcVolumeUuid = srcVolumeUuid;
58+
}
59+
60+
public String getSrcPoolUuid() {
61+
return srcPoolUuid;
62+
}
63+
64+
public Storage.StoragePoolType getSrcPoolType() {
65+
return srcPoolType;
66+
}
67+
68+
public String getSrcBackingFilePath() {
69+
return srcBackingFilePath;
70+
}
71+
72+
public boolean isCopySrcTemplate() {
73+
return copySrcTemplate;
74+
}
75+
76+
public String getSnapshotName() {
77+
return snapshotName;
78+
}
79+
80+
public String getSrcVolumeUuid() {
81+
return srcVolumeUuid;
82+
}
83+
84+
public Type getType() {
85+
return type;
86+
}
87+
88+
public int getTimeout() {
89+
return timeout;
90+
}
91+
92+
public void setTimeout(int timeout) {
93+
this.timeout = timeout;
94+
}
95+
96+
public String getBackingFile() {
97+
return backingFile;
98+
}
99+
}

core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public CreateVMSnapshotCommand(String vmName, String vmUuid, VMSnapshotTO snapsh
3232
this.vmUuid = vmUuid;
3333
}
3434

35+
public CreateVMSnapshotCommand(String vmName, VMSnapshotTO snapshot) {
36+
super(vmName, snapshot, null, null);
37+
}
38+
3539
public String getVmUuid() {
3640
return vmUuid;
3741
}

core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ public class DeleteVMSnapshotCommand extends VMSnapshotBaseCommand {
2727
public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType) {
2828
super(vmName, snapshot, volumeTOs, guestOSType);
2929
}
30+
31+
public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot) {
32+
super(vmName, snapshot, null, null);
33+
}
3034
}

core/src/com/cloud/agent/api/MigrateCommand.java

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,21 @@
1919

2020
package com.cloud.agent.api;
2121

22+
import java.util.HashMap;
23+
import java.util.Map;
24+
2225
import com.cloud.agent.api.to.VirtualMachineTO;
2326

2427
public class MigrateCommand extends Command {
25-
String vmName;
26-
String destIp;
27-
String hostGuid;
28-
boolean isWindows;
29-
VirtualMachineTO vmTO;
30-
boolean executeInSequence = false;
28+
private String vmName;
29+
private String destIp;
30+
private Map<String, MigrateDiskInfo> migrateStorage;
31+
private boolean migrateStorageManaged;
32+
private boolean autoConvergence;
33+
private String hostGuid;
34+
private boolean isWindows;
35+
private VirtualMachineTO vmTO;
36+
private boolean executeInSequence = false;
3137

3238
protected MigrateCommand() {
3339
}
@@ -40,6 +46,30 @@ public MigrateCommand(String vmName, String destIp, boolean isWindows, VirtualMa
4046
this.executeInSequence = executeInSequence;
4147
}
4248

49+
public void setMigrateStorage(Map<String, MigrateDiskInfo> migrateStorage) {
50+
this.migrateStorage = migrateStorage;
51+
}
52+
53+
public Map<String, MigrateDiskInfo> getMigrateStorage() {
54+
return migrateStorage != null ? new HashMap<>(migrateStorage) : new HashMap<String, MigrateDiskInfo>();
55+
}
56+
57+
public boolean isMigrateStorageManaged() {
58+
return migrateStorageManaged;
59+
}
60+
61+
public void setMigrateStorageManaged(boolean migrateStorageManaged) {
62+
this.migrateStorageManaged = migrateStorageManaged;
63+
}
64+
65+
public void setAutoConvergence(boolean autoConvergence) {
66+
this.autoConvergence = autoConvergence;
67+
}
68+
69+
public boolean isAutoConvergence() {
70+
return autoConvergence;
71+
}
72+
4373
public boolean isWindows() {
4474
return isWindows;
4575
}
@@ -68,4 +98,68 @@ public String getHostGuid() {
6898
public boolean executeInSequence() {
6999
return executeInSequence;
70100
}
101+
102+
public static class MigrateDiskInfo {
103+
104+
public enum DiskType {
105+
FILE, BLOCK;
106+
107+
@Override
108+
public String toString() {
109+
return name().toLowerCase();
110+
}
111+
}
112+
113+
public enum DriverType {
114+
QCOW2, RAW;
115+
116+
@Override
117+
public String toString() {
118+
return name().toLowerCase();
119+
}
120+
}
121+
122+
public enum Source {
123+
FILE, DEV;
124+
125+
@Override
126+
public String toString() {
127+
return name().toLowerCase();
128+
}
129+
}
130+
131+
private final String serialNumber;
132+
private final DiskType diskType;
133+
private final DriverType driverType;
134+
private final Source source;
135+
private final String sourceText;
136+
137+
public MigrateDiskInfo(final String serialNumber, final DiskType diskType, final DriverType driverType, final Source source, final String sourceText) {
138+
this.serialNumber = serialNumber;
139+
this.diskType = diskType;
140+
this.driverType = driverType;
141+
this.source = source;
142+
this.sourceText = sourceText;
143+
}
144+
145+
public String getSerialNumber() {
146+
return serialNumber;
147+
}
148+
149+
public DiskType getDiskType() {
150+
return diskType;
151+
}
152+
153+
public DriverType getDriverType() {
154+
return driverType;
155+
}
156+
157+
public Source getSource() {
158+
return source;
159+
}
160+
161+
public String getSourceText() {
162+
return sourceText;
163+
}
164+
}
71165
}

core/src/com/cloud/agent/api/ModifyTargetsAnswer.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,27 @@
1919

2020
package com.cloud.agent.api;
2121

22+
import java.util.List;
23+
2224
public class ModifyTargetsAnswer extends Answer {
25+
26+
private List<String> connectedPaths;
27+
28+
public void setConnectedPaths(List<String> connectedPaths) {
29+
this.connectedPaths = connectedPaths;
30+
}
31+
32+
public List<String> getConnectedPaths() {
33+
return connectedPaths;
34+
}
35+
36+
public ModifyTargetsAnswer() {
37+
super();
38+
}
39+
40+
public ModifyTargetsAnswer(boolean result, String details) {
41+
super();
42+
this.result = result;
43+
this.details = details;
44+
}
2345
}

core/src/com/cloud/agent/api/ModifyTargetsCommand.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
import java.util.Map;
2424

2525
public class ModifyTargetsCommand extends Command {
26+
public enum TargetTypeToRemove { BOTH, NEITHER, STATIC, DYNAMIC }
27+
2628
public static final String IQN = "iqn";
29+
public static final String STORAGE_TYPE = "storageType";
30+
public static final String STORAGE_UUID = "storageUuid";
2731
public static final String STORAGE_HOST = "storageHost";
2832
public static final String STORAGE_PORT = "storagePort";
2933
public static final String CHAP_NAME = "chapName";
@@ -32,6 +36,9 @@ public class ModifyTargetsCommand extends Command {
3236
public static final String MUTUAL_CHAP_SECRET = "mutualChapSecret";
3337

3438
private boolean add;
39+
private boolean applyToAllHostsInCluster;
40+
private TargetTypeToRemove targetTypeToRemove = TargetTypeToRemove.BOTH;
41+
private boolean removeAsync;
3542
private List<Map<String, String>> targets;
3643

3744
public void setAdd(boolean add) {
@@ -42,6 +49,30 @@ public boolean getAdd() {
4249
return add;
4350
}
4451

52+
public void setApplyToAllHostsInCluster(boolean applyToAllHostsInCluster) {
53+
this.applyToAllHostsInCluster = applyToAllHostsInCluster;
54+
}
55+
56+
public boolean getApplyToAllHostsInCluster() {
57+
return applyToAllHostsInCluster;
58+
}
59+
60+
public void setTargetTypeToRemove(TargetTypeToRemove targetTypeToRemove) {
61+
this.targetTypeToRemove = targetTypeToRemove;
62+
}
63+
64+
public TargetTypeToRemove getTargetTypeToRemove() {
65+
return targetTypeToRemove;
66+
}
67+
68+
public void setRemoveAsync(boolean removeAsync) {
69+
this.removeAsync = removeAsync;
70+
}
71+
72+
public boolean isRemoveAsync() {
73+
return removeAsync;
74+
}
75+
4576
public void setTargets(List<Map<String, String>> targets) {
4677
this.targets = targets;
4778
}

core/src/com/cloud/agent/api/PrepareForMigrationCommand.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
import com.cloud.agent.api.to.VirtualMachineTO;
2323

2424
public class PrepareForMigrationCommand extends Command {
25-
VirtualMachineTO vm;
25+
private VirtualMachineTO vm;
26+
private boolean rollback;
2627

2728
protected PrepareForMigrationCommand() {
2829
}
@@ -35,6 +36,14 @@ public VirtualMachineTO getVirtualMachine() {
3536
return vm;
3637
}
3738

39+
public void setRollback(boolean rollback) {
40+
this.rollback = rollback;
41+
}
42+
43+
public boolean isRollback() {
44+
return rollback;
45+
}
46+
3847
@Override
3948
public boolean executeInSequence() {
4049
return true;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package com.cloud.agent.api.storage;
21+
22+
import com.cloud.agent.api.Command;
23+
import com.cloud.storage.Storage;
24+
25+
import java.util.Map;
26+
27+
public class CheckStorageAvailabilityCommand extends Command {
28+
29+
private Map<String, Storage.StoragePoolType> poolsMap;
30+
31+
public CheckStorageAvailabilityCommand(Map<String, Storage.StoragePoolType> poolsMap) {
32+
this.poolsMap = poolsMap;
33+
}
34+
35+
public Map<String, Storage.StoragePoolType> getPoolsMap() {
36+
return poolsMap;
37+
}
38+
39+
@Override
40+
public boolean executeInSequence() {
41+
return false;
42+
}
43+
}

0 commit comments

Comments
 (0)