obslock: add reason to indicate what command is being run.
This commit is contained in:
parent
f6ec028ea5
commit
77f79f9175
@ -334,7 +334,7 @@ def do_staging(self, subcmd, opts, *args):
|
||||
if opts.wipe_cache:
|
||||
Cache.delete_all()
|
||||
|
||||
lock = OBSLock(opts.apiurl, opts.project)
|
||||
lock = OBSLock(opts.apiurl, opts.project, reason=cmd)
|
||||
if cmd == 'unlock':
|
||||
lock.release()
|
||||
return
|
||||
|
@ -28,7 +28,7 @@ from osc.core import http_POST
|
||||
class OBSLock(object):
|
||||
"""Implement a distributed lock using a shared OBS resource."""
|
||||
|
||||
def __init__(self, apiurl, project, ttl=3600):
|
||||
def __init__(self, apiurl, project, ttl=3600, reason=None):
|
||||
self.apiurl = apiurl
|
||||
self.project = project
|
||||
self.lock = conf.config[project]['lock']
|
||||
@ -36,21 +36,24 @@ class OBSLock(object):
|
||||
# TTL is measured in seconds
|
||||
self.ttl = ttl
|
||||
self.user = conf.config['api_host_options'][apiurl]['user']
|
||||
self.reason = reason
|
||||
self.locked = False
|
||||
|
||||
def _signature(self):
|
||||
"""Create a signature with a timestamp."""
|
||||
return '%s@%s' % (self.user, datetime.isoformat(datetime.utcnow()))
|
||||
reason = str(self.reason).replace('@', 'at').replace('#', 'hash')
|
||||
return '%s#%s@%s' % (self.user, reason, datetime.isoformat(datetime.utcnow()))
|
||||
|
||||
def _parse(self, signature):
|
||||
"""Parse a signature into an user and a timestamp."""
|
||||
user, ts = None, None
|
||||
user, reason, ts = None, None, None
|
||||
try:
|
||||
user, ts_str = signature.split('@')
|
||||
rest, ts_str = signature.split('@')
|
||||
user, reason = rest.split('#')
|
||||
ts = datetime.strptime(ts_str, '%Y-%m-%dT%H:%M:%S.%f')
|
||||
except (AttributeError, ValueError):
|
||||
pass
|
||||
return user, ts
|
||||
return user, reason, ts
|
||||
|
||||
def _read(self):
|
||||
url = makeurl(self.apiurl, ['source', self.lock, '_attribute', '%s:LockedBy' % self.ns])
|
||||
@ -79,20 +82,20 @@ class OBSLock(object):
|
||||
warnings.warn('Locking attribute is not found. Create one to avoid race conditions.')
|
||||
return self
|
||||
|
||||
user, ts = self._parse(self._read())
|
||||
user, reason, ts = self._parse(self._read())
|
||||
if user and ts:
|
||||
now = datetime.utcnow()
|
||||
if now < ts:
|
||||
raise Exception('Lock acquired from the future [%s] by [%s]. Try later.' % (ts, user))
|
||||
delta = now - ts
|
||||
if delta.seconds < self.ttl:
|
||||
print 'Lock acquired by [%s] %s ago. Try later.' % (user, delta)
|
||||
print 'Lock acquired by [%s] %s ago, reason <%s>. Try later.' % (user, delta, reason)
|
||||
exit(-1)
|
||||
# raise Exception('Lock acquired by [%s]. Try later.' % user)
|
||||
self._write(self._signature())
|
||||
|
||||
time.sleep(1)
|
||||
user, ts = self._parse(self._read())
|
||||
user, _, _ = self._parse(self._read())
|
||||
if user != self.user:
|
||||
raise Exception('Race condition, [%s] wins. Try later.' % user)
|
||||
|
||||
@ -104,7 +107,7 @@ class OBSLock(object):
|
||||
if not self.lock:
|
||||
return
|
||||
|
||||
user, ts = self._parse(self._read())
|
||||
user, reason, _ = self._parse(self._read())
|
||||
if user == self.user:
|
||||
self._write('')
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user