appview: render the install scripts from config instead of shipping ATCR's

seamark.dev's /install and /settings/devices told users to pipe
seamark.dev/static/install.sh into bash. That file was the unmodified ATCR
script: it announced itself as the "ATCR Credential Helper Installer",
installed docker-credential-atcr, and finished by telling the user to configure
credHelpers for atcr.io, the wrong registry for that deployment. Anyone
following the documented setup ended up pointed at another service. The
templates hardcoded docker-credential-atcr, "atcr" and ~/.atcr/device.json
alongside a correctly themed {{ .RegistryURL }}.

The scripts are now rendered from config by a handler, rather than forked per
brand. A theme overlay was the alternative and was worse: it needed a full copy
of both install.sh and install.ps1 per brand, four scripts to keep in sync, and
the operator asked for these values to come from config.

credential_helper.name is the single knob. Docker resolves a credHelpers value
x by exec'ing docker-credential-x, so the credHelpers value, the binary suffix
and the config directory are genuinely one word, not three that can drift. It
is validated against a strict pattern because it is interpolated into a shell
script.

install.sh renders byte-identical to the deleted static file under the atcr
default, so existing installs are unaffected. install.ps1 differs by one line,
where a stale usage comment named a path the script is not served at.

Two behaviour changes worth noting: these two URLs drop from a one-year
Cache-Control to five minutes, since the body now depends on deployment config;
and credential_helper.tangled_repo becomes a real overridable default. It was
previously assigned over unconditionally and read by nothing, while the shipped
script used a different URL form.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDqoCE1j3njokkZ9b1C5n9
This commit is contained in:
Evan Jarrett
2026-09-02 21:38:10 -05:00
co-authored by Claude Opus 5
parent 2743445e65
commit 9d8bd513da
18 changed files with 805 additions and 44 deletions
+13 -6
View File
@@ -95,11 +95,17 @@ The artifacts become downloadable from the Tangled repo's tag download path
### 2. Install Scripts
Both scripts are served by the AppView from its static directory
(`pkg/appview/public/static/`) at `/static/install.sh` and
`/static/install.ps1`. They resolve the latest version by following the
`{repo}/tags/latest` redirect chain on Tangled, then download the matching
archive from the tag download path.
Both scripts are rendered by the AppView from templates in
`pkg/appview/installscript/templates/` and served at `/static/install.sh` and
`/static/install.ps1` (public, no auth: `curl | bash` runs before the user has
credentials). They are rendered rather than served as static files so the
helper binary name, the Docker `credHelpers` key/value and the config
directory follow the deployment's own branding: `credential_helper.name` in
the AppView config picks the brand (`atcr` by default, `seamark` on
seamark.dev), and the `credHelpers` key is the deployment's primary registry
domain. They resolve the latest version by following the `{repo}/tags/latest`
redirect chain on Tangled, then download the matching archive from the tag
download path.
**Linux/macOS:** `install.sh`
- Detects OS and architecture
@@ -110,7 +116,8 @@ archive from the tag download path.
**Windows:** `install.ps1`
- Detects architecture
- Resolves the latest tag from Tangled and downloads the archive
- Installs to `%ProgramFiles%\ATCR` (override with `ATCR_INSTALL_DIR`)
- Installs to `%ProgramFiles%\ATCR` (override with `ATCR_INSTALL_DIR`; the
brand name and env prefix follow `credential_helper.name`)
- Adds to system PATH (requires Administrator to modify the machine PATH)
- Uses the bundled `tar.exe` to extract the `.tar.gz`