Skip to content

feat(LinuxTentacleE2E): Phase 12.M.L.A.3 — install-tentacle.sh v-prefix fallback E2E

Summary

Pins the .sh's two-URL retry contract: when --version 1.6.0 returns 404 from the plain URL form, the .sh MUST retry with the v-prefixed form (v1.6.0).

Real-world driver

GitHub Releases tag conventions vary: some operators publish only v1.6.0, some only 1.6.0, some both. The .sh's retry-with-v-prefix is the operator-friendly compatibility shim. Without coverage, regressions in this path break operators on legacy / private mirrors silently.

Production failure modes regression-pinned

  • .sh stops retrying on plain 404 → operator on legacy mirror sees install fail with "could not download 1.6.0" even though v1.6.0 IS published
  • .sh doesn't echo the retry attempt → operators have no log signal that the fallback was tried (vs "single shot fail")
  • .sh's exit-on-failure regression after retry → silently swallows the v-prefix 404 and exits 0 with no actual install

Test mechanism — surgical 404

ctx.Mirror.ConfigureNotFoundForPath($"/download/{version}/");

New ConfigureNotFoundForPath API does substring match on URL AbsolutePath. The leading slash in "/download/<version>/" makes it NOT match the v-prefixed sibling "/download/v<version>/" because the leading character of the version segment differs.

ConfigureNotFoundForVersion("1.6.0-vfallback") would have 404'd BOTH URLs (substring "1.6.0-vfallback" appears in both paths). The new API is the strict-substring escape hatch needed for path-disambiguating tests.

Assertions

Assertion Pins
exitCode == 0 Fallback succeeded
stdout contains "retrying with 'v<version>'" .sh line 236 retry log fires
stdout echoes the v-prefixed URL Operators verify which form worked
INSTALL_DIR/Squid.Tentacle exists Binary actually downloaded via v-prefix path
/usr/local/bin/squid-tentacle symlink exists Post-extract steps ran the same way as plain-URL happy path

Infrastructure additions

LocalReleaseMirror.ConfigureNotFoundForPath(string pathSubstring) — surgical 404 sibling of ConfigureNotFoundForVersion. Composes with StagePreBuiltArchive: configure 404 for the plain path, archive serves at the v-prefixed path.

Fidelity tier

🟢 High (Rule 12.4): real .sh + real bash + real curl + real LocalReleaseMirror responding 404 vs 200 per-URL. No mocks at OS-resource layer.

Test runs in LinuxTentacleHostStateCollection (serializes against upgrade + service-fixture tests on shared host state).

Expected runtime: ~5s.

Test plan

  • Linux E2E workflow runs (manual workflow_dispatch after merge)
  • A2u2_PlainVersion404FallsBackToVPrefix_InstallSucceeds passes within ~10s
  • No regression on existing 22 Linux E2E tests

🤖 Generated with Claude Code

Merge request reports

Loading