Locking: Let's get some locking mechanism so we hopefully step less on

each others toes.
This commit is contained in:
Dominique Leuenberger 2015-02-09 17:25:43 +01:00 committed by Alberto Planas
parent 8ccb01701d
commit 12c2f5618c

View File

@ -8,12 +8,14 @@ import json
import logging
import urllib2
import time
import sys
import re
from xml.etree import cElementTree as ET
import yaml
from osc import oscerr
from osc import conf
from osc.core import change_review_state
from osc.core import delete_package
from osc.core import get_request
@ -36,8 +38,10 @@ class StagingAPI(object):
Initialize instance variables
"""
user = conf.config['api_host_options'][apiurl]['user']
self.apiurl = apiurl
self.opensuse = opensuse
self.grab_lock('openSUSE:Factory:Staging', user)
self.rings = (
'openSUSE:{}:Rings:0-Bootstrap'.format(self.opensuse),
'openSUSE:{}:Rings:1-MinimalX'.format(self.opensuse),
@ -46,6 +50,9 @@ class StagingAPI(object):
self.ring_packages = self._generate_ring_packages()
self.packages_staged = self._get_staged_requests()
def __del__(self):
self.release_lock('openSUSE:Factory:Staging')
def makeurl(self, l, query=None):
"""
Wrapper around osc's makeurl passing our apiurl
@ -84,6 +91,42 @@ class StagingAPI(object):
return self.retried_PUT(url, data)
raise e
def read_lock(self, project):
url = self.makeurl(['source', project, '_attribute', 'openSUSE:LockedBy'])
root = ET.parse(http_GET(url)).getroot()
try:
lockedby = root[0][0].text
except IndexError:
# There was no value specified we could parse - assume unlocked
lockedby = None
return lockedby
def set_lock(self, project, user):
url = self.makeurl(['source', project, '_attribute', 'openSUSE:LockedBy'])
try:
schema = "<attributes><attribute namespace='openSUSE' name='LockedBy'><value>%s</value></attribute></attributes>"
http_POST(url, data=schema % user)
except:
print "Failed to acquire lock - exiting"
sys.exit(2)
def grab_lock(self, project, user):
lockedby = self.read_lock(project)
if lockedby != None:
print "Staging tasks are currently executed by %s - project locked" % lockedby
sys.exit(9)
self.set_lock(project, user)
# wait 2s to see if the lock is now actually ours or if we were racing somebody
time.sleep(2)
lockedby = self.read_lock(project)
if lockedby != user:
print "Lock was stolen by '%s' - ABORTING" % lockedby
sys.exit(8)
def release_lock(self, project):
self.set_lock(project, '')
def _generate_ring_packages(self):
"""
Generate dictionary with names of the rings