Files
nasmon/internal/web/templates/zfs.html
T
a.gritsenkoandClaude Sonnet 5 09159a5f31 Initial import: nasmon health monitor, split out of home_nas
Go service (nasmon/) plus nfpm packaging (packaging/), carried over from
the home_nas monorepo. Adds rpm packaging alongside the existing deb
build (Fedora/RHEL/Rocky dependency names via nfpm overrides, per-format
systemd unit path, dpkg+rpm-compatible maintainer scripts) and a Gitea
Actions workflow that builds both formats on every push.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 10:24:34 +03:00

83 lines
4.6 KiB
HTML

{{define "content"}}
{{template "flash" .}}
{{with .Data}}
{{if .S.PoolsErr}}<div class="flash crit">{{.S.PoolsErr}}</div>{{end}}
{{$form := .Form}}
{{range .S.Pools}}
<section class="card" id="{{.Name}}">
<h2>{{.Name}} <span class="badge {{healthClass .Health}}">{{.Health}}</span></h2>
<div class="kv cols">
<div><span class="muted">size</span> {{bytes .Size}}</div>
<div><span class="muted">allocated</span> {{bytes .Alloc}} ({{.CapPct}}%)</div>
<div><span class="muted">free</span> {{bytes .Free}}</div>
<div><span class="muted">fragmentation</span> {{.FragPct}}%</div>
<div><span class="muted">last scrub</span> {{if .LastScrub}}{{dtp .LastScrub}} ({{agop .LastScrub}}){{else}}never{{end}}</div>
<div><span class="muted">errors</span> {{if .Errors}}{{.Errors}}{{else}}—{{end}}</div>
</div>
<div class="bar"><span class="fill {{capClass .CapPct $.Data.Th.PoolCapacityPct 95}}" style="width:{{.CapPct}}%"></span></div>
{{if .Scan}}<p class="small"><span class="muted">scan:</span> {{.Scan}}</p>{{end}}
{{if .Status}}<p class="small warn-text"><span class="muted">status:</span> {{.Status}}</p>{{end}}
{{if .Action}}<p class="small"><span class="muted">action:</span> {{.Action}}</p>{{end}}
<div class="tablewrap"><table class="compact vdevs">
<thead><tr><th>vdev</th><th>State</th><th class="num">Read</th><th class="num">Write</th><th class="num">Cksum</th><th></th></tr></thead>
<tbody>
{{range .Vdevs}}
<tr class="{{if or .Read .Write .Cksum}}row-crit{{end}}">
<td class="mono" style="padding-left:{{.Depth}}.5em">{{.Name}}</td>
<td>{{if .State}}<span class="{{healthClass .State}}">{{.State}}</span>{{end}}</td>
<td class="num">{{.Read}}</td><td class="num">{{.Write}}</td><td class="num">{{.Cksum}}</td>
<td class="muted small">{{.Note}}</td>
</tr>
{{end}}
</tbody>
</table></div>
<details class="newds newds-{{.Name}}" {{if eq $form.Pool .Name}}open{{end}}>
<summary>New dataset in {{.Name}}</summary>
<form method="post" action="/zfs/create" class="ds-form">
<input type="hidden" name="pool" value="{{.Name}}">
<div class="form-grid">
<label>Name <input name="name" required placeholder="media/video" value="{{if eq $form.Pool .Name}}{{$form.Name}}{{end}}"></label>
<label>Owner (uid:gid) <input name="owner" value="{{$form.Owner}}" placeholder="1000:1000"></label>
<label>Compression
<select name="compression">
<option value="" {{if eq $form.Compression ""}}selected{{end}}>inherit</option>
<option value="lz4" {{if eq $form.Compression "lz4"}}selected{{end}}>lz4</option>
<option value="zstd" {{if eq $form.Compression "zstd"}}selected{{end}}>zstd</option>
<option value="off" {{if eq $form.Compression "off"}}selected{{end}}>off</option>
</select>
</label>
<label>Quota <input name="quota" placeholder="none, or 100G / 1.5T" value="{{if eq $form.Pool .Name}}{{$form.Quota}}{{end}}"></label>
</div>
<p class="small muted">Creates {{.Name}}/&lt;name&gt; (parents are created too), mounts it at /{{.Name}}/&lt;name&gt; and chowns the mountpoint to the owner.</p>
<button type="submit">Create dataset</button>
</form>
</details>
</section>
{{else}}<section class="card"><p class="muted">No ZFS pools found.</p></section>{{end}}
<section class="card">
<h2>Datasets</h2>
<div class="tablewrap"><table>
<thead><tr><th>Dataset</th><th>Mountpoint</th><th class="num">Used</th><th class="num">Referenced</th><th class="num">Available</th><th></th></tr></thead>
<tbody>
{{range .Datasets}}<tr>
<td class="mono">{{.Name}}</td><td class="muted mono small">{{.Mountpoint}}</td>
<td class="num">{{bytes .Used}}</td><td class="num">{{bytes .Refer}}</td><td class="num">{{bytes .Avail}}</td>
<td class="small">{{if hasPrefix .Mountpoint "/"}}<a href="/shares?path={{.Mountpoint}}">share…</a> {{end}}{{if .CanDestroy}}
<details class="destroy destroy-{{.DomID}}">
<summary class="muted">destroy…</summary>
<form method="post" action="/zfs/destroy" class="inline ds-destroy">
<input type="hidden" name="name" value="{{.Name}}">
<input name="confirm" placeholder="type {{.Name}} to confirm" size="30" required>
<button type="submit" class="secondary danger">Destroy empty dataset</button>
</form>
</details>
{{end}}</td>
</tr>{{end}}
</tbody>
</table></div>
<p class="small muted">Only empty datasets (no data, no children, no snapshots) can be destroyed here.</p>
</section>
{{end}}
{{end}}