Skip to content

destroy: a paused Hetzner VM is a snapshot, deleted only when asked as one - #1274

Merged
cdalar merged 1 commit into
mainfrom
hetzner-destroy-paused
Oct 27, 2026
Merged

cdalar merged 1 commit into
mainfrom
hetzner-destroy-paused

Conversation

@cdalar

@cdalar cdalar commented Oct 27, 2026

Copy link
Copy Markdown
Owner

What

On Hetzner, destroying a paused VM failed with No Server found with name: test. That happened in the TUI's ctrl-d and in onctl destroy test alike. Hetzner's pause deletes the server and keeps only a snapshot and the public IP. Destroy looks for a server, so it found nothing.

Now a paused Hetzner VM is called a snapshot, and it's deleted only after you've been asked as one:

  • cloud.SnapshotDestroyer: a new optional interface, implemented by Hetzner as DestroySnapshot(name). It deletes the VM's pause snapshots and the primary IPs kept for it. Both cost money until deleted: storage, and the IP's monthly fee. IPs attached to a server are never touched.
  • Destroy: still deletes only servers, so it can never delete a snapshot by surprise. For a name with no server it returns no server named "test".
  • TUI ctrl-d on a paused VM:
    • The question reads "Delete test's snapshot?" and says all that's left is a snapshot and its IP, and that once deleted it can never be resumed.
    • With marks, each paused VM's line says "(paused: only a snapshot)". The title counts them, for example "Destroy 3 VMs, 1 of them snapshots?", or "Delete 2 snapshots?" when every marked VM is one.
  • onctl destroy <name>: a paused VM gets the same explanation before the [y/N]. --force still skips the question.
  • Only status paused counts. A powered-off server (off, AWS's stopped) is filed with the paused VMs, but it's still a server and is destroyed as one.
  • Errors: Hetzner's Destroy returns API errors instead of calling log.Fatalln, which would have killed the TUI.

Testing

  • TestProviderHetzner_DestroyPaused runs against a fake Hetzner API. Destroy deletes nothing for a paused VM and still deletes a running server. DestroySnapshot deletes the snapshot and the unassigned IP only, and errors for an unknown name. It fails on the old Destroy.
  • TestTUIDestroySnapshot checks the single and marked questions' wording, that the snapshot goes to DestroySnapshot, and that a stopped VM still goes to Destroy. Two mutation checks failed it: using the broader paused state group, and never treating a VM as a snapshot.
  • go test ./... passes, and golangci-lint is clean.
  • Not tested: the onctl destroy prompt has no automated test, because its [y/N] is interactive. It hasn't been run against real Hetzner snapshots either. Your test and qwe are left for you to try.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ba6Vc6KwaV9dTWbzYVKA78

…s one

Hetzner's pause deletes the server, so destroying a paused VM by name
failed with "No Server found with name". Destroy still deletes only
servers; the new SnapshotDestroyer (Hetzner's DestroySnapshot) deletes
a paused VM's snapshot and the public IP kept for it. The tui's ctrl-d
and onctl destroy say the VM is only a snapshot, that it can never be
resumed after, and ask before calling it. Destroy also returns Hetzner's
errors instead of log.Fatalln, which would have killed the tui.
@codecov

codecov Bot commented Oct 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.44%. Comparing base (03ec3ca) to head (80e9a5c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/destroy.go 0.00% 21 Missing ⚠️
pkg/cloud/hetzner.go 84.61% 4 Missing ⚠️
cmd/tuiactions.go 94.11% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1274      +/-   ##
==========================================
+ Coverage   50.14%   50.44%   +0.30%     
==========================================
  Files          83       83              
  Lines        9764     9822      +58     
==========================================
+ Hits         4896     4955      +59     
+ Misses       4868     4867       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cdalar
cdalar merged commit d9e8c9c into main Oct 27, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

⌂ 换网址