
While trying to create multiple templates I got the following error on console: [08/Jun/2015:12:57:23] HTTP Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 670, in respond response.body = self.handler() File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 217, in __call__ self.body = self.oldhandler(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 61, in __call__ return self.callable(*self.args, **self.kwargs) File "/home/alinefm/kimchi/src/kimchi/control/base.py", line 330, in index return self.create(parse_request(), *args) File "/home/alinefm/kimchi/src/kimchi/control/base.py", line 262, in create name = create(*args) File "/home/alinefm/kimchi/src/kimchi/model/templates.py", line 48, in create user = UserTests().probe_user() File "/home/alinefm/kimchi/src/kimchi/kvmusertests.py", line 55, in probe_user flags=libvirt.VIR_DOMAIN_START_AUTODESTROY) File "/usr/lib/python2.7/dist-packages/libvirt.py", line 3424, in createXML if ret is None:raise libvirtError('virDomainCreateXML() failed', conn=self) libvirtError: operation failed: domain 'KVMUSERTEST_VM' already exists with uuid 2be4b2e8-f57a-4f87-8c24-5ac59d4bb4af The error happens because of a race condition while trying to get the kvm user (to validate the ISO file permissions). To avoid this problem, a lock was added to ensure the code is run once at a time. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- src/kimchi/kvmusertests.py | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/kimchi/kvmusertests.py b/src/kimchi/kvmusertests.py index 37a80d7..5724267 100644 --- a/src/kimchi/kvmusertests.py +++ b/src/kimchi/kvmusertests.py @@ -18,6 +18,7 @@ import platform import psutil +import threading import libvirt @@ -36,12 +37,14 @@ class UserTests(object): <boot dev='hd'/> </os> </domain>""" + lock = threading.Lock() user = None @classmethod def probe_user(cls): - if cls.user: - return cls.user + with cls.lock: + if cls.user: + return cls.user arch = 'ppc64' if platform.machine() == 'ppc64le' \ else platform.machine() @@ -49,23 +52,24 @@ class UserTests(object): xml = cls.SIMPLE_VM_XML % {'name': KVMUSERTEST_VM_NAME, 'arch': arch} with RollbackContext() as rollback: - conn = libvirt.open(None) - rollback.prependDefer(conn.close) - dom = conn.createXML(xml, - flags=libvirt.VIR_DOMAIN_START_AUTODESTROY) - rollback.prependDefer(dom.destroy) - filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME - with open(filename) as f: - pidStr = f.read() - p = psutil.Process(int(pidStr)) + with cls.lock: + conn = libvirt.open(None) + rollback.prependDefer(conn.close) + f = libvirt.VIR_DOMAIN_START_AUTODESTROY + dom = conn.createXML(xml, flags=f) + rollback.prependDefer(dom.destroy) + filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME + with open(filename) as f: + pidStr = f.read() + p = psutil.Process(int(pidStr)) - # bug fix #357 - # in psutil 2.0 and above versions, username will be a method, - # not a string - if callable(p.username): - cls.user = p.username() - else: - cls.user = p.username + # bug fix #357 + # in psutil 2.0 and above versions, username will be a method, + # not a string + if callable(p.username): + cls.user = p.username() + else: + cls.user = p.username return cls.user -- 2.1.0