Skip to content

Commit 1bdc357

Browse files
committed
Fixup
1 parent e881ee7 commit 1bdc357

File tree

8 files changed

+93
-281
lines changed

8 files changed

+93
-281
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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 com.cloud.agent.api;
18+
19+
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
20+
21+
public class ConvertInstanceAnswer extends Answer {
22+
23+
private String temporaryConvertUuid;
24+
25+
public ConvertInstanceAnswer() {
26+
super();
27+
}
28+
29+
public ConvertInstanceAnswer(Command command, String temporaryConvertUuid) {
30+
super(command, true, "");
31+
this.temporaryConvertUuid = temporaryConvertUuid;
32+
}
33+
34+
public String getTemporaryConvertUuid() {
35+
return temporaryConvertUuid;
36+
}
37+
}

core/src/main/java/com/cloud/agent/api/ImportConvertedInstanceCommand.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,18 @@ public class ImportConvertedInstanceCommand extends Command {
2626
private RemoteInstanceTO sourceInstance;
2727
private List<String> destinationStoragePools;
2828
private DataStoreTO conversionTemporaryLocation;
29+
private String temporaryConvertUuid;
2930

3031
public ImportConvertedInstanceCommand() {
3132
}
3233

3334
public ImportConvertedInstanceCommand(RemoteInstanceTO sourceInstance,
34-
List<String> destinationStoragePools, DataStoreTO conversionTemporaryLocation) {
35+
List<String> destinationStoragePools,
36+
DataStoreTO conversionTemporaryLocation, String temporaryConvertUuid) {
3537
this.sourceInstance = sourceInstance;
3638
this.destinationStoragePools = destinationStoragePools;
3739
this.conversionTemporaryLocation = conversionTemporaryLocation;
40+
this.temporaryConvertUuid = temporaryConvertUuid;
3841
}
3942

4043
public RemoteInstanceTO getSourceInstance() {
@@ -49,6 +52,10 @@ public DataStoreTO getConversionTemporaryLocation() {
4952
return conversionTemporaryLocation;
5053
}
5154

55+
public String getTemporaryConvertUuid() {
56+
return temporaryConvertUuid;
57+
}
58+
5259
@Override
5360
public boolean executeInSequence() {
5461
return false;

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConvertInstanceCommandWrapper.java

Lines changed: 8 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.UUID;
2626
import java.util.stream.Collectors;
2727

28+
import com.cloud.agent.api.ConvertInstanceAnswer;
2829
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
2930
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
3031
import org.apache.commons.collections.CollectionUtils;
@@ -122,6 +123,7 @@ public Answer execute(ConvertInstanceCommand cmd, LibvirtComputingResource serve
122123
final String temporaryConvertUuid = UUID.randomUUID().toString();
123124
boolean verboseModeEnabled = serverResource.isConvertInstanceVerboseModeEnabled();
124125

126+
boolean cleanupSecondaryStorage = false;
125127
try {
126128
boolean result = performInstanceConversion(sourceOVFDirPath, temporaryConvertPath, temporaryConvertUuid,
127129
timeout, verboseModeEnabled);
@@ -131,18 +133,23 @@ public Answer execute(ConvertInstanceCommand cmd, LibvirtComputingResource serve
131133
s_logger.error(err);
132134
return new Answer(cmd, false, err);
133135
}
134-
return new Answer(cmd, false, null);
136+
return new ConvertInstanceAnswer(cmd, temporaryConvertUuid);
135137
} catch (Exception e) {
136138
String error = String.format("Error converting instance %s from %s, due to: %s",
137139
sourceInstanceName, sourceHypervisorType, e.getMessage());
138140
s_logger.error(error, e);
141+
cleanupSecondaryStorage = true;
139142
return new Answer(cmd, false, error);
140143
} finally {
141144
if (ovfExported && StringUtils.isNotBlank(ovfTemplateDirOnConversionLocation)) {
142145
String sourceOVFDir = String.format("%s/%s", temporaryConvertPath, ovfTemplateDirOnConversionLocation);
143146
s_logger.debug("Cleaning up exported OVA at dir " + sourceOVFDir);
144147
FileUtil.deletePath(sourceOVFDir);
145148
}
149+
if (cleanupSecondaryStorage && conversionTemporaryLocation instanceof NfsTO) {
150+
s_logger.debug("Cleaning up secondary storage temporary location");
151+
storagePoolMgr.deleteStoragePool(temporaryStoragePool.getType(), temporaryStoragePool.getUuid());
152+
}
146153
}
147154
}
148155

@@ -183,44 +190,6 @@ private String getExportOVAUrlFromRemoteInstance(RemoteInstanceTO vmwareInstance
183190
encodedUsername, encodedPassword, vcenter, datacenter, vm);
184191
}
185192

186-
protected List<KVMPhysicalDisk> getTemporaryDisksFromParsedXml(KVMStoragePool pool, LibvirtDomainXMLParser xmlParser, String convertedBasePath) {
187-
List<LibvirtVMDef.DiskDef> disksDefs = xmlParser.getDisks();
188-
disksDefs = disksDefs.stream().filter(x -> x.getDiskType() == LibvirtVMDef.DiskDef.DiskType.FILE &&
189-
x.getDeviceType() == LibvirtVMDef.DiskDef.DeviceType.DISK).collect(Collectors.toList());
190-
if (CollectionUtils.isEmpty(disksDefs)) {
191-
String err = String.format("Cannot find any disk defined on the converted XML domain %s.xml", convertedBasePath);
192-
s_logger.error(err);
193-
throw new CloudRuntimeException(err);
194-
}
195-
sanitizeDisksPath(disksDefs);
196-
return getPhysicalDisksFromDefPaths(disksDefs, pool);
197-
}
198-
199-
private List<KVMPhysicalDisk> getPhysicalDisksFromDefPaths(List<LibvirtVMDef.DiskDef> disksDefs, KVMStoragePool pool) {
200-
List<KVMPhysicalDisk> disks = new ArrayList<>();
201-
for (LibvirtVMDef.DiskDef diskDef : disksDefs) {
202-
KVMPhysicalDisk physicalDisk = pool.getPhysicalDisk(diskDef.getDiskPath());
203-
disks.add(physicalDisk);
204-
}
205-
return disks;
206-
}
207-
208-
protected List<KVMPhysicalDisk> getTemporaryDisksWithPrefixFromTemporaryPool(KVMStoragePool pool, String path, String prefix) {
209-
String msg = String.format("Could not parse correctly the converted XML domain, checking for disks on %s with prefix %s", path, prefix);
210-
s_logger.info(msg);
211-
pool.refresh();
212-
List<KVMPhysicalDisk> disksWithPrefix = pool.listPhysicalDisks()
213-
.stream()
214-
.filter(x -> x.getName().startsWith(prefix) && !x.getName().endsWith(".xml"))
215-
.collect(Collectors.toList());
216-
if (CollectionUtils.isEmpty(disksWithPrefix)) {
217-
msg = String.format("Could not find any converted disk with prefix %s on temporary location %s", prefix, path);
218-
s_logger.error(msg);
219-
throw new CloudRuntimeException(msg);
220-
}
221-
return disksWithPrefix;
222-
}
223-
224193
protected void sanitizeDisksPath(List<LibvirtVMDef.DiskDef> disks) {
225194
for (LibvirtVMDef.DiskDef disk : disks) {
226195
String[] diskPathParts = disk.getDiskPath().split("/");
@@ -229,89 +198,6 @@ protected void sanitizeDisksPath(List<LibvirtVMDef.DiskDef> disks) {
229198
}
230199
}
231200

232-
protected List<KVMPhysicalDisk> moveTemporaryDisksToDestination(List<KVMPhysicalDisk> temporaryDisks,
233-
List<String> destinationStoragePools,
234-
KVMStoragePoolManager storagePoolMgr) {
235-
List<KVMPhysicalDisk> targetDisks = new ArrayList<>();
236-
if (temporaryDisks.size() != destinationStoragePools.size()) {
237-
String warn = String.format("Discrepancy between the converted instance disks (%s) " +
238-
"and the expected number of disks (%s)", temporaryDisks.size(), destinationStoragePools.size());
239-
s_logger.warn(warn);
240-
}
241-
for (int i = 0; i < temporaryDisks.size(); i++) {
242-
String poolPath = destinationStoragePools.get(i);
243-
KVMStoragePool destinationPool = storagePoolMgr.getStoragePool(Storage.StoragePoolType.NetworkFilesystem, poolPath);
244-
if (destinationPool == null) {
245-
String err = String.format("Could not find a storage pool by URI: %s", poolPath);
246-
s_logger.error(err);
247-
continue;
248-
}
249-
if (destinationPool.getType() != Storage.StoragePoolType.NetworkFilesystem) {
250-
String err = String.format("Storage pool by URI: %s is not an NFS storage", poolPath);
251-
s_logger.error(err);
252-
continue;
253-
}
254-
KVMPhysicalDisk sourceDisk = temporaryDisks.get(i);
255-
if (s_logger.isDebugEnabled()) {
256-
String msg = String.format("Trying to copy converted instance disk number %s from the temporary location %s" +
257-
" to destination storage pool %s", i, sourceDisk.getPool().getLocalPath(), destinationPool.getUuid());
258-
s_logger.debug(msg);
259-
}
260-
261-
String destinationName = UUID.randomUUID().toString();
262-
263-
KVMPhysicalDisk destinationDisk = storagePoolMgr.copyPhysicalDisk(sourceDisk, destinationName, destinationPool, 7200 * 1000);
264-
targetDisks.add(destinationDisk);
265-
}
266-
return targetDisks;
267-
}
268-
269-
protected List<UnmanagedInstanceTO.Disk> getUnmanagedInstanceDisks(List<KVMPhysicalDisk> vmDisks, LibvirtDomainXMLParser xmlParser) {
270-
List<UnmanagedInstanceTO.Disk> instanceDisks = new ArrayList<>();
271-
List<LibvirtVMDef.DiskDef> diskDefs = xmlParser != null ? xmlParser.getDisks() : null;
272-
for (int i = 0; i< vmDisks.size(); i++) {
273-
KVMPhysicalDisk physicalDisk = vmDisks.get(i);
274-
KVMStoragePool storagePool = physicalDisk.getPool();
275-
UnmanagedInstanceTO.Disk disk = new UnmanagedInstanceTO.Disk();
276-
disk.setPosition(i);
277-
Pair<String, String> storagePoolHostAndPath = getNfsStoragePoolHostAndPath(storagePool);
278-
disk.setDatastoreHost(storagePoolHostAndPath.first());
279-
disk.setDatastorePath(storagePoolHostAndPath.second());
280-
disk.setDatastoreName(storagePool.getUuid());
281-
disk.setDatastoreType(storagePool.getType().name());
282-
disk.setCapacity(physicalDisk.getVirtualSize());
283-
disk.setFileBaseName(physicalDisk.getName());
284-
if (CollectionUtils.isNotEmpty(diskDefs)) {
285-
LibvirtVMDef.DiskDef diskDef = diskDefs.get(i);
286-
disk.setController(diskDef.getBusType() != null ? diskDef.getBusType().toString() : LibvirtVMDef.DiskDef.DiskBus.VIRTIO.toString());
287-
} else {
288-
// If the job is finished but we cannot parse the XML, the guest VM can use the virtio driver
289-
disk.setController(LibvirtVMDef.DiskDef.DiskBus.VIRTIO.toString());
290-
}
291-
instanceDisks.add(disk);
292-
}
293-
return instanceDisks;
294-
}
295-
296-
protected Pair<String, String> getNfsStoragePoolHostAndPath(KVMStoragePool storagePool) {
297-
String sourceHostIp = null;
298-
String sourcePath = null;
299-
List<String[]> commands = new ArrayList<>();
300-
commands.add(new String[]{Script.getExecutableAbsolutePath("mount")});
301-
commands.add(new String[]{Script.getExecutableAbsolutePath("grep"), storagePool.getLocalPath()});
302-
String storagePoolMountPoint = Script.executePipedCommands(commands, 0).second();
303-
s_logger.debug(String.format("NFS Storage pool: %s - local path: %s, mount point: %s", storagePool.getUuid(), storagePool.getLocalPath(), storagePoolMountPoint));
304-
if (StringUtils.isNotEmpty(storagePoolMountPoint)) {
305-
String[] res = storagePoolMountPoint.strip().split(" ");
306-
res = res[0].split(":");
307-
if (res.length > 1) {
308-
sourceHostIp = res[0].strip();
309-
sourcePath = res[1].strip();
310-
}
311-
}
312-
return new Pair<>(sourceHostIp, sourcePath);
313-
}
314-
315201
private boolean exportOVAFromVMOnVcenter(String vmExportUrl,
316202
String targetOvfDir,
317203
int noOfThreads,

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtImportConvertedInstanceCommandWrapper.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,12 @@ public Answer execute(ImportConvertedInstanceCommand cmd, LibvirtComputingResour
6969
String sourceInstanceName = sourceInstance.getInstanceName();
7070
List<String> destinationStoragePools = cmd.getDestinationStoragePools();
7171
DataStoreTO conversionTemporaryLocation = cmd.getConversionTemporaryLocation();
72+
final String temporaryConvertUuid = cmd.getTemporaryConvertUuid();
7273

7374
final KVMStoragePoolManager storagePoolMgr = serverResource.getStoragePoolMgr();
7475
KVMStoragePool temporaryStoragePool = getTemporaryStoragePool(conversionTemporaryLocation, storagePoolMgr);
7576
final String temporaryConvertPath = temporaryStoragePool.getLocalPath();
7677

77-
final String temporaryConvertUuid = UUID.randomUUID().toString();
78-
7978
try {
8079
String convertedBasePath = String.format("%s/%s", temporaryConvertPath, temporaryConvertUuid);
8180
LibvirtDomainXMLParser xmlParser = parseMigratedVMXmlDomain(convertedBasePath);

0 commit comments

Comments
 (0)