claude_desktop: fix Codex install failing on every boot (#2915)

install_codex_cli was non-functional: every boot logged "Verified Codex
<version> installation failed; Codex is unavailable this boot" and no binary
was ever installed.

The download, its SHA-256 verification against the GitHub-published digest, and
the extraction all succeeded. The chain broke at the final step, which validates
the candidate binary by running --version as the abc runtime user: mktemp -d
creates its directory 0700 root:root, and abc cannot traverse a root-only
directory, so exec failed with "unable to exec: Permission denied" (exit 126)
before the binary could be moved into place. Because the whole chain is a single
&&-list, that surfaced only as the generic failure warning.

Fixed by making the staging directory traversable immediately after mktemp.
Nothing secret is staged there -- the public release archive and the extracted
binary, both world-readable upstream artifacts -- and the existing cleanup()
trap still removes the directory on exit. The validation deliberately keeps
running as abc rather than root, so the binary is exercised as the identity that
will actually run it.

Reproduced and verified on a live add-on container: the same probe goes from
exit 126 to success once the mode is widened, and the fixed script now completes
the install (codex-real 0.145.0 in place, wrapper on PATH, managed config
written, no staging leftovers).

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Alexandre
2026-07-27 22:09:21 +02:00
committed by GitHub
parent 0ead28a7bf
commit f10a566b4c
3 changed files with 12 additions and 1 deletions

View File

@@ -1,4 +1,8 @@
## 1.36.1 (27-07-2026)
- Fix the Codex CLI install failing on every boot with `Verified Codex <version> installation failed; Codex is unavailable this boot`, leaving `install_codex_cli` permanently non-functional. The download, its SHA-256 verification, and the extraction all succeeded; the chain broke at the final step, which validates the candidate binary by running `--version` as the `abc` runtime user. `mktemp -d` creates its directory `0700 root:root`, and `abc` cannot traverse a root-only directory, so executing the staged binary failed with `unable to exec: Permission denied` (exit 126) before it could be moved into place. Reproduced and fixed by making the staging directory traversable (`chmod 0755`) immediately after `mktemp`; verified on a live add-on container, where the same probe goes from exit 126 to success once the mode is widened. Nothing secret is staged there — the public release archive and the extracted binary, both world-readable upstream artifacts — and the existing `cleanup()` trap still removes the directory on exit. The validation deliberately keeps running as `abc` rather than root, so the binary is exercised as the identity that will actually run it.
## 1.36 (27-07-2026)
- Add optional OpenAI Codex CLI support, so a Claude session in this add-on can delegate work to ChatGPT Codex. Three parts: an `install_codex_cli` switch, a browserless way to activate a ChatGPT subscription on it, and an MCP registration that makes Codex callable as a tool from Claude.

View File

@@ -122,5 +122,5 @@ slug: claude_desktop
tmpfs: true
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "1.36"
version: "1.36.1"
video: true

View File

@@ -60,6 +60,13 @@ fi
# follows upstream updates without pinning a version, while downloading the large asset only when
# the installed version changes. A metadata outage never replaces or removes a working binary.
codex_tmp="$(mktemp -d -p "$CODEX_ROOT")"
# mktemp always creates 0700 root:root here, but the candidate binary is validated by running it
# as the abc runtime user, which cannot traverse a root-only directory — that made every install
# fail at the --version step with "unable to exec: Permission denied" (exit 126) and report
# "Codex is unavailable this boot". Make the staging directory traversable. Nothing secret is
# staged here: it holds the public release archive and the extracted binary, both of which are
# world-readable upstream artifacts, and cleanup() removes the directory on exit.
chmod 0755 "$codex_tmp"
cleanup() {
rm -rf "$codex_tmp"
}