Univention Bugzilla – Bug 32525
unjoin debhelper
Last modified: 2015-02-04 15:57:15 CET
The current unjoin handling is a PITA: Currently 3 scripts needs to be modified to integrate unjoin: prerm, postrm, and postinst. In there scripts are called, moved to different locations and who knows what else I'm currently missing or what needs fixing in the future because of design mistakes. IMHO the current approach is error prone and a maintenance nightmare. UCS should provide a script similar to dpkg-maintscript-helper, which is just called from the three locations as »ucs-join-helper "$@"« and do all the internal processing: 1. Get the name of the package from $DPKG_MAINTSCRIPT_PACKAGE 2. Find the relevant (un-)join script 3.1: Move it it prerm 3.2: Call it in postrm 3.3: Delete it in postinst This should be further integrated with the "dh" sequencer: dh --with=ucs-unjoin would automatically create the relevant debhelper fragments, so creating the files with 30 lines of copyright and boiler-plate could be reduced to a single change in debian/rules. Something like this (untested): (this should currently create the fragments directly, but a runtime-wrapper would allow us to further fix already shipped pckages) ### /usr/share/perl5/Debian/Debhelper/Sequence/ucs-unjoin.pm: #!/usr/bin/perl use warnings; use strict; use Debian::Debhelper::Dh_Lib; insert_after("dh_installinit", "dh_ucs-unjoin"); 1; ### /usr/bin/dh_ucs-unjoin: #!/usr/bin/python """ Integrate UCS un-join scripts into package build process. """ # inspired by </usr/bin/dh_python2> import os import logging from debpython.debhelper import DebHelper from optparse import OptionParser, SUPPRESS_HELP logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: ' '%(message)s') log = logging.getLogger(__name__) def parse_commandline(): parser = OptionParser() parser.add_option('-i', '--indep', action='store_false', dest='arch', default=None, help='act on architecture independent packages') parser.add_option('-a', '-s', '--arch', action='store_true', dest='arch', help='act on architecture dependent packages') parser.add_option('-q', '--quiet', action='store_false', dest='verbose', help='be quiet') parser.add_option('-p', '--package', action='append', help='act on the package named PACKAGE') parser.add_option('-N', '--no-package', action='append', help='do not act on the specified package') parser.add_option('-O', help=SUPPRESS_HELP) options, args = parser.parse_args(sys.argv[1:] + \ os.environ.get('DH_OPTIONS', '').split()) if options.verbose or os.environ.get('DH_VERBOSE') == '1': log.setLevel(logging.DEBUG) return options def process_packages(options): dh = DebHelper(options) for package, pdetails in dh.packages.iteritems(): if options.arch is False and pdetails['arch'] != 'all' or \ options.arch is True and pdetails['arch'] == 'all': continue log.debug('processing package %s...', package) unjoin_name = find_unjoin_file(package) if not unjoin_name: continue dh.autoscript(package, 'prerm', 'prerm-ucs-unjoin', unjoin_name) dh.autoscript(package, 'postrm', 'postrm-ucs-unjoin', unjoin_name) dh.autoscript(package, 'postinst', 'postinst-ucs-unjoin', unjoin_name) def find_unjoin_file(package): for unjoin_name in os.listdir(): if not unjoin_name.endswith('.uinst'): continue pkg_name = unjoin_name[2:-len('.uinst')] if pkg_name == package: return unjoin_name def main(): options = parse_commandlline() process_packages(options) if __name__ == '__main__': main() ### /usr/share/debhelper/autoscripts/prerm-ucs-unjoin: case "$1" in remove) cp /usr/lib/univention-uninstall/#ARGS# /usr/lib/univention-install/ ;; esac ### /usr/share/debhelper/autoscripts/postrm-ucs-unjoin: case "$1" in remove) . /usr/share/univention-lib/all.sh call_unjoinscript #ARGS# ;; esac ### /usr/share/debhelper/autoscripts/postinst-ucs-unjoin: case "$1" in install|upgrade|abort-remove) uinst=/usr/lib/univention-install/#ARGS# [ -e "$uinst" ] && rm "$uinst" ;; esac
Created attachment 6607 [details] univention-install-joinscripts Found this bug (wanted to open my own). I wrote a script for exactly that, based on univention-install-config-registry. I also finds joinscripts (not only unjoin scripts), works with a (hopefully) upcoming Python joinscript and also takes care of installing the file with the correct permissions. Add univention-install-joinscripts in debian/rules' override_dh_auto_install. So no further work after putting a joinscript with the name $package.inst in the root directory.
Fixed in univention-join 7.1.2-6.492.201501261007 QA: I have not tested it excessively (only in one rather simple package). The idea is: debian/rules override_dh_auto_install: univention-install-joinscript dh_auto_install Add a 50$package.inst and a 50$package-uninstall.uinst in the root directory (or only the .inst file) and that should do the whole trick. If anything else is required, this bug should be REOPENED. Notably no debian/$package.install and $package.dirs need to cover the join scripts. No further actions to be taken in the control files (except for #DEBHELPER#). The files should installed (with +x) in the correct directories. The control files preinst, postinst, etc. should do all the necessary steps (even when not created by the developer manually). For the end user (who installs the package) no new package dependency (or version dependency) should be required. At least this is what I hope for and what I will write down in a document while you are QA'ing.
The unjoin scripts aren't part of the package. Instead in debian there is a folder created named e.g.: univention-management-console-module-pkgdb-uninstall joinscript_remove_script_from_status_file is even called if the unjoin script fails. Is this correct? Some packages have the following lines in there POSTINST. Do we need to do this, too? """ if [ "$1" = "configure" ] then uinst=/usr/lib/univention-install/65univention-management-console-module-pkgdb-uninstall.uinst [ -e "$uinst" ] && rm "$uinst" fi """ Also sometimes we have cross dependencies, which require unjoinscripts of 2 packages to be called directly after each other. """ # always call 65 after 50 (to remove service) # packages are always removed in unison because of cross-dependencies call_unjoinscript 50univention-pkgdb-uninstall.uinst call_unjoinscript 65univention-management-console-module-pkgdb-uninstall.uinst """ We can't use the lib then, except if it would be possible to call univention-install-joinscript with parameters for specific packages. dh-umc-module-install adds a second call to univention-call-joinscript %s. So it is twice in the postinst if you have a UMC package. ucslint shows now this warning: "… join script is not mentioned in debian/rules or *.install files" Please fix the copyright year (2007-2014 → 2015).
Another thing: the glob.glob() is error prone if you have two packages with names like: 'test-univention-foo' and 'univention-foo'.
(In reply to Florian Best from comment #3) > The unjoin scripts aren't part of the package. Instead in debian there is a > folder created named e.g.: > univention-management-console-module-pkgdb-uninstall > Fixed > joinscript_remove_script_from_status_file is even called if the unjoin > script fails. Is this correct? > > Some packages have the following lines in there POSTINST. Do we need to do > this, too? > """ > if [ "$1" = "configure" ] > then > > uinst=/usr/lib/univention-install/65univention-management-console-module- > pkgdb-uninstall.uinst > [ -e "$uinst" ] && rm "$uinst" > fi > """ I have changed the behaviour according to the suggestions above. I have implemented one initial unjoin-patch for fetchmail, where this was apparently done a bit different. > > Also sometimes we have cross dependencies, which require unjoinscripts of 2 > packages to be called directly after each other. > """ > # always call 65 after 50 (to remove service) > # packages are always removed in unison because of cross-dependencies > call_unjoinscript 50univention-pkgdb-uninstall.uinst > call_unjoinscript > 65univention-management-console-module-pkgdb-uninstall.uinst > """ > We can't use the lib then, except if it would be possible to call > univention-install-joinscript with parameters for specific packages. I would rather deny using the lib here. If someone really needs it, one may change it later on, but this is a very special case. Parameters are also difficult for ucslint to handle. Maybe one should better try to avoid such situations. Maybe they only came up because the packages are older than the unjoin mechanism and there would be no dependency if one knew about (un)joinscripts in the first place. > > dh-umc-module-install adds a second call to univention-call-joinscript %s. > So it is twice in the postinst if you have a UMC package. > > ucslint shows now this warning: > "… join script is not mentioned in debian/rules or *.install files" > Fixed in ucslint 4.0.0-5.64.201502021431 > Please fix the copyright year (2007-2014 → 2015). Fixed (In reply to Florian Best from comment #4) > Another thing: the glob.glob() is error prone if you have two packages with > names like: 'test-univention-foo' and 'univention-foo'. Yes, fixed.
OK: I used nagios and pkgdb to test this. OK: python-unjoin OK: ucslint YAML: OK, please add one for ucslint.
OK
<http://errata.univention.de/ucs/4.0/68.html>
<http://errata.univention.de/ucs/4.0/69.html>