As discussed on debian-devel, different versions of these conffile handling shell functions on the wiki are being copied into maintainer scripts repeatedly, and adding a program to dpkg that handles things is a more maintainable approach. Note that in two places, parameters are required by dpkg-conffile that are not currently used. I did this to future-proof calls to the program. Perhaps in the future it will want to know the new conffile name in `prep_mv`, or the package name in `mv`. There is no copyright statement on the code in the wiki. (Which is being copied into many packages .. without a copyright statment!) I looked at the edit histories of both http://wiki.debian.org/DpkgConffileHandling and http://www.dpkg.org/dpkg/ConffileHandling, and it was originally written by Scott, and was then modified by Guillem. This patch assumes that both of them are willing to license it under GPL2+. Signed-off-by: Joey Hess <joeyh@debian.org> --- debian/changelog | 3 + debian/copyright | 3 +- debian/dpkg.install | 3 + man/Makefile.am | 1 + man/dpkg-conffile.8 | 132 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/Makefile.am | 2 + scripts/dpkg-conffile.sh | 94 ++++++++++++++++++++++++++++++++ 7 files changed, 237 insertions(+), 1 deletions(-) create mode 100644 man/dpkg-conffile.8 create mode 100755 scripts/dpkg-conffile.sh diff --git a/debian/changelog b/debian/changelog index 1eb6246..86c51e1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -22,6 +22,9 @@ dpkg (1.14.17) UNRELEASED; urgency=low * German (Helge Kreutzmann). * Swedish (Peter Karlsson). + [ Joey Hess ] + * Add dpkg-conffile, based upon http://wiki.debian.org/DpkgConffileHandling + -- Guillem Jover <guillem@debian.org> Mon, 21 Jan 2008 10:11:55 +0200 dpkg (1.14.16.5) unstable; urgency=low diff --git a/debian/copyright b/debian/copyright index 8ea1e6d..ac15365 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,11 +1,12 @@ This is Debian's package maintenance system. +Copyright © 2007 Guillem Jover <guillem@debian.org> Copyright © 2006-2007 Frank Lichtenheld <djpig@debian.org> Copyright © 2004-2005 Scott James Remnant <scott@netsplit.com> Copyright © 2004-2005 Canonical Ltd. Copyright © 1999-2002 Wichert Akkerman <wakkerma@debian.org> Copyright © 1999-2001 Marcus Brinkmann <brinkmd@debian.org> -Copyright © 2001 Joey Hess <joeyh@debian.org> +Copyright © 2001,2008 Joey Hess <joeyh@debian.org> Copyright © 1994-1999 Ian Jackson <ian@chiark.greenend.org.uk> Copyright © 1999 Richard Kettlewell <rjk@sfere.greenend.org.uk> Copyright © 1999 Ben Collins <bcollins@debian.org> diff --git a/debian/dpkg.install b/debian/dpkg.install index 2f54618..bd33273 100644 --- a/debian/dpkg.install +++ b/debian/dpkg.install @@ -7,6 +7,7 @@ usr/bin/dpkg usr/bin/dpkg-deb usr/bin/dpkg-query usr/bin/dpkg-split +usr/bin/dpkg-conffile usr/lib/dpkg/mksplit usr/sbin usr/share/dpkg @@ -21,6 +22,8 @@ usr/share/man/*/*/dpkg-query.1 usr/share/man/*/dpkg-query.1 usr/share/man/*/*/dpkg-split.1 usr/share/man/*/dpkg-split.1 +usr/share/man/*/*/dpkg-conffile.8 +usr/share/man/*/dpkg-conffile.8 usr/share/man/*/*/dpkg-statoverride.8 usr/share/man/*/dpkg-statoverride.8 usr/share/man/*/*/dpkg.cfg.5 diff --git a/man/Makefile.am b/man/Makefile.am index 42b17af..c975329 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -78,6 +78,7 @@ dist_man_MANS = \ dpkg-architecture.1 \ dpkg-buildpackage.1 \ dpkg-checkbuilddeps.1 \ + dpkg-conffile.8 \ dpkg-deb.1 \ dpkg-distaddfile.1 \ dpkg-divert.8 \ diff --git a/man/dpkg-conffile.8 b/man/dpkg-conffile.8 new file mode 100644 index 0000000..6bd8bf6 --- /dev/null +++ b/man/dpkg-conffile.8 @@ -0,0 +1,132 @@ +.\" This is an -*- nroff -*- source file. +.\" dpkg-conffile and this manpage are Copyright 2008 by Joey Hess. +.\" +.\" This is free software; see the GNU General Public Licence version 2 +.\" or later for copying conditions. There is NO warranty. +.TH dpkg\-conffile 8 "2008-1-25" "Debian Project" "dpkg utilities" +.SH NAME +dpkg\-conffile \- graceful deletion or moving of conffiles +. +.SH SYNOPSIS +.B dpkg\-conffile +.I rm <package> <conffile> +.P +.B dpkg\-conffile +.I prep_mv <package> <oldconffile> <newconffile> +.P +.B dpkg\-conffile +.I mv <package> <oldconffile> <newconffile> +. +.SH DESCRIPTION +When upgrading a package, dpkg will not automatically remove a conffile (a +configuration filefor which dpkg should preserve user changes) if it is not +present in the newer version. There are two principal reasons for this; the +first is that the conffile could've been dropped by accident and the next +version could restore it, users wouldn't want their changes thrown away. +The second is to allow packages to transition files from a dpkg-maintained +conffile to a file maintained by the package's maintainer scripts, usually +with a tool like debconf or ucf. +.P +This means that if a package is intended to rename or remove a conffile, +it must explicitly do do. +.B dpkg\-conffile +helps with graceful deletion and moving of conffiles. +. +.SH "REMOVING A CONFFILE" +If a conffile is completely removed, it should be removed from disk, +unless the user has modified it. If there are local modifications, they +should be preserved. This can be accomplished by making the package's +preinst script call +.B dpkg\-conffile rm <conffile> +.P +Generally the preinst should check to only do so on install or upgrade, +and only when upgrading from a version of the package that contained the +conffile. +.P +Internally, +.B dpkg\-conffile rm +will first check to make sure the conffile actually exists on the disk, if the +user has removed it already there's no point carrying on as everything's fine. +It then checks to see whether the user has modified it from the package's +version or not. It obtains the current md5sum, and compares that to +one taken from the dpkg database. This is why +.B dpkg\-conffile rm +must be called from the preinst, as the old md5sum information is still +available in the dpkg database at that point. +.P +If the user has not modified the conffile, it is simply removes from the disk. +If they have, it is moved to a filename that can be easily identified by the +user and ignored bytools such as run-parts. +. +.SH "MOVING A CONFFILE" +If a conffile is moved from one location to another, you need to make sure you +move across any changes the user has made. This may seem a simple change to the +preinst script at first, however that will result in the user being prompted by +dpkg to approve the conffile edits they have made. If you change the conffile +format, that may be desirable, however often you can do that kind of checking +yourself. +.P +.B dpkg\-conffile +allows moving a conffile without triggering the dpkg question. To move +a conffile, there are two steps. The preinst of the package, on install or +upgrade from the version that contained the conffile in the old location, +should call +.B dpkg\-conffile prep_mv <package> <oldconffile> <newconffile> +.P +Much like removal, this first checks to make sure the old conffile +exists on the disk and whether the user has changed it or not. If the user +has not changed it, the old conffile is simply removed from disk. If the +user has changed the conffile, it is left in place; its rename will be +handled by the postinst script. +.P +The postinst of the package should call +.B dpkg\-conffile mv <package> <oldconffile> <newconffile> +.P +This checks to see if the old conffile still exists on disk. If so, +it must contain changes that should be preserved. The new conffile (as +unpacked by dpkg) is moved to a .dpkg-new file, and the old conffile is +moved into its place. +. +.SH EXAMPLES +Removing a conffile, in a preinst script: + + case "$1" in + install|upgrade) + if dpkg --compare-versions "$2" le "$LASTVERSION"; then + dpkg-conffile rm mypackage /etc/pkg/conf + fi + esac + +Preparing to rename a conffile, in a preinst script: + + case "$1" in + install|upgrade) + if dpkg --compare-versions "$2" le "$LASTVERSION"; then + dpkg-conffile prep_mv mypackage /etc/pkg.conf /etc/pkg/conf + fi + esac + +Renaming the conffile, in a postinst script: + + case "$1" in + configure) + if dpkg --compare-versions "$2" le "$LASTVERSION"; then + dpkg-conffile mv mypackage /etc/pkg_conf /etc/pkg/conf + fi + esac +.P +In the above examples, replace $LASTVERSION with the last version +of the package to contain the old conffile. +. +.SH BUGS +Arguably the need for this program at all is a bug in dpkg. If dpkg is +ever changed to somehow handle conffile deletion and renaming on its own, +this program could turn into a deprecated no-op. +.SH SEE ALSO +.BR dpkg (1), +. +.SH AUTHOR +Copyright 2008 Joey Hess +.sp +This is free software; see the GNU General Public Licence version 2 or +later for copying conditions. There is NO WARRANTY. diff --git a/scripts/Makefile.am b/scripts/Makefile.am index e27f294..8c24971 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -7,6 +7,7 @@ bin_SCRIPTS = \ dpkg-architecture \ dpkg-buildpackage \ dpkg-checkbuilddeps \ + dpkg-conffile \ dpkg-distaddfile \ dpkg-genchanges \ dpkg-gencontrol \ @@ -34,6 +35,7 @@ EXTRA_DIST = \ dpkg-architecture.pl \ dpkg-buildpackage.pl \ dpkg-checkbuilddeps.pl \ + dpkg-conffile.sh \ dpkg-distaddfile.pl \ dpkg-genchanges.pl \ dpkg-gencontrol.pl \ diff --git a/scripts/dpkg-conffile.sh b/scripts/dpkg-conffile.sh new file mode 100755 index 0000000..9a1ce2d --- /dev/null +++ b/scripts/dpkg-conffile.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# Copyright (C) 2005 Scott James Remnant (original implementation on www.dpkg.org) +# Copyright (C) 2007 Guillem Jover (modifications on wiki.debian.org) +# Copyright (C) 2008 Joey Hess <joeyh@debian.org> (this script) +# +# This is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any +# later version. +# +# This is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file +# /usr/share/common-licenses/GPL for more details." + +set -e + +# Remove a no-longer used conffile +rm_conffile() { + PKGNAME="$1" + CONFFILE="$2" + if [ -e "$CONFFILE" ]; then + md5sum="`md5sum \"$CONFFILE\" | sed -e \"s/ .*//\"`" + old_md5sum="`dpkg-query -W -f='${Conffiles}' $PKGNAME | sed -n -e \"\\\\' $CONFFILE'{s/ obsolete$//;s/.* //p}\"`" + if [ "$md5sum" != "$old_md5sum" ]; then + echo "Obsolete conffile $CONFFILE has been modified by you." + echo "Saving as $CONFFILE.dpkg-bak ..." + mv -f "$CONFFILE" "$CONFFILE".dpkg-bak + else + echo "Removing obsolete conffile $CONFFILE ..." + rm -f "$CONFFILE" + fi + fi +} + +# Prepare to move a conffile without triggering a dpkg question +prep_mv_conffile() { + PKGNAME="$1" + OLDCONFFILE="$2" + NEWCONFFILE="$3" # currently not used + if [ -e "$OLDCONFFILE" ]; then + md5sum="`md5sum \"$OLDCONFFILE\" | sed -e \"s/ .*//\"`" + old_md5sum="`dpkg-query -W -f='${Conffiles}' $PKGNAME | sed -n -e \"\\\\' $OLDCONFFILE'{s/ obsolete$//;s/.* //p}\"`" + if [ "$md5sum" = "$old_md5sum" ]; then + rm -f "$OLDCONFFILE" + fi + fi +} + +# Move a conffile without triggering a dpkg question +mv_conffile() { + PKGNAME="$1" # currently not used + OLDCONFFILE="$2" + NEWCONFFILE="$3" + if [ -e "$OLDCONFFILE" ]; then + echo "Preserving user changes to $NEWCONFFILE ..." + mv -f "$NEWCONFFILE" "$NEWCONFFILE".dpkg-new + mv -f "$OLDCONFFILE" "$NEWCONFFILE" + fi +} + +usage() { + cat <<EOF >&2 +Usage: + dpkg-conffile rm <package> <conffile> + dpkg-conffile prep_mv <package> <oldconffile> <newconffile> + dpkg-conffile mv package <package> <oldconffile> <newconffile> +EOF + exit 1 +} + +case "$1" in +rm) + if [ -z "$2" ] || [ -z "$3" ]; then + usage + fi + rm_conffile "$2" "$3" +;; +prep_mv) + if [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then + usage + fi + prep_mv_conffile "$2" "$3" "$4" +;; +mv) + if [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then + usage + fi + mv_conffile "$2" "$3" "$4" +;; +*) + usage +;; +esac -- 1.5.3.8 -- see shy jo
Attachment:
signature.asc
Description: Digital signature