diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-03-22 16:41:59 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-03-22 16:41:59 +0100 |
commit | 46a88117a05c3469af5d99433af140c3de8ca088 (patch) | |
tree | d7f0557756d8f07a3081b3498c05ddc5a8ad429d /nixpkgs/nixos/modules/services/misc | |
parent | e97457545cea0b2ca421da257c83d8f1ef451d85 (diff) | |
parent | a343533bccc62400e8a9560423486a3b6c11a23b (diff) | |
download | nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.gz nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.bz2 nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.lz nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.xz nixlib-46a88117a05c3469af5d99433af140c3de8ca088.tar.zst nixlib-46a88117a05c3469af5d99433af140c3de8ca088.zip |
Merge commit 'a343533bccc62400e8a9560423486a3b6c11a23b'
Diffstat (limited to 'nixpkgs/nixos/modules/services/misc')
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/docker-registry.nix | 10 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/etebase-server.nix | 28 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix | 224 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/paperless.nix | 1 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/tabby.nix | 203 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/transfer-sh.nix | 102 |
6 files changed, 539 insertions, 29 deletions
diff --git a/nixpkgs/nixos/modules/services/misc/docker-registry.nix b/nixpkgs/nixos/modules/services/misc/docker-registry.nix index e8fbc05423d3..78d1d6339ed6 100644 --- a/nixpkgs/nixos/modules/services/misc/docker-registry.nix +++ b/nixpkgs/nixos/modules/services/misc/docker-registry.nix @@ -63,6 +63,12 @@ in { type = types.port; }; + openFirewall = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Opens the port used by the firewall."; + }; + storagePath = mkOption { type = types.nullOr types.path; default = "/var/lib/docker-registry"; @@ -154,5 +160,9 @@ in { isSystemUser = true; }; users.groups.docker-registry = {}; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.port ]; + }; }; } diff --git a/nixpkgs/nixos/modules/services/misc/etebase-server.nix b/nixpkgs/nixos/modules/services/misc/etebase-server.nix index 045048a1a2e3..f5a5e8a780d4 100644 --- a/nixpkgs/nixos/modules/services/misc/etebase-server.nix +++ b/nixpkgs/nixos/modules/services/misc/etebase-server.nix @@ -5,9 +5,6 @@ with lib; let cfg = config.services.etebase-server; - pythonEnv = pkgs.python3.withPackages (ps: with ps; - [ etebase-server daphne ]); - iniFmt = pkgs.formats.ini {}; configIni = iniFmt.generate "etebase-server.ini" cfg.settings; @@ -46,6 +43,13 @@ in ''; }; + package = mkOption { + type = types.package; + default = pkgs.python3.pkgs.etebase-server; + defaultText = literalExpression "pkgs.python3.pkgs.etebase-server"; + description = lib.mdDoc "etebase-server package to use."; + }; + dataDir = mkOption { type = types.str; default = "/var/lib/etebase-server"; @@ -164,7 +168,7 @@ in (runCommand "etebase-server" { nativeBuildInputs = [ makeWrapper ]; } '' - makeWrapper ${pythonEnv}/bin/etebase-server \ + makeWrapper ${cfg.package}/bin/etebase-server \ $out/bin/etebase-server \ --chdir ${escapeShellArg cfg.dataDir} \ --prefix ETEBASE_EASY_CONFIG_PATH : "${configIni}" @@ -178,8 +182,8 @@ in systemd.services.etebase-server = { description = "An Etebase (EteSync 2.0) server"; after = [ "network.target" "systemd-tmpfiles-setup.service" ]; + path = [ cfg.package ]; wantedBy = [ "multi-user.target" ]; - path = [ pythonEnv ]; serviceConfig = { User = cfg.user; Restart = "always"; @@ -187,24 +191,26 @@ in }; environment = { ETEBASE_EASY_CONFIG_PATH = configIni; + PYTHONPATH = cfg.package.pythonPath; }; preStart = '' # Auto-migrate on first run or if the package has changed versionFile="${cfg.dataDir}/src-version" - if [[ $(cat "$versionFile" 2>/dev/null) != ${pkgs.etebase-server} ]]; then + if [[ $(cat "$versionFile" 2>/dev/null) != ${cfg.package} ]]; then etebase-server migrate --no-input etebase-server collectstatic --no-input --clear - echo ${pkgs.etebase-server} > "$versionFile" + echo ${cfg.package} > "$versionFile" fi ''; script = let + python = cfg.package.python; networking = if cfg.unixSocket != null - then "-u ${cfg.unixSocket}" - else "-b 0.0.0.0 -p ${toString cfg.port}"; + then "--uds ${cfg.unixSocket}" + else "--host 0.0.0.0 --port ${toString cfg.port}"; in '' - cd "${pythonEnv}/lib/etebase-server"; - daphne ${networking} \ + ${python.pkgs.uvicorn}/bin/uvicorn ${networking} \ + --app-dir ${cfg.package}/${cfg.package.python.sitePackages} \ etebase_server.asgi:application ''; }; diff --git a/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix b/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix index 07a09e2b6bbf..02f1378cb0d5 100644 --- a/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix +++ b/nixpkgs/nixos/modules/services/misc/homepage-dashboard.nix @@ -6,6 +6,8 @@ let cfg = config.services.homepage-dashboard; + # Define the settings format used for this program + settingsFormat = pkgs.formats.yaml { }; in { options = { @@ -25,31 +27,217 @@ in default = 8082; description = lib.mdDoc "Port for Homepage to bind to."; }; + + environmentFile = lib.mkOption { + type = lib.types.str; + description = '' + The path to an environment file that contains environment variables to pass + to the homepage-dashboard service, for the purpose of passing secrets to + the service. + + See the upstream documentation: + + https://gethomepage.dev/latest/installation/docker/#using-environment-secrets + ''; + default = ""; + }; + + customCSS = lib.mkOption { + type = lib.types.lines; + description = lib.mdDoc '' + Custom CSS for styling Homepage. + + See https://gethomepage.dev/latest/configs/custom-css-js/. + ''; + default = ""; + }; + + customJS = lib.mkOption { + type = lib.types.lines; + description = lib.mdDoc '' + Custom Javascript for Homepage. + + See https://gethomepage.dev/latest/configs/custom-css-js/. + ''; + default = ""; + }; + + bookmarks = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage bookmarks configuration. + + See https://gethomepage.dev/latest/configs/bookmarks/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/bookmarks.yaml + example = [ + { + Developer = [ + { Github = [{ abbr = "GH"; href = "https://github.com/"; }]; } + ]; + } + { + Entertainment = [ + { YouTube = [{ abbr = "YT"; href = "https://youtube.com/"; }]; } + ]; + } + ]; + default = [ ]; + }; + + services = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage services configuration. + + See https://gethomepage.dev/latest/configs/services/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/services.yaml + example = [ + { + "My First Group" = [ + { + "My First Service" = { + href = "http://localhost/"; + description = "Homepage is awesome"; + }; + } + ]; + } + { + "My Second Group" = [ + { + "My Second Service" = { + href = "http://localhost/"; + description = "Homepage is the best"; + }; + } + ]; + } + ]; + default = [ ]; + }; + + widgets = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage widgets configuration. + + See https://gethomepage.dev/latest/configs/service-widgets/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/widgets.yaml + example = [ + { + resources = { + cpu = true; + memory = true; + disk = "/"; + }; + } + { + search = { + provider = "duckduckgo"; + target = "_blank"; + }; + } + ]; + default = [ ]; + }; + + kubernetes = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage kubernetes configuration. + + See https://gethomepage.dev/latest/configs/kubernetes/. + ''; + default = { }; + }; + + docker = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage docker configuration. + + See https://gethomepage.dev/latest/configs/docker/. + ''; + default = { }; + }; + + settings = lib.mkOption { + inherit (settingsFormat) type; + description = lib.mdDoc '' + Homepage settings. + + See https://gethomepage.dev/latest/configs/settings/. + ''; + # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/settings.yaml + default = { }; + }; }; }; - config = lib.mkIf cfg.enable { - systemd.services.homepage-dashboard = { - description = "Homepage Dashboard"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; + config = + let + # If homepage-dashboard is enabled, but none of the configuration values have been updated, + # then default to "unmanaged" configuration which is manually updated in + # var/lib/homepage-dashboard. This is to maintain backwards compatibility, and should be + # deprecated in a future release. + managedConfig = !( + cfg.bookmarks == [ ] && + cfg.customCSS == "" && + cfg.customJS == "" && + cfg.docker == { } && + cfg.kubernetes == { } && + cfg.services == [ ] && + cfg.settings == { } && + cfg.widgets == [ ] + ); + + configDir = if managedConfig then "/etc/homepage-dashboard" else "/var/lib/homepage-dashboard"; + + msg = "using unmanaged configuration for homepage-dashboard is deprecated and will be removed" + + " in 24.05. please see the NixOS documentation for `services.homepage-dashboard' and add" + + " your bookmarks, services, widgets, and other configuration using the options provided."; + in + lib.mkIf cfg.enable { + warnings = lib.optional (!managedConfig) msg; - environment = { - HOMEPAGE_CONFIG_DIR = "/var/lib/homepage-dashboard"; - PORT = "${toString cfg.listenPort}"; + environment.etc = lib.mkIf managedConfig { + "homepage-dashboard/custom.css".text = cfg.customCSS; + "homepage-dashboard/custom.js".text = cfg.customJS; + + "homepage-dashboard/bookmarks.yaml".source = settingsFormat.generate "bookmarks.yaml" cfg.bookmarks; + "homepage-dashboard/docker.yaml".source = settingsFormat.generate "docker.yaml" cfg.docker; + "homepage-dashboard/kubernetes.yaml".source = settingsFormat.generate "kubernetes.yaml" cfg.kubernetes; + "homepage-dashboard/services.yaml".source = settingsFormat.generate "services.yaml" cfg.services; + "homepage-dashboard/settings.yaml".source = settingsFormat.generate "settings.yaml" cfg.settings; + "homepage-dashboard/widgets.yaml".source = settingsFormat.generate "widgets.yaml" cfg.widgets; }; - serviceConfig = { - Type = "simple"; - DynamicUser = true; - StateDirectory = "homepage-dashboard"; - ExecStart = "${lib.getExe cfg.package}"; - Restart = "on-failure"; + systemd.services.homepage-dashboard = { + description = "Homepage Dashboard"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + HOMEPAGE_CONFIG_DIR = configDir; + PORT = toString cfg.listenPort; + LOG_TARGETS = lib.mkIf managedConfig "stdout"; + }; + + serviceConfig = { + Type = "simple"; + DynamicUser = true; + EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; + StateDirectory = lib.mkIf (!managedConfig) "homepage-dashboard"; + ExecStart = lib.getExe cfg.package; + Restart = "on-failure"; + }; }; - }; - networking.firewall = lib.mkIf cfg.openFirewall { - allowedTCPPorts = [ cfg.listenPort ]; + networking.firewall = lib.mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.listenPort ]; + }; }; - }; } diff --git a/nixpkgs/nixos/modules/services/misc/paperless.nix b/nixpkgs/nixos/modules/services/misc/paperless.nix index ab042e4b6ee2..9314c4f3848d 100644 --- a/nixpkgs/nixos/modules/services/misc/paperless.nix +++ b/nixpkgs/nixos/modules/services/misc/paperless.nix @@ -342,6 +342,7 @@ in User = cfg.user; Restart = "on-failure"; + LimitNOFILE = 65536; # gunicorn needs setuid, liblapack needs mbind SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "@setuid mbind" ]; # Needs to serve web page diff --git a/nixpkgs/nixos/modules/services/misc/tabby.nix b/nixpkgs/nixos/modules/services/misc/tabby.nix new file mode 100644 index 000000000000..a3072e5df75e --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/tabby.nix @@ -0,0 +1,203 @@ +{ config, lib, pkgs, ... }: +let + inherit (lib) types; + + cfg = config.services.tabby; + format = pkgs.formats.toml { }; + tabbyPackage = cfg.package.override { + inherit (cfg) acceleration; + }; +in +{ + options = { + services.tabby = { + enable = lib.mkEnableOption ( + lib.mdDoc "Self-hosted AI coding assistant using large language models" + ); + + package = lib.mkPackageOption pkgs "tabby" { }; + + port = lib.mkOption { + type = types.port; + default = 11029; + description = lib.mdDoc '' + Specifies the bind port on which the tabby server HTTP interface listens. + ''; + }; + + model = lib.mkOption { + type = types.str; + default = "TabbyML/StarCoder-1B"; + description = lib.mdDoc '' + Specify the model that tabby will use to generate completions. + + This model will be downloaded automatically if it is not already present. + + If you want to utilize an existing model that you've already + downloaded you'll need to move it into tabby's state directory which + lives in `/var/lib/tabby`. Because the tabby.service is configured to + use a DyanmicUser the service will need to have been started at least + once before you can move the locally existing model into + `/var/lib/tabby`. You can set the model to 'none' and tabby will + startup and fail to download a model, but will have created the + `/var/lib/tabby` directory. You can then copy over the model manually + into `/var/lib/tabby`, update the model option to the name you just + downloaded and copied over then `nixos-rebuild switch` to start using + it. + + $ tabby download --model TabbyML/DeepseekCoder-6.7B + $ find ~/.tabby/ | tail -n1 + /home/ghthor/.tabby/models/TabbyML/DeepseekCoder-6.7B/ggml/q8_0.v2.gguf + $ sudo rsync -r ~/.tabby/models/ /var/lib/tabby/models/ + $ sudo chown -R tabby:tabby /var/lib/tabby/models/ + + See for Model Options: + > https://github.com/TabbyML/registry-tabby + ''; + }; + + acceleration = lib.mkOption { + type = types.nullOr (types.enum [ "cpu" "rocm" "cuda" "metal" ]); + default = null; + example = "rocm"; + description = lib.mdDoc '' + Specifies the device to use for hardware acceleration. + + - `cpu`: no acceleration just use the CPU + - `rocm`: supported by modern AMD GPUs + - `cuda`: supported by modern NVIDIA GPUs + - `metal`: supported on darwin aarch64 machines + + Tabby will try and determine what type of acceleration that is + already enabled in your configuration when `acceleration = null`. + + - nixpkgs.config.cudaSupport + - nixpkgs.config.rocmSupport + - if stdenv.isDarwin && stdenv.isAarch64 + + IFF multiple acceleration methods are found to be enabled or if you + haven't set either `cudaSupport or rocmSupport` you will have to + specify the device type manually here otherwise it will default to + the first from the list above or to cpu. + ''; + }; + + settings = lib.mkOption { + inherit (format) type; + default = { }; + description = lib.mdDoc '' + Tabby scheduler configuration + + See for more details: + > https://tabby.tabbyml.com/docs/configuration/#repository-context-for-code-completion + ''; + example = lib.literalExpression '' + settings = { + repositories = [ + { name = "tabby"; git_url = "https://github.com/TabbyML/tabby.git"; } + { name = "CTranslate2"; git_url = "git@github.com:OpenNMT/CTranslate2.git"; } + + # local directory is also supported, but limited by systemd DynamicUser=1 + # adding local repositories will need to be done manually + { name = "repository_a"; git_url = "file:///var/lib/tabby/repository_a"; } + ]; + }; + ''; + }; + + usageCollection = lib.mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Enable sending anonymous usage data. + + See for more details: + > https://tabby.tabbyml.com/docs/configuration#usage-collection + ''; + }; + + indexInterval = lib.mkOption { + type = types.str; + default = "5hours"; + example = "5hours"; + description = lib.mdDoc '' + Run tabby scheduler to generate the index database at this interval. + Updates by default every 5 hours. This value applies to + `OnUnitInactiveSec` + + The format is described in + {manpage}`systemd.time(7)`. + + To disable running `tabby scheduler --now` updates, set to `"never"` + ''; + }; + }; + }; + + # TODO(ghthor): firewall config + + config = lib.mkIf cfg.enable { + environment = { + etc."tabby/config.toml".source = format.generate "config.toml" cfg.settings; + systemPackages = [ tabbyPackage ]; + }; + + + systemd = let + serviceUser = { + WorkingDirectory = "/var/lib/tabby"; + StateDirectory = [ "tabby" ]; + ConfigurationDirectory = [ "tabby" ]; + DynamicUser = true; + User = "tabby"; + Group = "tabby"; + }; + + serviceEnv = lib.mkMerge [ + { + TABBY_ROOT = "%S/tabby"; + } + (lib.mkIf (!cfg.usageCollection) { + TABBY_DISABLE_USAGE_COLLECTION = "1"; + }) + ]; + in { + services.tabby = { + wantedBy = [ "multi-user.target" ]; + description = "Self-hosted AI coding assistant using large language models"; + after = [ "network.target" ]; + environment = serviceEnv; + serviceConfig = lib.mkMerge [ + serviceUser + { + ExecStart = + "${lib.getExe tabbyPackage} serve --model ${cfg.model} --port ${toString cfg.port} --device ${tabbyPackage.featureDevice}"; + } + ]; + }; + + services.tabby-scheduler = lib.mkIf (cfg.indexInterval != "never") { + wantedBy = [ "multi-user.target" ]; + description = "Tabby repository indexing service"; + after = [ "network.target" ]; + environment = serviceEnv; + preStart = "cp -f /etc/tabby/config.toml \${TABBY_ROOT}/config.toml"; + serviceConfig = lib.mkMerge [ + serviceUser + { + # Type = "oneshot"; + ExecStart = "${lib.getExe tabbyPackage} scheduler --now"; + } + ]; + }; + timers.tabby-scheduler = lib.mkIf (cfg.indexInterval != "never") { + description = "Update timer for tabby-scheduler"; + partOf = [ "tabby-scheduler.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig.OnUnitInactiveSec = cfg.indexInterval; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ ghthor ]; +} diff --git a/nixpkgs/nixos/modules/services/misc/transfer-sh.nix b/nixpkgs/nixos/modules/services/misc/transfer-sh.nix new file mode 100644 index 000000000000..899d9dfc3c10 --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/transfer-sh.nix @@ -0,0 +1,102 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.transfer-sh; + inherit (lib) + mkDefault mkEnableOption mkPackageOption mkIf mkOption + types mapAttrs isBool getExe boolToString mdDoc optionalAttrs; +in +{ + options.services.transfer-sh = { + enable = mkEnableOption (mdDoc "Easy and fast file sharing from the command-line"); + + package = mkPackageOption pkgs "transfer-sh" { }; + + settings = mkOption { + type = types.submodule { freeformType = with types; attrsOf (oneOf [ bool int str ]); }; + default = { }; + example = { + LISTENER = ":8080"; + BASEDIR = "/var/lib/transfer.sh"; + TLS_LISTENER_ONLY = false; + }; + description = mdDoc '' + Additional configuration for transfer-sh, see + <https://github.com/dutchcoders/transfer.sh#usage-1> + for supported values. + + For secrets use secretFile option instead. + ''; + }; + + provider = mkOption { + type = types.enum [ "local" "s3" "storj" "gdrive" ]; + default = "local"; + description = mdDoc "Storage providers to use"; + }; + + secretFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/secrets/transfer-sh.env"; + description = mdDoc '' + Path to file containing environment variables. + Useful for passing down secrets. + Some variables that can be considered secrets are: + - AWS_ACCESS_KEY + - AWS_ACCESS_KEY + - TLS_PRIVATE_KEY + - HTTP_AUTH_HTPASSWD + ''; + }; + }; + + config = + let + localProvider = (cfg.provider == "local"); + stateDirectory = "/var/lib/transfer.sh"; + in + mkIf cfg.enable + { + services.transfer-sh.settings = { + LISTENER = mkDefault ":8080"; + } // optionalAttrs localProvider { + BASEDIR = mkDefault stateDirectory; + }; + + systemd.services.transfer-sh = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment = mapAttrs (_: v: if isBool v then boolToString v else toString v) cfg.settings; + serviceConfig = { + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + DevicePolicy = "closed"; + DynamicUser = true; + ExecStart = "${getExe cfg.package} --provider ${cfg.provider}"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = [ "native" ]; + SystemCallFilter = [ "@system-service" ]; + StateDirectory = baseNameOf stateDirectory; + } // optionalAttrs (cfg.secretFile != null) { + EnvironmentFile = cfg.secretFile; + } // optionalAttrs localProvider { + ReadWritePaths = cfg.settings.BASEDIR; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ ocfox ]; +} |