(self, *args, **kw)
Update the system's package lists (switching mirrors if necessary).

        :param args: Command line arguments to ``apt-get update`` (zero or more strings).
        :param max_attempts: The maximum number of attempts at successfully
                             updating the system's package lists (an integer,
                             defaults to 10).
        :param switch_mirrors: :data:`True` if we're allowed to switch mirrors
                               on 'hash sum mismatch' errors, :data:`False`
                               otherwise.
        :raises: If updating of the package lists fails 10 consecutive times
                 (`max_attempts`) an exception is raised.

        While :func:`dumb_update()` simply runs ``apt-get update`` the
        :func:`smart_update()` function works quite differently:

        - First the system's package lists are updated using
          :func:`dumb_update()`. If this is successful we're done.
        - If the update fails we check the command's output for the phrase
          'hash sum mismatch'. If we find this phrase we assume that the
          current mirror is faulty and switch to another one.
        - Failing ``apt-get update`` runs are retried up to `max_attempts`.
Update the system's package lists (switching mirrors if necessary).
Update the system s package lists ( switching mirrors if necessary ) .
def smart_update(self, *args, **kw):
        """
        Update the system's package lists (switching mirrors if necessary).

        :param args: Command line arguments to ``apt-get update`` (zero or more strings).
        :param max_attempts: The maximum number of attempts at successfully
                             updating the system's package lists (an integer,
                             defaults to 10).
        :param switch_mirrors: :data:`True` if we're allowed to switch mirrors
                               on 'hash sum mismatch' errors, :data:`False`
                               otherwise.
        :raises: If updating of the package lists fails 10 consecutive times
                 (`max_attempts`) an exception is raised.

        While :func:`dumb_update()` simply runs ``apt-get update`` the
        :func:`smart_update()` function works quite differently:

        - First the system's package lists are updated using
          :func:`dumb_update()`. If this is successful we're done.
        - If the update fails we check the command's output for the phrase
          'hash sum mismatch'. If we find this phrase we assume that the
          current mirror is faulty and switch to another one.
        - Failing ``apt-get update`` runs are retried up to `max_attempts`.
        """
        backoff_time = 10
        max_attempts = kw.get('max_attempts', 10)
        switch_mirrors = kw.get('switch_mirrors', True)
        for i in range(1, max_attempts + 1):
            with CaptureOutput() as session:
                try:
                    self.dumb_update(*args)
                    return
                except Exception:
                    if i < max_attempts:
                        output = session.get_text()
                        # Check for EOL releases. This somewhat peculiar way of
                        # checking is meant to ignore 404 responses from
                        # `secondary package mirrors' like PPAs. If the output
                        # of `apt-get update' implies that the release is EOL
                        # we need to verify our assumption.
                        if any(self.current_mirror in line and u'404' in line.split() for line in output.splitlines()):
                            logger.warning("%s may be EOL, checking ..", self.release)
                            if self.release_is_eol:
                                if switch_mirrors:
                                    logger.warning("Switching to old releases mirror because %s is EOL ..",
                                                   self.release)
                                    self.change_mirror(self.old_releases_url, update=False)
                                    continue
                                else:
                                    raise Exception(compact("""
                                        Failed to update package lists because it looks like
                                        the current release (%s) is end of life but I'm not
                                        allowed to switch mirrors! (there's no point in
                                        retrying so I'm not going to)
                                    """, self.distribution_codename))
                        # Check for `hash sum mismatch' errors.
                        if switch_mirrors and u'hash sum mismatch' in output.lower():
                            logger.warning("Detected 'hash sum mismatch' failure, switching to other mirror ..")
                            self.ignore_mirror(self.current_mirror)
                            self.change_mirror(update=False)
                        else:
                            logger.warning("Retrying after `apt-get update' failed (%i/%i) ..", i, max_attempts)
                            # Deal with unidentified (but hopefully transient) failures by retrying but backing off
                            # to give the environment (network connection, mirror state, etc.) time to stabilize.
                            logger.info("Sleeping for %s before retrying update ..", format_timespan(backoff_time))
                            time.sleep(backoff_time)
                            if backoff_time <= 120:
                                backoff_time *= 2
                            else:
                                backoff_time += backoff_time / 3
        raise Exception("Failed to update package lists %i consecutive times?!" % max_attempts)
def smart_update ( self , * args , * * kw ) : backoff_time = 10 max_attempts = kw . get ( 'max_attempts' , 10 ) switch_mirrors = kw . get ( 'switch_mirrors' , True ) for i in range ( 1 , max_attempts + 1 ) : with CaptureOutput ( ) as session : try : self . dumb_update ( * args ) return except Exception : if i < max_attempts : output = session . get_text ( ) # Check for EOL releases. This somewhat peculiar way of # checking is meant to ignore 404 responses from # `secondary package mirrors' like PPAs. If the output # of `apt-get update' implies that the release is EOL # we need to verify our assumption. if any ( self . current_mirror in line and u'404' in line . split ( ) for line in output . splitlines ( ) ) : logger . warning ( "%s may be EOL, checking .." , self . release ) if self . release_is_eol : if switch_mirrors : logger . warning ( "Switching to old releases mirror because %s is EOL .." , self . release ) self . change_mirror ( self . old_releases_url , update = False ) continue else : raise Exception ( compact ( """
                                        Failed to update package lists because it looks like
                                        the current release (%s) is end of life but I'm not
                                        allowed to switch mirrors! (there's no point in
                                        retrying so I'm not going to)
                                    """ , self . distribution_codename ) ) # Check for `hash sum mismatch' errors. if switch_mirrors and u'hash sum mismatch' in output . lower ( ) : logger . warning ( "Detected 'hash sum mismatch' failure, switching to other mirror .." ) self . ignore_mirror ( self . current_mirror ) self . change_mirror ( update = False ) else : logger . warning ( "Retrying after `apt-get update' failed (%i/%i) .." , i , max_attempts ) # Deal with unidentified (but hopefully transient) failures by retrying but backing off # to give the environment (network connection, mirror state, etc.) time to stabilize. logger . info ( "Sleeping for %s before retrying update .." , format_timespan ( backoff_time ) ) time . sleep ( backoff_time ) if backoff_time <= 120 : backoff_time *= 2 else : backoff_time += backoff_time / 3 raise Exception ( "Failed to update package lists %i consecutive times?!" % max_attempts )