コード例 #1
0
    def main(self):
        """See `LaunchpadScript`."""
        self.validateOptions()
        self.logOptions()

        for distribution in self.findDistros():
            allowed_suites = self.findAllowedSuites(distribution)
            for archive in self.getTargetArchives(distribution):
                set_request_started(
                    request_statements=LimitedList(10000),
                    txn=self.txn, enable_timeout=False)
                try:
                    if archive.status == ArchiveStatus.DELETING:
                        publisher = self.getPublisher(
                            distribution, archive, allowed_suites)
                        work_done = self.deleteArchive(archive, publisher)
                    elif archive.can_be_published:
                        publisher = self.getPublisher(
                            distribution, archive, allowed_suites)
                        self.publishArchive(archive, publisher)
                        work_done = True
                    else:
                        work_done = False
                finally:
                    clear_request_started()

                if work_done:
                    self.txn.commit()

        self.logger.debug("Ciao")
コード例 #2
0
    def processDeathRow(self, archive):
        """Process death-row for the given archive.

        It handles the current DB transaction according to the results of
        the operation just executed, i.e, commits successful runs and aborts
        runs with errors. It also respects 'dry-run' command-line option.
        """
        death_row = getDeathRow(archive, self.logger, self.options.pool_root)
        self.logger.debug("Unpublishing death row for %s." %
                          archive.displayname)
        set_request_started(request_statements=LimitedList(10000),
                            txn=self.txn,
                            enable_timeout=False)
        try:
            death_row.reap(self.options.dry_run)
        except Exception:
            self.logger.exception(
                "Unexpected exception while doing death-row unpublish")
            self.txn.abort()
        else:
            if self.options.dry_run:
                self.logger.info("Dry run mode; rolling back.")
                self.txn.abort()
            else:
                self.logger.debug("Committing")
                self.txn.commit()
        finally:
            clear_request_started()
コード例 #3
0
    def test_store_disconnected_after_request_handled_logs_oops(self):
        # Bug #504291 was that a Store was being left in a disconnected
        # state after a request, causing subsequent requests handled by that
        # thread to fail. We detect this state in endRequest and log an
        # OOPS to help track down the trigger.
        request = LaunchpadTestRequest()
        publication = WebServicePublication(None)
        dbadapter.set_request_started()

        # Disconnect a store
        store = IMasterStore(EmailAddress)
        store._connection._state = STATE_DISCONNECTED

        # Invoke the endRequest hook.
        publication.endRequest(request, None)

        self.assertEqual(1, len(self.oopses))
        oops = self.oopses[0]

        # Ensure the OOPS mentions the correct exception
        self.assertStartsWith(oops['value'], "Bug #504291")

        # Ensure the store has been rolled back and in a usable state.
        self.assertEqual(store._connection._state, STATE_RECONNECT)
        store.find(EmailAddress).first()  # Confirms Store is working.
コード例 #4
0
    def test_store_disconnected_after_request_handled_logs_oops(self):
        # Bug #504291 was that a Store was being left in a disconnected
        # state after a request, causing subsequent requests handled by that
        # thread to fail. We detect this state in endRequest and log an
        # OOPS to help track down the trigger.
        request = LaunchpadTestRequest()
        publication = WebServicePublication(None)
        dbadapter.set_request_started()

        # Disconnect a store
        store = IMasterStore(EmailAddress)
        store._connection._state = STATE_DISCONNECTED

        # Invoke the endRequest hook.
        publication.endRequest(request, None)

        self.assertEqual(1, len(self.oopses))
        oops = self.oopses[0]

        # Ensure the OOPS mentions the correct exception
        self.assertStartsWith(oops['value'], "Bug #504291")

        # Ensure the store has been rolled back and in a usable state.
        self.assertEqual(store._connection._state, STATE_RECONNECT)
        store.find(EmailAddress).first()  # Confirms Store is working.
コード例 #5
0
    def processForDistro(self, distribution):
        """Process all queue items for a distribution.

        Commits between items.

        :param distribution: The `Distribution` to process queue items for.
        :return: A list of all successfully processed items' ids.
        """
        processed_queue_ids = []
        for archive in self.getTargetArchives(distribution):
            set_request_started(request_statements=LimitedList(10000),
                                txn=self.txn,
                                enable_timeout=False)
            try:
                for distroseries in distribution.series:

                    self.logger.debug("Processing queue for %s %s" %
                                      (archive.reference, distroseries.name))

                    queue_items = distroseries.getPackageUploads(
                        status=PackageUploadStatus.ACCEPTED, archive=archive)
                    for queue_item in queue_items:
                        if self.processQueueItem(queue_item):
                            processed_queue_ids.append(queue_item.id)
                        # Commit even on error; we may have altered the
                        # on-disk archive, so the partial state must
                        # make it to the DB.
                        self.txn.commit()
                        close_bugs_for_queue_item(queue_item)
                        self.txn.commit()
            finally:
                clear_request_started()
        return processed_queue_ids
コード例 #6
0
 def test_reduced_timeout(self):
     """reduced_timeout caps the available timeout in various ways."""
     self.addCleanup(set_default_timeout_function, None)
     with reduced_timeout(1.0):
         self.assertIsNone(get_default_timeout_function()())
     with reduced_timeout(1.0, default=5.0):
         self.assertEqual(5.0, get_default_timeout_function()())
     set_default_timeout_function(lambda: 5.0)
     with reduced_timeout(1.0):
         self.assertEqual(4.0, get_default_timeout_function()())
     with reduced_timeout(1.0, default=5.0, webapp_max=2.0):
         self.assertEqual(4.0, get_default_timeout_function()())
     with reduced_timeout(1.0, default=5.0, webapp_max=6.0):
         self.assertEqual(4.0, get_default_timeout_function()())
     with reduced_timeout(6.0, default=5.0, webapp_max=2.0):
         self.assertEqual(5.0, get_default_timeout_function()())
     LaunchpadTestRequest()
     set_request_started()
     try:
         with reduced_timeout(1.0):
             self.assertEqual(4.0, get_default_timeout_function()())
         with reduced_timeout(1.0, default=5.0, webapp_max=2.0):
             self.assertEqual(2.0, get_default_timeout_function()())
         with reduced_timeout(1.0, default=5.0, webapp_max=6.0):
             self.assertEqual(4.0, get_default_timeout_function()())
         with reduced_timeout(6.0, default=5.0, webapp_max=2.0):
             self.assertEqual(2.0, get_default_timeout_function()())
     finally:
         clear_request_started()
コード例 #7
0
ファイル: rewrite.py プロジェクト: pombreda/UnnaturalCodeFork
    def rewriteLine(self, resource_location):
        """Rewrite 'resource_location' to a more concrete location.

        We use the 'translatePath' BranchFileSystemClient method.  There are
        three cases:

         (1) The request is for something within the .bzr directory of a
             branch.

             In this case we rewrite the request to the location from which
             branches are served by ID.

         (2) The request is for something within a branch, but not the .bzr
             directory.

             In this case, we hand the request off to codebrowse.

         (3) The branch is not found.  Two sub-cases: the request is for a
             product control directory or the we don't know how to translate
             the path.

             In both these cases we return 'NULL' which indicates to Apache
             that we don't know how to rewrite the request (and so it should
             go on to generate a 404 response).

        Other errors are allowed to propagate, on the assumption that the
        caller will catch and log them.
        """
        # Codebrowse generates references to its images and stylesheets
        # starting with "/static", so pass them on unthinkingly.
        T = time.time()
        # Tell the webapp adapter that we are in a request, so that DB
        # statement timeouts will be applied.
        set_request_started()
        try:
            cached = None
            if resource_location.startswith('/static/'):
                r = self._codebrowse_url(resource_location)
                cached = 'N/A'
            else:
                branch_id, trailing, cached = self._getBranchIdAndTrailingPath(
                    resource_location)
                if branch_id is None:
                    if resource_location.startswith('/' +
                                                    BRANCH_ID_ALIAS_PREFIX):
                        r = 'NULL'
                    else:
                        r = self._codebrowse_url(resource_location)
                else:
                    if trailing.startswith('/.bzr'):
                        r = urlutils.join(
                            config.codehosting.internal_branch_by_id_root,
                            branch_id_to_path(branch_id), trailing[1:])
                    else:
                        r = self._codebrowse_url(resource_location)
        finally:
            clear_request_started()
        self.logger.info("%r -> %r (%fs, cache: %s)", resource_location, r,
                         time.time() - T, cached)
        return r
コード例 #8
0
ファイル: runner.py プロジェクト: pombredanne/launchpad-3
 def runJobHandleError(self, job, fallback=None):
     set_request_started(enable_timeout=False,
                         detail_filter=job.timeline_detail_filter)
     try:
         return super(BaseJobRunner,
                      self).runJobHandleError(job, fallback=fallback)
     finally:
         clear_request_started()
コード例 #9
0
    def test_disconnect_logs_oops(self):
        # Ensure that OOPS reports are generated for database
        # disconnections, as per Bug #373837.
        request = LaunchpadTestRequest()
        publication = WebServicePublication(None)
        dbadapter.set_request_started()
        try:
            raise DisconnectionError('Fake')
        except DisconnectionError:
            self.assertRaises(Retry, publication.handleException, None,
                              request, sys.exc_info(), True)
        dbadapter.clear_request_started()
        self.assertEqual(1, len(self.oopses))
        oops = self.oopses[0]

        # Ensure the OOPS mentions the correct exception
        self.assertEqual(oops['type'], "DisconnectionError")
コード例 #10
0
 def endRequest(self, path='/', exception=None, pageid=None, work=None):
     start_event = self._get_start_event(path)
     da.set_request_started()
     profile.start_request(start_event)
     request = start_event.request
     if pageid is not None:
         request.setInWSGIEnvironment('launchpad.pageid', pageid)
     if work is not None:
         work()
     request.response.setResult(EXAMPLE_HTML)
     context = object()
     event = EndRequestEvent(context, request)
     if exception is not None:
         self.eru.raising((type(exception), exception, None), event.request)
     profile.end_request(event)
     da.clear_request_started()
     return event.request
コード例 #11
0
ファイル: tests.py プロジェクト: pombreda/UnnaturalCodeFork
 def endRequest(self, path='/', exception=None, pageid=None, work=None):
     start_event = self._get_start_event(path)
     da.set_request_started()
     profile.start_request(start_event)
     request = start_event.request
     if pageid is not None:
         request.setInWSGIEnvironment('launchpad.pageid', pageid)
     if work is not None:
         work()
     request.response.setResult(EXAMPLE_HTML)
     context = object()
     event = EndRequestEvent(context, request)
     if exception is not None:
         self.eru.raising(
             (type(exception), exception, None), event.request)
     profile.end_request(event)
     da.clear_request_started()
     return event.request
コード例 #12
0
    def test_disconnect_logs_oops(self):
        # Ensure that OOPS reports are generated for database
        # disconnections, as per Bug #373837.
        request = LaunchpadTestRequest()
        publication = WebServicePublication(None)
        dbadapter.set_request_started()
        try:
            raise DisconnectionError('Fake')
        except DisconnectionError:
            self.assertRaises(
                Retry,
                publication.handleException,
                None, request, sys.exc_info(), True)
        dbadapter.clear_request_started()
        self.assertEqual(1, len(self.oopses))
        oops = self.oopses[0]

        # Ensure the OOPS mentions the correct exception
        self.assertEqual(oops['type'], "DisconnectionError")
コード例 #13
0
    def beginErrorHandlingTransaction(self, request, ob, note):
        """Hook for when a new view is started to handle an exception.

        We need to add an additional behavior to the usual Zope behavior.
        We must restart the request timer.  Otherwise we can get OOPS errors
        from our exception views inappropriately.
        """
        super(LaunchpadBrowserPublication,
              self).beginErrorHandlingTransaction(request, ob, note)
        # XXX: gary 2008-11-04 bug=293614: As the bug describes, we want to
        # only clear the SQL records and timeout when we are preparing for a
        # view (or a side effect). Otherwise, we don't want to clear the
        # records because they are what the error reporting utility uses to
        # create OOPS reports with the SQL commands that led up to the error.
        # At the moment, we can only distinguish based on the "note" argument:
        # an undocumented argument of this undocumented method.
        if note in ('application error-handling',
                    'application error-handling side-effect'):
            da.clear_request_started()
            da.set_request_started()
コード例 #14
0
    def beginErrorHandlingTransaction(self, request, ob, note):
        """Hook for when a new view is started to handle an exception.

        We need to add an additional behavior to the usual Zope behavior.
        We must restart the request timer.  Otherwise we can get OOPS errors
        from our exception views inappropriately.
        """
        super(LaunchpadBrowserPublication,
              self).beginErrorHandlingTransaction(request, ob, note)
        # XXX: gary 2008-11-04 bug=293614: As the bug describes, we want to
        # only clear the SQL records and timeout when we are preparing for a
        # view (or a side effect). Otherwise, we don't want to clear the
        # records because they are what the error reporting utility uses to
        # create OOPS reports with the SQL commands that led up to the error.
        # At the moment, we can only distinguish based on the "note" argument:
        # an undocumented argument of this undocumented method.
        if note in ('application error-handling',
                    'application error-handling side-effect'):
            da.clear_request_started()
            da.set_request_started()
コード例 #15
0
    def beforeTraversal(self, request):
        notify(StartRequestEvent(request))
        request._traversalticks_start = tickcount.tickcount()
        threadid = thread.get_ident()
        threadrequestfile = open_for_writing(
            'logs/thread-%s.request' % threadid, 'w')
        try:
            request_txt = unicode(request).encode('UTF-8')
        except Exception:
            request_txt = 'Exception converting request to string\n\n'
            try:
                request_txt += traceback.format_exc()
            except:
                request_txt += 'Unable to render traceback!'
        threadrequestfile.write(request_txt)
        threadrequestfile.close()

        # Tell our custom database adapter that the request has started.
        da.set_request_started()

        newInteraction(request)

        transaction.begin()

        # Now we are logged in, install the correct IDatabasePolicy for
        # this request.
        db_policy = IDatabasePolicy(request)
        getUtility(IStoreSelector).push(db_policy)

        getUtility(IOpenLaunchBag).clear()

        # Set the default layer.
        adapters = getGlobalSiteManager().adapters
        layer = adapters.lookup((providedBy(request), ), IDefaultSkin, '')
        if layer is not None:
            layers.setAdditionalLayer(request, layer)

        principal = self.getPrincipal(request)
        request.setPrincipal(principal)
        self.maybeRestrictToTeam(request)
        maybe_block_offsite_form_post(request)
コード例 #16
0
    def beforeTraversal(self, request):
        notify(StartRequestEvent(request))
        request._traversalticks_start = tickcount.tickcount()
        threadid = thread.get_ident()
        threadrequestfile = open_for_writing(
            'logs/thread-%s.request' % threadid, 'w')
        try:
            request_txt = unicode(request).encode('UTF-8')
        except Exception:
            request_txt = 'Exception converting request to string\n\n'
            try:
                request_txt += traceback.format_exc()
            except:
                request_txt += 'Unable to render traceback!'
        threadrequestfile.write(request_txt)
        threadrequestfile.close()

        # Tell our custom database adapter that the request has started.
        da.set_request_started()

        newInteraction(request)

        transaction.begin()

        # Now we are logged in, install the correct IDatabasePolicy for
        # this request.
        db_policy = IDatabasePolicy(request)
        getUtility(IStoreSelector).push(db_policy)

        getUtility(IOpenLaunchBag).clear()

        # Set the default layer.
        adapters = getGlobalSiteManager().adapters
        layer = adapters.lookup((providedBy(request),), IDefaultSkin, '')
        if layer is not None:
            layers.setAdditionalLayer(request, layer)

        principal = self.getPrincipal(request)
        request.setPrincipal(principal)
        self.maybeRestrictToTeam(request)
        maybe_block_offsite_form_post(request)
コード例 #17
0
    def test_timeout(self):
        # The time permitted to get the diff from the librarian may be None,
        # or 2. If there is not 2 seconds left in the request, the number will
        # be 0.01 smaller or the actual remaining time.
        class DiffWithFakeText(Diff):
            diff_text = FakeMethod()

        diff = DiffWithFakeText()
        diff.diff_text.open = FakeMethod()
        diff.diff_text.read = FakeMethod()
        diff.diff_text.close = FakeMethod()
        value = None
        original_timeout_function = get_default_timeout_function()
        set_default_timeout_function(lambda: value)
        try:
            LaunchpadTestRequest()
            set_request_started()
            try:
                diff.text
                self.assertEqual(
                    LIBRARIAN_SERVER_DEFAULT_TIMEOUT,
                    diff.diff_text.open.calls[-1][0][0])
                value = 3.1
                diff.text
                self.assertEqual(2.0, diff.diff_text.open.calls[-1][0][0])
                value = 1.11
                diff.text
                self.assertEqual(1.1, diff.diff_text.open.calls[-1][0][0])
                value = 0.11
                diff.text
                self.assertEqual(0.1, diff.diff_text.open.calls[-1][0][0])
                value = 0.01
                diff.text
                self.assertEqual(0.01, diff.diff_text.open.calls[-1][0][0])
            finally:
                clear_request_started()
        finally:
            set_default_timeout_function(original_timeout_function)
コード例 #18
0
ファイル: base.py プロジェクト: pombreda/UnnaturalCodeFork
 def _statement_logging_start(self):
     """Start logging SQL statements and other database activity."""
     set_request_started(
         request_statements=LimitedList(MAX_SQL_STATEMENTS_LOGGED),
         txn=self._transaction_manager, enable_timeout=False)
コード例 #19
0
 def setUp(self):
     super(TestLoggingWithinRequest, self).setUp()
     self.connection = StubConnection()
     self.person = self.factory.makePerson()
     da.set_request_started(1000.0)
     self.addCleanup(da.clear_request_started)
コード例 #20
0
 def setUp(self):
     super(TestLoggingWithinRequest, self).setUp()
     self.connection = StubConnection()
     self.person = self.factory.makePerson()
     da.set_request_started(1000.0)
     self.addCleanup(da.clear_request_started)
コード例 #21
0
ファイル: base.py プロジェクト: pombreda/UnnaturalCodeFork
 def _statement_logging_start(self):
     """Start logging SQL statements and other database activity."""
     set_request_started(
         request_statements=LimitedList(MAX_SQL_STATEMENTS_LOGGED),
         txn=self._transaction_manager,
         enable_timeout=False)
コード例 #22
0
ファイル: rewrite.py プロジェクト: pombreda/UnnaturalCodeFork
    def rewriteLine(self, resource_location):
        """Rewrite 'resource_location' to a more concrete location.

        We use the 'translatePath' BranchFileSystemClient method.  There are
        three cases:

         (1) The request is for something within the .bzr directory of a
             branch.

             In this case we rewrite the request to the location from which
             branches are served by ID.

         (2) The request is for something within a branch, but not the .bzr
             directory.

             In this case, we hand the request off to codebrowse.

         (3) The branch is not found.  Two sub-cases: the request is for a
             product control directory or the we don't know how to translate
             the path.

             In both these cases we return 'NULL' which indicates to Apache
             that we don't know how to rewrite the request (and so it should
             go on to generate a 404 response).

        Other errors are allowed to propagate, on the assumption that the
        caller will catch and log them.
        """
        # Codebrowse generates references to its images and stylesheets
        # starting with "/static", so pass them on unthinkingly.
        T = time.time()
        # Tell the webapp adapter that we are in a request, so that DB
        # statement timeouts will be applied.
        set_request_started()
        try:
            cached = None
            if resource_location.startswith('/static/'):
                r = self._codebrowse_url(resource_location)
                cached = 'N/A'
            else:
                branch_id, trailing, cached = self._getBranchIdAndTrailingPath(
                    resource_location)
                if branch_id is None:
                    if resource_location.startswith(
                            '/' + BRANCH_ID_ALIAS_PREFIX):
                        r = 'NULL'
                    else:
                        r = self._codebrowse_url(resource_location)
                else:
                    if trailing.startswith('/.bzr'):
                        r = urlutils.join(
                            config.codehosting.internal_branch_by_id_root,
                            branch_id_to_path(branch_id), trailing[1:])
                    else:
                        r = self._codebrowse_url(resource_location)
        finally:
            clear_request_started()
        self.logger.info(
            "%r -> %r (%fs, cache: %s)",
            resource_location, r, time.time() - T, cached)
        return r