mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
style: alejandra $(fd -e nix)
This commit is contained in:
parent
97d9eecd3c
commit
e63304937d
91 changed files with 1422 additions and 1102 deletions
|
|
@ -11,7 +11,7 @@
|
|||
inherit (config.services) tailscale;
|
||||
inherit (config) networking;
|
||||
cfg = config.networking.access;
|
||||
cidrModule = { config, ... }: {
|
||||
cidrModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
all = mkOption {
|
||||
type = listOf str;
|
||||
|
|
@ -19,11 +19,11 @@
|
|||
};
|
||||
v4 = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
v6 = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
config.all = mkOptionDefault (
|
||||
|
|
@ -35,12 +35,14 @@ in {
|
|||
options.networking.access = with lib.types; {
|
||||
cidrForNetwork = mkOption {
|
||||
type = attrsOf (submodule cidrModule);
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
localaddrs = {
|
||||
enable = mkEnableOption "localaddrs" // {
|
||||
default = networking.firewall.interfaces.local.nftables.enable;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "localaddrs"
|
||||
// {
|
||||
default = networking.firewall.interfaces.local.nftables.enable;
|
||||
};
|
||||
stateDir = mkOption {
|
||||
type = path;
|
||||
default = "/var/lib/localaddrs";
|
||||
|
|
@ -87,10 +89,11 @@ in {
|
|||
};
|
||||
localaddrs = {
|
||||
nftablesInclude = mkBefore (''
|
||||
define localrange6 = 2001:568::/29
|
||||
'' + optionalString cfg.localaddrs.enable ''
|
||||
include "${cfg.localaddrs.stateDir}/*.nft"
|
||||
'');
|
||||
define localrange6 = 2001:568::/29
|
||||
''
|
||||
+ optionalString cfg.localaddrs.enable ''
|
||||
include "${cfg.localaddrs.stateDir}/*.nft"
|
||||
'');
|
||||
reloadScript = let
|
||||
localaddrs-reload = pkgs.writeShellScript "localaddrs-reload" ''
|
||||
${config.systemd.package}/bin/systemctl reload localaddrs 2>/dev/null ||
|
||||
|
|
@ -101,7 +104,7 @@ in {
|
|||
};
|
||||
moduleArgAttrs = {
|
||||
inherit (cfg) cidrForNetwork localaddrs;
|
||||
mkSnakeOil = pkgs.callPackage ../../packages/snakeoil.nix { };
|
||||
mkSnakeOil = pkgs.callPackage ../../packages/snakeoil.nix {};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -111,7 +114,8 @@ in {
|
|||
interfaces.local = {
|
||||
nftables.conditions = [
|
||||
"ip saddr { ${concatStringsSep ", " cfg.cidrForNetwork.local.v4} }"
|
||||
(mkIf networking.enableIPv6
|
||||
(
|
||||
mkIf networking.enableIPv6
|
||||
"ip6 saddr { $localrange6, ${concatStringsSep ", " cfg.cidrForNetwork.local.v6} }"
|
||||
)
|
||||
];
|
||||
|
|
@ -169,12 +173,12 @@ in {
|
|||
in {
|
||||
localaddrs = mkIf cfg.localaddrs.enable {
|
||||
unitConfig = {
|
||||
After = [ "network-online.target" ];
|
||||
After = ["network-online.target"];
|
||||
};
|
||||
serviceConfig = rec {
|
||||
StateDirectory = "localaddrs";
|
||||
ExecStart = mkMerge [
|
||||
[ "${localaddrs}" ]
|
||||
["${localaddrs}"]
|
||||
(mkIf networking.nftables.enable (mkAfter [
|
||||
"${localaddrs-nftables}"
|
||||
]))
|
||||
|
|
@ -188,7 +192,7 @@ in {
|
|||
};
|
||||
};
|
||||
nftables = mkIf (networking.nftables.enable && cfg.localaddrs.enable) rec {
|
||||
wants = [ "localaddrs.service" ];
|
||||
wants = ["localaddrs.service"];
|
||||
serviceConfig = {
|
||||
ExecReload = mkBefore [
|
||||
"+${cfg.localaddrs.reloadScript}"
|
||||
|
|
@ -196,7 +200,7 @@ in {
|
|||
};
|
||||
};
|
||||
nginx = mkIf (config.services.nginx.enable && cfg.localaddrs.enable) rec {
|
||||
wants = [ "localaddrs.service" ];
|
||||
wants = ["localaddrs.service"];
|
||||
after = wants;
|
||||
serviceConfig = {
|
||||
ExecReload = mkBefore [
|
||||
|
|
|
|||
|
|
@ -1,64 +1,79 @@
|
|||
{ pkgs, config, utils, lib, ... }: let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
utils,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.attrsets) mapAttrsToList mapAttrs' nameValuePair filterAttrsRecursive;
|
||||
inherit (lib.lists) singleton;
|
||||
inherit (lib.modules) mkIf mkMerge mkForce;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
cfg = config.services.cloudflared;
|
||||
settingsFormat = pkgs.formats.json { };
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
in {
|
||||
options.services.cloudflared = with lib.types; {
|
||||
tunnels = let
|
||||
tunnelModule = { config, ... }: {
|
||||
tunnelModule = {config, ...}: {
|
||||
options = {
|
||||
extraTunnel = {
|
||||
enable = mkEnableOption "extra tunnels" // {
|
||||
default = config.extraTunnel.ingress != { };
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "extra tunnels"
|
||||
// {
|
||||
default = config.extraTunnel.ingress != {};
|
||||
};
|
||||
ingress = mkOption {
|
||||
inherit (settingsFormat) type;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = attrsOf (submodule tunnelModule);
|
||||
};
|
||||
in
|
||||
mkOption {
|
||||
type = attrsOf (submodule tunnelModule);
|
||||
};
|
||||
};
|
||||
config.systemd.services = let
|
||||
filterConfig = filterAttrsRecursive (_: v: ! builtins.elem v [ null [ ] { } ]);
|
||||
mapIngress = hostname: ingress: {
|
||||
inherit hostname;
|
||||
} // filterConfig (filterConfig ingress);
|
||||
in mkIf cfg.enable (mapAttrs' (uuid: tunnel: let
|
||||
RuntimeDirectory = "cloudflared-tunnel-${uuid}";
|
||||
configPath = "/run/${RuntimeDirectory}/config.yml";
|
||||
settings = {
|
||||
tunnel = uuid;
|
||||
credentials-file = tunnel.credentialsFile;
|
||||
ingress = mapAttrsToList mapIngress tunnel.ingress
|
||||
++ mapAttrsToList mapIngress tunnel.extraTunnel.ingress
|
||||
++ singleton { service = tunnel.default; };
|
||||
};
|
||||
in nameValuePair "cloudflared-tunnel-${uuid}" (mkMerge [
|
||||
{
|
||||
after = mkIf config.services.tailscale.enable [ "tailscale-autoconnect.service" ];
|
||||
serviceConfig = {
|
||||
RestartSec = 10;
|
||||
filterConfig = filterAttrsRecursive (_: v: ! builtins.elem v [null [] {}]);
|
||||
mapIngress = hostname: ingress:
|
||||
{
|
||||
inherit hostname;
|
||||
}
|
||||
// filterConfig (filterConfig ingress);
|
||||
in
|
||||
mkIf cfg.enable (mapAttrs' (uuid: tunnel: let
|
||||
RuntimeDirectory = "cloudflared-tunnel-${uuid}";
|
||||
configPath = "/run/${RuntimeDirectory}/config.yml";
|
||||
settings = {
|
||||
tunnel = uuid;
|
||||
credentials-file = tunnel.credentialsFile;
|
||||
ingress =
|
||||
mapAttrsToList mapIngress tunnel.ingress
|
||||
++ mapAttrsToList mapIngress tunnel.extraTunnel.ingress
|
||||
++ singleton {service = tunnel.default;};
|
||||
};
|
||||
}
|
||||
(mkIf tunnel.extraTunnel.enable {
|
||||
serviceConfig = {
|
||||
inherit RuntimeDirectory;
|
||||
ExecStart = mkForce [
|
||||
"${cfg.package}/bin/cloudflared tunnel --config=${configPath} --no-autoupdate run"
|
||||
];
|
||||
ExecStartPre = [
|
||||
(pkgs.writeShellScript "cloudflared-tunnel-${uuid}-prepare" ''
|
||||
${utils.genJqSecretsReplacementSnippet settings configPath}
|
||||
'')
|
||||
];
|
||||
};
|
||||
})
|
||||
])) cfg.tunnels);
|
||||
in
|
||||
nameValuePair "cloudflared-tunnel-${uuid}" (mkMerge [
|
||||
{
|
||||
after = mkIf config.services.tailscale.enable ["tailscale-autoconnect.service"];
|
||||
serviceConfig = {
|
||||
RestartSec = 10;
|
||||
};
|
||||
}
|
||||
(mkIf tunnel.extraTunnel.enable {
|
||||
serviceConfig = {
|
||||
inherit RuntimeDirectory;
|
||||
ExecStart = mkForce [
|
||||
"${cfg.package}/bin/cloudflared tunnel --config=${configPath} --no-autoupdate run"
|
||||
];
|
||||
ExecStartPre = [
|
||||
(pkgs.writeShellScript "cloudflared-tunnel-${uuid}-prepare" ''
|
||||
${utils.genJqSecretsReplacementSnippet settings configPath}
|
||||
'')
|
||||
];
|
||||
};
|
||||
})
|
||||
]))
|
||||
cfg.tunnels);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
cfg = config.services.github-runners;
|
||||
nixosConfig = config;
|
||||
enabledRunners = filterAttrs (_: runner: runner.enable) cfg;
|
||||
runnerModule = { config, ... }: {
|
||||
runnerModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
networkNamespace.name = mkOption {
|
||||
type = nullOr str;
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
};
|
||||
serviceSettings = mkOption {
|
||||
type = unmerged.type;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
|
|
@ -58,8 +58,10 @@ in {
|
|||
};
|
||||
};
|
||||
config = {
|
||||
systemd.services = mapAttrs' (name: runner: nameValuePair "github-runner-${name}" (
|
||||
unmerged.merge runner.serviceSettings
|
||||
)) enabledRunners;
|
||||
systemd.services = mapAttrs' (name: runner:
|
||||
nameValuePair "github-runner-${name}" (
|
||||
unmerged.merge runner.serviceSettings
|
||||
))
|
||||
enabledRunners;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,29 +17,43 @@ in {
|
|||
default = config.networking.domain;
|
||||
};
|
||||
homekit = {
|
||||
enable = mkEnableOption "homekit" // {
|
||||
default = cfg.config.homekit or [ ] != [ ];
|
||||
enable =
|
||||
mkEnableOption "homekit"
|
||||
// {
|
||||
default = cfg.config.homekit or [] != [];
|
||||
};
|
||||
openFirewall =
|
||||
mkEnableOption "homekit ports"
|
||||
// {
|
||||
default = cfg.openFirewall;
|
||||
};
|
||||
};
|
||||
googleAssistant.enable =
|
||||
mkEnableOption "Google Assistant"
|
||||
// {
|
||||
default = cfg.config.google_assistant or {} != {};
|
||||
};
|
||||
openFirewall = mkEnableOption "homekit ports" // {
|
||||
default = cfg.openFirewall;
|
||||
androidTv.enable =
|
||||
mkEnableOption "Android TV"
|
||||
// {
|
||||
default = elem "androidtv" cfg.extraComponents;
|
||||
};
|
||||
brother.enable =
|
||||
mkEnableOption "brother"
|
||||
// {
|
||||
default = elem "brother" cfg.extraComponents;
|
||||
};
|
||||
};
|
||||
googleAssistant.enable = mkEnableOption "Google Assistant" // {
|
||||
default = cfg.config.google_assistant or { } != { };
|
||||
};
|
||||
androidTv.enable = mkEnableOption "Android TV" // {
|
||||
default = elem "androidtv" cfg.extraComponents;
|
||||
};
|
||||
brother.enable = mkEnableOption "brother" // {
|
||||
default = elem "brother" cfg.extraComponents;
|
||||
};
|
||||
cast = {
|
||||
enable = mkEnableOption "Chromecast" // {
|
||||
default = elem "cast" cfg.extraComponents;
|
||||
};
|
||||
openFirewall = mkEnableOption "Chromecast ports" // {
|
||||
default = cfg.openFirewall;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "Chromecast"
|
||||
// {
|
||||
default = elem "cast" cfg.extraComponents;
|
||||
};
|
||||
openFirewall =
|
||||
mkEnableOption "Chromecast ports"
|
||||
// {
|
||||
default = cfg.openFirewall;
|
||||
};
|
||||
};
|
||||
finalPackage = mkOption {
|
||||
type = types.path;
|
||||
|
|
@ -50,7 +64,7 @@ in {
|
|||
config = {
|
||||
networking.firewall = let
|
||||
homekitTcp = mkIf cfg.homekit.enable (
|
||||
map ({ port, ... }: port) cfg.config.homekit or [ ]
|
||||
map ({port, ...}: port) cfg.config.homekit or []
|
||||
);
|
||||
|
||||
castUdpRanges = mkIf cfg.cast.enable [
|
||||
|
|
@ -59,21 +73,23 @@ in {
|
|||
to = 60999;
|
||||
}
|
||||
];
|
||||
in mkIf cfg.enable {
|
||||
interfaces.local = {
|
||||
allowedTCPPorts = mkIf (!cfg.homekit.openFirewall) homekitTcp;
|
||||
allowedUDPPortRanges = mkIf (!cfg.cast.openFirewall) castUdpRanges;
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
interfaces.local = {
|
||||
allowedTCPPorts = mkIf (!cfg.homekit.openFirewall) homekitTcp;
|
||||
allowedUDPPortRanges = mkIf (!cfg.cast.openFirewall) castUdpRanges;
|
||||
};
|
||||
allowedTCPPorts = mkIf cfg.homekit.openFirewall homekitTcp;
|
||||
allowedUDPPortRanges = mkIf cfg.cast.openFirewall castUdpRanges;
|
||||
};
|
||||
allowedTCPPorts = mkIf cfg.homekit.openFirewall homekitTcp;
|
||||
allowedUDPPortRanges = mkIf cfg.cast.openFirewall castUdpRanges;
|
||||
};
|
||||
|
||||
# MDNS
|
||||
services.avahi = mkIf (cfg.enable && cfg.homekit.enable) {
|
||||
enable = mkDefault true;
|
||||
publish.enable = let
|
||||
homekitNames = map (homekit: toLower homekit.name) cfg.config.homekit or [ ];
|
||||
in mkIf (elem config.networking.hostName homekitNames) false;
|
||||
homekitNames = map (homekit: toLower homekit.name) cfg.config.homekit or [];
|
||||
in
|
||||
mkIf (elem config.networking.hostName homekitNames) false;
|
||||
};
|
||||
|
||||
systemd.services.home-assistant = mkIf (cfg.enable && cfg.mutableUiConfig) {
|
||||
|
|
@ -101,12 +117,13 @@ in {
|
|||
use_x_forwarded_for = "true";
|
||||
trusted_proxies = let
|
||||
inherit (config.networking.access) cidrForNetwork;
|
||||
in cidrForNetwork.loopback.all
|
||||
++ cidrForNetwork.local.all
|
||||
++ optionals config.services.tailscale.enable cidrForNetwork.tail.all
|
||||
++ [
|
||||
"200::/7"
|
||||
];
|
||||
in
|
||||
cidrForNetwork.loopback.all
|
||||
++ cidrForNetwork.local.all
|
||||
++ optionals config.services.tailscale.enable cidrForNetwork.tail.all
|
||||
++ [
|
||||
"200::/7"
|
||||
];
|
||||
};
|
||||
recorder = {
|
||||
db_url = mkIf config.services.postgresql.enable (mkDefault "postgresql://@/hass");
|
||||
|
|
@ -157,61 +174,75 @@ in {
|
|||
package = let
|
||||
inherit (cfg.package) python;
|
||||
# https://github.com/pysnmp/pysnmp/issues/51
|
||||
needsPyasn1pin = if lib.versionOlder python.pkgs.pysnmplib.version "6.0"
|
||||
needsPyasn1pin =
|
||||
if lib.versionOlder python.pkgs.pysnmplib.version "6.0"
|
||||
then true
|
||||
else lib.warn "pyasn1 pin likely no longer needed" false;
|
||||
pyasn1prefix = "${python.pkgs.pysnmp-pyasn1}/${python.sitePackages}";
|
||||
home-assistant = pkgs.home-assistant.override {
|
||||
packageOverrides = self: super: {
|
||||
brother = super.brother.overridePythonAttrs (old: {
|
||||
dontCheckRuntimeDeps = if old.dontCheckRuntimeDeps or false
|
||||
dontCheckRuntimeDeps =
|
||||
if old.dontCheckRuntimeDeps or false
|
||||
then lib.warn "brother override no longer needed" true
|
||||
else true;
|
||||
});
|
||||
mpd2 = super.mpd2.overridePythonAttrs (old: {
|
||||
patches = old.patches or [ ] ++ [
|
||||
../../packages/mpd2-skip-flaky-test.patch
|
||||
];
|
||||
disabledTests = unique (old.disabledTests or [ ] ++ [
|
||||
"test_idle_timeout"
|
||||
]);
|
||||
patches =
|
||||
old.patches
|
||||
or []
|
||||
++ [
|
||||
../../packages/mpd2-skip-flaky-test.patch
|
||||
];
|
||||
disabledTests = unique (old.disabledTests
|
||||
or []
|
||||
++ [
|
||||
"test_idle_timeout"
|
||||
]);
|
||||
});
|
||||
};
|
||||
};
|
||||
in home-assistant.overrideAttrs (old: {
|
||||
makeWrapperArgs = old.makeWrapperArgs ++ optional (cfg.brother.enable && needsPyasn1pin) "--prefix PYTHONPATH : ${pyasn1prefix}";
|
||||
disabledTests = unique (old.disabledTests or [ ] ++ [
|
||||
"test_check_config"
|
||||
]);
|
||||
});
|
||||
in
|
||||
home-assistant.overrideAttrs (old: {
|
||||
makeWrapperArgs = old.makeWrapperArgs ++ optional (cfg.brother.enable && needsPyasn1pin) "--prefix PYTHONPATH : ${pyasn1prefix}";
|
||||
disabledTests = unique (old.disabledTests
|
||||
or []
|
||||
++ [
|
||||
"test_check_config"
|
||||
]);
|
||||
});
|
||||
finalPackage = let
|
||||
inherit (lib.strings) hasSuffix removeSuffix splitString;
|
||||
inherit (lib.lists) head;
|
||||
inherit (lib.attrsets) attrNames filterAttrs;
|
||||
inherit (config.systemd.services.home-assistant.serviceConfig) ExecStart;
|
||||
isHassDrv = drv: context: hasSuffix "-${cfg.package.name}.drv" drv && context.outputs or [ ] == [ "out" ];
|
||||
isHassDrv = drv: context: hasSuffix "-${cfg.package.name}.drv" drv && context.outputs or [] == ["out"];
|
||||
drvs = filterAttrs isHassDrv (builtins.getContext ExecStart);
|
||||
isImpure = builtins ? currentSystem;
|
||||
in mkIf cfg.enable (mkOptionDefault (
|
||||
if isImpure then import (head (attrNames drvs))
|
||||
else removeSuffix "/bin/hass" (head (splitString " " ExecStart))
|
||||
));
|
||||
extraPackages = python3Packages: with python3Packages; mkMerge [
|
||||
[
|
||||
psycopg2
|
||||
securetar
|
||||
getmac # for upnp integration
|
||||
python-otbr-api
|
||||
(aiogithubapi.overrideAttrs (_: {doInstallCheck = false;}))
|
||||
]
|
||||
(mkIf cfg.homekit.enable [
|
||||
aiohomekit
|
||||
])
|
||||
(mkIf cfg.androidTv.enable [
|
||||
adb-shell
|
||||
androidtvremote2
|
||||
])
|
||||
];
|
||||
in
|
||||
mkIf cfg.enable (mkOptionDefault (
|
||||
if isImpure
|
||||
then import (head (attrNames drvs))
|
||||
else removeSuffix "/bin/hass" (head (splitString " " ExecStart))
|
||||
));
|
||||
extraPackages = python3Packages:
|
||||
with python3Packages;
|
||||
mkMerge [
|
||||
[
|
||||
psycopg2
|
||||
securetar
|
||||
getmac # for upnp integration
|
||||
python-otbr-api
|
||||
(aiogithubapi.overrideAttrs (_: {doInstallCheck = false;}))
|
||||
]
|
||||
(mkIf cfg.homekit.enable [
|
||||
aiohomekit
|
||||
])
|
||||
(mkIf cfg.androidTv.enable [
|
||||
adb-shell
|
||||
androidtvremote2
|
||||
])
|
||||
];
|
||||
extraComponents = mkMerge [
|
||||
[
|
||||
"automation"
|
||||
|
|
@ -232,8 +263,8 @@ in {
|
|||
"google_assistant"
|
||||
"google_cloud"
|
||||
])
|
||||
(map ({ platform, ... }: platform) cfg.config.media_player or [ ])
|
||||
(map ({ platform, ... }: platform) cfg.config.tts or [ ])
|
||||
(map ({platform, ...}: platform) cfg.config.media_player or [])
|
||||
(map ({platform, ...}: platform) cfg.config.tts or [])
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.jackett = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -60,13 +60,14 @@ in {
|
|||
|
||||
services.kanidm = {
|
||||
server.unencrypted = {
|
||||
domain = mkBefore [ cfg.server.frontend.domain ];
|
||||
domain = mkBefore [cfg.server.frontend.domain];
|
||||
package = let
|
||||
cert = mkSnakeOil {
|
||||
name = "kanidm-cert";
|
||||
inherit (cfg.server.unencrypted) domain;
|
||||
};
|
||||
in mkOptionDefault cert;
|
||||
in
|
||||
mkOptionDefault cert;
|
||||
};
|
||||
clientSettings = mkIf cfg.enableServer {
|
||||
uri = mkDefault cfg.serverSettings.origin;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.lidarr = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||
inherit (lib.lists) singleton;
|
||||
cfg = config.services.mediatomb;
|
||||
mediaDirModule = { config, ... }: {
|
||||
mediaDirModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
mountPoint = mkOption {
|
||||
type = nullOr str;
|
||||
|
|
@ -26,16 +26,23 @@
|
|||
paths = let
|
||||
paths = map (path: "${config.path}/${path}") config.subdirectories;
|
||||
path = singleton config.path;
|
||||
in mkOptionDefault (if config.subdirectories != null then paths else path);
|
||||
in
|
||||
mkOptionDefault (
|
||||
if config.subdirectories != null
|
||||
then paths
|
||||
else path
|
||||
);
|
||||
recursive = mkDefault true;
|
||||
hidden-files = mkDefault false;
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.services.mediatomb = with lib.types; {
|
||||
confine = mkEnableOption "containment" // {
|
||||
default = true;
|
||||
};
|
||||
confine =
|
||||
mkEnableOption "containment"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
mediaDirectories = mkOption {
|
||||
type = listOf (submodule mediaDirModule);
|
||||
};
|
||||
|
|
@ -47,9 +54,13 @@ in {
|
|||
};
|
||||
config.systemd.services.mediatomb = mkIf cfg.enable {
|
||||
confinement.enable = mkIf cfg.confine (mkDefault true);
|
||||
bindsTo = map (dir: mkIf (dir.mountPoint != null)
|
||||
"${utils.escapeSystemdPath dir.mountPoint}.mount"
|
||||
) cfg.mediaDirectories;
|
||||
bindsTo =
|
||||
map (
|
||||
dir:
|
||||
mkIf (dir.mountPoint != null)
|
||||
"${utils.escapeSystemdPath dir.mountPoint}.mount"
|
||||
)
|
||||
cfg.mediaDirectories;
|
||||
unitConfig.RequiresMountsFor = mkMerge (
|
||||
map (dir: dir.paths) cfg.mediaDirectories
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,18 +8,19 @@
|
|||
in {
|
||||
options.services.mosquitto = with lib.types; {
|
||||
listeners = let
|
||||
listenerModule = { ... }: {
|
||||
listenerModule = {...}: {
|
||||
options = {
|
||||
openFirewall = mkEnableOption "firewall";
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = listOf (submodule listenerModule);
|
||||
};
|
||||
in
|
||||
mkOption {
|
||||
type = listOf (submodule listenerModule);
|
||||
};
|
||||
};
|
||||
config = {
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.enable (mkMerge (
|
||||
map (listener: mkIf listener.openFirewall [ listener.port ]) cfg.listeners
|
||||
map (listener: mkIf listener.openFirewall [listener.port]) cfg.listeners
|
||||
));
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,12 @@
|
|||
enabledNamespaces = filter (ns: ns.enable) (attrValues networking.namespaces);
|
||||
ip = "${pkgs.iproute2}/bin/ip";
|
||||
ip-n = namespace: "${ip} -n ${escapeShellArg namespace.name}";
|
||||
namespaceInterfaceModule = { config, namespace, name, ... }: {
|
||||
namespaceInterfaceModule = {
|
||||
config,
|
||||
namespace,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = with lib.types; {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
|
|
@ -41,8 +46,8 @@
|
|||
};
|
||||
config = {
|
||||
serviceSettings = rec {
|
||||
bindsTo = [ "${namespace.unitName}.service" ];
|
||||
partOf = [ "${namespace.unitName}.target" ];
|
||||
bindsTo = ["${namespace.unitName}.service"];
|
||||
partOf = ["${namespace.unitName}.target"];
|
||||
after = bindsTo;
|
||||
stopIfChanged = false;
|
||||
restartIfChanged = false;
|
||||
|
|
@ -63,7 +68,11 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
groupModule = { config, namespace, ... }: {
|
||||
groupModule = {
|
||||
config,
|
||||
namespace,
|
||||
...
|
||||
}: {
|
||||
options = with lib.types; {
|
||||
id = mkOption {
|
||||
type = int;
|
||||
|
|
@ -78,8 +87,8 @@
|
|||
};
|
||||
config = {
|
||||
serviceSettings = rec {
|
||||
bindsTo = [ "${namespace.unitName}.service" ];
|
||||
partOf = [ "${namespace.unitName}.target" ];
|
||||
bindsTo = ["${namespace.unitName}.service"];
|
||||
partOf = ["${namespace.unitName}.target"];
|
||||
after = bindsTo;
|
||||
stopIfChanged = false;
|
||||
restartIfChanged = false;
|
||||
|
|
@ -100,17 +109,23 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
namespaceModule = { config, name, ... }: let
|
||||
namespaceModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: let
|
||||
linkGroupServices = optional (config.linkGroup != null) "${config.linkGroup.serviceName}.service";
|
||||
interfaceServices = mapAttrsToList (_: interface: "${interface.serviceName}.service") config.interfaces;
|
||||
submoduleArgs = { ... }: {
|
||||
submoduleArgs = {...}: {
|
||||
config._module.args.namespace = config;
|
||||
};
|
||||
in {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "network namespace" // {
|
||||
default = true;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "network namespace"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
resolvConf = mkOption {
|
||||
type = lines;
|
||||
default = ''
|
||||
|
|
@ -186,8 +201,9 @@
|
|||
groupModule
|
||||
submoduleArgs
|
||||
];
|
||||
idOrModule = coercedTo int (id: { inherit id; }) module;
|
||||
in nullOr idOrModule;
|
||||
idOrModule = coercedTo int (id: {inherit id;}) module;
|
||||
in
|
||||
nullOr idOrModule;
|
||||
default = null;
|
||||
};
|
||||
interfaces = mkOption {
|
||||
|
|
@ -195,7 +211,7 @@
|
|||
namespaceInterfaceModule
|
||||
submoduleArgs
|
||||
]);
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
path = mkOption {
|
||||
type = path;
|
||||
|
|
@ -226,8 +242,8 @@
|
|||
};
|
||||
config = {
|
||||
serviceSettings = {
|
||||
wants = [ "network.target" ];
|
||||
after = [ "network.target" ];
|
||||
wants = ["network.target"];
|
||||
after = ["network.target"];
|
||||
stopIfChanged = false;
|
||||
restartIfChanged = false;
|
||||
serviceConfig = {
|
||||
|
|
@ -245,12 +261,12 @@
|
|||
};
|
||||
};
|
||||
targetSettings = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
bindsTo = [ "${config.unitName}.service" ];
|
||||
wantedBy = ["multi-user.target"];
|
||||
bindsTo = ["${config.unitName}.service"];
|
||||
requires = linkGroupServices ++ interfaceServices;
|
||||
wants = mkMerge [
|
||||
(mkIf config.dhcpcd.enable [ "${config.dhcpcd.serviceName}.service" ])
|
||||
(mkIf config.nftables.enable [ "${config.nftables.serviceName}.service" ])
|
||||
(mkIf config.dhcpcd.enable ["${config.dhcpcd.serviceName}.service"])
|
||||
(mkIf config.nftables.enable ["${config.nftables.serviceName}.service"])
|
||||
];
|
||||
};
|
||||
configFiles = {
|
||||
|
|
@ -312,21 +328,22 @@
|
|||
addrs6 = access.cidrForNetwork.local.v6 ++ optionals tailscale.enable access.cidrForNetwork.tail.v6;
|
||||
daddr4 = ''{ ${concatStringsSep ", " addrs4} }'';
|
||||
daddr6 = ''{ ${concatStringsSep ", " addrs6} }'';
|
||||
in mkIf config.nftables.rejectLocaladdrs (mkMerge [
|
||||
''ct state { established, related } accept''
|
||||
''
|
||||
ip daddr ${daddr4} ip protocol tcp reject with tcp reset
|
||||
ip daddr ${daddr4} drop
|
||||
''
|
||||
(mkIf networking.enableIPv6 ''
|
||||
ip6 daddr ${daddr6} ip6 nexthdr tcp reject with tcp reset
|
||||
ip6 daddr ${daddr6} drop
|
||||
'')
|
||||
]);
|
||||
in
|
||||
mkIf config.nftables.rejectLocaladdrs (mkMerge [
|
||||
''ct state { established, related } accept''
|
||||
''
|
||||
ip daddr ${daddr4} ip protocol tcp reject with tcp reset
|
||||
ip daddr ${daddr4} drop
|
||||
''
|
||||
(mkIf networking.enableIPv6 ''
|
||||
ip6 daddr ${daddr6} ip6 nexthdr tcp reject with tcp reset
|
||||
ip6 daddr ${daddr6} drop
|
||||
'')
|
||||
]);
|
||||
serviceSettings = rec {
|
||||
bindsTo = [ "${config.unitName}.service" ];
|
||||
partOf = [ "${config.unitName}.target" ];
|
||||
wants = mkIf config.nftables.rejectLocaladdrs [ "localaddrs.service" ];
|
||||
bindsTo = ["${config.unitName}.service"];
|
||||
partOf = ["${config.unitName}.target"];
|
||||
wants = mkIf config.nftables.rejectLocaladdrs ["localaddrs.service"];
|
||||
after = mkMerge [
|
||||
bindsTo
|
||||
wants
|
||||
|
|
@ -346,7 +363,7 @@
|
|||
"${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft"
|
||||
];
|
||||
ExecReload = mkMerge [
|
||||
(mkIf config.nftables.rejectLocaladdrs [ "+${access.localaddrs.reloadScript}" ])
|
||||
(mkIf config.nftables.rejectLocaladdrs ["+${access.localaddrs.reloadScript}"])
|
||||
[
|
||||
"${pkgs.nftables}/bin/nft flush ruleset"
|
||||
"${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft"
|
||||
|
|
@ -360,12 +377,15 @@
|
|||
};
|
||||
dhcpcd = {
|
||||
serviceSettings = rec {
|
||||
bindsTo = [ "${config.unitName}.service" ];
|
||||
partOf = [ "${config.unitName}.target" ];
|
||||
bindsTo = ["${config.unitName}.service"];
|
||||
partOf = ["${config.unitName}.target"];
|
||||
wants = linkGroupServices ++ interfaceServices;
|
||||
after = bindsTo ++ wants ++ [
|
||||
(mkIf config.nftables.enable "${config.nftables.serviceName}.service")
|
||||
];
|
||||
after =
|
||||
bindsTo
|
||||
++ wants
|
||||
++ [
|
||||
(mkIf config.nftables.enable "${config.nftables.serviceName}.service")
|
||||
];
|
||||
stopIfChanged = false;
|
||||
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
|
||||
serviceConfig = {
|
||||
|
|
@ -407,15 +427,21 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
serviceModule = { config, name, ... }: let
|
||||
serviceModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: let
|
||||
cfg = config.networkNamespace;
|
||||
hasNs = cfg.name != null;
|
||||
ns = networking.namespaces.${cfg.name};
|
||||
in {
|
||||
options.networkNamespace = with lib.types; {
|
||||
enable = mkEnableOption "netns" // {
|
||||
default = cfg.name != null;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "netns"
|
||||
// {
|
||||
default = cfg.name != null;
|
||||
};
|
||||
bindResolvConf = mkOption {
|
||||
type = nullOr path;
|
||||
};
|
||||
|
|
@ -446,15 +472,13 @@
|
|||
path = mkDefault (
|
||||
ns.path
|
||||
);
|
||||
bindResolvConf = mkDefault (
|
||||
"${ns.configPath}/resolv.conf"
|
||||
);
|
||||
bindResolvConf = mkDefault "${ns.configPath}/resolv.conf";
|
||||
})
|
||||
];
|
||||
}
|
||||
(mkIf cfg.enable rec {
|
||||
wants = mkIf hasNs [ "${ns.unitName}.target" ];
|
||||
bindsTo = mkIf hasNs [ "${ns.unitName}.service" ];
|
||||
wants = mkIf hasNs ["${ns.unitName}.target"];
|
||||
bindsTo = mkIf hasNs ["${ns.unitName}.service"];
|
||||
after = mkMerge [
|
||||
bindsTo
|
||||
(mkIf (hasNs && cfg.afterOnline) [
|
||||
|
|
@ -475,7 +499,7 @@ in {
|
|||
options = with lib.types; {
|
||||
networking.namespaces = mkOption {
|
||||
type = attrsOf (submodule namespaceModule);
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
systemd.services = mkOption {
|
||||
type = attrsOf (submodule serviceModule);
|
||||
|
|
@ -483,19 +507,25 @@ in {
|
|||
};
|
||||
config = {
|
||||
systemd = {
|
||||
services = listToAttrs (concatMap (ns:
|
||||
singleton (nameValuePair ns.unitName (unmerged.merge ns.serviceSettings))
|
||||
++ optional (ns.linkGroup != null) (nameValuePair ns.linkGroup.serviceName (unmerged.merge ns.linkGroup.serviceSettings))
|
||||
++ mapAttrsToList (_: interface: nameValuePair interface.serviceName (unmerged.merge interface.serviceSettings)) ns.interfaces
|
||||
++ optional ns.dhcpcd.enable (nameValuePair ns.dhcpcd.serviceName (unmerged.merge ns.dhcpcd.serviceSettings))
|
||||
++ optional ns.nftables.enable (nameValuePair ns.nftables.serviceName (unmerged.merge ns.nftables.serviceSettings))
|
||||
) enabledNamespaces);
|
||||
targets = listToAttrs (map (ns: nameValuePair ns.unitName (
|
||||
unmerged.merge ns.targetSettings
|
||||
)) enabledNamespaces);
|
||||
services = listToAttrs (concatMap (
|
||||
ns:
|
||||
singleton (nameValuePair ns.unitName (unmerged.merge ns.serviceSettings))
|
||||
++ optional (ns.linkGroup != null) (nameValuePair ns.linkGroup.serviceName (unmerged.merge ns.linkGroup.serviceSettings))
|
||||
++ mapAttrsToList (_: interface: nameValuePair interface.serviceName (unmerged.merge interface.serviceSettings)) ns.interfaces
|
||||
++ optional ns.dhcpcd.enable (nameValuePair ns.dhcpcd.serviceName (unmerged.merge ns.dhcpcd.serviceSettings))
|
||||
++ optional ns.nftables.enable (nameValuePair ns.nftables.serviceName (unmerged.merge ns.nftables.serviceSettings))
|
||||
)
|
||||
enabledNamespaces);
|
||||
targets = listToAttrs (map (ns:
|
||||
nameValuePair ns.unitName (
|
||||
unmerged.merge ns.targetSettings
|
||||
))
|
||||
enabledNamespaces);
|
||||
};
|
||||
environment.etc = mkMerge (map (ns:
|
||||
mapAttrs' (name: file: nameValuePair "${ns.configDir}/${name}" (unmerged.merge file)) ns.configFiles
|
||||
) enabledNamespaces);
|
||||
environment.etc = mkMerge (map (
|
||||
ns:
|
||||
mapAttrs' (name: file: nameValuePair "${ns.configDir}/${name}" (unmerged.merge file)) ns.configFiles
|
||||
)
|
||||
enabledNamespaces);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,17 +8,21 @@
|
|||
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||
inherit (inputs.self.lib.lib) eui64;
|
||||
inherit (config) networking services;
|
||||
networkModule = { config, ... }: {
|
||||
networkModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
mdns = {
|
||||
enable = mkEnableOption "SLAAC" // {
|
||||
default = config.matchConfig.Type or null == "ether" && services.resolved.enable;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "SLAAC"
|
||||
// {
|
||||
default = config.matchConfig.Type or null == "ether" && services.resolved.enable;
|
||||
};
|
||||
};
|
||||
slaac = {
|
||||
enable = mkEnableOption "SLAAC" // {
|
||||
default = config.matchConfig.Type or null == "ether" && networking.enableIPv6;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "SLAAC"
|
||||
// {
|
||||
default = config.matchConfig.Type or null == "ether" && networking.enableIPv6;
|
||||
};
|
||||
postfix = mkOption {
|
||||
type = str;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{ lib, config, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) types;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf;
|
||||
|
|
@ -13,11 +15,13 @@ let
|
|||
doDocker = config.virtualisation.docker.enable && cfg.generateDockerRules;
|
||||
|
||||
mkPorts = cond: ports: ranges: action: let
|
||||
portStrings = (map (range: "${toString range.from}-${toString range.to}") ranges)
|
||||
++ (map toString ports);
|
||||
in optionalString (portStrings != []) ''
|
||||
${cond} dport { ${concatStringsSep "," portStrings} } ${action}
|
||||
'';
|
||||
portStrings =
|
||||
(map (range: "${toString range.from}-${toString range.to}") ranges)
|
||||
++ (map toString ports);
|
||||
in
|
||||
optionalString (portStrings != []) ''
|
||||
${cond} dport { ${concatStringsSep "," portStrings} } ${action}
|
||||
'';
|
||||
|
||||
ruleset = ''
|
||||
table inet filter {
|
||||
|
|
@ -32,18 +36,21 @@ let
|
|||
ct state established,related accept
|
||||
|
||||
iifname { ${
|
||||
concatStringsSep "," (["lo"] ++ fwcfg.trustedInterfaces)
|
||||
} } accept
|
||||
concatStringsSep "," (["lo"] ++ fwcfg.trustedInterfaces)
|
||||
} } accept
|
||||
|
||||
${mkPorts "tcp" fwcfg.allowedTCPPorts fwcfg.allowedTCPPortRanges "accept"}
|
||||
${mkPorts "udp" fwcfg.allowedUDPPorts fwcfg.allowedUDPPortRanges "accept"}
|
||||
|
||||
${
|
||||
concatStringsSep "\n" (mapAttrsToList (name: ifcfg: concatMapStringsSep "\n" (cond:
|
||||
mkPorts "${cond} tcp" ifcfg.allowedTCPPorts ifcfg.allowedTCPPortRanges "accept"
|
||||
concatStringsSep "\n" (mapAttrsToList (name: ifcfg:
|
||||
concatMapStringsSep "\n" (
|
||||
cond:
|
||||
mkPorts "${cond} tcp" ifcfg.allowedTCPPorts ifcfg.allowedTCPPortRanges "accept"
|
||||
+ mkPorts "${cond} udp" ifcfg.allowedUDPPorts ifcfg.allowedUDPPortRanges "accept"
|
||||
) (optionals ifcfg.nftables.enable ifcfg.nftables.conditions)) fwcfg.interfaces)
|
||||
}
|
||||
) (optionals ifcfg.nftables.enable ifcfg.nftables.conditions))
|
||||
fwcfg.interfaces)
|
||||
}
|
||||
|
||||
# DHCPv6
|
||||
ip6 daddr fe80::/64 udp dport 546 accept
|
||||
|
|
@ -65,10 +72,10 @@ let
|
|||
policy ${cfg.forwardPolicy}
|
||||
|
||||
${optionalString doDocker ''
|
||||
oifname docker0 ct state invalid drop
|
||||
oifname docker0 ct state established,related accept
|
||||
iifname docker0 accept
|
||||
''}
|
||||
oifname docker0 ct state invalid drop
|
||||
oifname docker0 ct state established,related accept
|
||||
iifname docker0 accept
|
||||
''}
|
||||
|
||||
${cfg.extraForward}
|
||||
|
||||
|
|
@ -85,14 +92,23 @@ let
|
|||
''}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
interfaceModule = { config, name, ... }: {
|
||||
interfaceModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
nftables = {
|
||||
enable = mkEnableOption "nftables firewall" // {
|
||||
default =
|
||||
config.allowedTCPPorts != [ ] || config.allowedTCPPortRanges != [ ]
|
||||
|| config.allowedUDPPorts != [ ] || config.allowedUDPPortRanges != [ ];
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "nftables firewall"
|
||||
// {
|
||||
default =
|
||||
config.allowedTCPPorts
|
||||
!= []
|
||||
|| config.allowedTCPPortRanges != []
|
||||
|| config.allowedUDPPorts != []
|
||||
|| config.allowedUDPPortRanges != [];
|
||||
};
|
||||
conditions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = "iifname ${name}";
|
||||
|
|
@ -100,7 +116,6 @@ let
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
options = {
|
||||
networking.nftables = {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
inherit (lib.lists) optionals;
|
||||
inherit (config.services) tailscale;
|
||||
inherit (config.networking.access) cidrForNetwork localaddrs;
|
||||
localModule = { config, ... }: {
|
||||
localModule = {config, ...}: {
|
||||
options.local = with lib.types; {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
|
|
@ -37,16 +37,23 @@
|
|||
cidrForNetwork.loopback.all
|
||||
++ cidrForNetwork.local.all
|
||||
++ optionals tailscale.enable cidrForNetwork.tail.all;
|
||||
allows = concatMapStringsSep "\n" mkAllow allowAddresses + optionalString localaddrs.enable ''
|
||||
include ${localaddrs.stateDir}/*.nginx.conf;
|
||||
allows =
|
||||
concatMapStringsSep "\n" mkAllow allowAddresses
|
||||
+ optionalString localaddrs.enable ''
|
||||
include ${localaddrs.stateDir}/*.nginx.conf;
|
||||
'';
|
||||
in
|
||||
mkBefore ''
|
||||
${allows}
|
||||
deny all;
|
||||
'';
|
||||
in mkBefore ''
|
||||
${allows}
|
||||
deny all;
|
||||
'';
|
||||
};
|
||||
};
|
||||
locationModule = { config, virtualHost, ... }: {
|
||||
locationModule = {
|
||||
config,
|
||||
virtualHost,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
localModule
|
||||
];
|
||||
|
|
@ -58,13 +65,13 @@
|
|||
emitDenyGlobal = virtualHost.local.emitDenyGlobal;
|
||||
};
|
||||
};
|
||||
hostModule = { config, ... }: {
|
||||
imports = [ localModule ];
|
||||
hostModule = {config, ...}: {
|
||||
imports = [localModule];
|
||||
|
||||
options = with lib.types; {
|
||||
locations = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ locationModule ];
|
||||
modules = [locationModule];
|
||||
shorthandOnlyDefinesConfig = true;
|
||||
specialArgs = {
|
||||
virtualHost = config;
|
||||
|
|
@ -83,7 +90,7 @@ in {
|
|||
options = with lib.types; {
|
||||
services.nginx.virtualHosts = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ hostModule ];
|
||||
modules = [hostModule];
|
||||
shorthandOnlyDefinesConfig = true;
|
||||
specialArgs = {
|
||||
nixosConfig = config;
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@
|
|||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
}: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||
inherit (config) networking;
|
||||
inherit (config.services) vouch-proxy tailscale;
|
||||
vouchModule = { config, ... }: {
|
||||
vouchModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
vouch = {
|
||||
enable = mkEnableOption "vouch auth proxy";
|
||||
|
|
@ -49,15 +48,20 @@ let
|
|||
vouch = mkIf vouch-proxy.enable {
|
||||
proxyOrigin = let
|
||||
inherit (vouch-proxy.settings.vouch) listen port;
|
||||
host = if listen == "0.0.0.0" || listen == "[::]" then "localhost" else listen;
|
||||
in mkDefault "http://${host}:${toString port}";
|
||||
host =
|
||||
if listen == "0.0.0.0" || listen == "[::]"
|
||||
then "localhost"
|
||||
else listen;
|
||||
in
|
||||
mkDefault "http://${host}:${toString port}";
|
||||
authUrl = mkDefault vouch-proxy.authUrl;
|
||||
url = mkDefault vouch-proxy.url;
|
||||
doubleProxy = mkDefault false;
|
||||
};
|
||||
}
|
||||
{
|
||||
vouch.proxyOrigin = mkIf (tailscale.enable && !vouch-proxy.enable) (mkDefault
|
||||
vouch.proxyOrigin = mkIf (tailscale.enable && !vouch-proxy.enable) (
|
||||
mkDefault
|
||||
"http://login.tail.${networking.domain}"
|
||||
);
|
||||
}
|
||||
|
|
@ -96,22 +100,23 @@ let
|
|||
set $vouch_url $vouch_scheme://${config.vouch.tailDomain};
|
||||
}
|
||||
'';
|
||||
in mkMerge [
|
||||
(mkBefore ''
|
||||
set $vouch_url ${config.vouch.url};
|
||||
set $vouch_scheme $scheme;
|
||||
'')
|
||||
(mkIf config.local.trusted (mkBefore ''
|
||||
if ($http_x_forwarded_proto) {
|
||||
set $vouch_scheme $http_x_forwarded_proto;
|
||||
}
|
||||
''))
|
||||
(mkIf (config.local.enable or false) localVouchUrl)
|
||||
(mkIf (config.local.enable or false && tailscale.enable) tailVouchUrl)
|
||||
''
|
||||
return 302 $vouch_url/login?url=$vouch_scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
||||
''
|
||||
];
|
||||
in
|
||||
mkMerge [
|
||||
(mkBefore ''
|
||||
set $vouch_url ${config.vouch.url};
|
||||
set $vouch_scheme $scheme;
|
||||
'')
|
||||
(mkIf config.local.trusted (mkBefore ''
|
||||
if ($http_x_forwarded_proto) {
|
||||
set $vouch_scheme $http_x_forwarded_proto;
|
||||
}
|
||||
''))
|
||||
(mkIf (config.local.enable or false) localVouchUrl)
|
||||
(mkIf (config.local.enable or false && tailscale.enable) tailVouchUrl)
|
||||
''
|
||||
return 302 $vouch_url/login?url=$vouch_scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
||||
''
|
||||
];
|
||||
};
|
||||
"/validate" = {
|
||||
recommendedProxySettings = false;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
wsModule = { config, ... }: {
|
||||
wsModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
proxy.websocket.enable = mkEnableOption "websocket proxy";
|
||||
};
|
||||
|
|
@ -16,8 +13,8 @@
|
|||
'';
|
||||
};
|
||||
};
|
||||
hostModule = { config, ... }: {
|
||||
imports = [ wsModule ];
|
||||
hostModule = {config, ...}: {
|
||||
imports = [wsModule];
|
||||
|
||||
options = with lib.types; {
|
||||
locations = mkOption {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.plex = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.networking.policyrouting;
|
||||
|
||||
ruleOpts = { ... }: {
|
||||
ruleOpts = {...}: {
|
||||
options = {
|
||||
prio = mkOption {
|
||||
type = types.int;
|
||||
|
|
@ -15,37 +16,44 @@ let
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
in {
|
||||
options = {
|
||||
networking.policyrouting = {
|
||||
enable = mkEnableOption "Declarative Policy-Routing";
|
||||
rules = mkOption {
|
||||
type = with types; listOf (submodule ruleOpts);
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
rules6 = mkOption {
|
||||
type = with types; listOf (submodule ruleOpts);
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
rules4 = mkOption {
|
||||
type = with types; listOf (submodule ruleOpts);
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.policyrouting.rules = [
|
||||
{ rule = "lookup main"; prio = 32000; }
|
||||
{
|
||||
rule = "lookup main";
|
||||
prio = 32000;
|
||||
}
|
||||
];
|
||||
networking.localCommands = ''
|
||||
set -x
|
||||
ip -6 rule flush
|
||||
ip -4 rule flush
|
||||
${concatMapStringsSep "\n" ({ prio, rule }: "ip -6 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules6)}
|
||||
${concatMapStringsSep "\n" ({ prio, rule }: "ip -4 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules4)}
|
||||
${concatMapStringsSep "\n" ({
|
||||
prio,
|
||||
rule,
|
||||
}: "ip -6 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules6)}
|
||||
${concatMapStringsSep "\n" ({
|
||||
prio,
|
||||
rule,
|
||||
}: "ip -4 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules4)}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,19 +10,24 @@
|
|||
inherit (config) networking;
|
||||
cfg = config.services.postgresql;
|
||||
formatHost = host:
|
||||
if hasInfix "/" host then host
|
||||
else if hasInfix ":" host then "${host}/128"
|
||||
else if hasInfix "." host then "${host}/32"
|
||||
if hasInfix "/" host
|
||||
then host
|
||||
else if hasInfix ":" host
|
||||
then "${host}/128"
|
||||
else if hasInfix "." host
|
||||
then "${host}/32"
|
||||
else throw "unsupported IP address ${host}";
|
||||
ensureUserModule = { config, ... }: {
|
||||
ensureUserModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
authentication = {
|
||||
enable = mkEnableOption "TCP connections" // {
|
||||
default = config.authentication.hosts != [ ];
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "TCP connections"
|
||||
// {
|
||||
default = config.authentication.hosts != [];
|
||||
};
|
||||
hosts = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
default = [];
|
||||
};
|
||||
method = mkOption {
|
||||
type = str;
|
||||
|
|
@ -47,13 +52,15 @@
|
|||
authentication = {
|
||||
hosts = let
|
||||
inherit (networking.access) cidrForNetwork;
|
||||
in mkMerge [
|
||||
(mkIf config.authentication.tailscale.allow cidrForNetwork.tail.all)
|
||||
(mkIf config.authentication.local.allow (cidrForNetwork.loopback.all ++ cidrForNetwork.local.all))
|
||||
];
|
||||
in
|
||||
mkMerge [
|
||||
(mkIf config.authentication.tailscale.allow cidrForNetwork.tail.all)
|
||||
(mkIf config.authentication.local.allow (cidrForNetwork.loopback.all ++ cidrForNetwork.local.all))
|
||||
];
|
||||
authentication = mkMerge (map (host: ''
|
||||
host ${config.authentication.database} ${config.name} ${formatHost host} ${config.authentication.method}
|
||||
'') config.authentication.hosts);
|
||||
host ${config.authentication.database} ${config.name} ${formatHost host} ${config.authentication.method}
|
||||
'')
|
||||
config.authentication.hosts);
|
||||
};
|
||||
authentication.database = mkIf config.ensureDBOwnership (
|
||||
mkOptionDefault config.name
|
||||
|
|
@ -70,11 +77,13 @@ in {
|
|||
enableTCPIP = mkIf (any (user: user.authentication.enable) cfg.ensureUsers) (
|
||||
mkDefault true
|
||||
);
|
||||
authentication = mkMerge (map (user:
|
||||
mkIf user.authentication.enable user.authentication.authentication
|
||||
) cfg.ensureUsers);
|
||||
authentication = mkMerge (map (
|
||||
user:
|
||||
mkIf user.authentication.enable user.authentication.authentication
|
||||
)
|
||||
cfg.ensureUsers);
|
||||
};
|
||||
config.networking.firewall.interfaces.local = mkIf cfg.enable {
|
||||
allowedTCPPorts = mkIf (any (user: user.authentication.local.allow) cfg.ensureUsers) [ cfg.port ];
|
||||
allowedTCPPorts = mkIf (any (user: user.authentication.local.allow) cfg.ensureUsers) [cfg.port];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.prowlarr = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.radarr = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.readarr = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -11,14 +11,17 @@
|
|||
inherit (config.services) samba-wsdd;
|
||||
cfg = config.services.samba;
|
||||
settingValue = value:
|
||||
if builtins.isList value then concatMapStringsSep ", " settingValue value
|
||||
else if value == true then "yes"
|
||||
else if value == false then "no"
|
||||
if builtins.isList value
|
||||
then concatMapStringsSep ", " settingValue value
|
||||
else if value == true
|
||||
then "yes"
|
||||
else if value == false
|
||||
then "no"
|
||||
else toString value;
|
||||
in {
|
||||
options.services.samba = with lib.types; let
|
||||
settingPrimitive = oneOf [ str int bool ];
|
||||
settingType = oneOf [ settingPrimitive (listOf settingPrimitive) ];
|
||||
settingPrimitive = oneOf [str int bool];
|
||||
settingType = oneOf [settingPrimitive (listOf settingPrimitive)];
|
||||
in {
|
||||
ldap = {
|
||||
enable = mkEnableOption "LDAP";
|
||||
|
|
@ -64,7 +67,11 @@ in {
|
|||
};
|
||||
};
|
||||
idmap = let
|
||||
idmapModule = { config, name, ... }: {
|
||||
idmapModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
backend = mkOption {
|
||||
type = str;
|
||||
|
|
@ -89,7 +96,7 @@ in {
|
|||
};
|
||||
settings = mkOption {
|
||||
type = attrsOf settingType;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
|
|
@ -117,7 +124,7 @@ in {
|
|||
};
|
||||
settings = mkOption {
|
||||
type = attrsOf settingType;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -139,35 +146,36 @@ in {
|
|||
})
|
||||
];
|
||||
settings = mkMerge ([
|
||||
{
|
||||
"use sendfile" = mkOptionDefault true;
|
||||
}
|
||||
(mkIf (cfg.passdb.smbpasswd.path != null) {
|
||||
"passdb backend" = mkOptionDefault "smbpasswd:${cfg.passdb.smbpasswd.path}";
|
||||
})
|
||||
(mkIf cfg.ldap.enable {
|
||||
"passdb backend" = mkOptionDefault ''ldapsam:"${cfg.ldap.url}"'';
|
||||
"ldap ssl" = mkIf (hasPrefix "ldaps://" cfg.ldap.url) (mkOptionDefault "off");
|
||||
"ldap admin dn" = mkOptionDefault "name=anonymous,${cfg.ldap.baseDn}";
|
||||
"ldap suffix" = mkOptionDefault cfg.ldap.baseDn;
|
||||
})
|
||||
(mkIf (cfg.ldap.enable && true) {
|
||||
"ntlm auth" = mkOptionDefault "disabled";
|
||||
"encrypt passwords" = mkOptionDefault false;
|
||||
})
|
||||
(mkIf cfg.usershare.enable {
|
||||
"usershare allow guests" = mkOptionDefault true;
|
||||
"usershare max shares" = mkOptionDefault 16;
|
||||
"usershare owner only" = mkOptionDefault true;
|
||||
"usershare template share" = mkOptionDefault cfg.usershare.templateShare;
|
||||
"usershare path" = mkOptionDefault cfg.usershare.path;
|
||||
"usershare prefix allow list" = mkOptionDefault [ cfg.usershare.path ];
|
||||
})
|
||||
(mkIf cfg.guest.enable {
|
||||
"map to guest" = mkOptionDefault "Bad User";
|
||||
"guest account" = mkOptionDefault cfg.guest.user;
|
||||
})
|
||||
] ++ mapAttrsToList (_: idmap: mapAttrs' (key: value: nameValuePair "idmap config ${idmap.domain} : ${key}" (mkOptionDefault value)) idmap.settings) cfg.idmap.domains);
|
||||
{
|
||||
"use sendfile" = mkOptionDefault true;
|
||||
}
|
||||
(mkIf (cfg.passdb.smbpasswd.path != null) {
|
||||
"passdb backend" = mkOptionDefault "smbpasswd:${cfg.passdb.smbpasswd.path}";
|
||||
})
|
||||
(mkIf cfg.ldap.enable {
|
||||
"passdb backend" = mkOptionDefault ''ldapsam:"${cfg.ldap.url}"'';
|
||||
"ldap ssl" = mkIf (hasPrefix "ldaps://" cfg.ldap.url) (mkOptionDefault "off");
|
||||
"ldap admin dn" = mkOptionDefault "name=anonymous,${cfg.ldap.baseDn}";
|
||||
"ldap suffix" = mkOptionDefault cfg.ldap.baseDn;
|
||||
})
|
||||
(mkIf (cfg.ldap.enable && true) {
|
||||
"ntlm auth" = mkOptionDefault "disabled";
|
||||
"encrypt passwords" = mkOptionDefault false;
|
||||
})
|
||||
(mkIf cfg.usershare.enable {
|
||||
"usershare allow guests" = mkOptionDefault true;
|
||||
"usershare max shares" = mkOptionDefault 16;
|
||||
"usershare owner only" = mkOptionDefault true;
|
||||
"usershare template share" = mkOptionDefault cfg.usershare.templateShare;
|
||||
"usershare path" = mkOptionDefault cfg.usershare.path;
|
||||
"usershare prefix allow list" = mkOptionDefault [cfg.usershare.path];
|
||||
})
|
||||
(mkIf cfg.guest.enable {
|
||||
"map to guest" = mkOptionDefault "Bad User";
|
||||
"guest account" = mkOptionDefault cfg.guest.user;
|
||||
})
|
||||
]
|
||||
++ mapAttrsToList (_: idmap: mapAttrs' (key: value: nameValuePair "idmap config ${idmap.domain} : ${key}" (mkOptionDefault value)) idmap.settings) cfg.idmap.domains);
|
||||
extraConfig = mkMerge (mapAttrsToList (key: value: ''${key} = ${settingValue value}'') cfg.settings);
|
||||
shares.${cfg.usershare.templateShare} = mkIf cfg.usershare.enable {
|
||||
"-valid" = false;
|
||||
|
|
@ -194,12 +202,12 @@ in {
|
|||
|
||||
networking.firewall.interfaces.local = {
|
||||
allowedTCPPorts = mkMerge [
|
||||
(mkIf (cfg.enable && !cfg.openFirewall) [ 139 445 ])
|
||||
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [ 5357 ])
|
||||
(mkIf (cfg.enable && !cfg.openFirewall) [139 445])
|
||||
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [5357])
|
||||
];
|
||||
allowedUDPPorts = mkMerge [
|
||||
(mkIf (cfg.enable && !cfg.openFirewall) [ 137 138 ])
|
||||
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [ 3702 ])
|
||||
(mkIf (cfg.enable && !cfg.openFirewall) [137 138])
|
||||
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [3702])
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.sonarr = with lib.types; {
|
||||
|
|
|
|||
|
|
@ -76,30 +76,35 @@ in {
|
|||
inherit owner;
|
||||
inherit (shared) group mode;
|
||||
};
|
||||
setupFiles = singleton {
|
||||
${cfg.rootDir} = toplevel;
|
||||
${cfg.binDir} = toplevel;
|
||||
${cfg.binDir + "/users"} = shared;
|
||||
${cfg.dataDir} = toplevel;
|
||||
${cfg.sharedDataDir} = shared;
|
||||
${cfg.workingDir} = toplevel;
|
||||
${cfg.sharedWorkingDir} = shared;
|
||||
} ++ map (owner: {
|
||||
${cfg.dataDir + "/${owner}"} = personal owner;
|
||||
${cfg.workingDir + "/${owner}"} = personal owner;
|
||||
}) cfg.users;
|
||||
userBinFiles = listToAttrs (map (user: nameValuePair "${cfg.binDir}/users/${user}.bat" {
|
||||
inherit (toplevel) owner group;
|
||||
mode = "0755";
|
||||
type = "copy";
|
||||
src = pkgs.writeTextFile {
|
||||
name = "steam-${user}.bat";
|
||||
executable = true;
|
||||
text = ''
|
||||
setx GENSO_STEAM_USER ${user}
|
||||
'';
|
||||
};
|
||||
}) cfg.users);
|
||||
setupFiles =
|
||||
singleton {
|
||||
${cfg.rootDir} = toplevel;
|
||||
${cfg.binDir} = toplevel;
|
||||
${cfg.binDir + "/users"} = shared;
|
||||
${cfg.dataDir} = toplevel;
|
||||
${cfg.sharedDataDir} = shared;
|
||||
${cfg.workingDir} = toplevel;
|
||||
${cfg.sharedWorkingDir} = shared;
|
||||
}
|
||||
++ map (owner: {
|
||||
${cfg.dataDir + "/${owner}"} = personal owner;
|
||||
${cfg.workingDir + "/${owner}"} = personal owner;
|
||||
})
|
||||
cfg.users;
|
||||
userBinFiles = listToAttrs (map (user:
|
||||
nameValuePair "${cfg.binDir}/users/${user}.bat" {
|
||||
inherit (toplevel) owner group;
|
||||
mode = "0755";
|
||||
type = "copy";
|
||||
src = pkgs.writeTextFile {
|
||||
name = "steam-${user}.bat";
|
||||
executable = true;
|
||||
text = ''
|
||||
setx GENSO_STEAM_USER ${user}
|
||||
'';
|
||||
};
|
||||
})
|
||||
cfg.users);
|
||||
in {
|
||||
enable = mkIf (cfg.enable || cfg.setup) true;
|
||||
files = mkMerge [
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@
|
|||
inherit (lib.meta) getExe;
|
||||
inherit (config.services.steam) accountSwitch;
|
||||
cfg = config.services.steam.beatsaber;
|
||||
versionModule = { config, name, ... }: {
|
||||
versionModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = with lib.types; {
|
||||
version = mkOption {
|
||||
type = str;
|
||||
|
|
@ -23,11 +27,12 @@
|
|||
};
|
||||
};
|
||||
|
||||
mkSharePath = path: mkWinPath (
|
||||
"%GENSO_SMB_SHARED_MOUNT%"
|
||||
+ "/${accountSwitch.sharePath}"
|
||||
+ "/${removePrefix (accountSwitch.rootDir + "/") path}"
|
||||
);
|
||||
mkSharePath = path:
|
||||
mkWinPath (
|
||||
"%GENSO_SMB_SHARED_MOUNT%"
|
||||
+ "/${accountSwitch.sharePath}"
|
||||
+ "/${removePrefix (accountSwitch.rootDir + "/") path}"
|
||||
);
|
||||
vars = ''
|
||||
if "%GENSO_STEAM_INSTALL%" == "" set "GENSO_STEAM_INSTALL=C:\Program Files (x86)\Steam"
|
||||
if "%GENSO_STEAM_LIBRARY_BS%" == "" set "GENSO_STEAM_LIBRARY_BS=%GENSO_STEAM_INSTALL%"
|
||||
|
|
@ -102,9 +107,11 @@
|
|||
in {
|
||||
options.services.steam.beatsaber = with lib.types; {
|
||||
enable = mkEnableOption "beatsaber scripts";
|
||||
setup = mkEnableOption "beatsaber data" // {
|
||||
default = accountSwitch.setup;
|
||||
};
|
||||
setup =
|
||||
mkEnableOption "beatsaber data"
|
||||
// {
|
||||
default = accountSwitch.setup;
|
||||
};
|
||||
group = mkOption {
|
||||
type = str;
|
||||
default = "beatsaber";
|
||||
|
|
@ -114,7 +121,7 @@ in {
|
|||
};
|
||||
versions = mkOption {
|
||||
type = attrsOf (submodule versionModule);
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
users = mkOption {
|
||||
type = listOf str;
|
||||
|
|
@ -127,7 +134,7 @@ in {
|
|||
bsUsers = filterAttrs (_: userIs cfg.group) config.users.users;
|
||||
allVersions = mapAttrsToList (_: version: version.version) cfg.versions;
|
||||
in {
|
||||
defaultVersion = mkIf (allVersions != [ ]) (mkOptionDefault (
|
||||
defaultVersion = mkIf (allVersions != []) (mkOptionDefault (
|
||||
head allVersions
|
||||
));
|
||||
users = mkOptionDefault (
|
||||
|
|
@ -140,24 +147,27 @@ in {
|
|||
mkbeatsabersh
|
||||
];
|
||||
};
|
||||
systemd.services = mkIf cfg.setup (listToAttrs (map (user: nameValuePair "steam-setup-beatsaber-${user}" {
|
||||
script = mkMerge (mapAttrsToList (_: version: ''
|
||||
${getExe mkbeatsaber} ${version.version} ${user}
|
||||
'') cfg.versions);
|
||||
path = [
|
||||
pkgs.coreutils
|
||||
];
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
];
|
||||
after = [
|
||||
"tmpfiles.service"
|
||||
];
|
||||
serviceConfig = {
|
||||
RemainAfterExit = mkOptionDefault true;
|
||||
User = mkOptionDefault user;
|
||||
};
|
||||
}) cfg.users));
|
||||
systemd.services = mkIf cfg.setup (listToAttrs (map (user:
|
||||
nameValuePair "steam-setup-beatsaber-${user}" {
|
||||
script = mkMerge (mapAttrsToList (_: version: ''
|
||||
${getExe mkbeatsaber} ${version.version} ${user}
|
||||
'')
|
||||
cfg.versions);
|
||||
path = [
|
||||
pkgs.coreutils
|
||||
];
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
];
|
||||
after = [
|
||||
"tmpfiles.service"
|
||||
];
|
||||
serviceConfig = {
|
||||
RemainAfterExit = mkOptionDefault true;
|
||||
User = mkOptionDefault user;
|
||||
};
|
||||
})
|
||||
cfg.users));
|
||||
services.tmpfiles = let
|
||||
toplevel = {
|
||||
owner = mkDefault "admin";
|
||||
|
|
@ -187,77 +197,92 @@ in {
|
|||
"AppData"
|
||||
"UserData"
|
||||
];
|
||||
setupFiles = [
|
||||
setupFiles =
|
||||
[
|
||||
{
|
||||
"${accountSwitch.sharedDataDir}/BeatSaber" = toplevel;
|
||||
"${accountSwitch.binDir}/beatsaber" = shared;
|
||||
}
|
||||
(listToAttrs (
|
||||
map (
|
||||
folder:
|
||||
nameValuePair "${accountSwitch.sharedDataDir}/BeatSaber/${folder}" shared
|
||||
)
|
||||
sharedFolders
|
||||
))
|
||||
]
|
||||
++ concatMap (
|
||||
owner:
|
||||
singleton {
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber" = personal owner;
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/AppData" = personal owner;
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/UserData" = personal owner;
|
||||
}
|
||||
++ mapAttrsToList (_: version: {
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/${version.version}" = personal owner;
|
||||
})
|
||||
cfg.versions
|
||||
)
|
||||
accountSwitch.users
|
||||
++ mapAttrsToList (_: version: {
|
||||
"${accountSwitch.sharedDataDir}/BeatSaber/${version.version}" = shared;
|
||||
})
|
||||
cfg.versions;
|
||||
versionBinFiles =
|
||||
mapAttrs' (
|
||||
_: version:
|
||||
nameValuePair
|
||||
"${accountSwitch.binDir}/beatsaber/${replaceStrings ["."] ["_"] version.version}.bat"
|
||||
{
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-${version.version}.bat";
|
||||
executable = true;
|
||||
text = ''
|
||||
setx GENSO_STEAM_BS_VERSION ${version.version}
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
cfg.versions;
|
||||
binFiles =
|
||||
{
|
||||
"${accountSwitch.sharedDataDir}/BeatSaber" = toplevel;
|
||||
"${accountSwitch.binDir}/beatsaber" = shared;
|
||||
}
|
||||
(listToAttrs (
|
||||
map (folder:
|
||||
nameValuePair "${accountSwitch.sharedDataDir}/BeatSaber/${folder}" shared
|
||||
) sharedFolders
|
||||
))
|
||||
] ++ concatMap (owner:
|
||||
singleton {
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber" = personal owner;
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/AppData" = personal owner;
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/UserData" = personal owner;
|
||||
} ++ mapAttrsToList (_: version: {
|
||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/${version.version}" = personal owner;
|
||||
}) cfg.versions
|
||||
) accountSwitch.users
|
||||
++ mapAttrsToList (_: version: {
|
||||
"${accountSwitch.sharedDataDir}/BeatSaber/${version.version}" = shared;
|
||||
}) cfg.versions;
|
||||
versionBinFiles = mapAttrs' (_: version: nameValuePair
|
||||
"${accountSwitch.binDir}/beatsaber/${replaceStrings [ "." ] [ "_" ] version.version}.bat"
|
||||
{
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-${version.version}.bat";
|
||||
executable = true;
|
||||
text = ''
|
||||
setx GENSO_STEAM_BS_VERSION ${version.version}
|
||||
'';
|
||||
"${accountSwitch.binDir}/beatsaber/mount.bat" = {
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-mount.bat";
|
||||
executable = true;
|
||||
text = mountbeatsaber;
|
||||
};
|
||||
};
|
||||
"${accountSwitch.binDir}/beatsaber/launch.bat" = {
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-launch.bat";
|
||||
executable = true;
|
||||
text = launchbeatsaber;
|
||||
};
|
||||
};
|
||||
"${accountSwitch.binDir}/beatsaber/fpfc.bat" = {
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-fpfc.bat";
|
||||
executable = true;
|
||||
text = fpfcbeatsaber;
|
||||
};
|
||||
};
|
||||
"${accountSwitch.binDir}/beatsaber/ModAssistant.exe" = {
|
||||
inherit (toplevel) owner group;
|
||||
mode = "0755";
|
||||
type = "copy";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/Assistant/ModAssistant/releases/download/v1.1.32/ModAssistant.exe";
|
||||
hash = "sha256-ozu2gYFiz+2BjptqL80DmUopbahbyGKFO1IPd7BhVPM=";
|
||||
executable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
) cfg.versions;
|
||||
binFiles = {
|
||||
"${accountSwitch.binDir}/beatsaber/mount.bat" = {
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-mount.bat";
|
||||
executable = true;
|
||||
text = mountbeatsaber;
|
||||
};
|
||||
};
|
||||
"${accountSwitch.binDir}/beatsaber/launch.bat" = {
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-launch.bat";
|
||||
executable = true;
|
||||
text = launchbeatsaber;
|
||||
};
|
||||
};
|
||||
"${accountSwitch.binDir}/beatsaber/fpfc.bat" = {
|
||||
inherit (bin) owner group mode type;
|
||||
src = pkgs.writeTextFile {
|
||||
name = "beatsaber-fpfc.bat";
|
||||
executable = true;
|
||||
text = fpfcbeatsaber;
|
||||
};
|
||||
};
|
||||
"${accountSwitch.binDir}/beatsaber/ModAssistant.exe" = {
|
||||
inherit (toplevel) owner group;
|
||||
mode = "0755";
|
||||
type = "copy";
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/Assistant/ModAssistant/releases/download/v1.1.32/ModAssistant.exe";
|
||||
hash = "sha256-ozu2gYFiz+2BjptqL80DmUopbahbyGKFO1IPd7BhVPM=";
|
||||
executable = true;
|
||||
};
|
||||
};
|
||||
} // versionBinFiles;
|
||||
// versionBinFiles;
|
||||
in {
|
||||
enable = mkIf (cfg.enable || cfg.setup) true;
|
||||
files = mkMerge [
|
||||
|
|
|
|||
|
|
@ -18,11 +18,17 @@
|
|||
systemdFiles = filter (file: file.systemd.enable) files;
|
||||
setupFiles = filter (file: !file.systemd.enable) files;
|
||||
bindFiles = filter (file: file.type == "bind") files;
|
||||
fileModule = { config, name, ... }: {
|
||||
fileModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "file" // {
|
||||
default = true;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "file"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
mkdirParent = mkEnableOption "mkdir";
|
||||
bindReadOnly = mkEnableOption "mount -oro";
|
||||
relativeSymlink = mkEnableOption "ln -sr";
|
||||
|
|
@ -32,8 +38,11 @@
|
|||
default = name;
|
||||
};
|
||||
type = mkOption {
|
||||
type = enum [ "directory" "symlink" "link" "copy" "bind" ];
|
||||
default = if config.src != null then "symlink" else "directory";
|
||||
type = enum ["directory" "symlink" "link" "copy" "bind"];
|
||||
default =
|
||||
if config.src != null
|
||||
then "symlink"
|
||||
else "directory";
|
||||
};
|
||||
mode = mkOption {
|
||||
type = str;
|
||||
|
|
@ -71,7 +80,7 @@
|
|||
};
|
||||
config = let
|
||||
acls = concatStringsSep "," config.acls;
|
||||
enableAcls = config.type == "directory" && config.acls != [ ];
|
||||
enableAcls = config.type == "directory" && config.acls != [];
|
||||
systemdAclRule = "a+ ${config.path} - - - - ${acls}";
|
||||
systemdRule = {
|
||||
directory = [
|
||||
|
|
@ -168,7 +177,7 @@
|
|||
systemd = {
|
||||
rules = mkMerge [
|
||||
systemdRule.${config.type}
|
||||
(mkIf enableAcls [ systemdAclRule ])
|
||||
(mkIf enableAcls [systemdAclRule])
|
||||
];
|
||||
mountSettings = mkIf (config.type == "bind") {
|
||||
enable = mkDefault config.enable;
|
||||
|
|
@ -191,16 +200,21 @@
|
|||
};
|
||||
in {
|
||||
options.services.tmpfiles = with lib.types; {
|
||||
enable = mkEnableOption "extended tmpfiles" // {
|
||||
default = cfg.files != { };
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "extended tmpfiles"
|
||||
// {
|
||||
default = cfg.files != {};
|
||||
};
|
||||
user = mkOption {
|
||||
type = str;
|
||||
default = if config.proxmoxLXC.privileged or true then "root" else "admin";
|
||||
default =
|
||||
if config.proxmoxLXC.privileged or true
|
||||
then "root"
|
||||
else "admin";
|
||||
};
|
||||
files = mkOption {
|
||||
type = attrsOf (submodule fileModule);
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
|
|
@ -209,15 +223,19 @@ in {
|
|||
map (file: file.systemd.rules) systemdFiles
|
||||
);
|
||||
services.tmpfiles = {
|
||||
path = [ pkgs.coreutils pkgs.acl ];
|
||||
path = [pkgs.coreutils pkgs.acl];
|
||||
script = mkMerge (
|
||||
[ ''
|
||||
EXITCODE=0
|
||||
'' ]
|
||||
[
|
||||
''
|
||||
EXITCODE=0
|
||||
''
|
||||
]
|
||||
++ map (file: file.setup.script) setupFiles
|
||||
++ [ ''
|
||||
exit $EXITCODE
|
||||
'' ]
|
||||
++ [
|
||||
''
|
||||
exit $EXITCODE
|
||||
''
|
||||
]
|
||||
);
|
||||
wantedBy = [
|
||||
"sysinit.target"
|
||||
|
|
|
|||
|
|
@ -13,28 +13,33 @@
|
|||
userMatchBlock = user: let
|
||||
inherit (user.openssh) matchBlock;
|
||||
criteria = mapAttrsToList toSshdCriteria matchBlock.criteria;
|
||||
in mkAfter ''
|
||||
Match ${concatStringsSep " " criteria}
|
||||
${matchBlock.settingsConfig}
|
||||
'';
|
||||
userModule = { config, ... }: let
|
||||
in
|
||||
mkAfter ''
|
||||
Match ${concatStringsSep " " criteria}
|
||||
${matchBlock.settingsConfig}
|
||||
'';
|
||||
userModule = {config, ...}: let
|
||||
toSshdValue = value:
|
||||
if value == true then "yes"
|
||||
else if value == false then "no"
|
||||
if value == true
|
||||
then "yes"
|
||||
else if value == false
|
||||
then "no"
|
||||
else toString value;
|
||||
toSshdConf = key: value: "${key} ${toSshdValue value}";
|
||||
in {
|
||||
options = with lib.types; {
|
||||
openssh.matchBlock = {
|
||||
enable = mkEnableOption "match block" // {
|
||||
default = config.openssh.matchBlock.settings != { };
|
||||
};
|
||||
enable =
|
||||
mkEnableOption "match block"
|
||||
// {
|
||||
default = config.openssh.matchBlock.settings != {};
|
||||
};
|
||||
criteria = mkOption {
|
||||
type = attrsOf str;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = attrsOf (oneOf [ str path bool int ]);
|
||||
default = { };
|
||||
type = attrsOf (oneOf [str path bool int]);
|
||||
default = {};
|
||||
};
|
||||
settingsConfig = mkOption {
|
||||
type = lines;
|
||||
|
|
|
|||
|
|
@ -5,11 +5,20 @@
|
|||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkMerge mkDefault mkOptionDefault mkOption mkEnableOption types
|
||||
getExe;
|
||||
inherit
|
||||
(lib)
|
||||
mkIf
|
||||
mkMerge
|
||||
mkDefault
|
||||
mkOptionDefault
|
||||
mkOption
|
||||
mkEnableOption
|
||||
types
|
||||
getExe
|
||||
;
|
||||
nixosConfig = config;
|
||||
cfg = config.services.vouch-proxy;
|
||||
settingsFormat = pkgs.formats.json { };
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
in {
|
||||
options.services.vouch-proxy = with types; {
|
||||
enable = mkEnableOption "vouch";
|
||||
|
|
@ -35,7 +44,7 @@ in {
|
|||
};
|
||||
enableSettingsSecrets = mkEnableOption "genJqSecretsReplacementSnippet";
|
||||
settings = let
|
||||
settingsModule = { ... }: {
|
||||
settingsModule = {...}: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
vouch = {
|
||||
|
|
@ -98,13 +107,14 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = submodule settingsModule;
|
||||
default = { };
|
||||
};
|
||||
in
|
||||
mkOption {
|
||||
type = submodule settingsModule;
|
||||
default = {};
|
||||
};
|
||||
extraSettings = mkOption {
|
||||
inherit (settingsFormat) type;
|
||||
default = { };
|
||||
default = {};
|
||||
};
|
||||
settingsPath = mkOption {
|
||||
type = path;
|
||||
|
|
@ -116,48 +126,51 @@ in {
|
|||
cfg.settings
|
||||
cfg.extraSettings
|
||||
];
|
||||
settingsPath = if cfg.enableSettingsSecrets
|
||||
settingsPath =
|
||||
if cfg.enableSettingsSecrets
|
||||
then "/run/vouch-proxy/vouch-config.json"
|
||||
else settingsFormat.generate "vouch-config.json" settings;
|
||||
in mkMerge [
|
||||
{
|
||||
services.vouch-proxy = {
|
||||
settingsPath = mkOptionDefault settingsPath;
|
||||
};
|
||||
}
|
||||
(mkIf cfg.enable {
|
||||
systemd.services.vouch-proxy = {
|
||||
description = "Vouch-proxy";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStartPre = let
|
||||
preprocess = pkgs.writeShellScript "vouch-proxy-prestart" (
|
||||
utils.genJqSecretsReplacementSnippet settings cfg.settingsPath
|
||||
);
|
||||
in mkIf cfg.enableSettingsSecrets [
|
||||
"${preprocess}"
|
||||
];
|
||||
ExecStart = [
|
||||
"${getExe pkgs.vouch-proxy} -config ${cfg.settingsPath}"
|
||||
];
|
||||
Restart = "on-failure";
|
||||
RestartSec = mkDefault 5;
|
||||
WorkingDirectory = "/var/lib/vouch-proxy";
|
||||
StateDirectory = "vouch-proxy";
|
||||
RuntimeDirectory = "vouch-proxy";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StartLimitBurst = mkDefault 3;
|
||||
in
|
||||
mkMerge [
|
||||
{
|
||||
services.vouch-proxy = {
|
||||
settingsPath = mkOptionDefault settingsPath;
|
||||
};
|
||||
}
|
||||
(mkIf cfg.enable {
|
||||
systemd.services.vouch-proxy = {
|
||||
description = "Vouch-proxy";
|
||||
after = ["network.target"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
serviceConfig = {
|
||||
ExecStartPre = let
|
||||
preprocess = pkgs.writeShellScript "vouch-proxy-prestart" (
|
||||
utils.genJqSecretsReplacementSnippet settings cfg.settingsPath
|
||||
);
|
||||
in
|
||||
mkIf cfg.enableSettingsSecrets [
|
||||
"${preprocess}"
|
||||
];
|
||||
ExecStart = [
|
||||
"${getExe pkgs.vouch-proxy} -config ${cfg.settingsPath}"
|
||||
];
|
||||
Restart = "on-failure";
|
||||
RestartSec = mkDefault 5;
|
||||
WorkingDirectory = "/var/lib/vouch-proxy";
|
||||
StateDirectory = "vouch-proxy";
|
||||
RuntimeDirectory = "vouch-proxy";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StartLimitBurst = mkDefault 3;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
inherit (cfg) group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.users.${cfg.user} = {
|
||||
inherit (cfg) group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.${cfg.group} = {};
|
||||
})
|
||||
];
|
||||
users.groups.${cfg.group} = {};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue