{config, ...}: { services.glance = { enable = true; openFirewall = true; settings = { server = { host = "0.0.0.0"; }; pages = [ { name = "Home"; columns = [ { size = "small"; widgets = [ { type = "calendar"; first-day-of-week = "monday"; } { type = "twitch-channels"; channels = [ "theprimeagen" ]; } ]; } { size = "full"; widgets = [ { type = "group"; widgets = [ {type = "hacker-news";} {type = "lobsters";} ]; } { type = "server-stats"; servers = [ { type = "local"; name = "Tyr"; } ]; } { type = "custom-api"; title = "Beszel stats"; cache = "5m"; options = { base-url = "\${BESZEL_URL}"; api-key = "\${BESZEL_TOKEN}"; }; template = '' {{/* Required config options */}} {{ $baseURL := .Options.StringOr "base-url" "" }} {{ $apiKey := .Options.StringOr "api-key" "" }} {{/* Error message template */}} {{ define "errorMsg" }}
ERROR

{{ . }}

{{ end }} {{ define "formatGigabytes" }} {{ $value := . }} {{ $label := "GB" }} {{- if lt $value 1.0 }} {{ $value = mul $value 1000.0 }} {{ $label = "MB" }} {{- else if lt $value 1000.0 }} {{ else }} {{ $value = div $value 1000.0 }} {{ $label = "TB" }} {{ end }} {{ printf "%.1f" $value }} {{ $label }} {{ end }} {{/* Check required fields */}} {{ if or (eq $baseURL "") (eq $apiKey "") }} {{ template "errorMsg" "Some required options are not set." }} {{ else }} {{ $token := concat "Bearer " $apiKey }} {{ $systemsResponse := newRequest (print $baseURL "/api/collections/systems/records") | withHeader "Authorization" $token | getResponse }} {{ $systems := $systemsResponse.JSON.Array "items" }} {{ range $n, $system := $systems }} {{ $status := $system.String "status" }} {{ $systemStatsRequest := newRequest (print $baseURL "/api/collections/system_stats/records") | withHeader "Authorization" $token | withParameter "sort" "-created" | withParameter "page" "1" | withParameter "perPage" "1" | withParameter "filter" (print "type='1m'&&system='" ($system.String "id") "'") | getResponse }} {{ $systemStats := index ($systemStatsRequest.JSON.Array "items") 0 }} {{ $hostname := $system.String "name" }} {{ $uptimeSec := $system.Float "info.u" }} {{ $systemTemp := $system.Float "info.dt"}} {{ $cpuLoad := $system.Float "info.cpu" }} {{ $cpuLoad1m := $system.Float "info.l1" }} {{ $cpuLoad15m := $system.Float "info.l15" }} {{ $memoryUsedPercent := $system.Float "info.mp" }} {{ $memoryTotalGb := $systemStats.Float "stats.m" }} {{ $memoryUsedGb := $systemStats.Float "stats.mu" }} {{ $swapTotalGb := $systemStats.Float "stats.s" }} {{ $swapUsedGb := $systemStats.Float "stats.su" }} {{ $swapUsedPercent := mul (div $swapUsedGb $swapTotalGb) 100.0 }} {{ $rootUsedPercent := $system.Float "info.dp" }} {{ $rootTotalGb := $systemStats.Float "stats.d" }} {{ $rootUsedGb := $systemStats.Float "stats.du" }}
{{ $hostname }}
{{ if eq $status "up" }} {{ printf "%.1f" (mul $uptimeSec 0.000011574) }}d uptime {{ else }} unreachable {{ end }}
{{- if eq $status "up" }}
Kernel
{{ $system.String "info.k" }}
CPU
{{ $system.String "info.m" }}
{{- end }}
CPU
{{- if ge $systemTemp 80.0 }} {{- end }}
{{ $cpuLoad }} %
1M AVG
{{ printf "%.1f" $cpuLoad1m }} %
15M AVG
{{ printf "%.1f" $cpuLoad15m }} %
TEMP C
{{ printf "%.1f" $systemTemp }} °
RAM
{{ $memoryUsedPercent }} %
RAM
{{ template "formatGigabytes" $memoryUsedGb }} / {{ template "formatGigabytes" $memoryTotalGb }}
{{- if gt $swapTotalGb 0.0 }}
SWAP
{{ template "formatGigabytes" $swapUsedGb }} / {{ template "formatGigabytes" $swapTotalGb }}
{{- end }}
{{- if gt $swapTotalGb 0.0 }}
{{- end }}
DISK
{{ $rootUsedPercent }} %
  • /
    {{ template "formatGigabytes" $rootUsedGb }} / {{ template "formatGigabytes" $rootTotalGb }}
  • {{ range $key, $efs := ($systemStats.Get "stats.efs").Map }}
  • {{ $key }}
    {{ template "formatGigabytes" (($efs.Get "du").Float) }} / {{ template "formatGigabytes" (($efs.Get "d").Float) }}
  • {{ end }}
{{ range $key, $efs := ($systemStats.Get "stats.efs").Map }} {{ $efsTotalGb := (($efs.Get "d").Float) }} {{ $efsUsedGb := (($efs.Get "du").Float) }} {{ $efsPercent := mul (div $efsUsedGb $efsTotalGb) 100 }}
{{ end }}
{{ end }} {{ end }} ''; } ]; } { size = "small"; widgets = [ { type = "weather"; units = "metric"; hour-format = "24h"; location = "Otočac, Hrvatska"; } { type = "releases"; cache = "1d"; repositories = [ "glanceapp/glance" "immich-app/immich" "syncthing/syncthing" ]; } ]; } ]; } ]; }; }; systemd.services.glance.serviceConfig = { EnvironmentFile = ["${config.age.secrets.glance.path}"]; }; }