2525import java .util .UUID ;
2626import java .util .stream .Collectors ;
2727
28+ import com .cloud .agent .api .ConvertInstanceAnswer ;
2829import org .apache .cloudstack .storage .to .PrimaryDataStoreTO ;
2930import org .apache .cloudstack .vm .UnmanagedInstanceTO ;
3031import 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 ,
0 commit comments