diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index 97e0ca92469f19..fc75f1f07e6dbb 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -81,6 +81,8 @@ - [duckdns](https://www.duckdns.org), free dynamic DNS. Available with [services.duckdns](options.html#opt-services.duckdns.enable) +- [gokapi](https://github.com/Forceu/Gokapi), Lightweight selfhosted Firefox Send alternative without public upload. AWS S3 supported. Available with [services.gokapi](options.html#opt-services.gokapi.enable) + - [nostr-rs-relay](https://git.sr.ht/~gheartsfield/nostr-rs-relay/), This is a nostr relay, written in Rust. Available as [services.nostr-rs-relay](options.html#opt-services.nostr-rs-relay.enable). - [Actual Budget](https://actualbudget.org/), a local-first personal finance app. Available as [services.actual](#opt-services.actual.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b5b6fd8c0e2fe8..af837bf3b01ef7 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1089,6 +1089,7 @@ ./services/networking/go-neb.nix ./services/networking/go-shadowsocks2.nix ./services/networking/gobgpd.nix + ./services/networking/gokapi.nix ./services/networking/gvpe.nix ./services/networking/hans.nix ./services/networking/harmonia.nix diff --git a/nixos/modules/services/networking/gokapi.nix b/nixos/modules/services/networking/gokapi.nix new file mode 100644 index 00000000000000..823b54593cdccd --- /dev/null +++ b/nixos/modules/services/networking/gokapi.nix @@ -0,0 +1,136 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.services.gokapi; + settingsFormat = pkgs.formats.json { }; + userSettingsFile = settingsFormat.generate "generated-config.json" cfg.settings; +in +{ + options.services.gokapi = { + enable = lib.mkEnableOption "Lightweight selfhosted Firefox Send alternative without public upload. AWS S3 supported."; + + mutableSettings = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Allow changes to the program config made by the program to persist between restarts. If disabled all required values must be set using nix, and all changes to config format over application updates must be resolved by user."; + }; + + package = lib.mkPackageOption pkgs "gokapi" { }; + + environment = lib.mkOption { + type = lib.types.submodule { + freeformType = lib.types.attrsOf (lib.types.either lib.types.str lib.types.int); + options = { + GOKAPI_CONFIG_DIR = lib.mkOption { + type = lib.types.str; + default = "%S/gokapi/config"; + description = "Sets the directory for the config file."; + }; + GOKAPI_CONFIG_FILE = lib.mkOption { + type = lib.types.str; + default = "config.json"; + description = "Sets the filename for the config file."; + }; + GOKAPI_DATA_DIR = lib.mkOption { + type = lib.types.str; + default = "%S/gokapi/data"; + description = "Sets the directory for the data."; + }; + GOKAPI_PORT = lib.mkOption { + type = lib.types.str; + default = "53842"; + description = "Sets the port of the service."; + }; + }; + }; + default = { }; + description = "Environment variables to be set for the gokapi service. Can use systemd specifiers. For full list see https://gokapi.readthedocs.io/en/latest/advanced.html#environment-variables"; + }; + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = settingsFormat.type; + options = { }; + }; + default = { }; + description = '' + Configuration settings for the generated config json file. + See https://gokapi.readthedocs.io/en/latest/advanced.html#config-json for more information + ''; + }; + settingsFile = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = '' + Path to config file to parse and append to settings. Largely useful for loading secrets from a file not in the nix store. Can use systemd specifiers. See https://gokapi.readthedocs.io/en/latest/advanced.html#config-json for more information + ''; + }; + + }; + + config = lib.mkIf cfg.enable { + systemd.services.gokapi = { + wantedBy = [ "default.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + inherit (cfg) environment; + unitConfig = { + Description = "gokapi service"; + }; + serviceConfig = { + ExecStartPre = + let + updateScript = lib.getExe ( + pkgs.writeShellApplication { + name = "merge-config"; + runtimeInputs = with pkgs; [ jq ]; + text = '' + echo "Running merge-config" + mutableSettings="$1" + statefulSettingsFile="$2" + settingsFile="$3" + if [ "$mutableSettings" == "true" ]; + then + if [ -f "$statefulSettingsFile" ]; then + echo "Updating stateful config file" + merged="$(jq -s '.[0] * .[1]' "$statefulSettingsFile" ${userSettingsFile})" + echo "$merged" > "$statefulSettingsFile" + fi + else + echo "Overwriting stateful config file" + mkdir -p "$(dirname "$statefulSettingsFile")" + cat ${userSettingsFile} > "$statefulSettingsFile" + fi + if [ "$settingsFile" != "null" ]; then + echo "Merging settings file into current stateful settings file" + merged="$(jq -s '.[0] * .[1]' "$statefulSettingsFile" "$settingsFile")" + echo "$merged" > "$statefulSettingsFile" + fi + ''; + } + ); + in + lib.strings.concatStringsSep " " [ + "${updateScript}" + (lib.boolToString cfg.mutableSettings) + "${cfg.environment.GOKAPI_CONFIG_DIR}/${cfg.environment.GOKAPI_CONFIG_FILE}" + (if (cfg.settingsFile == null) then "null" else cfg.settingsFile) + ]; + ExecStart = lib.getExe cfg.package; + RestartSec = 30; + DynamicUser = true; + PrivateTmp = true; + StateDirectory = "gokapi"; + CacheDirectory = "gokapi"; + Restart = "on-failure"; + }; + }; + }; + meta.maintainers = with lib.maintainers; [ + delliott + ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 56653b64e5c7b4..8cccb6196bceaa 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -397,6 +397,7 @@ in { gobgpd = handleTest ./gobgpd.nix {}; gocd-agent = handleTest ./gocd-agent.nix {}; gocd-server = handleTest ./gocd-server.nix {}; + gokapi = handleTest ./gokapi.nix {}; gollum = handleTest ./gollum.nix {}; gonic = handleTest ./gonic.nix {}; google-oslogin = handleTest ./google-oslogin {}; diff --git a/nixos/tests/gokapi.nix b/nixos/tests/gokapi.nix new file mode 100644 index 00000000000000..e6800ad6f34ca5 --- /dev/null +++ b/nixos/tests/gokapi.nix @@ -0,0 +1,26 @@ +import ./make-test-python.nix ( + { pkgs, lib, ... }: + let + port = 6000; + in + { + name = "gokapi"; + + meta.maintainers = with lib.maintainers; [ delliott ]; + + nodes.machine = + { pkgs, ... }: + { + services.gokapi = { + enable = true; + environment.GOKAPI_PORT = toString port; + }; + }; + + testScript = '' + machine.wait_for_unit("gokapi.service") + machine.wait_for_open_port(${toString port}) + machine.succeed("curl --fail http://localhost:${toString port}/") + ''; + } +)