7fb7ef5c3d
A slice-10 enrolled guest's data drive is a host bind-mount mp0 that the privsep
token can't vzrestore ("bind mount is only possible for root") — so the restore-test
failed for every enrolled guest regardless of backup tier. The restore-test now reads
the source guest config (vmid from the archive volid) and passes RestoreLXC mp
overrides converting each bind-mount mpN to a throwaway 1G volume on the restore
storage (no root needed; boot-verify doesn't need the data). proxmox.RestoreLXC gains
MountOverrides. + unit tests (archiveVMID, bindMountOverrides).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
49 lines
1.8 KiB
Go
49 lines
1.8 KiB
Go
package reconcile
|
|
|
|
import "testing"
|
|
|
|
func TestArchiveVMID(t *testing.T) {
|
|
cases := map[string]struct {
|
|
volid string
|
|
want int
|
|
ok bool
|
|
}{
|
|
"pbs ct": {"felhom-pbs:backup/ct/9201/2026-06-12T18:29:58Z", 9201, true},
|
|
"pbs vm": {"felhom-pbs:backup/vm/142/2026-06-12T18:29:58Z", 142, true},
|
|
"vzdump lxc": {"local:backup/vzdump-lxc-9201-2026_06_12-18_29_58.tar.zst", 9201, true},
|
|
"vzdump qemu": {"local:backup/vzdump-qemu-100-2026_06_12.vma.zst", 100, true},
|
|
"none": {"local:iso/whatever.iso", 0, false},
|
|
}
|
|
for name, c := range cases {
|
|
t.Run(name, func(t *testing.T) {
|
|
got, ok := archiveVMID(c.volid)
|
|
if ok != c.ok || got != c.want {
|
|
t.Errorf("archiveVMID(%q) = (%d,%v), want (%d,%v)", c.volid, got, ok, c.want, c.ok)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBindMountOverrides(t *testing.T) {
|
|
mps := map[string]string{
|
|
"mp0": "/mnt/felhom-usb/felhom-data,mp=/mnt/felhom-usb", // bind mount → override
|
|
"mp1": "local-lvm:8,mp=/data,backup=0", // real volume → left alone
|
|
"mp2": "/srv/extra", // bind mount, no explicit mp= → use host path
|
|
}
|
|
out := bindMountOverrides(mps, "local-lvm")
|
|
if _, ok := out["mp1"]; ok {
|
|
t.Error("mp1 is a storage volume and must NOT be overridden")
|
|
}
|
|
if got, want := out["mp0"], "local-lvm:1,mp=/mnt/felhom-usb,backup=0"; got != want {
|
|
t.Errorf("mp0 override = %q, want %q", got, want)
|
|
}
|
|
if got, want := out["mp2"], "local-lvm:1,mp=/srv/extra,backup=0"; got != want {
|
|
t.Errorf("mp2 override = %q, want %q", got, want)
|
|
}
|
|
|
|
// No bind mounts → nil (restore proceeds unchanged).
|
|
if bindMountOverrides(map[string]string{"mp0": "local-lvm:8,mp=/data"}, "local-lvm") != nil {
|
|
t.Error("expected nil when there are no bind mounts")
|
|
}
|
|
}
|