Massive nixfmt reformatting
This commit is contained in:
parent
fe4492f004
commit
b29ddd5e65
109 changed files with 4323 additions and 2368 deletions
|
@ -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
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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; {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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}`)";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.cloud.writefreely;
|
||||
|
@ -62,4 +67,3 @@ in
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{ }
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.swaylock;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue