From 62540c69a2dce928f3daeec3fe1f04a5293108d8 Mon Sep 17 00:00:00 2001 From: eding Date: Sun, 6 Sep 2026 09:38:46 +0200 Subject: [PATCH] fix: detect absent Proxmox VM response --- internal/bootstrap/bootstrap.go | 14 +++---- internal/bootstrap/bootstrap_test.go | 60 ++++++++++++++++++---------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 6afab1d..b493f7c 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -40,12 +40,12 @@ const ( ) type Runner struct { - Config config.Config - Mode Mode - ConfirmRebuild bool - RegisterWebhook bool - EnableDelivery bool - SkipDeliveryScaffolding bool + Config config.Config + Mode Mode + ConfirmRebuild bool + RegisterWebhook bool + EnableDelivery bool + SkipDeliveryScaffolding bool AutoMergeBootstrapMigration bool } @@ -1407,7 +1407,7 @@ func terraformReconcileTargets(cfg config.Config) []string { func (r Runner) rebuildTalosVMs(terraformDir string, environment []string) error { if err := r.importConfiguredTalosVMs(terraformDir, environment); err != nil { var apiErr proxmox.APIError - if errors.As(err, &apiErr) && apiErr.StatusCode == 404 { + if errors.As(err, &apiErr) && (apiErr.StatusCode == 404 || apiErr.StatusCode == 500 && apiErr.Message == `{"data":null}` && strings.HasSuffix(apiErr.Path, "/config")) { return nil } return err diff --git a/internal/bootstrap/bootstrap_test.go b/internal/bootstrap/bootstrap_test.go index 2d33897..c930b6b 100644 --- a/internal/bootstrap/bootstrap_test.go +++ b/internal/bootstrap/bootstrap_test.go @@ -1294,31 +1294,47 @@ func TestRebuildTerraformSkipsAlreadyAbsentTalosVM(t *testing.T) { Nodes: []config.TalosNode{{Name: "cp-01", ProxmoxNode: "pve", VMID: 100, Role: "controlplane"}}, }} var events []string + for _, apiErr := range []proxmox.APIError{{StatusCode: 404}, {StatusCode: 500, Message: `{"data":null}`, Path: "/nodes/pve/qemu/100/config"}} { + verifyTalosVMs = func(config.Config) error { + return fmt.Errorf("inspect configured Talos VM: %w", apiErr) + } + destroyTalosVMs = func(string, []string) error { + t.Fatal("destroy ran for an already-absent VM") + return nil + } + runTerraform = func(_ string, _ []string, name string, args ...string) error { + if name != "terraform" { + t.Fatalf("unexpected command %q", name) + } + switch args[0] { + case "init", "plan", "apply": + events = append(events, args[0]) + default: + t.Fatalf("unexpected Terraform operation %q", args[0]) + } + return nil + } + + if err := (Runner{Config: cfg, Mode: Rebuild}).reconcileTerraform(t.TempDir()); err != nil { + t.Fatal(err) + } + if strings.Join(events, ",") != "init,plan,apply" { + t.Fatalf("Terraform phase order = %q", events) + } + events = nil + } +} + +func TestRebuildTerraformRejectsUnexpectedProxmoxError(t *testing.T) { + originalVerify := verifyTalosVMs + t.Cleanup(func() { verifyTalosVMs = originalVerify }) verifyTalosVMs = func(config.Config) error { - return fmt.Errorf("inspect configured Talos VM: %w", proxmox.APIError{StatusCode: 404}) - } - destroyTalosVMs = func(string, []string) error { - t.Fatal("destroy ran for an already-absent VM") - return nil - } - runTerraform = func(_ string, _ []string, name string, args ...string) error { - if name != "terraform" { - t.Fatalf("unexpected command %q", name) - } - switch args[0] { - case "init", "plan", "apply": - events = append(events, args[0]) - default: - t.Fatalf("unexpected Terraform operation %q", args[0]) - } - return nil + return fmt.Errorf("inspect configured Talos VM: %w", proxmox.APIError{StatusCode: 500, Message: "server unavailable", Path: "/nodes/pve/qemu/100/config"}) } - if err := (Runner{Config: cfg, Mode: Rebuild}).reconcileTerraform(t.TempDir()); err != nil { - t.Fatal(err) - } - if strings.Join(events, ",") != "init,plan,apply" { - t.Fatalf("Terraform phase order = %q", events) + err := (Runner{Config: config.Config{Talos: config.TalosConfig{Nodes: []config.TalosNode{{Name: "cp-01", ProxmoxNode: "pve", VMID: 100}}}}, Mode: Rebuild}).rebuildTalosVMs(t.TempDir(), nil) + if err == nil || !strings.Contains(err.Error(), "server unavailable") { + t.Fatalf("unexpected Proxmox error was accepted: %v", err) } }