fix(entrypoint): locate Claude binary by path, not command -v (Claude 2.1+ native install) #56
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Patch fix for the entrypoint's Claude-install path.
Claude Code 2.1+ ships as a native binary, dropped at
~/.local/bin/claudebyinstall.sh— but the installer no longer adds that dir to$PATH(it just prints a manual setup hint). The entrypoint'scommand -v claudelookup then returned empty and aborted withclaude not on PATH after install — installer layout changed?even though the install had succeeded.Fix: check the known native-install paths (
/root/.local/bin/claude,$HOME/.local/bin/claude) directly before falling back to a PATH-widenedcommand -v. The fallback preserves compatibility with older installer layouts.Surfaced by
Fresh per-project volume + android-flutter image — the volume override feature itself worked, install succeeded ("Claude Code 2.1.150 successfully installed"), but the next entrypoint step bailed.
Test plan
sccinvideoguard-app→ entrypoint should find the just-installed binary at/root/.local/bin/claude, copy it to the volume, and exec successfullyVersion
scc.sh.versionbumped 1.4.0 → 1.4.1 (patch).Until now scc only installed Claude once, then served the cached binary from the scc-claude volume forever — no version check, no nudge when Anthropic shipped a fix. The only refresh path was the user knowing to set SCC_FORCE_REINSTALL=1. This adds a once-per-day check mirroring the existing scc.sh self-update flow: scc.sh GETs @anthropic-ai/claude-code/latest from npm (~1 KB, 1 s timeout), compares it to the version cached in the volume, and warns + prompts when upstream is newer. Decisions are remembered per upstream version so users don't get re-prompted for the same release. Plumbing: - scc-entrypoint.sh writes `claude --version` into both /opt/scc-claude/version (canonical, lives with the binary) and /scc-meta/claude_version (bind-mounted from ~/.scc/volume-meta/, so the host launcher can read it without a docker-exec roundtrip). Re-captured after every reinstall; idempotent on the fast path. - scc.sh adds the /scc-meta mount alongside the existing volume mount. Older launchers don't mount /scc-meta; the entrypoint silently skips the mirror in that case, so a new image works with an old launcher. - New check_for_claude_update() in scc.sh: 24h-cached fetch, semver comparison via sort -V, per-version ack file at ~/.scc/claude-update-check. Fail-closed: non-TTY runs note and continue, never auto-update. Three new env vars: - SCC_AUTO_UPDATE_CLAUDE=1 skip the prompt, auto-set SCC_FORCE_REINSTALL=1 on detection. - SCC_NO_CLAUDE_UPDATE_CHECK=1 skip the daily probe entirely. - (existing SCC_FORCE_REINSTALL=1 still works; suppresses the check when set, since reinstall is already happening.) Tests: - tests/feature/helpers.bash exports SCC_NO_CLAUDE_UPDATE_CHECK=1 alongside SCC_NO_UPDATE_CHECK=1 so the daily curl never fires under test. All 56 existing bats tests pass; no new tests added (the new function is HTTP-bound and matches the established pattern). README "Claude binary handling" section gains a "Daily Claude update check" subsection documenting the prompt, the env vars, and where the metadata lives. scc.sh.version bumped 1.1.2 → 1.2.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Adds a third configurable field next to image and claude_args: a docker --platform pin. Use case: running the new fedora/android-flutter image (amd64-only, since Google ships no arm64 Android SDK) on Apple Silicon under Rosetta-for-Linux. Without --platform, docker warns about arch mismatch and Rosetta's behavior is implicit; with --platform=linux/amd64 the launcher tells docker exactly what to pull + run. Resolution order matches the existing image plumbing: SCC_PLATFORM env > .scc/config.ini platform= > (omit, docker chooses) Wired through both `docker pull` and `docker run` via a shared platform_args array. The status line prints "(--platform linux/amd64)" when set so you can tell at a glance whether emulation is in play. Validation is minimal — `^[a-z0-9]+/[a-z0-9/.-]+$` catches the obvious typo (`amd64` without the `linux/` prefix) but otherwise trusts docker to error on garbage. Anything that looks like os/arch passes through. Trust gate extended: - require_project_trust() takes a 4th argument (platform). - Trust file format gains a `platform=` line. Old trust files without the line keep working because ini_get returns "" for missing keys and ""="" compares equal when the project also doesn't pin platform. Re-prompt only fires when a project NEWLY pins a platform that wasn't in the old trust file. - SCC_PLATFORM env is user-explicit and does NOT trigger the trust prompt, matching the SCC_IMAGE behavior. Tests: 3 new bats cases in project_config.bats: - platform = … in config.ini reaches docker run argv as `--platform linux/amd64` - SCC_PLATFORM env overrides the config.ini value - Malformed platform (`amd64`, no `linux/` prefix) rejected with rc=2 All 59/59 tests pass (was 56 before). README's "Schema" + "Trust prompt" sections updated to document the new field, the resolution order, and the bypass env vars. scc.sh.version bumped 1.2.0 → 1.3.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>The named volume `scc-claude` is shared across all image flavors — first image to install Claude wins, every subsequent flavor exec's that same binary. When two flavors have substantially different runtime layouts (e.g. default Fedora-with-Node vs android-flutter without it, or amd64 under Rosetta vs native arm64), the cached binary from flavor A can fail to exec under flavor B's environment. Add a project-pinnable override so each project can opt into its own Claude volume, matching the existing image= / claude_args= / platform= pattern: [scc] image = forge.stacktop.network/openstacktop/scc:android-flutter-fedora-latest volume = scc-claude-android-flutter Resolution: SCC_CLAUDE_VOLUME env > .scc/config.ini volume= > default "scc-claude". CLAUDE_VOLUME loses `readonly` so it can be reassigned after project-config parsing; the three downstream usages (status label, state label, bind mount) are unchanged. Not part of the trust gate: a project pointing at a different cached binary is no greater risk than image= itself (which already gates), and the existing SCC_CLAUDE_VOLUME env path doesn't gate either — adding it to the trust hash now would be asymmetric. Existing trust files keep working unchanged. Tests: - volume = … in config.ini → docker run argv contains `my-project-claude:/opt/scc-claude` and NOT `scc-claude:/opt/scc-claude` - SCC_CLAUDE_VOLUME env overrides the config.ini value All 61/61 bats tests pass (was 59 before). README schema + resolution-priority table updated; help text mentions the new field and the env precedence. scc.sh.version bumped 1.3.0 → 1.4.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Claude Code 2.1+ ships as a single native binary and the install.sh drops it at ~/.local/bin/claude WITHOUT adding that directory to PATH (the installer just prints "echo 'export PATH=...' >> your shell config" as a manual setup hint). The entrypoint was using `command -v claude` to find what the installer just dropped, which returned empty and aborted the install with "claude not on PATH after install — installer layout changed?" — even though the binary was successfully written. Fix: check the known native-install locations directly (/root/.local/bin/claude, $HOME/.local/bin/claude) before falling back to a PATH-widened `command -v` for older or relocated layouts. The fallback keeps backward compatibility with the previous installer that did expose claude on PATH; the explicit-path checks handle the 2.1+ native-install flow. Surfaced by: - fresh `scc-claude-android-flutter` volume + `scc` against the android-flutter image. Install succeeded ("Claude Code successfully installed! Version: 2.1.150 Location: ~/.local/bin/claude") but the next entrypoint step bailed out with the missing-on-PATH error. scc.sh.version bumped 1.4.0 → 1.4.1; 61/61 bats tests still pass (the entrypoint runs inside the container, not on the bats host, so coverage is unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>