2626from optparse import OptionParser , OptionGroup , OptParseError , BadOptionError , OptionError , OptionConflictError , OptionValueError
2727import re
2828import traceback
29+ import libvirt
2930
3031logpath = "/var/run/cloud/" # FIXME: Logs should reside in /var/log/cloud
3132iptables = Command ("iptables" )
3233bash = Command ("/bin/bash" )
33- virsh = Command ("virsh" )
3434ebtablessave = Command ("ebtables-save" )
3535ebtables = Command ("ebtables" )
3636def execute (cmd ):
@@ -83,6 +83,78 @@ def ipset(ipsetname, proto, start, end, ips):
8383
8484 return result
8585'''
86+ def virshlist (* states ):
87+
88+ libvirt_states = { 'running' : libvirt .VIR_DOMAIN_RUNNING ,
89+ 'shutoff' : libvirt .VIR_DOMAIN_SHUTOFF ,
90+ 'shutdown' : libvirt .VIR_DOMAIN_SHUTDOWN ,
91+ 'paused' : libvirt .VIR_DOMAIN_PAUSED ,
92+ 'nostate' : libvirt .VIR_DOMAIN_NOSTATE ,
93+ 'blocked' : libvirt .VIR_DOMAIN_BLOCKED ,
94+ 'crashed' : libvirt .VIR_DOMAIN_CRASHED ,
95+ }
96+
97+ searchstates = list (libvirt_states [state ] for state in states )
98+
99+ conn = libvirt .openReadOnly ('qemu:///system' )
100+ if conn == None :
101+ print 'Failed to open connection to the hypervisor'
102+ sys .exit (3 )
103+
104+ alldomains = map (conn .lookupByID , conn .listDomainsID ())
105+ alldomains += map (conn .lookupByName , conn .listDefinedDomains ())
106+
107+ domains = []
108+ for domain in alldomains :
109+ if domain .info ()[0 ] in searchstates :
110+ domains .append (domain .name ())
111+
112+ conn .close ()
113+
114+ return domains
115+
116+ def virshdomstate (domain ):
117+
118+ libvirt_states = { libvirt .VIR_DOMAIN_RUNNING : 'running' ,
119+ libvirt .VIR_DOMAIN_SHUTOFF : 'shut off' ,
120+ libvirt .VIR_DOMAIN_SHUTDOWN : 'shut down' ,
121+ libvirt .VIR_DOMAIN_PAUSED : 'paused' ,
122+ libvirt .VIR_DOMAIN_NOSTATE : 'no state' ,
123+ libvirt .VIR_DOMAIN_BLOCKED : 'blocked' ,
124+ libvirt .VIR_DOMAIN_CRASHED : 'crashed' ,
125+ }
126+
127+ conn = libvirt .openReadOnly ('qemu:///system' )
128+ if conn == None :
129+ print 'Failed to open connection to the hypervisor'
130+ sys .exit (3 )
131+
132+ try :
133+ dom = (conn .lookupByName (domain ))
134+ except libvirt .libvirtError :
135+ return None
136+
137+ state = libvirt_states [dom .info ()[0 ]]
138+ conn .close ()
139+
140+ return state
141+
142+ def virshdumpxml (domain ):
143+
144+ conn = libvirt .openReadOnly ('qemu:///system' )
145+ if conn == None :
146+ print 'Failed to open connection to the hypervisor'
147+ sys .exit (3 )
148+
149+ try :
150+ dom = (conn .lookupByName (domain ))
151+ except libvirt .libvirtError :
152+ return None
153+
154+ xml = dom .XMLDesc (0 )
155+ conn .close ()
156+
157+ return xml
86158
87159def destroy_network_rules_for_vm (vm_name , vif = None ):
88160 vmchain = vm_name
@@ -509,13 +581,9 @@ def get_rule_log_for_vm(vmName):
509581 return ',' .join ([_vmName , _vmID , _vmIP , _domID , _signature , _seqno ])
510582
511583def check_domid_changed (vmName ):
512- curr_domid = '-1'
513- try :
514- curr_domid = getvmId (vmName )
515- if (curr_domid is None ) or (not curr_domid .isdigit ()):
516- curr_domid = '-1'
517- except :
518- pass
584+ curr_domid = getvmId (vmName )
585+ if (curr_domid is None ) or (not curr_domid .isdigit ()):
586+ curr_domid = '-1'
519587
520588 vm_name = vmName ;
521589 logfilename = logpath + vm_name + ".log"
@@ -592,8 +660,7 @@ def network_rules_for_rebooted_vm(vmName):
592660 return True
593661
594662def get_rule_logs_for_vms ():
595- cmd = "virsh list|awk '/running/ {print $2}'"
596- vms = bash ("-c" , cmd ).stdout .split ("\n " )
663+ vms = virshlist ('running' )
597664
598665 result = []
599666 try :
@@ -623,11 +690,7 @@ def cleanup_rules():
623690 if 1 in [ chain .startswith (c ) for c in ['r-' , 'i-' , 's-' , 'v-' ] ]:
624691 vm_name = chain
625692
626- cmd = "virsh list |awk '/" + vm_name + "/ {print $3}'"
627- try :
628- result = execute (cmd ).strip ()
629- except :
630- result = None
693+ result = virshdomstate (vm_name )
631694
632695 if result == None or len (result ) == 0 :
633696 logging .debug ("chain " + chain + " does not correspond to a vm, cleaning up iptable rules" )
@@ -643,11 +706,7 @@ def cleanup_rules():
643706 if 1 in [ chain .startswith (c ) for c in ['r-' , 'i-' , 's-' , 'v-' ] ]:
644707 vm_name = chain
645708
646- cmd = "virsh list |awk '/" + vm_name + "/ {print $3}'"
647- try :
648- result = execute (cmd ).strip ()
649- except :
650- result = None
709+ result = virshdomstate (vm_name )
651710
652711 if result == None or len (result ) == 0 :
653712 logging .debug ("chain " + chain + " does not correspond to a vm, cleaning up ebtable rules" )
@@ -727,9 +786,6 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif
727786 vmName = vm_name
728787 domId = getvmId (vmName )
729788
730-
731-
732-
733789 changes = []
734790 changes = check_rule_log_for_vm (vmName , vm_id , vm_ip , domId , signature , seqno )
735791
@@ -827,9 +883,8 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif
827883
828884def getVifs (vmName ):
829885 vifs = []
830- try :
831- xmlfile = virsh ("dumpxml" , vmName ).stdout
832- except :
886+ xmlfile = virshdumpxml (vmName )
887+ if xmlfile == None :
833888 return vifs
834889
835890 dom = xml .dom .minidom .parseString (xmlfile )
@@ -841,9 +896,8 @@ def getVifs(vmName):
841896
842897def getVifsForBridge (vmName , brname ):
843898 vifs = []
844- try :
845- xmlfile = virsh ("dumpxml" , vmName ).stdout
846- except :
899+ xmlfile = virshdumpxml (vmName )
900+ if xmlfile == None :
847901 return vifs
848902
849903 dom = xml .dom .minidom .parseString (xmlfile )
@@ -858,9 +912,8 @@ def getVifsForBridge(vmName, brname):
858912
859913def getBridges (vmName ):
860914 bridges = []
861- try :
862- xmlfile = virsh ("dumpxml" , vmName ).stdout
863- except :
915+ xmlfile = virshdumpxml (vmName )
916+ if xmlfile == None :
864917 return bridges
865918
866919 dom = xml .dom .minidom .parseString (xmlfile )
@@ -871,8 +924,20 @@ def getBridges(vmName):
871924 return list (set (bridges ))
872925
873926def getvmId (vmName ):
874- cmd = "virsh list |awk '/" + vmName + "/ {print $1}'"
875- return bash ("-c" , cmd ).stdout .strip ()
927+
928+ conn = libvirt .openReadOnly ('qemu:///system' )
929+ if conn == None :
930+ print 'Failed to open connection to the hypervisor'
931+ sys .exit (3 )
932+
933+ try :
934+ dom = (conn .lookupByName (domain ))
935+ except libvirt .libvirtError :
936+ return None
937+
938+ conn .close ()
939+
940+ return dom .ID ()
876941
877942def addFWFramework (brname ):
878943 try :
0 commit comments