1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
243
243
# have a similar bug allowing someone to think they got the lock
244
244
# when it's already held.
246
# See <https://bugs.launchpad.net/bzr/+bug/498378> for one case.
246
# See <https://bugs.edge.launchpad.net/bzr/+bug/498378> for one case.
248
248
# Strictly the check is unnecessary and a waste of time for most
249
249
# people, but probably worth trapping if something is wrong.
253
253
raise LockFailed(self, "lock was renamed into place, but "
254
254
"now is missing!")
255
if info.get('nonce') != self.nonce:
255
if info['nonce'] != self.nonce:
256
256
self._trace("rename succeeded, "
257
257
"but lock is still held by someone else")
258
258
raise LockContention(self)
431
431
"""Check if the lock is held by anyone.
433
If it is held, this returns the lock info structure as a dict
433
If it is held, this returns the lock info structure as a rio Stanza,
434
434
which contains some information about the current lock holder.
435
435
Otherwise returns None.
447
447
# XXX: is creating this here inefficient?
448
448
config = bzrlib.config.GlobalConfig()
450
user = config.user_email()
451
except errors.NoEmailInUsername:
450
452
user = config.username()
451
except errors.NoWhoami:
452
user = osutils.getuser_unicode()
453
453
s = rio.Stanza(hostname=get_host_name(),
454
454
pid=str(os.getpid()),
455
455
start_time=str(int(time.time())),
459
459
return s.to_string()
461
461
def _parse_info(self, info_bytes):
462
stanza = rio.read_stanza(osutils.split_lines(info_bytes))
464
# see bug 185013; we fairly often end up with the info file being
465
# empty after an interruption; we could log a message here but
466
# there may not be much we can say
469
return stanza.as_dict()
462
# TODO: Handle if info_bytes is empty
463
return rio.read_stanza(osutils.split_lines(info_bytes)).as_dict()
471
465
def attempt_lock(self):
472
466
"""Take the lock; fail if it's already held.
539
533
if deadline_str is None:
540
534
deadline_str = time.strftime('%H:%M:%S',
541
535
time.localtime(deadline))
542
# As local lock urls are correct we display them.
543
# We avoid displaying remote lock urls.
544
536
lock_url = self.transport.abspath(self.path)
545
if lock_url.startswith('file://'):
546
lock_url = lock_url.split('.bzr/')[0]
549
user, hostname, pid, time_ago = formatted_info
550
msg = ('%s lock %s ' # lock_url
554
'[process #%s], ' # pid
555
'acquired %s.') # time ago
556
msg_args = [start, lock_url, user, hostname, pid, time_ago]
558
msg += ('\nWill continue to try until %s, unless '
560
msg_args.append(deadline_str)
561
msg += '\nSee "bzr help break-lock" for more.'
562
self._report_function(msg, *msg_args)
537
# See <https://bugs.edge.launchpad.net/bzr/+bug/250451>
538
# the URL here is sometimes not one that is useful to the
539
# user, perhaps being wrapped in a lp-%d or chroot decorator,
540
# especially if this error is issued from the server.
541
self._report_function('%s %s\n'
543
'%s\n' # locked ... ago
544
'Will continue to try until %s, unless '
545
'you press Ctrl-C.\n'
546
'See "bzr help break-lock" for more.',
563
554
if (max_attempts is not None) and (attempt_count >= max_attempts):
564
555
self._trace("exceeded %d attempts")
565
556
raise LockContention(self)
567
558
self._trace("waiting %ss", poll)
570
# As timeout is always 0 for remote locks
571
# this block is applicable only for local
573
561
self._trace("timeout after waiting %ss", timeout)
574
raise LockContention('(local)', lock_url)
562
raise LockContention(self)
576
564
def leave_in_place(self):
577
565
self._locked_via_token = True
623
611
def _format_lock_info(self, info):
624
612
"""Turn the contents of peek() into something for the user"""
625
start_time = info.get('start_time')
626
if start_time is None:
627
time_ago = '(unknown)'
629
time_ago = format_delta(time.time() - int(info['start_time']))
630
user = info.get('user', '<unknown>')
631
hostname = info.get('hostname', '<unknown>')
632
pid = info.get('pid', '<unknown>')
613
lock_url = self.transport.abspath(self.path)
614
delta = time.time() - int(info['start_time'])
616
'lock %s' % (lock_url,),
617
'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
618
'locked %s' % (format_delta(delta),),
640
621
def validate_token(self, token):