feat: add storage info to settings page and improve NFS export handling
Backend: - Add source/used_by/available/error fields to diskUsage in system status - collectDiskUsage() now reads /proc/mounts, samba shares and NFS exports from DB - Paths are deduplicated; shared paths list all shares/exports using them - syscall.Statfs errors surface as available=false with user-facing error - collectServiceStatus made a method of Server (receiver consistency) Frontend: - Settings page now shows two cards: mount points and shared resources - Each path shows source badge (Sistema/Mount/SMB/NFS), used_by chips, progress bar - Unavailable paths show amber warning instead of progress bar - DiskUsage interface updated with new fields - NFSExport interface updated with structured fields (fsid, async, etc) - NFS page updated to use new export fields
This commit is contained in:
@@ -3,6 +3,9 @@ package importer
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
@@ -58,11 +61,11 @@ func parseExports(data []byte) ([]db.NFSExport, error) {
|
||||
}
|
||||
export.Clients = validClients
|
||||
|
||||
if export.Options != "" {
|
||||
if err := system.ValidateNFSOptions(export.Options); err != nil {
|
||||
continue
|
||||
}
|
||||
fsid, err := generateImportFSID()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
export.FSID = fsid
|
||||
|
||||
exports = append(exports, export)
|
||||
}
|
||||
@@ -141,13 +144,43 @@ func parseExportLine(line string) (db.NFSExport, bool) {
|
||||
options = "rw,sync,no_root_squash"
|
||||
}
|
||||
|
||||
readOnly := strings.Contains(options, "ro")
|
||||
async := strings.Contains(options, "async")
|
||||
rootSquash := !strings.Contains(options, "no_root_squash")
|
||||
subtreeCheck := strings.Contains(options, "subtree_check")
|
||||
|
||||
adv := db.NFSAdvanced{
|
||||
AllSquash: strings.Contains(options, "all_squash"),
|
||||
Secure: strings.Contains(options, "secure"),
|
||||
WDelay: strings.Contains(options, "wdelay"),
|
||||
Hide: strings.Contains(options, "hide"),
|
||||
Crossmnt: strings.Contains(options, "crossmnt"),
|
||||
}
|
||||
advJSON, _ := json.Marshal(adv)
|
||||
|
||||
return db.NFSExport{
|
||||
Path: path,
|
||||
Clients: clients,
|
||||
Options: options,
|
||||
Path: path,
|
||||
Clients: clients,
|
||||
ReadOnly: readOnly,
|
||||
Async: async,
|
||||
RootSquash: rootSquash,
|
||||
SubtreeCheck: subtreeCheck,
|
||||
Advanced: string(advJSON),
|
||||
}, true
|
||||
}
|
||||
|
||||
func generateImportFSID() (int64, error) {
|
||||
var b [4]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n := binary.BigEndian.Uint32(b[:])
|
||||
if n == 0 {
|
||||
n = 1
|
||||
}
|
||||
return int64(n), nil
|
||||
}
|
||||
|
||||
func splitExportsClients(s string) []string {
|
||||
var result []string
|
||||
var current []byte
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestParseExports(t *testing.T) {
|
||||
if len(got) != tt.wantLen {
|
||||
t.Errorf("parseExports() got %d exports, want %d", len(got), tt.wantLen)
|
||||
for i, e := range got {
|
||||
t.Logf(" export[%d]: path=%q clients=%v options=%q", i, e.Path, e.Clients, e.Options)
|
||||
t.Logf(" export[%d]: path=%q clients=%v fsid=%d", i, e.Path, e.Clients, e.FSID)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user