{{/* host_detail_body — the shared per-host detail sections, rendered by BOTH the standalone /hosts/{id} page (host_detail.html) and the customer page's Host tab (customer_unified.html, one instance per host). Data = the map built by hostDetailData (web/hosts.go); never carries api_key/escrow/PBS secret values. */}} {{define "host_detail_body"}}

{{.HostID}}

{{.StatusLabel}}
Host ID {{.HostID}}
Agent Version {{if .AgentVersion}}{{.AgentVersion}}{{else}}—{{end}}
{{if .WrapperDrift}}
PBS wrapper {{if eq .WrapperDrift "ok"}} matches vouched {{slice .ReportedWrapperSHA 0 12}}… {{else}} DRIFT — installed {{slice .ReportedWrapperSHA 0 12}}…, vouched {{slice .VouchedWrapperSHA 0 12}}…
/usr/local/sbin/felhom-pbs-apply differs from the manifest. It is delivered unversioned from main (R-50b), so this host may be running privileged code from a different commit.
{{end}}
{{end}}
Enrolled {{timeAgo .CreatedAt}}
Last Report {{if .HasReport}}{{timeAgoPtr .LastReportAt}}{{else}}waiting for first report{{end}}
Desired Generation {{.DesiredGeneration}}
{{if .RecoveryMode}}
Recovery Mode ACTIVE (until {{timeAgoPtr .RecoveryUntil}})
{{end}}
{{if .HasReport}}

Vitals

CPU {{formatFloat .Vitals.CPUPercent}}%
Memory {{formatFloat .Vitals.MemoryPercent}}%
Disk (root fs) {{formatFloat .Vitals.DiskPercent}}%
Cloudflared {{if .Vitals.CloudflaredStatus}}{{.Vitals.CloudflaredStatus}}{{else}}—{{end}}
Guests {{.GuestRunning}}/{{.GuestTotal}} running
{{else}}

Waiting for first report.

Vitals, guests and storage appear once this host's agent sends a host-report.

{{end}}

Guests

{{if .Guests}} {{range .Guests}} {{end}}
VMID Name Status Controller Last Seen
{{.VMID}} {{if .DisplayName}}{{.DisplayName}}{{else}}—{{end}} {{if eq .Status "running"}}{{.Status}}{{else if eq .Status "stopped"}}{{.Status}}{{else}}{{.Status}}{{end}} {{if .ControllerVersion}}{{.ControllerVersion}}{{else}}—{{end}} {{timeAgoPtr .LastSeenAt}}
{{else}}

No guests reported on this host.

{{end}}

Storage Targets

{{if .StorageTargets}} {{range .StorageTargets}} {{end}}
Name Role Type State Fill Thin Pool SMART Temp Wear
{{.Name}} {{if .Role}}{{.Role}}{{else}}—{{end}} {{if .Type}}{{.Type}}{{else}}—{{end}} {{if .State}}{{.State}}{{else}}—{{end}} {{formatFloat .FillPct}}% {{if .HasThin}}{{formatFloat .ThinDataPct}}%{{else}}—{{end}} {{if .SmartHealth}}{{if eq .SmartHealth "PASSED"}}{{.SmartHealth}}{{else if eq .SmartHealth "FAILED"}}{{.SmartHealth}}{{else}}{{.SmartHealth}}{{end}}{{else}}—{{end}} {{if .TempC}}{{.TempC}}°C{{else}}—{{end}} {{if .WearPct}}{{.WearPct}}%{{else}}—{{end}}
{{else}}

No storage targets reported.

{{end}}

Capabilities

{{if .NeedsDRMigration}}

This box predates the uniform DR plumbing (host-install < v1.15.0) — the pbsdr wrapper is missing. Migration one-liner set (as root on the host): fetch configs/felhom-pbs-apply from the agent repo to /usr/local/sbin/felhom-pbs-apply (0755), apt-get install -y age, set wg_tunnel.enabled: true in agent.json, restart felhom-agent — see documentation/runbooks/day0-install.md (retrofit).

{{end}} {{if .Capabilities}} {{range .Capabilities}} {{end}}
Capability Status Feature / reason
{{.Name}}{{if .Critical}} critical{{end}} {{.Status}} {{.Feature}}{{if .Reason}} — {{.Reason}}{{end}}
{{else}}

No capability report yet (waiting for the first host report).

{{end}}

Diagnostics — Log Bundles

Pull-based: the box ships its debug ring on its own next cycle — controller ≤ one report interval (~15 min), agent ≈ one heartbeat. The pull is recorded in the box's own log (customer-visible). Bundles expire after 72 h.

{{if .LogBundles}} {{range .LogBundles}} {{end}}
Component State Collected Received Size
{{.Component}} {{if eq .State "pending"}}pending {{else if eq .State "blocked"}}blocked: possible secret {{else}}available{{end}} {{if .CollectedAt.IsZero}}—{{else}}{{timeAgo .CollectedAt}}{{end}} {{if .ReceivedAt.IsZero}}—{{else}}{{timeAgo .ReceivedAt}}{{end}} {{if .SizeBytes}}{{.SizeBytes}} B{{else}}—{{end}} {{if eq .State "available"}} View Download {{end}}
{{else}}

No log bundles. Use the request buttons above — the box delivers on its next cycle.

{{end}}

DR / Backup

DR Recipe {{if .DRPresent}}present{{else}}none{{end}}
Key Escrow {{if .EscrowPresent}}present{{else}}none{{end}}{{if gt .SupersededEscrowCount 0}} · {{.SupersededEscrowCount}} superseded escrow blob(s) retained{{end}}

Console access

{{if .RecoveryVaulted}}
User {{.RecoveryUsername}}
Password set {{timeAgo .RecoverySetAt}}
••••••••••••••••

Break-glass credential for the PVE web console at https://<host-ip>:8006 (realm: Linux PAM standard authentication). Revealing it is recorded on the customer's event timeline. Last vaulted value — if root@pam was changed on the box without re-vaulting, this is stale.

{{else}}

not vaulted

No console credential is vaulted for this host. Expected for a byo host — the owner manages root@pam. Otherwise the installer's step 4b did not run; re-run felhom-host-install.sh, or set and vault one per the break-glass runbook §5.

{{end}}
{{if .RecoveryVaulted}} {{end}} {{if .Deletable}}

Danger zone

Removing this host deletes its reports, guests, log bundles and WireGuard peer, and permanently invalidates its API key — a still-running agent would receive 401s. Re-enrollment requires the Day-0 passphrase flow.

{{end}} {{end}}