Release 2026.09.27.r001: support array disk rsync backups to mounted USB disks

This commit is contained in:
Mikei386
2026-09-27 16:07:00 +02:00
parent 5009dc202b
commit 106f9c9387
13 changed files with 252 additions and 15 deletions
+72 -1
View File
@@ -1,6 +1,11 @@
package platform
import "testing"
import (
"os"
"path/filepath"
"reflect"
"testing"
)
func TestValidateBrowsePathRejectsUnsafePaths(t *testing.T) {
for _, path := range []string{"", "/", "/etc", "/mnt/user/../../etc", "relative"} {
@@ -9,3 +14,69 @@ func TestValidateBrowsePathRejectsUnsafePaths(t *testing.T) {
}
}
}
func TestBrowseDirectoriesIncludesSafeLinks(t *testing.T) {
root, err := filepath.EvalSymlinks(t.TempDir())
if err != nil {
t.Fatal(err)
}
outside := t.TempDir()
for _, name := range []string{"disk1", "USB"} {
if err := os.Mkdir(filepath.Join(root, name), 0755); err != nil {
t.Fatal(err)
}
}
if err := os.WriteFile(filepath.Join(root, "file"), nil, 0600); err != nil {
t.Fatal(err)
}
for name, target := range map[string]string{"alias": "USB", "escape": outside, "broken": "missing", "file-link": "file"} {
if err := os.Symlink(target, filepath.Join(root, name)); err != nil {
t.Fatal(err)
}
}
items, err := browseDirectories(root, []string{root})
if err != nil {
t.Fatal(err)
}
var names []string
for _, item := range items {
names = append(names, item.Name)
}
if !reflect.DeepEqual(names, []string{"alias", "disk1", "USB"}) {
t.Fatalf("entries = %v", names)
}
if _, err := browseDirectories(filepath.Join(root, "alias"), []string{root}); err != nil {
t.Fatal(err)
}
if _, err := browseDirectories(filepath.Join(root, "escape"), []string{root}); err == nil {
t.Fatal("escaped storage root")
}
}
func TestStorageBrowseRootsOnlyMountedArrayDisks(t *testing.T) {
mounts := []string{"/mnt/disk1", "/mnt/disk12", "/mnt/disk1", "/mnt/disk0", "/mnt/disk01", "/mnt/disk1-extra", "/mnt/disk2/subdir", "/etc", "/mnt/disks/USB"}
want := append(append([]string{}, browseRoots...), "/mnt/disk1", "/mnt/disk12")
if got := storageBrowseRoots(mounts); !reflect.DeepEqual(got, want) {
t.Fatalf("roots = %v", got)
}
}
func TestMountPathsAndUnmountedDisks(t *testing.T) {
mounts := parseMountPaths("36 25 8:1 / /mnt/disk1 rw - xfs /dev/md1 rw\n37 25 8:2 / /mnt/disks/USB\\040Backup rw - xfs /dev/sdb1 rw\n")
if !reflect.DeepEqual(mounts, []string{"/mnt/disk1", "/mnt/disks/USB Backup"}) {
t.Fatalf("mounts = %v", mounts)
}
for _, path := range []string{"/mnt/disk1", "/mnt/disk1/data", "/mnt/disks/USB Backup", "/mnt/disks/USB Backup/disk1"} {
if !diskPathMounted(path, mounts) {
t.Fatalf("mounted path rejected: %s", path)
}
}
for _, path := range []string{"/mnt/disk2", "/mnt/disk10", "/mnt/disks", "/mnt/disks/USB Backup-old", "/mnt/disks/unmounted"} {
if diskPathMounted(path, mounts) {
t.Fatalf("unmounted path accepted: %s", path)
}
}
if diskPathMounted("/mnt/disks/USB", []string{"/", "/mnt", "/mnt/disks"}) {
t.Fatal("parent mount accepted as USB mount")
}
}