Deletion
VM deletion separates registration removal from storage and MAC cleanup. The default is conservative: remove the VM while retaining its managed disks and MAC objects. Add explicit flags only for resources that should be destroyed.
Understand the two commands
Section titled “Understand the two commands”Use delete for a normally registered VM. It can remove the libvirt domain, database registration, runtime files, selected managed storage, and selected MAC objects.
Use purge only when a Sylve registration remains but its local libvirt domain is already missing. Purge removes registration and runtime metadata, but deliberately leaves disks alone.
Preview before deleting
Section titled “Preview before deleting”--dry-run builds the same removal plan as deletion without changing the VM or its resources:
doas sylve vms delete --rid 302 --dry-run --jsonThe default preview on Loki retained MAC object 16 and every managed dataset:
{ "registration": { "rid": 302, "name": "docs-from-template" }, "deleteMacObjectIds": [], "retainMacObjectIds": [16], "deleteRawDatasets": [], "deleteZvolDatasets": [], "deleteContainerDatasets": [], "deleteSnapshots": [], "retainedDatasets": [ "zroot/sylve/virtual-machines/302", "zroot/sylve/virtual-machines/302/raw-11", "zroot/sylve/virtual-machines/302/raw-13", "zroot/sylve/virtual-machines/302/zvol-12" ], "retainedImageUuids": [], "warnings": []}Read every preview field before proceeding:
deleteRawDatasetscontains managed raw disks selected for destruction.deleteZvolDatasetscontains managed ZVOLs selected for destruction.deleteContainerDatasetscontains empty VM roots that can be removed afterward.deleteSnapshotscontains Sylve-owned snapshots that storage cleanup must remove.retainedDatasetsidentifies storage that will remain after registration removal.retainedImageUuidslists download-backed images, which deletion does not own.warningsreports anything the planner could not resolve confidently.
Preview full cleanup
Section titled “Preview full cleanup”Select every managed resource category explicitly:
doas sylve vms delete \ --rid 302 \ --delete-macs \ --delete-raw-disks \ --delete-volumes \ --dry-run \ --jsonLoki’s second preview moved raw datasets raw-11 and raw-13, ZVOL zvol-12, the VM root, and MAC object 16 into the corresponding deletion lists. Its retainedDatasets list was empty.
Delete the VM
Section titled “Delete the VM”Run the reviewed command without --dry-run:
doas sylve vms delete \ --rid 302 \ --delete-macs \ --delete-raw-disks \ --delete-volumes \ --jsonThe real result was:
{ "deleted": true, "rid": 302, "warnings": [], "retainedDatasets": [], "deletedMacObjectIds": [16], "retainedMacObjectIds": []}Deletion is immediate, not a lifecycle task. A running VM is force-stopped before its registration is removed. If storage or MAC cleanup is incomplete after registration removal, the response reports retained resources and warnings rather than hiding them.
Choose what to retain
Section titled “Choose what to retain”The cleanup flags are independent:
| Command choice | Raw disks | ZVOLs | MAC objects |
|---|---|---|---|
| No cleanup flags | Retained | Retained | Retained |
--delete-raw-disks |
Deleted | Retained | Retained |
--delete-volumes |
Retained | Deleted | Retained |
--delete-macs |
Retained | Retained | Deleted |
| All three flags | Deleted | Deleted | Deleted |
External filesystem attachments and download-backed images are retained regardless of these flags. Sylve does not destroy storage it does not own as part of VM deletion.
Deleting only one managed storage type can preserve the common VM root because retained siblings still live below it. Trust the dry-run plan rather than assuming the root will be removed.
Remove backup jobs and replication policy first
Section titled “Remove backup jobs and replication policy first”Deletion and dry-run are rejected while any backup job or replication policy still references the VM RID, including disabled jobs or policies. Delete those jobs and remove the policy before deleting the VM so a future guest cannot inherit its backup or replication identity.
Recover an orphaned registration
Section titled “Recover an orphaned registration”If the database contains VM 304 but libvirt no longer has its domain, purge the stale registration:
doas sylve vms purge --rid 304 --jsonAdd --delete-macs only when the orphan’s MAC objects should also be removed:
doas sylve vms purge --rid 304 --delete-macs --jsonPurge never deletes VM disks. Inspect and recover or remove orphaned datasets separately after confirming their identity.
On Loki, VM 304 was healthy, so the safety check rejected the test without changing anything:
{ "error": "failed_to_purge_vm: vm_not_orphaned"}The VM was then removed through the normal delete path.
Use the interactive console
Section titled “Use the interactive console”The console puts the RID after the leaf command:
vms delete 302 --dry-run --jsonvms delete 302 --delete-macs --delete-raw-disks --delete-volumes --dry-run --jsonvms delete 302 --delete-macs --delete-raw-disks --delete-volumes --jsonvms purge 304 --delete-macs --jsonDirect and console modes use the same preview, ownership, backup-job, replication, and orphan checks.
Safe workflow
Section titled “Safe workflow”- Confirm the RID and inspect the VM’s storage and network attachments.
- Delete every backup job and remove any replication policy that references the VM.
- Run
delete --dry-run --jsonwith the intended cleanup flags. - Review every deletion, retention, snapshot, and warning list.
- Run the identical command without
--dry-run. - Check
warnings,retainedDatasets, and retained MAC IDs in the result. - Reserve
purgefor a verified missing local domain.