Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
 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())
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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:
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
 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)
Ejemplo n.º 8
0
 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()
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
 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)
Ejemplo n.º 14
0
 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)
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
0
 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)
Ejemplo n.º 17
0
 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))
Ejemplo n.º 18
0
    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()
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
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()
Ejemplo n.º 21
0
    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))
Ejemplo n.º 22
0
 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
Ejemplo n.º 23
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
Ejemplo n.º 24
0
 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()
Ejemplo n.º 25
0
    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()
Ejemplo n.º 26
0
    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)
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
 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)
Ejemplo n.º 30
0
    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