[debian-release: Read this if you care about the details. The executive summary is to note that openssh 1:4.3p2-8 corrects an RC bug and should be hinted into testing if its five days expire without any new RC bugs; also that all other packages that have had to deal with moving conffiles between packages may be affected by a similar problem depending on whether they're upgraded with sarge's dpkg or etch's dpkg, and need to be reviewed and corrected before release.]
I spent rather more time than I expected today cleaning up after my initial attempt to fix bug #335276 (working around a bug in sarge's dpkg with respect to conffile handling, fixed in etch's dpkg), which resulted in bug #402804. Specifically, I had been moving a set of conffiles from the old ssh package in sarge to the openssh-client and openssh-server packages in etch for some time, and I was now also migrating the same conffiles from the old ssh-krb5 package (which conflicted with ssh). Initially, I was informed that it was good enough simply to remove the conffiles in the preinst if their md5sums are identical to those recorded by dpkg is sufficient, although unfortunately I didn't put the effort in at the time to set up a proper test environment for this. How wrong I was ... I included a Replaces << the version of the package where I added the move logic. However, as previously discussed on debian-devel, this turned out not to be enough, since unlike all other files in a package conffiles stick around after unpacking a new version of their package without them at least until the new version is configured, so (when using etch's dpkg, although apparently at least not always with sarge's) Replaces << was ineffective. I decided the simplest approach here was just to remove the versioning on the Replaces, since I never plan to move the conffiles back. Even after that, though, it turned out that removing the conffile is the wrong approach. If you do that and happen to be using etch's dpkg rather than sarge's dpkg, you get something like the following: [EMAIL PROTECTED]:/# dpkg --unpack root/ssh-krb5_4.3p2-8_all.deb root/openssh-server_4.3p2-8_powerpc.deb root/openssh-client_4.3p2-8_powerpc.deb (Reading database ... 7701 files and directories currently installed.) Preparing to replace ssh-krb5 3.8.1p1-10 (using root/ssh-krb5_4.3p2-8_all.deb) ... Unpacking replacement ssh-krb5 ... dpkg: warning - unable to delete old directory `/etc/ssh': Directory not empty Selecting previously deselected package openssh-server. Unpacking openssh-server (from .../openssh-server_4.3p2-8_powerpc.deb) ... Transferring ownership of conffile /etc/default/ssh ... Transferring ownership of conffile /etc/pam.d/ssh ... Replacing files in old package ssh-krb5 ... Selecting previously deselected package openssh-client. Unpacking openssh-client (from .../openssh-client_4.3p2-8_powerpc.deb) ... Transferring ownership of conffile /etc/ssh/moduli ... Transferring ownership of conffile /etc/ssh/ssh_config ... Replacing files in old package ssh-krb5 ... [EMAIL PROTECTED]:/# dpkg --configure -a Setting up openssh-client (4.3p2-8) ... Configuration file `/etc/ssh/ssh_config' ==> Deleted (by you or by a script) since installation. ==> Package distributor has shipped an updated version. What would you like to do about it ? Your options are: Y or I : install the package maintainer's version N or O : keep your currently-installed version D : show the differences between the versions Z : background this process to examine the situation The default action is to keep your current version. A conffile prompt - exactly what we were trying to avoid in the first place! (Justin, your conf-owner-transfer test case exhibits this too with etch's dpkg, along with the Replaces bug above.) The only way to absolutely guarantee not to get a conffile prompt is to make sure that the current file on disk is identical to either the old or the new version of the conffile. When moving a conffile between packages, I'm not sure that dpkg will allow the old version, and in any case there's no easy way to retrieve it since all we have is the md5sum. However, we do have the new version, although getting at it from the preinst when the package hasn't been unpacked yet is rather fiddly. As long as your conffile is textual, you can resort to the nasty hack of duplicating it in the preinst script, and that's what I did in openssh. This time I've actually tested this, so pending receipt of any more fun upgrade bugs I believe it works. I know that there are other packages that followed the recommendation to remove the conffile in the preinst, so I would encourage maintainers of those packages to review their code with reference to openssh 1:4.3p2-8 in order to avoid nasty lurking upgrade problems. The key points are: * Grab the old md5sum from dpkg in the preinst and check that it matches. If so, forcibly blat the new conffile into its place. (Yes, this is technically a policy violation, but the main reason for that part of policy is to avoid spurious conffile prompts when you didn't touch the file, and that's exactly what we're avoiding here too. Just remember to BE CAREFUL. The md5sum check should be enough.) openssh-client.preinst is about right here, taking care to avoid problems in case we run out of disk space while writing the new conffile, although it looks in /var/lib/dpkg/status directly rather than calling dpkg, which is a bug; I haven't got round to checking whether it's safe to fetch the conffile md5sum from 'dpkg -s ssh' in openssh-client's preinst. * Make sure to include rollback code in case the upgrade fails. This is something nearly everyone forgets in maintainer scripts, but this is all fragile enough that it's a particularly good idea here; just keep a copy of the old conffile at preinst time and either remove it at the end of the postinst if you succeed or put it back in the postrm if you fail. openssh-client.{preinst,postinst,postrm} should be usable as a model. * Replace all versions of the package you're moving the conffile from, not just the ones before the move. Making the Replaces tight just isn't worth the hassle. * You'll need a copy of the new conffile in the preinst script, substituted on the fly so that it never gets out of sync, and it needs to be quoted correctly for use in a shell variable. debian/substitute-conffile.pl in the openssh source package deals with this; run it over the preinst in the installation tree with 'perl -i' and appropriate arguments after dh_installdeb or equivalent. * Test your upgrade procedure in both a chroot with sarge's dpkg installed and one with etch's dpkg installed. Really. This is horribly easy to get wrong, the behaviour is quite radically different between the two versions of dpkg, and the time needed to set up chroots is still way less than that taken to repeatedly upload until your users stop filing bugs. Fortunately, all of this is only necessary for upgrades from sarge to etch, and once we can expect everyone to have etch's dpkg installed we can move conffiles between packages more or less like any other files. Cheers, -- Colin Watson [EMAIL PROTECTED] -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]