Shares: allow any folder, not only ZFS datasets
build / build (push) Successful in 1m7s

SMB shares and NFS exports may now point to any existing directory
(USB disks under /mnt or /media, /srv, home folders...) instead of only
ZFS dataset mountpoints. System trees (/etc, /usr, /var, /boot, /proc,
/root, ...) are refused, also after resolving symlinks. The path
suggestions list mounted data filesystems from /proc/self/mounts in
addition to ZFS mountpoints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 22:48:31 +03:00
co-authored by Claude Opus 5.5
parent 78215ac100
commit b331bc736d
10 changed files with 183 additions and 37 deletions
+7 -2
View File
@@ -9,6 +9,7 @@ import (
"log"
"math"
"net/http"
"path/filepath"
"strings"
"sync"
"time"
@@ -38,7 +39,10 @@ type Server struct {
pages map[string]*template.Template
mux *http.ServeMux
dirExists func(string) bool // share path check; replaced in tests
// share path checks; replaced in tests
dirExists func(string) bool
realPath func(string) (string, error)
readMounts func() string
mu sync.Mutex
shareErr string // last failed Apply of the share config
@@ -47,7 +51,8 @@ type Server struct {
func New(cfg *config.Store, st *store.Store, ring *history.Ring, sch *sched.Scheduler, sh *shares.Store) *Server {
run := hostrun.Auto()
s := &Server{cfg: cfg, st: st, ring: ring, sch: sch, send: alert.SendMail,
admin: zfsadm.New(zfsadm.NoInput(run)), shares: sh, shm: shares.New(run), dirExists: statDir, mux: http.NewServeMux()}
admin: zfsadm.New(zfsadm.NoInput(run)), shares: sh, shm: shares.New(run),
dirExists: statDir, realPath: filepath.EvalSymlinks, readMounts: procMounts, mux: http.NewServeMux()}
s.pages = map[string]*template.Template{}
layout := template.Must(template.New("layout").Funcs(funcs).ParseFS(assets, "templates/layout.html"))
for _, name := range []string{"dashboard", "disk", "zfs", "alerts", "settings", "shares"} {