fix(lifecycle): remove usrmerge-breaking symlinks
Metadata
Current evaluation
Merged PR #498 (commit 05489c80) fixes Ubuntu 24.04 Python-plugin rocks by removing the primed lib64 -> lib symlink that broke the base usrmerge layout.
Resolution: closed resolved
Reason: The approved PR was merged as commit 05489c80. Its post-prime callback conditionally removes the Python venv's lib64 -> lib symlink for ubuntu@24.04, preserving the base layer's lib64 -> usr/lib64 mapping.
Evaluated by: mr-cal-bot
No scores available.
Issue body
This commit adds code in the post-prime callback to handle the specific combination of "ubuntu@24.04" base + "python" plugin. The handling detects and removes a primed "lib64" symlink to "lib", which can't stay because it breaks the "lib64" symlink to "usr/lib64" on the base layer, making the rock unusable.
Read on for more context on *why* this started happening now:
The Python plugin works by creating a virtual environment on the part's install dir (which eventually gets primed). By default, the creation of the virtual environment will setup a directory structure like this:
```
<install-dir>
|- bin/
|- lib/
|- ...
|- lib64 -> lib
```
That is, the creation itself places a "lib64" symlink pointing to "lib". If this gets primed as-is, this symlink will override the base layer's own symlink of "lib64" to "usr/lib64", which renders the rock unusable because all binaries expect the loader to exist in "lib64/ld-linux-x86-64.so.2", when the loader's "true" location is in "usr/lib64/ld-linux-x86-64.so.2".
This wasn't an issue prior to 24.04 because of the way we extract stage packages: since the base layer doesn't include the Python interpreter, rockcraft projects need to provision Python themselves, typically via the "python3-venv" stage-package. This causes the inclusion of the package's dependencies, ultimately pulling in "libc6".
On Ubuntu versions older than 24.04, the "lib64" package includes the "ld-linux-x86-64.so.2" loader as "/lib64/ld-linux-x86-64.so.2". This means that by the time the virtual environment creation starts the install dir already has a "lib64" directory, which I guess the venv just accepts and leaves alone. The end result is that "lib64" is not a symlink to "lib", and the usrmerge handling code that we already have when packing takes care of packing the files in "lib64" as inside "usr/lib64". The install dir looks like this:
```
<install-dir>
|- bin/
|- lib/
|- ...
|- lib64/
|- ld-linux-x86-64.so.2
```
However, 24.04 changed the usrmerge handling and now the libc6 package includes that loader as "/usr/lib64/ld-linux-x86-64.so.2", which means that the "lib64" directory doesn't exist anymore when the venv is created. Thus, "lib64" is created as a symlink to "lib" and breaks the base layer:
```
<install-dir>
|- bin/
|- lib/
|- ...
|- lib64 -> lib
|- usr
|- lib64
|- ld-linux-x86-64.so.2
```
Package listings:
Jammy: https://packages.ubuntu.com/jammy/amd64/libc6/filelist
Noble: https://packages.ubuntu.com/noble/amd64/libc6/filelist
-----
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Merged PR #498 (commit 05489c80) fixes Ubuntu 24.04 Python-plugin rocks by removing the primed lib64 -> lib symlink that broke the base usrmerge layout. | |
| stealth/space-bunny-alpha | — | closed resolved | Merged PR #498 (commit 05489c80) removes the Python venv lib64 -> lib symlink during post-prime on Ubuntu 24.04, preserving the base layer's usrmerge layout. | |
| stealth/space-bunny-alpha | — | closed resolved | Merged a fix for Ubuntu 24.04 Python venvs: post-prime cleanup removes lib64 -> lib so it cannot override the base layer's usrmerge symlink. | |
| qwen/qwen3.6-35b-a3b | — | — | Merged. Fixes a Ubuntu 24.04 usrmerge issue where Python venv creation overrides the base lib64 symlink. A post-prime callback now removes the conflicting symlink. Approved by two reviewers and passed CI. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Merged a fix stripping a lib64-to-lib symlink from Python venvs. It overrode Ubuntu 24.04's usrmerge layout, breaking rock builds. A post-prime callback now detects and removes the conflicting symlink before packaging. |
Update history
No update history recorded yet.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #246 usrmerge issue when using the Python plugin without provisioning Python | rockcraft | closed | Fixed by merged PR #498, which removes the Python plugin's primed lib64 symlink that broke the Ubuntu 24.04 usrmerge layout. | |
| #154 first pass at handling usrmerge | rockcraft | merged | Merged PR #154 (commit 607d934f, "oci: handle symlinks in base layer (usrmerge)"). add_layer() now takes the extracted base, so files primed under /lib or /bin are written to the usrmerge symlink target (/usr/lib, /usr/bin) instead of breaking Ubuntu-based rocks; lifecycle passes the base forward. | |
| #6425 fix(plugins/kernel): handle usrmerge | snapcraft | closed | Merged as be405aad6 via #6425, updating kernel-plugin paths to support usrmerged Linux packages and fix core26 build failures. |