1919
2020package com .cloud .hypervisor .kvm .resource .wrapper ;
2121
22+ import java .net .URISyntaxException ;
23+
2224import org .libvirt .Connect ;
2325import org .libvirt .Domain ;
2426import org .libvirt .LibvirtException ;
2527
2628import com .cloud .agent .api .Answer ;
2729import com .cloud .agent .api .UnmanageInstanceAnswer ;
2830import com .cloud .agent .api .UnmanageInstanceCommand ;
31+ import com .cloud .agent .api .to .VirtualMachineTO ;
32+ import com .cloud .exception .InternalErrorException ;
2933import com .cloud .hypervisor .kvm .resource .LibvirtComputingResource ;
34+ import com .cloud .hypervisor .kvm .resource .LibvirtKvmAgentHook ;
35+ import com .cloud .hypervisor .kvm .resource .LibvirtVMDef ;
3036import com .cloud .resource .CommandWrapper ;
3137import com .cloud .resource .ResourceWrapper ;
3238
@@ -37,18 +43,60 @@ public final class LibvirtUnmanageInstanceCommandWrapper extends CommandWrapper<
3743 @ Override
3844 public Answer execute (final UnmanageInstanceCommand command , final LibvirtComputingResource libvirtComputingResource ) {
3945 String instanceName = command .getInstanceName ();
46+ VirtualMachineTO vmSpec = command .getVm ();
4047 final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource .getLibvirtUtilitiesHelper ();
41- logger .debug ("Unmanaging KVM instance: {}" , instanceName );
48+ logger .debug ("Attempting to unmanage KVM instance: {}" , instanceName );
49+ Domain dom = null ;
50+ Connect conn = null ;
4251 try {
43- Connect conn = libvirtUtilitiesHelper .getConnectionByVmName (instanceName );
44- Domain dom = conn .domainLookupByName (instanceName );
45- String domainXML = dom .getXMLDesc (1 );
46- conn .domainDefineXML (domainXML );
52+ if (vmSpec == null ) {
53+ conn = libvirtUtilitiesHelper .getConnectionByVmName (instanceName );
54+ dom = conn .domainLookupByName (instanceName );
55+ String domainXML = dom .getXMLDesc (1 );
56+ conn .domainDefineXML (domainXML ).free ();
57+ } else {
58+ // define domain using reconstructed vmSpec
59+ logger .debug ("Unmanaging Stopped KVM instance: {}" , instanceName );
60+ LibvirtVMDef vm = libvirtComputingResource .createVMFromSpec (vmSpec );
61+ libvirtComputingResource .createVbd (conn , vmSpec , instanceName , vm );
62+ conn = libvirtUtilitiesHelper .getConnectionByType (vm .getHvsType ());
63+ String vmInitialSpecification = vm .toString ();
64+ String vmFinalSpecification = performXmlTransformHook (vmInitialSpecification , libvirtComputingResource );
65+ conn .domainDefineXML (vmFinalSpecification ).free ();
66+ }
4767 logger .debug ("Successfully unmanaged KVM instance: {}" , instanceName );
4868 return new UnmanageInstanceAnswer (command , true , "Successfully unmanaged" );
49- } catch (final LibvirtException ex ) {
50- logger .warn ("LibvirtException occurred during unmanaging instance: {} " , instanceName , ex );
51- return new UnmanageInstanceAnswer (command , false , ex .getMessage ());
69+ } catch (final LibvirtException e ) {
70+ logger .warn ("LibvirtException occurred during unmanaging instance: {} " , instanceName , e );
71+ return new UnmanageInstanceAnswer (command , false , e .getMessage ());
72+ } catch (final URISyntaxException | InternalErrorException e ) {
73+ logger .warn ("URISyntaxException " , e );
74+ return new UnmanageInstanceAnswer (command , false , e .getMessage ());
75+ } finally {
76+ if (dom != null ) {
77+ try {
78+ dom .free ();
79+ } catch (LibvirtException e ) {
80+ logger .error ("Ignore libvirt error on free." , e );
81+ }
82+ }
83+ }
84+ }
85+
86+ private String performXmlTransformHook (String vmInitialSpecification , final LibvirtComputingResource libvirtComputingResource ) {
87+ String vmFinalSpecification ;
88+ try {
89+ // if transformer fails, everything must go as it's just skipped.
90+ LibvirtKvmAgentHook t = libvirtComputingResource .getTransformer ();
91+ vmFinalSpecification = (String ) t .handle (vmInitialSpecification );
92+ if (null == vmFinalSpecification ) {
93+ logger .warn ("Libvirt XML transformer returned NULL, will use XML specification unchanged." );
94+ vmFinalSpecification = vmInitialSpecification ;
95+ }
96+ } catch (Exception e ) {
97+ logger .warn ("Exception occurred when handling LibVirt XML transformer hook: {}" , e );
98+ vmFinalSpecification = vmInitialSpecification ;
5299 }
100+ return vmFinalSpecification ;
53101 }
54102}
0 commit comments