1
# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
1
# Copyright (C) 2006-2010 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.edge.launchpad.net/bzr/+bug/498378> for one case.
246
# See <https://bugs.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['nonce'] != self.nonce:
255
if info.get('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 rio Stanza,
433
If it is held, this returns the lock info structure as a dict
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:
452
450
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
# TODO: Handle if info_bytes is empty
463
return rio.read_stanza(osutils.split_lines(info_bytes)).as_dict()
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()
465
471
def attempt_lock(self):
466
472
"""Take the lock; fail if it's already held.
533
539
if deadline_str is None:
534
540
deadline_str = time.strftime('%H:%M:%S',
535
541
time.localtime(deadline))
542
# As local lock urls are correct we display them.
543
# We avoid displaying remote lock urls.
536
544
lock_url = self.transport.abspath(self.path)
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.',
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)
554
563
if (max_attempts is not None) and (attempt_count >= max_attempts):
555
564
self._trace("exceeded %d attempts")
556
565
raise LockContention(self)
558
567
self._trace("waiting %ss", poll)
570
# As timeout is always 0 for remote locks
571
# this block is applicable only for local
561
573
self._trace("timeout after waiting %ss", timeout)
562
raise LockContention(self)
574
raise LockContention('(local)', lock_url)
564
576
def leave_in_place(self):
565
577
self._locked_via_token = True
611
623
def _format_lock_info(self, info):
612
624
"""Turn the contents of peek() into something for the user"""
613
lock_url = self.transport.abspath(self.path)
614
delta = time.time() - int(info['start_time'])
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>')
616
'lock %s' % (lock_url,),
617
'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
618
'locked %s' % (format_delta(delta),),
621
640
def validate_token(self, token):