Attached is patch that implements what you are doing with scripts "internally".

It defines a new option --no-diversions, which defaults to False; i.e. DO check for differences between dpkg-divert --list executions after chroot setup and after package purge. Any differences are logged with one/both of:

Error: Installed diversions (dpkg-divert) not removed by purge:
    line(s) from post setup ...

Error: Existing diversions (dpkg-divert) removed/modified:
    line(s) from post purge ...

Same warnings re other patch I submitted apply ... my (lack of) Python skills and relative ignorance re piuparts codebase, plus limited regression testing make this subject to extra review.


diff --git a/piuparts.1.txt b/piuparts.1.txt
--- a/piuparts.1.txt
+++ b/piuparts.1.txt
@@ -102,6 +102,9 @@
 +
 Note that file: addresses works if the directories are made accessible from within the chroot with '--bindmount'.
 
+*--no-diversions*::
+  Don't check for broken diversions.
+
 *-n, --no-ignores*::
   Forget all built-in and other ignores that have been set so far. Any '-i' or '-I' arguments that come after this one will be obeyed, but none of the ones that come before.
 
diff --git a/piuparts.py b/piuparts.py
--- a/piuparts.py
+++ b/piuparts.py
@@ -152,6 +152,7 @@
         self.no_upgrade_test = False
         self.skip_cronfiles_test = False
         self.skip_logrotatefiles_test = False
+        self.check_broken_diversions = True
         self.check_broken_symlinks = True
         self.warn_broken_symlinks = False
         self.debfoster_options = None
@@ -572,6 +573,8 @@
     
     def __init__(self):
         self.name = None
+        self.pre_install_diversions = None
+        self.post_install_diversions = None
         
     def create_temp_dir(self):
         """Create a temporary directory for the chroot."""
@@ -609,6 +612,8 @@
                 if (sfile.startswith("post_") or sfile.startswith("pre_")) and os.path.isfile(os.path.join((settings.scriptsdir), sfile)):
                     shutil.copy(os.path.join((settings.scriptsdir), sfile), dest) 
 
+        self.pre_install_diversions = self.get_diversions()
+
         # Run custom scripts after creating the chroot.
         if settings.scriptsdir is not None: 
             self.run_scripts("post_setup")
@@ -837,6 +842,32 @@
             vdict[name] = status
         return vdict
 
+    def get_diversions(self):
+    	"""Get current dpkg-divert --list in a chroot."""
+        if not settings.check_broken_diversions:
+            return
+        (status, output) = self.run(["dpkg-divert", "--list"])
+        lines = []
+        for line in output.split("\n"):
+            lines.append(line)
+        return lines
+
+
+    def check_for_broken_diversions(self):
+        """Check that diversions in chroot are identical (though potenttially reordered)."""
+        if not settings.check_broken_diversions:
+            return
+        if self.pre_install_diversions and self.post_install_diversions:
+            added = [ln for ln in self.pre_install_diversions if not ln in self.post_install_diversions]
+            removed = [ln for ln in self.post_install_diversions if not ln in self.pre_install_diversions]
+            if added:
+                logging.error("Error: Installed diversions (dpkg-divert) not removed by purge:\n%s" %  
+                              indent_string("\n".join(added)))
+            if removed:
+                logging.error("Error: Existing diversions (dpkg-divert) removed/modified:\n%s" %
+                              indent_string("\n".join(removed)))
+    	
+
     def remove_or_purge(self, operation, packages):
         """Remove or purge packages in a chroot."""
         for name in packages:
@@ -894,6 +925,8 @@
         # Finally, purge actual packages.
         self.remove_or_purge("purge", nondeps_to_purge)
 
+        self.post_install_diversions = self.get_diversions()
+
         # remove logrotate and it's depends 
         #    (this is a fix for #602409 introduced by #566597 
         #    - search for the latter bug number in this file)
@@ -1721,6 +1754,7 @@
     changes = diff_selections(chroot, selections)
     chroot.restore_selections(changes, packages)
     
+    chroot.check_for_broken_diversions()
     chroot.check_for_broken_symlinks()
 
     return check_results(chroot, root_info, file_owners, deps_info=deps_info)
@@ -1996,6 +2030,10 @@
                       default=[],
                       help="Which Debian mirror to use.")
     
+    parser.add_option("--no-diversions", action="store_true",
+                      default=False,
+                      help="Don't check for broken diversions.")
+
     parser.add_option("-n", "--no-ignores", action="callback",
                       callback=forget_ignores,
                       help="Forget all ignores set so far, including " +
@@ -2122,6 +2160,7 @@
     
     settings.debian_mirrors = [parse_mirror_spec(x, defaults.get_components())
                                for x in opts.mirror]
+    settings.check_broken_diversions = not opts.no_diversions
     settings.check_broken_symlinks = not opts.no_symlinks
     settings.warn_broken_symlinks = opts.warn_symlinks
     settings.savetgz = opts.save

Reply via email to