Skip to content

Commit 211b180

Browse files
RPDiepwido
authored andcommitted
Replaced virsh() by python-libvirt functions
Signed-off-by: Rene Diepstraten <rene@renediepstraten.nl>
1 parent 2c5388a commit 211b180

3 files changed

Lines changed: 101 additions & 35 deletions

File tree

debian/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Description: CloudStack server library
2222

2323
Package: cloudstack-agent
2424
Architecture: all
25-
Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, libjna-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset
25+
Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, libjna-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt
2626
Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts
2727
Description: CloudStack agent
2828
The CloudStack agent is in charge of managing shared computing resources in

packaging/centos63/cloud.spec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Requires: jsvc
122122
Requires: jakarta-commons-daemon
123123
Requires: jakarta-commons-daemon-jsvc
124124
Requires: perl
125+
Requires: libvirt-python
125126
Provides: cloud-agent
126127
Obsoletes: cloud-agent < 4.1.0
127128
Obsoletes: cloud-agent-libs < 4.1.0

scripts/vm/network/security_group.py

Lines changed: 99 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
2727
import re
2828
import traceback
29+
import libvirt
2930

3031
logpath = "/var/run/cloud/" # FIXME: Logs should reside in /var/log/cloud
3132
iptables = Command("iptables")
3233
bash = Command("/bin/bash")
33-
virsh = Command("virsh")
3434
ebtablessave = Command("ebtables-save")
3535
ebtables = Command("ebtables")
3636
def 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

87159
def 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

511583
def 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

594662
def 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

828884
def 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

842897
def 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

859913
def 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

873926
def 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

877942
def addFWFramework(brname):
878943
try:

0 commit comments

Comments
 (0)