Differences between revisions 1 and 8 (spanning 7 versions)
Revision 1 as of 2010-04-10 08:34:42
Size: 2654
Editor: ?JonathanNieder
Comment: removing diversions: binutils-multiarch shows this is hard to do, so list some best practices
Revision 8 as of 2019-09-07 18:46:26
Size: 3330
Editor: nodiscc
Comment: standardize page names
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
Diversions allow files from a package ''pkg-A'' to be temporarily replaced by files from another package ''pkg-B''.  When ''pkg-B'' is uninstalled, the files from ''pkg-A'' are put back into place. ## page was renamed from Adding and removing diversions
Diversions allow files from a package ''pkg-A'' to be temporarily replaced by files from another package ''pkg-B''. When ''pkg-B'' is uninstalled, the files from ''pkg-A'' are put back into place.
Line 3: Line 4:
For example, the `vim-tiny` package includes a small stub file in `/usr/share/vim/doc/help.txt`, which is renamed to help.txt.vim-tiny to make room for a fuller version when `vim-runtime` is installed.  When `vim-runtime` is uninstalled, the `help.txt.vim-tiny` is renamed back to `help.txt`. For example, the `vim-tiny` package includes a small stub file in `/usr/share/vim/doc/help.txt`, which is renamed to help.txt.vim-tiny to make room for a fuller version when `vim-runtime` is installed. When `vim-runtime` is uninstalled, the `help.txt.vim-tiny` is renamed back to `help.txt`.
Line 5: Line 6:
Diversions are a bit finicky.  Consider whether a Conflicts relation or `update-alternatives` might be a better way to achieve what you are trying to accomplish. Diversions are a bit finicky. Consider whether a Conflicts relation or `update-alternatives` might be a better way to achieve what you are trying to accomplish.
Line 9: Line 10:
See [[http://www.debian.org/doc/debian-policy/ap-pkg-diversions.html|Appendix G]] in the Debian policy manual. See [[http://www.debian.org/doc/debian-policy/ap-pkg-diversions.html|Appendix G]] in the Debian policy manual, but take into account the information within is currently quite out-of-date.
Line 11: Line 12:
In `preinst`, make sure the diversion is added in all cases.
If you want to avoid spurious messages on upgrades,
you can check for versions known to already include the diversion,
or you can explicitly check whether the diversion already exists.
In `preinst`, make sure the diversion is added in all cases. If you want to avoid spurious messages on upgrades, you can check for versions known to already include the diversion, or you can explicitly check whether the diversion already exists.
Line 17: Line 15:
pkg=me
Line 26: Line 23:
 dpkg-divert --package "$pkg" --add --rename \
  --divert "
/usr/share/foo.diverted-$pkg" /usr/share/foo
 dpkg-divert --add --rename /usr/share/foo
Line 31: Line 27:
In `postrm`, remove the diversion if and only if the package is being either removed or downgraded to a version before the diversion was added.  On upgrades to a newer version, do nothing: the diversion is the new version’s responsibility now. In `postrm`, remove the diversion if and only if the package is being either removed or downgraded to a version before the diversion was added. On upgrades to a newer version, do nothing: the diversion is the new version’s responsibility now.
Line 34: Line 30:
pkg=me
Line 36: Line 31:
this_version=3.8-2
Line 38: Line 34:
if dpkg --compare-versions "$2" lt "$diversion_added_version"
if test "$1" = failed-upgrade
then
 dpkg --compare-versions "$2" le-nl "$this_version" ||
 # An upgrade from a newer version failed.
 # There is no way for us to know enough to take over from here,
 # so abort the upgrade.
 exit 1
elif dpkg --compare-versions "$2" lt-nl "$diversion_added_version"
Line 44: Line 48:
remove,*|abort-install,*|disappear,*)
*,y)
 dpkg-divert --package "$pkg" --remove --rename \
  --divert "
/usr/share/foo.diverted-$pkg" /usr/share/foo
remove,*|abort-install,*|disappear,*|*,y)
 dpkg-divert --remove --rename /usr/share/foo
Line 54: Line 56:
In ''`postinst`'' and ''`prerm`'', remove the diversion.
Since failed upgrades can change the version number without configuration succeeding,
the last version configured is not a reliable indication of whether the diversion is still around.
If you want to avoid spurious messages, you can check for the diversion before removing it.
In ''`postinst`'' and ''`prerm`'', remove the diversion. Since failed upgrades can change the version number without configuration succeeding, the last version configured is not a reliable indication of whether the diversion is still around. If you want to avoid spurious messages, you can check for the diversion before removing it.
Line 60: Line 59:
pkg=me

if dpkg-divert --package "$pkg" --list | grep -F "/usr/share/foo.diverted-$pkg"
if dpkg-divert --list | grep -F "/usr/share/foo.distrib"
Line 64: Line 61:
 dpkg-divert --package "$pkg" --remove --rename \
  --divert "
/usr/share/foo.diverted-$pkg" /usr/share/foo
 dpkg-divert --remove --rename /usr/share/foo
Line 68: Line 64:

Without perfect foresight, the `prerm` surely cannot recover from failed attempts to upgrade from a newer version. (Nor can any other package; arguably this is a flaw in policy.) So supporting such downgrades reliably requires a check.

{{{
this_version=7.1

if test "$1" = failed-upgrade
then
 dpkg --compare-versions "$2" le "$this_version" ||
 # An upgrade from a newer version failed.
 # There is no way for us to know enough to take over from here,
 # so abort the upgrade.
 exit 1
fi
}}}
Line 69: Line 81:
CategoryDebianDevelopment
CategoryDeveloper CategoryPackaging

Diversions allow files from a package pkg-A to be temporarily replaced by files from another package pkg-B. When pkg-B is uninstalled, the files from pkg-A are put back into place.

For example, the vim-tiny package includes a small stub file in /usr/share/vim/doc/help.txt, which is renamed to help.txt.vim-tiny to make room for a fuller version when vim-runtime is installed. When vim-runtime is uninstalled, the help.txt.vim-tiny is renamed back to help.txt.

Diversions are a bit finicky. Consider whether a Conflicts relation or update-alternatives might be a better way to achieve what you are trying to accomplish.

Adding a diversion to a package

See Appendix G in the Debian policy manual, but take into account the information within is currently quite out-of-date.

In preinst, make sure the diversion is added in all cases. If you want to avoid spurious messages on upgrades, you can check for versions known to already include the diversion, or you can explicitly check whether the diversion already exists.

diversion_added_version=1.0.9-1
this_version=3.8-2

if
        test "$1" = install ||
        dpkg --compare-versions "$2" lt "$diversion_added_version" ||
        dpkg --compare-versions "$this_version" lt "$2"
then
        dpkg-divert --add --rename /usr/share/foo
fi

In postrm, remove the diversion if and only if the package is being either removed or downgraded to a version before the diversion was added. On upgrades to a newer version, do nothing: the diversion is the new version’s responsibility now.

diversion_added_version=1.0.9-1
this_version=3.8-2

losing_diversion=n

if test "$1" = failed-upgrade
then
        dpkg --compare-versions "$2" le-nl "$this_version" ||
        # An upgrade from a newer version failed.
        # There is no way for us to know enough to take over from here,
        # so abort the upgrade.
        exit 1
elif dpkg --compare-versions "$2" lt-nl "$diversion_added_version"
then
        losing_diversion=y
fi

case "$1,$losing_diversion" in
remove,*|abort-install,*|disappear,*|*,y)
        dpkg-divert --remove --rename /usr/share/foo
        ;;
esac

Removing a diversion from a package

In postinst and prerm, remove the diversion. Since failed upgrades can change the version number without configuration succeeding, the last version configured is not a reliable indication of whether the diversion is still around. If you want to avoid spurious messages, you can check for the diversion before removing it.

if dpkg-divert --list | grep -F "/usr/share/foo.distrib"
then
        dpkg-divert --remove --rename /usr/share/foo
fi

Without perfect foresight, the prerm surely cannot recover from failed attempts to upgrade from a newer version. (Nor can any other package; arguably this is a flaw in policy.) So supporting such downgrades reliably requires a check.

this_version=7.1

if test "$1" = failed-upgrade
then
        dpkg --compare-versions "$2" le "$this_version" ||
        # An upgrade from a newer version failed.
        # There is no way for us to know enough to take over from here,
        # so abort the upgrade.
        exit 1
fi


CategoryDeveloper CategoryPackaging