Dear maintainer,
I want one of my packages to divert files from an essential package: I used code
from examples (with --rename option) online [1] that works fine, but lintian complains.
Moving essential files can be dangerous, use the --no-rename.
Ok. So I assumend that the same code would work fine, just replacing '--rename' with
'no-rename', silly me.. instead it broke my system.
It is true that the manpage states under [ --add/remove]
"The file is currently not renamed, see --rename"
However reading the --rename/--no-rename description I was under the impression that the
--no-rename was a safer option - overwrite during unpack instead of moving aside
before the unpack, and that it's safer also when the diversion is removed.
This is not the case, or maybe there is an easy way that i'm not considering
but it's not documented anywere and also serching the code base for examples [2]
provides no clue.
Somehow i found a way but it requires some additional code in preinst and giving that
lintian screams in all the four cardinal direction I suspect it's not the right way
[ example appended at the end ]
I'm having the following problems with --no-rename:
* At preinst, it doesn't create a copy of the original file "file.real"
* at postrm, the file disappear and it's not replaced by anything;
also, if there is a copy "file.real" is left there (i guess piuparts would complain)
Even if one use the --rename option in postrm, the "file.real" is not granted
to exists untill the package that ship the original file is upgraded or reinstalled.
Finally, while during the unpack the file is overwritten, during the removal there is
still a moment where the file disappear (am I wrong?) so overall it does look more
complex to handle but not that safer than a standard --rename.
Regards,
Lorenzo
[1] https://www.debian.org/doc/debian-policy/ap-pkg-diversions.html
[2] https://codesearch.debian.net/search?q=dpkg-divert+--no-rename&literal=1
Example
$ cat runit-init.preinst
#!/bin/sh
set -e
# make sure that the *.real diverted file exists when postrm is called
# as with --no-rename the diverted file is not created: if this package
# is removed before init-system-helpers is upgraded the system will be
# left without helpers!! see postrm
if [ upgrade != "$1" ] || dpkg --compare-versions "$2" lt 2.1.2-41; then
for file in /usr/sbin/invoke-rc.d /usr/sbin/service /usr/sbin/update-rc.d ; do
if [ ! -e "$file".real ] ; then
cp "$file" "$file".real
fi
done
fi
# install helpers with runit support
if [ upgrade != "$1" ] || dpkg --compare-versions "$2" lt 2.1.2-41; then
dpkg-divert --package runit-init --add --no-rename \
--divert /usr/sbin/invoke-rc.d.real /usr/sbin/invoke-rc.d
dpkg-divert --package runit-init --add --no-rename \
--divert /usr/sbin/service.real /usr/sbin/service
dpkg-divert --package runit-init --add --no-rename \
--divert /usr/sbin/update-rc.d.real /usr/sbin/update-rc.d
fi
#DEBHELPER#
exit 0
-------------------
$ cat runit-init.postrm
#!/bin/sh
set -e
# need to use --rename here, with --no-rename the *.real diverted file will
# not be back and the system is left without helpers!
# *.real is granted to be there because of preinst
if [ "$1" = "remove" ] || [ "$1" = "abort-install" ] || [ "$1" = "disappear" ] ; then
dpkg-divert --package runit-init --remove --rename \
--divert /usr/sbin/invoke-rc.d.real /usr/sbin/invoke-rc.d
dpkg-divert --package runit-init --remove --rename \
--divert /usr/sbin/service.real /usr/sbin/service
dpkg-divert --package runit-init --remove --rename \
--divert /usr/sbin/update-rc.d.real /usr/sbin/update-rc.d
fi
#the following can be removed as runit 2.1.2-41 is out of oldoldstable
if [ "abort-upgrade" = "$1" ] && dpkg --compare-versions "$2" lt 2.1.2-41; then
dpkg-divert --package runit-init --remove --rename \
--divert /usr/sbin/invoke-rc.d.real /usr/sbin/invoke-rc.d
dpkg-divert --package runit-init --remove --rename \
--divert /usr/sbin/service.real /usr/sbin/service
dpkg-divert --package runit-init --remove --rename \
--divert /usr/sbin/update-rc.d.real /usr/sbin/update-rc.d
fi
#DEBHELPER#
exit 0
--------------------
$ cat runit-init.install
debian/contrib/helpers/invoke-rc.d /usr/sbin
debian/contrib/helpers/service /usr/sbin
debian/contrib/helpers/update-rc.d /usr/sbin
---------------------
$ lintian -Ev --pedantic runit_2.1.2-41_amd64.changes
N: Using profile debian/main.
N: Starting on group runit/2.1.2-41
N: Finished processing group runit/2.1.2-41
E: runit-init: diversion-for-unknown-file --no-rename/usr/sbin/invoke-rc.d preinst:19
E: runit-init: diversion-for-unknown-file --no-rename/usr/sbin/service preinst:21
E: runit-init: diversion-for-unknown-file --no-rename/usr/sbin/update-rc.d preinst:23
E: runit-init: orphaned-diversion --no-rename/usr/sbin/invoke-rc.d preinst
E: runit-init: orphaned-diversion --no-rename/usr/sbin/service preinst
E: runit-init: orphaned-diversion --no-rename/usr/sbin/update-rc.d preinst
E: runit-init: remove-of-unknown-diversion usr/sbin/invoke-rc.d postrm:10
E: runit-init: remove-of-unknown-diversion usr/sbin/invoke-rc.d postrm:20
E: runit-init: remove-of-unknown-diversion usr/sbin/service postrm:12
E: runit-init: remove-of-unknown-diversion usr/sbin/service postrm:22
E: runit-init: remove-of-unknown-diversion usr/sbin/update-rc.d postrm:14
E: runit-init: remove-of-unknown-diversion usr/sbin/update-rc.d postrm:24
W: runit-init: no-manual-page usr/sbin/invoke-rc.d
W: runit-init: no-manual-page usr/sbin/service
W: runit-init: no-manual-page usr/sbin/update-rc.d
X: runit source: debian-watch-does-not-check-gpg-signature
X: runit-run: systemd-service-file-missing-hardening-features lib/systemd/system/runit.service
N: 13 hints overridden (1 warning, 12 info)
[1] https://www.debian.org/doc/debian-policy/ap-pkg-diversions.html
[2] https://codesearch.debian.net/search?q=dpkg-divert+--no-rename&literal=1