Discussion:
Advice for directory to symlink transition
(too old to reply)
Timo Röhling
2025-02-20 09:10:01 UTC
Permalink
Hello,

I have run into an unexpected quirk of dpkg (I think) and would like
to solicit some advice on how to handle it.

For better cross building/multi-arch support, I recently moved a
bunch of files from python3-numpy to python3-numpy-dev. More
precisely, I moved

/usr/lib/python3/dist-packages/numpy/_core/include
/usr/lib/python3/dist-packages/numpy/_core/lib
/usr/lib/python3/dist-packages/numpy/random/lib
/usr/lib/python3/dist-packages/numpy/f2py/src

to an arch-dependent location and replaced them with symlinks. The
symlinks are intended to retain directory layout compatibility with
upstream, so anyone how does not care about cross building is not
inconvenienced by my create shuffling.

This worked great for the former two directories, but the latter two
are left as empty real directories, not symlinks, after an upgrade.

I assume it is because the _core directory is new in NumPy 2, so
dpkg can just create the symlinks at unpack time. The latter two
directories need to be transitioned from a real directory in NumPy 1
to a symlink during the package upgrade. Apparently this step fails,
leaving an empty directory instead.

The question is, how do I fix this? I could add some code to
postinst to check if there is an empty directory where a symlink
should be. Is this a reasonable approach?


Cheers
Timo
--
⢀⣎⠟⠻⢶⣊⠀ ╭────────────────────────────────────────────────────╮
⣟⠁⢠⠒⠀⣿⡁ │ Timo Röhling │
⢿⡄⠘⠷⠚⠋⠀ │ 9B03 EBB9 8300 DF97 C2B1 23BF CC8C 6BDD 1403 F4CA │
⠈⠳⣄⠀⠀⠀⠀ ╰────────────────────────────────────────────────────╯
Andrey Rakhmatullin
2025-02-20 09:30:01 UTC
Permalink
Post by Timo Röhling
Hello,
I have run into an unexpected quirk of dpkg (I think) and would like to
solicit some advice on how to handle it.
For better cross building/multi-arch support, I recently moved a bunch of
files from python3-numpy to python3-numpy-dev. More precisely, I moved
/usr/lib/python3/dist-packages/numpy/_core/include
/usr/lib/python3/dist-packages/numpy/_core/lib
/usr/lib/python3/dist-packages/numpy/random/lib
/usr/lib/python3/dist-packages/numpy/f2py/src
to an arch-dependent location and replaced them with symlinks. The symlinks
are intended to retain directory layout compatibility with upstream, so
anyone how does not care about cross building is not inconvenienced by my
create shuffling.
This worked great for the former two directories, but the latter two are
left as empty real directories, not symlinks, after an upgrade.
I assume it is because the _core directory is new in NumPy 2, so dpkg can
just create the symlinks at unpack time. The latter two directories need to
be transitioned from a real directory in NumPy 1 to a symlink during the
package upgrade. Apparently this step fails, leaving an empty directory
instead.
The question is, how do I fix this? I could add some code to postinst to
check if there is an empty directory where a symlink should be. Is this a
reasonable approach?
dpkg-maintscript-helper dir_to_symlink
--
WBR, wRAR
Simon Richter
2025-02-20 09:30:01 UTC
Permalink
Hi,
Post by Timo Röhling
I assume it is because the _core directory is new in NumPy 2, so dpkg
can just create the symlinks at unpack time. The latter two directories
need to be transitioned from a real directory in NumPy 1 to a symlink
during the package upgrade. Apparently this step fails, leaving an empty
directory instead.
The way I understood it, dpkg does not track the type of files, only
ownership. Multiple owners are permitted, if multiple packages contain
the same path -- conflicts are checked and resolved only at unpack time.

So what happens is that the symlink is unpacked, and the resolution rule
decides in favour of the directory, but the new package also shares in
the ownership of this path, so it is never removed.

Guillem is working on a branch of dpkg that tracks types and other
metadata as well, which would probably detect and report this as a file
conflict. Not sure if the "directory wins against symlink without
causing an error" resolution rule would remain here.

I think this can be fixed only with a Conflicts to make sure packages
that provide the old path as a directory are removed or upgraded before
the package providing the symlink is unpacked.

I *think* (but I haven't tested it) that if the package unpacking the
symlink is also the last remaining owner of the directory and the
directory is empty, then the unpack should succeed and the symlink
installed.
Post by Timo Röhling
The question is, how do I fix this? I could add some code to postinst to
check if there is an empty directory where a symlink should be. Is this
a reasonable approach?
I think the preinst is a better place -- it is sequenced closer to
unpacking, and it has a chance of aborting the unpack if the directory
is not empty (so you still need the Conflicts against the older packages).

Simon

Loading...