tags 447214 patch
thanks

Hi,

Here is a patch to implement a retry on apt-get actions.
With --retry you can specify how many times you want to retry.

Regards,
Carl Chenet
--- piuparts-original/piuparts.py	2009-04-21 21:54:52.000000000 +0200
+++ piuparts/piuparts.py	2009-04-21 21:32:50.000000000 +0200
@@ -132,6 +132,7 @@
         self.single_changes_list = False
         # limit output of logfiles to the last megabyte:
         self.max_command_output_size = 1024 * 1024
+        self.retry = 0
         self.args_are_package_files = True
         self.debian_mirrors = []
         self.debian_distros = []
@@ -347,29 +348,36 @@
     return "".join(result)
 
 
-def run(command, ignore_errors=False):
+def run(command, ignore_errors=False, retry=0):
     """Run an external command and die with error message if it fails."""
     assert type(command) == type([])
     logging.debug("Starting command: %s" % command)
     env = os.environ.copy()
     env["LC_ALL"] = "C"
     env["LANGUAGES"] = ""
-    p = subprocess.Popen(command, env=env, stdin=subprocess.PIPE, 
-                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-    (output, _) = p.communicate()
-
-    if output:
-        dump("\n" + indent_string(output.rstrip("\n")))
-
-    if p.returncode == 0:
-        logging.debug("Command ok: %s" % repr(command))
-    elif ignore_errors:
-        logging.debug("Command failed (status=%d), but ignoring error: %s" % 
-              (p.returncode, repr(command)))
-    else:
-        logging.error("Command failed (status=%d): %s\n%s" % 
-              (p.returncode, repr(command), indent_string(output)))
-        panic()
+    retry += 1
+    while retry != 0:
+        p = subprocess.Popen(command, env=env, stdin=subprocess.PIPE, 
+                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        (output, _) = p.communicate()
+
+        if output:
+            dump("\n" + indent_string(output.rstrip("\n")))
+
+        if p.returncode == 0:
+            logging.debug("Command ok: %s" % repr(command))
+            retry = 0
+        elif ignore_errors:
+            logging.debug("Command failed (status=%d), but ignoring error: %s" % 
+                  (p.returncode, repr(command)))
+            retry = 0
+        else:
+            logging.error("Command failed (status=%d): %s\n%s" % 
+                  (p.returncode, repr(command), indent_string(output)))
+            if retry - 1 == 0:
+                panic()
+            else:
+                retry -= 1
     return p.returncode, output
 
 
@@ -556,7 +564,7 @@
         self.mount_proc()
         self.mount_selinux()
         if settings.basetgz:
-            self.run(["apt-get", "-yf", "upgrade"])
+            self.run(["apt-get", "-yf", "upgrade"], retry=settings.retry)
         self.minimize()
         self.run(["apt-get", "clean"])
 
@@ -603,9 +611,9 @@
         logging.debug("Unpacking %s into %s" % (tarball, self.name))
         run(["tar", "-C", self.name, "-zxf", tarball])
 
-    def run(self, command, ignore_errors=False):
+    def run(self, command, ignore_errors=False, retry=0):
         return run(["chroot", self.name] + command,
-                   ignore_errors=ignore_errors)
+                   ignore_errors=ignore_errors, retry=retry)
 
     def create_apt_sources(self, distro):
         """Create an /etc/apt/sources.list with a given distro."""
@@ -647,7 +655,7 @@
         if settings.skip_minimize:
              return
 
-        self.run(["apt-get", "install", "debfoster"])
+        self.run(["apt-get", "install", "debfoster"], retry=settings.retry)
         self.run(["debfoster"] + settings.debfoster_options)
         remove_files([self.relative("var/lib/debfoster/keepers")])
         self.run(["dpkg", "--purge", "debfoster"])
@@ -661,7 +669,7 @@
         for bindmount in settings.bindmounts:
             run(["mkdir", "-p", self.relative(bindmount)])
             run(["mount", "-obind", bindmount, self.relative(bindmount)])
-        self.run(["apt-get", "update"])
+        self.run(["apt-get", "update"], retry=settings.retry)
 
     def upgrade_to_distros(self, distros, packages):
         """Upgrade a chroot installation to each successive distro."""
@@ -671,8 +679,8 @@
 	    # Run custom scripts before upgrade
             if settings.scriptsdir is not None:
                 self.run_scripts("pre_distupgrade")
-            self.run(["apt-get", "update"])
-            self.run(["apt-get", "-yf", "dist-upgrade"])
+            self.run(["apt-get", "update"], retry=settings.retry)
+            self.run(["apt-get", "-yf", "dist-upgrade"], retry=settings.retry)
             # Sometimes dist-upgrade won't upgrade the packages we want
             # to test because the new version depends on a newer library,
             # and installing that would require removing the old version
@@ -688,7 +696,7 @@
         """Does apt-get (or apt-cache) know about a set of packages?"""
         for name in package_names:
             (status, output) = self.run(["apt-cache", "show", name],
-                                        ignore_errors=True)
+                                        ignore_errors=True, retry=settings.retry)
             if not os.WIFEXITED(status):
                 logging.error("Error occurred when running apt-cache " +
                               " in chroot:\n" + output)
@@ -748,12 +756,12 @@
                 self.run(["dpkg", "-i"] + tmp_files, ignore_errors=True)
                 self.list_installed_files (pre_info, self.save_meta_data())
 
-                self.run(["apt-get", "-yf", "--no-remove", "install"])
+                self.run(["apt-get", "-yf", "--no-remove", "install"], retry=settings.retry)
                 self.list_installed_files (pre_info, self.save_meta_data())
 
             else:
                 self.run(["dpkg", "-i"] + tmp_files, ignore_errors=True)
-                self.run(["apt-get", "-yf", "--no-remove", "install"])
+                self.run(["apt-get", "-yf", "--no-remove", "install"], retry=settings.retry)
 
             if settings.scriptsdir is not None:
                 self.run_scripts("post_install")
@@ -871,10 +879,10 @@
         if packages:
 	    if settings.list_installed_files:
                 pre_info = self.save_meta_data()
-                self.run(["apt-get", "-y", "install"] + packages)
+                self.run(["apt-get", "-y", "install"] + packages, retry=settings.retry)
                 self.list_installed_files (pre_info, self.save_meta_data())
             else:
-                self.run(["apt-get", "-y", "install"] + packages)
+                self.run(["apt-get", "-y", "install"] + packages, retry=settings.retry)
 	    
 	    
     def check_for_no_processes(self):
@@ -1643,7 +1651,7 @@
 
     chroot.check_for_no_processes()
     
-    chroot.run(["apt-get", "update"])
+    chroot.run(["apt-get", "update"], retry=settings.retry)
     chroot.install_packages_by_name(packages)
 
     chroot.check_for_no_processes()
@@ -1816,6 +1824,12 @@
                       help="Use /var/cache/pbuilder/base.tgz as the base " +
                            "tarball.")
     
+    parser.add_option("-r", "--retry", metavar="N", 
+                      action="store",
+                      type="int",
+                      default=0,
+                      help="Retry fetching commands N times if errors occur.")
+    
     parser.add_option('', "--adt-virt",
                       metavar='CMDLINE', default=None,
                       help="Use CMDLINE via autopkgtest (adt-virt-*)"
@@ -1857,6 +1871,7 @@
     settings.single_changes_list = opts.single_changes_list
     settings.keep_sources_list = opts.keep_sources_list
     settings.skip_minimize = opts.skip_minimize
+    settings.retry = opts.retry
     settings.list_installed_files = opts.list_installed_files
     settings.no_upgrade_test = opts.no_upgrade_test
     settings.skip_cronfiles_test = opts.skip_cronfiles_test

Reply via email to