my nix configs for my servers and desktop

weh

Changed files
+901 -26
home
regent
hosts
buer
focalor
modules
seaweedfs
+25 -25
flake.lock
···
"nixpkgs": "nixpkgs_2"
},
"locked": {
-
"lastModified": 1751021896,
-
"narHash": "sha256-L9u68mNPPiuW7+OV5BKbXaj/AENTiiuEx8+QnMBjRlU=",
"owner": "catppuccin",
"repo": "nix",
-
"rev": "a6b0e34d083c79f08efabb1fd6ccf12b882daae6",
"type": "github"
},
"original": {
···
]
},
"locked": {
-
"lastModified": 1751384836,
-
"narHash": "sha256-7xRbl/VLXxE5DzJmk1wdKWJmPx8rAfNC/a6mXtqp5cc=",
"owner": "nix-community",
"repo": "home-manager",
-
"rev": "479f8889675770881033878a1c114fbfc6de7a4d",
"type": "github"
},
"original": {
···
"spectrum": "spectrum"
},
"locked": {
-
"lastModified": 1750358184,
-
"narHash": "sha256-17EYMeY5v8KRk9HW6Z4dExY8Wg4y/zM2eM2wbbx+vMs=",
"owner": "astro",
"repo": "microvm.nix",
-
"rev": "fd9f5dba1ffee5ad6f29394b2a9e4c66c1ce77dc",
"type": "github"
},
"original": {
···
},
"nixos-hardware": {
"locked": {
-
"lastModified": 1751393906,
-
"narHash": "sha256-I1x6K61ZcdFlqc07weRBy3erCAB0lVkX10i0c9eXjDI=",
"owner": "nixos",
"repo": "nixos-hardware",
-
"rev": "f49bb3b4107a0917ee144337bb02d311033ee1ba",
"type": "github"
},
"original": {
···
},
"nixpkgs_2": {
"locked": {
-
"lastModified": 1744463964,
-
"narHash": "sha256-LWqduOgLHCFxiTNYi3Uj5Lgz0SR+Xhw3kr/3Xd0GPTM=",
"owner": "NixOS",
"repo": "nixpkgs",
-
"rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
"type": "github"
},
"original": {
···
},
"nixpkgs_3": {
"locked": {
-
"lastModified": 1751271578,
-
"narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=",
"owner": "nixos",
"repo": "nixpkgs",
-
"rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df",
"type": "github"
},
"original": {
···
"spectrum": {
"flake": false,
"locked": {
-
"lastModified": 1746869549,
-
"narHash": "sha256-BKZ/yZO/qeLKh9YqVkKB6wJiDQJAZNN5rk5NsMImsWs=",
"ref": "refs/heads/main",
-
"rev": "d927e78530892ec8ed389e8fae5f38abee00ad87",
-
"revCount": 862,
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
},
···
]
},
"locked": {
-
"lastModified": 1751383329,
-
"narHash": "sha256-52dUY8jEkuXEIZINYb+AVsrmw6FxMhBAG3K9J/2qiSo=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
-
"rev": "f29a4fece3b76c3e4579d67e2cf0cb8037f6a351",
"type": "github"
},
"original": {
···
"nixpkgs": "nixpkgs_2"
},
"locked": {
+
"lastModified": 1751705516,
+
"narHash": "sha256-Y099OGYWYHtpYFP4offuV6rldBnpUv4CYk+HwuaQwLU=",
"owner": "catppuccin",
"repo": "nix",
+
"rev": "719bb50ca2c99bc9c077669a48bfd9815493a11d",
"type": "github"
},
"original": {
···
]
},
"locked": {
+
"lastModified": 1751824240,
+
"narHash": "sha256-aDDC0CHTlL7QDKWWhdbEgVPK6KwWt+ca0QkmHYZxMzI=",
"owner": "nix-community",
"repo": "home-manager",
+
"rev": "fd9e55f5fac45a26f6169310afca64d56b681935",
"type": "github"
},
"original": {
···
"spectrum": "spectrum"
},
"locked": {
+
"lastModified": 1751732733,
+
"narHash": "sha256-MuaFFGHdShvGdHKrd3PUI2om+njixdG/1dGlglRdK8Q=",
"owner": "astro",
"repo": "microvm.nix",
+
"rev": "9d3d845ccb1a3f81747d027e95b110d4637468d0",
"type": "github"
},
"original": {
···
},
"nixos-hardware": {
"locked": {
+
"lastModified": 1751432711,
+
"narHash": "sha256-136MeWtckSHTN9Z2WRNRdZ8oRP3vyx3L8UxeBYE+J9w=",
"owner": "nixos",
"repo": "nixos-hardware",
+
"rev": "497ae1357f1ac97f1aea31a4cb74ad0d534ef41f",
"type": "github"
},
"original": {
···
},
"nixpkgs_2": {
"locked": {
+
"lastModified": 1750776420,
+
"narHash": "sha256-/CG+w0o0oJ5itVklOoLbdn2dGB0wbZVOoDm4np6w09A=",
"owner": "NixOS",
"repo": "nixpkgs",
+
"rev": "30a61f056ac492e3b7cdcb69c1e6abdcf00e39cf",
"type": "github"
},
"original": {
···
},
"nixpkgs_3": {
"locked": {
+
"lastModified": 1751637120,
+
"narHash": "sha256-xVNy/XopSfIG9c46nRmPaKfH1Gn/56vQ8++xWA8itO4=",
"owner": "nixos",
"repo": "nixpkgs",
+
"rev": "5c724ed1388e53cc231ed98330a60eb2f7be4be3",
"type": "github"
},
"original": {
···
"spectrum": {
"flake": false,
"locked": {
+
"lastModified": 1751265943,
+
"narHash": "sha256-XoHSo6GEElzRUOYAEg/jlh5c8TDsyDESFIux3nU/NMc=",
"ref": "refs/heads/main",
+
"rev": "37c8663fab86fdb202fece339ef7ac7177ffc201",
+
"revCount": 904,
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
},
···
]
},
"locked": {
+
"lastModified": 1751779188,
+
"narHash": "sha256-o1PidAPLtSSqI6isos6v/e6s7t3zQ56NBYhXVaUesXc=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
+
"rev": "b3200f40877a3e0a679070d96f8793a06105c06e",
"type": "github"
},
"original": {
+1 -1
home/regent/home.nix
···
height = 0;
output = [
"HDMI-A-1"
-
"DP-1"
"DP-2"
];
modules-left = [
···
height = 0;
output = [
"HDMI-A-1"
+
"DP-3"
"DP-2"
];
modules-left = [
+15
hosts/buer/default.nix
···
# CUSTOM MODULES
# =============================================================================
modules.garage.enable = true;
# =============================================================================
# BOOT CONFIGURATION
···
# CUSTOM MODULES
# =============================================================================
modules.garage.enable = true;
+
modules.seaweedfs.clusters.default = {
+
package = pkgs.seaweedfs;
+
+
masters.main = {
+
openFirewall = true;
+
ip = "fs.nkp.pet";
+
volumePreallocate = true;
+
+
defaultReplication = {
+
dataCenter = 0;
+
rack = 0;
+
server = 0;
+
};
+
};
+
};
# =============================================================================
# BOOT CONFIGURATION
+2
hosts/focalor/default.nix
···
environment.systemPackages = with pkgs; [
inputs.agenix.packages.x86_64-linux.default
prismlauncher
];
# =============================================================================
···
environment.systemPackages = with pkgs; [
inputs.agenix.packages.x86_64-linux.default
prismlauncher
+
temurin-bin
+
signal-desktop
];
# =============================================================================
+858
modules/seaweedfs/default.nix
···
···
+
/*https://hg.sr.ht/~dermetfan/seaweedfs-nixos/browse/seaweedfs.nix?rev=tip*/
+
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
let
+
cfg = config.modules.seaweedfs;
+
+
clusterModule = cluster: {
+
options = {
+
package = mkOption {
+
type = types.package;
+
default = pkgs.seaweedfs;
+
};
+
+
security.grpc = let
+
auth = mkOption {
+
type = with types; nullOr (submodule {
+
options = {
+
cert = mkOption { type = path; };
+
key = mkOption { type = path; };
+
};
+
});
+
default = null;
+
};
+
in {
+
ca = mkOption {
+
type = with types; nullOr str;
+
default = null;
+
};
+
+
master = auth;
+
volume = auth;
+
filer = auth;
+
client = auth;
+
msgBroker = auth;
+
};
+
+
masters = mkOption {
+
type = with types; attrsOf (submodule (masterModule cluster.config));
+
default = {};
+
description = "SeaweedFS masters";
+
};
+
+
volumes = mkOption {
+
type = with types; attrsOf (submodule (volumeModule cluster.config));
+
default = {};
+
description = "SeaweedFS volumes";
+
};
+
+
filers = mkOption {
+
type = with types; attrsOf (submodule (filerModule cluster.config));
+
default = {};
+
description = "SeaweedFS filers";
+
};
+
+
webdavs = mkOption {
+
type = with types; attrsOf (submodule (webdavModule cluster.config));
+
default = {};
+
description = "SeaweedFS WebDAV servers";
+
};
+
+
instances = mkOption {
+
type = with types; attrsOf (submodule instanceModule);
+
description = "SeaweedFS instances";
+
default =
+
mapAttrs' (name: master: nameValuePair
+
"master-${name}"
+
{
+
inherit (master) cluster configs;
+
+
command = "master";
+
+
args = with master;
+
[
+
"-port=${toString port}"
+
"-volumeSizeLimitMB=${toString volumeSizeLimitMB}"
+
] ++
+
optional (cpuprofile != "") "-cpuprofile=${cpuprofile}" ++
+
optional (defaultReplication != null) ("-defaultReplication=${defaultReplication.code}") ++
+
optional disableHttp "-disableHttp" ++
+
optional (garbageThreshold != "") "-garbageThreshold=${garbageThreshold}" ++
+
optional (ip != "") "-ip=${ip}" ++
+
optional (master."ip.bind" != "") "-ip.bind=${master."ip.bind"}" ++
+
optional (mdir != "") "-mdir=${mdir}" ++
+
optional (memprofile != "") "-memprofile=${memprofile}" ++
+
optional metrics.enable "-metrics.address=${metrics.address.text}" ++
+
optional (metrics.intervalSeconds != null) "-metrics.intervalSeconds=${toString metrics.intervalSeconds}" ++
+
optional (peers != []) ("-peers=" + (concatStringsSep "," (map (peer: peer.text) peers))) ++
+
optional resumeState "-resumeState" ++
+
optional volumePreallocate "-volumePreallocate" ++
+
optional (whiteList != []) ("-whiteList=" + (concatStringsSep "," whiteList));
+
}
+
) cluster.config.masters //
+
mapAttrs' (name: volume: nameValuePair
+
"volume-${name}"
+
{
+
inherit (volume) cluster configs;
+
+
command = "volume";
+
+
args = with volume;
+
[
+
"-port=${toString port}"
+
"-dir=${concatStringsSep "," dir}"
+
"-fileSizeLimitMB=${toString fileSizeLimitMB}"
+
"-idleTimeout=${toString idleTimeout}"
+
"-index=${index}"
+
"-minFreeSpacePercent=${toString minFreeSpacePercent}"
+
"-preStopSeconds=${toString preStopSeconds}"
+
] ++
+
optional (compactionMBps != null) ("-compactionMBps=${compactionMBps}") ++
+
optional (cpuprofile != "") "-cpuprofile=${cpuprofile}" ++
+
optional (dataCenter != "") "-dataCenter=${dataCenter}" ++
+
optional volume."images.fix.orientation" "-images.fix.orientation" ++
+
optional (ip != "") "-ip=${ip}" ++
+
optional (volume."ip.bind" != "") "-ip.bind=${volume."ip.bind"}" ++
+
optional (max != []) "-max=${concatStringsSep "," (map toString max)}" ++
+
optional (memprofile != "") "-memprofile=${memprofile}" ++
+
optional (metricsPort != null) "-metricsPort=${toString metricsPort}" ++
+
optional (mserver != []) ("-mserver=" + (concatStringsSep "," (map (mserver: mserver.text) mserver))) ++
+
optional (volume."port.public" != null) "-port.public=${toString volume."port.public"}" ++
+
optional pprof "-pprof" ++
+
optional (publicUrl != "") "-publicUrl=${publicUrl}" ++
+
optional (rack != "") "-rack=${rack}" ++
+
optional (!volume."read.redirect") "-read.redirect=false" ++
+
optional (whiteList != []) ("-whiteList=" + (concatStringsSep "," whiteList));
+
+
systemdService.preStart = "mkdir -p ${concatStringsSep " " volume.dir}";
+
}
+
) cluster.config.volumes //
+
mapAttrs' (name: filer: nameValuePair
+
"filer-${name}"
+
{
+
inherit (filer) cluster configs;
+
+
command = "filer";
+
+
args = with filer;
+
[
+
"-port=${toString port}"
+
"-dirListLimit=${toString dirListLimit}"
+
"-maxMB=${toString maxMB}"
+
] ++
+
optional (collection != "") "-collection=${collection}" ++
+
optional (dataCenter != "") "-dataCenter=${dataCenter}" ++
+
optional (defaultReplicaPlacement != null) ("-defaultReplicaPlacement=${defaultReplicaPlacement.code}") ++
+
optional disableDirListing "-disableDirListing" ++
+
optional disableHttp "-disableHttp" ++
+
optional encryptVolumeData "-encryptVolumeData" ++
+
optional (ip != "") "-ip=${ip}" ++
+
optional (filer."ip.bind" != "") "-ip.bind=${filer."ip.bind"}" ++
+
optional (master != []) ("-master=" + (concatStringsSep "," (map (master: master.text) master))) ++
+
optional (metricsPort != null) "-metricsPort=${toString metricsPort}" ++
+
optional (peers != []) ("-peers=" + (concatStringsSep "," (map (peer: peer.text) peers))) ++
+
optional (filer."port.readonly" != null) "-port.readonly=${toString filer."port.readonly"}" ++
+
optional (rack != "") "-rack=${rack}" ++
+
optionals s3.enable [
+
"-s3"
+
"-s3.port=${toString filer.s3.port}"
+
] ++
+
optional (s3.enable && s3."cert.file" != "") "-s3.cert.file=${s3."cert.file"}" ++
+
optional (s3.enable && s3."key.file" != "") "-s3.key.file=${s3."key.file"}" ++
+
optional (s3.enable && s3.config != "") "-s3.config=${s3.config}" ++
+
optional (s3.enable && s3.domainName != []) "-s3.domainName=${concatStringsSep "," s3.domainName}";
+
+
systemdService.preStart = let
+
conf = filer.configs.filer.leveldb2 or {};
+
in optionalString (conf ? "dir") "mkdir -p ${conf.dir}";
+
}
+
) cluster.config.filers //
+
mapAttrs' (name: webdav: nameValuePair
+
"webdav-${name}"
+
{
+
inherit (webdav) cluster;
+
+
command = "webdav";
+
+
args = with webdav;
+
[
+
"-port=${toString port}"
+
"-filer=${filer.text}"
+
"-cacheCapacityMB=${toString cacheCapacityMB}"
+
] ++
+
optional (collection != "") "-collection=${collection}" ++
+
optional (cacheDir != "") "-cacheDir=${cacheDir}";
+
}
+
) cluster.config.webdavs;
+
};
+
};
+
};
+
+
commonModule = cluster: common: {
+
options = {
+
cluster = mkOption {
+
type = types.submodule clusterModule;
+
internal = true;
+
};
+
+
openFirewall = mkEnableOption "open the firewall";
+
};
+
+
config = { inherit cluster; };
+
};
+
+
masterModule = cluster: master: {
+
imports = [ (commonModule cluster) ];
+
+
options = {
+
configs = mkOption {
+
type = with types; attrsOf attrs;
+
default.master.maintenance = {
+
scripts = ''
+
ec.encode -fullPercent=95 -quietFor=1h
+
ec.rebuild -force
+
ec.balance -force
+
volume.balance -force
+
volume.fix.replication
+
'';
+
sleep_minutes = 17;
+
};
+
};
+
+
cpuprofile = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
defaultReplication = mkOption {
+
type = types.submodule replicationModule;
+
default = {};
+
};
+
+
disableHttp = mkEnableOption "disable HTTP requests, gRPC only";
+
+
garbageThreshold = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
ip = mkOption {
+
type = types.str;
+
default = config.networking.hostName;
+
};
+
+
"ip.bind" = mkOption {
+
type = types.str;
+
default = "0.0.0.0";
+
};
+
+
mdir = mkOption {
+
type = types.str;
+
default = ".";
+
};
+
+
memprofile = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
metrics = {
+
enable = mkEnableOption "Prometheus";
+
+
address = mkOption {
+
type = types.submodule ipPortModule;
+
default = {};
+
};
+
+
intervalSeconds = mkOption {
+
type = types.ints.unsigned;
+
default = 15;
+
};
+
};
+
+
peers = mkOption {
+
type = peersType;
+
default = mapAttrsIpPort master.config.cluster.masters;
+
};
+
+
port = mkOption {
+
type = types.port;
+
default = 9333;
+
};
+
+
resumeState = mkEnableOption "resume previous state on master server";
+
+
volumePreallocate = mkEnableOption "preallocate disk space for volumes";
+
+
volumeSizeLimitMB = mkOption {
+
type = types.ints.unsigned;
+
default = 30000;
+
};
+
+
whiteList = mkOption {
+
type = with types; listOf str;
+
default = [];
+
};
+
};
+
};
+
+
volumeModule = cluster: volume: {
+
imports = [ (commonModule cluster) ];
+
+
options = {
+
configs = mkOption {
+
type = with types; attrsOf attrs;
+
default = {};
+
};
+
+
compactionMBps = mkOption {
+
type = with types; nullOr ints.unsigned;
+
default = null;
+
};
+
+
cpuprofile = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
dataCenter = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
dir = mkOption {
+
type = with types; listOf str;
+
default = [ "/var/lib/seaweedfs/${cluster._module.args.name}/volume-${volume.config._module.args.name}" ];
+
};
+
+
fileSizeLimitMB = mkOption {
+
type = types.ints.unsigned;
+
default = 256;
+
};
+
+
idleTimeout = mkOption{
+
type = types.ints.unsigned;
+
default = 30;
+
};
+
+
"images.fix.orientation" = mkEnableOption "adjustment of jpg orientation when uploading";
+
+
index = mkOption {
+
type = types.enum [
+
"memory"
+
"leveldb"
+
"leveldbMedium"
+
"leveldbLarge"
+
];
+
default = "memory";
+
};
+
+
ip = mkOption {
+
type = types.str;
+
default = config.networking.hostName;
+
};
+
+
"ip.bind" = mkOption {
+
type = types.str;
+
default = "0.0.0.0";
+
};
+
+
max = mkOption {
+
type = with types; listOf ints.unsigned;
+
default = [ 8 ];
+
};
+
+
memprofile = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
metricsPort = mkOption {
+
type = with types; nullOr port;
+
default = null;
+
};
+
+
minFreeSpacePercent = mkOption {
+
type = types.ints.unsigned;
+
default = 1;
+
};
+
+
mserver = mkOption {
+
type = peersType;
+
default = mapAttrsIpPort volume.config.cluster.masters;
+
};
+
+
port = mkOption {
+
type = types.port;
+
default = 8080;
+
};
+
+
"port.public" = mkOption {
+
type = with types; nullOr port;
+
default = null;
+
};
+
+
pprof = mkEnableOption "pprof http handlers. precludes -memprofile and -cpuprofile";
+
+
preStopSeconds = mkOption {
+
type = types.int;
+
default = 10;
+
};
+
+
publicUrl = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
rack = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
"read.redirect" = mkOption {
+
type = types.bool;
+
default = true;
+
};
+
+
whiteList = mkOption {
+
type = with types; listOf str;
+
default = [];
+
};
+
};
+
};
+
+
filerModule = cluster: filer: {
+
imports = [ (commonModule cluster) ];
+
+
options = {
+
configs = mkOption {
+
type = with types; attrsOf attrs;
+
default.filer.leveldb2 = {
+
enabled = true;
+
dir = "/var/lib/seaweedfs/${cluster._module.args.name}/filer-${filer.config._module.args.name}/filerldb2";
+
};
+
};
+
+
collection = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
dataCenter = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
defaultReplicaPlacement = mkOption {
+
type = with types; nullOr (submodule replicationModule);
+
default = null;
+
};
+
+
dirListLimit = mkOption {
+
type = types.ints.unsigned;
+
default = 100000;
+
};
+
+
disableDirListing = mkEnableOption "turn off directory listing";
+
+
disableHttp = mkEnableOption "disable http request, only gRpc operations are allowed";
+
+
encryptVolumeData = mkEnableOption "encrypt data on volume servers";
+
+
ip = mkOption {
+
type = types.str;
+
default = config.networking.hostName;
+
};
+
+
"ip.bind" = mkOption {
+
type = types.str;
+
default = "0.0.0.0";
+
};
+
+
master = mkOption {
+
type = peersType;
+
default = mapAttrsIpPort filer.config.cluster.masters;
+
};
+
+
maxMB = mkOption {
+
type = types.ints.unsigned;
+
default = 32;
+
};
+
+
metricsPort = mkOption {
+
type = with types; nullOr port;
+
default = null;
+
};
+
+
peers = mkOption {
+
type = peersType;
+
default = mapAttrsIpPort filer.config.cluster.filers;
+
};
+
+
port = mkOption {
+
type = types.port;
+
default = 8888;
+
};
+
+
"port.readonly" = mkOption {
+
type = with types; nullOr port;
+
default = null;
+
};
+
+
rack = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
s3 = {
+
enable = mkEnableOption "whether to start S3 gateway";
+
+
"cert.file" = mkOption {
+
type = types.path;
+
default = "";
+
};
+
+
config = mkOption {
+
type = types.path;
+
default = "";
+
};
+
+
domainName = mkOption {
+
type = with types; listOf str;
+
default = [];
+
};
+
+
"key.file" = mkOption {
+
type = types.path;
+
default = "";
+
};
+
+
port = mkOption {
+
type = types.port;
+
default = 8333;
+
};
+
};
+
};
+
};
+
+
webdavModule = cluster: webdav: {
+
imports = [ (commonModule cluster) ];
+
+
options = {
+
cacheCapacityMB = mkOption {
+
type = types.int;
+
default = 1000;
+
};
+
+
cacheDir = mkOption {
+
type = types.str;
+
default = ".";
+
};
+
+
collection = mkOption {
+
type = types.str;
+
default = "";
+
};
+
+
filer = mkOption {
+
type = types.submodule ipPortModule;
+
default = {
+
ip = "127.0.0.1";
+
port = 8888;
+
};
+
};
+
+
port = mkOption {
+
type = types.port;
+
default = 7333;
+
};
+
};
+
};
+
+
instanceModule = instance: {
+
options = {
+
cluster = mkOption {
+
type = types.submodule clusterModule;
+
internal = true;
+
};
+
+
command = mkOption {
+
type = types.enum [
+
"server"
+
"master"
+
"volume"
+
"mount"
+
"filer"
+
"filer.replicate"
+
"filer.sync"
+
"s3"
+
"msgBroker"
+
"watch"
+
"webdav"
+
];
+
};
+
+
logArgs = mkOption {
+
type = with types; listOf str;
+
default = [];
+
};
+
+
args = mkOption {
+
type = with types; listOf str;
+
default = [];
+
};
+
+
configs = mkOption {
+
type = with types; attrsOf attrs;
+
default = {};
+
};
+
+
package = mkOption {
+
type = types.package;
+
default = instance.config.cluster.package;
+
};
+
+
systemdService = mkOption {
+
type = types.attrs;
+
default = {};
+
};
+
};
+
+
config = {
+
logArgs = [ "-logtostderr" ];
+
+
systemdService.path = optional (instance.config.command == "mount") pkgs.fuse;
+
};
+
};
+
+
replicationModule = replication: {
+
options = {
+
dataCenter = mkOption {
+
type = types.ints.between 0 9;
+
default = 0;
+
};
+
+
rack = mkOption {
+
type = types.ints.between 0 9;
+
default = 0;
+
};
+
+
server = mkOption {
+
type = types.ints.between 0 9;
+
default = 0;
+
};
+
+
code = mkOption {
+
readOnly = true;
+
internal = true;
+
type = types.str;
+
default = with replication.config; "${toString dataCenter}${toString rack}${toString server}";
+
};
+
};
+
};
+
+
peersType = with types; listOf (submodule ipPortModule);
+
+
ipPortModule = ipPort: {
+
options = {
+
ip = mkOption {
+
type = types.str;
+
};
+
+
port = mkOption {
+
type = types.port;
+
};
+
+
text = mkOption {
+
internal = true;
+
readOnly = true;
+
type = types.str;
+
default = with ipPort.config; "${ip}:${toString port}";
+
};
+
};
+
};
+
+
mapAttrsIpPort = attrs: mapAttrsToList (name: value: { inherit (value) ip port; }) attrs;
+
+
toTOML = with generators; toINI {
+
mkKeyValue = mkKeyValueDefault {
+
mkValueString = v:
+
if isString v
+
then (
+
if hasInfix "\n" v
+
then ''
+
"""
+
${removeSuffix "\n" v}
+
"""
+
''
+
else ''"${v}"''
+
)
+
else mkValueStringDefault {} v;
+
} "=";
+
};
+
+
flattenAttrs = separator: attrs: let
+
/*
+
attrs = {
+
a = {
+
m1 = {};
+
m2 = {};
+
};
+
b = {
+
m1 = {};
+
};
+
}
+
*/
+
+
/*
+
step1 = {
+
a = [
+
{ name = "a-m1"; value = {}; }
+
{ name = "a-m2"; value = {}; }
+
];
+
b = [
+
{ name = "b-m1"; value = {}; }
+
];
+
};
+
*/
+
step1 = mapAttrs (outerName: outerValues:
+
mapAttrsToList (innerName: innerValues: nameValuePair
+
"${outerName}${separator}${innerName}"
+
innerValues
+
) outerValues
+
) attrs;
+
+
/*
+
step2 = [
+
[
+
{ name = "a-m1"; value = {}; }
+
{ name = "a-m2"; value = {}; }
+
]
+
[
+
{ name = "b-m1"; value = {}; }
+
]
+
];
+
*/
+
step2 = mapAttrsToList (name: value: value) step1;
+
+
/*
+
step3 = [
+
{ name = "a-m1"; value = {}; }
+
{ name = "a-m2"; value = {}; }
+
{ name = "b-m1"; value = {}; }
+
];
+
*/
+
step3 = flatten step2;
+
in
+
/*
+
{
+
a-m1 = {};
+
a-m2 = {};
+
b-m1 = {};
+
};
+
*/
+
builtins.listToAttrs step3;
+
in {
+
options.modules.seaweedfs = {
+
clusters = mkOption {
+
type = with types; attrsOf (submodule clusterModule);
+
default = {};
+
description = "SeaweedFS clusters";
+
};
+
};
+
+
config = {
+
systemd.services = mapAttrs'
+
(name: instance: nameValuePair "seaweedfs-${name}" instance)
+
(flattenAttrs "-" (
+
mapAttrs (clusterName: cluster:
+
mapAttrs (instanceName: instance: with instance; recursiveUpdate systemdService rec {
+
description = "SeaweedFS ${clusterName} ${instanceName}";
+
wants = [ "network.target" ];
+
after = wants;
+
wantedBy = [ "multi-user.target" ];
+
preStart = with serviceConfig; ''
+
${
+
let securityFile = config.environment.etc."seaweedfs/${clusterName}/security.toml";
+
in optionalString securityFile.enable "ln -s /etc/${securityFile.target} ${WorkingDirectory}/"
+
}
+
+
# TODO replace find usage with statically known condition
+
find -L /etc/${ConfigurationDirectory} -type f -exec ln -s '{}' ${WorkingDirectory}/ \;
+
+
${optionalString (systemdService ? preStart) systemdService.preStart}
+
'';
+
serviceConfig = rec {
+
ExecStart = "${package}/bin/weed ${concatStringsSep " " logArgs} ${command} ${concatStringsSep " " args}";
+
Restart = "on-failure";
+
Type = "exec";
+
ConfigurationDirectory = "seaweedfs/${clusterName}/${instanceName}";
+
RuntimeDirectory = ConfigurationDirectory;
+
RuntimeDirectoryPreserve = "restart";
+
WorkingDirectory = "/run/${RuntimeDirectory}";
+
};
+
}) cluster.instances
+
) cfg.clusters
+
));
+
+
environment.etc =
+
(mapAttrs' (name: cluster:
+
let file = "seaweedfs/${name}/security.toml";
+
in nameValuePair file {
+
enable = config.environment.etc.${file}.text != "";
+
text = with cluster.security.grpc; toTOML (
+
(if ca == null then {} else { grpc.ca = ca; }) //
+
(if master == null then {} else { "grpc.master" = { inherit (master) cert key; }; }) //
+
(if volume == null then {} else { "grpc.volume" = { inherit (volume) cert key; }; }) //
+
(if filer == null then {} else { "grpc.filer" = { inherit (filer) cert key; }; }) //
+
(if client == null then {} else { "grpc.client" = { inherit (client) cert key; }; }) //
+
(if msgBroker == null then {} else { "grpc.msg_broker" = { inherit (msgBroker) cert key; }; })
+
);
+
}
+
) cfg.clusters) //
+
(mapAttrs'
+
(name: config: nameValuePair
+
"seaweedfs/${name}.toml"
+
{ text = toTOML config; }
+
)
+
(flattenAttrs "/" (
+
mapAttrs (clusterName: cluster:
+
flattenAttrs "/" (
+
mapAttrs
+
(instanceName: instance: instance.configs)
+
cluster.instances
+
)
+
) cfg.clusters
+
))
+
);
+
+
networking.firewall.allowedTCPPorts = let
+
modulesToPorts = extraPorts: mapAttrsToList (name: module:
+
with module;
+
optionals openFirewall (
+
[ port (port + 10000) ] ++
+
(filter (p: p != null) (extraPorts module))
+
)
+
);
+
in flatten (mapAttrsToList (clusterName: cluster:
+
modulesToPorts
+
(master: [])
+
cluster.masters ++
+
+
modulesToPorts
+
(volume: with volume; [ metricsPort volume."port.public" ])
+
cluster.volumes ++
+
+
modulesToPorts
+
(filer: with filer; [ metricsPort filer."port.readonly" s3.port])
+
cluster.filers ++
+
+
modulesToPorts
+
(webdav: [])
+
cluster.webdavs
+
) cfg.clusters);
+
};
+
}