From 5b62e26752ae805d6c63ffb30366079c2295d15f Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 23 Jul 2026 13:33:27 -0500 Subject: [PATCH 01/20] rotate netbird authSecret --- modules/k3s/netbird/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/k3s/netbird/config.yaml b/modules/k3s/netbird/config.yaml index 285a2b9..3eb16ed 100644 --- a/modules/k3s/netbird/config.yaml +++ b/modules/k3s/netbird/config.yaml @@ -23,7 +23,7 @@ data: domains: [] email: "" awsRoute53: false - authSecret: "182c13eec94ba6ef89ce8f3e33b4694b051fe4b0bf6d2c9188f738d1c000b6d7" + authSecret: "4bd2ecf3f8be38cd6e640d4eb5f844d8d73c094be7e036b7c6ce1e1b67396e1b" dataDir: "/var/lib/netbird/" disableAnonymousMetrics: false disableGeoliteUpdate: false From f9289fa766d250994ec203d11057bee37a8ef666 Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 23 Jul 2026 13:45:04 -0500 Subject: [PATCH 02/20] netbird: move authSecret out of git into k8s secret (netbird-relay-auth), render via init container --- modules/k3s/netbird/config.yaml | 4 ++-- modules/k3s/netbird/server.yaml | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/modules/k3s/netbird/config.yaml b/modules/k3s/netbird/config.yaml index 3eb16ed..2448dcc 100644 --- a/modules/k3s/netbird/config.yaml +++ b/modules/k3s/netbird/config.yaml @@ -4,7 +4,7 @@ metadata: name: netbird-server-config namespace: netbird data: - config.yaml: | + config.yaml.tpl: | server: listenAddress: ":80" exposedAddress: "https://netbird.archfox.org:443" @@ -23,7 +23,7 @@ data: domains: [] email: "" awsRoute53: false - authSecret: "4bd2ecf3f8be38cd6e640d4eb5f844d8d73c094be7e036b7c6ce1e1b67396e1b" + authSecret: "__AUTH_SECRET__" dataDir: "/var/lib/netbird/" disableAnonymousMetrics: false disableGeoliteUpdate: false diff --git a/modules/k3s/netbird/server.yaml b/modules/k3s/netbird/server.yaml index 4b954e2..c74033d 100644 --- a/modules/k3s/netbird/server.yaml +++ b/modules/k3s/netbird/server.yaml @@ -13,6 +13,25 @@ spec: labels: app: netbird-server spec: + initContainers: + - name: render-config + image: busybox + env: + - name: AUTH_SECRET + valueFrom: + secretKeyRef: + name: netbird-relay-auth + key: authSecret + command: + - sh + - -c + - | + sed "s|__AUTH_SECRET__|$AUTH_SECRET|g" /tpl/config.yaml.tpl > /etc/netbird/config.yaml + volumeMounts: + - name: config-tpl + mountPath: /tpl + - name: config-rendered + mountPath: /etc/netbird containers: - name: netbird-server image: netbirdio/netbird-server:latest @@ -29,14 +48,16 @@ spec: name: netbird-encryption key: encryptionKey volumeMounts: - - name: config + - name: config-rendered mountPath: /etc/netbird - name: data mountPath: /var/lib/netbird volumes: - - name: config + - name: config-tpl configMap: name: netbird-server-config + - name: config-rendered + emptyDir: {} - name: data persistentVolumeClaim: claimName: netbird-data From 10637d950f6bbada0906007321ee6f250f99d3d0 Mon Sep 17 00:00:00 2001 From: poslop Date: Tue, 28 Jul 2026 21:46:44 -0500 Subject: [PATCH 03/20] hermes-age changes --- modules/core/zsh/.zshrc | 2 +- modules/hermes/hermes.nix | 4 ++-- modules/hermes/secrets/hermes-env.age | Bin 799 -> 798 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/core/zsh/.zshrc b/modules/core/zsh/.zshrc index 3274b22..b05ba80 100644 --- a/modules/core/zsh/.zshrc +++ b/modules/core/zsh/.zshrc @@ -17,7 +17,7 @@ alias gs='git status' alias hermes='docker exec -it -u hermes hermes-agent /data/current-package/bin/hermes' -alias hermes-age='cd /etc/rice-flakes/modules/hermes/secrets && sudo EDITOR=nvim agenix -e ./hermes-env.age -i /etc/ssh/ssh_host_ed25519_key' +alias hermes-age='cd /etc/rice-flakes/modules/hermes/secrets && sudo EDITOR=nvim agenix -e hermes-env.age -i /etc/ssh/ssh_host_ed25519_key' ga() { if [[ -z "$1" ]]; then diff --git a/modules/hermes/hermes.nix b/modules/hermes/hermes.nix index acdb3dc..fd345ec 100644 --- a/modules/hermes/hermes.nix +++ b/modules/hermes/hermes.nix @@ -44,8 +44,8 @@ }; delegation = { - model = "openai/gpt-5.6-luna"; - provider = "nous"; + model = "us.anthropic.claude-sonnet-5"; + provider = "bedrock"; }; discord = { diff --git a/modules/hermes/secrets/hermes-env.age b/modules/hermes/secrets/hermes-env.age index 1583299daf7985e512b8e829a2af83cbe44e30ed..f383b245a9c4d54d68ef069c932c5d73cfbe8d85 100644 GIT binary patch delta 766 zcmV2A&3xEPpRhbYW9(Y;R#fG(|IKWjSSaX>V9=XJl<}Ra#jzR#z)9$q^t);chOWt+7*}R zZ@#Kp99+#g%g}DuWEe2a*;h7S!3FZnX92nct?yeawk(=_wT zY=!txIMh*X|!P7>x$KfDURECbwc#F>v1AnJIi}&v}Bn=gb_vb`f9V=zX*$FjVT;Y zoIgmWrGJv-@>4wD<^TSrcxsIH76UjvTqGgwOP}zS09Y87dpL65feeLA-VB#SCb&76 zSrOej_bSo_ZJ%1YR}V63oLlm1OEK0F9ZyX9dTTbM$ij?&=tlY^YcWxndK`lgsXyA` zpd3gSn6(a+LrXudaoSHnQ#|f)42fy8Ya()-N_VU((~XMo0SZS!c0ZL@C$*Ybw?oaq zlqauTnIsXFYgM}}{7=HPY<}*wm6#6Xlyr;m3DlqtPGRu=<>r7>OPgidz<$19$mg>y wYn6C+|2vc|y4uMbD9KnO8{_RsQeWI1n5QsD7?|F2M7A*kaF4){=<%RVjRU`5{{R30 delta 767 zcmV9yEPpdjZE!(jSyE3oGkR@Ea&K6ALP9HWT2o?Cd2CcKQ({k1Wprgz zId586cM5K4bwWvKb!&AuOi)ruYEdvRXJ=zqLo{YIX+=~oY;JciR9ACzZcTVZNeV43 zEg*VQPHlQcNjO6=X=G4GRWWBlOi?&hRarPiL_ud*WMwO6Wq&nwb4@T-a(4<9Vj#U3 zMYqm`w+f_l+wfMh@_}Bm?}hxm6v#tO%5Kfm=MyXYO2l%*-9Bw6eUCzhV-`IHQn$@G^D00OTc~p5R}Pvw zvi)JekQPKNPno@Hd(Gy`%w0+%a!+xq_{l-j_EXvb*?(TbU>tn+TkK?uT6J}wbk?UZ zOT{6DdSb<$3P8=YFDl-^XIO(x5Ff>zHVY7l(iK;QL@kVJD6iF27@3~%D5Yx3RV=PFIijh-+Sl!#aOQP8i|x zSK%k9NM3>BvM0&7Duvk+r-Ltt@gN|_;qWDx=6FZk9?7J~EkLTbXHu}vG2Sy2h=1TP zR9HlgqjOk`Xt&j*LVk=W6pb7@WZSa6$qr)0I;4^z_la5+G#{8R*jJOLsv8nLA*vBN xNYA=U+m#{%KxtJA`(i$zVwH;Mzy5R Date: Thu, 30 Jul 2026 18:03:05 -0500 Subject: [PATCH 04/20] add yamlfmt to dev packages --- modules/core/packages/dev.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/core/packages/dev.nix b/modules/core/packages/dev.nix index ee70dcc..80cda7d 100644 --- a/modules/core/packages/dev.nix +++ b/modules/core/packages/dev.nix @@ -5,6 +5,7 @@ neovim git tree-sitter + yamlfmt gcc # lua From eadba798eaadf45ff2a6f6768f9ecb93c00e5445 Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 30 Jul 2026 18:17:59 -0500 Subject: [PATCH 05/20] k3s: wipe netbird/traefik manifests, back to bare k3s --- modules/k3s/k3s.nix | 15 +---- modules/k3s/netbird/config.yaml | 45 -------------- modules/k3s/netbird/dashboard.yaml | 56 ----------------- modules/k3s/netbird/ingress.yaml | 26 -------- modules/k3s/netbird/namespace.yaml | 4 -- modules/k3s/netbird/server.yaml | 95 ----------------------------- modules/k3s/traefik/deployment.yaml | 35 ----------- modules/k3s/traefik/namespace.yaml | 4 -- modules/k3s/traefik/pvc.yaml | 11 ---- modules/k3s/traefik/rbac.yaml | 41 ------------- modules/k3s/traefik/service.yaml | 16 ----- 11 files changed, 1 insertion(+), 347 deletions(-) delete mode 100644 modules/k3s/netbird/config.yaml delete mode 100644 modules/k3s/netbird/dashboard.yaml delete mode 100644 modules/k3s/netbird/ingress.yaml delete mode 100644 modules/k3s/netbird/namespace.yaml delete mode 100644 modules/k3s/netbird/server.yaml delete mode 100644 modules/k3s/traefik/deployment.yaml delete mode 100644 modules/k3s/traefik/namespace.yaml delete mode 100644 modules/k3s/traefik/pvc.yaml delete mode 100644 modules/k3s/traefik/rbac.yaml delete mode 100644 modules/k3s/traefik/service.yaml diff --git a/modules/k3s/k3s.nix b/modules/k3s/k3s.nix index 8eaa99c..bd25ee9 100644 --- a/modules/k3s/k3s.nix +++ b/modules/k3s/k3s.nix @@ -1,22 +1,9 @@ { - networking.firewall.allowedTCPPorts = [ 6443 80 443 33073 ]; - networking.firewall.allowedUDPPorts = [ 3479 ]; + networking.firewall.allowedTCPPorts = [ 6443 80 443 ]; services.k3s = { enable = true; role = "server"; extraFlags = "--write-kubeconfig-mode 644"; - manifests = { - traefik-namespace = { source = ./traefik/namespace.yaml; }; - traefik-rbac = { source = ./traefik/rbac.yaml; }; - traefik-pvc = { source = ./traefik/pvc.yaml; }; - traefik-deployment = { source = ./traefik/deployment.yaml; }; - traefik-service = { source = ./traefik/service.yaml; }; - netbird-namespace = { source = ./netbird/namespace.yaml; }; - netbird-config = { source = ./netbird/config.yaml; }; - netbird-server = { source = ./netbird/server.yaml; }; - netbird-dashboard = { source = ./netbird/dashboard.yaml; }; - netbird-ingress = { source = ./netbird/ingress.yaml; }; - }; }; } diff --git a/modules/k3s/netbird/config.yaml b/modules/k3s/netbird/config.yaml deleted file mode 100644 index 2448dcc..0000000 --- a/modules/k3s/netbird/config.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: netbird-server-config - namespace: netbird -data: - config.yaml.tpl: | - server: - listenAddress: ":80" - exposedAddress: "https://netbird.archfox.org:443" - metricsPort: 9090 - healthcheckAddress: ":9000" - logLevel: "info" - logFile: "console" - stunPorts: - - 3479 - tls: - certFile: "" - keyFile: "" - letsencrypt: - enabled: false - dataDir: "" - domains: [] - email: "" - awsRoute53: false - authSecret: "__AUTH_SECRET__" - dataDir: "/var/lib/netbird/" - disableAnonymousMetrics: false - disableGeoliteUpdate: false - auth: - issuer: "https://netbird.archfox.org/oauth2" - localAuthDisabled: false - signKeyRefreshEnabled: true - dashboardRedirectURIs: - - "https://netbird.archfox.org/nb-auth" - - "https://netbird.archfox.org/nb-silent-auth" - cliRedirectURIs: - - "http://localhost:53000/" - store: - engine: "sqlite" - dsn: "" - encryptionKey: "" - reverseProxy: - trustedHTTPProxies: - - "10.0.1.45/32" diff --git a/modules/k3s/netbird/dashboard.yaml b/modules/k3s/netbird/dashboard.yaml deleted file mode 100644 index 3766dfa..0000000 --- a/modules/k3s/netbird/dashboard.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: dashboard - namespace: netbird -spec: - replicas: 1 - selector: - matchLabels: - app: dashboard - template: - metadata: - labels: - app: dashboard - spec: - containers: - - name: dashboard - image: netbirdio/dashboard:latest - ports: - - containerPort: 80 - env: - - name: NETBIRD_MGMT_API_ENDPOINT - value: "https://netbird.archfox.org" - - name: NETBIRD_MGMT_GRPC_API_ENDPOINT - value: "https://netbird.archfox.org" - - name: AUTH_AUDIENCE - value: "netbird-dashboard" - - name: AUTH_CLIENT_ID - value: "netbird-dashboard" - - name: AUTH_CLIENT_SECRET - value: "" - - name: AUTH_AUTHORITY - value: "https://netbird.archfox.org/oauth2" - - name: USE_AUTH0 - value: "false" - - name: AUTH_SUPPORTED_SCOPES - value: "openid profile email groups" - - name: AUTH_REDIRECT_URI - value: "/nb-auth" - - name: AUTH_SILENT_REDIRECT_URI - value: "/nb-silent-auth" - - name: LETSENCRYPT_DOMAIN - value: "none" ---- -apiVersion: v1 -kind: Service -metadata: - name: dashboard - namespace: netbird -spec: - selector: - app: dashboard - ports: - - name: http - port: 80 - targetPort: 80 diff --git a/modules/k3s/netbird/ingress.yaml b/modules/k3s/netbird/ingress.yaml deleted file mode 100644 index 0a8c46d..0000000 --- a/modules/k3s/netbird/ingress.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: netbird - namespace: netbird -spec: - entryPoints: - - web - routes: - - match: Host(`netbird.archfox.org`) && (PathPrefix(`/management.ManagementService/`) || PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ProxyService/`)) - kind: Rule - services: - - name: netbird-server - port: 80 - scheme: h2c - - match: Host(`netbird.archfox.org`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`)) - kind: Rule - services: - - name: netbird-server - port: 80 - - match: Host(`netbird.archfox.org`) - kind: Rule - priority: 1 - services: - - name: dashboard - port: 80 diff --git a/modules/k3s/netbird/namespace.yaml b/modules/k3s/netbird/namespace.yaml deleted file mode 100644 index db05a13..0000000 --- a/modules/k3s/netbird/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: netbird diff --git a/modules/k3s/netbird/server.yaml b/modules/k3s/netbird/server.yaml deleted file mode 100644 index c74033d..0000000 --- a/modules/k3s/netbird/server.yaml +++ /dev/null @@ -1,95 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: netbird-server - namespace: netbird -spec: - replicas: 1 - selector: - matchLabels: - app: netbird-server - template: - metadata: - labels: - app: netbird-server - spec: - initContainers: - - name: render-config - image: busybox - env: - - name: AUTH_SECRET - valueFrom: - secretKeyRef: - name: netbird-relay-auth - key: authSecret - command: - - sh - - -c - - | - sed "s|__AUTH_SECRET__|$AUTH_SECRET|g" /tpl/config.yaml.tpl > /etc/netbird/config.yaml - volumeMounts: - - name: config-tpl - mountPath: /tpl - - name: config-rendered - mountPath: /etc/netbird - containers: - - name: netbird-server - image: netbirdio/netbird-server:latest - args: ["--config", "/etc/netbird/config.yaml"] - ports: - - containerPort: 80 - - containerPort: 3479 - protocol: UDP - - containerPort: 33073 - env: - - name: NETBIRD_STORE_ENCRYPTION_KEY - valueFrom: - secretKeyRef: - name: netbird-encryption - key: encryptionKey - volumeMounts: - - name: config-rendered - mountPath: /etc/netbird - - name: data - mountPath: /var/lib/netbird - volumes: - - name: config-tpl - configMap: - name: netbird-server-config - - name: config-rendered - emptyDir: {} - - name: data - persistentVolumeClaim: - claimName: netbird-data ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: netbird-data - namespace: netbird -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi ---- -apiVersion: v1 -kind: Service -metadata: - name: netbird-server - namespace: netbird -spec: - selector: - app: netbird-server - ports: - - name: http - port: 80 - targetPort: 80 - - name: grpc-compat - port: 33073 - targetPort: 33073 - - name: stun - port: 3479 - targetPort: 3479 - protocol: UDP diff --git a/modules/k3s/traefik/deployment.yaml b/modules/k3s/traefik/deployment.yaml deleted file mode 100644 index 7dcca15..0000000 --- a/modules/k3s/traefik/deployment.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: traefik - namespace: traefik -spec: - replicas: 1 - selector: - matchLabels: - app: traefik - template: - metadata: - labels: - app: traefik - spec: - serviceAccountName: traefik - containers: - - name: traefik - image: traefik:v3.4 - args: - - --log.level=INFO - - --api.dashboard=true - - --entrypoints.web.address=:80 - - --providers.kubernetescrd=true - - --providers.kubernetesingress=true - ports: - - name: web - containerPort: 80 - volumeMounts: - - name: acme-storage - mountPath: /data - volumes: - - name: acme-storage - persistentVolumeClaim: - claimName: traefik-acme diff --git a/modules/k3s/traefik/namespace.yaml b/modules/k3s/traefik/namespace.yaml deleted file mode 100644 index c088a91..0000000 --- a/modules/k3s/traefik/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: traefik diff --git a/modules/k3s/traefik/pvc.yaml b/modules/k3s/traefik/pvc.yaml deleted file mode 100644 index 46187de..0000000 --- a/modules/k3s/traefik/pvc.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: traefik-acme - namespace: traefik -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 128Mi diff --git a/modules/k3s/traefik/rbac.yaml b/modules/k3s/traefik/rbac.yaml deleted file mode 100644 index a10b9eb..0000000 --- a/modules/k3s/traefik/rbac.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: traefik - namespace: traefik ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: traefik -rules: - - apiGroups: [""] - resources: ["services", "endpoints", "secrets", "configmaps", "nodes", "namespaces", "pods"] - verbs: ["get", "list", "watch"] - - apiGroups: ["discovery.k8s.io"] - resources: ["endpointslices"] - verbs: ["get", "list", "watch"] - - apiGroups: ["extensions", "networking.k8s.io"] - resources: ["ingresses", "ingressclasses"] - verbs: ["get", "list", "watch"] - - apiGroups: ["extensions", "networking.k8s.io"] - resources: ["ingresses/status"] - verbs: ["update"] - - apiGroups: ["traefik.io"] - resources: ["ingressroutes", "ingressroutetcps", "ingressrouteudps", "middlewares", - "middlewaretcps", "tlsoptions", "tlsstores", "traefikservices", - "serverstransports", "serverstransporttcps"] - verbs: ["get", "list", "watch"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: traefik -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: traefik -subjects: - - kind: ServiceAccount - name: traefik - namespace: traefik diff --git a/modules/k3s/traefik/service.yaml b/modules/k3s/traefik/service.yaml deleted file mode 100644 index 04377c8..0000000 --- a/modules/k3s/traefik/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: traefik - namespace: traefik -spec: - type: LoadBalancer - selector: - app: traefik - ports: - - name: web - port: 80 - targetPort: 80 - - name: websecure - port: 443 - targetPort: 443 From 8b65c53a11030c9c8d8ce8468cb9f723e94e23ad Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 30 Jul 2026 18:27:55 -0500 Subject: [PATCH 06/20] netbird: fresh setup routed through built-in traefik, secrets via kubectl not git --- modules/k3s/k3s.nix | 10 +++- modules/k3s/netbird/config.yaml | 45 ++++++++++++++ modules/k3s/netbird/dashboard.yaml | 56 +++++++++++++++++ modules/k3s/netbird/ingress.yaml | 26 ++++++++ modules/k3s/netbird/namespace.yaml | 4 ++ modules/k3s/netbird/server.yaml | 96 ++++++++++++++++++++++++++++++ 6 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 modules/k3s/netbird/config.yaml create mode 100644 modules/k3s/netbird/dashboard.yaml create mode 100644 modules/k3s/netbird/ingress.yaml create mode 100644 modules/k3s/netbird/namespace.yaml create mode 100644 modules/k3s/netbird/server.yaml diff --git a/modules/k3s/k3s.nix b/modules/k3s/k3s.nix index bd25ee9..b34742c 100644 --- a/modules/k3s/k3s.nix +++ b/modules/k3s/k3s.nix @@ -1,9 +1,17 @@ { - networking.firewall.allowedTCPPorts = [ 6443 80 443 ]; + networking.firewall.allowedTCPPorts = [ 6443 80 443 33073 ]; + networking.firewall.allowedUDPPorts = [ 3479 ]; services.k3s = { enable = true; role = "server"; extraFlags = "--write-kubeconfig-mode 644"; + manifests = { + netbird-namespace = { source = ./netbird/namespace.yaml; }; + netbird-config = { source = ./netbird/config.yaml; }; + netbird-server = { source = ./netbird/server.yaml; }; + netbird-dashboard = { source = ./netbird/dashboard.yaml; }; + netbird-ingress = { source = ./netbird/ingress.yaml; }; + }; }; } diff --git a/modules/k3s/netbird/config.yaml b/modules/k3s/netbird/config.yaml new file mode 100644 index 0000000..d3e22be --- /dev/null +++ b/modules/k3s/netbird/config.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: netbird-server-config + namespace: netbird +data: + config.yaml.tpl: | + server: + listenAddress: ":80" + exposedAddress: "https://netbird.archfox.org:443" + metricsPort: 9090 + healthcheckAddress: ":9000" + logLevel: "info" + logFile: "console" + stunPorts: + - 3479 + tls: + certFile: "" + keyFile: "" + letsencrypt: + enabled: false + dataDir: "" + domains: [] + email: "" + awsRoute53: false + authSecret: "__AUTH_SECRET__" + dataDir: "/var/lib/netbird/" + disableAnonymousMetrics: false + disableGeoliteUpdate: false + auth: + issuer: "https://netbird.archfox.org/oauth2" + localAuthDisabled: false + signKeyRefreshEnabled: true + dashboardRedirectURIs: + - "https://netbird.archfox.org/nb-auth" + - "https://netbird.archfox.org/nb-silent-auth" + cliRedirectURIs: + - "http://localhost:53000/" + store: + engine: "sqlite" + dsn: "" + encryptionKey: "__STORE_ENCRYPTION_KEY__" + reverseProxy: + trustedHTTPProxies: + - "10.0.1.45/32" diff --git a/modules/k3s/netbird/dashboard.yaml b/modules/k3s/netbird/dashboard.yaml new file mode 100644 index 0000000..3766dfa --- /dev/null +++ b/modules/k3s/netbird/dashboard.yaml @@ -0,0 +1,56 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dashboard + namespace: netbird +spec: + replicas: 1 + selector: + matchLabels: + app: dashboard + template: + metadata: + labels: + app: dashboard + spec: + containers: + - name: dashboard + image: netbirdio/dashboard:latest + ports: + - containerPort: 80 + env: + - name: NETBIRD_MGMT_API_ENDPOINT + value: "https://netbird.archfox.org" + - name: NETBIRD_MGMT_GRPC_API_ENDPOINT + value: "https://netbird.archfox.org" + - name: AUTH_AUDIENCE + value: "netbird-dashboard" + - name: AUTH_CLIENT_ID + value: "netbird-dashboard" + - name: AUTH_CLIENT_SECRET + value: "" + - name: AUTH_AUTHORITY + value: "https://netbird.archfox.org/oauth2" + - name: USE_AUTH0 + value: "false" + - name: AUTH_SUPPORTED_SCOPES + value: "openid profile email groups" + - name: AUTH_REDIRECT_URI + value: "/nb-auth" + - name: AUTH_SILENT_REDIRECT_URI + value: "/nb-silent-auth" + - name: LETSENCRYPT_DOMAIN + value: "none" +--- +apiVersion: v1 +kind: Service +metadata: + name: dashboard + namespace: netbird +spec: + selector: + app: dashboard + ports: + - name: http + port: 80 + targetPort: 80 diff --git a/modules/k3s/netbird/ingress.yaml b/modules/k3s/netbird/ingress.yaml new file mode 100644 index 0000000..0a8c46d --- /dev/null +++ b/modules/k3s/netbird/ingress.yaml @@ -0,0 +1,26 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: netbird + namespace: netbird +spec: + entryPoints: + - web + routes: + - match: Host(`netbird.archfox.org`) && (PathPrefix(`/management.ManagementService/`) || PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ProxyService/`)) + kind: Rule + services: + - name: netbird-server + port: 80 + scheme: h2c + - match: Host(`netbird.archfox.org`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`)) + kind: Rule + services: + - name: netbird-server + port: 80 + - match: Host(`netbird.archfox.org`) + kind: Rule + priority: 1 + services: + - name: dashboard + port: 80 diff --git a/modules/k3s/netbird/namespace.yaml b/modules/k3s/netbird/namespace.yaml new file mode 100644 index 0000000..db05a13 --- /dev/null +++ b/modules/k3s/netbird/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: netbird diff --git a/modules/k3s/netbird/server.yaml b/modules/k3s/netbird/server.yaml new file mode 100644 index 0000000..158a6a5 --- /dev/null +++ b/modules/k3s/netbird/server.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: netbird-server + namespace: netbird +spec: + replicas: 1 + selector: + matchLabels: + app: netbird-server + template: + metadata: + labels: + app: netbird-server + spec: + initContainers: + - name: render-config + image: busybox + env: + - name: AUTH_SECRET + valueFrom: + secretKeyRef: + name: netbird-relay-auth + key: authSecret + - name: STORE_KEY + valueFrom: + secretKeyRef: + name: netbird-encryption + key: encryptionKey + command: + - sh + - -c + - | + sed -e "s|__AUTH_SECRET__|$AUTH_SECRET|g" \ + -e "s|__STORE_ENCRYPTION_KEY__|$STORE_KEY|g" \ + /tpl/config.yaml.tpl > /etc/netbird/config.yaml + volumeMounts: + - name: config-tpl + mountPath: /tpl + - name: config-rendered + mountPath: /etc/netbird + containers: + - name: netbird-server + image: netbirdio/netbird-server:latest + args: ["--config", "/etc/netbird/config.yaml"] + ports: + - containerPort: 80 + - containerPort: 3479 + protocol: UDP + - containerPort: 33073 + volumeMounts: + - name: config-rendered + mountPath: /etc/netbird + - name: data + mountPath: /var/lib/netbird + volumes: + - name: config-tpl + configMap: + name: netbird-server-config + - name: config-rendered + emptyDir: {} + - name: data + persistentVolumeClaim: + claimName: netbird-data +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: netbird-data + namespace: netbird +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: netbird-server + namespace: netbird +spec: + selector: + app: netbird-server + ports: + - name: http + port: 80 + targetPort: 80 + - name: grpc-compat + port: 33073 + targetPort: 33073 + - name: stun + port: 3479 + targetPort: 3479 + protocol: UDP From 765be54fb5e9f0e9dafa84204820b4c098686399 Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 30 Jul 2026 18:29:00 -0500 Subject: [PATCH 07/20] Revert "netbird: fresh setup routed through built-in traefik, secrets via kubectl not git" This reverts commit 8b65c53a11030c9c8d8ce8468cb9f723e94e23ad. --- modules/k3s/k3s.nix | 10 +--- modules/k3s/netbird/config.yaml | 45 -------------- modules/k3s/netbird/dashboard.yaml | 56 ----------------- modules/k3s/netbird/ingress.yaml | 26 -------- modules/k3s/netbird/namespace.yaml | 4 -- modules/k3s/netbird/server.yaml | 96 ------------------------------ 6 files changed, 1 insertion(+), 236 deletions(-) delete mode 100644 modules/k3s/netbird/config.yaml delete mode 100644 modules/k3s/netbird/dashboard.yaml delete mode 100644 modules/k3s/netbird/ingress.yaml delete mode 100644 modules/k3s/netbird/namespace.yaml delete mode 100644 modules/k3s/netbird/server.yaml diff --git a/modules/k3s/k3s.nix b/modules/k3s/k3s.nix index b34742c..bd25ee9 100644 --- a/modules/k3s/k3s.nix +++ b/modules/k3s/k3s.nix @@ -1,17 +1,9 @@ { - networking.firewall.allowedTCPPorts = [ 6443 80 443 33073 ]; - networking.firewall.allowedUDPPorts = [ 3479 ]; + networking.firewall.allowedTCPPorts = [ 6443 80 443 ]; services.k3s = { enable = true; role = "server"; extraFlags = "--write-kubeconfig-mode 644"; - manifests = { - netbird-namespace = { source = ./netbird/namespace.yaml; }; - netbird-config = { source = ./netbird/config.yaml; }; - netbird-server = { source = ./netbird/server.yaml; }; - netbird-dashboard = { source = ./netbird/dashboard.yaml; }; - netbird-ingress = { source = ./netbird/ingress.yaml; }; - }; }; } diff --git a/modules/k3s/netbird/config.yaml b/modules/k3s/netbird/config.yaml deleted file mode 100644 index d3e22be..0000000 --- a/modules/k3s/netbird/config.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: netbird-server-config - namespace: netbird -data: - config.yaml.tpl: | - server: - listenAddress: ":80" - exposedAddress: "https://netbird.archfox.org:443" - metricsPort: 9090 - healthcheckAddress: ":9000" - logLevel: "info" - logFile: "console" - stunPorts: - - 3479 - tls: - certFile: "" - keyFile: "" - letsencrypt: - enabled: false - dataDir: "" - domains: [] - email: "" - awsRoute53: false - authSecret: "__AUTH_SECRET__" - dataDir: "/var/lib/netbird/" - disableAnonymousMetrics: false - disableGeoliteUpdate: false - auth: - issuer: "https://netbird.archfox.org/oauth2" - localAuthDisabled: false - signKeyRefreshEnabled: true - dashboardRedirectURIs: - - "https://netbird.archfox.org/nb-auth" - - "https://netbird.archfox.org/nb-silent-auth" - cliRedirectURIs: - - "http://localhost:53000/" - store: - engine: "sqlite" - dsn: "" - encryptionKey: "__STORE_ENCRYPTION_KEY__" - reverseProxy: - trustedHTTPProxies: - - "10.0.1.45/32" diff --git a/modules/k3s/netbird/dashboard.yaml b/modules/k3s/netbird/dashboard.yaml deleted file mode 100644 index 3766dfa..0000000 --- a/modules/k3s/netbird/dashboard.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: dashboard - namespace: netbird -spec: - replicas: 1 - selector: - matchLabels: - app: dashboard - template: - metadata: - labels: - app: dashboard - spec: - containers: - - name: dashboard - image: netbirdio/dashboard:latest - ports: - - containerPort: 80 - env: - - name: NETBIRD_MGMT_API_ENDPOINT - value: "https://netbird.archfox.org" - - name: NETBIRD_MGMT_GRPC_API_ENDPOINT - value: "https://netbird.archfox.org" - - name: AUTH_AUDIENCE - value: "netbird-dashboard" - - name: AUTH_CLIENT_ID - value: "netbird-dashboard" - - name: AUTH_CLIENT_SECRET - value: "" - - name: AUTH_AUTHORITY - value: "https://netbird.archfox.org/oauth2" - - name: USE_AUTH0 - value: "false" - - name: AUTH_SUPPORTED_SCOPES - value: "openid profile email groups" - - name: AUTH_REDIRECT_URI - value: "/nb-auth" - - name: AUTH_SILENT_REDIRECT_URI - value: "/nb-silent-auth" - - name: LETSENCRYPT_DOMAIN - value: "none" ---- -apiVersion: v1 -kind: Service -metadata: - name: dashboard - namespace: netbird -spec: - selector: - app: dashboard - ports: - - name: http - port: 80 - targetPort: 80 diff --git a/modules/k3s/netbird/ingress.yaml b/modules/k3s/netbird/ingress.yaml deleted file mode 100644 index 0a8c46d..0000000 --- a/modules/k3s/netbird/ingress.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: netbird - namespace: netbird -spec: - entryPoints: - - web - routes: - - match: Host(`netbird.archfox.org`) && (PathPrefix(`/management.ManagementService/`) || PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ProxyService/`)) - kind: Rule - services: - - name: netbird-server - port: 80 - scheme: h2c - - match: Host(`netbird.archfox.org`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`)) - kind: Rule - services: - - name: netbird-server - port: 80 - - match: Host(`netbird.archfox.org`) - kind: Rule - priority: 1 - services: - - name: dashboard - port: 80 diff --git a/modules/k3s/netbird/namespace.yaml b/modules/k3s/netbird/namespace.yaml deleted file mode 100644 index db05a13..0000000 --- a/modules/k3s/netbird/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: netbird diff --git a/modules/k3s/netbird/server.yaml b/modules/k3s/netbird/server.yaml deleted file mode 100644 index 158a6a5..0000000 --- a/modules/k3s/netbird/server.yaml +++ /dev/null @@ -1,96 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: netbird-server - namespace: netbird -spec: - replicas: 1 - selector: - matchLabels: - app: netbird-server - template: - metadata: - labels: - app: netbird-server - spec: - initContainers: - - name: render-config - image: busybox - env: - - name: AUTH_SECRET - valueFrom: - secretKeyRef: - name: netbird-relay-auth - key: authSecret - - name: STORE_KEY - valueFrom: - secretKeyRef: - name: netbird-encryption - key: encryptionKey - command: - - sh - - -c - - | - sed -e "s|__AUTH_SECRET__|$AUTH_SECRET|g" \ - -e "s|__STORE_ENCRYPTION_KEY__|$STORE_KEY|g" \ - /tpl/config.yaml.tpl > /etc/netbird/config.yaml - volumeMounts: - - name: config-tpl - mountPath: /tpl - - name: config-rendered - mountPath: /etc/netbird - containers: - - name: netbird-server - image: netbirdio/netbird-server:latest - args: ["--config", "/etc/netbird/config.yaml"] - ports: - - containerPort: 80 - - containerPort: 3479 - protocol: UDP - - containerPort: 33073 - volumeMounts: - - name: config-rendered - mountPath: /etc/netbird - - name: data - mountPath: /var/lib/netbird - volumes: - - name: config-tpl - configMap: - name: netbird-server-config - - name: config-rendered - emptyDir: {} - - name: data - persistentVolumeClaim: - claimName: netbird-data ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: netbird-data - namespace: netbird -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi ---- -apiVersion: v1 -kind: Service -metadata: - name: netbird-server - namespace: netbird -spec: - selector: - app: netbird-server - ports: - - name: http - port: 80 - targetPort: 80 - - name: grpc-compat - port: 33073 - targetPort: 33073 - - name: stun - port: 3479 - targetPort: 3479 - protocol: UDP From dac900756c8fd11a23a6e4435c39daa5be7ab3fa Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 30 Jul 2026 20:09:40 -0500 Subject: [PATCH 08/20] k3s: bind-mount apps/ from separate poslop/k3s repo, add traefik firewall port --- modules/k3s/k3s.nix | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/k3s/k3s.nix b/modules/k3s/k3s.nix index bd25ee9..9f0b0e4 100644 --- a/modules/k3s/k3s.nix +++ b/modules/k3s/k3s.nix @@ -1,9 +1,26 @@ { - networking.firewall.allowedTCPPorts = [ 6443 80 443 ]; + networking.firewall.allowedTCPPorts = [ 6443 80 443 33073 ]; + networking.firewall.allowedUDPPorts = [ 3479 ]; services.k3s = { enable = true; role = "server"; extraFlags = "--write-kubeconfig-mode 644"; }; + + # k3s manifests live in a separate repo (git.archfox.org/poslop/k3s), + # cloned at /home/poslop/k3s. Bind-mounting (not symlinking!) into + # k3s's manifest dir lets k3s's native recursive directory watch pick + # up new/changed files automatically -- no nixos-rebuild, no kubectl + # apply needed for changes under apps/. Symlinked dirs are explicitly + # NOT picked up by k3s's watcher (see k3s-io/k3s#9288), hence bind mount. + # + # TODO: once Flux is set up, replace this bind mount with a Flux + # GitRepository/Kustomization pointing at the same repo, and remove + # this fileSystems entry. + fileSystems."/var/lib/rancher/k3s/server/manifests/apps" = { + device = "/home/poslop/k3s/apps"; + fsType = "none"; + options = [ "bind" "ro" ]; + }; } From 434e6dfb975d7ef03bf0622fb324141573091b4f Mon Sep 17 00:00:00 2001 From: poslop Date: Thu, 30 Jul 2026 21:05:15 -0500 Subject: [PATCH 09/20] k3s: allow traefik dashboard port 8969 --- modules/k3s/k3s.nix | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/modules/k3s/k3s.nix b/modules/k3s/k3s.nix index 9f0b0e4..d5310cc 100644 --- a/modules/k3s/k3s.nix +++ b/modules/k3s/k3s.nix @@ -1,5 +1,11 @@ { - networking.firewall.allowedTCPPorts = [ 6443 80 443 33073 ]; + networking.firewall.allowedTCPPorts = [ + 6443 + 80 + 443 + 8969 + 33073 + ]; networking.firewall.allowedUDPPorts = [ 3479 ]; services.k3s = { @@ -8,19 +14,12 @@ extraFlags = "--write-kubeconfig-mode 644"; }; - # k3s manifests live in a separate repo (git.archfox.org/poslop/k3s), - # cloned at /home/poslop/k3s. Bind-mounting (not symlinking!) into - # k3s's manifest dir lets k3s's native recursive directory watch pick - # up new/changed files automatically -- no nixos-rebuild, no kubectl - # apply needed for changes under apps/. Symlinked dirs are explicitly - # NOT picked up by k3s's watcher (see k3s-io/k3s#9288), hence bind mount. - # - # TODO: once Flux is set up, replace this bind mount with a Flux - # GitRepository/Kustomization pointing at the same repo, and remove - # this fileSystems entry. fileSystems."/var/lib/rancher/k3s/server/manifests/apps" = { device = "/home/poslop/k3s/apps"; fsType = "none"; - options = [ "bind" "ro" ]; + options = [ + "bind" + "ro" + ]; }; } From 590f4a70acfa188354dc4d9c508a92399fc89112 Mon Sep 17 00:00:00 2001 From: poslop Date: Wed, 19 Aug 2026 16:59:01 -0500 Subject: [PATCH 10/20] flake.lock: bump inputs (hyprland, flake-parts, hermes-agent) --- flake.lock | 148 +++++++++++++++++++++++------------------------------ 1 file changed, 63 insertions(+), 85 deletions(-) diff --git a/flake.lock b/flake.lock index 2fc079a..a7510e0 100644 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1784368054, - "narHash": "sha256-zF1iJkBQSDWmRO4/LEeHR1SpKY0lqZaxkoQJpPS9K9U=", + "lastModified": 1786464219, + "narHash": "sha256-WKqWL8r7CyTDYueTr2ffJ9ya50dellv6IR1JX5PghDY=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "9b5f14d9483445e766294eb8fbe0b8f370269ed0", + "rev": "f3d1804205e8158c15595cdda1b566f93349ffae", "type": "github" }, "original": { @@ -100,11 +100,11 @@ ] }, "locked": { - "lastModified": 1772408722, - "narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=", + "lastModified": 1782949081, + "narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3", + "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", "type": "github" }, "original": { @@ -123,11 +123,11 @@ "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1784644108, - "narHash": "sha256-WFwNw701EOVHRwEpgifbYQaT68LOxATKDTXaep82yN4=", + "lastModified": 1787081890, + "narHash": "sha256-Ray82kTcLBd9249yAqC5lK4ew0b6d578SNjs3/JpUjE=", "owner": "NousResearch", "repo": "hermes-agent", - "rev": "d604141d097eec4a49493ad1eaceb9b2ca1e496d", + "rev": "de213b5210af6f635720035fc7dc331f0a3ec012", "type": "github" }, "original": { @@ -143,11 +143,11 @@ ] }, "locked": { - "lastModified": 1784601896, - "narHash": "sha256-rkpUOBv9pVG+GxhK90ebCrFpvjnfP4u2y/iGrzA42K4=", + "lastModified": 1785929776, + "narHash": "sha256-qwppDYdtxqtDpI1iSp7bs8prOJ0KQSvhJchfROD04f0=", "owner": "feel-co", "repo": "hjem", - "rev": "35e95ebb9557ac41a72fe00dd55218d1a7f21679", + "rev": "b610953d0c56da6b28fd39c21bd193b88e91341c", "type": "github" }, "original": { @@ -161,17 +161,16 @@ "hjem": [ "hjem" ], - "nix-darwin": "nix-darwin", "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1784361899, - "narHash": "sha256-QIzbnJIwy5cMYvPmLYPA4ar0lhficYLKZ6ytcHK90Uo=", + "lastModified": 1786806107, + "narHash": "sha256-QQecd6eWZj41JaWf2MoTtKj55N9o4OfnQYk7S5SsJWI=", "owner": "snugnug", "repo": "hjem-rum", - "rev": "73f6d1c01fe94e3de1cb3a84b9346da52f483c60", + "rev": "5b60842e8f76ae5e818b502f874c469a92930d42", "type": "github" }, "original": { @@ -217,11 +216,11 @@ ] }, "locked": { - "lastModified": 1776511930, - "narHash": "sha256-fCpwFiTW0rT7oKJqr3cqHMnkwypSwQKpbtUEtxdkgrM=", + "lastModified": 1786464181, + "narHash": "sha256-2alOMkLjXANh7unkZnYnCF2K2rApZaOLMoQ3o+VX2CY=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "39435900785d0c560c6ae8777d29f28617d031ef", + "rev": "e4ed7c08123df5af460a0a70961380cbfb872f76", "type": "github" }, "original": { @@ -246,11 +245,11 @@ ] }, "locked": { - "lastModified": 1782566056, - "narHash": "sha256-haEZcHzYrePnjFOYSWTbxm/Nrla0aPslJfmvdCvqtVc=", + "lastModified": 1786464367, + "narHash": "sha256-k58p4wbzIXWyRWrW84pP8tD+iaZSSYiiM+fr0Auk4oU=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "c6e7b9f673f4360bc813d3dc75028f75ee88d3f8", + "rev": "7c895c44e3ca6d28ed68ddd80ec02b02b925e7fc", "type": "github" }, "original": { @@ -276,11 +275,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1784641930, - "narHash": "sha256-j1c/65skFvp1WPbHBlAfVWaeCz0Bgwr/WPwIg0H+Ncg=", + "lastModified": 1787078251, + "narHash": "sha256-4Y51BYE6U0u41BdcnQAjzc6LXrDaEqH7zrDSFurm+pk=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "1a3606234c59842340ad9a42baeeffe44a9d6cda", + "rev": "9d4f7a83ce2764ddb51b4ea01f8ae1e6f1c18f66", "type": "github" }, "original": { @@ -322,11 +321,11 @@ ] }, "locked": { - "lastModified": 1784196523, - "narHash": "sha256-ahtKMGXFJdlQNhatQm1+BBU/pGfGYnAqQt3vWvq4p8s=", + "lastModified": 1786464504, + "narHash": "sha256-7sHwM86KILQyHDHDuE2SDBlQ2jvZ0EW3hY7sW009/cg=", "owner": "hyprwm", "repo": "hyprland-guiutils", - "rev": "a6ccb6cb112ed5a244c0191fb972347ecfa893e0", + "rev": "4c30cf3097ea963c0e250749ee0c59f8b08816d6", "type": "github" }, "original": { @@ -376,11 +375,11 @@ ] }, "locked": { - "lastModified": 1777320127, - "narHash": "sha256-Qu+Wf2Bp5qUjyn2YpZNq8a7JyzTGowhT1knrwE38a9U=", + "lastModified": 1786464129, + "narHash": "sha256-339AkTlpMYSIvFuG0rnR+8Yg4/AZKeJalshJavlnKfg=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "090117506ddc3d7f26e650ff344d378c2ec329cc", + "rev": "9508458be316a0d70d37ebed1ab725ccd10411ff", "type": "github" }, "original": { @@ -428,11 +427,11 @@ ] }, "locked": { - "lastModified": 1782554491, - "narHash": "sha256-+p3MlyN/nqRefcf2IckPlGRUn9+hielqpS9XClbLleM=", + "lastModified": 1785930473, + "narHash": "sha256-DitTu625BhEYpZjtjxtGpjrEJwPwW+X/+jJvhSZNSJM=", "owner": "hyprwm", "repo": "hyprtoolkit", - "rev": "bdba25ced39ea39ab004a8f31593ba0b0ff1ca35", + "rev": "af515b69dfbe366dc7873aa1475cb2f4db3ebad7", "type": "github" }, "original": { @@ -453,11 +452,11 @@ ] }, "locked": { - "lastModified": 1784323413, - "narHash": "sha256-XnAVV+H4f8Xdv0yZcSwJ5kCjLyE8fHxPeLX6a3HSrAU=", + "lastModified": 1786464080, + "narHash": "sha256-W1hxvumEM57yV+QwsZ4QdAHEqOkr7e4S8VAkLX60qDE=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "5f03477ab3a005ff27c527486f551883535aea2f", + "rev": "c157fe1e3092b980cc69315a6631f89aff09dcce", "type": "github" }, "original": { @@ -478,11 +477,11 @@ ] }, "locked": { - "lastModified": 1777159683, - "narHash": "sha256-Jxixw6wZphUp+nHYxOKUYSckL17QMBx2d5Zp0rJHr1g=", + "lastModified": 1786464033, + "narHash": "sha256-QM8Qe4/L8lpdVN4bgwahmi+jyyc4fisseDMe4afcDxA=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "b8632713a6beaf28b56f2a7b0ab2fb7088dbb404", + "rev": "62e62c1ca23da17612c6890d4ad2064f575643db", "type": "github" }, "original": { @@ -507,11 +506,11 @@ ] }, "locked": { - "lastModified": 1778410714, - "narHash": "sha256-o6RzFj4nJXaPRY7EM01siuCQeT41RfwwmcmFQqwFJJg=", + "lastModified": 1786464294, + "narHash": "sha256-ZQsZ2WvBdkboCIyh8LStDPdAIARmxzn0XMNxxoOhjPE=", "owner": "hyprwm", "repo": "hyprwire", - "rev": "85148a8e612808cf5ddb25d0b3c5840f3498a7dc", + "rev": "4ce7cd6b6128c1ac41caf23c58a30a26b327f9dd", "type": "github" }, "original": { @@ -520,27 +519,6 @@ "type": "github" } }, - "nix-darwin": { - "inputs": { - "nixpkgs": [ - "hjem-rum", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1779036909, - "narHash": "sha256-zXcwYQGCT6pzinK+1dBB2ekTVtfxGZAapb3Evdcu4fY=", - "owner": "nix-darwin", - "repo": "nix-darwin", - "rev": "56c666e108467d87d13508936aade6d567f2a501", - "type": "github" - }, - "original": { - "owner": "nix-darwin", - "repo": "nix-darwin", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1754028485, @@ -559,11 +537,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1775036866, - "narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", + "lastModified": 1785318670, + "narHash": "sha256-dN6Ou5x/+23FZLEpYP3IffO+NyJFzUlGumt1uu3MMaY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6201e203d09599479a3b3450ed24fa81537ebc4e", + "rev": "0954f7ee2f6bb3dc7d4e3d0d8bcb8fd4bde4cfc5", "type": "github" }, "original": { @@ -575,11 +553,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1784356753, - "narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=", + "lastModified": 1786247143, + "narHash": "sha256-8S3Kcxs7D4UtxJxSJZz0m14CGhuW0MxfrIwJxeGWGnQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "61b7c44c4073f0b827768aff0049561b5110ea5a", + "rev": "279b4a8275f032c566576b3f181fa0f27197f588", "type": "github" }, "original": { @@ -591,11 +569,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1784497964, - "narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=", + "lastModified": 1787001381, + "narHash": "sha256-Ue1Yo8gfHdD4TMtNewhA4tkSYeFqXThju0nCyJc3ALo=", "owner": "nixos", "repo": "nixpkgs", - "rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163", + "rev": "ec2d622de0773551768cf98f3fc50cbcc003b9c5", "type": "github" }, "original": { @@ -664,11 +642,11 @@ ] }, "locked": { - "lastModified": 1772555609, - "narHash": "sha256-3BA3HnUvJSbHJAlJj6XSy0Jmu7RyP2gyB/0fL7XuEDo=", + "lastModified": 1785115949, + "narHash": "sha256-8AM37BfyGaL2v/SZyg4PupRxJ01Y4htvM+WrTjWrPpo=", "owner": "pyproject-nix", "repo": "build-system-pkgs", - "rev": "c37f66a953535c394244888598947679af231863", + "rev": "62c0d86027edb1c4f39a5facc09876348144f7c9", "type": "github" }, "original": { @@ -685,11 +663,11 @@ ] }, "locked": { - "lastModified": 1772865871, - "narHash": "sha256-/ZTSg97aouL0SlPHaokA4r3iuH9QzHVuWPACD2CUCFY=", + "lastModified": 1784591072, + "narHash": "sha256-zP/WaDxrRu8GANZM61+V2LT/7ycEEdoyLWn7M6WzU7M=", "owner": "pyproject-nix", "repo": "pyproject.nix", - "rev": "e537db02e72d553cea470976b9733581bcf5b3ed", + "rev": "e3b599ca2e7fcf93d4edf65d7f19bbf6491724f3", "type": "github" }, "original": { @@ -750,11 +728,11 @@ ] }, "locked": { - "lastModified": 1773039484, - "narHash": "sha256-+boo33KYkJDw9KItpeEXXv8+65f7hHv/earxpcyzQ0I=", + "lastModified": 1785277507, + "narHash": "sha256-9Tq3UDX2hD/aveW/HvkBlAmEwJTOlY5HQXJM+L5BGmE=", "owner": "pyproject-nix", "repo": "uv2nix", - "rev": "b68be7cfeacbed9a3fa38a2b5adc0cfb81d9bb1f", + "rev": "5a836d395cbf5fc22670eb98dd4aa4fc4d406977", "type": "github" }, "original": { @@ -791,11 +769,11 @@ ] }, "locked": { - "lastModified": 1784371182, - "narHash": "sha256-S8A1lezEalltWcCp3gAic5lssS0xTSISK6fKODefhOk=", + "lastModified": 1786464334, + "narHash": "sha256-/TBQT5rhBB2Dm4HoZzhGDaCwYmRTs3W3DPhMXFWc/BU=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "08d99f727944dd15e4740090305e31c5fb92a50a", + "rev": "9f0e9ff02739cd538d39bd706422dc50e9ca60dd", "type": "github" }, "original": { From 96865caaebc23ef727ed04a07bd019dddee10476 Mon Sep 17 00:00:00 2001 From: poslop Date: Wed, 19 Aug 2026 16:59:05 -0500 Subject: [PATCH 11/20] hermes-vm: narrow module import to modules/core --- hosts/hermes-vm/configuration.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosts/hermes-vm/configuration.nix b/hosts/hermes-vm/configuration.nix index 9203c1e..a3d6a2d 100644 --- a/hosts/hermes-vm/configuration.nix +++ b/hosts/hermes-vm/configuration.nix @@ -3,7 +3,7 @@ { imports = [ ./hardware-configuration.nix - ../../modules + ../../modules/core ../../modules/hermes ]; From d0dc1743e167c456e47f7df0a7be9181280e9b76 Mon Sep 17 00:00:00 2001 From: poslop Date: Wed, 19 Aug 2026 16:59:08 -0500 Subject: [PATCH 12/20] core/network: enable netbird --- modules/core/network.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/core/network.nix b/modules/core/network.nix index c102531..6bde584 100644 --- a/modules/core/network.nix +++ b/modules/core/network.nix @@ -3,4 +3,6 @@ { networking.hostName = host; networking.networkmanager.enable = true; + + services.netbird.enable = true; } From 7ae32770d5dfee454df86890953d4334fc2f144e Mon Sep 17 00:00:00 2001 From: poslop Date: Wed, 19 Aug 2026 16:59:13 -0500 Subject: [PATCH 13/20] hermes: add serve and dashboard services, run as hermes user - Add hermes-serve (port 9120) for desktop JSON-RPC backend - Add hermes-dashboard (port 9121) for web UI - Both docker exec with -u hermes to avoid root-owned files - Add BW_SERVERURL env var - Expose port 9120 in container extraOptions --- modules/hermes/hermes.nix | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/modules/hermes/hermes.nix b/modules/hermes/hermes.nix index fd345ec..b0cb530 100644 --- a/modules/hermes/hermes.nix +++ b/modules/hermes/hermes.nix @@ -1,6 +1,8 @@ { inputs, config, + lib, + pkgs, ... }: @@ -14,6 +16,10 @@ config.age.secrets.hermes-env.path ]; + environment = { + BW_SERVERURL = "https://vault.archfox.org"; + }; + container = { image = "debian:bookworm"; backend = "docker"; @@ -24,6 +30,8 @@ "9119:9119" "-p" "8642:8642" + "-p" + "9120:9120" ]; }; @@ -55,9 +63,66 @@ }; }; + # Hermes serve (desktop app JSON-RPC backend, headless) + # Port 9120 avoids conflict with the gateway's API server on 9119. + systemd.services.hermes-serve = { + description = "Hermes Agent Serve (desktop remote backend)"; + wantedBy = [ "multi-user.target" ]; + after = [ "hermes-agent.service" "network-online.target" ]; + wants = [ "network-online.target" ]; + requires = [ "hermes-agent.service" ]; + + serviceConfig = { + Type = "simple"; + Restart = "always"; + RestartSec = 5; + TimeoutStopSec = 15; + }; + + script = '' + exec ${pkgs.docker}/bin/docker exec -i -u hermes \ + -e HERMES_HOME=/data/.hermes \ + -e HOME=/home/hermes \ + hermes-agent \ + /data/current-package/bin/hermes serve \ + --host 0.0.0.0 \ + --port 9120 + ''; + }; + + # Hermes dashboard (web UI for browser access) + # Port 9121, full web dashboard with login page. + systemd.services.hermes-dashboard = { + description = "Hermes Agent Dashboard (web UI)"; + wantedBy = [ "multi-user.target" ]; + after = [ "hermes-agent.service" "network-online.target" ]; + wants = [ "network-online.target" ]; + requires = [ "hermes-agent.service" ]; + + serviceConfig = { + Type = "simple"; + Restart = "always"; + RestartSec = 5; + TimeoutStopSec = 15; + }; + + script = '' + exec ${pkgs.docker}/bin/docker exec -i -u hermes \ + -e HERMES_HOME=/data/.hermes \ + -e HOME=/home/hermes \ + hermes-agent \ + /data/current-package/bin/hermes dashboard \ + --host 0.0.0.0 \ + --port 9121 \ + --no-open + ''; + }; + networking.firewall.allowedTCPPorts = [ 8080 9119 + 9120 + 9121 8642 ]; } From d54d954dffcb83830db346bda5679a59aa54a79b Mon Sep 17 00:00:00 2001 From: poslop Date: Wed, 19 Aug 2026 16:59:16 -0500 Subject: [PATCH 14/20] secrets: re-encrypt hermes-env.age --- modules/hermes/secrets/hermes-env.age | Bin 798 -> 1162 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modules/hermes/secrets/hermes-env.age b/modules/hermes/secrets/hermes-env.age index f383b245a9c4d54d68ef069c932c5d73cfbe8d85..8c8124db450569b6bb24e4bcd1a8343129887f70 100644 GIT binary patch delta 1133 zcmV-z1d{un28s!gEPrlhR53($Z$x2nY+E_HBB~dMq^h?QBQPiRbe?|bxKH7Zwf6f zEg&&$Hh4m4LU~4LSz<#>b!bCQcSkuwHg->UZZK z==QpoYW`EQLhZ*lv3$V|$0Q4uhdw*X?FG6(P`h%X5T0yYR&CtcIS*(7wQCRh$FM}| zB9xm}mda1HlFt!Uk(qN%$yjhJCOl7i&PcRudncYDP!*Yq4RQhid)9NOi~wxi0p<-g zAVhh^U)~fbzkfKU%j?Err+|!AnRi_jtUM6*Vc#9)wW?0jdL6V|h&-;K$Fn_WV4c3P z%-&3k3m4qjt(x}o74#Wafa-`XZrboi1Vl>?%1zWyk|tIr(X3;3YY|V4lZW7in+u`ZGkacr2kblfwi{h5e`j*Md|5>w;hfJSq z_HT0{jIo*-VuXBKbYzW6!)CG9c_D1hd6SRfqR0L{SRvMJIj$BR3}D=IP|<^2l0mTo zC$%$eIceXAv<(CE<-pVbD_JDhNHM|{Zs>yLeuvtXz$YG72+GYX;W@d`pRt0$I>U<1 zqMQqmVt?`Plrb12HYW$0GxXbQCN;pFTBRtqg&n`B;FFMw3IXwikd#9K_Y$iKIgdoU2{VDUnKF8Y)x-eEC8t!YskrQy1D{GxcX_}8`845_UEAw`}|WJOcV2b^=qsW5bOe}54c$^F;x$|E>z7bygJbGR>G&%wm5 z9AwGT9!xj$#oB_%Y+E+?M|u)4>cQ%#gt zF)i~gZiwxCzEq1iwulg$T_iFE3U4YU*5)5?V0WacLx1bXRzx{6I{4WGN%S99Sj?t1 z`+xSpn7oknR5{^2WXi5DTlEhnMB<#(u{FvmAkiL+2Z^ zH2FSBzNh@qL4rttS74&<98awyAOmcX{+hzG*`I1G+=cdiJ6$mMGc5H3FPw#KUyqzL z=3aR+w_r!>fFV|{910I3b+!1|iKV~upPK-ZD0q&nuORKtW-Ic!d~w#JODyag7H0aD zCv%smf^!=XDK;f);Lp=3oQD{Jyuz+Cq=8Yk=c|4QOO6`fh!@?JuoK37z>RA}G;%u% zs{}g`I(l5&5~+K&^*N-2t?uMqj$fJ0q}NTUzg+b3`_*#?-#M@T9AV%N4}tv8<_!{K delta 766 zcmVV9=XJl<}Ra#jzR#z)9$q^t);chOWt+7*}R zZ@#Kp99+#g%g}DuWEe2a*;h7S!3FZnX92nct?yeawk(=_wT zY=!txIMh*X|!P7>x$KfDURECbwc#F>v1AnJIi}&v}Bn=gb_vb`f9V=zX*$FjVT;Y zoIgmWrGJv-@>4wD<^TSrcxsIH76UjvTqGgwOP}zS09Y87dpL65feeLA-VB#SCb&76 zSrOej_bSo_ZJ%1YR}V63oLlm1OEK0F9ZyX9dTTbM$ij?&=tlY^YcWxndK`lgsXyA` zpd3gSn6(a+LrXudaoSHnQ#|f)42fy8Ya()-N_VU((~XMo0SZS!c0ZL@C$*Ybw?oaq zlqauTnIsXFYgM}}{7=HPY<}*wm6#6Xlyr;m3DlqtPGRu=<>r7>OPgidz<$19$mg>y wYn6C+|2vc|y4uMbD9KnO8{_RsQeWI1n5QsD7?|F2M7A*kaF4){=<%RVjm^ Date: Fri, 21 Aug 2026 09:40:56 -0500 Subject: [PATCH 15/20] flake update --- flake.lock | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index a7510e0..d5f546b 100644 --- a/flake.lock +++ b/flake.lock @@ -116,6 +116,7 @@ "hermes-agent": { "inputs": { "flake-parts": "flake-parts", + "home-manager": "home-manager_2", "nixpkgs": "nixpkgs_2", "npm-lockfile-fix": "npm-lockfile-fix", "pyproject-build-systems": "pyproject-build-systems", @@ -123,11 +124,11 @@ "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1787081890, - "narHash": "sha256-Ray82kTcLBd9249yAqC5lK4ew0b6d578SNjs3/JpUjE=", + "lastModified": 1787314587, + "narHash": "sha256-oeFJlEoFybqKkbuWT4mW8PRauusjt3y44ZJXAcA7TPY=", "owner": "NousResearch", "repo": "hermes-agent", - "rev": "de213b5210af6f635720035fc7dc331f0a3ec012", + "rev": "fcbd1076a93841fa88855acce810e342a5b78101", "type": "github" }, "original": { @@ -143,11 +144,11 @@ ] }, "locked": { - "lastModified": 1785929776, - "narHash": "sha256-qwppDYdtxqtDpI1iSp7bs8prOJ0KQSvhJchfROD04f0=", + "lastModified": 1787194407, + "narHash": "sha256-hMgbN6InoW+S5G/cqGrVwHUmOJcGIT/yUg1Xe6y7t8Q=", "owner": "feel-co", "repo": "hjem", - "rev": "b610953d0c56da6b28fd39c21bd193b88e91341c", + "rev": "7cd7f1c567beaf5527781e0b51647a98acde54e6", "type": "github" }, "original": { @@ -166,11 +167,11 @@ ] }, "locked": { - "lastModified": 1786806107, - "narHash": "sha256-QQecd6eWZj41JaWf2MoTtKj55N9o4OfnQYk7S5SsJWI=", + "lastModified": 1787315974, + "narHash": "sha256-LLToYudTlFqNY0NsG//CnE2I/zF0cpktX44ZhFJ2alY=", "owner": "snugnug", "repo": "hjem-rum", - "rev": "5b60842e8f76ae5e818b502f874c469a92930d42", + "rev": "217c6e1f445b3973ca8f988f070c9b84cceaa1ca", "type": "github" }, "original": { @@ -200,6 +201,27 @@ "type": "github" } }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "hermes-agent", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1786487128, + "narHash": "sha256-ad60hrRVhH/bo3Jl1YLzO+QcS3mUNZr9LNJdzhMO2P4=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "f404edbfa4117810c96b97048299242fc50e5362", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, "hyprcursor": { "inputs": { "hyprlang": [ @@ -275,11 +297,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1787078251, - "narHash": "sha256-4Y51BYE6U0u41BdcnQAjzc6LXrDaEqH7zrDSFurm+pk=", + "lastModified": 1787311583, + "narHash": "sha256-EXpfUX7oLzqwd+m/T1TvH/rHwnTNtZL+TZ5wiCwklMo=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "9d4f7a83ce2764ddb51b4ea01f8ae1e6f1c18f66", + "rev": "0f97a22d1172d8fbd77834ec932383ed18110edb", "type": "github" }, "original": { @@ -569,11 +591,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1787001381, - "narHash": "sha256-Ue1Yo8gfHdD4TMtNewhA4tkSYeFqXThju0nCyJc3ALo=", + "lastModified": 1787135253, + "narHash": "sha256-RD2kNWCG+Bjo6h+JVjWVNntZs2GtRoeY2xHjts/FNkA=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ec2d622de0773551768cf98f3fc50cbcc003b9c5", + "rev": "ffb3c9b700e759be2ef13237c9d8f953b32a1e46", "type": "github" }, "original": { From 3d15148c770bb11465305a87aa24814992e1c167 Mon Sep 17 00:00:00 2001 From: poslop Date: Fri, 28 Aug 2026 14:13:43 +0000 Subject: [PATCH 16/20] roles: add role-based host composition in flake - mkHost now takes a role list, roles resolve to ./roles/.nix - roles/core.nix = shared baseline (modules/) - roles/k3s-server.nix = core + k3s (goyplex-vm) - roles/hermes.nix = core + hermes (hermes-vm) - host configuration.nix trimmed to hardware + boot + stateVersion - optional hosts//custom.nix loads last for per-host overrides - new hosts: one flake line + hosts// dir --- flake.nix | 28 +++++++++++++++++++++------- hosts/goyplex-vm/configuration.nix | 7 ++++--- hosts/hermes-vm/configuration.nix | 7 ++++--- hosts/nixos-vm2/configuration.nix | 1 - hosts/qemu-vm/configuration.nix | 1 - roles/core.nix | 6 ++++++ roles/hermes.nix | 7 +++++++ roles/k3s-server.nix | 7 +++++++ 8 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 roles/core.nix create mode 100644 roles/hermes.nix create mode 100644 roles/k3s-server.nix diff --git a/flake.nix b/flake.nix index 65dd8a0..3109786 100644 --- a/flake.nix +++ b/flake.nix @@ -27,26 +27,40 @@ let system = "x86_64-linux"; username = "poslop"; + lib = nixpkgs.lib; + + # mkHost + # roles resolve to ./roles/.nix; list entries may also be + # inline attrsets or paths, which load after (and override) roles. + # hosts//custom.nix, if present, always loads last. mkHost = - host: modules: + name: roles: nixpkgs.lib.nixosSystem { - modules = [ { nixpkgs.hostPlatform = system; } ] ++ modules; + modules = + [ { nixpkgs.hostPlatform = system; } ] + ++ [ ./hosts/${name}/configuration.nix ] + ++ map ( + role: + if builtins.isString role then ./roles/${role}.nix else role + ) roles + ++ lib.optional (builtins.pathExists ./hosts/${name}/custom.nix) + ./hosts/${name}/custom.nix; specialArgs = { inherit self inputs username - host ; + host = name; }; }; in { nixosConfigurations = { - nixos-vm2 = mkHost "nixos-vm2" [ ./hosts/nixos-vm2/configuration.nix ]; - qemu-vm = mkHost "qemu-vm" [ ./hosts/qemu-vm/configuration.nix ]; - goyplex-vm = mkHost "goyplex-vm" [ ./hosts/goyplex-vm/configuration.nix ]; - hermes-vm = mkHost "hermes-vm" [ ./hosts/hermes-vm/configuration.nix ]; + nixos-vm2 = mkHost "nixos-vm2" [ "core" ]; + qemu-vm = mkHost "qemu-vm" [ "core" ]; + goyplex-vm = mkHost "goyplex-vm" [ "k3s-server" ]; + hermes-vm = mkHost "hermes-vm" [ "hermes" ]; }; }; } diff --git a/hosts/goyplex-vm/configuration.nix b/hosts/goyplex-vm/configuration.nix index ec77758..1f679a6 100644 --- a/hosts/goyplex-vm/configuration.nix +++ b/hosts/goyplex-vm/configuration.nix @@ -1,10 +1,11 @@ -{ pkgs, ... }: +{ + pkgs, + ... +}: { imports = [ ./hardware-configuration.nix - ../../modules - ../../modules/k3s/k3s.nix ]; boot.loader.systemd-boot.enable = true; diff --git a/hosts/hermes-vm/configuration.nix b/hosts/hermes-vm/configuration.nix index a3d6a2d..1f679a6 100644 --- a/hosts/hermes-vm/configuration.nix +++ b/hosts/hermes-vm/configuration.nix @@ -1,10 +1,11 @@ -{ pkgs, ... }: +{ + pkgs, + ... +}: { imports = [ ./hardware-configuration.nix - ../../modules/core - ../../modules/hermes ]; boot.loader.systemd-boot.enable = true; diff --git a/hosts/nixos-vm2/configuration.nix b/hosts/nixos-vm2/configuration.nix index fd54cb1..9b1c8dd 100644 --- a/hosts/nixos-vm2/configuration.nix +++ b/hosts/nixos-vm2/configuration.nix @@ -5,7 +5,6 @@ { imports = [ ./hardware-configuration.nix - ../../modules ]; boot.loader.grub.enable = true; diff --git a/hosts/qemu-vm/configuration.nix b/hosts/qemu-vm/configuration.nix index 866fe4e..62ebaa4 100644 --- a/hosts/qemu-vm/configuration.nix +++ b/hosts/qemu-vm/configuration.nix @@ -5,7 +5,6 @@ { imports = [ ./hardware-configuration.nix - ../../modules ]; boot.loader.grub.enable = true; diff --git a/roles/core.nix b/roles/core.nix new file mode 100644 index 0000000..5db7cb9 --- /dev/null +++ b/roles/core.nix @@ -0,0 +1,6 @@ +{ + # shared baseline: core system + home manager config + imports = [ + ../modules + ]; +} diff --git a/roles/hermes.nix b/roles/hermes.nix new file mode 100644 index 0000000..ebe73a8 --- /dev/null +++ b/roles/hermes.nix @@ -0,0 +1,7 @@ +{ + # hermes agent host: core + hermes container + secrets + imports = [ + ./core.nix + ../modules/hermes + ]; +} diff --git a/roles/k3s-server.nix b/roles/k3s-server.nix new file mode 100644 index 0000000..e7331bb --- /dev/null +++ b/roles/k3s-server.nix @@ -0,0 +1,7 @@ +{ + # k3s server node (goyplex-vm): k3s + manifests + firewall + imports = [ + ./core.nix + ../modules/k3s/k3s.nix + ]; +} From 5e0bcc53ff0253f497c7b66e173ddf64e812f6c5 Mon Sep 17 00:00:00 2001 From: poslop Date: Fri, 28 Aug 2026 09:21:45 -0500 Subject: [PATCH 17/20] write test --- .write-test | 1 + 1 file changed, 1 insertion(+) create mode 100644 .write-test diff --git a/.write-test b/.write-test new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/.write-test @@ -0,0 +1 @@ +test \ No newline at end of file From 041a8a36af86e57559f3e0a0abc5f55b7369a5fd Mon Sep 17 00:00:00 2001 From: poslop Date: Fri, 28 Aug 2026 14:22:26 +0000 Subject: [PATCH 18/20] remove write test file --- .write-test | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .write-test diff --git a/.write-test b/.write-test deleted file mode 100644 index 30d74d2..0000000 --- a/.write-test +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file From 4f777a9b962623eb0eec18d845bca8940fa5d42d Mon Sep 17 00:00:00 2001 From: poslop Date: Fri, 28 Aug 2026 09:23:08 -0500 Subject: [PATCH 19/20] hermes: glm-5.3-flash delegation, drop auxiliary block; flake.lock bump (live system state) --- flake.lock | 48 +++++++++++++++++++-------------------- modules/hermes/hermes.nix | 30 ++++++++++++++---------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/flake.lock b/flake.lock index d5f546b..f2d628a 100644 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1786464219, - "narHash": "sha256-WKqWL8r7CyTDYueTr2ffJ9ya50dellv6IR1JX5PghDY=", + "lastModified": 1787400831, + "narHash": "sha256-H3MEkFDZf+UH+QrVgW8TdKrssPFltF8fBg/rh0J1zIc=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "f3d1804205e8158c15595cdda1b566f93349ffae", + "rev": "7ce889cb78b97979b83a4648509fc3ef405c3286", "type": "github" }, "original": { @@ -124,11 +124,11 @@ "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1787314587, - "narHash": "sha256-oeFJlEoFybqKkbuWT4mW8PRauusjt3y44ZJXAcA7TPY=", + "lastModified": 1787852122, + "narHash": "sha256-QFOvSx7laGYIIPq+LNNEyrqxfSmXOrv+4Y80nKbXkjA=", "owner": "NousResearch", "repo": "hermes-agent", - "rev": "fcbd1076a93841fa88855acce810e342a5b78101", + "rev": "0dfba37b11ff2ca908ae2df85b55f4f4c9b7fd8b", "type": "github" }, "original": { @@ -144,11 +144,11 @@ ] }, "locked": { - "lastModified": 1787194407, - "narHash": "sha256-hMgbN6InoW+S5G/cqGrVwHUmOJcGIT/yUg1Xe6y7t8Q=", + "lastModified": 1787500880, + "narHash": "sha256-UrAlku7KST0DT+j1bdVGYI8tCz23PWL88uGMer3IZ2U=", "owner": "feel-co", "repo": "hjem", - "rev": "7cd7f1c567beaf5527781e0b51647a98acde54e6", + "rev": "d248f0e4f7abd6e1f0eb9ace778dd7928481943e", "type": "github" }, "original": { @@ -297,11 +297,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1787311583, - "narHash": "sha256-EXpfUX7oLzqwd+m/T1TvH/rHwnTNtZL+TZ5wiCwklMo=", + "lastModified": 1787842129, + "narHash": "sha256-+C4MYYZsT+JdgZj70g7ERYm4zjJRwRnwy7o1QHPW5eg=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "0f97a22d1172d8fbd77834ec932383ed18110edb", + "rev": "3b1aa6be7b8d672c7180ea616f9eca1992e227c3", "type": "github" }, "original": { @@ -474,11 +474,11 @@ ] }, "locked": { - "lastModified": 1786464080, - "narHash": "sha256-W1hxvumEM57yV+QwsZ4QdAHEqOkr7e4S8VAkLX60qDE=", + "lastModified": 1786903207, + "narHash": "sha256-QTwMqLLONRhv9iz6CVeuX6BqQNQCIqI8hL/cPYlR/24=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "c157fe1e3092b980cc69315a6631f89aff09dcce", + "rev": "6cf50415e06dc6bd9f1252f1b745eac6b4a1cc39", "type": "github" }, "original": { @@ -575,11 +575,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1786247143, - "narHash": "sha256-8S3Kcxs7D4UtxJxSJZz0m14CGhuW0MxfrIwJxeGWGnQ=", + "lastModified": 1787360063, + "narHash": "sha256-dt4WdcvsA8/RCe+VZZwqU0X+XMM3wBbGCWA0/sFWzGo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "279b4a8275f032c566576b3f181fa0f27197f588", + "rev": "2c423e03bbafcff28bfadc6781a4a8257f205cb5", "type": "github" }, "original": { @@ -591,11 +591,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1787135253, - "narHash": "sha256-RD2kNWCG+Bjo6h+JVjWVNntZs2GtRoeY2xHjts/FNkA=", + "lastModified": 1787736819, + "narHash": "sha256-cV5xEJJK3BvhU8rEd4mC9UsmDi5qscv/kzGPhBRC5WA=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ffb3c9b700e759be2ef13237c9d8f953b32a1e46", + "rev": "9fbb54b33e91ee4ca368e35a78e0613c720600b3", "type": "github" }, "original": { @@ -791,11 +791,11 @@ ] }, "locked": { - "lastModified": 1786464334, - "narHash": "sha256-/TBQT5rhBB2Dm4HoZzhGDaCwYmRTs3W3DPhMXFWc/BU=", + "lastModified": 1786988229, + "narHash": "sha256-frEFLVRj8xXvBBDs44IRiqHo6R2PxsRpluygL7abjjI=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "9f0e9ff02739cd538d39bd706422dc50e9ca60dd", + "rev": "59d429bf45aed4e2209043c0c36565ad8e2859a5", "type": "github" }, "original": { diff --git a/modules/hermes/hermes.nix b/modules/hermes/hermes.nix index b0cb530..0ed2df7 100644 --- a/modules/hermes/hermes.nix +++ b/modules/hermes/hermes.nix @@ -1,7 +1,6 @@ { inputs, config, - lib, pkgs, ... }: @@ -42,7 +41,17 @@ mcp_reload_confirm = "false"; }; + gateway = { + multiplex_profiles = true; + }; + + delegation = { + model = "z-ai/glm-5.3-flash"; + provider = "nous"; + }; + memory = { + provider = "holographic"; memory_enabled = true; user_profile_enabled = true; }; @@ -51,11 +60,6 @@ credits_notices = true; }; - delegation = { - model = "us.anthropic.claude-sonnet-5"; - provider = "bedrock"; - }; - discord = { group_sessions_per_user = false; reactions = false; @@ -63,12 +67,13 @@ }; }; - # Hermes serve (desktop app JSON-RPC backend, headless) - # Port 9120 avoids conflict with the gateway's API server on 9119. systemd.services.hermes-serve = { description = "Hermes Agent Serve (desktop remote backend)"; wantedBy = [ "multi-user.target" ]; - after = [ "hermes-agent.service" "network-online.target" ]; + after = [ + "hermes-agent.service" + "network-online.target" + ]; wants = [ "network-online.target" ]; requires = [ "hermes-agent.service" ]; @@ -90,12 +95,13 @@ ''; }; - # Hermes dashboard (web UI for browser access) - # Port 9121, full web dashboard with login page. systemd.services.hermes-dashboard = { description = "Hermes Agent Dashboard (web UI)"; wantedBy = [ "multi-user.target" ]; - after = [ "hermes-agent.service" "network-online.target" ]; + after = [ + "hermes-agent.service" + "network-online.target" + ]; wants = [ "network-online.target" ]; requires = [ "hermes-agent.service" ]; From cce057cb6c0763af309131d082216773c4d0b431 Mon Sep 17 00:00:00 2001 From: poslop Date: Fri, 28 Aug 2026 14:29:46 +0000 Subject: [PATCH 20/20] agenix: use stdenv.hostPlatform.system, fixes eval warning --- modules/hermes/secrets/agenix.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hermes/secrets/agenix.nix b/modules/hermes/secrets/agenix.nix index 182b916..02925cd 100644 --- a/modules/hermes/secrets/agenix.nix +++ b/modules/hermes/secrets/agenix.nix @@ -10,6 +10,6 @@ age.secrets."hermes-env".file = ./hermes-env.age; hjem.users.${username}.packages = with pkgs; [ - inputs.agenix.packages."${system}".default + inputs.agenix.packages."${pkgs.stdenv.hostPlatform.system}".default ]; }