Massive nixfmt reformatting

This commit is contained in:
Natsu Kagami 2025-04-03 13:59:50 +02:00
parent fe4492f004
commit b29ddd5e65
Signed by: nki
GPG key ID: 55A032EB38B49ADB
109 changed files with 4323 additions and 2368 deletions

View file

@ -1,11 +1,15 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
cfg = config.cloud.authentik;
mkImage =
{ imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
mkImage = { imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
# If we can pullImage we can just do
# mkImage = pkgs.dockerTools.pullImage;
@ -62,7 +66,10 @@ in
image = images.postgresql;
restart = "unless-stopped";
healthcheck = {
test = [ "CMD-SHELL" "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}" ];
test = [
"CMD-SHELL"
"pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"
];
start_period = "20s";
interval = "30s";
retries = 5;
@ -73,14 +80,20 @@ in
POSTGRES_USER = "authentik";
POSTGRES_DB = "authentik";
};
env_file = [ cfg.envFile "${postgresEnv}" ];
env_file = [
cfg.envFile
"${postgresEnv}"
];
};
services.redis.service = {
image = images.redis;
command = "--save 60 1 --loglevel warning";
restart = "unless-stopped";
healthcheck = {
test = [ "CMD-SHELL" "redis-cli ping | grep PONG" ];
test = [
"CMD-SHELL"
"redis-cli ping | grep PONG"
];
start_period = "20s";
interval = "30s";
retries = 5;
@ -102,7 +115,10 @@ in
AUTHENTIK_POSTGRESQL__USER = "authentik";
AUTHENTIK_POSTGRESQL__NAME = "authentik";
};
env_file = [ cfg.envFile "${authentikEnv}" ];
env_file = [
cfg.envFile
"${authentikEnv}"
];
ports = [
"127.0.0.1:${toString cfg.port}:9000"
];
@ -124,7 +140,10 @@ in
AUTHENTIK_POSTGRESQL__USER = "authentik";
AUTHENTIK_POSTGRESQL__NAME = "authentik";
};
env_file = [ cfg.envFile "${authentikEnv}" ];
env_file = [
cfg.envFile
"${authentikEnv}"
];
user = "root";
};
docker-compose.volumes = {
@ -134,4 +153,3 @@ in
};
};
}

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }:
{
pkgs,
lib,
config,
...
}:
with lib;
let

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
let
cfg = config.cloud.conduit;
@ -33,95 +38,105 @@ with lib;
};
instances = mkOption {
type = types.attrsOf (types.submodule {
options = {
host = mkOption {
type = types.str;
type = types.attrsOf (
types.submodule {
options = {
host = mkOption {
type = types.str;
};
server_name = mkOption {
type = types.str;
default = "";
};
port = mkOption {
type = types.int;
};
noCloudflare = mkOption {
type = types.bool;
default = false;
};
allow_registration = mkOption {
type = types.bool;
default = false;
};
well-known_port = mkOption {
type = types.int;
};
};
server_name = mkOption {
type = types.str;
default = "";
};
port = mkOption {
type = types.int;
};
noCloudflare = mkOption {
type = types.bool;
default = false;
};
allow_registration = mkOption {
type = types.bool;
default = false;
};
well-known_port = mkOption {
type = types.int;
};
};
});
}
);
};
};
config.systemd.services = mkIf cfg.enable
(lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "matrix-conduit-${name}"
(
let
srvName = "matrix-conduit-${name}";
format = pkgs.formats.toml { };
server_name = if instance.server_name == "" then instance.host else instance.server_name;
configFile = format.generate "conduit.toml" (lib.attrsets.recursiveUpdate defaultConfig {
config.systemd.services = mkIf cfg.enable (
lib.attrsets.mapAttrs' (
name: instance:
lib.attrsets.nameValuePair "matrix-conduit-${name}" (
let
srvName = "matrix-conduit-${name}";
format = pkgs.formats.toml { };
server_name = if instance.server_name == "" then instance.host else instance.server_name;
configFile = format.generate "conduit.toml" (
lib.attrsets.recursiveUpdate defaultConfig {
global.server_name = server_name;
global.port = instance.port;
global.allow_registration = instance.allow_registration;
global.database_path = "/mnt/data/${srvName}/";
global.well_known_client = "https://${instance.host}";
global.well_known_server = "${instance.host}:443";
});
in
{
description = "Conduit Matrix Server (for ${server_name})";
documentation = [ "https://gitlab.com/famedly/conduit/" ];
wantedBy = [ "multi-user.target" ];
environment = { CONDUIT_CONFIG = configFile; };
serviceConfig = {
DynamicUser = true;
User = "${srvName}";
LockPersonality = true;
MemoryDenyWriteExecute = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateUsers = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
# StateDirectory = "/mnt/data/${srvName}";
BindPaths = [ "/mnt/data/${srvName}" ];
ExecStart = "${cfg.package}/bin/conduit";
Restart = "on-failure";
RestartSec = 10;
StartLimitBurst = 5;
};
}
))
cfg.instances);
}
);
in
{
description = "Conduit Matrix Server (for ${server_name})";
documentation = [ "https://gitlab.com/famedly/conduit/" ];
wantedBy = [ "multi-user.target" ];
environment = {
CONDUIT_CONFIG = configFile;
};
serviceConfig = {
DynamicUser = true;
User = "${srvName}";
LockPersonality = true;
MemoryDenyWriteExecute = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateUsers = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
# StateDirectory = "/mnt/data/${srvName}";
BindPaths = [ "/mnt/data/${srvName}" ];
ExecStart = "${cfg.package}/bin/conduit";
Restart = "on-failure";
RestartSec = 10;
StartLimitBurst = 5;
};
}
)
) cfg.instances
);
config.cloud.traefik.hosts = mkIf cfg.enable (
(lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}" ({
(lib.attrsets.mapAttrs' (
name: instance:
lib.attrsets.nameValuePair "conduit-${name}" ({
inherit (instance) host port noCloudflare;
}))
cfg.instances)
})
) cfg.instances)
);
}

View file

@ -1,9 +1,15 @@
{ pkgs, lib, config, ... }:
{
pkgs,
lib,
config,
...
}:
let
cfg = config.cloud.conduit.heisenbridge;
cfgConduit = config.cloud.conduit;
in
with lib; {
with lib;
{
options.cloud.conduit.heisenbridge = {
enable = mkEnableOption "Enable heisenbridge for conduit";
package = mkPackageOption pkgs "heisenbridge" { };
@ -23,17 +29,26 @@ with lib; {
};
config = mkIf cfg.enable (
let
cfgFile = if cfg.port == null then cfg.appserviceFile else
pkgs.runCommand "heisenbridge-config" { } ''
cp ${cfg.appserviceFile} $out
${pkgs.sd}/bin/sd '^url: .*$' "url: http://127.0.0.1:${cfg.port}"
'';
listenArgs = lists.optionals (cfg.port != null) [ "--listen-port" (toString cfg.port) ];
cfgFile =
if cfg.port == null then
cfg.appserviceFile
else
pkgs.runCommand "heisenbridge-config" { } ''
cp ${cfg.appserviceFile} $out
${pkgs.sd}/bin/sd '^url: .*$' "url: http://127.0.0.1:${cfg.port}"
'';
listenArgs = lists.optionals (cfg.port != null) [
"--listen-port"
(toString cfg.port)
];
in
{
systemd.services.heisenbridge = {
description = "Matrix<->IRC bridge";
requires = [ "matrix-conduit-nkagami.service" "matrix-synapse.service" ]; # So the registration file can be used by Synapse
requires = [
"matrix-conduit-nkagami.service"
"matrix-synapse.service"
]; # So the registration file can be used by Synapse
wantedBy = [ "multi-user.target" ];
serviceConfig = rec {
@ -77,12 +92,18 @@ with lib; {
RemoveIPC = true;
UMask = "0077";
CapabilityBoundingSet = [ "CAP_CHOWN" ] ++ optional (cfg.port != null && cfg.port < 1024) "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = [
"CAP_CHOWN"
] ++ optional (cfg.port != null && cfg.port < 1024) "CAP_NET_BIND_SERVICE";
AmbientCapabilities = CapabilityBoundingSet;
NoNewPrivileges = true;
LockPersonality = true;
RestrictRealtime = true;
SystemCallFilter = [ "@system-service" "~@privileged" "@chown" ];
SystemCallFilter = [
"@system-service"
"~@privileged"
"@chown"
];
SystemCallArchitectures = "native";
RestrictAddressFamilies = "AF_INET AF_INET6";
};
@ -97,4 +118,3 @@ with lib; {
}
);
}

View file

@ -1,11 +1,15 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
cfg = config.cloud.firezone;
mkImage =
{ imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
mkImage = { imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
# If we can pullImage we can just do
# mkImage = pkgs.dockerTools.pullImage;
@ -48,7 +52,10 @@ in
image = images.postgresql;
restart = "unless-stopped";
healthcheck = {
test = [ "CMD-SHELL" "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}" ];
test = [
"CMD-SHELL"
"pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"
];
start_period = "20s";
interval = "30s";
retries = 5;
@ -89,7 +96,10 @@ in
driver = "bridge";
ipam.config = [
{ subnet = "172.25.0.0/16"; }
{ subnet = "2001:3990:3990::/64"; gateway = "2001:3990:3990::1"; }
{
subnet = "2001:3990:3990::/64";
gateway = "2001:3990:3990::1";
}
];
};
};

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
cfg = config.cloud.gotosocial;
@ -41,13 +46,21 @@ in
# Postgres
cloud.postgresql.databases = [ dbUser ];
# Traefik
cloud.traefik.hosts = { gotosocial = { inherit (cfg) host port; }; } //
(if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then {
gotosocial-wellknown = {
inherit (cfg) port;
filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))";
};
} else { });
cloud.traefik.hosts =
{
gotosocial = { inherit (cfg) host port; };
}
// (
if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then
{
gotosocial-wellknown = {
inherit (cfg) port;
filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))";
};
}
else
{ }
);
# The service itself
services.gotosocial = {
enable = true;
@ -60,7 +73,10 @@ in
bind-address = "localhost";
port = cfg.port;
# Instance
instance-languages = [ "en-ca" "vi" ];
instance-languages = [
"en-ca"
"vi"
];
# Accounts
accounts-registration-open = false;
accounts-allow-custom-css = true;
@ -73,15 +89,23 @@ in
web-template-base-dir = "${cfg.package}/share/gotosocial/web/template";
web-asset-base-dir = "${cfg.package}/share/gotosocial/web/assets";
# Media
media-emoji-remote-max-size = 256 * 1024 /* bytes */;
media-emoji-local-max-size = 256 * 1024 /* bytes */;
media-emoji-remote-max-size =
256 * 1024 # bytes
;
media-emoji-local-max-size =
256 * 1024 # bytes
;
media-remote-cache-days = 7;
media-cleanup-from = "00:00";
media-cleanup-every = "24h";
# OIDC
oidc-enabled = true;
oidc-idp-name = "DTTH";
oidc-scopes = [ "openid" "email" "profile" ];
oidc-scopes = [
"openid"
"email"
"profile"
];
# HTTP Client
http-client.block-ips = [ "11.0.0.0/24" ];
# Advanced
@ -92,8 +116,14 @@ in
# instance-inject-mastodon-version = true;
};
};
systemd.services.gotosocial.requires = mkAfter [ "postgresql.service" "arion-authentik.service" ];
systemd.services.gotosocial.after = mkAfter [ "postgresql.service" "arion-authentik.service" ];
systemd.services.gotosocial.requires = mkAfter [
"postgresql.service"
"arion-authentik.service"
];
systemd.services.gotosocial.after = mkAfter [
"postgresql.service"
"arion-authentik.service"
];
systemd.services.gotosocial.unitConfig = {
RequiresMountsFor = [ storageLocation ];
ReadWritePaths = [ storageLocation ];

View file

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with lib;
let
@ -238,7 +243,12 @@ in
# MTA-STS server
services.nginx.enable = true;
services.nginx.virtualHosts.maddy-mta-sts = {
listen = [{ addr = "127.0.0.1"; port = mtaStsPort; }];
listen = [
{
addr = "127.0.0.1";
port = mtaStsPort;
}
];
root = mtaStsDir;
};
@ -273,7 +283,10 @@ in
# maddy itself
systemd.services."${name}" = {
after = [ "network.target" "traefik-certs-dumper.service" ];
after = [
"network.target"
"traefik-certs-dumper.service"
];
wantedBy = [ "multi-user.target" ];
requires = [ "postgresql.service" ];
@ -327,7 +340,6 @@ in
KillMode = "mixed";
KillSignal = "SIGTERM";
# Required to bind on ports lower than 1024.
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }:
{
pkgs,
lib,
config,
...
}:
with lib;
let
@ -9,126 +14,169 @@ let
};
# Copied from traefik.nix
jsonValue = with types;
jsonValue =
with types;
let
valueType = nullOr
(oneOf [
valueType =
nullOr (oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
]) // {
description = "JSON value";
emptyValue.value = { };
};
])
// {
description = "JSON value";
emptyValue.value = { };
};
in
valueType;
hostType = with types; submodule {
options = {
host = mkOption {
type = str;
description = "The host for the router filter";
};
path = mkOption {
type = nullOr str;
default = null;
description = "The path for the router filter (exact path is matched)";
};
filter = mkOption {
type = nullOr str;
default = null;
description = "The filter syntax for the router. Overrides `host` and `path` if provided";
};
localHost = mkOption {
type = types.nullOr types.str;
description = "The local host of the service. Must be an IP if protocol is TCP. Default to localhost/127.0.0.1";
default = null;
};
port = mkOption {
type = types.port;
description = "The port that the service is listening on";
};
entrypoints = mkOption {
type = listOf (enum [ "http" "https" "smtp-submission" "smtp-submission-ssl" "imap" "wireguard" ]);
default = [ "https" ];
description = "The entrypoints that will serve the host";
};
middlewares = mkOption {
type = listOf jsonValue;
default = [ ];
description = "The middlewares to be used with the host.";
};
protocol = mkOption {
type = enum [ "http" "tcp" "udp" ];
default = "http";
description = "The protocol of the router and service";
};
tlsPassthrough = mkOption {
type = types.bool;
default = true;
description = "Sets the TCP passthrough value. Defaults to `true` if the connection is tcp";
};
noCloudflare = mkOption {
type = types.bool;
default = false;
description = "Bypasses the client cert requirement, enable if you don't route things through cloudflare";
hostType =
with types;
submodule {
options = {
host = mkOption {
type = str;
description = "The host for the router filter";
};
path = mkOption {
type = nullOr str;
default = null;
description = "The path for the router filter (exact path is matched)";
};
filter = mkOption {
type = nullOr str;
default = null;
description = "The filter syntax for the router. Overrides `host` and `path` if provided";
};
localHost = mkOption {
type = types.nullOr types.str;
description = "The local host of the service. Must be an IP if protocol is TCP. Default to localhost/127.0.0.1";
default = null;
};
port = mkOption {
type = types.port;
description = "The port that the service is listening on";
};
entrypoints = mkOption {
type = listOf (enum [
"http"
"https"
"smtp-submission"
"smtp-submission-ssl"
"imap"
"wireguard"
]);
default = [ "https" ];
description = "The entrypoints that will serve the host";
};
middlewares = mkOption {
type = listOf jsonValue;
default = [ ];
description = "The middlewares to be used with the host.";
};
protocol = mkOption {
type = enum [
"http"
"tcp"
"udp"
];
default = "http";
description = "The protocol of the router and service";
};
tlsPassthrough = mkOption {
type = types.bool;
default = true;
description = "Sets the TCP passthrough value. Defaults to `true` if the connection is tcp";
};
noCloudflare = mkOption {
type = types.bool;
default = false;
description = "Bypasses the client cert requirement, enable if you don't route things through cloudflare";
};
};
};
};
# Returns the filter given a host configuration
filterOfHost = host:
filterOfHost =
host:
let
hostFilter = if host.protocol == "http" then "Host" else "HostSNI";
in
if host.filter != null then host.filter
else if host.path == null then "${hostFilter}(`${host.host}`)"
else "${hostFilter}(`${host.host}`) && Path(`${host.path}`)";
if host.filter != null then
host.filter
else if host.path == null then
"${hostFilter}(`${host.host}`)"
else
"${hostFilter}(`${host.host}`) && Path(`${host.path}`)";
# Turns a host configuration into dynamic traefik configuration
hostToConfig = name: host: {
"${host.protocol}" = {
routers."${name}-router" = (if (host.protocol != "udp") then {
rule = filterOfHost host;
tls = { certResolver = "le"; }
// (if host.protocol == "tcp" then { passthrough = if (host ? tlsPassthrough) then host.tlsPassthrough else true; } else { })
// (if host.noCloudflare then tlsNoCloudflare else { });
} else { }) // {
entryPoints = host.entrypoints;
service = "${name}-service";
} // (
if host.protocol == "http" then
{ middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares; }
else if host.middlewares == [ ] then
"${host.protocol}" =
{
routers."${name}-router" =
(
if (host.protocol != "udp") then
{
rule = filterOfHost host;
tls =
{
certResolver = "le";
}
// (
if host.protocol == "tcp" then
{ passthrough = if (host ? tlsPassthrough) then host.tlsPassthrough else true; }
else
{ }
)
// (if host.noCloudflare then tlsNoCloudflare else { });
}
else
{ }
)
// {
entryPoints = host.entrypoints;
service = "${name}-service";
}
// (
if host.protocol == "http" then
{ middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares; }
else if host.middlewares == [ ] then
{ }
else
abort "Cannot have middlewares on non-http routers"
);
services."${name}-service".loadBalancer.servers = [
(
let
localhost =
if isNull host.localHost then
(if host.protocol == "http" then "localhost" else "127.0.0.1")
else
host.localHost;
in
if host.protocol == "http" then
{ url = "http://${localhost}:${toString host.port}"; }
else
{ address = "${localhost}:${toString host.port}"; }
)
];
}
// (
if (host.middlewares != [ ]) then
{
middlewares = builtins.listToAttrs (
lists.imap0 (id: v: {
name = "${name}-middleware-${toString id}";
value = v;
}) host.middlewares
);
}
else
{ }
else abort "Cannot have middlewares on non-http routers"
);
services."${name}-service".loadBalancer.servers = [
(
let
localhost =
if isNull host.localHost then
(
if host.protocol == "http" then "localhost"
else "127.0.0.1"
) else host.localHost;
in
if host.protocol == "http" then
{ url = "http://${localhost}:${toString host.port}"; }
else { address = "${localhost}:${toString host.port}"; }
)
];
} // (if (host.middlewares != [ ]) then {
middlewares = builtins.listToAttrs (lists.imap0
(id: v: {
name = "${name}-middleware-${toString id}";
value = v;
})
host.middlewares);
} else { });
};
tlsConfig = {

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
@ -28,7 +33,8 @@ in
# Dynamic configuration
# ---------------------
## Middleware
services.traefik.dynamicConfigOptions.http.middlewares.dashboard-auth.basicAuth.usersFile = cfg.usersFile;
services.traefik.dynamicConfigOptions.http.middlewares.dashboard-auth.basicAuth.usersFile =
cfg.usersFile;
## Router
services.traefik.dynamicConfigOptions.http.routers.dashboard = {
rule = "Host(`${cfg.host}`)";

View file

@ -1,22 +1,29 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
# Copied from traefik.nix
jsonValue = with types;
jsonValue =
with types;
let
valueType = nullOr
(oneOf [
valueType =
nullOr (oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
]) // {
description = "JSON value";
emptyValue.value = { };
};
])
// {
description = "JSON value";
emptyValue.value = { };
};
in
valueType;
@ -41,7 +48,11 @@ let
cfg = config.cloud.traefik;
in
{
imports = [ ./config.nix ./dashboard.nix ./certs-dumper.nix ];
imports = [
./config.nix
./dashboard.nix
./certs-dumper.nix
];
options.cloud.traefik = {
cloudflareKeyFile = mkOption {
type = types.path;
@ -104,7 +115,12 @@ in
config.systemd.services.traefik.environment.CF_DNS_API_TOKEN_FILE = cfg.cloudflareKeyFile;
# Set up firewall to allow traefik traffic.
config.networking.firewall.allowedTCPPorts = [ 443 993 587 465 ];
config.networking.firewall.allowedTCPPorts = [
443
993
587
465
];
config.networking.firewall.allowedUDPPorts = [
443 # QUIC
51820 # Wireguard

View file

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with lib;
let
cfg = config.cloud.writefreely;
@ -62,4 +67,3 @@ in
}
);
}

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
@ -6,118 +11,142 @@ let
# Modules
modules = {
adb = { config, ... }: mkIf config.common.linux.enable {
services.udev.packages = with pkgs; [ android-udev-rules ];
programs.adb.enable = true;
users.users.${config.common.linux.username}.extraGroups = [ "adbusers" ];
};
ios = { config, pkgs, ... }: mkIf config.common.linux.enable {
services.usbmuxd.enable = true;
services.usbmuxd.package = pkgs.usbmuxd2;
environment.systemPackages = with pkgs; [
libimobiledevice
ifuse
];
users.users.${config.common.linux.username}.extraGroups = [ config.services.usbmuxd.group ];
systemd.network.networks."05-ios-tethering" = {
matchConfig.Driver = "ipheth";
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = "no";
adb =
{ config, ... }:
mkIf config.common.linux.enable {
services.udev.packages = with pkgs; [ android-udev-rules ];
programs.adb.enable = true;
users.users.${config.common.linux.username}.extraGroups = [ "adbusers" ];
};
};
graphics = { config, pkgs, ... }: {
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
# Monitor backlight
hardware.i2c.enable = true;
services.ddccontrol.enable = true;
environment.systemPackages = [ pkgs.luminance pkgs.ddcutil ];
};
accounts = { pkgs, ... }: mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
environment.systemPackages = [ pkgs.glib (pkgs.gnome-control-center or pkgs.gnome.gnome-control-center) ];
services.accounts-daemon.enable = true;
services.gnome.gnome-online-accounts.enable = true;
# programs.evolution.enable = true;
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
# services.gnome.evolution-data-server.enable = true;
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
};
wlr = { lib, config, ... }: mkIf config.common.linux.enable {
# swaync disable notifications on screencast
xdg.portal.wlr.settings.screencast = {
exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true'';
exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true'';
ios =
{ config, pkgs, ... }:
mkIf config.common.linux.enable {
services.usbmuxd.enable = true;
services.usbmuxd.package = pkgs.usbmuxd2;
environment.systemPackages = with pkgs; [
libimobiledevice
ifuse
];
users.users.${config.common.linux.username}.extraGroups = [ config.services.usbmuxd.group ];
systemd.network.networks."05-ios-tethering" = {
matchConfig.Driver = "ipheth";
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = "no";
};
};
# Niri stuff
# https://github.com/sodiboo/niri-flake/blob/main/docs.md
programs.niri.enable = true;
programs.niri.package = pkgs.niri-stable;
# Override gnome-keyring disabling
services.gnome.gnome-keyring.enable = lib.mkForce false;
};
logitech = { pkgs, ... }: mkIf cfg.enable {
services.ratbagd.enable = true;
environment.systemPackages = with pkgs; [ piper ];
};
kwallet = { pkgs, lib, ... }: mkIf cfg.enable {
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
xdg.portal = {
extraPortals = [ pkgs.kdePackages.kwallet ];
graphics =
{ config, pkgs, ... }:
{
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
# Monitor backlight
hardware.i2c.enable = true;
services.ddccontrol.enable = true;
environment.systemPackages = [
pkgs.luminance
pkgs.ddcutil
];
};
};
virtualisation = { pkgs, ... }: mkIf cfg.enable {
virtualisation.podman = {
accounts =
{ pkgs, ... }:
mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
environment.systemPackages = [
pkgs.glib
(pkgs.gnome-control-center or pkgs.gnome.gnome-control-center)
];
services.accounts-daemon.enable = true;
services.gnome.gnome-online-accounts.enable = true;
# programs.evolution.enable = true;
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
# services.gnome.evolution-data-server.enable = true;
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
};
wlr =
{ lib, config, ... }:
mkIf config.common.linux.enable {
# swaync disable notifications on screencast
xdg.portal.wlr.settings.screencast = {
exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true'';
exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true'';
};
# Niri stuff
# https://github.com/sodiboo/niri-flake/blob/main/docs.md
programs.niri.enable = true;
programs.niri.package = pkgs.niri-stable;
# Override gnome-keyring disabling
services.gnome.gnome-keyring.enable = lib.mkForce false;
};
logitech =
{ pkgs, ... }:
mkIf cfg.enable {
services.ratbagd.enable = true;
environment.systemPackages = with pkgs; [ piper ];
};
kwallet =
{ pkgs, lib, ... }:
mkIf cfg.enable {
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
xdg.portal = {
extraPortals = [ pkgs.kdePackages.kwallet ];
};
};
virtualisation =
{ pkgs, ... }:
mkIf cfg.enable {
virtualisation.podman = {
enable = true;
extraPackages = [ pkgs.slirp4netns ];
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
};
virtualisation.oci-containers.backend = "podman";
virtualisation.virtualbox.host.enable = false;
users.extraGroups.vboxusers.members = [ cfg.username ];
};
};
rt-audio =
{ pkgs, ... }:
mkIf cfg.enable {
services.pipewire.lowLatency = {
# enable this module
enable = true;
extraPackages = [ pkgs.slirp4netns ];
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
# defaults (no need to be set unless modified)
quantum = 32;
rate = 44100;
};
security.rtkit.enable = true;
virtualisation.oci-containers.backend = "podman";
virtualisation.virtualbox.host.enable = false;
users.extraGroups.vboxusers.members = [ cfg.username ];
# Real time configurations
boot.kernel.sysctl = {
"vm.swappiness" = 10;
"fs.inotify.max_user_watches" = 524288;
};
security.pam.loginLimits = [
{
domain = "@audio";
item = "rtprio";
type = "-";
value = "90";
}
{
domain = "@audio";
item = "memlock";
type = "-";
value = "unlimited";
}
];
};
};
rt-audio = { pkgs, ... }: mkIf cfg.enable {
services.pipewire.lowLatency = {
# enable this module
enable = true;
# defaults (no need to be set unless modified)
quantum = 32;
rate = 44100;
};
security.rtkit.enable = true;
# Real time configurations
boot.kernel.sysctl = {
"vm.swappiness" = 10;
"fs.inotify.max_user_watches" = 524288;
};
security.pam.loginLimits = [
{
domain = "@audio";
item = "rtprio";
type = "-";
value = "90";
}
{
domain = "@audio";
item = "memlock";
type = "-";
value = "unlimited";
}
];
};
in
{
imports = with modules; [
@ -155,23 +184,30 @@ in
dnsServers = mkOption {
type = types.listOf types.str;
description = "DNS server list";
default = [ "1.1.1.1" "2606:4700:4700:1111" ];
default = [
"1.1.1.1"
"2606:4700:4700:1111"
];
};
networks = mkOption {
type = types.attrsOf (types.submodule {
options.match = mkOption {
type = types.str;
description = "The interface name to match";
};
options.isRequired = mkOption {
type = types.bool;
description = "Require this interface to be connected for network-online.target";
default = false;
};
});
type = types.attrsOf (
types.submodule {
options.match = mkOption {
type = types.str;
description = "The interface name to match";
};
options.isRequired = mkOption {
type = types.bool;
description = "Require this interface to be connected for network-online.target";
default = false;
};
}
);
description = "Network configuration";
default = {
default = { match = "*"; };
default = {
match = "*";
};
};
};
};
@ -196,18 +232,16 @@ in
};
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
# LUKS devices
boot.initrd.luks.devices = builtins.mapAttrs
(name: path: {
device = path;
preLVM = true;
allowDiscards = true;
boot.initrd.luks.devices = builtins.mapAttrs (name: path: {
device = path;
preLVM = true;
allowDiscards = true;
crypttabExtraOpts = [
"tpm2-device=auto"
"fido2-device=auto"
];
})
cfg.luksDevices;
crypttabExtraOpts = [
"tpm2-device=auto"
"fido2-device=auto"
];
}) cfg.luksDevices;
## Hardware-related
@ -251,7 +285,10 @@ in
];
shell = pkgs.fish;
};
nix.settings.trusted-users = [ "root" cfg.username ];
nix.settings.trusted-users = [
"root"
cfg.username
];
## Network configuration
systemd.network.enable = true;
@ -262,13 +299,11 @@ in
networking.hostName = cfg.networking.hostname;
networking.wireless.iwd.enable = true;
networking.wireless.iwd.settings.General.EnableNetworkConfiguration = true;
systemd.network.networks = builtins.mapAttrs
(name: cfg: {
matchConfig.Name = cfg.match;
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = if cfg.isRequired then "yes" else "no";
})
cfg.networking.networks;
systemd.network.networks = builtins.mapAttrs (name: cfg: {
matchConfig.Name = cfg.match;
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = if cfg.isRequired then "yes" else "no";
}) cfg.networking.networks;
# Leave DNS to systemd-resolved
services.resolved.enable = true;
services.resolved.domains = cfg.networking.dnsServers;
@ -285,19 +320,26 @@ in
console.keyMap = "jp106"; # Console key layout
i18n.defaultLocale = "ja_JP.UTF-8";
# Input methods (only fcitx5 works reliably on Wayland)
i18n.inputMethod = {
fcitx5.waylandFrontend = true;
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-unikey
fcitx5-gtk
];
} // (if config.system.nixos.release == "24.05" then {
enabled = "fcitx5";
} else {
enable = true;
type = "fcitx5";
});
i18n.inputMethod =
{
fcitx5.waylandFrontend = true;
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-unikey
fcitx5-gtk
];
}
// (
if config.system.nixos.release == "24.05" then
{
enabled = "fcitx5";
}
else
{
enable = true;
type = "fcitx5";
}
);
# Default packages
environment.systemPackages = with pkgs; [
@ -335,7 +377,10 @@ in
programs.gamescope = {
enable = true;
# capSysNice = true; # https://github.com/NixOS/nixpkgs/issues/351516
args = [ "--adaptive-sync" "--rt" ];
args = [
"--adaptive-sync"
"--rt"
];
};
## Services
@ -353,11 +398,22 @@ in
wlr.enable = true;
xdgOpenUsePortal = true;
# gtk portal needed to make gtk apps happy
extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde pkgs.xdg-desktop-portal-gtk ];
extraPortals = [
pkgs.kdePackages.xdg-desktop-portal-kde
pkgs.xdg-desktop-portal-gtk
];
config.sway.default = [ "wlr" "kde" "kwallet" ];
config.sway.default = [
"wlr"
"kde"
"kwallet"
];
config.niri = {
default = [ "kde" "gnome" "gtk" ];
default = [
"kde"
"gnome"
"gtk"
];
# "org.freedesktop.impl.portal.Access" = "gtk";
# "org.freedesktop.impl.portal.Notification" = "gtk";
"org.freedesktop.impl.portal.ScreenCast" = "gnome";

View file

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with lib;
let
@ -36,72 +41,89 @@ in
};
};
config = mkIf cfg.enable (builtins.seq
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (builtins.abort "one of the keys must be defined"))
(
let
networkName = "my-tinc";
config = mkIf cfg.enable (
builtins.seq
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (
builtins.abort "one of the keys must be defined"
))
(
let
networkName = "my-tinc";
myHost = builtins.getAttr cfg.hostName hosts;
myMeshIp = myHost.subnetAddr;
in
{
# Scripts that set up the tinc services
environment.etc = {
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
#!${pkgs.stdenv.shell}
${pkgs.nettools}/bin/ifconfig $INTERFACE ${myMeshIp} netmask 255.255.255.0
'';
"tinc/${networkName}/tinc-down".source = pkgs.writeScript "tinc-down-${networkName}" ''
#!${pkgs.stdenv.shell}
/run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
'';
};
myHost = builtins.getAttr cfg.hostName hosts;
myMeshIp = myHost.subnetAddr;
in
{
# Scripts that set up the tinc services
environment.etc = {
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
#!${pkgs.stdenv.shell}
${pkgs.nettools}/bin/ifconfig $INTERFACE ${myMeshIp} netmask 255.255.255.0
'';
"tinc/${networkName}/tinc-down".source = pkgs.writeScript "tinc-down-${networkName}" ''
#!${pkgs.stdenv.shell}
/run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
'';
};
# Allow the tinc service to call ifconfig without sudo password.
security.sudo.extraRules = [
{
users = [ "tinc.${networkName}" ];
commands = [
# Allow the tinc service to call ifconfig without sudo password.
security.sudo.extraRules = [
{
users = [ "tinc.${networkName}" ];
commands = [
{
command = "${pkgs.nettools}/bin/ifconfig";
options = [ "NOPASSWD" ];
}
];
}
];
# simple interface setup
# ----------------------
networking.interfaces."tinc.${networkName}".ipv4.addresses = [
{
address = myMeshIp;
prefixLength = 24;
}
];
# firewall
networking.firewall.allowedUDPPorts = [ 655 ];
networking.firewall.allowedTCPPorts = [ 655 ];
networking.firewall.interfaces."tinc.${networkName}" = {
allowedUDPPortRanges = [
{
command = "${pkgs.nettools}/bin/ifconfig";
options = [ "NOPASSWD" ];
from = 0;
to = 65535;
}
];
}
];
allowedTCPPortRanges = [
{
from = 0;
to = 65535;
}
];
};
# simple interface setup
# ----------------------
networking.interfaces."tinc.${networkName}".ipv4.addresses = [{ address = myMeshIp; prefixLength = 24; }];
# configure tinc service
# ----------------------
services.tinc.networks."${networkName}" = {
# firewall
networking.firewall.allowedUDPPorts = [ 655 ];
networking.firewall.allowedTCPPorts = [ 655 ];
networking.firewall.interfaces."tinc.${networkName}" = {
allowedUDPPortRanges = [{ from = 0; to = 65535; }];
allowedTCPPortRanges = [{ from = 0; to = 65535; }];
};
name = cfg.hostName; # who are we in this network.
debugLevel = 3; # the debug level for journal -u tinc.private
chroot = false; # otherwise addresses can't be a DNS
interfaceType = "tap"; # tun might also work.
# configure tinc service
# ----------------------
services.tinc.networks."${networkName}" = {
bindToAddress = "* ${toString cfg.bindPort}";
name = cfg.hostName; # who are we in this network.
ed25519PrivateKeyFile = cfg.ed25519PrivateKey;
rsaPrivateKeyFile = cfg.rsaPrivateKey;
debugLevel = 3; # the debug level for journal -u tinc.private
chroot = false; # otherwise addresses can't be a DNS
interfaceType = "tap"; # tun might also work.
bindToAddress = "* ${toString cfg.bindPort}";
ed25519PrivateKeyFile = cfg.ed25519PrivateKey;
rsaPrivateKeyFile = cfg.rsaPrivateKey;
settings.ExperimentalProtocol = "yes";
};
}
)
settings.ExperimentalProtocol = "yes";
};
}
)
);
}

View file

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with lib;
let
@ -6,30 +11,34 @@ let
cfg = config.services.my-tinc;
mapAttrs = f: attrs: builtins.listToAttrs (
map (name: { inherit name; value = f name (builtins.getAttr name attrs); }) (builtins.attrNames attrs)
);
mapAttrs =
f: attrs:
builtins.listToAttrs (
map (name: {
inherit name;
value = f name (builtins.getAttr name attrs);
}) (builtins.attrNames attrs)
);
in
{
config = mkIf cfg.enable {
# All hosts we know of
services.tinc.networks.my-tinc.hostSettings = mapAttrs
(name: host: {
addresses = if (host ? address) then [{ address = host.address; }] else [ ];
subnets = [{ address = host.subnetAddr; }];
rsaPublicKey = mkIf (host ? "rsaPublicKey") host.rsaPublicKey;
settings.Ed25519PublicKey = mkIf (host ? "ed25519PublicKey") host.ed25519PublicKey;
})
hosts;
services.tinc.networks.my-tinc.hostSettings = mapAttrs (name: host: {
addresses = if (host ? address) then [ { address = host.address; } ] else [ ];
subnets = [ { address = host.subnetAddr; } ];
rsaPublicKey = mkIf (host ? "rsaPublicKey") host.rsaPublicKey;
settings.Ed25519PublicKey = mkIf (host ? "ed25519PublicKey") host.ed25519PublicKey;
}) hosts;
# Add all of them to host
nki.services.edns = {
enable = true;
cloaking-rules =
(lib.attrsets.mapAttrs'
(name: host: { name = "${name}.tinc"; value = host.subnetAddr; })
hosts)
;
cloaking-rules = (
lib.attrsets.mapAttrs' (name: host: {
name = "${name}.tinc";
value = host.subnetAddr;
}) hosts
);
};
};
}

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }:
{
pkgs,
lib,
config,
...
}:
with lib;
let
@ -11,46 +16,76 @@ in
{
imports = [ ./mounting.nix ];
# Fonts
config.fonts = {
packages = with pkgs; mkForce [
noto-fonts-emoji-blob-bin
ibm-plex
nerd-fonts
noto-fonts
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk)
merriweather
corefonts
font-awesome
hack-font # for Plasma
];
} // (if pkgs.stdenv.isLinux then {
enableDefaultPackages = false;
fontconfig = {
defaultFonts = {
emoji = lib.mkBefore [ "Blobmoji" ];
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
monospace = lib.mkBefore [ "IBM Plex Mono" "Font Awesome 6 Free" "Symbols Nerd Font" "Blobmoji" "IBM Plex Sans JP" ];
};
localConf = ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<alias binding="same">
<family>system-ui</family>
<prefer>
<family>IBM Plex Sans</family>
<family>IBM Plex Sans JP</family>
<family>IBM Plex Sans KR</family>
<family>Blobmoji</family>
</prefer>
</alias>
</fontconfig>
'';
};
fontDir.enable = true;
} else { }) // (if pkgs.stdenv.isDarwin then {
fontDir.enable = true;
} else { });
config.fonts =
{
packages =
with pkgs;
mkForce [
noto-fonts-emoji-blob-bin
ibm-plex
nerd-fonts
noto-fonts
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk)
merriweather
corefonts
font-awesome
hack-font # for Plasma
];
}
// (
if pkgs.stdenv.isLinux then
{
enableDefaultPackages = false;
fontconfig = {
defaultFonts = {
emoji = lib.mkBefore [ "Blobmoji" ];
serif = lib.mkBefore [
"IBM Plex Serif"
"IBM Plex Sans JP"
"IBM Plex Sans KR"
"Blobmoji"
];
sansSerif = lib.mkBefore [
"IBM Plex Sans"
"IBM Plex Sans JP"
"IBM Plex Sans KR"
"Blobmoji"
];
monospace = lib.mkBefore [
"IBM Plex Mono"
"Font Awesome 6 Free"
"Symbols Nerd Font"
"Blobmoji"
"IBM Plex Sans JP"
];
};
localConf = ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<alias binding="same">
<family>system-ui</family>
<prefer>
<family>IBM Plex Sans</family>
<family>IBM Plex Sans JP</family>
<family>IBM Plex Sans KR</family>
<family>Blobmoji</family>
</prefer>
</alias>
</fontconfig>
'';
};
fontDir.enable = true;
}
else
{ }
)
// (
if pkgs.stdenv.isDarwin then
{
fontDir.enable = true;
}
else
{ }
);
}

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
lib.mkIf pkgs.stdenv.isLinux {
system.fsPackages = [ pkgs.bindfs ];
fileSystems =
@ -6,7 +11,11 @@ lib.mkIf pkgs.stdenv.isLinux {
mkRoSymBind = path: {
device = path;
fsType = "fuse.bindfs";
options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ];
options = [
"ro"
"resolve-symlinks"
"x-gvfs-hide"
];
};
aggregatedIcons = pkgs.buildEnv {
name = "system-icons";

View file

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with lib;
let

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
with lib;
let
@ -34,7 +39,10 @@ in
# Sources
sources.public_resolvers = {
urls = [ "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md" "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" ];
urls = [
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
"https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md"
];
cache_file = "/var/lib/dnscrypt-proxy/public_resolvers.md";
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
};
@ -44,14 +52,22 @@ in
# Anonymized DNS
anonymized_dns.routes = [
{ server_name = "*"; via = [ "anon-plan9-dns" "anon-v.dnscrypt.up-ipv4" ]; }
{
server_name = "*";
via = [
"anon-plan9-dns"
"anon-v.dnscrypt.up-ipv4"
];
}
];
anonymized_dns.skip_incompatible = true;
# Cloaking rules
cloaking_rules = pkgs.writeText "cloaking_rules.txt" (lib.strings.concatStringsSep
"\n"
(lib.attrsets.mapAttrsToList (name: ip: "${name} ${ip}") cfg.cloaking-rules));
cloaking_rules = pkgs.writeText "cloaking_rules.txt" (
lib.strings.concatStringsSep "\n" (
lib.attrsets.mapAttrsToList (name: ip: "${name} ${ip}") cfg.cloaking-rules
)
);
};
};
};

View file

@ -40,20 +40,24 @@ in
in
{
nix.distributedBuilds = true;
nix.buildMachines = lib.mapAttrsToList
(name: host: {
nix.buildMachines = lib.mapAttrsToList (
name: host:
{
hostName = host.host;
sshUser = build-user;
sshKey = cfg.privateKeyFile;
} // host.builder)
otherBuilders;
}
// host.builder
) otherBuilders;
users = mkIf (isBuilder host) {
users.${build-user} = {
description = "Nix build farm user";
group = build-user;
isNormalUser = true;
openssh.authorizedKeys.keys = lib.mapAttrsToList (_: host: ''from="${cfg.ipAddrs}" ${host.pubKey}'') otherHosts;
openssh.authorizedKeys.keys = lib.mapAttrsToList (
_: host: ''from="${cfg.ipAddrs}" ${host.pubKey}''
) otherHosts;
};
groups.${build-user} = { };
};
@ -62,5 +66,3 @@ in
}
);
}

View file

@ -10,10 +10,18 @@
builder = {
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUhiVTh2NlNBa0kyOTBCc1QzVG1IRVVJQWdXcVFyNm9jRmpjakRRczRoT2ggcm9vdEBrYWdhbWlQQwo=";
systems = [ "x86_64-linux" "aarch64-linux" ];
systems = [
"x86_64-linux"
"aarch64-linux"
];
maxJobs = 16;
speedFactor = 2;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
supportedFeatures = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
];
};
};
@ -28,10 +36,18 @@
builder = {
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUdOUlBCVFRkNTVVMXY1U1Jac0FjYVdhS3JGZTY0ZjIxOVViODVTQ2NWd28gcm9vdEBua2ktZnJhbWV3b3JrCg==";
systems = [ "x86_64-linux" "aarch64-linux" ];
systems = [
"x86_64-linux"
"aarch64-linux"
];
maxJobs = 16;
speedFactor = 3;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
supportedFeatures = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
];
};
};
}

View file

@ -1,6 +1,18 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with { inherit (lib) mkEnableOption mkOption types mkIf; };
with {
inherit (lib)
mkEnableOption
mkOption
types
mkIf
;
};
let
cfg = config.nki.services.nix-cache;

View file

@ -1,4 +1,9 @@
{ config, pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
with lib;
let
cfg = config.services.swaylock;