def _convert_items(items, format, clean_up, dry_run, label=None): """Convert a sequence of control directories to the given format. :param items: the control directories to upgrade :param format: the format to convert to or None for the best default :param clean-up: if True, the backup.bzr directory is removed if the upgrade succeeded for a given repo/branch/tree :param dry_run: show what would happen but don't actually do any upgrades :param label: the label for these items or None to calculate one :return: items successfully upgraded, exceptions """ succeeded = [] exceptions = [] child_pb = ui.ui_factory.nested_progress_bar() child_pb.update(gettext('Upgrading bzrdirs'), 0, len(items)) for i, control_dir in enumerate(items): # Do the conversion location = control_dir.root_transport.base bzr_object, bzr_label = _get_object_and_label(control_dir) type_label = label or bzr_label child_pb.update(gettext("Upgrading %s") % (type_label), i+1, len(items)) ui.ui_factory.note(gettext('Upgrading {0} {1} ...').format(type_label, urlutils.unescape_for_display(location, 'utf-8'),)) try: if not dry_run: cv = Convert(control_dir=control_dir, format=format) except errors.UpToDateFormat, ex: ui.ui_factory.note(str(ex)) succeeded.append(control_dir) continue except Exception, ex: trace.warning('conversion error: %s' % ex) exceptions.append(ex) continue
def serve(self, thread_name_suffix=''): self._should_terminate = False # for hooks we are letting code know that a server has started (and # later stopped). # There are three interesting urls: # The URL the server can be contacted on. (e.g. bzr://host/) # The URL that a commit done on the same machine as the server will # have within the servers space. (e.g. file:///home/user/source) # The URL that will be given to other hooks in the same process - # the URL of the backing transport itself. (e.g. chroot+:///) # We need all three because: # * other machines see the first # * local commits on this machine should be able to be mapped to # this server # * commits the server does itself need to be mapped across to this # server. # The latter two urls are different aliases to the servers url, # so we group those in a list - as there might be more aliases # in the future. backing_urls = [self.backing_transport.base] try: backing_urls.append(self.backing_transport.external_url()) except errors.InProcessTransport: pass for hook in SmartTCPServer.hooks['server_started']: hook(backing_urls, self.get_url()) self._started.set() try: try: while not self._should_terminate: try: conn, client_addr = self._server_socket.accept() except self._socket_timeout: # just check if we're asked to stop pass except self._socket_error, e: # if the socket is closed by stop_background_thread # we might get a EBADF here, any other socket errors # should get logged. if e.args[0] != errno.EBADF: trace.warning("listening socket error: %s", e) else: self.serve_conn(conn, thread_name_suffix) except KeyboardInterrupt: # dont log when CTRL-C'd. raise except Exception, e: trace.error("Unhandled smart server error.") trace.log_exception_quietly() raise finally: self._stopped.set() try: # ensure the server socket is closed. self._server_socket.close() except self._socket_error: # ignore errors on close pass for hook in SmartTCPServer.hooks['server_stopped']: hook(backing_urls, self.get_url())
def _try_append(self, relpath, text, mode=None, retries=0): """Try repeatedly to append the given text to the file at relpath. This is a recursive function. On errors, it will be called until the number of retries is exceeded. """ try: abspath = self._remote_path(relpath) mutter("FTP appe (try %d) to %s", retries, abspath) ftp = self._get_FTP() cmd = "APPE %s" % abspath conn = ftp.transfercmd(cmd) conn.sendall(text) conn.close() self._setmode(relpath, mode) ftp.getresp() except ftplib.error_perm, e: # Check whether the command is not supported (reply code 502) if str(e).startswith('502 '): warning("FTP server does not support file appending natively. " "Performance may be severely degraded! (%s)", e) self._has_append = False self._fallback_append(relpath, text, mode) else: self._translate_ftp_error(e, abspath, extra='error appending', unknown_exc=errors.NoSuchFile)
def _call_and_read_response(self, method, args, body=None, readv_body=None, expect_response_body=True): if self._medium._protocol_version is not None: response_handler = self._send_request( self._medium._protocol_version, method, args, body=body, readv_body=readv_body) return (response_handler.read_response_tuple( expect_body=expect_response_body), response_handler) else: for protocol_version in [3, 2]: if protocol_version == 2: # If v3 doesn't work, the remote side is older than 1.6. self._medium._remember_remote_is_before((1, 6)) response_handler = self._send_request( protocol_version, method, args, body=body, readv_body=readv_body) try: response_tuple = response_handler.read_response_tuple( expect_body=expect_response_body) except errors.UnexpectedProtocolVersionMarker, err: # TODO: We could recover from this without disconnecting if # we recognise the protocol version. warning( 'Server does not understand Bazaar network protocol %d,' ' reconnecting. (Upgrade the server to avoid this.)' % (protocol_version,)) self._medium.disconnect() continue except errors.ErrorFromSmartServer: # If we received an error reply from the server, then it # must be ok with this protocol version. self._medium._protocol_version = protocol_version raise else:
def _mkdir(self, abspath, mode=None): if mode is None: local_mode = 0777 else: local_mode = mode try: self._report_activity(len(abspath), 'write') self._get_sftp().mkdir(abspath, local_mode) self._report_activity(1, 'read') if mode is not None: # chmod a dir through sftp will erase any sgid bit set # on the server side. So, if the bit mode are already # set, avoid the chmod. If the mode is not fine but # the sgid bit is set, report a warning to the user # with the umask fix. stat = self._get_sftp().lstat(abspath) mode = mode & 0777 # can't set special bits anyway if mode != stat.st_mode & 0777: if stat.st_mode & 06000: warning('About to chmod %s over sftp, which will result' ' in its suid or sgid bits being cleared. If' ' you want to preserve those bits, change your ' ' environment on the server to use umask 0%03o.' % (abspath, 0777 - mode)) self._get_sftp().chmod(abspath, mode=mode) except (paramiko.SSHException, IOError), e: self._translate_io_exception(e, abspath, ': unable to mkdir', failure_exc=FileExists)
def _call_determining_protocol_version(self): """Determine what protocol the remote server supports. We do this by placing a request in the most recent protocol, and handling the UnexpectedProtocolVersionMarker from the server. """ for protocol_version in [3, 2]: if protocol_version == 2: # If v3 doesn't work, the remote side is older than 1.6. self.client._medium._remember_remote_is_before((1, 6)) try: response_tuple, response_handler = self._call(protocol_version) except errors.UnexpectedProtocolVersionMarker, err: # TODO: We could recover from this without disconnecting if # we recognise the protocol version. trace.warning( 'Server does not understand Bazaar network protocol %d,' ' reconnecting. (Upgrade the server to avoid this.)' % (protocol_version,)) self.client._medium.disconnect() continue except errors.ErrorFromSmartServer: # If we received an error reply from the server, then it # must be ok with this protocol version. self.client._medium._protocol_version = protocol_version raise
def cleanup(path): # Warn in case the file couldn't be deleted (in case windows still # holds the file open, but not if the files have already been # deleted) try: os.remove(path) except OSError, e: if e.errno not in (errno.ENOENT,): warning('Failed to delete temporary file: %s %s', path, e)
def serve(self, thread_name_suffix=''): # Note: There is a temptation to do # signals.register_on_hangup(id(self), self._stop_gracefully) # However, that creates a temporary object which is a bound # method. signals._on_sighup is a WeakKeyDictionary so it # immediately gets garbage collected, because nothing else # references it. Instead, we need to keep a real reference to the # bound method for the lifetime of the serve() function. stop_gracefully = self._stop_gracefully signals.register_on_hangup(id(self), stop_gracefully) self._should_terminate = False # for hooks we are letting code know that a server has started (and # later stopped). self.run_server_started_hooks() self._started.set() try: try: while not self._should_terminate: try: conn, client_addr = self._server_socket.accept() except self._socket_timeout: # just check if we're asked to stop pass except self._socket_error, e: # if the socket is closed by stop_background_thread # we might get a EBADF here, or if we get a signal we # can get EINTR, any other socket errors should get # logged. if e.args[0] not in (errno.EBADF, errno.EINTR): trace.warning(gettext("listening socket error: %s") % (e,)) else: if self._should_terminate: conn.close() break self.serve_conn(conn, thread_name_suffix) # Cleanout any threads that have finished processing. self._poll_active_connections() except KeyboardInterrupt: # dont log when CTRL-C'd. raise except Exception, e: trace.report_exception(sys.exc_info(), sys.stderr) raise finally: try: # ensure the server socket is closed. self._server_socket.close() except self._socket_error: # ignore errors on close pass self._stopped.set() signals.unregister_on_hangup(id(self)) self.run_server_stopped_hooks() if self._gracefully_stopping: self._wait_for_clients_to_disconnect() self._fully_stopped.set()
def _validate_references_from_repository(self, repository): """Now that we have a repository which should have some of the revisions we care about, go through and validate all of them that we can. """ rev_to_sha = {} inv_to_sha = {} def add_sha(d, revision_id, sha1): if revision_id is None: if sha1 is not None: raise BzrError('A Null revision should always' 'have a null sha1 hash') return if revision_id in d: # This really should have been validated as part # of _validate_revisions but lets do it again if sha1 != d[revision_id]: raise BzrError('** Revision %r referenced with 2 different' ' sha hashes %s != %s' % (revision_id, sha1, d[revision_id])) else: d[revision_id] = sha1 # All of the contained revisions were checked # in _validate_revisions checked = {} for rev_info in self.revisions: checked[rev_info.revision_id] = True add_sha(rev_to_sha, rev_info.revision_id, rev_info.sha1) for (rev, rev_info) in zip(self.real_revisions, self.revisions): add_sha(inv_to_sha, rev_info.revision_id, rev_info.inventory_sha1) count = 0 missing = {} for revision_id, sha1 in rev_to_sha.iteritems(): if repository.has_revision(revision_id): testament = StrictTestament.from_revision(repository, revision_id) local_sha1 = self._testament_sha1_from_revision(repository, revision_id) if sha1 != local_sha1: raise BzrError('sha1 mismatch. For revision id {%s}' 'local: %s, bundle: %s' % (revision_id, local_sha1, sha1)) else: count += 1 elif revision_id not in checked: missing[revision_id] = sha1 if len(missing) > 0: # I don't know if this is an error yet warning('Not all revision hashes could be validated.' ' Unable validate %d hashes' % len(missing)) mutter('Verified %d sha hashes for the bundle.' % count) self._validated_revisions_against_repo = True
def put_file(self, relpath, fp, mode=None, retries=0): """Copy the file-like or string object into the location. :param relpath: Location to put the contents, relative to base. :param fp: File-like or string object. :param retries: Number of retries after temporary failures so far for this operation. TODO: jam 20051215 ftp as a protocol seems to support chmod, but ftplib does not """ abspath = self._remote_path(relpath) tmp_abspath = '%s.tmp.%.9f.%d.%d' % (abspath, time.time(), os.getpid(), random.randint(0,0x7FFFFFFF)) bytes = None if getattr(fp, 'read', None) is None: # hand in a string IO bytes = fp fp = StringIO(bytes) else: # capture the byte count; .read() may be read only so # decorate it. class byte_counter(object): def __init__(self, fp): self.fp = fp self.counted_bytes = 0 def read(self, count): result = self.fp.read(count) self.counted_bytes += len(result) return result fp = byte_counter(fp) try: mutter("FTP put: %s", abspath) f = self._get_FTP() try: f.storbinary('STOR '+tmp_abspath, fp) self._rename_and_overwrite(tmp_abspath, abspath, f) self._setmode(relpath, mode) if bytes is not None: return len(bytes) else: return fp.counted_bytes except (ftplib.error_temp, EOFError), e: warning("Failure during ftp PUT of %s: %s. Deleting temporary file." % (tmp_abspath, e, )) try: f.delete(tmp_abspath) except: warning("Failed to delete temporary file on the" " server.\nFile: %s", tmp_abspath) raise e raise except ftplib.error_perm, e: self._translate_ftp_error(e, abspath, extra='could not store', unknown_exc=errors.NoSuchFile)
def _trailing_backslashes_regex(m): """Check trailing backslashes. Does a head count on trailing backslashes to ensure there isn't an odd one on the end that would escape the brackets we wrap the RE in. """ if (len(m) % 2) != 0: warning(u"Regular expressions cannot end with an odd number of '\\'. " "Dropping the final '\\'.") return m[:-1] return m
def load_from_dir(d): """Load the plugins in directory d.""" # Get the list of valid python suffixes for __init__.py? # this includes .py, .pyc, and .pyo (depending on if we are running -O) # but it doesn't include compiled modules (.so, .dll, etc) valid_suffixes = [suffix for suffix, mod_type, flags in imp.get_suffixes() if flags in (imp.PY_SOURCE, imp.PY_COMPILED)] package_entries = ['__init__'+suffix for suffix in valid_suffixes] plugin_names = set() for f in os.listdir(d): path = osutils.pathjoin(d, f) if os.path.isdir(path): for entry in package_entries: # This directory should be a package, and thus added to # the list if os.path.isfile(osutils.pathjoin(path, entry)): break else: # This directory is not a package continue else: for suffix_info in imp.get_suffixes(): if f.endswith(suffix_info[0]): f = f[:-len(suffix_info[0])] if suffix_info[2] == imp.C_EXTENSION and f.endswith('module'): f = f[:-len('module')] break else: continue if getattr(_mod_plugins, f, None): mutter('Plugin name %s already loaded', f) else: # mutter('add plugin name %s', f) plugin_names.add(f) for name in plugin_names: try: exec "import bzrlib.plugins.%s" % name in {} except KeyboardInterrupt: raise except Exception, e: ## import pdb; pdb.set_trace() if re.search('\.|-| ', name): sanitised_name = re.sub('[-. ]', '_', name) if sanitised_name.startswith('bzr_'): sanitised_name = sanitised_name[len('bzr_'):] warning("Unable to load %r in %r as a plugin because the " "file path isn't a valid module name; try renaming " "it to %r." % (name, d, sanitised_name)) else: warning('Unable to load plugin %r from %r' % (name, d)) log_exception_quietly() if 'error' in debug.debug_flags: trace.print_exception(sys.exc_info(), sys.stderr)
def get_tag_dict(self): self.branch.lock_read() try: try: tag_content = self.branch._transport.get_bytes('tags') except errors.NoSuchFile, e: # ugly, but only abentley should see this :) trace.warning('No branch/tags file in %s. ' 'This branch was probably created by bzr 0.15pre. ' 'Create an empty file to silence this message.' % (self.branch, )) return {} return self._deserialize_tag_dict(tag_content)
def _shutdown_children(self): self._wait_for_children(self.WAIT_FOR_CHILDREN_TIMEOUT) if self._child_processes: trace.warning("Children still running: %s" % ", ".join(map(str, self._child_processes))) for c_id in self._child_processes: trace.warning("sending SIGINT to %d" % (c_id,)) os.kill(c_id, signal.SIGINT) # We sent the SIGINT signal, see if they exited self._wait_for_children(self.SLEEP_FOR_CHILDREN_TIMEOUT) if self._child_processes: # No? Then maybe something more powerful for c_id in self._child_processes: trace.warning("sending SIGKILL to %d" % (c_id,)) os.kill(c_id, signal.SIGKILL) # We sent the SIGKILL signal, see if they exited self._wait_for_children(self.SLEEP_FOR_CHILDREN_TIMEOUT) if self._child_processes: for c_id, (c_path, sock) in self._child_processes.iteritems(): # TODO: We should probably put something into this message? # However, the likelyhood is very small that this isn't # already closed because of SIGKILL + _wait_for_children # And I don't really know what to say... sock.close() if os.path.exists(c_path): trace.warning("Cleaning up after immortal child %d: %s\n" % (c_id, c_path)) shutil.rmtree(c_path)
def _resolve(self, url, _request_factory=ResolveLaunchpadPathRequest, _lp_login=None): """Resolve the base URL for this transport.""" url, path = self._update_url_scheme(url) if _lp_login is None: _lp_login = get_lp_login() path = path.strip('/') path = self._expand_user(path, url, _lp_login) if _lp_login is not None: result = self._resolve_locally(path, url, _request_factory) if 'launchpad' in debug.debug_flags: local_res = result result = self._resolve_via_xmlrpc(path, url, _request_factory) trace.note(gettext( 'resolution for {0}\n local: {1}\n remote: {2}').format( url, local_res['urls'], result['urls'])) else: result = self._resolve_via_xmlrpc(path, url, _request_factory) if 'launchpad' in debug.debug_flags: trace.mutter("resolve_lp_path(%r) == %r", url, result) _warned_login = False for url in result['urls']: scheme, netloc, path, query, fragment = urlsplit(url) if self._requires_launchpad_login(scheme, netloc, path, query, fragment): # Only accept launchpad.net bzr+ssh URLs if we know # the user's Launchpad login: if _lp_login is not None: break if _lp_login is None: if not _warned_login: trace.warning( 'You have not informed bzr of your Launchpad ID, and you must do this to\n' 'write to Launchpad or access private data. See "bzr help launchpad-login".') _warned_login = True else: # Use the URL if we can create a transport for it. try: transport.get_transport(url) except (errors.PathError, errors.TransportError): pass else: break else: raise errors.InvalidURL(path=url, extra='no supported schemes') return url
def test_fromBranchMergeProposal_does_not_warn_on_conflicts(self): """PreviewDiff generation emits no conflict warnings.""" reload(trace) bmp, source_rev_id, target_rev_id = self.createExampleMerge() handler = RecordLister() logger = logging.getLogger('bzr') logger.addHandler(handler) try: PreviewDiff.fromBranchMergeProposal(bmp) self.assertEqual(handler.records, []) # check that our handler would normally intercept warnings. trace.warning('foo!') self.assertNotEqual(handler.records, []) finally: logger.removeHandler(handler)
def _validate_inventory(self, inv, revision_id): """At this point we should have generated the BundleTree, so build up an inventory, and make sure the hashes match. """ # Now we should have a complete inventory entry. s = serializer_v5.write_inventory_to_string(inv) sha1 = sha_string(s) # Target revision is the last entry in the real_revisions list rev = self.get_revision(revision_id) if rev.revision_id != revision_id: raise AssertionError() if sha1 != rev.inventory_sha1: open(',,bogus-inv', 'wb').write(s) warning('Inventory sha hash mismatch for revision %s. %s' ' != %s' % (revision_id, sha1, rev.inventory_sha1))
def run(self, directory=None): from dulwich.server import TCPGitServer from bzrlib.plugins.git.server import BzrBackend from bzrlib.trace import warning import os warning("server support in bzr-git is experimental.") if directory is None: directory = os.getcwd() backend = BzrBackend(directory) server = TCPGitServer(backend, 'localhost') server.serve_forever()
def get_client(): global _client_checked, _client if _client_checked: return _client _client_checked = True try: from zeitgeist.client import ZeitgeistClient except ImportError: _client = None return _client import dbus try: _client = ZeitgeistClient() except dbus.DBusException, e: trace.warning("zeitgeist: %s. No events will be sent." % e.message) _client = None
def export_marks(filename, revision_ids): """Save marks to a file. :param filename: filename to save data to :param revision_ids: dictionary mapping marks -> bzr revision-ids """ try: f = file(filename, 'w') except IOError: warning("Could not open export-marks file %s - not exporting marks", filename) return # Write the revision info for mark, revid in revision_ids.iteritems(): f.write(':%s %s\n' % (str(mark).lstrip(':'), revid)) f.close()
def _setmode(self, relpath, mode): """Set permissions on a path. Only set permissions if the FTP server supports the 'SITE CHMOD' extension. """ if mode: try: mutter("FTP site chmod: setting permissions to %s on %s", oct(mode), self._remote_path(relpath)) ftp = self._get_FTP() cmd = "SITE CHMOD %s %s" % (oct(mode), self._remote_path(relpath)) ftp.sendcmd(cmd) except ftplib.error_perm, e: # Command probably not available on this server warning("FTP Could not set permissions to %s on %s. %s", oct(mode), self._remote_path(relpath), str(e))
def read_config_from_repository(self): rev_tree = self.branch.repository.revision_tree(self.revid) if self.use_snapshot: file_id = rev_tree.path2id(SNAPSHOT_PATH) if not file_id: file_id = rev_tree.path2id(CONFIG_PATH) if file_id: warning('warning: for this revision there is no snapshot of external branches!') else: file_id = rev_tree.path2id(CONFIG_PATH) if not file_id: # there is no config or snapshot files in repository return False rev_tree.lock_read() try: text = rev_tree.get_file_text(file_id) self._set_config(text) finally: rev_tree.unlock() return len(self.config) > 0
def capture_tree_contents(top): """Make a Python datastructure description of a tree. If top is an absolute path the descriptions will be absolute.""" for dirpath, dirnames, filenames in os.walk(top): yield (dirpath + '/', ) filenames.sort() for fn in filenames: fullpath = pathjoin(dirpath, fn) if (fullpath[-1] in '@/'): raise AssertionError(fullpath) info = os.lstat(fullpath) if stat.S_ISLNK(info.st_mode): yield (fullpath + '@', os.readlink(fullpath)) elif stat.S_ISREG(info.st_mode): yield (fullpath, file(fullpath, 'rb').read()) else: warning("can't capture file %s with mode %#o", fullpath, info.st_mode) pass
def _do_loop(self): while not self._should_terminate.isSet(): try: conn, client_addr = self._server_socket.accept() except self._socket_timeout: pass # Run shutdown and children checks. except self._socket_error as e: if e.args[0] == errno.EINTR: pass # Run shutdown and children checks. elif e.args[0] != errno.EBADF: # We can get EBADF here while we are shutting down # So we just ignore it for now pass else: # Log any other failure mode trace.warning("listening socket error: %s", e) else: self.log(client_addr, "connected") # TODO: We should probably trap exceptions coming out of # this and log them, so that we don't kill the service # because of an unhandled error. # Note: settimeout is used so that a malformed request # doesn't cause us to hang forever. Also note that the # particular implementation means that a malicious # client could probably send us one byte every once in a # while, and we would just keep trying to read it. # However, as a local service, we aren't worrying about # it. conn.settimeout(self.WAIT_FOR_REQUEST_TIMEOUT) try: self.serve_one_connection(conn, client_addr) except self._socket_timeout as e: trace.log_exception_quietly() self.log(client_addr, "request timeout failure: %s" % (e,)) conn.sendall("FAILURE\nrequest timed out\n") conn.close() except Exception as e: trace.log_exception_quietly() self.log(client_addr, "trapped a failure while handling" " connection: %s" % (e,)) self._poll_children()
def _poll_children(self): """See if children are still running, etc. One interesting hook here would be to track memory consumption, etc. """ while self._child_processes: try: c_id, exit_code, rusage = os.wait3(os.WNOHANG) except OSError as e: if e.errno == errno.ECHILD: # TODO: We handle this right now because the test suite # fakes a child, since we wanted to test some code # without actually forking anything trace.mutter( "_poll_children() called, and" " self._child_processes indicates there are" " children, but os.wait3() says there are not." " current_children: %s" % (self._child_processes,) ) return if c_id == 0: # No more children stopped right now return c_path, sock = self._child_processes.pop(c_id) trace.mutter("%s exited %s and usage: %s" % (c_id, exit_code, rusage)) # Cleanup the child path, before mentioning it exited to the # caller. This avoids a race condition in the test suite. if os.path.exists(c_path): # The child failed to cleanup after itself, do the work here trace.warning("Had to clean up after child %d: %s\n" % (c_id, c_path)) shutil.rmtree(c_path, ignore_errors=True) # See [Decision #4] try: sock.sendall("exited\n%s\n" % (exit_code,)) except (self._socket_timeout, self._socket_error) as e: # The client disconnected before we wanted them to, # no big deal trace.mutter("%s's socket already closed: %s" % (c_id, e)) else: sock.close()
def _call(self, protocol_version): """We know the protocol version. So this just sends the request, and then reads the response. This is where the code will be to retry requests if the connection is closed. """ response_handler = self._send(protocol_version) try: response_tuple = response_handler.read_response_tuple( expect_body=self.expect_response_body) except errors.ConnectionReset, e: self.client._medium.reset() if not self._is_safe_to_send_twice(): raise trace.warning('ConnectionReset reading response for %r, retrying' % (self.method,)) trace.log_exception_quietly() encoder, response_handler = self._construct_protocol( protocol_version) self._send_no_retry(encoder) response_tuple = response_handler.read_response_tuple( expect_body=self.expect_response_body)
def run(self, num=10): try: num = int(num) except (ValueError, TypeError): num = 10 warning('bzr lastlog only accepts numbers, defaulting to %d.' % num) dir, relpath = bzrdir.BzrDir.open_containing('.') b = dir.open_branch() num_revisions = len(b.revision_history()) if num_revisions == 0: error('Sorry, no revisions available.') return first_revision = num_revisions - num + 1 last_revision = num_revisions if first_revision < 1: first_revision = 1 outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace') lf = log_formatter('short', show_ids=False, to_file=outf, show_timezone='original') show_log(b, lf, None, verbose=False, direction='forward', start_revision=first_revision, end_revision=last_revision, search=None)
def import_marks(filename): """Read the mapping of marks to revision-ids from a file. :param filename: the file to read from :return: None if an error is encountered or a dictionary with marks as keys and revision-ids as values """ # Check that the file is readable and in the right format try: f = file(filename) except IOError: warning("Could not import marks file %s - not importing marks", filename) return None # Read the revision info revision_ids = {} line = f.readline() if line == 'format=1\n': # Cope with old-style marks files # Read the branch info branch_names = {} for string in f.readline().rstrip('\n').split('\0'): if not string: continue name, integer = string.rsplit('.', 1) branch_names[name] = int(integer) line = f.readline() while line: line = line.rstrip('\n') mark, revid = line.split(' ', 1) mark = mark.lstrip(':') revision_ids[mark] = revid line = f.readline() f.close() return revision_ids
def run(self): while True: readable, writable_unused, exception_unused = \ select.select([self._socket], [], [], 0.1) if self._stop_event.isSet(): return if len(readable) == 0: continue try: s, addr_unused = self._socket.accept() # because the loopback socket is inline, and transports are # never explicitly closed, best to launch a new thread. threading.Thread(target=self._callback, args=(s,)).start() except socket.error, x: sys.excepthook(*sys.exc_info()) warning('Socket error during accept() within unit test server' ' thread: %r' % x) except Exception, x: # probably a failed test; unit test thread will log the # failure/error sys.excepthook(*sys.exc_info()) warning('Exception from within unit test server thread: %r' % x)
def _open_handles(self, base_path): """Open the given file handles. This will attempt to open all of these file handles, but will not block while opening them, timing out after self._child_connect_timeout seconds. :param base_path: The directory where all FIFOs are located. :return: (stdin_fid, stdout_fid, stderr_fid). """ stdin_path, stdout_path, stderr_path = self._compute_paths(base_path) # These open calls will block until another process connects (which # must connect in the same order) fids = [] to_open = [(stdin_path, os.O_RDONLY), (stdout_path, os.O_WRONLY), (stderr_path, os.O_WRONLY)] # If we set it to 0, we won't get an alarm, so require some time > 0. signal.alarm(max(1, self._child_connect_timeout)) tstart = time.time() for path, flags in to_open: try: fids.append(os.open(path, flags)) except OSError: # In production code, signal.alarm will generally just kill # us. But if something installs a signal handler for SIGALRM, # do what we can to die gracefully. error = "After %.3fs we failed to open %s, exiting" % (time.time() - tstart, path) trace.warning(error) for fid in fids: try: os.close(fid) except OSError: pass raise errors.BzrError(error) # If we get to here, that means all the handles were opened # successfully, so cancel the wakeup call. signal.alarm(0) return fids