4

I have a debian package that installs a file to /usr/local/java/jre/lib/ext, where /usr/local/java is a symlink to where the jvm is actually installed, in this case /usr/lib/jvm/java-6-sun.

The new version of this package installs the jar elsewhere. The problem is that installing the new version causes dpkg to try and tidy up after itself, ending up deleting the /usr/local/java symlink.

This is a deeply undesirable state to be in, even temporarily.

I haven't been able to find the flag for dpkg that will persuade it to leave the symlink in place, and it does not appear to be possible to set the immutable bit on symlinks.

Here are the changes to the debian packaging config:

diff --git a/debian/dirs b/debian/dirs
--- a/debian/dirs
+++ b/debian/dirs
@@ -1 +1 @@
-usr/local/java/jre/lib/ext
+usr/share/java
diff --git a/debian/rules b/debian/rules
--- a/debian/rules
+++ b/debian/rules
@@ -30,7 +30,7 @@ install: build

        # Add here commands to install the package into debian/tmp.
        # $(MAKE) pure_install
-       cp thejar.jar $(TMP)/usr/local/java/jre/lib/ext
+       cp thejar.jar $(TMP)/usr/share/java

 # Build architecture-independent files here.
 binary-indep: build install

I imagine that leaving usr/local/java/jre/lib/ext in dirs would have the desired effect, but this is just kicking the problem down the road - I'd rather that this package not be responsible for maintaining the symlink.

So: what are my options?

ryanm
  • 141
  • 2

3 Answers3

2

Symlinks are just files which the package installs, and so the normal behaviour applies. These are the options I can think of:

  • Mark the symlink as a config file. I don't know whether this is supported, but if it is, the symlink should only be removed if the package is purged.
  • Don't install the symlink as a file, but rather create it in the postinst script.
  • Just create the symlink manually and not as part of the package at all.

Note that whatever the symlink points to is going to be removed when the old version is uninstalled, so I don't see how this make it any better.

mgorven
  • 30,615
  • 7
  • 79
  • 122
  • That's the thing though - the symlink *was* created manually. – ryanm Aug 14 '12 at 07:39
  • @ryanm Then I don't understand what this has to do with dpkg. – mgorven Aug 14 '12 at 16:56
  • Because dpkg removes the symlink. Here's the output from installing the new version: `Unpacking replacement thepackage ... dpkg: warning: unable to delete old directory '/usr/local/java/jre/lib/ext': Directory not empty dpkg: warning: unable to delete old directory '/usr/local/java/jre/lib': Directory not empty dpkg: warning: unable to delete old directory '/usr/local/java/jre': Directory not empty Setting up thepackage (theversion) ...` The advance of deletion attempts towards the symlink is fairly ominous, no? – ryanm Aug 15 '12 at 14:03
1

I ran into this issue when I try to bootstrap Debian-based distro.

I have /bin symlinked to usr/bin. After installing dash, my /bin symlink was replaced with a directory.

The --keep-directory-symlink flag helped me to resolve this issue. For example:

(cd /tmp; apt-get download dash)
dpkg-deb --fsys-tarfile /tmp/dash_*.deb | tar -x --keep-directory-symlink -C /chroot
youfu
  • 111
  • 2
0

If you have dpkg > 1.15.8, try populating /etc/dpkg/dpkg.cfg.d/excludes with:

path-exclude=/usr/local/java/jre/lib/ext

Source: Save disk space by excluding useless files with dpkg | Raphaël Hertzog.

For Arch users, use NoExtract= in /etc/pacman.conf and exclude the leading slash from your path. See ArchWiki or man pacman.conf.