diff --git a/hosts/common/seaweedfs.nix b/hosts/common/seaweedfs.nix index 8ba32b2..8c40b34 100644 --- a/hosts/common/seaweedfs.nix +++ b/hosts/common/seaweedfs.nix @@ -1,14 +1,45 @@ -{ pkgs, ... }: +{ pkgs, config, ... }: +let + masters = [ "192.168.1.71:9333" "192.168.1.72:9333" "192.168.1.73:9333" ]; + master_enabled = true; #builtins.elem config.networking.hostName masters; +in { - environment.persistence."/persist".directories = [ - ]; + imports = [ ./seaweedfs_lib.nix ]; - environment.systemPackages = [ - pkgs.unstable.seaweedfs - ]; - - networking.firewall = { - allowedTCPPorts = [ ]; - allowedUDPPorts = [ ]; + services.seaweedfs.master = { + enable = master_enabled; + peers = masters; }; + services.seaweedfs.filer = { + enable = true; + master = masters; + }; + services.seaweedfs.volumes = { + default = { + enable = true; + mserver = masters; + dir = [ "/persist/weed/volume-default" ]; + }; + }; + + users.users.seaweedfs.group = "seaweedfs"; + users.groups.seaweedfs = {}; + + environment.persistence."/persist".directories = [ + "/var/lib/seaweedfs" + ]; + + networking.firewall.allowedTCPPorts = [ + config.services.seaweedfs.volumes.default.port + 9333 + 19333 + config.services.seaweedfs.filer.port + 8888 + 18888 +# ] ++ (if master_enabled then [ + config.services.seaweedfs.master.port + 9333 + 19333 +# ] else [ ]) + ]; } diff --git a/hosts/common/seaweedfs_lib.nix b/hosts/common/seaweedfs_lib.nix new file mode 100644 index 0000000..8105086 --- /dev/null +++ b/hosts/common/seaweedfs_lib.nix @@ -0,0 +1,183 @@ +# https://discourse.nixos.org/t/casual-nixpkgs-contributions/9607/11? + +{ config, lib, pkgs, ... }: +with lib; +let + + seaweedfs = pkgs.unstable.seaweedfs; + + user = "seaweedfs"; + group = "seaweedfs"; + cfg = config.services.seaweedfs; + enabledVolumes = filterAttrs (_: v: v.enable) cfg.volumes; + anyEnabled = cfg.master.enable || cfg.filer.enable || cfg.webdav.enable + || enabledVolumes != { }; + + mkCmdLineArguments = mapAttrsToList (option: value: + if isBool value then + "-${option}" + else + "-${option}=${ + if isList value then + builtins.concatStringsSep "," value + else + toString value + }"); + + mkWeedExec = subcmd: options: + (toString ([ "${seaweedfs}/bin/weed" subcmd ] ++ mkCmdLineArguments + ((removeAttrs options [ "enable" "extraConfig" ]) + // (if options ? "extraConfig" then + (removeAttrs options.extraConfig (builtins.attrNames options)) + else + { })))); + + mkExtraConfigOption = subcmd: + mkOption { + default = { }; + type = with types; attrs; + description = '' + Additional configuration, see output of 'weed ${subcmd} --help' for attributes. + Do not define settings for flags for which explicit configuration options exist, these will be ignored. + ''; + }; + + mkPortOption = defaultPort: + mkOption { + default = defaultPort; + type = with types; uniq port; + description = "Http listen port"; + }; + + mkServerListOption = subcmd: + mkOption { + default = [ "localhost:${toString cfg.${subcmd}.port}" ]; + type = with types; listOf str; + description = "List of ${subcmd} servers (host/ip:port)"; + }; + + mkVolumeService = id: options: + nameValuePair "seaweedfs-volume-${id}" { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ] + ++ optional cfg.master.enable "seaweedfs-master.service"; + description = "SeaweedFS volume - ${id}"; + unitConfig.ConditionPathIsDirectory = options.dir; + serviceConfig = { + User = user; + Group = group; + ExecStart = mkWeedExec "volume" options; + KillSignal = "SIGTERM"; + }; + }; + + mkVolumeOptions = { id, ... }: { + options = { + enable = mkEnableOption "SeaweedFS volume server"; + port = mkPortOption 8080; + mserver = mkServerListOption "master"; + extraConfig = mkExtraConfigOption "volume"; + + dir = mkOption { + default = [ "/tmp" ]; + type = with types; listOf path; + description = '' + One or more directories to store data files. + These must exist before the volume server service is started, + and must be owned by ${user}:${group}.''; + }; + }; + }; + +in { + + ###### interface + + options = { + services.seaweedfs = { + + master = { + enable = mkEnableOption "SeaweedFS master server"; + port = mkPortOption 9333; + peers = mkServerListOption "peers"; + extraConfig = mkExtraConfigOption "master"; + + }; + + filer = { + enable = mkEnableOption "SeaweedFS file server"; + port = mkPortOption 8888; + master = mkServerListOption "master"; + extraConfig = mkExtraConfigOption "filer"; + + }; + + volumes = mkOption { + default = { }; + type = with types; attrsOf (submodule mkVolumeOptions); + }; + + webdav = { + enable = mkEnableOption "SeaweedFS webdav server"; + port = mkPortOption 7333; + filer = mkServerListOption "filer"; + extraConfig = mkExtraConfigOption "webdav"; + + }; + }; + }; + + ###### implementation + + config = mkIf anyEnabled { + environment.systemPackages = [ seaweedfs ]; + users.users.${user} = { + description = "SeaweedFS user"; + isSystemUser = true; + }; + users.groups.${group} = { }; + systemd.services = (mapAttrs' mkVolumeService enabledVolumes) // { + seaweedfs-master = mkIf cfg.master.enable { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + description = "SeaweedFS master"; + serviceConfig = rec { + User = user; + Group = group; + StateDirectory = "seaweedfs/master"; + ExecStart = (mkWeedExec "master" cfg.master) + + " -mdir=/var/lib/${StateDirectory}"; + KillSignal = "SIGTERM"; + }; + }; + + seaweedfs-filer = mkIf cfg.filer.enable { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ] + ++ optional cfg.master.enable "seaweedfs-master.service"; + description = "SeaweedFS filer"; + serviceConfig = rec { + User = user; + Group = group; + WorkingDirectory = "/var/lib/${StateDirectory}"; + StateDirectory = "seaweedfs/filer"; + ExecStart = mkWeedExec "filer" cfg.filer; + KillSignal = "SIGTERM"; + }; + }; + + seaweedfs-webdav = mkIf cfg.webdav.enable { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ] + ++ optional cfg.filer.enable "seaweedfs-filer.service"; + description = "SeaweedFS webdav"; + serviceConfig = { + User = user; + Group = group; + ExecStart = mkWeedExec "webdav" cfg.webdav; + KillSignal = "SIGTERM"; + }; + }; + }; + }; +}