proxmox: Delete with seed cleanup, health Checker, CRD type comment
Delete stops and destroys a VM of ours under the per-name lock, then deletes its seed on the VM's node, or on every node when no VM of ours was left. A hibernated VM of ours is Permanent, as in Create. The Checker verifies each node concurrently (version, node status, ISO storage, templates) and adds CertificateInvalid, CredentialsUnavailable, StorageNotFound and TemplateNotFound to the shared reasons. The ProviderHealth type comment gains proxmox. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -474,3 +475,60 @@ func TestGet_resourcesFailureIsTransient(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet_afterDeleteReturnsNotFound(t *testing.T) {
|
||||
t.Parallel()
|
||||
fx := newFixture(t, 1)
|
||||
fx.addOurVM(testVMID, testName, "running").ifaces = capturedIfaces(t)
|
||||
if inst := fx.get(fx.id()); inst.State != provider.StateRunning {
|
||||
t.Fatalf("Get before Delete = %+v, want Running", inst)
|
||||
}
|
||||
if err := fx.p.Delete(fx.ctx, fx.id()); err != nil {
|
||||
t.Fatalf("Delete error = %v", err)
|
||||
}
|
||||
assertGetFails(t, fx, provider.ErrNotFound)
|
||||
}
|
||||
|
||||
// TestGet_duringDeleteStillReturnsInstance holds the destroy task running:
|
||||
// destroying sets no lock and keeps the VM listed until the task ends, as
|
||||
// Phase 0's mid-destroy captures show, so Get sees it Stopped, not gone.
|
||||
func TestGet_duringDeleteStillReturnsInstance(t *testing.T) {
|
||||
t.Parallel()
|
||||
if _, locked := capturedConfig(t, "config_during_destroy")["lock"]; locked {
|
||||
t.Fatal("capture config_during_destroy has a lock; the fake models none")
|
||||
}
|
||||
listed := decodeData[[]vmResource](t, "cluster_resources_during_destroy")
|
||||
if !slices.ContainsFunc(listed, func(r vmResource) bool { return r.VMID == 199999 && r.Status == "stopped" && r.Lock == "" }) {
|
||||
t.Fatal("capture cluster_resources_during_destroy does not list VM 199999 stopped and unlocked")
|
||||
}
|
||||
|
||||
fx := newFixture(t, 1)
|
||||
fx.addOurVM(testVMID, testName, "running")
|
||||
inTask, release := make(chan struct{}), make(chan struct{})
|
||||
var once sync.Once
|
||||
fx.fake.hookOn("TaskStatus", func() error {
|
||||
if fx.fake.callCount("Destroy") > 0 {
|
||||
once.Do(func() {
|
||||
close(inTask)
|
||||
<-release
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
done := make(chan error, 1)
|
||||
go func() { done <- fx.p.Delete(fx.ctx, fx.id()) }()
|
||||
select {
|
||||
case <-inTask:
|
||||
case err := <-done:
|
||||
t.Fatalf("Delete returned %v before its destroy task was polled", err)
|
||||
}
|
||||
inst := fx.get(fx.id())
|
||||
if inst.State != provider.StateStopped || inst.UID != testUID || inst.ID != fx.id() {
|
||||
t.Errorf("Get during the destroy = %+v, want the instance Stopped with its uid", inst)
|
||||
}
|
||||
close(release)
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("Delete error = %v", err)
|
||||
}
|
||||
assertGetFails(t, fx, provider.ErrNotFound)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user