checkpoint
This commit is contained in:
parent
be2843ca80
commit
e07257e137
61 changed files with 258 additions and 156 deletions
|
|
@ -1,6 +1,10 @@
|
|||
{
|
||||
description = "Nixos config flake";
|
||||
|
||||
nixConfig = {
|
||||
warn-dirty = false;
|
||||
};
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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") (
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf hasHosts {
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
|
||||
services.caddy = {
|
||||
enable = cfg.enable;
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}'
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
57
packages/arrtrix/pkg/runtime/envconfig_test.go
Normal file
57
packages/arrtrix/pkg/runtime/envconfig_test.go
Normal file
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/machines/ulmo
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../../../sops/users/chris
|
||||
Loading…
Add table
Add a link
Reference in a new issue