From e07257e13723ec55035fc9f41f9b3f3f16feb986 Mon Sep 17 00:00:00 2001 From: Chris Kruining Date: Thu, 16 Apr 2026 15:36:33 +0200 Subject: [PATCH] checkpoint --- flake.nix | 4 ++ .../authentication/zitadel/default.nix | 11 ++- .../services/communication/matrix/default.nix | 36 ++++++++-- .../nixos/services/media/glance/default.nix | 10 +-- .../nixos/services/media/servarr/default.nix | 42 +++++++---- .../services/networking/caddy/default.nix | 2 + .../services/observability/alloy/default.nix | 23 +++--- .../observability/grafana/default.nix | 72 +++++++++---------- .../services/observability/tempo/default.nix | 21 +++--- .../nixos/temp/services/arrtrix/default.nix | 13 ++++ packages/arrtrix/pkg/runtime/envconfig.go | 50 +++++++++++++ .../arrtrix/pkg/runtime/envconfig_test.go | 57 +++++++++++++++ systems/x86_64-linux/ulmo/default.nix | 25 ------- .../ulmo/lidarr/api_key/machines/ulmo | 1 - .../ulmo/lidarr/api_key/users/chris | 1 - .../ulmo/lidarr/config.env/machines/ulmo | 1 - .../ulmo/lidarr/config.env/users/chris | 1 - .../ulmo/postgresql/.pgpass/machines/ulmo | 1 - .../ulmo/postgresql/.pgpass/users/chris | 1 - .../ulmo/postgresql/lidarr_hash/users/chris | 1 - .../postgresql/lidarr_password/users/chris | 1 - .../ulmo/postgresql/prowlarr_hash/users/chris | 1 - .../postgresql/prowlarr_password/users/chris | 1 - .../ulmo/postgresql/radarr_hash/users/chris | 1 - .../postgresql/radarr_password/users/chris | 1 - .../ulmo/postgresql/server.crt/machines/ulmo | 1 - .../ulmo/postgresql/server.crt/users/chris | 1 - .../ulmo/postgresql/server.key/machines/ulmo | 1 - .../ulmo/postgresql/server.key/users/chris | 1 - .../ulmo/postgresql/sonarr_hash/users/chris | 1 - .../postgresql/sonarr_password/users/chris | 1 - .../ulmo/prowlarr/api_key/machines/ulmo | 1 - .../ulmo/prowlarr/api_key/users/chris | 1 - .../ulmo/prowlarr/config.env/machines/ulmo | 1 - .../ulmo/prowlarr/config.env/users/chris | 1 - .../ulmo/qbittorrent/password/machines/ulmo | 1 - .../ulmo/qbittorrent/password/users/chris | 1 - .../qbittorrent/password_hash/machines/ulmo | 1 - .../qbittorrent/password_hash/users/chris | 1 - .../qBittorrent.conf/machines/ulmo | 1 - .../qbittorrent/qBittorrent.conf/users/chris | 1 - .../ulmo/radarr/api_key/machines/ulmo | 1 - .../ulmo/radarr/api_key/users/chris | 1 - .../ulmo/radarr/config.env/machines/ulmo | 1 - .../ulmo/radarr/config.env/users/chris | 1 - .../ulmo/sabnzbd/api_key/machines/ulmo | 1 - .../ulmo/sabnzbd/api_key/users/chris | 1 - .../ulmo/sabnzbd/config.ini/machines/ulmo | 1 - .../ulmo/sabnzbd/config.ini/users/chris | 1 - .../ulmo/sabnzbd/nzb_key/machines/ulmo | 1 - .../ulmo/sabnzbd/nzb_key/users/chris | 1 - .../ulmo/sabnzbd/password/machines/ulmo | 1 - .../ulmo/sabnzbd/password/users/chris | 1 - .../ulmo/sabnzbd/username/machines/ulmo | 1 - .../ulmo/sabnzbd/username/users/chris | 1 - .../ulmo/servarr/config.tfvars/machines/ulmo | 1 - .../ulmo/servarr/config.tfvars/users/chris | 1 - .../ulmo/sonarr/api_key/machines/ulmo | 1 - .../ulmo/sonarr/api_key/users/chris | 1 - .../ulmo/sonarr/config.env/machines/ulmo | 1 - .../ulmo/sonarr/config.env/users/chris | 1 - 61 files changed, 258 insertions(+), 156 deletions(-) create mode 100644 packages/arrtrix/pkg/runtime/envconfig_test.go delete mode 120000 vars/per-machine/ulmo/lidarr/api_key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/lidarr/api_key/users/chris delete mode 120000 vars/per-machine/ulmo/lidarr/config.env/machines/ulmo delete mode 120000 vars/per-machine/ulmo/lidarr/config.env/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/.pgpass/machines/ulmo delete mode 120000 vars/per-machine/ulmo/postgresql/.pgpass/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/lidarr_hash/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/lidarr_password/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/prowlarr_hash/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/prowlarr_password/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/radarr_hash/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/radarr_password/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/server.crt/machines/ulmo delete mode 120000 vars/per-machine/ulmo/postgresql/server.crt/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/server.key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/postgresql/server.key/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/sonarr_hash/users/chris delete mode 120000 vars/per-machine/ulmo/postgresql/sonarr_password/users/chris delete mode 120000 vars/per-machine/ulmo/prowlarr/api_key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/prowlarr/api_key/users/chris delete mode 120000 vars/per-machine/ulmo/prowlarr/config.env/machines/ulmo delete mode 120000 vars/per-machine/ulmo/prowlarr/config.env/users/chris delete mode 120000 vars/per-machine/ulmo/qbittorrent/password/machines/ulmo delete mode 120000 vars/per-machine/ulmo/qbittorrent/password/users/chris delete mode 120000 vars/per-machine/ulmo/qbittorrent/password_hash/machines/ulmo delete mode 120000 vars/per-machine/ulmo/qbittorrent/password_hash/users/chris delete mode 120000 vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/machines/ulmo delete mode 120000 vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/users/chris delete mode 120000 vars/per-machine/ulmo/radarr/api_key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/radarr/api_key/users/chris delete mode 120000 vars/per-machine/ulmo/radarr/config.env/machines/ulmo delete mode 120000 vars/per-machine/ulmo/radarr/config.env/users/chris delete mode 120000 vars/per-machine/ulmo/sabnzbd/api_key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sabnzbd/api_key/users/chris delete mode 120000 vars/per-machine/ulmo/sabnzbd/config.ini/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sabnzbd/config.ini/users/chris delete mode 120000 vars/per-machine/ulmo/sabnzbd/nzb_key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sabnzbd/nzb_key/users/chris delete mode 120000 vars/per-machine/ulmo/sabnzbd/password/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sabnzbd/password/users/chris delete mode 120000 vars/per-machine/ulmo/sabnzbd/username/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sabnzbd/username/users/chris delete mode 120000 vars/per-machine/ulmo/servarr/config.tfvars/machines/ulmo delete mode 120000 vars/per-machine/ulmo/servarr/config.tfvars/users/chris delete mode 120000 vars/per-machine/ulmo/sonarr/api_key/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sonarr/api_key/users/chris delete mode 120000 vars/per-machine/ulmo/sonarr/config.env/machines/ulmo delete mode 120000 vars/per-machine/ulmo/sonarr/config.env/users/chris diff --git a/flake.nix b/flake.nix index 7ccab59..692afe1 100644 --- a/flake.nix +++ b/flake.nix @@ -1,6 +1,10 @@ { description = "Nixos config flake"; + nixConfig = { + warn-dirty = false; + }; + inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; diff --git a/modules/nixos/services/authentication/zitadel/default.nix b/modules/nixos/services/authentication/zitadel/default.nix index 7674835..6e42eeb 100644 --- a/modules/nixos/services/authentication/zitadel/default.nix +++ b/modules/nixos/services/authentication/zitadel/default.nix @@ -1,9 +1,10 @@ { config, lib, pkgs, namespace, system, inputs, ... }: let - inherit (lib) mkIf mkEnableOption mkOption types toUpper toSentenceCase nameValuePair mapAttrs mapAttrs' concatMapAttrs concatMapStringsSep filterAttrsRecursive listToAttrs imap0 head drop length literalExpression attrNames; + inherit (lib) mkIf mkEnableOption mkOption toString types toUpper toSentenceCase nameValuePair mapAttrs mapAttrs' concatMapAttrs concatMapStringsSep filterAttrsRecursive listToAttrs imap0 head drop length literalExpression attrNames; inherit (lib.${namespace}.strings) toSnakeCase; cfg = config.${namespace}.services.authentication.zitadel; + port = 3010; database = "zitadel"; in @@ -543,12 +544,12 @@ in networking.caddy = { hosts = { "auth.kruining.eu" = '' - reverse_proxy h2c://[::1]:9092 + reverse_proxy h2c://[::1]:${toString port} ''; }; extraConfig = '' (auth) { - forward_auth h2c://[::1]:9092 { + forward_auth h2c://[::1]:${toString port} { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } @@ -612,7 +613,7 @@ in masterKeyFile = config.sops.secrets."zitadel/masterKey".path; tlsMode = "external"; settings = { - Port = 9092; + Port = port; ExternalDomain = "auth.kruining.eu"; ExternalPort = 443; @@ -698,8 +699,6 @@ in }; }; - networking.firewall.allowedTCPPorts = [ 80 443 ]; - # Secrets sops = { secrets = { diff --git a/modules/nixos/services/communication/matrix/default.nix b/modules/nixos/services/communication/matrix/default.nix index cd5aff2..4661f2a 100644 --- a/modules/nixos/services/communication/matrix/default.nix +++ b/modules/nixos/services/communication/matrix/default.nix @@ -112,9 +112,29 @@ in { (mkMautrix "mautrix-telegram" 2 {}) (mkMautrix "mautrix-whatsapp" 3 {}) (mkMautrix "arrtrix" 4 { - settings.observability = { - otlp_grpc_endpoint = "http://[::1]:1000"; - service_name = "arrtrix"; + environmentFile = config.sops.templates."arrtrix/secrets".path; + + settings = { + observability = { + otlp_grpc_endpoint = "http://[::1]:9062"; + service_name = "arrtrix"; + }; + + network.content = { + movies = { + url = "http://[::1]:${toString config.services.radarr.settings.server.port}"; + api_key = "$RADARR_APIKEY"; + root_folder_path = "/var/media/movies"; + quality_profile_id = 5; + }; + series = { + url = "http://[::1]:${toString config.services.radarr.settings.server.port}"; + api_key = "$SONARR_APIKEY"; + root_folder_path = "/var/media/series"; + quality_profile_id = 5; + language_profile_id = 1; + }; + }; }; }) { @@ -167,7 +187,7 @@ in { }; sso = { - client_whitelist = ["http://[::1]:9092/" "https://auth.kruining.eu/"]; + client_whitelist = ["http://[::1]:${toString config.services.zitadel.settings.Port}/" "https://auth.kruining.eu/"]; update_profile_information = true; }; @@ -365,6 +385,14 @@ in { ''; restartUnits = ["matrix-synapse.service"]; }; + "arrtrix/secrets" = { + owner = "arrtrix"; + content = '' + RADARR_APIKEY=${config.sops.placeholder."radarr/apikey"} + SONARR_APIKEY=${config.sops.placeholder."sonarr/apikey"} + ''; + restartUnits = ["arrtrix.service"]; + }; }; }; }; diff --git a/modules/nixos/services/media/glance/default.nix b/modules/nixos/services/media/glance/default.nix index b042297..bdd4c87 100644 --- a/modules/nixos/services/media/glance/default.nix +++ b/modules/nixos/services/media/glance/default.nix @@ -13,11 +13,11 @@ in { }; config = mkIf cfg.enable { - ${namespace}.services.networking.caddy.hosts = { - "https://${config.networking.hostName}:443" = '' - reverse_proxy http://[::1]:2000 - ''; - }; + # ${namespace}.services.networking.caddy.hosts = { + # "https://${config.networking.hostName}.arda:443" = '' + # reverse_proxy http://[::1]:2000 + # ''; + # }; services.glance = { enable = true; diff --git a/modules/nixos/services/media/servarr/default.nix b/modules/nixos/services/media/servarr/default.nix index 18932b1..ed9b94a 100644 --- a/modules/nixos/services/media/servarr/default.nix +++ b/modules/nixos/services/media/servarr/default.nix @@ -56,7 +56,8 @@ in { auth.authenticationMethod = "External"; server = { - bindaddress = "0.0.0.0"; + # bindaddress = "0.0.0.0"; + bindaddress = "[::]"; port = port; }; @@ -194,7 +195,7 @@ in { source = "devopsarr/${service}"; version = { - radarr = "2.3.3"; + radarr = "2.3.5"; sonarr = "3.4.0"; prowlarr = "3.1.0"; lidarr = "1.13.0"; @@ -217,10 +218,15 @@ in { { method = 1; # HTTP METHOD 1=POST, 2=PUT name = "Arrtrix"; - url = "http://[::1]${toString config'.services.arrtrix.settings.appservice.port}"; + url = "http://localhost:${toString config'.services.arrtrix.settings.appservice.port}/_arrtrix/webhook"; + + on_grab = true; + on_download = true; + on_rename = true; + on_upgrade = true; } // (lib.optionalAttrs (lib.elem service ["radarr" "whisparr"]) { - onMovieDelete = true; + on_movie_delete = true; }); }; @@ -244,15 +250,25 @@ in { }; "${service}_download_client_sabnzbd" = mkIf (lib.elem service ["radarr" "sonarr" "lidarr" "whisparr"]) { - "main" = { - name = "SABnzbd"; - enable = true; - priority = 1; - host = "localhost"; - api_key = lib.tfRef "var.sabnzbd_api_key"; - url_base = "/"; - port = 2090; - }; + "main" = + { + name = "SABnzbd"; + enable = true; + priority = 1; + host = "localhost"; + api_key = lib.tfRef "var.sabnzbd_api_key"; + url_base = "/"; + port = 2090; + } + // ({ + radarr = {movie_category = "movies";}; + sonarr = {tv_category = "tv";}; + lidarr = {music_category = "audio";}; + whisparr = {movie_category = "movies";}; + readarr = {book_category = "Default";}; + }.${ + service + }); }; } // (lib.optionalAttrs (service == "prowlarr") ( diff --git a/modules/nixos/services/networking/caddy/default.nix b/modules/nixos/services/networking/caddy/default.nix index e18a707..21ab908 100644 --- a/modules/nixos/services/networking/caddy/default.nix +++ b/modules/nixos/services/networking/caddy/default.nix @@ -24,6 +24,8 @@ in { }; config = mkIf hasHosts { + networking.firewall.allowedTCPPorts = [80 443]; + services.caddy = { enable = cfg.enable; diff --git a/modules/nixos/services/observability/alloy/default.nix b/modules/nixos/services/observability/alloy/default.nix index c6f5cac..3b64f2e 100644 --- a/modules/nixos/services/observability/alloy/default.nix +++ b/modules/nixos/services/observability/alloy/default.nix @@ -1,5 +1,9 @@ -{ config, lib, namespace, ... }: -let +{ + config, + lib, + namespace, + ... +}: let inherit (builtins) toString; inherit (lib) mkEnableOption mkIf; @@ -9,8 +13,7 @@ let otlpGrpcPort = 9071; otlpHttpPort = 9072; tempoOtlpGrpcPort = 9062; -in -{ +in { options.${namespace}.services.observability.alloy = { enable = mkEnableOption "enable Grafana Alloy"; }; @@ -21,7 +24,7 @@ in configPath = "/etc/alloy"; extraFlags = [ "--disable-reporting" - "--server.http.listen-addr=0.0.0.0:${toString httpPort}" + "--server.http.listen-addr=[::]:${toString httpPort}" "--storage.path=/var/lib/alloy" ]; }; @@ -29,11 +32,11 @@ in environment.etc."alloy/config.alloy".text = '' otelcol.receiver.otlp "default" { grpc { - endpoint = "127.0.0.1:${toString otlpGrpcPort}" + endpoint = "[::1]:${toString otlpGrpcPort}" } http { - endpoint = "127.0.0.1:${toString otlpHttpPort}" + endpoint = "[::1]:${toString otlpHttpPort}" } output { @@ -60,13 +63,13 @@ in prometheus.remote_write "local" { endpoint { - url = "http://127.0.0.1:${toString config.services.prometheus.port}/api/v1/write" + url = "http://[::1]:${toString config.services.prometheus.port}/api/v1/write" } } otelcol.exporter.otlp "tempo" { client { - endpoint = "127.0.0.1:${toString tempoOtlpGrpcPort}" + endpoint = "[::1]:${toString tempoOtlpGrpcPort}" tls { insecure = true @@ -75,6 +78,6 @@ in } ''; - networking.firewall.allowedTCPPorts = [ httpPort ]; + networking.firewall.allowedTCPPorts = [httpPort]; }; } diff --git a/modules/nixos/services/observability/grafana/default.nix b/modules/nixos/services/observability/grafana/default.nix index d9308c0..363033c 100644 --- a/modules/nixos/services/observability/grafana/default.nix +++ b/modules/nixos/services/observability/grafana/default.nix @@ -26,7 +26,7 @@ in { settings = { server = { http_port = 9010; - http_addr = "0.0.0.0"; + http_addr = "::"; domain = "ulmo"; }; @@ -102,43 +102,43 @@ in { }; datasources.settings.datasources = [ - { - name = "Prometheus"; - uid = "prometheus"; - type = "prometheus"; - url = "http://localhost:9020"; - isDefault = true; - editable = false; - } + # { + # name = "Prometheus"; + # uid = "prometheus"; + # type = "prometheus"; + # url = "http://[::1]:9020"; + # isDefault = true; + # editable = false; + # } - { - name = "Loki"; - uid = "loki"; - type = "loki"; - url = "http://localhost:9030"; - editable = false; - } + # { + # name = "Loki"; + # uid = "loki"; + # type = "loki"; + # url = "http://[::1]:9030"; + # editable = false; + # } - { - name = "Tempo"; - uid = "tempo"; - type = "tempo"; - url = "http://localhost:9060"; - editable = false; - jsonData = { - nodeGraph.enabled = true; - serviceMap.datasourceUid = "prometheus"; - tracesToLogsV2 = { - datasourceUid = "loki"; - filterByTraceID = true; - spanStartTimeShift = "-1h"; - spanEndTimeShift = "1h"; - }; - }; - } - ]; - }; - }; + # { + # name = "Tempo"; + # uid = "tempo"; + # type = "tempo"; + # url = "http://localhost:9060"; + # editable = false; + # jsonData = { + # nodeGraph.enabled = true; + # serviceMap.datasourceUid = "prometheus"; + # tracesToLogsV2 = { + # datasourceUid = "loki"; + # filterByTraceID = true; + # spanStartTimeShift = "-1h"; + # spanEndTimeShift = "1h"; + # }; + # }; + # } + ]; + }; + }; postgresql = { enable = true; diff --git a/modules/nixos/services/observability/tempo/default.nix b/modules/nixos/services/observability/tempo/default.nix index dd0602c..46339bc 100644 --- a/modules/nixos/services/observability/tempo/default.nix +++ b/modules/nixos/services/observability/tempo/default.nix @@ -1,5 +1,9 @@ -{ config, lib, namespace, ... }: -let +{ + config, + lib, + namespace, + ... +}: let inherit (lib) mkEnableOption mkIf; cfg = config.${namespace}.services.observability.tempo; @@ -8,8 +12,7 @@ let grpcPort = 9061; otlpGrpcPort = 9062; otlpHttpPort = 9063; -in -{ +in { options.${namespace}.services.observability.tempo = { enable = mkEnableOption "enable Grafana Tempo"; }; @@ -22,15 +25,15 @@ in search_enabled = true; server = { - http_listen_address = "0.0.0.0"; + http_listen_address = "[::]"; http_listen_port = httpPort; - grpc_listen_address = "127.0.0.1"; + grpc_listen_address = "[::1]"; grpc_listen_port = grpcPort; }; distributor.receivers.otlp.protocols = { - grpc.endpoint = "127.0.0.1:${builtins.toString otlpGrpcPort}"; - http.endpoint = "127.0.0.1:${builtins.toString otlpHttpPort}"; + grpc.endpoint = "[::1]:${builtins.toString otlpGrpcPort}"; + http.endpoint = "[::1]:${builtins.toString otlpHttpPort}"; }; storage.trace = { @@ -43,6 +46,6 @@ in }; }; - networking.firewall.allowedTCPPorts = [ httpPort ]; + networking.firewall.allowedTCPPorts = [httpPort]; }; } diff --git a/modules/nixos/temp/services/arrtrix/default.nix b/modules/nixos/temp/services/arrtrix/default.nix index 0e0d5c8..6bb1d9f 100644 --- a/modules/nixos/temp/services/arrtrix/default.nix +++ b/modules/nixos/temp/services/arrtrix/default.nix @@ -106,6 +106,18 @@ in { example = {}; }; + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing environment variables to be passed to the arrtrix service. + If an environment variable `ARRTRIX_BRIDGE_LOGIN_SHARED_SECRET` is set, + then its value will be used in the configuration file for the option + `double_puppet.secrets` without leaking it to the store, using the configured + `homeserver.domain` as key. + ''; + }; + serviceDependencies = lib.mkOption { type = with lib.types; listOf str; default = @@ -168,6 +180,7 @@ in { StateDirectory = baseNameOf dataDir; WorkingDirectory = dataDir; + EnvironmentFile = cfg.environmentFile; ExecStart = '' ${lib.getExe cfg.package} --config='${settingsFile}' --registration='${registrationFile}' diff --git a/packages/arrtrix/pkg/runtime/envconfig.go b/packages/arrtrix/pkg/runtime/envconfig.go index f8ffd13..173de78 100644 --- a/packages/arrtrix/pkg/runtime/envconfig.go +++ b/packages/arrtrix/pkg/runtime/envconfig.go @@ -36,12 +36,16 @@ func updateConfigFromEnv(cfg, networkData any, prefix string) error { } key = strings.ToLower(key) + lookupKey := key if !strings.ContainsRune(key, '.') { key = strings.ReplaceAll(key, "__", ".") } path := strings.Split(key, ".") field, ok := reflectGetFromMainOrNetwork(cfgVal, networkVal, path) + if !ok && !strings.ContainsRune(lookupKey, '.') { + field, ok = reflectGetFromMainOrNetworkTokens(cfgVal, networkVal, strings.Split(lookupKey, "_")) + } if !ok { return fmt.Errorf("%s not found", formatKey(path)) } @@ -80,6 +84,13 @@ func reflectGetFromMainOrNetwork(main, network reflect.Value, path []string) (*r return reflectGetYAML(main, path) } +func reflectGetFromMainOrNetworkTokens(main, network reflect.Value, tokens []string) (*reflectedField, bool) { + if len(tokens) > 0 && normalizeKey(tokens[0]) == "network" { + return reflectGetYAMLTokens(network, tokens[1:]) + } + return reflectGetYAMLTokens(main, tokens) +} + func reflectGetYAML(value reflect.Value, path []string) (*reflectedField, bool) { if len(path) == 0 { return &reflectedField{value: value, valueKind: value.Kind()}, true @@ -108,6 +119,41 @@ func reflectGetYAML(value reflect.Value, path []string) (*reflectedField, bool) return nil, false } +func reflectGetYAMLTokens(value reflect.Value, tokens []string) (*reflectedField, bool) { + if len(tokens) == 0 { + return &reflectedField{value: value, valueKind: value.Kind()}, true + } + if value.Kind() == reflect.Ptr { + value = value.Elem() + } + + switch value.Kind() { + case reflect.Map: + return &reflectedField{ + value: value, + valueKind: value.Type().Elem().Kind(), + remainingPath: []string{strings.Join(tokens, "_")}, + }, true + case reflect.Struct: + fields := reflect.VisibleFields(value.Type()) + for _, field := range fields { + name := yamlFieldName(field) + if name == "" { + continue + } + normalizedFieldName := normalizeKey(name) + for i := len(tokens); i >= 1; i-- { + if normalizeKey(strings.Join(tokens[:i], "_")) != normalizedFieldName { + continue + } + return reflectGetYAMLTokens(value.FieldByIndex(field.Index), tokens[i:]) + } + } + } + + return nil, false +} + func yamlFieldName(field reflect.StructField) string { parts := strings.SplitN(field.Tag.Get("yaml"), ",", 2) switch name := parts[0]; { @@ -120,6 +166,10 @@ func yamlFieldName(field reflect.StructField) string { } } +func normalizeKey(value string) string { + return strings.ReplaceAll(strings.ToLower(value), "_", "") +} + func setReflectedValue(field *reflectedField, path []string, raw string) error { parsed, err := parseValue(field.valueKind, raw, path) if err != nil { diff --git a/packages/arrtrix/pkg/runtime/envconfig_test.go b/packages/arrtrix/pkg/runtime/envconfig_test.go new file mode 100644 index 0000000..6381a47 --- /dev/null +++ b/packages/arrtrix/pkg/runtime/envconfig_test.go @@ -0,0 +1,57 @@ +package runtime + +import ( + "os" + "testing" + + "maunium.net/go/mautrix/bridgev2/bridgeconfig" + + "sneeuwvlok/packages/arrtrix/pkg/connector" +) + +func TestUpdateConfigFromEnvSupportsFlatUnderscorePaths(t *testing.T) { + t.Setenv("ARRTRIX_NETWORK_CONTENT_MOVIES_APIKEY", "radarr-secret") + + cfg := &bridgeconfig.Config{} + network := &connector.Config{} + if err := updateConfigFromEnv(cfg, network, "ARRTRIX_"); err != nil { + t.Fatalf("updateConfigFromEnv returned error: %v", err) + } + + if network.Content.Movies.APIKey != "radarr-secret" { + t.Fatalf("expected movies api key to be overridden, got %q", network.Content.Movies.APIKey) + } +} + +func TestUpdateConfigFromEnvSupportsExplicitUnderscoredFieldNames(t *testing.T) { + t.Setenv("ARRTRIX_NETWORK_CONTENT_MOVIES_ROOT_FOLDER_PATH", "/data/movies") + + cfg := &bridgeconfig.Config{} + network := &connector.Config{} + if err := updateConfigFromEnv(cfg, network, "ARRTRIX_"); err != nil { + t.Fatalf("updateConfigFromEnv returned error: %v", err) + } + + if network.Content.Movies.RootFolderPath != "/data/movies" { + t.Fatalf("expected root folder path to be overridden, got %q", network.Content.Movies.RootFolderPath) + } +} + +func TestUpdateConfigFromEnvSupportsDoubleUnderscorePaths(t *testing.T) { + t.Setenv("ARRTRIX_NETWORK__CONTENT__SERIES__API_KEY", "sonarr-secret") + + cfg := &bridgeconfig.Config{} + network := &connector.Config{} + if err := updateConfigFromEnv(cfg, network, "ARRTRIX_"); err != nil { + t.Fatalf("updateConfigFromEnv returned error: %v", err) + } + + if network.Content.Series.APIKey != "sonarr-secret" { + t.Fatalf("expected series api key to be overridden, got %q", network.Content.Series.APIKey) + } +} + +func TestMain(m *testing.M) { + code := m.Run() + os.Exit(code) +} diff --git a/systems/x86_64-linux/ulmo/default.nix b/systems/x86_64-linux/ulmo/default.nix index 59077d8..fd25824 100644 --- a/systems/x86_64-linux/ulmo/default.nix +++ b/systems/x86_64-linux/ulmo/default.nix @@ -39,31 +39,6 @@ }; }; - # virtualisation = { - # containers.enable = true; - # podman = { - # enable = true; - # dockerCompat = true; - # }; - - # oci-containers = { - # backend = "podman"; - # containers = { - # homey = { - # image = "ghcr.io/athombv/homey-shs:latest"; - # autoStart = true; - # privileged = true; - # volumes = [ - # "/home/chris/.homey-shs:/homey/user" - # ]; - # ports = [ - # "4859:4859" - # ]; - # }; - # }; - # }; - # }; - sneeuwvlok = { services = { backup.borg.enable = true; diff --git a/vars/per-machine/ulmo/lidarr/api_key/machines/ulmo b/vars/per-machine/ulmo/lidarr/api_key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/lidarr/api_key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/lidarr/api_key/users/chris b/vars/per-machine/ulmo/lidarr/api_key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/lidarr/api_key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/lidarr/config.env/machines/ulmo b/vars/per-machine/ulmo/lidarr/config.env/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/lidarr/config.env/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/lidarr/config.env/users/chris b/vars/per-machine/ulmo/lidarr/config.env/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/lidarr/config.env/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/.pgpass/machines/ulmo b/vars/per-machine/ulmo/postgresql/.pgpass/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/postgresql/.pgpass/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/.pgpass/users/chris b/vars/per-machine/ulmo/postgresql/.pgpass/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/.pgpass/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/lidarr_hash/users/chris b/vars/per-machine/ulmo/postgresql/lidarr_hash/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/lidarr_hash/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/lidarr_password/users/chris b/vars/per-machine/ulmo/postgresql/lidarr_password/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/lidarr_password/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/prowlarr_hash/users/chris b/vars/per-machine/ulmo/postgresql/prowlarr_hash/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/prowlarr_hash/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/prowlarr_password/users/chris b/vars/per-machine/ulmo/postgresql/prowlarr_password/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/prowlarr_password/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/radarr_hash/users/chris b/vars/per-machine/ulmo/postgresql/radarr_hash/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/radarr_hash/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/radarr_password/users/chris b/vars/per-machine/ulmo/postgresql/radarr_password/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/radarr_password/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/server.crt/machines/ulmo b/vars/per-machine/ulmo/postgresql/server.crt/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/postgresql/server.crt/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/server.crt/users/chris b/vars/per-machine/ulmo/postgresql/server.crt/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/server.crt/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/server.key/machines/ulmo b/vars/per-machine/ulmo/postgresql/server.key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/postgresql/server.key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/server.key/users/chris b/vars/per-machine/ulmo/postgresql/server.key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/server.key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/sonarr_hash/users/chris b/vars/per-machine/ulmo/postgresql/sonarr_hash/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/sonarr_hash/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/postgresql/sonarr_password/users/chris b/vars/per-machine/ulmo/postgresql/sonarr_password/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/postgresql/sonarr_password/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/prowlarr/api_key/machines/ulmo b/vars/per-machine/ulmo/prowlarr/api_key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/prowlarr/api_key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/prowlarr/api_key/users/chris b/vars/per-machine/ulmo/prowlarr/api_key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/prowlarr/api_key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/prowlarr/config.env/machines/ulmo b/vars/per-machine/ulmo/prowlarr/config.env/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/prowlarr/config.env/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/prowlarr/config.env/users/chris b/vars/per-machine/ulmo/prowlarr/config.env/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/prowlarr/config.env/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/qbittorrent/password/machines/ulmo b/vars/per-machine/ulmo/qbittorrent/password/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/qbittorrent/password/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/qbittorrent/password/users/chris b/vars/per-machine/ulmo/qbittorrent/password/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/qbittorrent/password/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/qbittorrent/password_hash/machines/ulmo b/vars/per-machine/ulmo/qbittorrent/password_hash/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/qbittorrent/password_hash/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/qbittorrent/password_hash/users/chris b/vars/per-machine/ulmo/qbittorrent/password_hash/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/qbittorrent/password_hash/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/machines/ulmo b/vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/users/chris b/vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/qbittorrent/qBittorrent.conf/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/radarr/api_key/machines/ulmo b/vars/per-machine/ulmo/radarr/api_key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/radarr/api_key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/radarr/api_key/users/chris b/vars/per-machine/ulmo/radarr/api_key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/radarr/api_key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/radarr/config.env/machines/ulmo b/vars/per-machine/ulmo/radarr/config.env/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/radarr/config.env/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/radarr/config.env/users/chris b/vars/per-machine/ulmo/radarr/config.env/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/radarr/config.env/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/api_key/machines/ulmo b/vars/per-machine/ulmo/sabnzbd/api_key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sabnzbd/api_key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/api_key/users/chris b/vars/per-machine/ulmo/sabnzbd/api_key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sabnzbd/api_key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/config.ini/machines/ulmo b/vars/per-machine/ulmo/sabnzbd/config.ini/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sabnzbd/config.ini/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/config.ini/users/chris b/vars/per-machine/ulmo/sabnzbd/config.ini/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sabnzbd/config.ini/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/nzb_key/machines/ulmo b/vars/per-machine/ulmo/sabnzbd/nzb_key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sabnzbd/nzb_key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/nzb_key/users/chris b/vars/per-machine/ulmo/sabnzbd/nzb_key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sabnzbd/nzb_key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/password/machines/ulmo b/vars/per-machine/ulmo/sabnzbd/password/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sabnzbd/password/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/password/users/chris b/vars/per-machine/ulmo/sabnzbd/password/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sabnzbd/password/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/username/machines/ulmo b/vars/per-machine/ulmo/sabnzbd/username/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sabnzbd/username/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sabnzbd/username/users/chris b/vars/per-machine/ulmo/sabnzbd/username/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sabnzbd/username/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/servarr/config.tfvars/machines/ulmo b/vars/per-machine/ulmo/servarr/config.tfvars/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/servarr/config.tfvars/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/servarr/config.tfvars/users/chris b/vars/per-machine/ulmo/servarr/config.tfvars/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/servarr/config.tfvars/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sonarr/api_key/machines/ulmo b/vars/per-machine/ulmo/sonarr/api_key/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sonarr/api_key/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sonarr/api_key/users/chris b/vars/per-machine/ulmo/sonarr/api_key/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sonarr/api_key/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file diff --git a/vars/per-machine/ulmo/sonarr/config.env/machines/ulmo b/vars/per-machine/ulmo/sonarr/config.env/machines/ulmo deleted file mode 120000 index e5129f9..0000000 --- a/vars/per-machine/ulmo/sonarr/config.env/machines/ulmo +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/machines/ulmo \ No newline at end of file diff --git a/vars/per-machine/ulmo/sonarr/config.env/users/chris b/vars/per-machine/ulmo/sonarr/config.env/users/chris deleted file mode 120000 index 91b7741..0000000 --- a/vars/per-machine/ulmo/sonarr/config.env/users/chris +++ /dev/null @@ -1 +0,0 @@ -../../../../../../sops/users/chris \ No newline at end of file