v0.63.0: B3+B2 fresh-install fixes — TokenStore reload-on-miss + guesthook snippets dir
B3: Lookup re-reads the append-only store once on a miss (cross-process coherence with the one-shot provisioner; size short-circuit bounds the cost; behind the TokenAuthority seam). B2: fenced mkdir -p /var/lib/vz/snippets before the snippet install + the one narrow sudoers grant. Both red-proofed; drill findings DRILL-day0-cleanroom-2026-07-03 B3/B2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -53,6 +53,13 @@ func InstallSnippet(ctx context.Context, runner proxmox.Runner) error {
|
||||
if err := f.Close(); err != nil {
|
||||
return fmt.Errorf("guesthook: close temp snippet: %w", err)
|
||||
}
|
||||
// Ensure the snippets dir exists FIRST (B2, DRILL-day0-cleanroom-2026-07-03): a fresh PVE has
|
||||
// no /var/lib/vz/snippets, and `install` (without -D) won't create the parent — the whole
|
||||
// hook install silently failed on a freshly-bootstrapped box. Fenced root op like the install
|
||||
// itself; idempotent.
|
||||
if _, stderr, err := runner.Run(ctx, "mkdir", "-p", SnippetDir); err != nil {
|
||||
return fmt.Errorf("guesthook: ensure snippets dir %s: %w: %s", SnippetDir, err, string(stderr))
|
||||
}
|
||||
if _, stderr, err := runner.Run(ctx, "install", "-m", "0755", "--", tmp, SnippetPath); err != nil {
|
||||
return fmt.Errorf("guesthook: install snippet to %s: %w: %s", SnippetPath, err, string(stderr))
|
||||
}
|
||||
|
||||
@@ -41,16 +41,22 @@ func TestInstallSnippet_RandomTempName(t *testing.T) {
|
||||
if err := InstallSnippet(context.Background(), r); err != nil {
|
||||
t.Fatalf("InstallSnippet #2: %v", err)
|
||||
}
|
||||
if len(r.calls) != 2 {
|
||||
t.Fatalf("expected 2 install calls, got %d: %v", len(r.calls), r.calls)
|
||||
var installs [][]string
|
||||
for _, call := range r.calls {
|
||||
if call[0] == "install" {
|
||||
installs = append(installs, call)
|
||||
}
|
||||
}
|
||||
if len(installs) != 2 {
|
||||
t.Fatalf("expected 2 install calls, got %d: %v", len(installs), r.calls)
|
||||
}
|
||||
|
||||
randomName := regexp.MustCompile(`felhom-guest-hook-[^/\\]+\.sh$`)
|
||||
fixedName := regexp.MustCompile(`felhom-guest-hook\.sh$`)
|
||||
var srcs []string
|
||||
for i, call := range r.calls {
|
||||
for i, call := range installs {
|
||||
// install -m 0755 -- <src> <dest>
|
||||
if call[0] != "install" || len(call) != 6 {
|
||||
if len(call) != 6 {
|
||||
t.Fatalf("call %d: unexpected vector %v", i, call)
|
||||
}
|
||||
src, dest := call[4], call[5]
|
||||
@@ -81,3 +87,42 @@ func TestInstallSnippet_RandomTempName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// B2 Scenario D (DRILL-day0-cleanroom-2026-07-03): on a fresh PVE, /var/lib/vz/snippets does not
|
||||
// exist and `install` (no -D) cannot create it — the drill saw
|
||||
// `install: cannot create regular file … No such file or directory` and the guest silently got no
|
||||
// pre-start self-heal hook. InstallSnippet must therefore issue a `mkdir -p <SnippetDir>` fenced op
|
||||
// BEFORE the `install` op. Pre-fix wrong outcome: no mkdir call at all — only the doomed install.
|
||||
func TestInstallSnippet_EnsuresSnippetsDirFirst(t *testing.T) {
|
||||
r := &recordingRunner{}
|
||||
if err := InstallSnippet(context.Background(), r); err != nil {
|
||||
t.Fatalf("InstallSnippet: %v", err)
|
||||
}
|
||||
|
||||
mkdirIdx, installIdx := -1, -1
|
||||
for i, call := range r.calls {
|
||||
switch call[0] {
|
||||
case "mkdir":
|
||||
if mkdirIdx == -1 {
|
||||
mkdirIdx = i
|
||||
want := []string{"mkdir", "-p", SnippetDir}
|
||||
if len(call) != 3 || call[1] != want[1] || call[2] != want[2] {
|
||||
t.Errorf("mkdir vector = %v, want %v (the sudoers fence matches exactly this argv)", call, want)
|
||||
}
|
||||
}
|
||||
case "install":
|
||||
if installIdx == -1 {
|
||||
installIdx = i
|
||||
}
|
||||
}
|
||||
}
|
||||
if mkdirIdx == -1 {
|
||||
t.Fatalf("no `mkdir -p %s` op issued — on a fresh box the snippet install fails ENOENT (B2); calls: %v", SnippetDir, r.calls)
|
||||
}
|
||||
if installIdx == -1 {
|
||||
t.Fatalf("no install op issued; calls: %v", r.calls)
|
||||
}
|
||||
if mkdirIdx > installIdx {
|
||||
t.Fatalf("mkdir (call %d) must PRECEDE install (call %d) — order: %v", mkdirIdx, installIdx, r.calls)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user