Skip to main content

Glkvm Health

@figy/glkvm-healthv2026.10.17.2· MIT· 6d agoWORKFLOWSACCEPTED WARNINGS
01README

fi.gy's scheduled GL.iNet KVM health and TLS: check the out-of-band KVM on my LAN every 15 minutes, forward its verdict to the swamp-managed OpenTelemetry collector, and give its web UI a publicly trusted Let's Encrypt certificate.

WHAT IT DOES

Adds the missing reporting half to @sntxrr/glinet-kvm: that model can check a GL.iNet KVM (Comet GL-RM1 / GL-RM1PE) but cannot report it. This extension adds an emit method (health to OTel) and a cert method (install a TLS certificate onto the KVM) to the type — the same shape @svendowideit/nanokvm ships — and a scheduled workflow that runs health then emit every 15 minutes. An unreachable KVM is a fail sample rather than a silent gap. A second workflow, @figy/glkvm-dns, publishes the KVM's address as an A record (glkvm.fi.gy) and declares the name as a TLS subject, so the shared Caddy issues and renews a Let's Encrypt certificate for it. A third, @figy/glkvm-cert, installs that certificate onto the KVM (over SSH, since the device has no cert-upload API) so its web UI serves a trusted certificate.

INSTALL

swamp extension pull @figy/glkvm-health

DEPENDENCIES

@sntxrr/glinet-kvm (the model this extends, pulled automatically), a GL.iNet KVM reachable at the configured address, its login password in the glkvm vault (swamp vault create @svendowideit/systemd-creds glkvm then swamp vault put glkvm GLKVM_PASSWORD), and a running OTLP gateway listening on 127.0.0.1:4318 (the @svendowideit/otel-gateway). Without the gateway the emit step still runs and records why it skipped.

RUN

# Run the pipeline once now, instead of waiting for the 15-minute trigger.
swamp workflow run @figy/glkvm-health

# Check a different GL.iNet KVM on the same LAN (any input can be overridden).
swamp workflow run @figy/glkvm-health --input host=10.10.6.151

# Validate the DAG before running it (no device contact).
swamp workflow validate @figy/glkvm-health

# Read the last emit result back (endpoint, HTTP statuses, verdict).
swamp data get glkvm emit --json

# Publish the KVM's address and declare it for a certificate: reconcile
# glkvm.fi.gy -> the KVM into the shared Caddy (run after changing the
# address or the caddy model). Caddy then issues and renews a Let's
# Encrypt certificate for glkvm.fi.gy.
swamp workflow run @figy/glkvm-dns

# Install that certificate onto the KVM's web UI (scheduled daily; the
# device has no cert-upload API, so it is written over SSH).
swamp workflow run @figy/glkvm-cert

CONFIGURE

Inputs (all overridable per run; the defaults are my repo): device, host, port, username, vaultName, passwordRef, timeoutMs, otelModel, otelEndpoint, otelMesh, otelVaultName, otelTokenRef. host and vaultName are the ones that matter — the KVM's address and the vault holding its password. The trigger is read-only inside an extension; change the schedule from the host with swamp workflow trigger set @figy/glkvm-health --schedule "…". See the README for the full table.

@figy/glkvm-dns drives a @svendowideit/caddy model named glkvm-caddy that must be a repo model (under models/) — the caddy mixin ignores workflow/auto-created models. Create it once, declaring only the KVM's A record plus the settings shared with the Caddy's other models (my-caddy), then reconcile it:

  # One-time: create the repo model declaring glkvm.fi.gy -> the KVM. Its
  # serviceName/target share my-caddy's Caddy by default; baseDomain, the
  # ACME email, plugins and environmentFile must match my-caddy's too.
  swamp model create @svendowideit/caddy glkvm-caddy \
    --global-arg baseDomain=fi.gy \
    --global-arg letsEncryptEmail=SvenDowideit@home.org.au \
    --global-arg environmentFile=$HOME/.config/caddy/dns.env \
    --global-arg 'plugins:json=["github.com/caddy-dns/gandi"]' \
    --global-arg 'dnsRecords:json=[{"name":"glkvm.fi.gy","type":"A","value":["10.10.6.150"],"zone":"fi.gy"}]'

  # Reconcile it into the shared Caddy (re-run after changing the address).
  swamp workflow run @figy/glkvm-dns

To move the KVM, edit the model's dnsRecords and re-run the DNS workflow. See the README for the full input table.

UPGRADE

This extension installs nothing on the host, so an upgrade has nothing to rebuild or reconcile. Refresh the pulled copy with one idempotent command:

  swamp extension update

The @sntxrr/glinet-kvm model it extends is upgraded by that extension's own upgrades entry on the next method run.

WHAT IT INSTALLS

Nothing on the host — no services, cron triggers, daemons or webhooks. The schedule is a swamp trigger evaluated by swamp serve; it runs the @sntxrr/glinet-kvm model with the added emit method, which talks to the device and the collector and writes swamp data.

02Workflows3
@figy/glkvm-health1cb1b624-8641-448c-9a41-c71bfaf4c99e

fi.gy's scheduled GL.iNet KVM health: check the out-of-band KVM at 10.10.6.150, forward its health to the swamp-managed OpenTelemetry collector, and require the run to leave a health record. This is the concrete, site-specific half. The portable model that knows how to talk to a GL.iNet KVM (the kvmd fork, self-signed TLS, viewer-driven snapshots) is @sntxrr/glinet-kvm; this workflow pins it to my device and my collector. Every 15 minutes it runs `health`, then the `emit` method added by @figy/

healthCheck the device and forward its health to OTel.
1.check— Run the read-only GL.iNet KVM health check (always records a verdict).
2.emit— Push the latest health to the OTLP receiver. A no-op that records the reason when no collector is configured, so it is safe to leave enabled.
3.assert-checked— Confirm the health step produced a record (not that the device is up).
@figy/glkvm-dns95d8c724-960f-4ad3-8066-11a7349d7552

fi.gy's GL.iNet KVM DNS and certificate: reconcile glkvm.fi.gy -> the KVM into the shared Caddy, and declare the name as a TLS subject so Caddy issues and renews a Let's Encrypt certificate for it (via DNS-01), without giving the KVM its own Caddy. The A record lives on its own @svendowideit/caddy model, `glkvm-caddy`, whose only desired state is that one record — plus the shared settings (base domain fi.gy, ACME email, the Gandi DNS provider via the shared environment file) the caddy extension

dnsConfigure the KVM's DNS provider and reconcile its A record into the shared Caddy.
1.tls— Ensure the model has a DNS provider (Gandi, inferred from its plugins and environment file) so it can write records, and declare the KVM's name as a TLS subject, so Caddy issues and renews a Let's Encrypt certificate for it via DNS-01. No reverse-proxy route: the name points at the KVM itself.
2.dns— Reconcile this model's A record — merged with its Caddy peers' records — into Caddy.
3.assert-applied— Confirm the DNS reconcile wrote its dnsConfig record.
@figy/glkvm-cert896d4667-76f2-445b-b83b-d6329b58646c

fi.gy's GL.iNet KVM TLS: install the Let's Encrypt certificate Caddy issued for glkvm.fi.gy onto the KVM and keep it current. The GLKVM has no certificate-upload API, so this drives the `cert install` method @figy/glkvm-health adds to @sntxrr/glinet-kvm, which writes /etc/kvmd/user/ssl/server.crt and .key over SSH (root, the device password) and reloads nginx. The certificate files are taken from Caddy's store (~/.local/share/caddy/certificates), where Caddy issued them and renews them automati

certInstall the Caddy-issued certificate onto the KVM and verify it is served.
1.install— Locate the Caddy-issued certificate for the KVM's name, write it onto the KVM over SSH, reload nginx and verify the web UI serves it.
2.assert-installed— Confirm the KVM now serves a certificate carrying its name.
03Stats
A
100 / 100
Downloads
4
Archive size
29.6 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License2/2earned
  • Verified public repository2/2earned

05Platforms