{ depot, config, pkgs, lib, ... }: let cfg = config.my.services.seaweedfs; tomlFormat = pkgs.formats.toml {}; makeCommandLine' = prefix: options: let makeFlag = name: value: if builtins.isAttrs value then makeCommandLine' "${prefix}${name}." value else if builtins.isString value then "-${prefix}${name}=${lib.strings.escapeShellArg value}" else if builtins.isInt value then "-${prefix}${name}=${toString value}" else "-${name}"; optionsList = lib.attrsets.mapAttrsToList makeFlag options; in lib.strings.concatStringsSep " " optionsList; makeCommandLine = makeCommandLine' ""; commandLineType = lib.types.oneOf [ lib.types.bool lib.types.int lib.types.str (lib.types.attrsOf commandLineType) ]; in { options.my.services.seaweedfs = { package = lib.mkOption { type = lib.types.package; default = depot.nix.pkgs.seaweedfs; # pkgs.seaweedfs; }; securitySettings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; default = {}; }; filer = { enable = lib.mkEnableOption "SeaweedFS filer"; package = lib.mkOption { type = lib.types.package; }; earlyOptions = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; options = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; }; settings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; default = {}; }; notificationSettings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; default = {}; }; replicationSettings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; default = {}; }; }; master = { enable = lib.mkEnableOption "SeaweedFS master"; package = lib.mkOption { type = lib.types.package; }; earlyOptions = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; options = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; settings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; default = {}; }; }; volume = { enable = lib.mkEnableOption "SeaweedFS volume"; package = lib.mkOption { type = lib.types.package; }; earlyOptions = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; options = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; }; cli = { enable = lib.mkEnableOption "add SeaweedFS CLI"; package = lib.mkOption { type = lib.types.package; }; settings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; default = {}; }; }; sync = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { options = { package = lib.mkOption { type = lib.types.package; default = cfg.package; }; earlyOptions = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; options = lib.mkOption { type = lib.types.submodule { freeformType = commandLineType; }; default = {}; }; }; }); default = {}; }; }; config = lib.mkMerge [{ my.services.seaweedfs.master.package = lib.mkDefault cfg.package; my.services.seaweedfs.filer.package = lib.mkDefault cfg.package; my.services.seaweedfs.volume.package = lib.mkDefault cfg.package; my.services.seaweedfs.cli.package = lib.mkDefault cfg.package; } (lib.mkIf (cfg.filer.enable || cfg.master.enable || cfg.volume.enable) { environment.etc."seaweedfs/security.toml".source = tomlFormat.generate "seaweedfs-security.toml" cfg.securitySettings; my.services.seaweedfs.cli.enable = lib.mkDefault true; users.groups.seaweedfs = {}; systemd.targets.seaweedfs = { description = "SeaweedFS components"; wantedBy = [ "multi-user.target" ]; }; }) (lib.mkIf (cfg.cli.enable) { environment.systemPackages = [ cfg.cli.package ]; environment.etc."seaweedfs/shell.toml".source = tomlFormat.generate "seaweedfs-shell.toml" cfg.cli.settings; }) (lib.mkIf (cfg.filer.enable) { environment.etc."seaweedfs/filer.toml".source = tomlFormat.generate "seaweedfs-filer.toml" cfg.filer.settings; environment.etc."seaweedfs/notification.toml".source = tomlFormat.generate "seaweedfs-notification.toml" cfg.filer.notificationSettings; environment.etc."seaweedfs/replication.toml".source = tomlFormat.generate "seaweedfs-replication.toml" cfg.filer.replicationSettings; my.services.seaweedfs.filer.options = { localSocket = lib.mkDefault "/run/seaweedfs-filer/filer.sock"; }; systemd.services."seaweedfs-filer" = { wantedBy = [ "seaweedfs.target" ]; restartTriggers = [ (config.environment.etc."seaweedfs/security.toml".source) (config.environment.etc."seaweedfs/filer.toml".source) (config.environment.etc."seaweedfs/notification.toml".source) (config.environment.etc."seaweedfs/replication.toml".source) ]; serviceConfig = { ExecStart = "${cfg.filer.package}/bin/weed ${makeCommandLine cfg.filer.earlyOptions} filer ${makeCommandLine cfg.filer.options}"; User = "seaweedfs-filer"; Group = "seaweedfs"; DynamicUser = true; RuntimeDirectory = "seaweedfs-filer"; StateDirectory = "seaweedfs-filer"; Restart = "always"; }; }; }) (lib.mkIf (cfg.master.enable) { environment.etc."seaweedfs/master.toml".source = tomlFormat.generate "seaweedfs-master.toml" cfg.master.settings; systemd.services."seaweedfs-master" = { wantedBy = [ "seaweedfs.target" ]; restartTriggers = [ (config.environment.etc."seaweedfs/security.toml".source) ]; serviceConfig = { ExecStart = "${cfg.master.package}/bin/weed ${makeCommandLine cfg.master.earlyOptions} master ${makeCommandLine cfg.master.options}"; User = "seaweedfs-master"; Group = "seaweedfs"; DynamicUser = true; RuntimeDirectory = "seaweedfs-master"; StateDirectory = "seaweedfs-master"; Restart = "always"; }; }; }) (lib.mkIf (cfg.volume.enable) { my.services.seaweedfs.volume.options = { dir = lib.mkDefault "/var/lib/seaweedfs-volume/data"; "dir.idx" = lib.mkDefault "/var/lib/seaweedfs-volume/idx"; }; systemd.services."seaweedfs-volume" = { wantedBy = [ "seaweedfs.target" ]; restartTriggers = [ (config.environment.etc."seaweedfs/security.toml".source) ]; serviceConfig = { ExecStart = "${cfg.volume.package}/bin/weed ${makeCommandLine cfg.volume.earlyOptions} volume ${makeCommandLine cfg.volume.options}"; User = "seaweedfs-volume"; Group = "seaweedfs"; DynamicUser = true; RuntimeDirectory = "seaweedfs-volume"; StateDirectory = "seaweedfs-volume"; Restart = "always"; }; }; }) { systemd.services = lib.mapAttrs' (k: v: lib.nameValuePair "seaweedfs-sync-${k}" { wantedBy = [ "seaweedfs.target" ]; unitConfig = { StartLimitIntervalSec = "0"; }; serviceConfig = { ExecStart = "${v.package}/bin/weed ${makeCommandLine v.earlyOptions} filer.sync ${makeCommandLine v.options}"; User = "seaweedfs-sync"; DynamicUser = true; Restart = "always"; RestartSec = "100ms"; RestartSteps = 10; RestartMaxDelaySec = "1min"; }; }) cfg.sync; }]; }