1818//
1919package com .cloud .hypervisor .kvm .resource .wrapper ;
2020
21- import java .io .BufferedInputStream ;
22- import java .io .File ;
23- import java .io .FileInputStream ;
24- import java .io .IOException ;
25- import java .io .InputStream ;
21+
2622import java .net .URLEncoder ;
2723import java .nio .charset .Charset ;
28- import java .util .ArrayList ;
2924import java .util .List ;
3025import java .util .UUID ;
31- import java .util .stream .Collectors ;
32-
3326import org .apache .cloudstack .storage .to .PrimaryDataStoreTO ;
34- import org .apache .cloudstack .vm .UnmanagedInstanceTO ;
35- import org .apache .commons .collections .CollectionUtils ;
36- import org .apache .commons .io .IOUtils ;
3727import org .apache .commons .lang3 .StringUtils ;
3828
3929import com .cloud .agent .api .Answer ;
4434import com .cloud .agent .api .to .RemoteInstanceTO ;
4535import com .cloud .hypervisor .Hypervisor ;
4636import com .cloud .hypervisor .kvm .resource .LibvirtComputingResource ;
47- import com .cloud .hypervisor .kvm .resource .LibvirtDomainXMLParser ;
4837import com .cloud .hypervisor .kvm .resource .LibvirtVMDef ;
49- import com .cloud .hypervisor .kvm .storage .KVMPhysicalDisk ;
5038import com .cloud .hypervisor .kvm .storage .KVMStoragePool ;
5139import com .cloud .hypervisor .kvm .storage .KVMStoragePoolManager ;
5240import com .cloud .resource .CommandWrapper ;
5341import com .cloud .resource .ResourceWrapper ;
54- import com .cloud .storage .Storage ;
5542import com .cloud .utils .FileUtil ;
56- import com .cloud .utils .Pair ;
57- import com .cloud .utils .exception .CloudRuntimeException ;
5843import com .cloud .utils .script .OutputInterpreter ;
5944import com .cloud .utils .script .Script ;
6045
@@ -70,7 +55,6 @@ public Answer execute(ConvertInstanceCommand cmd, LibvirtComputingResource serve
7055 Hypervisor .HypervisorType sourceHypervisorType = sourceInstance .getHypervisorType ();
7156 String sourceInstanceName = sourceInstance .getInstanceName ();
7257 Hypervisor .HypervisorType destinationHypervisorType = cmd .getDestinationHypervisorType ();
73- List <String > destinationStoragePools = cmd .getDestinationStoragePools ();
7458 DataStoreTO conversionTemporaryLocation = cmd .getConversionTemporaryLocation ();
7559 long timeout = (long ) cmd .getWait () * 1000 ;
7660
@@ -130,7 +114,6 @@ public Answer execute(ConvertInstanceCommand cmd, LibvirtComputingResource serve
130114 final String temporaryConvertUuid = UUID .randomUUID ().toString ();
131115 boolean verboseModeEnabled = serverResource .isConvertInstanceVerboseModeEnabled ();
132116
133- boolean cleanupSecondaryStorage = false ;
134117 try {
135118 boolean result = performInstanceConversion (sourceOVFDirPath , temporaryConvertPath , temporaryConvertUuid ,
136119 timeout , verboseModeEnabled );
@@ -148,18 +131,13 @@ public Answer execute(ConvertInstanceCommand cmd, LibvirtComputingResource serve
148131 String error = String .format ("Error converting instance %s from %s, due to: %s" ,
149132 sourceInstanceName , sourceHypervisorType , e .getMessage ());
150133 logger .error (error , e );
151- cleanupSecondaryStorage = true ;
152134 return new ConvertInstanceAnswer (cmd , false , error );
153135 } finally {
154136 if (ovfExported && StringUtils .isNotBlank (ovfTemplateDirOnConversionLocation )) {
155137 String sourceOVFDir = String .format ("%s/%s" , temporaryConvertPath , ovfTemplateDirOnConversionLocation );
156138 logger .debug ("Cleaning up exported OVA at dir " + sourceOVFDir );
157139 FileUtil .deletePath (sourceOVFDir );
158140 }
159- if (cleanupSecondaryStorage && conversionTemporaryLocation instanceof NfsTO ) {
160- logger .debug ("Cleaning up secondary storage temporary location" );
161- storagePoolMgr .deleteStoragePool (temporaryStoragePool .getType (), temporaryStoragePool .getUuid ());
162- }
163141 }
164142 }
165143
@@ -200,55 +178,6 @@ private String getExportOVAUrlFromRemoteInstance(RemoteInstanceTO vmwareInstance
200178 encodedUsername , encodedPassword , vcenter , datacenter , vm );
201179 }
202180
203- protected List <KVMPhysicalDisk > getTemporaryDisksFromParsedXml (KVMStoragePool pool , LibvirtDomainXMLParser xmlParser , String convertedBasePath ) {
204- List <LibvirtVMDef .DiskDef > disksDefs = xmlParser .getDisks ();
205- disksDefs = disksDefs .stream ().filter (x -> x .getDiskType () == LibvirtVMDef .DiskDef .DiskType .FILE &&
206- x .getDeviceType () == LibvirtVMDef .DiskDef .DeviceType .DISK ).collect (Collectors .toList ());
207- if (CollectionUtils .isEmpty (disksDefs )) {
208- String err = String .format ("Cannot find any disk defined on the converted XML domain %s.xml" , convertedBasePath );
209- logger .error (err );
210- throw new CloudRuntimeException (err );
211- }
212- sanitizeDisksPath (disksDefs );
213- return getPhysicalDisksFromDefPaths (disksDefs , pool );
214- }
215-
216- private List <KVMPhysicalDisk > getPhysicalDisksFromDefPaths (List <LibvirtVMDef .DiskDef > disksDefs , KVMStoragePool pool ) {
217- List <KVMPhysicalDisk > disks = new ArrayList <>();
218- for (LibvirtVMDef .DiskDef diskDef : disksDefs ) {
219- KVMPhysicalDisk physicalDisk = pool .getPhysicalDisk (diskDef .getDiskPath ());
220- disks .add (physicalDisk );
221- }
222- return disks ;
223- }
224-
225- protected List <KVMPhysicalDisk > getTemporaryDisksWithPrefixFromTemporaryPool (KVMStoragePool pool , String path , String prefix ) {
226- String msg = String .format ("Could not parse correctly the converted XML domain, checking for disks on %s with prefix %s" , path , prefix );
227- logger .info (msg );
228- pool .refresh ();
229- List <KVMPhysicalDisk > disksWithPrefix = pool .listPhysicalDisks ()
230- .stream ()
231- .filter (x -> x .getName ().startsWith (prefix ) && !x .getName ().endsWith (".xml" ))
232- .collect (Collectors .toList ());
233- if (CollectionUtils .isEmpty (disksWithPrefix )) {
234- msg = String .format ("Could not find any converted disk with prefix %s on temporary location %s" , prefix , path );
235- logger .error (msg );
236- throw new CloudRuntimeException (msg );
237- }
238- return disksWithPrefix ;
239- }
240-
241- private void cleanupDisksAndDomainFromTemporaryLocation (List <KVMPhysicalDisk > disks ,
242- KVMStoragePool temporaryStoragePool ,
243- String temporaryConvertUuid ) {
244- for (KVMPhysicalDisk disk : disks ) {
245- logger .info (String .format ("Cleaning up temporary disk %s after conversion from temporary location" , disk .getName ()));
246- temporaryStoragePool .deletePhysicalDisk (disk .getName (), Storage .ImageFormat .QCOW2 );
247- }
248- logger .info (String .format ("Cleaning up temporary domain %s after conversion from temporary location" , temporaryConvertUuid ));
249- FileUtil .deleteFiles (temporaryStoragePool .getLocalPath (), temporaryConvertUuid , ".xml" );
250- }
251-
252181 protected void sanitizeDisksPath (List <LibvirtVMDef .DiskDef > disks ) {
253182 for (LibvirtVMDef .DiskDef disk : disks ) {
254183 String [] diskPathParts = disk .getDiskPath ().split ("/" );
@@ -257,105 +186,6 @@ protected void sanitizeDisksPath(List<LibvirtVMDef.DiskDef> disks) {
257186 }
258187 }
259188
260- protected List <KVMPhysicalDisk > moveTemporaryDisksToDestination (List <KVMPhysicalDisk > temporaryDisks ,
261- List <String > destinationStoragePools ,
262- KVMStoragePoolManager storagePoolMgr ) {
263- List <KVMPhysicalDisk > targetDisks = new ArrayList <>();
264- String poolUuid = destinationStoragePools .get (0 );
265- logger .debug (String .format ("Destination Pool UUID : %s" , poolUuid ));
266- for (int i = 0 ; i < temporaryDisks .size (); i ++) {
267- KVMStoragePool destinationPool = storagePoolMgr .getStoragePool (Storage .StoragePoolType .RBD , poolUuid );
268- if (destinationPool == null ) {
269- String err = String .format ("Could not find a storage pool : %s" , destinationPool );
270- logger .error (err );
271- continue ;
272- }
273- KVMPhysicalDisk sourceDisk = temporaryDisks .get (i );
274- if (logger .isDebugEnabled ()) {
275- String msg = String .format ("Trying to copy converted instance disk number %s from the temporary location %s" +
276- " to destination storage pool %s" , i , sourceDisk .getPool ().getLocalPath (), destinationPool .getUuid ());
277- logger .debug (msg );
278- }
279-
280- String destinationName = UUID .randomUUID ().toString ();
281-
282- KVMPhysicalDisk destinationDisk = storagePoolMgr .copyPhysicalDisk (sourceDisk , destinationName , destinationPool , 7200 * 1000 );
283- targetDisks .add (destinationDisk );
284- }
285- return targetDisks ;
286- }
287-
288- private UnmanagedInstanceTO getConvertedUnmanagedInstance (String baseName ,
289- List <KVMPhysicalDisk > vmDisks ,
290- LibvirtDomainXMLParser xmlParser ) {
291- UnmanagedInstanceTO instanceTO = new UnmanagedInstanceTO ();
292- instanceTO .setName (baseName );
293- instanceTO .setDisks (getUnmanagedInstanceDisks (vmDisks , xmlParser ));
294- instanceTO .setNics (getUnmanagedInstanceNics (xmlParser ));
295- return instanceTO ;
296- }
297-
298- private List <UnmanagedInstanceTO .Nic > getUnmanagedInstanceNics (LibvirtDomainXMLParser xmlParser ) {
299- List <UnmanagedInstanceTO .Nic > nics = new ArrayList <>();
300- if (xmlParser != null ) {
301- List <LibvirtVMDef .InterfaceDef > interfaces = xmlParser .getInterfaces ();
302- for (LibvirtVMDef .InterfaceDef interfaceDef : interfaces ) {
303- UnmanagedInstanceTO .Nic nic = new UnmanagedInstanceTO .Nic ();
304- nic .setMacAddress (interfaceDef .getMacAddress ());
305- nic .setNicId (interfaceDef .getBrName ());
306- nic .setAdapterType (interfaceDef .getModel ().toString ());
307- nics .add (nic );
308- }
309- }
310- return nics ;
311- }
312-
313- protected List <UnmanagedInstanceTO .Disk > getUnmanagedInstanceDisks (List <KVMPhysicalDisk > vmDisks , LibvirtDomainXMLParser xmlParser ) {
314- List <UnmanagedInstanceTO .Disk > instanceDisks = new ArrayList <>();
315- List <LibvirtVMDef .DiskDef > diskDefs = xmlParser != null ? xmlParser .getDisks () : null ;
316- for (int i = 0 ; i < vmDisks .size (); i ++) {
317- KVMPhysicalDisk physicalDisk = vmDisks .get (i );
318- KVMStoragePool storagePool = physicalDisk .getPool ();
319- UnmanagedInstanceTO .Disk disk = new UnmanagedInstanceTO .Disk ();
320- disk .setPosition (i );
321- Pair <String , String > storagePoolHostAndPath = getNfsStoragePoolHostAndPath (storagePool );
322- disk .setDatastoreHost (storagePoolHostAndPath .first ());
323- disk .setDatastorePath (storagePoolHostAndPath .second ());
324- disk .setDatastoreName (storagePool .getUuid ());
325- disk .setDatastoreType (storagePool .getType ().name ());
326- disk .setCapacity (physicalDisk .getVirtualSize ());
327- disk .setFileBaseName (physicalDisk .getName ());
328- if (CollectionUtils .isNotEmpty (diskDefs )) {
329- LibvirtVMDef .DiskDef diskDef = diskDefs .get (i );
330- disk .setController (diskDef .getBusType () != null ? diskDef .getBusType ().toString () : LibvirtVMDef .DiskDef .DiskBus .VIRTIO .toString ());
331- } else {
332- // If the job is finished but we cannot parse the XML, the guest VM can use the virtio driver
333- disk .setController (LibvirtVMDef .DiskDef .DiskBus .VIRTIO .toString ());
334- }
335- instanceDisks .add (disk );
336- }
337- return instanceDisks ;
338- }
339-
340- protected Pair <String , String > getNfsStoragePoolHostAndPath (KVMStoragePool storagePool ) {
341- String sourceHostIp = null ;
342- String sourcePath = null ;
343- List <String []> commands = new ArrayList <>();
344- commands .add (new String []{Script .getExecutableAbsolutePath ("mount" )});
345- commands .add (new String []{Script .getExecutableAbsolutePath ("grep" ), storagePool .getLocalPath ()});
346- String storagePoolMountPoint = Script .executePipedCommands (commands , 0 ).second ();
347- logger .debug (String .format ("NFS Storage pool: %s - local path: %s, mount point: %s" , storagePool .getUuid (), storagePool .getLocalPath (), storagePoolMountPoint ));
348- if (StringUtils .isNotEmpty (storagePoolMountPoint )) {
349- String [] res = storagePoolMountPoint .strip ().split (" " );
350- res = res [0 ].split (":" );
351- if (res .length > 1 ) {
352- sourceHostIp = res [0 ].strip ();
353- sourcePath = res [1 ].strip ();
354- }
355- }
356- return new Pair <>(sourceHostIp , sourcePath );
357- }
358-
359189 private boolean exportOVAFromVMOnVcenter (String vmExportUrl ,
360190 String targetOvfDir ,
361191 int noOfThreads ,
@@ -398,27 +228,6 @@ protected boolean performInstanceConversion(String sourceOVFDirPath,
398228 return exitValue == 0 ;
399229 }
400230
401- protected LibvirtDomainXMLParser parseMigratedVMXmlDomain (String installPath ) throws IOException {
402- String xmlPath = String .format ("%s.xml" , installPath );
403- if (!new File (xmlPath ).exists ()) {
404- String err = String .format ("Conversion failed. Unable to find the converted XML domain, expected %s" , xmlPath );
405- logger .error (err );
406- throw new CloudRuntimeException (err );
407- }
408- InputStream is = new BufferedInputStream (new FileInputStream (xmlPath ));
409- String xml = IOUtils .toString (is , Charset .defaultCharset ());
410- final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser ();
411- try {
412- parser .parseDomainXML (xml );
413- return parser ;
414- } catch (RuntimeException e ) {
415- String err = String .format ("Error parsing the converted instance XML domain at %s: %s" , xmlPath , e .getMessage ());
416- logger .error (err , e );
417- logger .debug (xml );
418- return null ;
419- }
420- }
421-
422231 protected String encodeUsername (String username ) {
423232 return URLEncoder .encode (username , Charset .defaultCharset ());
424233 }
0 commit comments