chore: nf-fmt-nix

This commit is contained in:
arcnmx 2024-05-13 15:13:58 -07:00
parent 7486517713
commit 9903866044
160 changed files with 4570 additions and 3019 deletions

View file

@ -3,19 +3,25 @@
whitelist = [
"overlays/default.nix"
"ci/fmt.nix"
"docs/derivation.nix"
"devShells.nix"
"shell.nix"
"generate.nix"
"lib.nix"
"outputs.nix"
"tree.nix"
];
whitelistDirs = [
"modules/extern"
"modules/nixos"
"modules/system"
"nixos"
"overlays"
"packages"
"systems"
];
blacklistDirs = [
"overlays"
"modules/nixos/ldap"
"ci"
];
};

View file

@ -151,11 +151,15 @@
LDAPSASL_NOCANON = "on";
};
arc = let
ldapdm = cmd: pkgs.writeShellScriptBin "dm-${cmd}" ''
ldapdm = cmd:
pkgs.writeShellScriptBin "dm-${cmd}" ''
${cmd} -D 'cn=Directory Manager' -y <(bitw get -f password ldap-directory-manager) "$@"
'';
in default.overrideAttrs (default: {
nativeBuildInputs = default.nativeBuildInputs ++ [
in
default.overrideAttrs (default: {
nativeBuildInputs =
default.nativeBuildInputs
++ [
(ldapdm "ldapwhoami")
(ldapdm "ldappasswd")
(ldapdm "ldapsearch")

View file

@ -19,23 +19,33 @@
};
nodeSystems = let
matchesNode = nodeName: system: system.config.proxmox.enabled && system.config.proxmox.node.name == nodeName;
in nodeName: filterAttrs (_: matchesNode nodeName) systems;
in
nodeName: filterAttrs (_: matchesNode nodeName) systems;
mkNodeSystem = system: {
inherit (system.config.access) hostName;
network = let
inherit (system.config.network) networks;
in {
networks = {
int = if networks.int.enable or false then {
int =
if networks.int.enable or false
then {
inherit (networks.int) macAddress address4 address6;
} else null;
local = if networks.local.enable or false then {
}
else null;
local =
if networks.local.enable or false
then {
inherit (networks.local) macAddress address4 address6;
} else null;
tail = if networks.tail.enable or false then {
}
else null;
tail =
if networks.tail.enable or false
then {
inherit (networks.tail) address4 address6;
macAddress = null;
} else null;
}
else null;
};
};
};
@ -43,10 +53,12 @@
mkExtern = system: let
enabledFiles = filterAttrs (_: file: file.enable) system.extern.files;
in {
files = mapAttrs' (_: file: nameValuePair file.path {
files = mapAttrs' (_: file:
nameValuePair file.path {
source = assert file.relativeSource != null; file.relativeSource;
inherit (file) owner group mode;
}) enabledFiles;
})
enabledFiles;
};
mkNode = system: {
users = mkNodeUsers templateUsers;
@ -58,13 +70,17 @@
};
mkNetwork = system: {
inherit (system.config.access) hostName;
networks = {
networks =
{
int = null;
local = null;
tail = null;
} // mapAttrs' (_: network: nameValuePair network.name {
}
// mapAttrs' (_: network:
nameValuePair network.name {
inherit (network) macAddress address4 address6;
}) system.config.network.networks;
})
system.config.network.networks;
};
mkSystem = name: system: {
network = mkNetwork system;
@ -72,6 +88,7 @@
in {
nodes = let
nodes = filterAttrs (_: node: node.config.proxmox.node.enable) systems;
in mapAttrs (_: mkNode) nodes;
in
mapAttrs (_: mkNode) nodes;
systems = mapAttrs mkSystem systems;
}

57
lib.nix
View file

@ -23,11 +23,15 @@
parts' = Regex.match ''^([^:]+)://(\[[0-9a-fA-F:]+]|[^/:\[]+)(|:[0-9]+)(|/.*)$'' url;
parts = parts'.value;
port' = List.index parts 2;
in assert Opt.isJust parts'; rec {
in
assert Opt.isJust parts'; rec {
inherit url parts;
scheme = List.index parts 0;
host = List.index parts 1;
port = if port' != "" then UInt.Parse (Str.removePrefix ":" port') else null;
port =
if port' != ""
then UInt.Parse (Str.removePrefix ":" port')
else null;
hostport = host + port';
path = List.index parts 3;
};
@ -36,7 +40,10 @@
mkWinPath = Str.replace ["/"] ["\\"];
mkBaseDn = domain: Str.concatMapSep "," (part: "dc=${part}") (Regex.splitOn "\\." domain);
mkAddress6 = addr: if Str.hasInfix ":" addr && ! Str.hasPrefix "[" addr then "[${addr}]" else addr;
mkAddress6 = addr:
if Str.hasInfix ":" addr && ! Str.hasPrefix "[" addr
then "[${addr}]"
else addr;
coalesce = values: Opt.default null (List.find (v: v != null) values);
mapListToAttrs = f: l: listToAttrs (map f l);
@ -85,13 +92,43 @@ in {
Std = inputs.std-fl.lib;
lib = {
domain = "gensokyo.zone";
inherit treeToModulesOutput userIs
eui64 parseUrl mkWinPath mkBaseDn mkAddress6
mapListToAttrs coalesce
mkAlmostOptionDefault mkAlmostDefault mkAlmostForce mapOverride mapOptionDefaults mapAlmostOptionDefaults mapDefaults
overrideOptionDefault overrideAlmostOptionDefault overrideDefault overrideAlmostDefault overrideNone overrideAlmostForce overrideForce overrideVM
orderJustBefore orderBefore orderAlmostBefore orderNone orderAfter orderAlmostAfter orderJustAfter
mkJustBefore mkAlmostBefore mkAlmostAfter mkJustAfter;
inherit
treeToModulesOutput
userIs
eui64
parseUrl
mkWinPath
mkBaseDn
mkAddress6
mapListToAttrs
coalesce
mkAlmostOptionDefault
mkAlmostDefault
mkAlmostForce
mapOverride
mapOptionDefaults
mapAlmostOptionDefaults
mapDefaults
overrideOptionDefault
overrideAlmostOptionDefault
overrideDefault
overrideAlmostDefault
overrideNone
overrideAlmostForce
overrideForce
overrideVM
orderJustBefore
orderBefore
orderAlmostBefore
orderNone
orderAfter
orderAlmostAfter
orderJustAfter
mkJustBefore
mkAlmostBefore
mkAlmostAfter
mkJustAfter
;
inherit (inputs.arcexprs.lib) unmerged json;
};
gensokyo-zone = {

View file

@ -1,4 +1,8 @@
{inputs, ...}: {lib, osConfig, ...}: let
{inputs, ...}: {
lib,
osConfig,
...
}: let
inherit (inputs.self.lib) meta;
inherit (lib.modules) mkIf;
in {

View file

@ -19,16 +19,23 @@ let
system = gensokyo-zone.systems.${config.systemName}.config;
networks = let
fallbackNetwork =
if system.network.networks.local.enable or false && access.local.enable then "local"
else if system.access.global.enable then null
else if system.network.networks.int.enable or false then "int"
else if system.network.networks.local.enable or false then "local"
if system.network.networks.local.enable or false && access.local.enable
then "local"
else if system.access.global.enable
then null
else if system.network.networks.int.enable or false
then "int"
else if system.network.networks.local.enable or false
then "local"
else null;
networks = map (name: coalesce [name fallbackNetwork]) config.networks;
in unique networks;
in
unique networks;
in {
options = with lib.types; {
enable = mkEnableOption "ssh client configuration" // {
enable =
mkEnableOption "ssh client configuration"
// {
default = true;
};
name = mkOption {
@ -66,12 +73,17 @@ let
enabledNetworks = filterAttrs (_: net: net.enable) system.network.networks;
networkNames = mapAttrsToList (_: net: net.name) enabledNetworks;
networks = filter (name: name == null || elem name networkNames) cfg.networks;
in mkOptionDefault networks;
in
mkOptionDefault networks;
set = {
matchBlocksSettings = let
canonNetworkName' = intersectLists networks [null "int" "local"];
canonNetworkName = if canonNetworkName' != [ ] then head canonNetworkName' else null;
in mapListToAttrs (network: let
canonNetworkName =
if canonNetworkName' != []
then head canonNetworkName'
else null;
in
mapListToAttrs (network: let
name = config.name + optionalString (network != canonNetworkName) "-${network}";
inherit (system.exports.services) sshd;
port = head (
@ -80,9 +92,11 @@ let
++ [sshd.ports.standard.port]
);
needsProxy = network == "int" || (network == "local" && !access.local.enable);
in nameValuePair name {
in
nameValuePair name {
hostname = mkDefault (
if network == null then system.access.fqdn
if network == null
then system.access.fqdn
else system.network.networks.${network}.fqdn
);
user = mkIf (config.user != null) (mkDefault config.user);
@ -97,7 +111,8 @@ let
HostKeyAlias = mkIf (config.hostName != null && network != null) (mkOptionDefault system.access.fqdn);
}
];
}) networks;
})
networks;
};
};
};
@ -150,7 +165,8 @@ let
};
config = {
proxyJump = mkOptionDefault (
if config.hosts.hakurei.enable then config.hosts.hakurei.name
if config.hosts.hakurei.enable
then config.hosts.hakurei.name
else gensokyo-zone.systems.hakurei.config.access.fqdn
);
networks = mkOptionDefault [
@ -159,19 +175,23 @@ let
];
hosts = mapAttrs (name: system: let
enabled = system.config.access.online.enable && system.config.exports.services.sshd.enable;
in mkIf enabled {
in
mkIf enabled {
systemName = mkOptionDefault name;
}) gensokyo-zone.systems;
})
gensokyo-zone.systems;
set = {
matchBlocksSettings = let
mkMatchBlocksHost = host: mkIf host.enable (unmerged.mergeAttrs host.set.matchBlocksSettings);
in mkMerge (
in
mkMerge (
mapAttrsToList (_: mkMatchBlocksHost) config.hosts
);
};
};
};
in {
in
{
config,
osConfig,
lib,

View file

@ -67,7 +67,8 @@
];
nameservers = let
inherit (gensokyo-zone.systems) utsuho hakurei;
in mkMerge [
in
mkMerge [
(mkOptionDefault [])
(mkIf access.local.enable [
(mkIf enableIPv6 utsuho.config.access.address6ForNetwork.local)
@ -79,20 +80,25 @@
hakurei.config.access.address4ForNetwork.tail
])
];
fallbackNameservers = mkOptionDefault {
fallbackNameservers =
mkOptionDefault
{
cloudflare = [
"1.1.1.1#cloudflare-dns.com"
"1.0.0.1#cloudflare-dns.com"
];
google = optionals enableIPv6 [
google =
optionals enableIPv6 [
"[2001:4860:4860::8888]#dns.google"
"[2001:4860:4860::8844]#dns.google"
] ++ [
]
++ [
"8.8.8.8#dns.google"
"8.8.4.4#dns.google"
];
${toString null} = [];
}.${toString config.fallback};
}
.${toString config.fallback};
set = {
nssSettings = {
hosts = mkMerge [

View file

@ -40,7 +40,9 @@
default = toUpper config.domain;
};
ca = {
trust = mkEnableOption "trust CA" // {
trust =
mkEnableOption "trust CA"
// {
default = true;
};
pem = mkOption {
@ -109,14 +111,18 @@
pam.enable = mkEnableOption "PAM";
backend = mkOption {
type = enum ["ipa" "ldap"];
default = {
default =
{
ipa = "ipa";
kldap = "ldap";
}.${config.db.backend};
}
.${config.db.backend};
};
};
ntp = {
enable = mkEnableOption "ntp" // {
enable =
mkEnableOption "ntp"
// {
default = true;
};
servers = mkOption {
@ -185,7 +191,8 @@
url = "https://${config.ipa.httpHost}/ipa/config/ca.crt";
sha256 = "sha256-PKjnjn1jIq9x4BX8+WGkZfj4HQtmnHqmFSALqggo91o=";
};
in mkOptionDefault caPem;
in
mkOptionDefault caPem;
ldap = {
urls = mkMerge [
(mkIf access.local.enable (mkOptionDefault (mkBefore [
@ -200,7 +207,8 @@
];
bind = let
inherit (nixosConfig.sops) secrets;
in mkIf (nixosOptions ? sops.secrets && secrets ? gensokyo-zone-krb5-passwords) {
in
mkIf (nixosOptions ? sops.secrets && secrets ? gensokyo-zone-krb5-passwords) {
passwordFileKrb5 = mkOptionDefault nixosConfig.sops.secrets.gensokyo-zone-krb5-passwords.path;
passwordFile = mkOptionDefault nixosConfig.sops.secrets.gensokyo-zone-krb5-peep-password.path;
passwordFileSssdEnv = mkOptionDefault nixosConfig.sops.secrets.gensokyo-zone-sssd-passwords.path;
@ -243,13 +251,15 @@
};
};
sssdSettings = let
servers = optional access.local.enable "idp.local.${config.domain}"
servers =
optional access.local.enable "idp.local.${config.domain}"
++ ["_srv"];
backups = mkMerge [
(mkIf access.tail.enabled (mkAlmostOptionDefault ["ipa.tail.${config.domain}"]))
(mkIf access.local.enable (mkAlmostOptionDefault ["ipa.local.${config.domain}"]))
];
in mkIf config.sssd.enable {
in
mkIf config.sssd.enable {
enable = mkAlmostOptionDefault true;
gensokyo-zone = {
backend = mkAlmostOptionDefault config.sssd.backend;
@ -268,7 +278,8 @@
]));
};
};
environmentFile = mkIf (config.sssd.backend == "ldap") (mkAlmostOptionDefault
environmentFile = mkIf (config.sssd.backend == "ldap") (
mkAlmostOptionDefault
config.ldap.bind.passwordFileSssdEnv
);
services = {
@ -284,14 +295,19 @@
realm = config.realm;
server = config.ipa.server;
# TODO: dyndns?
} // {
}
// {
overrideConfigs = mapAlmostOptionDefaults {
sssd = false;
krb5 = false;
};
});
nfsSettings = mkIf config.nfs.enable {
${if nixosOptions ? services.nfs.settings then "settings" else null} = mkMerge [
${
if nixosOptions ? services.nfs.settings
then "settings"
else null
} = mkMerge [
{
gssd = mapOptionDefaults {
#use-machine-creds = false;
@ -314,7 +330,11 @@
};
})
];
${if nixosOptions ? services.nfs.settings then null else "extraConfig"} = mkMerge [
${
if nixosOptions ? services.nfs.settings
then null
else "extraConfig"
} = mkMerge [
''
[gssd]
#use-machine-creds = false
@ -413,7 +433,8 @@ in {
hosts = let
inherit (gensokyo-zone.systems) freeipa;
# TODO: consider hakurei instead...
in mkIf (cfg.enable && !config.gensokyo-zone.dns.enable or false && config.gensokyo-zone.access.local.enable) {
in
mkIf (cfg.enable && !config.gensokyo-zone.dns.enable or false && config.gensokyo-zone.access.local.enable) {
${freeipa.config.access.address6ForNetwork.local} = mkIf config.networking.enableIPv6 (mkBefore [cfg.host]);
${freeipa.config.access.address4ForNetwork.local} = mkBefore [cfg.host];
};
@ -425,14 +446,20 @@ in {
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${config.system.nssModules.path}"
exec ${cfg.nfs.package}/bin/nfsidmap "$@"
'';
in mkForce (pkgs.writeText "request-key.conf" ''
in
mkForce (pkgs.writeText "request-key.conf" ''
create id_resolver * * ${nfsidmap} -t 600 %k %d
'');
};
};
${if options ? sops.secrets then "sops" else null}.secrets = let
${
if options ? sops.secrets
then "sops"
else null
}.secrets = let
sopsFile = mkDefault ../secrets/krb5.yaml;
in mkIf cfg.enable {
in
mkIf cfg.enable {
gensokyo-zone-krb5-passwords = mkIf (cfg.db.backend == "kldap") {
inherit sopsFile;
};

View file

@ -33,18 +33,26 @@
options = with lib.types; {
enable = mkEnableOption "kyuuto";
media = {
enable = mkEnableOption "/mnt/kyuuto-media" // {
enable =
mkEnableOption "/mnt/kyuuto-media"
// {
default = true;
};
krb5.enable = mkEnableOption "krb5" // {
krb5.enable =
mkEnableOption "krb5"
// {
default = enabled.krb5;
};
};
transfer = {
enable = mkEnableOption "/mnt/kyuuto-transfer" // {
enable =
mkEnableOption "/mnt/kyuuto-transfer"
// {
default = true;
};
krb5.enable = mkEnableOption "krb5" // {
krb5.enable =
mkEnableOption "krb5"
// {
default = enabled.krb5;
};
};
@ -135,7 +143,8 @@
(mkIf config.nfs.enable "nfs4")
(mkIf config.smb.enable "smb3")
];
options = mkMerge (setFilesystemOptions ++ [
options = mkMerge (setFilesystemOptions
++ [
(mkIf config.media.krb5.enable [
"sec=krb5"
(mkIf config.nfs.enable "nfsvers=4")
@ -151,9 +160,14 @@
(mkIf config.nfs.enable "nfs4")
(mkIf config.smb.enable "smb3")
];
options = mkMerge (setFilesystemOptions ++ [
options = mkMerge (setFilesystemOptions
++ [
(mkIf config.media.krb5.enable [
(if access.local.enable || access.tail.enabled then "sec=sys:krb5" else "sec=krb5")
(
if access.local.enable || access.tail.enabled
then "sec=sys:krb5"
else "sec=krb5"
)
#(mkIf config.nfs.enable "nfsvers=3")
])
]);

View file

@ -46,7 +46,9 @@
default = "ssh";
};
ssh = {
commonKey = mkEnableOption "shared secret nixbld key" // {
commonKey =
mkEnableOption "shared secret nixbld key"
// {
default = true;
};
user = mkOption {
@ -114,7 +116,9 @@
];
ssh.key = let
inherit (nixosConfig.sops) secrets;
in mkIf (nixosOptions ? sops.secrets && secrets ? gensokyo-zone-nix-bld-key) (mkAlmostOptionDefault
in
mkIf (nixosOptions ? sops.secrets && secrets ? gensokyo-zone-nix-bld-key) (
mkAlmostOptionDefault
nixosConfig.sops.secrets.gensokyo-zone-nix-bld-key.path
);
setBuildMachine = {
@ -153,9 +157,14 @@ in {
settings = unmerged.merge cfg.setNixSettings;
buildMachines = unmerged.merge cfg.setNixBuildMachines;
};
${if options ? sops.secrets then "sops" else null}.secrets = let
${
if options ? sops.secrets
then "sops"
else null
}.secrets = let
sopsFile = mkDefault ../secrets/nix.yaml;
in mkIf cfg.enable {
in
mkIf cfg.enable {
gensokyo-zone-nix-bld-key = mkIf cfg.builder.ssh.commonKey {
inherit sopsFile;
};

View file

@ -76,10 +76,12 @@ in {
];
};
allLan = {
v4 = cfg.cidrForNetwork.loopback.v4
v4 =
cfg.cidrForNetwork.loopback.v4
++ cfg.cidrForNetwork.local.v4
++ cfg.cidrForNetwork.int.v4;
v6 = cfg.cidrForNetwork.loopback.v6
v6 =
cfg.cidrForNetwork.loopback.v6
++ cfg.cidrForNetwork.local.v6
++ cfg.cidrForNetwork.int.v6;
};

View file

@ -25,18 +25,27 @@ in {
default = "/run/access/peeps";
};
};
config.${if hasSops then "sops" else null}.secrets = let
config.${
if hasSops
then "sops"
else null
}.secrets = let
sopsFile = mkDefault ../../../nixos/secrets/access.yaml;
sopsSecrets = mapAttrs' (name: _: nameValuePair (mkSopsName name) {
sopsSecrets = mapAttrs' (name: _:
nameValuePair (mkSopsName name) {
inherit sopsFile;
path = mkDefault "${cfg.stateDir}/${name}.nft";
}) cfg.ranges;
in mkIf cfg.enable sopsSecrets;
})
cfg.ranges;
in
mkIf cfg.enable sopsSecrets;
config.networking = let
nftRanges = mapAttrsToList (name: range: let
nft = "define ${mkNftName name} = ${range}";
in mkBefore nft) cfg.ranges;
in
mkBefore nft)
cfg.ranges;
condition = "ip6 saddr { ${concatStringsSep "," (mapAttrsToList (name: _: "$" + mkNftName name) cfg.ranges)} }";
in {
nftables.ruleset = mkIf cfg.enable (mkMerge (

View file

@ -1,4 +1,10 @@
{ config, lib, gensokyo-zone, pkgs, ... }: let
{
config,
lib,
gensokyo-zone,
pkgs,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault mapOptionDefaults unmerged;
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
@ -8,9 +14,12 @@
cfg = config.services.barcodebuddy;
toEnvName = key: "BBUDDY_" + key;
toEnvValue = value:
if value == true then "true"
else if value == false then "false"
else if isList value then concatStringsSep ";" (imap0 (i: v: "${toString i}=${toEnvValue v}") value)
if value == true
then "true"
else if value == false
then "false"
else if isList value
then concatStringsSep ";" (imap0 (i: v: "${toString i}=${toEnvValue v}") value)
else toString value;
toEnvPair = key: value: nameValuePair (toEnvName key) (toEnvValue value);
toPhpEnvPair = key: value: nameValuePair (toEnvName key) ''"${toEnvValue value}"'';
@ -65,10 +74,12 @@ in {
type = nullOr str;
default = null;
};
/* TODO: passwordFile = mkOption {
/*
TODO: passwordFile = mkOption {
type = nullOr path;
default = null;
};*/
};
*/
};
settings = mkOption {
type = attrsOf (oneOf [str bool int (listOf str)]);
@ -95,9 +106,19 @@ in {
bbuddyConfig.services.barcodebuddy = {
settings = let
defaults = mapOptionDefaults {
${if cfg.screen.enable then "PORT_WEBSOCKET_SERVER" else null} = cfg.screen.websocketPort;
${
if cfg.screen.enable
then "PORT_WEBSOCKET_SERVER"
else null
} =
cfg.screen.websocketPort;
SEARCH_ENGINE = "https://google.com/search?q=";
${if cfg.reverseProxy.enable then "TRUSTED_PROXIES" else null} = cfg.reverseProxy.trustedAddresses;
${
if cfg.reverseProxy.enable
then "TRUSTED_PROXIES"
else null
} =
cfg.reverseProxy.trustedAddresses;
DISABLE_AUTHENTICATION = false;
DATABASE_PATH = cfg.databasePath;
AUTHDB_PATH = cfg.authDatabasePath;
@ -109,7 +130,8 @@ in {
REDIS_PORT = cfg.redis.port;
REDIS_PW = toString cfg.redis.password;
};
in mkMerge [ defaults (mkIf cfg.redis.enable redis) ];
in
mkMerge [defaults (mkIf cfg.redis.enable redis)];
nginxConfig = ''
index index.php index.html index.htm;
'';
@ -125,9 +147,14 @@ in {
};
redis = let
redis = config.services.redis.servers.${cfg.redis.server};
in mkIf (cfg.redis.server != null) {
in
mkIf (cfg.redis.server != null) {
enable = mkAlmostOptionDefault redis.enable;
ip = mkOptionDefault (if redis.bind == null then "localhost" else redis.bind);
ip = mkOptionDefault (
if redis.bind == null
then "localhost"
else redis.bind
);
port = mkIf (redis.port != 0) (mkOptionDefault redis.port);
password = mkAlmostOptionDefault redis.requirePass;
# TODO: passwordFile = mkAlmostOptionDefault redis.requirePassFile;
@ -146,7 +173,10 @@ in {
user = "barcodebuddy";
inherit (config.services.nginx) group;
phpPackage = cfg.phpPackageUnwrapped.withExtensions ({ enabled, all }: [
phpPackage = cfg.phpPackageUnwrapped.withExtensions ({
enabled,
all,
}: [
all.curl
all.mbstring
all.sqlite3
@ -202,5 +232,6 @@ in {
User = "barcodebuddy";
};
};
in mkMerge [ bbuddyConfig (mkIf cfg.enable conf) ];
in
mkMerge [bbuddyConfig (mkIf cfg.enable conf)];
}

View file

@ -36,7 +36,8 @@ in {
config.services.sssd = let
inherit (config.services) sssd;
ipaDebugLevel = 65510;
in mkIf cfg.enable {
in
mkIf cfg.enable {
debugLevel = mkAlmostOptionDefault ipaDebugLevel;
domains = {
${cfg.domain} = {
@ -47,7 +48,8 @@ in {
telephoneNumber = "telephoneNumber";
lock = "nsaccountlock";
};
settings = mapOptionDefaults {
settings =
mapOptionDefaults {
id_provider = "ipa";
auth_provider = "ipa";
access_provider = "ipa";
@ -67,7 +69,8 @@ in {
dyndns_iface = cfg.dyndns.interface;
ldap_tls_cacert = "/etc/ipa/ca.crt";
} // {
}
// {
krb5_realm = mkIf (toLower cfg.domain != toLower cfg.realm) (mkOptionDefault cfg.realm);
};
};
@ -137,7 +140,8 @@ in {
config.environment.etc."krb5.conf" = let
inherit (config.security) krb5;
format = import (modulesPath + "/security/krb5/krb5-conf-format.nix") {inherit pkgs lib;} {};
in mkIf (cfg.enable && !cfg.overrideConfigs.krb5) {
in
mkIf (cfg.enable && !cfg.overrideConfigs.krb5) {
text = mkForce (format.generate "krb5.conf" krb5.settings).text;
};
}

View file

@ -1,4 +1,8 @@
{config, lib, ...}: let
{
config,
lib,
...
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkOptionDefault;
cfg = config.services.keycloak;
@ -14,7 +18,11 @@ in {
};
};
config.services.keycloak = {
protocol = mkOptionDefault (if cfg.sslCertificate != null then "https" else "http");
protocol = mkOptionDefault (
if cfg.sslCertificate != null
then "https"
else "http"
);
port = mkOptionDefault cfg.settings."${cfg.protocol}-port";
};
}

View file

@ -1,4 +1,10 @@
{ gensokyo-zone, pkgs, config, lib, ... }: let
{
gensokyo-zone,
pkgs,
config,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkBaseDn mapDefaults mkAlmostOptionDefault mapOptionDefaults domain;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkDefault mkOptionDefault mkForce;
@ -64,7 +70,8 @@ in {
krb5-ldap = pkgs.krb5.override {
withLdap = true;
};
in mkIf (cfg.enable && cfg.db.backend == "kldap") (mkDefault pkgs.krb5-ldap or krb5-ldap);
in
mkIf (cfg.enable && cfg.db.backend == "kldap") (mkDefault pkgs.krb5-ldap or krb5-ldap);
settings = mkIf cfg.enable {
dbmodules = {
genso-kldap = mkIf (cfg.db.backend == "kldap") (mapDefaults {
@ -72,7 +79,8 @@ in {
ldap_servers = concatStringsSep " " cfg.ldap.urls;
ldap_kdc_dn = cfg.ldap.bind.dn;
ldap_kerberos_container_dn = cfg.ldap.baseDn;
} // {
}
// {
ldap_service_password_file = mkIf (cfg.ldap.bind.passwordFile != null) (mkDefault cfg.ldap.bind.passwordFile);
});
genso-ipa = mkIf (cfg.db.backend == "ipa") (mapDefaults {
@ -80,13 +88,15 @@ in {
});
${cfg.realm} = mkIf ipa.enable (mkForce {});
};
realms.${cfg.realm} = mapDefaults {
realms.${cfg.realm} =
mapDefaults {
kdc = "${cfg.host}:88";
master_kdc = "${cfg.host}:88";
admin_server = "${cfg.host}:749";
default_domain = cfg.domain;
pkinit_anchors = ["FILE:${cfg.ca.cert}"];
} // {
}
// {
database_module = mkOptionDefault "genso-${cfg.db.backend}";
auth_to_local_names = mkIf (cfg.authToLocalNames != {}) (mkDefault (subsection cfg.authToLocalNames));
};
@ -112,7 +122,8 @@ in {
url = "https://ipa.${cfg.domain}/ipa/config/ca.crt";
sha256 = "sha256-PKjnjn1jIq9x4BX8+WGkZfj4HQtmnHqmFSALqggo91o=";
};
in mkOptionDefault caPem;
in
mkOptionDefault caPem;
db.backend = mkIf ipa.enable (mkAlmostOptionDefault "ipa");
ldap.urls = mkOptionDefault [
"ldaps://ldap.${cfg.domain}"
@ -127,9 +138,11 @@ in {
domain = mkDefault cfg.domain;
realm = mkDefault cfg.realm;
server = mkDefault cfg.canonHost;
ifpAllowedUids = [
ifpAllowedUids =
[
"root"
] ++ config.users.groups.wheel.members;
]
++ config.users.groups.wheel.members;
dyndns.enable = mkDefault false;
};
};

View file

@ -1,5 +1,11 @@
let
allowListModule = {config, name, gensokyo-zone, lib, ...}: let
allowListModule = {
config,
name,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.Std) UInt;
inherit (lib.options) mkOption;
inherit (lib.modules) mkOptionDefault;
@ -25,10 +31,12 @@ let
};
};
config = let
xuid = {
xuid =
{
string = toString (UInt.FromHex config.xuid);
int = toString config.xuid;
}.${typeOf config.xuid};
}
.${typeOf config.xuid};
in {
settings = {
name = mkOptionDefault config.name;
@ -41,14 +49,20 @@ let
};
};
};
packModule = {config, lib, ...}: let
packModule = {
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.strings) splitString;
inherit (builtins) typeOf;
in {
options = with lib.types; {
enable = mkEnableOption "pack" // {
enable =
mkEnableOption "pack"
// {
default = true;
};
package = mkOption {
@ -72,28 +86,42 @@ let
};
};
config = {
packId = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.pack_id) (mkOptionDefault
packId = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.pack_id) (
mkOptionDefault
config.package.minecraft-bedrock.pack.pack_id
);
packType = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.type) (mkOptionDefault
packType = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.type) (
mkOptionDefault
config.package.minecraft-bedrock.pack.type
);
version = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.version) (mkOptionDefault
version = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.version) (
mkOptionDefault
config.package.minecraft-bedrock.pack.version
);
packDir = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.dir) (mkOptionDefault
packDir = mkIf (config.package != null && config.package ? minecraft-bedrock.pack.dir) (
mkOptionDefault
config.package.minecraft-bedrock.pack.dir
);
settings = {
pack_id = mkOptionDefault config.packId;
version = mkOptionDefault {
version =
mkOptionDefault
{
string = splitString "." config.version;
list = config.version;
}.${typeOf config.version};
}
.${typeOf config.version};
};
};
};
in { config, gensokyo-zone, lib, pkgs, ... }: let
in
{
config,
gensokyo-zone,
lib,
pkgs,
...
}: let
# see https://gist.github.com/datakurre/cfdf627fb23ed8ff62bb7b3520b92674
inherit (gensokyo-zone.lib) mapOptionDefaults;
inherit (lib.options) mkOption mkPackageOption;
@ -106,12 +134,17 @@ in { config, gensokyo-zone, lib, pkgs, ... }: let
inherit (builtins) toJSON;
cfg = config.services.minecraft-bedrock-server;
cfgToString = v: if builtins.isBool v then boolToString v else toString v;
cfgToString = v:
if builtins.isBool v
then boolToString v
else toString v;
serverPropertiesFile = pkgs.writeText "server.properties" (''
# server.properties managed by NixOS configuration
'' + concatStringsSep "\n" (mapAttrsToList
(n: v: "${n}=${cfgToString v}") cfg.serverProperties));
''
+ concatStringsSep "\n" (mapAttrsToList
(n: v: "${n}=${cfgToString v}")
cfg.serverProperties));
in {
options.services.minecraft-bedrock-server = with lib.types; {
enable = mkOption {
@ -167,7 +200,9 @@ in {
'';
};
package = mkPackageOption pkgs "minecraft-bedrock-server" { }// {
package =
mkPackageOption pkgs "minecraft-bedrock-server" {}
// {
description = "Version of minecraft-bedrock-server to run.";
};
@ -249,8 +284,10 @@ in {
allowListJson = pkgs.writeText "minecraft-bedrock-server-allowlist.json" (
toJSON allowPlayers
);
in mkOptionDefault (
if cfg.allowPlayers != null then allowListJson
in
mkOptionDefault (
if cfg.allowPlayers != null
then allowListJson
else null
);
permissions = let
@ -258,8 +295,10 @@ in {
permissionsJson = pkgs.writeText "minecraft-bedrock-server-permissions.json" (
toJSON permissions
);
in mkOptionDefault (
if cfg.allowPlayers != null then permissionsJson
in
mkOptionDefault (
if cfg.allowPlayers != null
then permissionsJson
else null
);
};
@ -292,13 +331,15 @@ in {
"config/default"
"bedrock_server_symbols.debug"
"env-vars"
] ++ optional (cfg.permissions == null) "permissions.json");
]
++ optional (cfg.permissions == null) "permissions.json");
mkWorldPacks = type: let
enabledPacks = filterAttrs (_: pack: pack.enable && pack.packType == "${type}_packs") cfg.packs;
jsonName = "world_${type}_packs.json";
packsJson = mapAttrsToList (_: pack: pack.settings) enabledPacks;
packsJsonPath = pkgs.writeText jsonName (toJSON packsJson);
in mkIf (enabledPacks != { }) [
in
mkIf (enabledPacks != {}) [
"${packsJsonPath}:${cfg.dataDir}/worlds/${cfg.serverProperties.level-name}/${jsonName}"
];
mapWorldPacks = packs: let
@ -306,13 +347,15 @@ in {
mapPackPath = _: pack: let
subDir = "${pack.packType}/${pack.packDir}";
in "${pack.package}/${cfg.package.dataDir}/${subDir}:${cfg.dataDir}/${subDir}";
in mapAttrsToList mapPackPath enabledPacks;
in
mapAttrsToList mapPackPath enabledPacks;
packsPaths = mkMerge [
(mkWorldPacks "behavior")
(mkWorldPacks "resource")
(mapWorldPacks cfg.packs)
];
in mkMerge [
in
mkMerge [
packageResources
(mkIf (cfg.allowList != null) ["${cfg.allowList}:${cfg.dataDir}/allowlist.json"])
(mkIf (cfg.permissions != null) ["${cfg.permissions}:${cfg.dataDir}/permissions.json"])
@ -340,10 +383,12 @@ in {
conf.networking.firewall = let
ports = [cfg.serverProperties.server-port cfg.serverProperties.server-portv6];
in mkIf cfg.openFirewall {
in
mkIf cfg.openFirewall {
allowedUDPPorts = ports;
};
in mkMerge [
in
mkMerge [
confService
(mkIf cfg.enable conf)
];

View file

@ -9,7 +9,11 @@
inherit (lib.strings) concatStringsSep;
inherit (config.system) nssDatabases;
inherit (config) networking;
netgroupMemberModule = { config, name, ... }: {
netgroupMemberModule = {
config,
name,
...
}: {
options = with lib.types; {
hostname = mkOption {
type = str;
@ -32,7 +36,11 @@
triple = mkOptionDefault "(${config.hostname},${toString config.user},${config.domain})";
};
};
netgroupModule = { config, name, ... }: {
netgroupModule = {
config,
name,
...
}: {
options = with lib.types; {
name = mkOption {
type = str;

View file

@ -1,4 +1,8 @@
{config, lib, ...}: let
{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.lists) filter optional;
@ -7,11 +11,20 @@
enabledNameservers = filter (ns: ns.enable) (config.networking.nameservers');
nameserverModule = {config, ...}: let
dnsPort = 53;
mkResolvedValue = { address, port, interface ? null, host ? null }: let
mkResolvedValue = {
address,
port,
interface ? null,
host ? null,
}: let
isIpv6 = hasInfix ":" address;
isPlain = port == dnsPort && interface == null && host == null;
addr = if isIpv6 && !isPlain then "[${address}]" else address;
in concatStrings (
addr =
if isIpv6 && !isPlain
then "[${address}]"
else address;
in
concatStrings (
[addr]
++ optional (port != dnsPort) ":${toString port}"
++ optional (interface != null) "%${interface}"
@ -19,7 +32,9 @@
);
in {
options = with lib.types; {
enable = mkEnableOption "nameserver" // {
enable =
mkEnableOption "nameserver"
// {
default = true;
};
address = mkOption {
@ -64,7 +79,11 @@ in {
};
config = {
networking.nameservers = mkIf (config.networking.nameservers' != []) (
map (ns: if resolved.enable then ns.resolvedValue else ns.value) enabledNameservers
map (ns:
if resolved.enable
then ns.resolvedValue
else ns.value)
enabledNameservers
);
};
}

View file

@ -21,7 +21,11 @@
(mkIf (cfg.server.mountdPort != null) cfg.server.mountdPort)
];
concatFlags = concatStringsSep ",";
clientModule = { config, name, ... }: {
clientModule = {
config,
name,
...
}: {
options = with lib.types; {
machine = mkOption {
type = oneOf [str (listOf str)];
@ -40,10 +44,15 @@
entry = let
flags = optionalString (config.flags != []) "(${concatFlags config.flags})";
machines = toList config.machine;
in mkOptionDefault (concatMapStringsSep " " (machine: machine + flags) machines);
in
mkOptionDefault (concatMapStringsSep " " (machine: machine + flags) machines);
};
};
exportModule = { config, name, ... }: {
exportModule = {
config,
name,
...
}: {
options = with lib.types; {
path = mkOption {
type = path;
@ -62,10 +71,12 @@
config = {
flags = mkOptionDefault (cfg.export.flagSets.common or []);
fileLine = let
parts = [ config.path ]
parts =
[config.path]
++ optional (config.flags != []) "-${concatFlags config.flags}"
++ mapAttrsToList (_: client: client.entry) config.clients;
in mkOptionDefault (concatStringsSep " " parts);
in
mkOptionDefault (concatStringsSep " " parts);
};
};
in {

View file

@ -1,13 +1,16 @@
{
lib,
...
}: let
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOverride;
mkExtraForce = mkOverride 25;
locationModule = { config, virtualHost, ... }: {
locationModule = {
config,
virtualHost,
...
}: {
options = with lib.types; {
enable = mkEnableOption "enable location" // {
enable =
mkEnableOption "enable location"
// {
default = true;
};
};
@ -17,7 +20,9 @@
};
hostModule = {config, ...}: {
options = with lib.types; {
enable = mkEnableOption "enable server" // {
enable =
mkEnableOption "enable server"
// {
default = true;
};
locations = mkOption {

View file

@ -43,7 +43,8 @@ let
config = {
fastcgi = {
socket = mkIf (cfg.phpfpmPool != null) (mkAlmostOptionDefault
socket = mkIf (cfg.phpfpmPool != null) (
mkAlmostOptionDefault
nixosConfig.services.phpfpm.pools.${cfg.phpfpmPool}.socket
);
params = mapOptionDefaults {
@ -60,18 +61,24 @@ let
extraConfig = let
passHeadersConfig = map (header: "fastcgi_pass_header ${xvars.escapeString header};") passHeaders;
paramsConfig = mapAttrsToList (param: value: mkJustAfter "fastcgi_param ${param} ${xvars.escapeString value};") params;
in mkIf cfg.enable (mkMerge ([
in
mkIf cfg.enable (mkMerge ([
(mkIf cfg.includeDefaults (mkAlmostBefore ''
include ${nginx.package}/conf/fastcgi.conf;
''))
(mkIf (cfg.socket != null) (mkJustAfter ''
fastcgi_pass unix:${cfg.socket};
''))
] ++ passHeadersConfig
]
++ passHeadersConfig
++ paramsConfig));
};
};
hostModule = {config, lib, ...}: let
hostModule = {
config,
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options = with lib.types; {
@ -80,10 +87,8 @@ let
};
};
};
in {
lib,
...
}: let
in
{lib, ...}: let
inherit (lib.options) mkOption;
in {
options = with lib.types; {

View file

@ -1,5 +1,12 @@
let
locationModule = { config, virtualHost, xvars, gensokyo-zone, lib, ... }: let
locationModule = {
config,
virtualHost,
xvars,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mapOptionDefaults;
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkAfter mkOptionDefault;
@ -18,7 +25,8 @@ let
};
config = let
mkHeader = name: value:
if isList value then mkMerge (map (mkHeader name) value)
if isList value
then mkMerge (map (mkHeader name) value)
else mkAfter "add_header ${name} ${xvars.escapeString value};";
setHeaders = mapAttrsToList (name: value: mkIf (value != null) (mkHeader name value)) cfg.set;
in {
@ -31,7 +39,13 @@ let
extraConfig = mkMerge setHeaders;
};
};
hostModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
hostModule = {
config,
nixosConfig,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mapOptionDefaults;
inherit (lib.options) mkOption;
inherit (nixosConfig.services) nginx;
@ -55,10 +69,8 @@ let
};
};
};
in {
lib,
...
}: let
in
{lib, ...}: let
inherit (lib.options) mkOption;
in {
options.services.nginx = with lib.types; {

View file

@ -10,9 +10,16 @@
inherit (lib.attrsets) attrValues mapAttrs;
inherit (lib.lists) optional filter concatMap;
inherit (config.services) nginx;
listenModule = { config, virtualHost, listenKind, ... }: {
listenModule = {
config,
virtualHost,
listenKind,
...
}: {
options = with lib.types; {
enable = mkEnableOption "this port" // {
enable =
mkEnableOption "this port"
// {
default = true;
};
addr = mkOption {
@ -59,7 +66,9 @@
(mkIf (listenKind == "streamServer" && !config.ssl && virtualHost.ssl.enable && virtualHost.ssl.force != false) (mkForce false))
];
port = mkIf (listenKind == "virtualHost") (mkOptionDefault (
if config.ssl then nginx.defaultSSLListenPort else nginx.defaultHTTPListenPort
if config.ssl
then nginx.defaultSSLListenPort
else nginx.defaultHTTPListenPort
));
addresses = mkMerge [
(mkOptionDefault virtualHost.listenAddresses')
@ -74,26 +83,44 @@
);
listenConfigs = let
# TODO: handle quic listener..?
mkListenHost = { addr, port }: let
mkListenHost = {
addr,
port,
}: let
host =
if addr != null then "${mkAddress6 addr}:${toString port}"
if addr != null
then "${mkAddress6 addr}:${toString port}"
else toString port;
in assert port != null; host;
in
assert port != null; host;
mkDirective = addr: let
host = mkListenHost { inherit addr; inherit (config) port; };
in mkMerge (
host = mkListenHost {
inherit addr;
inherit (config) port;
};
in
mkMerge (
[(mkBefore host)]
++ config.listenParameters
);
in mkOptionDefault (map (mkDirective) config.addresses);
in
mkOptionDefault (map mkDirective config.addresses);
listenDirectives = mkMerge (map (conf: mkOptionDefault "listen ${conf};") config.listenConfigs);
};
};
listenType = { specialArgs, modules ? [ ] }: lib.types.submoduleWith {
listenType = {
specialArgs,
modules ? [],
}:
lib.types.submoduleWith {
inherit specialArgs;
modules = [listenModule] ++ modules;
};
hostModule = { nixosConfig, config, ... }: let
hostModule = {
nixosConfig,
config,
...
}: let
cfg = attrValues config.listen';
enabledCfg = filter (port: port.enable) cfg;
mkListen = listen: addr: let
@ -101,7 +128,8 @@
inherit addr;
inherit (listen) port ssl extraParameters proxyProtocol;
};
in mapAttrs (_: mkAlmostOptionDefault) listenAttrs;
in
mapAttrs (_: mkAlmostOptionDefault) listenAttrs;
mkListens = listen: map (mkListen listen) listen.addresses;
in {
options = with lib.types; {
@ -124,14 +152,20 @@
config = {
enable = mkIf (cfg != [] && enabledCfg == []) (mkForce false);
listenAddresses' = mkOptionDefault (
if config.listenAddresses != [ ] then config.listenAddresses else nginx.defaultListenAddresses
if config.listenAddresses != []
then config.listenAddresses
else nginx.defaultListenAddresses
);
listen = mkIf (cfg != {}) (mkAlmostOptionDefault (
concatMap (mkListens) enabledCfg
concatMap mkListens enabledCfg
));
};
};
streamServerModule = { nixosConfig, config, ... }: let
streamServerModule = {
nixosConfig,
config,
...
}: let
enabledListen = filter (port: port.enable) (attrValues config.listen);
in {
options = with lib.types; {
@ -165,7 +199,9 @@
config = {
enable = mkIf (config.listen != {} && enabledListen == []) (mkForce false);
listenAddresses' = mkOptionDefault (
if config.listenAddresses != null then config.listenAddresses else nginx.defaultListenAddresses
if config.listenAddresses != null
then config.listenAddresses
else nginx.defaultListenAddresses
);
streamConfig = mkIf (config.listen != {}) (mkMerge (
map (listen: mkBefore listen.listenDirectives) enabledListen

View file

@ -8,16 +8,19 @@
inherit (lib.strings) concatMapStringsSep optionalString;
inherit (config.services) tailscale;
inherit (config.networking.access) cidrForNetwork localaddrs;
mkAddrVar = remoteAddr: varPrefix: ''
mkAddrVar = remoteAddr: varPrefix:
''
set ${varPrefix}tailscale 0;
'' + optionalString tailscale.enable ''
''
+ optionalString tailscale.enable ''
if (${remoteAddr} ~ "^fd7a:115c:a1e0:(:|ab12:)") {
set ${varPrefix}tailscale 1;
}
if (${remoteAddr} ~ "^100\.(6[4-9]|([7-9]|1[01])[0-9]|12[0-7])\.[0-9]+\.[0-9]+") {
set ${varPrefix}tailscale 1;
}
'' + ''
''
+ ''
set ${varPrefix}lan 0;
if (${remoteAddr} ~ "^10\.1\.1\.[0-9]+") {
set ${varPrefix}lan 1;
@ -56,7 +59,11 @@
set ${varPrefix}client 1;
}
'';
localModule = {config, xvars, ...}: let
localModule = {
config,
xvars,
...
}: let
cfg = config.local;
in {
options.local = with lib.types; {
@ -97,7 +104,8 @@
${allows}
deny all;
'';
in mkMerge [
in
mkMerge [
(mkIf cfg.emitDenyGlobal (mkBefore allowDirectives))
(mkIf cfg.emitVars (mkBefore (mkAddrVar "$remote_addr" "$local_")))
(mkIf (cfg.emitVars && config.xvars.enable) (mkBefore (mkAddrVar (xvars.remote_addr.get) "$x_local_")))

View file

@ -1,4 +1,9 @@
{pkgs, config, lib, ...}: let
{
pkgs,
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkAfter mkOptionDefault;
inherit (lib.strings) hasPrefix;
@ -10,7 +15,8 @@
luaModule = {config, ...}: let
cfg = config.lua;
mkSetBy = var: value:
if hasPrefix "/" "${value}" then "set_by_lua_file \$${var} ${value};"
if hasPrefix "/" "${value}"
then "set_by_lua_file \$${var} ${value};"
else ''
set_by_lua_block ''$${var} {
${value}
@ -40,10 +46,12 @@
${cfg.access.block}
}
''))
(mkIf (cfg.access.files != [ ]) (assert lua.http.enable; mkMerge (
(mkIf (cfg.access.files != []) (assert lua.http.enable;
mkMerge (
map (file: "access_by_lua_file ${file};") cfg.access.files
)))
(mkIf (cfg.set != { }) (assert lua.http.enable && lua.ndk.enable; mkMerge (
(mkIf (cfg.set != {}) (assert lua.http.enable && lua.ndk.enable;
mkMerge (
mapAttrsToList mkSetBy cfg.set
)))
];
@ -92,9 +100,11 @@ in {
config = {
services.nginx = {
lua = {
modules = [
modules =
[
cfg.luaPackage.pkgs.lua-resty-core
] ++ cfg.luaPackage.pkgs.lua-resty-core.propagatedBuildInputs;
]
++ cfg.luaPackage.pkgs.lua-resty-core.propagatedBuildInputs;
luaPath = mkMerge (
map luaPkgPath cfg.modules
++ [(mkAfter ";")]

View file

@ -46,18 +46,21 @@
config = {
name = {
qualifier = mkOptionDefault (
if config.local.enable then "local"
if config.local.enable
then "local"
else null
);
includeTailscale = mkOptionDefault (
config.local.enable && tailscale.enable && cfg.qualifier != "tail"
);
localName = mkOptionDefault (
if cfg.includeLocal then "${cfg.shortServer}.local.${networking.domain}"
if cfg.includeLocal
then "${cfg.shortServer}.local.${networking.domain}"
else null
);
tailscaleName = mkOptionDefault (
if cfg.includeTailscale then "${cfg.shortServer}.tail.${networking.domain}"
if cfg.includeTailscale
then "${cfg.shortServer}.tail.${networking.domain}"
else null
);
};

View file

@ -1,5 +1,12 @@
let
serverModule = {config, nixosConfig, name, gensokyo-zone, lib, ...}: let
serverModule = {
config,
nixosConfig,
name,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkBefore mkOptionDefault;
@ -26,7 +33,8 @@ let
inherit (nginx.stream) upstreams;
mkUpstream = host: upstream: "${host} ${upstreams.${upstream}.name};";
upstreams' = removeAttrs cfg.upstreams ["default"];
upstreamLines = mapAttrsToList mkUpstream upstreams'
upstreamLines =
mapAttrsToList mkUpstream upstreams'
++ optional (cfg.upstreams ? default) (mkUpstream "default" cfg.upstreams.default);
in {
ssl.preread = {
@ -46,7 +54,13 @@ let
serverBlock = mkIf cfg.enable (mkOptionDefault (mkBefore cfg.streamConfig));
};
};
in {config, gensokyo-zone, lib, ...}: let
in
{
config,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkDefault mkOptionDefault;

View file

@ -18,7 +18,14 @@ let
${xvars.init "forwarded_server" "$http_x_forwarded_server"}
}
'';
locationModule = { config, virtualHost, xvars, gensokyo-zone, lib, ... }: let
locationModule = {
config,
virtualHost,
xvars,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkJustBefore mkAlmostOptionDefault;
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
@ -65,7 +72,14 @@ let
];
};
};
hostModule = { config, nixosConfig, xvars, gensokyo-zone, lib, ... }: let
hostModule = {
config,
nixosConfig,
xvars,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault orderJustBefore unmerged;
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkOrder mkDefault;
@ -105,11 +119,20 @@ let
proxied = {
cloudflared = let
listen = config.listen'.proxied;
scheme = if listen.ssl then "https" else "http";
in mkIf (cfg.enable == "cloudflared") {
scheme =
if listen.ssl
then "https"
else "http";
in
mkIf (cfg.enable == "cloudflared") {
ingressSettings.${config.serverName} = {
service = "${scheme}://localhost:${toString listen.port}";
originRequest.${if scheme == "https" then "noTLSVerify" else null} = true;
originRequest.${
if scheme == "https"
then "noTLSVerify"
else null
} =
true;
};
getIngress = {}: unmerged.mergeAttrs cfg.cloudflared.ingressSettings;
};
@ -127,7 +150,8 @@ let
);
};
};
in {
in
{
config,
system,
gensokyo-zone,

View file

@ -1,5 +1,12 @@
let
proxyModule = {config, name, options, gensokyo-zone, lib, ...}: let
proxyModule = {
config,
name,
options,
gensokyo-zone,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkAfter mkOptionDefault;
inherit (lib.strings) optionalString;
@ -32,7 +39,14 @@ let
]);
};
};
serverModule = {config, name, options, gensokyo-zone, lib, ...}: let
serverModule = {
config,
name,
options,
gensokyo-zone,
lib,
...
}: let
inherit (lib.modules) mkIf mkAfter;
cfg = config.proxy;
in {
@ -41,12 +55,22 @@ let
config = let
warnProxy = lib.warnIf (!cfg.enable && options.proxy.url.isDefined) "nginx.stream.servers.${name}.proxy.url set without proxy.enable";
in {
streamConfig = warnProxy (mkIf cfg.enable (mkAfter
streamConfig = warnProxy (mkIf cfg.enable (
mkAfter
"proxy_pass ${cfg.url};"
));
};
};
locationModule = { config, nixosConfig, name, virtualHost, xvars, gensokyo-zone, lib, ... }: let
locationModule = {
config,
nixosConfig,
name,
virtualHost,
xvars,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkJustBefore mkJustAfter mkAlmostOptionDefault mapOptionDefaults coalesce parseUrl;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkBefore mkOptionDefault;
@ -75,7 +99,9 @@ let
host = mkOption {
type = nullOr str;
};
websocket.enable = mkEnableOption "websocket proxy" // {
websocket.enable =
mkEnableOption "websocket proxy"
// {
default = cfg.inheritServerDefaults && virtualHost.proxy.websocket.enable;
};
parsed = {
@ -129,7 +155,10 @@ let
hasUpstream = cfg.upstream != null && !dynamicUpstream;
hasUpstreamServer = upstream.defaultServerName != null;
recommendedHeaders = {
Host = if cfg.host == null then xvars.get.proxy_hostport else cfg.host;
Host =
if cfg.host == null
then xvars.get.proxy_hostport
else cfg.host;
Referer = xvars.get.referer;
X-Real-IP = xvars.get.remote_addr;
X-Forwarded-For = xvars.get.forwarded_for;
@ -137,10 +166,13 @@ let
X-Forwarded-Host = xvars.get.host;
X-Forwarded-Server = xvars.get.forwarded_server;
};
schemePort = {
schemePort =
{
http = 80;
https = 443;
}.${cfg.parsed.scheme} or (throw "unsupported proxy_scheme ${toString cfg.parsed.scheme}");
}
.${cfg.parsed.scheme}
or (throw "unsupported proxy_scheme ${toString cfg.parsed.scheme}");
upstreamHost = coalesce ([upstream.host] ++ optional hasUpstreamServer upstreamServer.addr);
port = coalesce [cfg.parsed.port schemePort];
hostport = cfg.parsed.host + optionalString (port != schemePort) ":${toString port}";
@ -174,8 +206,12 @@ let
${xvars.init "proxy_hostport" xvars.get.proxy_host}
}
'';
init = if cfg.upstream != null then initUpstream else initDynamic;
in init;
init =
if cfg.upstream != null
then initUpstream
else initDynamic;
in
init;
hostHeader = coalesce [
cfg.headers.set.Host or null
cfg.host
@ -192,7 +228,8 @@ let
setHeaders' = filterAttrs (_: header: header != null) cfg.headers.set;
setHeaders = concatStringsSep "\n" (mapAttrsToList (
name: value: "proxy_set_header ${name} ${xvars.escapeString value};"
) setHeaders');
)
setHeaders');
hideHeaders = mapAttrsToList (header: hide: mkIf hide "proxy_hide_header ${xvars.escapeString header};") cfg.headers.hide;
in {
xvars = {
@ -210,9 +247,13 @@ let
url = mkIf (cfg.inheritServerDefaults && virtualHost.proxy.url != null) (mkOptionDefault virtualHost.proxy.url);
headers = {
enableRecommended = mkOptionDefault (
if cfg.enable && (!cfg.inheritServerDefaults || virtualHost.proxy.headers.enableRecommended != false) then true
else if cfg.inheritServerDefaults then virtualHost.proxy.headers.enableRecommended
else if nginx.recommendedProxySettings then "nixpkgs" else false
if cfg.enable && (!cfg.inheritServerDefaults || virtualHost.proxy.headers.enableRecommended != false)
then true
else if cfg.inheritServerDefaults
then virtualHost.proxy.headers.enableRecommended
else if nginx.recommendedProxySettings
then "nixpkgs"
else false
);
set = mkMerge [
(mkOptionDefault {})
@ -230,8 +271,10 @@ let
];
};
host = mkOptionDefault (
if cfg.inheritServerDefaults && virtualHost.proxy.host != null then virtualHost.proxy.host
else if cfg.headers.enableRecommended == false then null
if cfg.inheritServerDefaults && virtualHost.proxy.host != null
then virtualHost.proxy.host
else if cfg.headers.enableRecommended == false
then null
else xvars.get.host
);
parsed = {
@ -242,11 +285,13 @@ let
mapNullable (_: url.path) config.proxyPass
);
host = mkOptionDefault (
if hasUpstream then assert url.host == upstream.name; upstreamHost
if hasUpstream
then assert url.host == upstream.name; upstreamHost
else mapNullable (_: url.host) config.proxyPass
);
port = mkOptionDefault (
if hasUpstream && hasUpstreamServer && url.port == null then assert url.host == upstream.name; upstreamServer.port
if hasUpstream && hasUpstreamServer && url.port == null
then assert url.host == upstream.name; upstreamServer.port
else mapNullable (_: url.port) config.proxyPass
);
};
@ -257,12 +302,19 @@ let
(mkIf virtualHost.xvars.enable (mkJustBefore initProxyVars))
(mkIf (cfg.headers.rewriteReferer.enable) (mkJustBefore rewriteReferer))
(mkIf (cfg.redirect.enable) (mkBefore redirect))
(mkIf (emitHeaders) (mkJustAfter setHeaders))
(mkIf emitHeaders (mkJustAfter setHeaders))
(mkIf cfg.websocket.enable "proxy_cache_bypass $http_upgrade;")
] ++ hideHeaders));
]
++ hideHeaders));
};
};
hostModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
hostModule = {
config,
nixosConfig,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mapOptionDefaults mapAlmostOptionDefaults;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
@ -289,7 +341,10 @@ let
websocket.enable = mkEnableOption "websocket proxy";
headers.enableRecommended = mkOption {
type = enum [true false "nixpkgs"];
default = if nginx.recommendedProxySettings then "nixpkgs" else false;
default =
if nginx.recommendedProxySettings
then "nixpkgs"
else false;
};
};
locations = mkOption {
@ -303,9 +358,11 @@ let
needsReferer = loc: loc.proxy.enabled && loc.proxy.headers.rewriteReferer.enable;
confCopy = let
proxyHost = nginx.virtualHosts.${cfg.copyFromVhost};
in mapAlmostOptionDefaults {
in
mapAlmostOptionDefaults {
inherit (proxyHost.proxy) host url upstream;
} // {
}
// {
websocket = mapAlmostOptionDefaults {
inherit (proxyHost.proxy.websocket) enable;
};
@ -326,10 +383,8 @@ let
proxy = mkIf (cfg.copyFromVhost != null) confCopy;
};
};
in {
lib,
...
}: let
in
{lib, ...}: let
inherit (lib.options) mkOption;
in {
options.services.nginx = with lib.types; {

View file

@ -1,5 +1,11 @@
let
sslModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
sslModule = {
config,
nixosConfig,
gensokyo-zone,
lib,
...
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
inherit (nixosConfig.services) nginx;
@ -60,14 +66,19 @@ let
};
copyCertVhost = mkCopyCert nginx.virtualHosts.${cfg.cert.copyFromVhost}.ssl.cert;
copyCertStreamServer = mkCopyCert nginx.stream.servers.${cfg.cert.copyFromStreamServer}.ssl.cert;
in mkMerge [
in
mkMerge [
(mkIf (cfg.cert.copyFromStreamServer != null) copyCertStreamServer)
(mkIf (cfg.cert.copyFromVhost != null) copyCertVhost)
];
};
};
};
sslProxyModule = { config, lib, ... }: let
sslProxyModule = {
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkAfter;
inherit (config) proxy;
@ -78,7 +89,9 @@ let
type = bool;
};
verify = mkEnableOption "proxy_ssl_verify";
sni = mkEnableOption "proxy_ssl_server_name" // {
sni =
mkEnableOption "proxy_ssl_server_name"
// {
default = cfg.host != null;
};
host = mkOption {
@ -97,7 +110,13 @@ let
]);
};
};
streamServerModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
streamServerModule = {
config,
nixosConfig,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostDefault;
inherit (lib.options) mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
@ -106,7 +125,9 @@ let
imports = [sslModule sslProxyModule];
options = with lib.types; {
ssl = {
kTLS = mkEnableOption "kTLS support" // {
kTLS =
mkEnableOption "kTLS support"
// {
default = true;
};
};
@ -126,13 +147,15 @@ let
(mkIf cfg.kTLS "ssl_conf_command Options KTLS;")
];
confProxy.extraConfig = mkIf proxy.ssl.enable "proxy_ssl on;";
in mkMerge [
in
mkMerge [
conf
(mkIf cfg.enable confSsl)
(mkIf proxy.enable confProxy)
];
};
in {
in
{
config,
gensokyo-zone,
lib,
@ -145,12 +168,20 @@ in {
inherit (lib.trivial) warnIf;
inherit (lib.strings) hasPrefix;
inherit (config.services) nginx;
forceRedirectConfig = { virtualHost, xvars }: ''
forceRedirectConfig = {
virtualHost,
xvars,
}: ''
if (${xvars.get.scheme} = http) {
return ${toString virtualHost.redirectCode} https://${xvars.get.host}$request_uri;
}
'';
locationModule = { config, virtualHost, xvars, ... }: let
locationModule = {
config,
virtualHost,
xvars,
...
}: let
cfg = config.ssl;
emitForce = cfg.force && !virtualHost.ssl.forced;
in {
@ -164,7 +195,11 @@ in {
extraConfig = mkIf emitForce (forceRedirectConfig {inherit xvars virtualHost;});
};
};
hostModule = { config, xvars, ... }: let
hostModule = {
config,
xvars,
...
}: let
cfg = config.ssl;
emitForce = cfg.forced && config.proxied.enabled;
in {
@ -188,7 +223,8 @@ in {
certConfig.name = mkIf cfg.cert.enable (warnIf (config.name.shortServer == null) "ssl.cert.enable set but name.shortServer is null" (
mkAlmostOptionDefault config.name.shortServer
));
in certConfig;
in
certConfig;
};
addSSL = mkIf (cfg.enable && (cfg.force == false || emitForce)) (mkDefault true);
forceSSL = mkIf (cfg.enable && cfg.force == true && !emitForce) (mkDefault true);
@ -200,7 +236,10 @@ in {
kTLS = mkAlmostOptionDefault true;
xvars.enable = mkIf emitForce true;
extraConfig = mkIf emitForce (forceRedirectConfig { virtualHost = config; inherit xvars; });
extraConfig = mkIf emitForce (forceRedirectConfig {
virtualHost = config;
inherit xvars;
});
};
};
in {
@ -219,11 +258,13 @@ in {
};
};
config.systemd.services.nginx = let
mapStreamServer = server: mkIf (server.enable && server.ssl.enable && server.ssl.cert.name != null) {
mapStreamServer = server:
mkIf (server.enable && server.ssl.enable && server.ssl.cert.name != null) {
wants = ["acme-finished-${server.ssl.cert.name}.target"];
after = ["acme-selfsigned-${server.ssl.cert.name}.service"];
before = ["acme-${server.ssl.cert.name}.service"];
};
streamServerCerts = mapAttrsToList (_: mapStreamServer) nginx.stream.servers;
in mkIf nginx.enable (mkMerge streamServerCerts);
in
mkIf nginx.enable (mkMerge streamServerCerts);
}

View file

@ -10,7 +10,9 @@
cfg = config.services.nginx.stream;
serverModule = {config, ...}: {
options = with lib.types; {
enable = mkEnableOption "stream server block" // {
enable =
mkEnableOption "stream server block"
// {
default = true;
};
extraConfig = mkOption {

View file

@ -1,5 +1,13 @@
let
upstreamServerAccessModule = {config, nixosConfig, name, gensokyo-zone, lib, upstreamKind, ...}: let
upstreamServerAccessModule = {
config,
nixosConfig,
name,
gensokyo-zone,
lib,
upstreamKind,
...
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
@ -57,12 +65,20 @@ let
port = mkOptionDefault port.port;
ssl.enable = mkIf port.ssl (mkAlmostOptionDefault true);
};
in mkMerge [
in
mkMerge [
confAccess
(mkIf cfg.enable conf)
];
};
upstreamServerModule = {config, name, gensokyo-zone, lib, upstreamKind, ...}: let
upstreamServerModule = {
config,
name,
gensokyo-zone,
lib,
upstreamKind,
...
}: let
inherit (gensokyo-zone.lib) mkAddress6;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkBefore mkOptionDefault;
@ -72,7 +88,9 @@ let
inherit (lib.trivial) isBool;
in {
options = with lib.types; {
enable = mkEnableOption "upstream server" // {
enable =
mkEnableOption "upstream server"
// {
default = true;
};
addr = mkOption {
@ -108,7 +126,8 @@ let
};
config = let
mapSetting = key: value:
if isBool value then mkIf value key
if isBool value
then mkIf value key
else "${key}=${toString value}";
settings = mapAttrsToList mapSetting config.settings;
port = optionalString (config.port != null) ":${toString config.port}";
@ -122,7 +141,15 @@ let
serverDirective = mkOptionDefault "server ${config.serverConfig};";
};
};
upstreamModule = {config, name, nixosConfig, gensokyo-zone, lib, upstreamKind, ...}: let
upstreamModule = {
config,
name,
nixosConfig,
gensokyo-zone,
lib,
upstreamKind,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault unmerged;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
@ -139,7 +166,9 @@ let
};
};
in {
enable = mkEnableOption "upstream block" // {
enable =
mkEnableOption "upstream block"
// {
default = true;
};
name = mkOption {
@ -199,16 +228,28 @@ let
upstreamSettings = assertServers (mkOptionDefault {
#extraConfig = config.upstreamConfig;
extraConfig = config.extraConfig;
servers = mapAttrs' (name: server: nameValuePair (if server.enable then server.server else "disabled_${name}") (mkIf server.enable (mkMerge [
servers = mapAttrs' (name: server:
nameValuePair (
if server.enable
then server.server
else "disabled_${name}"
) (mkIf server.enable (mkMerge [
server.settings
(mkIf (server.extraConfig != "") {
${config.extraConfig} = true;
})
]))) config.servers;
])))
config.servers;
});
};
};
serverModule = {config, nixosConfig, gensokyo-zone, lib, ...}: let
serverModule = {
config,
nixosConfig,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf;
@ -229,7 +270,8 @@ let
dynamicUpstream = hasPrefix "$" config.proxy.upstream;
hasUpstream = config.proxy.upstream != null && !dynamicUpstream;
proxyPass =
if dynamicUpstream then config.proxy.upstream
if dynamicUpstream
then config.proxy.upstream
else assert proxyUpstream.enable; proxyUpstream.name;
in {
proxy = {
@ -242,7 +284,12 @@ let
};
};
};
proxyUpstreamModule = {config, nixosConfig, lib, ...}: let
proxyUpstreamModule = {
config,
nixosConfig,
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options = with lib.types; {
@ -253,7 +300,14 @@ let
};
};
};
locationModule = {config, nixosConfig, virtualHost, gensokyo-zone, lib, ...}: let
locationModule = {
config,
nixosConfig,
virtualHost,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.strings) hasPrefix;
@ -263,28 +317,42 @@ let
config = let
proxyUpstream = nginx.upstreams'.${config.proxy.upstream};
proxyScheme = if config.proxy.ssl.enable then "https" else "http";
proxyScheme =
if config.proxy.ssl.enable
then "https"
else "http";
dynamicUpstream = hasPrefix "$" config.proxy.upstream;
hasUpstream = config.proxy.upstream != null && !dynamicUpstream;
proxyHost =
if dynamicUpstream then config.proxy.upstream
if dynamicUpstream
then config.proxy.upstream
else assert proxyUpstream.enable; proxyUpstream.name;
in {
proxy = {
upstream = mkOptionDefault virtualHost.proxy.upstream;
enable = mkIf (config.proxy.upstream != null && virtualHost.proxy.upstream == null) true;
url = mkIf (config.proxy.upstream != null) (mkAlmostOptionDefault
url = mkIf (config.proxy.upstream != null) (
mkAlmostOptionDefault
"${proxyScheme}://${proxyHost}"
);
ssl = {
enable = mkAlmostOptionDefault (if hasUpstream then proxyUpstream.ssl.enable else false);
enable = mkAlmostOptionDefault (
if hasUpstream
then proxyUpstream.ssl.enable
else false
);
host = mkIf hasUpstream (mkAlmostOptionDefault proxyUpstream.ssl.host);
};
host = mkIf (hasUpstream && proxyUpstream.host != null) (mkAlmostOptionDefault proxyUpstream.host);
};
};
};
hostModule = {config, nixosConfig, lib, ...}: let
hostModule = {
config,
nixosConfig,
lib,
...
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkOptionDefault;
in {
@ -302,7 +370,8 @@ let
};
};
};
in {
in
{
config,
lib,
gensokyo-zone,
@ -356,14 +425,21 @@ in {
mapAttrsToList (_: upstream: mkIf upstream.enable upstream.upstreamBlock) cfg.stream.upstreams
);
useUpstreams = true;
confUpstreams.upstreams = mkMerge (mapAttrsToList (_: upstream: mkIf upstream.enable {
confUpstreams.upstreams = mkMerge (mapAttrsToList (_: upstream:
mkIf upstream.enable {
${upstream.name} = unmerged.mergeAttrs upstream.upstreamSettings;
}) cfg.upstreams');
})
cfg.upstreams');
confBlock.commonHttpConfig = mkMerge (
mapAttrsToList (_: upstream: mkIf upstream.enable upstream.upstreamBlock) cfg.upstreams'
);
in mkMerge [
in
mkMerge [
confStream
(if useUpstreams then confUpstreams else confBlock)
(
if useUpstreams
then confUpstreams
else confBlock
)
];
}

View file

@ -13,7 +13,12 @@
inherit (config) networking;
inherit (config.services) vouch-proxy nginx tailscale;
inherit (nginx) vouch;
locationModule = {config, virtualHost, xvars, ...}: {
locationModule = {
config,
virtualHost,
xvars,
...
}: {
options.vouch = with lib.types; {
requireAuth = mkEnableOption "require auth to access this location";
setProxyHeader = mkOption {
@ -26,7 +31,8 @@
enableVouchLocal = virtualHost.vouch.localSso.enable;
enableVouchTail = enableVouchLocal && tailscale.enable && false;
allowOrigin = url: "add_header Access-Control-Allow-Origin ${url};";
in mkIf config.vouch.requireAuth {
in
mkIf config.vouch.requireAuth {
lua = mkIf virtualHost.vouch.auth.lua.enable {
access.block = mkMerge [
(mkBefore virtualHost.vouch.auth.lua.accessRequest)
@ -36,7 +42,8 @@
};
xvars.enable = mkIf (enableVouchTail || virtualHost.vouch.auth.lua.enable) true;
proxy.headers.set.X-Vouch-User = mkOptionDefault "$auth_resp_x_vouch_user";
extraConfig = assert virtualHost.vouch.enable; mkMerge [
extraConfig = assert virtualHost.vouch.enable;
mkMerge [
(mkIf (!virtualHost.vouch.requireAuth) virtualHost.vouch.auth.requestDirective)
(allowOrigin vouch.url)
(allowOrigin vouch.authUrl)
@ -46,7 +53,11 @@
];
};
};
hostModule = {config, xvars, ...}: let
hostModule = {
config,
xvars,
...
}: let
cfg = config.vouch;
mkHeaderVar = header: toLower (replaceStrings ["-"] ["_"] header);
mkUpstreamVar = header: "\$upstream_http_${mkHeaderVar header}";
@ -57,10 +68,14 @@
};
vouch = {
enable = mkEnableOption "vouch auth proxy";
localSso.enable = mkEnableOption "lan-local vouch" // {
localSso.enable =
mkEnableOption "lan-local vouch"
// {
default = vouch.localSso.enable && config.local.enable;
};
requireAuth = mkEnableOption "require auth to access this host" // {
requireAuth =
mkEnableOption "require auth to access this host"
// {
default = true;
};
auth = {
@ -129,9 +144,12 @@
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
'');
accessVariables = mkMerge (mapAttrsToList (authVar: header: mkOptionDefault
accessVariables = mkMerge (mapAttrsToList (
authVar: header:
mkOptionDefault
''ngx.var["${authVar}"] = ngx.ctx.auth_res.header["${header}"] or ""''
) cfg.auth.variables);
)
cfg.auth.variables);
};
errorLocation = mkIf cfg.auth.lua.enable (mkAlmostOptionDefault null);
requestDirective = mkIf cfg.auth.lua.enable (mkAlmostOptionDefault "");
@ -161,14 +179,18 @@
(mkIf cfg.localSso.enable localVouchUrl)
(mkIf (cfg.localSso.enable && tailscale.enable) tailVouchUrl)
];
in mkIf cfg.enable (mkMerge (
in
mkIf cfg.enable (mkMerge (
[
(mkIf (cfg.requireAuth) (mkBefore cfg.auth.requestDirective))
(mkIf (cfg.auth.errorLocation != null) "error_page 401 = ${cfg.auth.errorLocation};")
] ++ setVouchUrl
++ mapAttrsToList (authVar: header: mkIf (!cfg.auth.lua.enable) (
]
++ setVouchUrl
++ mapAttrsToList (authVar: header:
mkIf (!cfg.auth.lua.enable) (
mkBefore "auth_request_set \$${authVar} ${mkUpstreamVar header};"
)) cfg.auth.variables
))
cfg.auth.variables
));
xvars.enable = mkIf cfg.enable true;
locations = mkIf cfg.enable {
@ -181,18 +203,30 @@
return 302 $vouch_url/login?url=${xvars.get.scheme}://${xvars.get.host}$request_uri&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
'';
};
${cfg.auth.requestLocation} = { config, xvars, ... }: {
${cfg.auth.requestLocation} = {
config,
xvars,
...
}: {
proxy = {
enable = true;
inheritServerDefaults = false;
upstream = mkDefault (
if vouch.doubleProxy.enable then "vouch'proxy"
else if cfg.localSso.enable then "vouch'auth'local"
if vouch.doubleProxy.enable
then "vouch'proxy"
else if cfg.localSso.enable
then "vouch'auth'local"
else "vouch'auth"
);
# nginx-proxied vouch must use X-Forwarded-Host, but vanilla vouch requires Host
host = if config.proxy.upstream == "vouch'proxy"
then (if cfg.localSso.enable then vouch.doubleProxy.localServerName else vouch.doubleProxy.serverName)
host =
if config.proxy.upstream == "vouch'proxy"
then
(
if cfg.localSso.enable
then vouch.doubleProxy.localServerName
else vouch.doubleProxy.serverName
)
else xvars.get.host;
headers = {
set.Content-Length = "";
@ -212,7 +246,9 @@ in {
vouch = {
enable = mkEnableOption "vouch auth proxy";
localSso = {
enable = mkEnableOption "lan-local auth" // {
enable =
mkEnableOption "lan-local auth"
// {
default = true;
};
};
@ -283,7 +319,9 @@ in {
vouch'auth'local = {
enable = vouch.enable && vouch.localSso.enable;
servers = {
local = localVouch // {
local =
localVouch
// {
enable = mkAlmostOptionDefault false;
};
service = {upstream, ...}: {

View file

@ -1,5 +1,10 @@
let
locationModule = { config, virtualHost, lib, ... }: let
locationModule = {
config,
virtualHost,
lib,
...
}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.attrsets) mapAttrs;
cfg = config.xvars;
@ -18,15 +23,28 @@ let
xvars = {
lib = let
xvars = virtualHost.xvars.lib;
get = mapAttrs (name: default: if virtualHost.xvars.enable then "$x_${name}" else assert default != null; default) cfg.defaults;
in xvars // {
get = mapAttrs (name: default:
if virtualHost.xvars.enable
then "$x_${name}"
else assert default != null; default)
cfg.defaults;
in
xvars
// {
get = xvars.get // get;
};
};
_module.args.xvars = config.xvars.lib;
};
};
hostModule = { config, nixosConfig, gensokyo-zone, xvars, lib, ... }: let
hostModule = {
config,
nixosConfig,
gensokyo-zone,
xvars,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkJustBefore;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
@ -36,11 +54,16 @@ let
inherit (lib.trivial) isInt;
cfg = config.xvars;
escapeString = value:
if value == "" then ''""''
else if isInt value then toString value
else if hasPrefix ''"'' value || hasPrefix "'" value then value # already escaped, may include trailing arguments
else if hasInfix ''"'' value then "'${value}'"
else if hasInfix " " value || hasInfix ";" value || hasInfix "'" value then ''"${value}"''
if value == ""
then ''""''
else if isInt value
then toString value
else if hasPrefix ''"'' value || hasPrefix "'" value
then value # already escaped, may include trailing arguments
else if hasInfix ''"'' value
then "'${value}'"
else if hasInfix " " value || hasInfix ";" value || hasInfix "'" value
then ''"${value}"''
else value;
anyLocations = f: any (loc: loc.enable && f loc) (attrValues config.locations);
in {
@ -99,7 +122,11 @@ let
referer_path = null;
});
lib = {
get = mapAttrs (name: default: if cfg.enable then "$x_${name}" else assert default != null; default) cfg.defaults;
get = mapAttrs (name: default:
if cfg.enable
then "$x_${name}"
else assert default != null; default)
cfg.defaults;
init = name: value: assert cfg.enable && cfg.defaults ? ${name}; "set $x_${name} ${escapeString value};";
inherit escapeString;
};
@ -111,7 +138,8 @@ let
_module.args.xvars = config.xvars.lib;
};
};
in {
in
{
config,
lib,
gensokyo-zone,

View file

@ -40,7 +40,9 @@
allow = mkEnableOption "tailscale TCP connections";
};
int = {
allow = mkEnableOption "internal TCP connections" // {
allow =
mkEnableOption "internal TCP connections"
// {
default = config.authentication.local.allow;
};
};

View file

@ -55,7 +55,9 @@ in {
ldap = {
enable = mkEnableOption "LDAP";
passdb = {
enable = mkEnableOption "LDAP authentication" // {
enable =
mkEnableOption "LDAP authentication"
// {
default = true;
};
backend = mkOption {
@ -64,7 +66,9 @@ in {
};
};
idmap = {
enable = mkEnableOption "LDAP users" // {
enable =
mkEnableOption "LDAP users"
// {
default = true;
};
domain = mkOption {
@ -98,10 +102,14 @@ in {
};
};
tls = {
enable = mkEnableOption "tls" // {
enable =
mkEnableOption "tls"
// {
default = cfg.tls.certPath != null;
};
peer.enable = mkEnableOption "peer verification" // {
peer.enable =
mkEnableOption "peer verification"
// {
default = cfg.tls.caPath != null;
};
useACMECert = mkOption {
@ -212,19 +220,30 @@ in {
config = {
services.samba = {
package = mkIf cfg.ldap.enable (mkAlmostOptionDefault (
if cfg.ldap.passdb.enable && cfg.ldap.passdb.backend == "ipasam" then pkgs.samba-ipa else pkgs.samba-ldap
if cfg.ldap.passdb.enable && cfg.ldap.passdb.backend == "ipasam"
then pkgs.samba-ipa
else pkgs.samba-ldap
));
domain = {
isWorkgroup = mkOptionDefault (cfg.securityType != "domain" && cfg.securityType != "ads");
netbiosName' = let
name = if cfg.domain.netbiosName != null then cfg.domain.netbiosName else config.networking.hostName;
in mkOptionDefault (if cfg.domain.isWorkgroup then toUpper name else name);
name =
if cfg.domain.netbiosName != null
then cfg.domain.netbiosName
else config.networking.hostName;
in
mkOptionDefault (
if cfg.domain.isWorkgroup
then toUpper name
else name
);
netbiosHostAddresses = mkIf (cfg.domain.netbiosName != null) {
${cfg.domain.netbiosName'} = ["127.0.0.1" "::1"];
};
lmhosts = let
addrs = mapAttrsToList (name: map (flip nameValuePair name)) cfg.domain.netbiosHostAddresses;
in listToAttrs (concatLists addrs);
in
listToAttrs (concatLists addrs);
};
ldap = {
adminPasswordPath = mkIf (cfg.ldap.adminDn != null && hasPrefix "name=anonymous," cfg.ldap.adminDn) (mkAlmostOptionDefault (
@ -269,10 +288,12 @@ in {
(mkIf cfg.kerberos.enable {
"realm" = mkOptionDefault cfg.kerberos.realm;
"kerberos method" = mkOptionDefault (
if cfg.kerberos.keytabPath != null then "dedicated keytab"
if cfg.kerberos.keytabPath != null
then "dedicated keytab"
else "system keytab"
);
"dedicated keytab file" = mkIf (cfg.kerberos.keytabPath != null) (mkOptionDefault
"dedicated keytab file" = mkIf (cfg.kerberos.keytabPath != null) (
mkOptionDefault
"FILE:${cfg.kerberos.keytabPath}"
);
"kerberos encryption types" = mkOptionDefault "strong";
@ -302,7 +323,8 @@ in {
"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);
]
++ 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
++ [

View file

@ -1,11 +1,20 @@
{ config, lib, utils, ... }: let
{
config,
lib,
utils,
...
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.lists) head;
inherit (lib.strings) splitString;
inherit (utils) escapeSystemdPath;
mountModule = { config, name, ... }: {
mountModule = {
config,
name,
...
}: {
options = with lib.types; {
source = mkOption {
type = path;
@ -32,23 +41,38 @@
};
};
};
mkMountType' = { rootDir, specialArgs, modules ? [ ] }: let
mkMountType' = {
rootDir,
specialArgs,
modules ? [],
}: let
rootDirModule = {...}: {
config.rootDir = mkOptionDefault rootDir;
};
in lib.types.submoduleWith {
in
lib.types.submoduleWith {
modules = [mountModule rootDirModule] ++ modules;
inherit specialArgs;
};
mkMountType = args: with lib.types; coercedTo path (path: {path = mkOptionDefault path;}) (mkMountType' args);
serviceModule = { config, nixosConfig, ... }: let
serviceModule = {
config,
nixosConfig,
...
}: let
cfg = config.gensokyo-zone;
mapSharedMounts = f: mapAttrsToList (_: target:
mapSharedMounts = f:
mapAttrsToList (
_: target:
f target
) cfg.sharedMounts;
mapCacheMounts = f: mapAttrsToList (_: target:
)
cfg.sharedMounts;
mapCacheMounts = f:
mapAttrsToList (
_: target:
f target
) cfg.cacheMounts;
)
cfg.cacheMounts;
mkRequire = mount: mount.mountUnit;
mkBindPath = mount: "${mount.source}:${mount.path}";
specialArgs = {
@ -62,11 +86,17 @@
in {
options.gensokyo-zone = with lib.types; {
sharedMounts = mkOption {
type = attrsOf (mkMountType { rootDir = "/mnt/shared"; inherit specialArgs; });
type = attrsOf (mkMountType {
rootDir = "/mnt/shared";
inherit specialArgs;
});
default = {};
};
cacheMounts = mkOption {
type = attrsOf (mkMountType { rootDir = "/mnt/caches"; inherit specialArgs; });
type = attrsOf (mkMountType {
rootDir = "/mnt/caches";
inherit specialArgs;
});
default = {};
};
};

View file

@ -1,4 +1,10 @@
{ gensokyo-zone, pkgs, config, lib, ... }: let
{
gensokyo-zone,
pkgs,
config,
lib,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault mapOptionDefaults mapAlmostOptionDefaults mapDefaults;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkAfter mkDefault mkOptionDefault;
@ -39,21 +45,26 @@
};
};
};
mkServerType = { modules }: lib.types.submoduleWith {
mkServerType = {modules}:
lib.types.submoduleWith {
modules = [serverModule] ++ modules;
specialArgs = {
inherit gensokyo-zone pkgs;
nixosConfig = config;
};
};
mkServerOption = { name, kind ? "server" }: let
mkServerOption = {
name,
kind ? "server",
}: let
serverInfoModule = {...}: {
config = {
serverName = mkOptionDefault name;
serverKind = mkAlmostOptionDefault kind;
};
};
in mkOption {
in
mkOption {
type = mkServerType {
modules = [serverInfoModule];
};
@ -61,7 +72,9 @@
};
in {
options.services.sssd.gensokyo-zone = with lib.types; {
enable = mkEnableOption "realm" // {
enable =
mkEnableOption "realm"
// {
default = genso.enable;
};
ldap = {
@ -71,13 +84,18 @@ in {
default = null;
};
};
uris = mkServerOption { name = "ldap"; kind = "uri"; };
uris = mkServerOption {
name = "ldap";
kind = "uri";
};
};
krb5 = {
servers = mkServerOption {name = "krb5";};
};
ipa = {
servers = mkServerOption { name = "ipa"; } // {
servers =
mkServerOption {name = "ipa";}
// {
default = {
inherit (cfg.krb5.servers) servers backups;
};
@ -97,12 +115,14 @@ in {
# or "ipaNTSecurityIdentifier" which isn't set for most groups, maybe check netgroups..?
objectsid = "sambaSID";
backendDomainSettings = {
ldap = mapDefaults {
ldap =
mapDefaults {
id_provider = "ldap";
auth_provider = "krb5";
access_provider = "ldap";
ldap_tls_cacert = "/etc/ssl/certs/ca-bundle.crt";
} // mapOptionDefaults {
}
// mapOptionDefaults {
ldap_access_order = ["host"];
ldap_schema = "IPA";
ldap_default_bind_dn = genso.ldap.bind.dn;
@ -124,9 +144,11 @@ in {
dyndns_iface = ipa.dyndns.interface;
};
};
domainSettings = mapAlmostOptionDefaults {
domainSettings =
mapAlmostOptionDefaults {
ipa_hostname = cfg.ipa.hostName;
} // mapOptionDefaults {
}
// mapOptionDefaults {
enumerate = true;
ipa_domain = genso.domain;
krb5_realm = genso.realm;
@ -191,4 +213,3 @@ in {
};
};
}

View file

@ -15,13 +15,16 @@
inherit (lib) generators;
cfg = config.services.sssd;
mkValuePrimitive = value:
if value == true then "True"
else if value == false then "False"
if value == true
then "True"
else if value == false
then "False"
else toString value;
toINI = generators.toINI {
mkKeyValue = generators.mkKeyValueDefault {
mkValueString = value:
if isList value then concatMapStringsSep ", " mkValuePrimitive value
if isList value
then concatMapStringsSep ", " mkValuePrimitive value
else mkValuePrimitive value;
} " = ";
};
@ -51,7 +54,9 @@
};
domainModule = {name, ...}: {
options = with lib.types; {
enable = mkEnableOption "domain" // {
enable =
mkEnableOption "domain"
// {
default = true;
};
domain = mkOption {
@ -95,14 +100,16 @@
authtokConfig = mkIf (cfg.authtok.password != null || cfg.authtok.passwordFile != null) {
ldap_default_authtok_type = mkOptionDefault cfg.authtok.type;
ldap_default_authtok = mkOptionDefault (
if cfg.authtok.passwordFile != null then "\$${cfg.authtok.passwordVar}"
if cfg.authtok.passwordFile != null
then "\$${cfg.authtok.passwordVar}"
else cfg.authtok.password
);
};
extraAttrsConfig = mkIf (cfg.extraAttrs.user != {}) {
ldap_user_extra_attrs = let
mkAttr = name: attr: "${name}:${attr}";
in mapAttrsToList mkAttr cfg.extraAttrs.user;
in
mapAttrsToList mkAttr cfg.extraAttrs.user;
};
in {
settings = mkMerge [
@ -135,7 +142,8 @@ in {
};
};
services = let
mkServiceOption = name: { modules ? [ ] }: mkOption {
mkServiceOption = name: {modules ? []}:
mkOption {
type = submoduleWith {
modules = [serviceModule] ++ modules;
specialArgs = {
@ -153,7 +161,8 @@ in {
ssh = {};
pac = {};
};
in mapAttrs mkServiceOption services;
in
mapAttrs mkServiceOption services;
settings = mkOption {
type = attrsOf settingsType;
};
@ -175,11 +184,14 @@ in {
domains = map (domain: domain.domain) enabledDomains;
};
};
domainSettings = map (domain: {
domainSettings =
map (domain: {
"domain/${domain.domain}" = mapAttrs (_: mkOptionDefault) domain.settings;
}) enabledDomains;
})
enabledDomains;
settings = [defaultSettings serviceSettings] ++ domainSettings;
in mkMerge settings;
in
mkMerge settings;
services = {
nss.enable = mkAlmostOptionDefault true;
pam.enable = mkAlmostOptionDefault true;
@ -201,8 +213,14 @@ in {
};
config.system.nssDatabases = let
inherit (cfg.services) nss;
in mkIf cfg.enable {
${if options ? system.nssDatabases.netgroup then "netgroup" else null} = mkIf (nss.enable && nss.netgroup.enable) [ "sss" ];
in
mkIf cfg.enable {
${
if options ? system.nssDatabases.netgroup
then "netgroup"
else null
} =
mkIf (nss.enable && nss.netgroup.enable) ["sss"];
shadow = mkIf (!nss.enable || !nss.shadow.enable) (
mkForce ["files"]
);

View file

@ -12,7 +12,11 @@
inherit (lib.lists) singleton;
inherit (lib.strings) removePrefix;
cfg = config.services.steam.accountSwitch;
machineModule = { config, name, ... }: {
machineModule = {
config,
name,
...
}: {
options = with lib.types; {
name = mkOption {
type = str;
@ -93,7 +97,8 @@ in {
inherit owner;
inherit (shared) group mode;
};
setupFiles = singleton {
setupFiles =
singleton {
${cfg.rootDir} = toplevel;
${cfg.binDir} = toplevel;
${cfg.binDir + "/users"} = shared;
@ -101,15 +106,19 @@ in {
${cfg.sharedDataDir} = shared;
${cfg.workingDir} = toplevel;
${cfg.sharedWorkingDir} = shared;
} ++ map (owner: {
}
++ map (owner: {
${cfg.dataDir + "/${owner}"} = personal owner;
${cfg.workingDir + "/${owner}"} = personal owner;
}) cfg.users
})
cfg.users
++ mapAttrsToList (_: machine: {
${cfg.dataDir + "/${machine.name}"} = personal machine.owner;
${cfg.workingDir + "/${machine.name}"} = personal machine.owner;
}) cfg.machines;
userBinFiles = listToAttrs (map (user: nameValuePair "${cfg.binDir}/users/${user}.bat" {
})
cfg.machines;
userBinFiles = listToAttrs (map (user:
nameValuePair "${cfg.binDir}/users/${user}.bat" {
inherit (toplevel) owner group;
mode = "0755";
type = "copy";
@ -120,7 +129,8 @@ in {
setx GENSO_STEAM_USER ${user}
'';
};
}) cfg.users);
})
cfg.users);
in {
enable = mkIf (cfg.enable || cfg.setup) true;
files = mkMerge [
@ -132,12 +142,14 @@ in {
mkSharePathWith = {
path,
winRoot ? "%GENSO_SMB_SHARED_MOUNT%",
}: mkWinPath (
}:
mkWinPath (
winRoot
+ "/${cfg.sharePath}"
+ "/${removePrefix (cfg.rootDir + "/") path}"
);
mkSharePath = path: config.lib.steam.mkSharePathWith {
mkSharePath = path:
config.lib.steam.mkSharePathWith {
inherit path;
};
};

View file

@ -17,8 +17,15 @@
sortedVersions = sort (a: b: versionOlder a.version b.version) (attrValues cfg.versions);
prevVersionFor = version: let
olderVersions = filter (v: versionOlder v.version version) sortedVersions;
in if olderVersions != [] then last olderVersions else null;
versionModule = { config, name, ... }: {
in
if olderVersions != []
then last olderVersions
else null;
versionModule = {
config,
name,
...
}: {
options = with lib.types; {
version = mkOption {
type = str;
@ -40,7 +47,11 @@
);
};
};
fileModule = { config, name, ... }: {
fileModule = {
config,
name,
...
}: {
options = with lib.types; {
relativePath = mkOption {
type = str;
@ -61,7 +72,10 @@
mode = {
file = mkOption {
type = str;
default = if hasSuffix ".exe" config.relativePath || hasSuffix ".dll" config.relativePath then "775" else "664";
default =
if hasSuffix ".exe" config.relativePath || hasSuffix ".dll" config.relativePath
then "775"
else "664";
};
dir = mkOption {
type = str;
@ -106,32 +120,56 @@
versionPathFor = version: optionalString config.versioned "/${version}";
in {
init = mkOptionDefault (
if config.target == "game" then null
else if config.type == "directory" then "${emptyDir}"
else if hasSuffix ".json" config.relativePath then "${emptyJson}"
else if hasSuffix ".dll" config.relativePath || hasSuffix ".exe" config.relativePath then "${emptyExecutable}"
if config.target == "game"
then null
else if config.type == "directory"
then "${emptyDir}"
else if hasSuffix ".json" config.relativePath
then "${emptyJson}"
else if hasSuffix ".dll" config.relativePath || hasSuffix ".exe" config.relativePath
then "${emptyExecutable}"
else "${emptyFile}"
);
initFor = mkOptionDefault (
{ user, version }: config.init
{
user,
version,
}:
config.init
);
ownerFor = mkOptionDefault (user:
if config.target == "user" then user else "admin"
ownerFor = mkOptionDefault (
user:
if config.target == "user"
then user
else "admin"
);
srcPathFor = mkOptionDefault ({ user, version }:
srcPathFor = mkOptionDefault (
{
user,
version,
}:
{
shared = cfg.sharedDataDir + versionPathFor version;
user = cfg.dataDirFor user + versionPathFor version;
game = cfg.gameDirFor version;
}.${config.target} or (throw "unsupported target")
}
.${config.target}
or (throw "unsupported target")
+ "/${config.relativePath}"
);
workingPathFor = mkOptionDefault ({ user, version }:
workingPathFor = mkOptionDefault (
{
user,
version,
}:
cfg.workingDirFor {inherit user version;}
+ "/${config.relativePath}"
);
# TODO: setup.shared and do inits seperately!
setup.script = { user, version }@args: let
setup.script = {
user,
version,
} @ args: let
owner = config.ownerFor user;
srcPath = config.srcPathFor args;
workingPath = config.workingPathFor args;
@ -148,13 +186,30 @@
fi
chown ${owner}:${cfg.group} ${escapeShellArg dest}
'';
mkStyle = { style, src }: if style != "none" && src == {
mkStyle = {
style,
src,
}:
if
style
!= "none"
&& src
== {
file = "${emptyFile}";
directory = "${emptyDir}";
}.${config.type} then "empty" else style;
doInit = { style, src, dest }: {
}
.${config.type}
then "empty"
else style;
doInit = {
style,
src,
dest,
}:
{
none = "true";
copy = {
copy =
{
file = ''
if [[ -L ${escapeShellArg dest} ]]; then
rm -f ${escapeShellArg dest}
@ -172,8 +227,10 @@
chown -R ${owner}:${cfg.group} ${escapeShellArg dest}
find ${escapeShellArg dest} -type f -exec chmod -m${config.mode.file} "{}" \;
'';
}.${config.type};
empty = {
}
.${config.type};
empty =
{
directory = ''
${mkdir dest}
'';
@ -182,7 +239,8 @@
chmod ${config.mode.file} ${escapeShellArg dest}
chown ${owner}:${cfg.group} ${escapeShellArg dest}
'';
}.${config.type};
}
.${config.type};
symlink = ''
if [[ -e ${escapeShellArg dest} && ! -L ${escapeShellArg dest} ]]; then
echo ERR: something is in the way of linking ${escapeShellArg dest} >&2
@ -190,16 +248,25 @@
fi
ln -sfT ${escapeShellArg src} ${escapeShellArg dest}
'';
symlink-shallow = {
symlink-shallow =
{
directory = ''
${mkdir dest}
ln -sf ${escapeShellArg src}/* ${escapeShellArg dest}/
'';
}.${config.type};
}.${mkStyle { inherit style src; }};
doSetup = { style, src, dest }: rec {
}
.${config.type};
}
.${mkStyle {inherit style src;}};
doSetup = {
style,
src,
dest,
}:
rec {
none = "true";
copy = {
copy =
{
file = ''
${empty}
'';
@ -209,8 +276,10 @@
chmod -m${config.mode.file} ${escapeShellArg dest}/*
fi
'';
}.${config.type};
empty = {
}
.${config.type};
empty =
{
directory = ''
chmod ${config.mode.dir} ${escapeShellArg dest}
chown ${owner}:${cfg.group} ${escapeShellArg dest}
@ -219,14 +288,18 @@
chmod ${config.mode.file} ${escapeShellArg dest}
chown ${owner}:${cfg.group} ${escapeShellArg dest}
'';
}.${config.type};
}
.${config.type};
symlink = "true";
symlink-shallow = {
symlink-shallow =
{
directory = ''
${mkdir.directory}
'';
}.${config.type};
}.${mkStyle { inherit style src; }};
}
.${config.type};
}
.${mkStyle {inherit style src;}};
init = doInit {
style = config.initStyle;
src = initPath;
@ -242,32 +315,41 @@
src = srcPath;
dest = workingPath;
};
checkFlag = {
file = {
checkFlag =
{
file =
{
none = "e";
copy = "f";
symlink = "L";
}.${config.initStyle};
directory = {
}
.${config.initStyle};
directory =
{
none = "e";
copy = "d";
symlink-shallow = "d";
symlink = "L";
}.${config.initStyle};
}.${config.type};
}
.${config.initStyle};
}
.${config.type};
checkParent = ''
if [[ ! -d ${escapeShellArg parentWorkingPath} ]]; then
echo ERR: parent of ${escapeShellArg workingPath} does not exist >&2
exit 1
fi
'';
check = if initPath != null then ''
check =
if initPath != null
then ''
if [[ ! -${checkFlag} ${escapeShellArg srcPath} ]]; then
${init}
else
${setup}
fi
'' else ''
''
else ''
if [[ ! -${checkFlag} ${escapeShellArg srcPath} ]]; then
echo ERR: src ${escapeShellArg srcPath} for ${escapeShellArg workingPath} does not exist >&2
exit 1
@ -280,7 +362,11 @@
'';
};
};
userModule = { config, name, ... }: {
userModule = {
config,
name,
...
}: {
options = with lib.types; {
name = mkOption {
type = str;
@ -347,9 +433,11 @@
rmdir "%STEAM_BS_LIBRARY%"
mklink /D "%STEAM_BS_LIBRARY%" "%STEAM_BS_LAUNCH%"
'';
launch = ''
launch =
''
cd /d "%STEAM_BS_LIBRARY%"
'' + ''"%STEAM_BS_LIBRARY%\Beat Saber.exe"'';
''
+ ''"%STEAM_BS_LIBRARY%\Beat Saber.exe"'';
setup = ''
rmdir "%STEAM_BS_APPDATA%"
rmdir "%STEAM_BS_LIBRARY%"
@ -404,7 +492,10 @@
${launch}
${eof}
'';
beatsaber-user = { user, version }: ''
beatsaber-user = {
user,
version,
}: ''
set GENSO_STEAM_USER=${user}
set GENSO_STEAM_BS_VERSION=${version}
${vars}
@ -416,9 +507,13 @@
setx GENSO_STEAM_BS_VERSION Vanilla
'';
mksetupbeatsaber = { user, version }: let
mksetupbeatsaber = {
user,
version,
}: let
setupFiles = mapAttrsToList (_: file: file.setup.script {inherit user version;}) cfg.files;
in pkgs.writeShellScript "setupbeatsaber-${user}-${version}" ''
in
pkgs.writeShellScript "setupbeatsaber-${user}-${version}" ''
set -eu
export PATH="$PATH:${makeBinPath [pkgs.coreutils]}"
${concatStringsSep "\n" setupFiles}
@ -426,7 +521,9 @@
in {
options.services.steam.beatsaber = with lib.types; {
enable = mkEnableOption "beatsaber scripts";
setup = mkEnableOption "beatsaber data" // {
setup =
mkEnableOption "beatsaber data"
// {
default = accountSwitch.setup;
};
group = mkOption {
@ -489,7 +586,11 @@ in {
};
workingDirFor = mkOption {
type = functionTo path;
default = { user, version }: cfg.userWorkingDirFor user + "/${version}";
default = {
user,
version,
}:
cfg.userWorkingDirFor user + "/${version}";
};
};
@ -658,17 +759,23 @@ in {
"UserData/JDFixer.json".versioned = true;
};
userDataFiles = [
"modprefs.ini" "Disabled Mods.json"
"modprefs.ini"
"Disabled Mods.json"
"AutoPauseStealth.json"
"BeatSaberMarkupLanguage.json"
"BeatSaviorData.ini"
"BetterSongList.json"
"BetterSongSearch.json"
"bookmarkedSongs.json" "votedSongs.json"
"bookmarkedSongs.json"
"votedSongs.json"
"Chroma.json"
"Cinema.json"
"CountersPlus.json"
"CustomAvatars.CalibrationData.dat" "CustomAvatars.json" "CustomNotes.json" "Custom Platforms.json" "CustomWalls.json"
"CustomAvatars.CalibrationData.dat"
"CustomAvatars.json"
"CustomNotes.json"
"Custom Platforms.json"
"CustomWalls.json"
"DrinkWater.json"
"EasyOffset.json"
"Enhancements.json"
@ -702,13 +809,18 @@ in {
"Tweaks55.json"
"UITweaks.json"
];
mapSharedFile = file: file // {
mapSharedFile = file:
file
// {
target = "shared";
};
mapGameFile = file: file // {
mapGameFile = file:
file
// {
target = "game";
};
mapUserDataFile = file: nameValuePair "UserData/${file}" {
mapUserDataFile = file:
nameValuePair "UserData/${file}" {
target = "user";
};
in {
@ -736,11 +848,16 @@ in {
serviceConfig = {
Type = mkOptionDefault "oneshot";
RemainAfterExit = mkOptionDefault true;
ExecStart = mkMerge (mapAttrsToList (_: user:
(mapAttrsToList (_: version:
"${mksetupbeatsaber { user = user.name; inherit (version) version; }}"
) cfg.versions)
) cfg.users);
ExecStart = mkMerge (mapAttrsToList (
_: user: (mapAttrsToList (
_: version: "${mksetupbeatsaber {
user = user.name;
inherit (version) version;
}}"
)
cfg.versions)
)
cfg.users);
};
};
services.tmpfiles = let
@ -774,31 +891,49 @@ in {
"AppData"
"UserData"
];
setupFiles = [
setupFiles =
[
{
${cfg.sharedDataDir} = toplevel;
${cfg.binDir} = shared;
}
(listToAttrs (
map (folder:
map (
folder:
nameValuePair "${cfg.sharedDataDir}/${folder}" shared
) sharedFolders
)
sharedFolders
))
] ++ concatLists (mapAttrsToList (_: user:
]
++ concatLists (mapAttrsToList (
_: user:
singleton {
${cfg.dataDirFor user.name} = personal user.name;
"${cfg.dataDirFor user.name}/AppData" = personal user.name;
"${cfg.dataDirFor user.name}/UserData" = personal user.name;
} ++ mapAttrsToList (_: version: {
}
++ mapAttrsToList (_: version: {
"${cfg.dataDirFor user.name}/${version.version}" = personal user.name;
${cfg.userWorkingDirFor user.name} = personal user.name;
${cfg.workingDirFor { user = user.name; inherit (version) version; }} = personal user.name;
}) cfg.versions
) cfg.users)
${
cfg.workingDirFor {
user = user.name;
inherit (version) version;
}
} =
personal user.name;
})
cfg.versions
)
cfg.users)
++ mapAttrsToList (_: version: {
"${cfg.sharedDataDir}/${version.version}" = shared;
}) cfg.versions;
versionBinFiles = mapAttrs' (_: version: nameValuePair
})
cfg.versions;
versionBinFiles =
mapAttrs' (
_: version:
nameValuePair
"${cfg.binDir}/${replaceStrings ["."] ["_"] version.version}.bat"
{
inherit (bin) owner group mode type;
@ -810,8 +945,12 @@ in {
'';
};
}
) cfg.versions;
userBinFiles = mapAttrs' (_: user: nameValuePair
)
cfg.versions;
userBinFiles =
mapAttrs' (
_: user:
nameValuePair
"${cfg.binDir}/${user.name}.bat"
{
inherit (bin) owner group mode type;
@ -824,8 +963,10 @@ in {
};
};
}
) cfg.users;
binFiles = {
)
cfg.users;
binFiles =
{
"${cfg.binDir}/mount.bat" = {
inherit (bin) owner group mode type;
src = pkgs.writeTextFile {
@ -898,7 +1039,8 @@ in {
executable = true;
};
};
} // versionBinFiles
}
// versionBinFiles
// userBinFiles;
in {
enable = mkIf cfg.setup true;

View file

@ -24,7 +24,10 @@
...
}: let
cfg = config.networking.access;
addressForAttr = if config.networking.enableIPv6 then "address6ForNetwork" else "address4ForNetwork";
addressForAttr =
if config.networking.enableIPv6
then "address6ForNetwork"
else "address4ForNetwork";
has'Int = system.network.networks.int.enable or false;
has'Local = system.network.networks.local.enable or false;
has'Tail' = system.network.networks.tail.enable or false;
@ -48,26 +51,53 @@
forSystem = access.systemFor hostName;
forSystemHas = network: forSystem.access ? ${addressForAttr}.${network} || forSystem.access ? address4ForNetwork.${network};
err = throw "no interface found between ${config.networking.hostName} -> ${hostName}@${network}";
fallback = if nameAllowed
fallback =
if nameAllowed
then lib.warn "getAddressFor hostname fallback for ${config.networking.hostName} -> ${hostName}@${network}" (access.getHostnameFor hostName network)
else err;
local = forSystem.access.${addressForAttr}.local or forSystem.access.address4ForNetwork.local or fallback;
int = forSystem.access.${addressForAttr}.int or forSystem.access.address4ForNetwork.int or fallback;
tail = forSystem.access.${addressForAttr}.tail or fallback;
in {
in
{
lan =
if hostName == system.name then forSystem.access.${addressForAttr}.localhost
else if has'Int && forSystemHas "int" then int
else if has'Local && forSystemHas "local" then local
if hostName == system.name
then forSystem.access.${addressForAttr}.localhost
else if has'Int && forSystemHas "int"
then int
else if has'Local && forSystemHas "local"
then local
else fallback;
${if has'Local then "local" else null} = local;
${if has'Int then "int" else null} = int;
${if has'Tail then "tail" else null} = tail;
}.${network} or fallback;
${
if has'Local
then "local"
else null
} =
local;
${
if has'Int
then "int"
else null
} =
int;
${
if has'Tail
then "tail"
else null
} =
tail;
}
.${network}
or fallback;
in {
inherit (systemAccess)
hostnameForNetwork address4ForNetwork address6ForNetwork
systemForService systemForServiceId;
inherit
(systemAccess)
hostnameForNetwork
address4ForNetwork
address6ForNetwork
systemForService
systemForServiceId
;
addressForNetwork = systemAccess.${addressForAttr};
systemFor = hostName:
if hostName == config.networking.hostName
@ -91,34 +121,63 @@
getHostnameFor = hostName: network: let
forSystem = access.systemFor hostName;
err = throw "no hostname found between ${config.networking.hostName} and ${hostName}@${network}";
in {
in
{
lan =
if hostName == system.name then forSystem.access.hostnameForNetwork.localhost
else if has'Int && forSystem.access.hostnameForNetwork ? int then forSystem.access.hostnameForNetwork.int
else if has'Local && forSystem.access.hostnameForNetwork ? local then forSystem.access.hostnameForNetwork.local
if hostName == system.name
then forSystem.access.hostnameForNetwork.localhost
else if has'Int && forSystem.access.hostnameForNetwork ? int
then forSystem.access.hostnameForNetwork.int
else if has'Local && forSystem.access.hostnameForNetwork ? local
then forSystem.access.hostnameForNetwork.local
else err;
${if has'Local then "local" else null} = forSystem.access.hostnameForNetwork.local or err;
${if has'Int then "int" else null} = forSystem.access.hostnameForNetwork.int or err;
${if has'Tail then "tail" else null} = forSystem.access.hostnameForNetwork.tail or err;
}.${network} or err;
${
if has'Local
then "local"
else null
} =
forSystem.access.hostnameForNetwork.local or err;
${
if has'Int
then "int"
else null
} =
forSystem.access.hostnameForNetwork.int or err;
${
if has'Tail
then "tail"
else null
} =
forSystem.access.hostnameForNetwork.tail or err;
}
.${network}
or err;
proxyUrlFor = {
system ? if serviceId != null then access.systemForServiceId serviceId else access.systemForService serviceName,
system ?
if serviceId != null
then access.systemForServiceId serviceId
else access.systemForService serviceName,
serviceName ? mapNullable (serviceId: (findSingle (s: s.id == serviceId) null null (attrValues system.exports.services)).name) serviceId,
serviceId ? null,
service ? system.exports.services.${serviceName},
portName ? "default",
network ? "lan",
scheme ? null,
getAddressFor ? "getAddressFor"
getAddressFor ? "getAddressFor",
}: let
port = service.ports.${portName};
scheme' = if scheme == null then port.protocol else scheme;
port' = if !port.enable
scheme' =
if scheme == null
then port.protocol
else scheme;
port' =
if !port.enable
then throw "${system.name}.exports.services.${service.name}.ports.${portName} isn't enabled"
else ":${toString port.port}";
host = access.${getAddressFor} system.name network;
url = "${scheme'}://${mkAddress6 host}${port'}";
in assert service.enable; url;
in
assert service.enable; url;
};
};
networking.tempAddresses = mkIf cfg.global.enable (
@ -142,7 +201,9 @@ in {
default = domain;
};
global.enable = mkEnableOption "globally routeable";
online.enable = mkEnableOption "a deployed machine" // {
online.enable =
mkEnableOption "a deployed machine"
// {
default = true;
};
hostnameForNetwork = mkOption {
@ -164,7 +225,12 @@ in {
];
access = let
noNetwork = { enable = false; address4 = null; address6 = null; fqdn = null; };
noNetwork = {
enable = false;
address4 = null;
address6 = null;
fqdn = null;
};
local = config.network.networks.local or noNetwork;
int = config.network.networks.int or noNetwork;
mapNetwork' = mkDefault: attr: network: mkIf (network.enable && network.${attr} != null) (mkDefault network.${attr});
@ -216,12 +282,14 @@ in {
hasService = system: system.config.exports.services.${service}.enable;
notFound = throw "no system found serving ${service}";
multiple = throw "multiple systems found serving ${service}";
in (findSingle hasService notFound multiple (attrValues systems)).config;
in
(findSingle hasService notFound multiple (attrValues systems)).config;
systemForServiceId = serviceId: let
hasService = system: findSingle (service: service.id == serviceId && service.enable) null multiple (attrValues system.config.exports.services) != null;
notFound = throw "no system found serving ${serviceId}";
multiple = throw "multiple systems found serving ${serviceId}";
in (findSingle hasService notFound multiple (attrValues systems)).config;
in
(findSingle hasService notFound multiple (attrValues systems)).config;
};
};
}

View file

@ -10,7 +10,9 @@
inherit (lib.modules) mkIf mkOptionDefault;
in {
options.ci = with lib.types; {
enable = mkEnableOption "build via CI" // {
enable =
mkEnableOption "build via CI"
// {
default = config.type == "NixOS";
};
allowFailure = mkOption {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -24,7 +24,12 @@
};
id = mkOption {
type = str;
default = cfg.services.${config.serviceName}.id/* or config.name*/;
default =
cfg.services.${config.serviceName}.id
/*
or config.name
*/
;
};
};
};

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -8,7 +12,8 @@ in {
config.exports.services.home-assistant = {config, ...}: let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.home-assistant;
in f nixosConfig cfg;
in
f nixosConfig cfg;
assertPort = nixosConfig: cfg: {
assertion = config.ports.default.port == cfg.config.http.server_port;
message = "port mismatch";
@ -16,7 +21,8 @@ in {
assertHomekitPort = let
portName = i: "homekit${toString i}";
mkAssertPort = i: homekit: config.ports.${portName i}.port or null == homekit.port;
in nixosConfig: cfg: {
in
nixosConfig: cfg: {
assertion = all id (imap0 mkAssertPort cfg.config.homekit);
message = "homekit port mismatch";
};

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -10,8 +14,10 @@ in {
assertions = let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.keycloak;
in f nixosConfig cfg;
in mkIf config.enable [
in
f nixosConfig cfg;
in
mkIf config.enable [
(mkAssertion (nixosConfig: cfg: {
assertion = config.ports.${cfg.protocol}.port == cfg.port;
message = "port mismatch";

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -6,7 +10,8 @@ in {
config.exports.services.minecraft-bedrock-server = {config, ...}: let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.minecraft-bedrock-server;
in f nixosConfig cfg;
in
f nixosConfig cfg;
in {
nixos = {
serviceAttr = "minecraft-bedrock-server";

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -13,7 +17,8 @@ in {
(nixosConfig: let
cfg = nixosConfig.services.mosquitto;
portName = i:
if i == 0 then "default"
if i == 0
then "default"
else "listener${toString i}";
mkAssertPort = i: listener: config.ports.${portName i}.port or null == listener.port;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -6,16 +10,22 @@ in {
config.exports.services.nfs = {config, ...}: let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.nfs;
in f nixosConfig cfg;
mkAssertionPort = portName: mkAssertion (nixosConfig: cfg: let
in
f nixosConfig cfg;
mkAssertionPort = portName:
mkAssertion (nixosConfig: cfg: let
portAttr = "${portName}Port";
in {
assertion = mkAssertPort config.ports.${portName} cfg.server.${portAttr};
message = "${portAttr} mismatch";
});
mkAssertPort = port: cfgPort: let
cmpPort = if port.enable then port.port else null;
in cfgPort == cmpPort;
cmpPort =
if port.enable
then port.port
else null;
in
cfgPort == cmpPort;
in {
nixos = {
serviceAttrPath = ["services" "nfs" "server"];

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -6,7 +10,8 @@ in {
config.exports.services.nginx = {config, ...}: let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.nginx;
in f nixosConfig cfg;
in
f nixosConfig cfg;
assertPorts = nixosConfig: cfg: {
assertion = config.ports.http.port == cfg.defaultHTTPListenPort && config.ports.https.port == cfg.defaultSSLListenPort;
message = "ports mismatch";

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs;
@ -10,8 +14,10 @@ in {
assertions = let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.openwebrx;
in f nixosConfig cfg;
in mkIf config.enable [
in
f nixosConfig cfg;
in
mkIf config.enable [
(mkAssertion (nixosConfig: cfg: {
assertion = config.ports.default.port == cfg.port;
message = "port mismatch";

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,11 +1,16 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults;
inherit (lib.modules) mkIf;
in {
config.exports.services.postgresql = {config, ...}: let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.postgresql;
in f nixosConfig cfg;
in
f nixosConfig cfg;
in {
nixos = {
serviceAttr = "postgresql";

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
in {
config.exports.services.proxmox = {config, ...}: {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -12,7 +12,11 @@
inherit (lib.trivial) mapNullable;
inherit (lib.strings) concatStringsSep;
systemConfig = config;
portModule = {config, service, ...}: {
portModule = {
config,
service,
...
}: {
options = with lib.types; {
enable =
mkEnableOption "port"
@ -107,7 +111,8 @@
serviceConfig = getAttrFromPath config.nixos.serviceAttrPath;
mkAssertion = f: nixosConfig: let
cfg = serviceConfig nixosConfig;
in f nixosConfig cfg;
in
f nixosConfig cfg;
enableAssertion = nixosConfig: cfg: {
assertion = (! cfg ? enable) || (config.enable == cfg.enable);
message = "enable == nixosConfig.${concatStringsSep "." config.nixos.serviceAttrPath}.enable";
@ -120,10 +125,16 @@
};
};
};
nixosModule = {config, system, ...}: let
nixosModule = {
config,
system,
...
}: let
mapAssertion = service: a: let
res = a config;
in res // {
in
res
// {
message = "system.exports.${service.name}: " + res.message or "assertion failed";
};
assertions = mapAttrsToList (_: service: map (mapAssertion service) service.nixos.assertions) system.exports.services;

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs filterAttrs mapAttrsToList;
@ -7,7 +11,8 @@ in {
config.exports.services.sshd = {config, ...}: let
mkAssertion = f: nixosConfig: let
cfg = nixosConfig.services.openssh;
in f nixosConfig cfg;
in
f nixosConfig cfg;
sorted = sort (a: b: a > b);
assertPorts = nixosConfig: cfg: let
nixosPorts = cfg.ports;

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.attrsets) mapAttrs;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
in {

View file

@ -1,4 +1,8 @@
{lib, gensokyo-zone, ...}: let
{
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
inherit (lib.modules) mkIf;
in {

View file

@ -1,11 +1,19 @@
let
fileModule = {config, name, gensokyo-zone, lib, ...}: let
fileModule = {
config,
name,
gensokyo-zone,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkOptionDefault;
inherit (lib.strings) hasPrefix removePrefix;
in {
options = with lib.types; {
enable = mkEnableOption "external file" // {
enable =
mkEnableOption "external file"
// {
default = true;
};
path = mkOption {
@ -35,13 +43,21 @@ let
relativeSource = let
flakeRoot = toString gensokyo-zone.self + "/";
sourcePath = toString config.source;
in mkOptionDefault (
if hasPrefix flakeRoot sourcePath then removePrefix flakeRoot sourcePath
in
mkOptionDefault (
if hasPrefix flakeRoot sourcePath
then removePrefix flakeRoot sourcePath
else null
);
};
};
in {config, gensokyo-zone, lib, ...}: let
in
{
config,
gensokyo-zone,
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options.extern = with lib.types; {

View file

@ -101,10 +101,13 @@ in {
darwin = inputs.darwin.lib.darwinSystem;
macos = inputs.darwin.lib.darwinSystem;
}
.${string.toLower config.type} or null;
built = mkOptionDefault (mapNullable (builder: builder {
.${string.toLower config.type}
or null;
built = mkOptionDefault (mapNullable (builder:
builder {
inherit (config) system modules specialArgs;
}) config.builder);
})
config.builder);
specialArgs = {
inherit name inputs std Std meta;
inherit (inputs.self.lib) gensokyo-zone;

View file

@ -1,9 +1,19 @@
{config, lib, inputs, ...}: let
{
config,
lib,
inputs,
...
}: let
inherit (inputs.self.lib.lib) eui64;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.trivial) mapNullable;
networkModule = { config, name, system, ... }: let
networkModule = {
config,
name,
system,
...
}: let
knownNetworks = {
local.slaac = {
enable = true;
@ -13,7 +23,9 @@
};
in {
options = with lib.types; {
enable = mkEnableOption "network" // {
enable =
mkEnableOption "network"
// {
default = true;
};
slaac = {

View file

@ -1,4 +1,8 @@
{config, lib, ...}: let
{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
cfg = config.proxmox.container;
in {

View file

@ -1,4 +1,10 @@
{config, gensokyo-zone, lib, Std, ...}: let
{
config,
gensokyo-zone,
lib,
Std,
...
}: let
inherit (Std) UInt;
inherit (gensokyo-zone.lib) unmerged eui64 mkAlmostOptionDefault mapAlmostOptionDefaults;
inherit (lib.options) mkOption mkEnableOption;
@ -9,9 +15,16 @@
inherit (lib.trivial) mapNullable;
cfg = config.proxmox.network;
internalOffset = 32;
networkInterfaceModule = { config, name, system, ... }: {
networkInterfaceModule = {
config,
name,
system,
...
}: {
options = with lib.types; {
enable = mkEnableOption "network interface" // {
enable =
mkEnableOption "network interface"
// {
default = true;
};
bridge = mkOption {
@ -51,7 +64,9 @@
default = "virtio";
};
mdns = {
enable = mkEnableOption "mDNS" // {
enable =
mkEnableOption "mDNS"
// {
default = config.local.enable && config.id == "net0";
};
};
@ -76,7 +91,9 @@
};
};
networkd = {
enable = mkEnableOption "systemd.network" // {
enable =
mkEnableOption "systemd.network"
// {
default = true;
};
name = mkOption {
@ -94,10 +111,16 @@
hasAddr6 = ! elem config.address6 [null "dhcp" "auto"];
conf = {
local = mkIf config.local.enable {
address4 = mkOptionDefault (if hasAddr4 then config.address4 else null);
address4 = mkOptionDefault (
if hasAddr4
then config.address4
else null
);
address6 = mkOptionDefault (
if config.address6 == "auto" && config.slaac.postfix != null then "fd0a::${config.slaac.postfix}"
else if hasAddr6 then config.address6
if config.address6 == "auto" && config.slaac.postfix != null
then "fd0a::${config.slaac.postfix}"
else if hasAddr6
then config.address6
else null
);
};
@ -142,9 +165,12 @@
(mkIf (config.gateway6 != null) [config.gateway6])
];
DHCP = mkAlmostOptionDefault (
if config.address4 == "dhcp" && config.address6 == "dhcp" then "yes"
else if config.address6 == "dhcp" then "ipv6"
else if config.address4 == "dhcp" then "ipv4"
if config.address4 == "dhcp" && config.address6 == "dhcp"
then "yes"
else if config.address6 == "dhcp"
then "ipv6"
else if config.address4 == "dhcp"
then "ipv4"
else "no"
);
};
@ -172,7 +198,8 @@
};
};
};
in mkMerge [
in
mkMerge [
conf
(mkIf config.internal.enable confInternal)
];

View file

@ -1,4 +1,9 @@
{config, lib, gensokyo-zone, ...}: let
{
config,
lib,
gensokyo-zone,
...
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf;

View file

@ -1,4 +1,8 @@
{config, lib, ...}: let
{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
cfg = config.proxmox;
in {

View file

@ -25,7 +25,8 @@ in {
requireAuth = false;
};
proxy = {
upstream = mkIf barcodebuddy.enable (mkDefault
upstream = mkIf barcodebuddy.enable (
mkDefault
"nginx'proxied"
);
host = mkDefault serverName;

View file

@ -5,8 +5,7 @@
gensokyo-zone,
lib,
...
}:
let
}: let
inherit (gensokyo-zone.lib) mapOptionDefaults;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
@ -19,7 +18,11 @@ let
ssl_verify_client optional_no_ca;
'';
locations = {
"/" = { config, xvars, ... }: {
"/" = {
config,
xvars,
...
}: {
proxy = {
enable = true;
upstream = "freeipa";
@ -67,7 +70,9 @@ in {
};
};
kerberos = {
enable = mkEnableOption "proxy kerberos" // {
enable =
mkEnableOption "proxy kerberos"
// {
default = true;
};
ports = {
@ -208,7 +213,8 @@ in {
ssl.cert.copyFromVhost = mkDefault "freeipa";
};
};
in mkMerge [
in
mkMerge [
conf
(mkIf nginx.ssl.preread.enable prereadConf)
(mkIf cfg.kerberos.enable kerberosConf)
@ -233,7 +239,11 @@ in {
name.shortServer = mkDefault "idp-ca";
locations."/" = mkMerge [
locations."/"
({config, virtualHost, ...}: {
({
config,
virtualHost,
...
}: {
proxy.ssl.host = virtualHost.serverName;
proxy.host = config.proxy.ssl.host;
})
@ -295,14 +305,16 @@ in {
inherit (nginx.stream.servers) krb5 kadmin kpasswd kticket4;
in {
allowedTCPPorts = mkMerge [
(mkIf cfg.kerberos.enable (map (server:
(mkIf cfg.kerberos.enable (map (
server:
mkIf (server.enable && server.listen.tcp.enable) server.listen.tcp.port
) [krb5 kticket4 kpasswd kadmin]))
(mkIf nginx.ssl.preread.enable [
ldapsPort
])
];
allowedUDPPorts = mkIf cfg.kerberos.enable (map (server:
allowedUDPPorts = mkIf cfg.kerberos.enable (map (
server:
mkIf (server.enable && server.listen.udp.enable) server.listen.udp.port
) [krb5 kticket4 kpasswd]);
};

View file

@ -13,8 +13,15 @@ in {
config.services.nginx = {
virtualHosts = let
proxyScheme = "https";
url = access.proxyUrlFor { serviceName = "freepbx"; portName = proxyScheme; };
ucpUrl = access.proxyUrlFor { serviceName = "freepbx"; portName = "ucp-ssl"; getAddressFor = "getAddress4For"; };
url = access.proxyUrlFor {
serviceName = "freepbx";
portName = proxyScheme;
};
ucpUrl = access.proxyUrlFor {
serviceName = "freepbx";
portName = "ucp-ssl";
getAddressFor = "getAddress4For";
};
ucpPath = "/socket.io";
# TODO: ports.asterisk/asterisk-ssl?
extraConfig = ''
@ -33,7 +40,11 @@ in {
};
};
};
${ucpPath} = { xvars, virtualHost, ... }: {
${ucpPath} = {
xvars,
virtualHost,
...
}: {
proxy = {
enable = true;
websocket.enable = true;
@ -103,9 +114,11 @@ in {
};
};
config.networking.firewall = let
websocketPorts = virtualHost: [
websocketPorts = virtualHost:
[
virtualHost.listen'.ucp.port
] ++ optional virtualHost.listen'.ucpSsl.enable virtualHost.listen'.ucpSsl.port;
]
++ optional virtualHost.listen'.ucpSsl.enable virtualHost.listen'.ucpSsl.port;
in {
interfaces.local.allowedTCPPorts = websocketPorts nginx.virtualHosts.freepbx'local;
allowedTCPPorts = mkIf (!nginx.virtualHosts.freepbx'ucp.local.denyGlobal) (websocketPorts nginx.virtualHosts.freepbx'ucp);

View file

@ -20,7 +20,11 @@
headers.set.X-Grocy-User = mkOptionDefault "$grocy_user";
};
};
luaAuthHost = { config, xvars, ... }: {
luaAuthHost = {
config,
xvars,
...
}: {
vouch.auth.lua = {
enable = true;
accessRequest = ''
@ -56,16 +60,20 @@ in {
proxied.enable = true;
local.denyGlobal = true;
};
grocy = mkMerge [ luaAuthHost {
grocy = mkMerge [
luaAuthHost
{
inherit name extraConfig locations;
vouch.enable = true;
proxy = {
upstream = mkIf grocy.enable (mkDefault
upstream = mkIf grocy.enable (
mkDefault
"nginx'proxied"
);
host = mkDefault serverName;
};
} ];
}
];
grocy'local = {
inherit name;
local.enable = mkDefault true;
@ -78,7 +86,9 @@ in {
proxy.enable = true;
};
};
grocy'local'int = mkMerge [ luaAuthHost {
grocy'local'int = mkMerge [
luaAuthHost
{
# internal proxy workaround for http2 lua compat issues
serverName = serverName'local;
inherit name extraConfig locations;
@ -91,7 +101,8 @@ in {
enable = true;
localSso.enable = true;
};
} ];
}
];
};
};
}

View file

@ -63,7 +63,8 @@ in {
};
config.networking.firewall.allowedTCPPorts = let
inherit (nginx.virtualHosts.home-assistant'local) listen';
in mkIf nginx.virtualHosts.home-assistant'local.enable [
in
mkIf nginx.virtualHosts.home-assistant'local.enable [
(mkIf listen'.hass.enable listen'.hass.port)
];
}

View file

@ -61,7 +61,11 @@ in {
upstream = "nginx'proxied";
host = mkDefault nginx.virtualHosts.invidious'int.serverName;
};
locations."/" = { xvars, virtualHost, ... }: {
locations."/" = {
xvars,
virtualHost,
...
}: {
proxy.enable = true;
extraConfig = ''
proxy_http_version 1.1;
@ -72,7 +76,11 @@ in {
'';
};
};
invidious'int = { config, xvars, ... }: {
invidious'int = {
config,
xvars,
...
}: {
serverName = "@invidious_internal";
proxied.enable = true;
local.denyGlobal = true;

View file

@ -12,8 +12,15 @@
in {
config.services.nginx = {
virtualHosts = let
url = access.proxyUrlFor { inherit system; service = motion; };
streamUrl = access.proxyUrlFor { inherit system; service = motion; portName = "stream"; };
url = access.proxyUrlFor {
inherit system;
service = motion;
};
streamUrl = access.proxyUrlFor {
inherit system;
service = motion;
portName = "stream";
};
extraConfig = ''
proxy_redirect off;
proxy_buffering off;
@ -49,9 +56,12 @@ in {
inherit name listen';
ssl.cert.copyFromVhost = "kitchencam";
local.enable = true;
locations = mapAttrs (name: location: location // {
locations = mapAttrs (name: location:
location
// {
proxyPass = mkDefault nginx.virtualHosts.kitchencam.locations.${name}.proxyPass;
}) locations;
})
locations;
};
};
};

View file

@ -4,8 +4,7 @@
gensokyo-zone,
access,
...
}:
let
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkOptionDefault;

View file

@ -4,8 +4,7 @@
access,
gensokyo-zone,
...
}:
let
}: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (config.services) nginx;
@ -42,7 +41,9 @@ in {
};
};
proxy.upstream = mkAlmostOptionDefault (
if nginx.stream.upstreams.mqtts.enable then "mqtts" else "mqtt"
if nginx.stream.upstreams.mqtts.enable
then "mqtts"
else "mqtt"
);
};
};

View file

@ -1,4 +1,8 @@
{config, lib, ...}: let
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
cfg = config.services.nginx;
in {

View file

@ -88,7 +88,8 @@ in {
};
config.networking.firewall.allowedTCPPorts = let
inherit (nginx.virtualHosts.plex) listen';
in mkIf listen'.external.enable [
in
mkIf listen'.external.enable [
listen'.external.port
];
}

View file

@ -28,7 +28,11 @@ in {
proxy_redirect default;
'';
};
"/validate" = {config, virtualHost, ...}: {
"/validate" = {
config,
virtualHost,
...
}: {
proxied.enable = true;
proxy.enable = true;
local.denyGlobal = true;

View file

@ -1,4 +1,9 @@
{config, access, lib, ...}: let
{
config,
access,
lib,
...
}: let
inherit (lib.modules) mkIf mkDefault;
inherit (config.services) nginx;
cfg = config.services.barcodebuddy;
@ -28,7 +33,8 @@ in {
};
config.systemd.services = let
gensokyo-zone.sharedMounts.barcodebuddy.path = mkDefault cfg.dataDir;
in mkIf cfg.enable {
in
mkIf cfg.enable {
phpfpm-barcodebuddy = {
inherit gensokyo-zone;
};

View file

@ -1,7 +1,4 @@
{
pkgs,
...
}: {
{pkgs, ...}: {
fonts.packages = [
pkgs.tamzen
];

View file

@ -14,8 +14,14 @@ in {
hostName = mkOverride 25 name;
nameservers' = [
#{ address = "8.8.8.8"; host = "dns.google"; }
{ address = "1.1.1.1"; host = "cloudflare-dns.com"; }
{ address = "1.0.0.1"; host = "cloudflare-dns.com"; }
{
address = "1.1.1.1";
host = "cloudflare-dns.com";
}
{
address = "1.0.0.1";
host = "cloudflare-dns.com";
}
];
};

View file

@ -23,10 +23,12 @@ in {
lock = importJSON ../../flake.lock;
mapFlake = name: let
node = lock.nodes.${name};
in {
in
{
inherit (node.original) type;
inherit (node.locked) lastModified rev narHash;
} // optionalAttrs (node.original.type == "github") {
}
// optionalAttrs (node.original.type == "github") {
inherit (node.original) repo owner;
};
in {

View file

@ -1,11 +1,18 @@
{ pkgs, config, lib, ... }: let
{
pkgs,
config,
lib,
...
}: let
inherit (lib.options) mkEnableOption mkPackageOption;
inherit (lib.modules) mkIf;
cfg = config.boot.binfmt.cross.aarch64;
in {
options = {
boot.binfmt.cross.aarch64 = {
enable = mkEnableOption "qemu-aarch64" // {
enable =
mkEnableOption "qemu-aarch64"
// {
default = true;
};
package = mkPackageOption pkgs "qemu" {};

View file

@ -13,9 +13,12 @@
inherit (lib.trivial) mapNullable flip;
cfg = config.services.dnsmasq;
inherit (gensokyo-zone) systems;
localSystems = filterAttrs (_: system:
localSystems =
filterAttrs (
_: system:
system.config.access.online.enable && system.config.network.networks.local.enable or false
) systems;
)
systems;
mkHostRecordPairs = _: system: [
(mkHostRecordPair "int" system)
(mkHostRecordPair "local" system)
@ -26,9 +29,12 @@
mkDynamicHostRecord = _: system: let
address4 = system.config.network.networks.local.address4 or null;
address6 = system.config.network.networks.local.address6 or null;
in concatStringsSep "," ([
in
concatStringsSep "," (
[
system.config.access.fqdn
] ++ optional (address4 != null)
]
++ optional (address4 != null)
(toString (mapNullable mapDynamic4 address4))
++ optional (address6 != null)
(toString (mapNullable mapDynamic6 address6))
@ -39,8 +45,13 @@
address4 = system.config.network.networks.${network}.address4 or null;
address6 = system.config.network.networks.${network}.address6 or null;
fqdn = system.config.network.networks.${network}.fqdn or null;
in nameValuePair
(if fqdn != null then fqdn else "${network}.${system.config.access.fqdn}")
in
nameValuePair
(
if fqdn != null
then fqdn
else "${network}.${system.config.access.fqdn}"
)
(concatStringsSep "," (
optional (address4 != null)
(toString address4)
@ -93,15 +104,16 @@ in {
"mco.cubecraft.net"
];
bedrockRecords = map (flip mkHostRecord bedrockRecord) bedrockRecordNames;
in mkMerge [
in
mkMerge [
(mapAttrsToList mkHostRecord systemHosts)
(mkIf (cfg.bedrockConnect.address != null || cfg.bedrockConnect.address6 != null) bedrockRecords)
];
dynamic-host = mapAttrsToList mkDynamicHostRecord localSystems;
server =
if config.networking.nameservers' != [ ] then map (ns: ns.address) (filter filterns' config.networking.nameservers')
else filter filterns config.networking.nameservers
;
if config.networking.nameservers' != []
then map (ns: ns.address) (filter filterns' config.networking.nameservers')
else filter filterns config.networking.nameservers;
max-cache-ttl = 60;
};
bedrockConnect = let

View file

@ -1,4 +1,8 @@
{config, lib, ...}: let
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
cfg = config.services.grocy;
in {
@ -72,7 +76,8 @@ in {
};
systemd.services = let
gensokyo-zone.sharedMounts.grocy.path = mkDefault cfg.dataDir;
in mkIf cfg.enable {
in
mkIf cfg.enable {
grocy-setup = {
inherit gensokyo-zone;
};

View file

@ -1,4 +1,8 @@
{lib, access, ...}: let
{
lib,
access,
...
}: let
inherit (lib.modules) mkDefault;
in {
config = {

View file

@ -1,4 +1,8 @@
{ config, lib, ... }: let
{
config,
lib,
...
}: let
inherit (lib.modules) mkDefault;
in {
# NOTE: requires manual post-install setup...

View file

@ -1,4 +1,11 @@
{inputs, system, access, config, lib, ...}: let
{
inputs,
system,
access,
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkForce mkDefault;
inherit (lib.lists) optional;
cfg = config.services.keycloak;
@ -20,7 +27,8 @@ in {
sopsFile = ./secrets/keycloak.yaml;
owner = "keycloak";
};
in mkIf cfg.enable {
in
mkIf cfg.enable {
keycloak_db_password = commonSecret;
};
users = mkIf cfg.enable {
@ -54,8 +62,16 @@ in {
};
settings = {
hostname = mkDefault (if hostname-strict then hostname else null);
proxy = mkDefault (if cfg.protocol == "https" then "reencrypt" else "edge");
hostname = mkDefault (
if hostname-strict
then hostname
else null
);
proxy = mkDefault (
if cfg.protocol == "https"
then "reencrypt"
else "edge"
);
hostname-strict = mkDefault hostname-strict;
hostname-strict-https = mkDefault hostname-strict;
proxy-headers = mkDefault "xforwarded";

View file

@ -1,4 +1,11 @@
{ inputs, pkgs, config, access, lib, ... }: let
{
inputs,
pkgs,
config,
access,
lib,
...
}: let
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mapAlmostOptionDefaults;
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault mkOptionDefault;
inherit (lib.strings) replaceStrings;
@ -68,7 +75,8 @@ in {
kinit -k host/${config.networking.fqdn}
'';
in mkIf enabled {
in
mkIf enabled {
path = [config.security.krb5.package];
serviceConfig = {
Type = mkOptionDefault "oneshot";
@ -78,7 +86,8 @@ in {
sops.secrets = let
sopsFile = mkDefault ./secrets/krb5.yaml;
in mkIf enabled {
in
mkIf enabled {
krb5-keytab = {
mode = "0400";
path = "/etc/krb5.keytab";

View file

@ -47,7 +47,8 @@ in {
"nfs-mountd.service"
];
before = wantedBy;
in mkIf config.services.nfs.server.enable [
in
mkIf config.services.nfs.server.enable [
{
inherit type options wantedBy before;
what = kyuuto.mountDir;

Some files were not shown because too many files have changed in this diff Show more