Skip to content

fix: launch polkit agent from libexecdir, not bindir - #5

Open
perlowja wants to merge 1 commit into
singularityos-lab:mainfrom
perlowja:fix/session-libexec-path
Open

fix: launch polkit agent from libexecdir, not bindir#5
perlowja wants to merge 1 commit into
singularityos-lab:mainfrom
perlowja:fix/session-libexec-path

Conversation

@perlowja

@perlowja perlowja commented Aug 9, 2026

Copy link
Copy Markdown

Summary

A clean meson install produces a session that starts with no polkit agent, so privilege prompts never appear.

singularity-polkit-agent is installed to libexecdir:

https://github.com/singularityos-lab/singularity-polkit-agent/blob/856cf43/meson.build#L45

but the session launcher execs it out of bindir:

nohup "$BIN/singularity-polkit-agent" >> "$_STATE/polkit.log" 2>&1 &

where BIN="$(dirname "$(readlink -f "$0")")". On --prefix=/usr that resolves to /usr/bin while the binary is in /usr/libexec, so the launch fails with exit 127 and only polkit.log records it. Same on any custom prefix — I hit it on /opt/singularity.

This is masked today because scripts/deploy-to-host.sh copies the libexec helpers into bin, flattening the layout. So the developer-deploy path works while a packaged/distro install does not.

It also contradicts what the README already promises:

The session does not hardcode the prefix: binaries are resolved next to the running executable and via PATH.

Reproduce

$ meson setup build --prefix=/usr && meson install -C build --destdir /tmp/stage
$ ls /tmp/stage/usr/libexec/singularity-polkit-agent   # present
$ ls /tmp/stage/usr/bin/singularity-polkit-agent       # No such file or directory
$ grep singularity-polkit-agent /tmp/stage/usr/bin/singularity-desktop-session
nohup "$BIN/singularity-polkit-agent" >> "$_STATE/polkit.log" 2>&1 &

Fix

Resolve the helper at runtime against the prefix the script already derives — prefer libexec, fall back to bin, then PATH. The bin fallback is what keeps the flattened deploy-to-host.sh layout working unchanged.

The same fix is applied to the launcher that scripts/install-session.sh generates for the per-user ~/.local/singularity install, which carried the identical assumption.

Scope

Only the polkit agent. Deliberately unchanged:

  • singularity-splash — installed with install: true and no install_dir override, so it really is in bindir; "$BIN/" is correct.
  • ush-broker — not in the meson graph at all, and already [ -x ]-guarded.
  • singularity-polkit-auth-helper — also in libexecdir, but agent.vala resolves it relative to its own executable (GLib.Path.get_dirname(exe)), so agent and helper stay co-located and it is already correct.

No meson install_dir changes, no build-graph changes.

Alternative considered

Turning the session scripts into configure_file templates and substituting @libexecdir@ at build time. That works too, but it touches the meson graph and converts two shipped scripts into .in templates for no extra robustness — the runtime resolver handles both layouts. Happy to switch to that if you'd prefer build-time substitution.

Validation

Resolver exercised against every install layout:

Layout Resolves to
meson install (libexec only) libexec/singularity-polkit-agent
both present libexec/… (libexec wins)
deploy-to-host.sh flattened (bin only) bin/singularity-polkit-agent
on PATH only the PATH hit
neither libexec/… (unchanged failure, but logged with a sensible path)

The launcher generated by install-session.sh was rendered and checked — the heredoc escaping survives generation and bash -n passes on both the generated launcher and the two modified scripts.

Compatibility

deploy-to-host.sh layout unchanged (falls back to $BIN); --prefix=/usr now finds the agent in /usr/libexec; custom prefixes work via prefix-relative resolution.

Rollback

Revert the single commit. No data, schema, or build-system migration involved.

meson installs singularity-polkit-agent and singularity-polkit-auth-helper
with install_dir: get_option('libexecdir'), but the session launcher execs
"$BIN/singularity-polkit-agent", where BIN is the launcher's own directory
(bindir). On any prefix where libexecdir != bindir - the normal case for
--prefix=/usr - a clean meson install produces a session that starts with no
polkit agent: privilege prompts never appear and polkit.log records exit 127.

scripts/deploy-to-host.sh masks this by copying the libexec helpers into bin,
so the developer-deploy path works while a packaged install does not.

Resolve the helper at runtime relative to the prefix the script already
derives: prefer libexec, fall back to bin (keeping the flattened
deploy-to-host layout working), then to PATH. This restores the behaviour
README.md already documents - that binaries are resolved relative to the
running executable rather than a hardcoded prefix.

singularity-splash and ush-broker are unchanged: splash is installed to
bindir (no install_dir override) and ush-broker is not part of the meson
graph, so "$BIN/" is correct for both.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f62ce18eb4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

PREFIX="$(dirname "$BIN")"
LIB="$PREFIX/lib"
SHARE="$PREFIX/share"
LIBEXEC="$PREFIX/libexec"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve the configured libexec directory

When the polkit agent is packaged with a nondefault libexecdir such as $prefix/lib/singularity, this hard-coded $PREFIX/libexec path does not match the directory selected by the agent's Meson get_option('libexecdir'). Because private helper directories normally are not on PATH, both subsequent fallbacks also miss the binary and privilege prompts remain unavailable for that valid installation layout. Substitute the configured libexec directory at build time or otherwise share the actual install path rather than assuming the default.

Useful? React with 👍 / 👎.

@mirkobrombin

Copy link
Copy Markdown
Member

The bug is valid, but PREFIX/libexec ignores a custom Meson libexecdir. Please inject the actual configured path instead of assuming the default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants