feat: structured NFS options with auto-fsid and manual watched mounts

NFS exports: replace plain-text options string with typed booleans
(read_only, async, root_squash, subtree_check) + advanced JSON blob.
fsid is auto-generated via crypto/rand with collision retry and is
never user-settable. Breaking API change (options field removed).

Dashboard: filter disks to manual+samba+nfs sources only; no more
auto-discovery of all /proc/mounts entries.

Settings: new 'Puntos de montaje vigilados' card with add/remove
for manual mount points. AllowedRoots validation applied.

Version bump: 0.1.10 -> 0.2.0
This commit is contained in:
2026-07-06 00:23:49 -04:00
parent 63e0b5146a
commit e3add68584
9 changed files with 280 additions and 60 deletions
+9 -3
View File
@@ -10,6 +10,10 @@ export default function Dashboard() {
api.systemStatus().then(setStatus).catch(() => setStatus(null));
}, []);
const visibleDisks = status?.disks.filter(
(d) => d.source === "manual" || d.source === "samba" || d.source === "nfs"
) ?? [];
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold text-white">Dashboard</h1>
@@ -19,9 +23,9 @@ export default function Dashboard() {
<h2 className="mb-4 text-sm font-semibold uppercase tracking-wide text-slate-400">
Uso de disco
</h2>
{status?.disks?.length ? (
{visibleDisks.length ? (
<div className="space-y-4">
{status.disks.map((d) => (
{visibleDisks.map((d) => (
<div key={d.path}>
<div className="mb-1 flex justify-between text-sm">
<span className="text-slate-300">{d.path}</span>
@@ -39,7 +43,9 @@ export default function Dashboard() {
))}
</div>
) : (
<p className="text-sm text-slate-500">Sin datos de disco.</p>
<p className="text-sm text-slate-500">
Sin puntos de montaje vigilados. Añádelos en Ajustes.
</p>
)}
</div>