Hello folks, I've tried to follow the suggestions Raphael gave me in the previous mail, and produced a new patch (indents as an 8-space-wide tab, please tell me if I got this right). I also created an initial test within pkg-tests, that I've called t-convert-dir-to-symlink-upgrade. It doesn't cover all cases produced by the command I've introduced in dpkg-maintscript-helper.sh, but I wanted to get some feedback before going on. The 2 patches are attached. Please let me know if I'm on the right path or made other mistakes. Best, -- Gianluca Ciccarelli http://disi.unitn.it/~ciccarelli GPG key ID: FDF429B0
From 54a14d3be727262cc354fc4e4129a7029847c45f Mon Sep 17 00:00:00 2001
From: Gianluca Ciccarelli (sturmer) <ciccarelli@disi.unitn.it>
Date: Thu, 29 Dec 2011 18:01:12 +0100
Subject: [PATCH] dpkg-maintscript-helper: implement command convert_dir_to_symlink
We have a directory that has to be transformed into a symlink in
a later version. In preinst, we just create a backup of the directory;
in postinst, the backup is safely eliminated; in postrm failed-upgrade,
the backup directory is restored.
---
scripts/dpkg-maintscript-helper.sh | 85 +++++++++++++++++++++++++++++++++++-
1 files changed, 84 insertions(+), 1 deletions(-)
diff --git a/scripts/dpkg-maintscript-helper.sh b/scripts/dpkg-maintscript-helper.sh
index 92088ae..27d5e4a 100755
--- a/scripts/dpkg-maintscript-helper.sh
+++ b/scripts/dpkg-maintscript-helper.sh
@@ -216,6 +216,83 @@ abort_mv_conffile() {
fi
}
+# Substitute a directory with a symlink
+convert_dir_to_symlink() {
+ local DIRECTORY="$1"
+ local LAST_VERSION="$2"
+
+ [ -d "$DIRECTORY" -o -L "$DIRECTORY" ] || \
+ error "a directory should be specified"
+ if [ "$LAST_VERSION" = "--" -o -z "$LAST_VERSION" ]; then
+ error "please specify the version number of the first package "\
+ "having a symlink"
+ fi
+
+ while [ "$1" != "--" -a $# -gt 0 ]; do shift; done
+ [ $# -gt 0 ] || badusage
+ [ -n "$DPKG_MAINTSCRIPT_NAME" ] || \
+ error "could not determine the launching maint script"
+ shift
+
+ # In the case statement, $1 is the name of the maint script, $2 the
+ # package version
+ case "$DPKG_MAINTSCRIPT_NAME" in
+ preinst)
+ if [ "$1" = "upgrade" ] && [ -n "$2" ] && \
+ dpkg --compare-versions "$2" le-nl "$LASTVERSION"; then
+ debug "preinst upgrade called"
+ prepare_convert_dir_to_symlink "$DIRECTORY"
+ fi
+ ;;
+ postinst)
+ if [ "$1" = "configure" ] && [ -n "$2" ] && \
+ dpkg --compare-versions "$2" le-nl "$LASTVERSION"; then
+ debug "postinst configure called"
+ finish_convert_dir_to_symlink "$DIRECTORY"
+ fi
+ ;;
+ postrm)
+ if [ "$1" = "failed-upgrade" ] && [ -n "$2" ] && \
+ dpkg --compare-versions "$2" le-nl "$LASTVERSION"; then
+ debug "postrm failed-upgrade called"
+ abort_convert_dir_to_symlink "$DIRECTORY"
+ fi
+ ;;
+ *)
+ debug "$0 convert_dir_to_symlink not required in "\
+ "$DPKG_MAINTSCRIPT_NAME"
+ ;;
+ esac
+ shift
+}
+
+prepare_convert_dir_to_symlink() {
+ local DIRECTORY="$1"
+
+ # Ensure ownership of the dir by the package ("dpkg -S $DIRECTORY"
+ # lists only one result before the dir name)
+ [ -d "$DIRECTORY" ] && \
+ [ "$(dpkg -S "$DIRECTORY" | awk '{printf NF-1}')" -eq 1 ] || \
+ error "the package has no exclusive ownership of the directory; "\
+ "please check permissions"
+
+ mv "$DIRECTORY" "$DIRECTORY".dpkg-bak
+}
+
+finish_convert_dir_to_symlink() {
+ local DIRECTORY="$1"
+
+ debug "Removing '$DIRECTORY.dpkg-bak'"
+ rm -rf "$DIRECTORY".dpkg-bak
+}
+
+abort_convert_dir_to_symlink() {
+ local DIRECTORY="$1"
+
+ unlink "$DIRECTORY"
+ mv "$DIRECTORY".dpkg-bak "$DIRECTORY"
+}
+
# Common functions
debug() {
if [ -n "$DPKG_DEBUG" ]; then
@@ -244,6 +321,9 @@ Commands:
postrm.
mv_conffile <old-conf> <new-conf> [<last-version> [<package>]]
Rename a conffile. Must be called in preinst, postinst and postrm.
+ convert_dir_to_symlink <directory> [<last-version>]
+ Convert a directory into a symbolic link. Must be called in preinst,
+ postinst, and postrm.
help
Display this usage information.
END
@@ -266,7 +346,7 @@ shift
case "$command" in
supports)
case "$1" in
- rm_conffile|mv_conffile)
+ rm_conffile|mv_conffile|convert_dir_to_symlink)
code=0
;;
*)
@@ -289,6 +369,9 @@ rm_conffile)
mv_conffile)
mv_conffile "$@"
;;
+convert_dir_to_symlink)
+ convert_dir_to_symlink "$@"
+ ;;
--help|help|-?|-h)
usage
;;
--
1.7.2.5
From d54d64d98e3a994df386649f34e594fdf1315031 Mon Sep 17 00:00:00 2001 From: Gianluca Ciccarelli (sturmer) <ciccarelli@disi.unitn.it> Date: Sat, 31 Dec 2011 18:33:32 +0100 Subject: [PATCH] Preliminary test for conversion dir->symlink. The maintainer of a package wants to transform a directory into a symlink when a new version of the package is released. This test ensures that the operations performed by dpkg-maintscript-helper.sh are done properly. --- t-convert-dir-to-symlink-upgrade/Makefile | 17 +++++++++++++++++ .../pkg-dir-to-symlink-0/DEBIAN/control | 7 +++++++ .../pkg-dir-to-symlink-0/DEBIAN/postrm | 17 +++++++++++++++++ .../pkg-dir-to-symlink-1/DEBIAN/control | 7 +++++++ .../pkg-dir-to-symlink-1/DEBIAN/postinst | 16 ++++++++++++++++ .../pkg-dir-to-symlink-1/DEBIAN/preinst | 6 ++++++ .../pkg-dir-to-symlink-1/test-dir | 1 + 7 files changed, 71 insertions(+), 0 deletions(-) create mode 100644 t-convert-dir-to-symlink-upgrade/Makefile create mode 100644 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/control create mode 100755 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/postrm create mode 100644 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/test-dir/test-file create mode 100644 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/control create mode 100755 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/postinst create mode 100755 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/preinst create mode 120000 t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/test-dir diff --git a/t-convert-dir-to-symlink-upgrade/Makefile b/t-convert-dir-to-symlink-upgrade/Makefile new file mode 100644 index 0000000..839cc7e --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/Makefile @@ -0,0 +1,17 @@ +TESTS_DEB := pkg-dir-to-symlink-0 pkg-dir-to-symlink-1 + +include ../Test.mk + +define VERIFY +test "`$(PKG_STATUS) pkg-dir-to-symlink`" = "install ok installed" +endef + +test-case: + $(DPKG_INSTALL) pkg-dir-to-symlink-0.deb + test -d /test-dir + $(DPKG_INSTALL) pkg-dir-to-symlink-1.deb + test -L /test-dir + $(VERIFY) + +test-clean: + $(DPKG_PURGE) pkg-dir-to-symlink diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/control b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/control new file mode 100644 index 0000000..5fa6012 --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/control @@ -0,0 +1,7 @@ +Package: pkg-dir-to-symlink +Version: 0 +Section: test +Priority: extra +Maintainer: Gianluca Ciccarelli <galiziacentrale@gmail.com> +Architecture: all +Description: test package - convert a directory into a symlink diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/postrm b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/postrm new file mode 100755 index 0000000..6bbc4a2 --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/DEBIAN/postrm @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e +case $1 in +upgrade) + echo "DEBUG: Called postrm upgrade" >&2 + ;; +failed-upgrade) + if dpkg-maintscript-helper supports convert_dir_to_symlink; then + export DPKG_DEBUG=1 + dpkg-maintscript-helper convert_dir_to_symlink "/test-dir" 0 -- "$@" + fi + ;; +*) + ;; +esac +exit 0 diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/test-dir/test-file b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-0/test-dir/test-file new file mode 100644 index 0000000..e69de29 diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/control b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/control new file mode 100644 index 0000000..0a94d8b --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/control @@ -0,0 +1,7 @@ +Package: pkg-dir-to-symlink +Version: 1 +Section: test +Priority: extra +Maintainer: Gianluca Ciccarelli <galiziacentrale@gmail.com> +Architecture: all +Description: test package - convert a directory into a symlink diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/postinst b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/postinst new file mode 100755 index 0000000..c3deb86 --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/postinst @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +case $1 in +configure) + #echo "Running postinst configure for version 1!" >&2 + if dpkg-maintscript-helper supports convert_dir_to_symlink; then + export DPKG_DEBUG=1 + dpkg-maintscript-helper convert_dir_to_symlink "/test-dir" 1 -- "$@" + fi + ;; +*) + ;; +esac +exit 0 diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/preinst b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/preinst new file mode 100755 index 0000000..0a28117 --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/DEBIAN/preinst @@ -0,0 +1,6 @@ +#!/bin/sh + +if dpkg-maintscript-helper supports convert_dir_to_symlink; then + export DPKG_DEBUG=1 + dpkg-maintscript-helper convert_dir_to_symlink "/test-dir" 0 -- "$@" +fi diff --git a/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/test-dir b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/test-dir new file mode 120000 index 0000000..2ce5a68 --- /dev/null +++ b/t-convert-dir-to-symlink-upgrade/pkg-dir-to-symlink-1/test-dir @@ -0,0 +1 @@ +new-test-dir/ \ No newline at end of file -- 1.7.2.5
Attachment:
signature.asc
Description: Digital signature