From f27974d3b4aa0af533539ce626622c7b6b53c3f5 Mon Sep 17 00:00:00 2001 From: Frede Braendstrup Date: Sat, 30 Aug 2025 17:59:37 +0200 Subject: [PATCH] shpool: init shpool module --- .../misc/news/2025/08/2025-08-30_18-07-19.nix | 11 +++ modules/services/shpool.nix | 98 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 modules/misc/news/2025/08/2025-08-30_18-07-19.nix create mode 100644 modules/services/shpool.nix diff --git a/modules/misc/news/2025/08/2025-08-30_18-07-19.nix b/modules/misc/news/2025/08/2025-08-30_18-07-19.nix new file mode 100644 index 000000000..004a95124 --- /dev/null +++ b/modules/misc/news/2025/08/2025-08-30_18-07-19.nix @@ -0,0 +1,11 @@ +{ + time = "2025-08-30T16:07:19+00:00"; + condition = true; + message = '' + A new module is available: 'services.shpool'. + + shpool is a service that enables session persistence by allowing the creation of named shell sessions owned by shpool so that the session is not lost if the connection drops. + + Read about it at https://github.com/shell-pool/shpool + ''; +} diff --git a/modules/services/shpool.nix b/modules/services/shpool.nix new file mode 100644 index 000000000..75760e50f --- /dev/null +++ b/modules/services/shpool.nix @@ -0,0 +1,98 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + getExe + mkEnableOption + mkIf + mkOption + mkPackageOption + ; + + cfg = config.services.shpool; + format = pkgs.formats.toml { }; +in +{ + meta.maintainers = with lib.maintainers; [ fredeb ]; + + options.services.shpool = { + enable = mkEnableOption "shpool"; + package = mkPackageOption pkgs "shpool" { nullable = true; }; + + settings = lib.mkOption { + type = format.type; + default = { }; + example = { + prompt_prefix = "[$SHPOOL_SESSION_NAME]"; + session_restore_mode.lines = 1000; + + keybinding = [ + { + binding = "Ctrl-a d"; + action = "detach"; + } + ]; + + motd = "never"; + }; + description = '' + Configuration to use for shpool. See + + for available options. + ''; + }; + + systemd = mkEnableOption "systemd service and socket for shpool" // mkOption { default = true; }; + }; + + config = mkIf cfg.enable { + + systemd.user = { + services.shpool = { + Unit = { + Description = "Shpool - Shell Session Pool"; + Requires = [ "shpool.socket" ]; + }; + + Service = { + Type = "simple"; + ExecStart = "${getExe cfg.package} daemon"; + KillMode = "mixed"; + TimeoutStopSec = "2s"; + SendSIGHUP = true; + }; + + Install = { + WantedBy = [ "default.target" ]; + }; + }; + + sockets.shpool = { + Unit = { + Description = "Shpool Shell Session Pooler"; + }; + + Socket = { + ListenStream = "%t/shpool/shpool.socket"; + SocketMode = "0600"; + RemoveOnStop = "yes"; + FlushPending = "yes"; + }; + Install = { + WantedBy = [ "sockets.target" ]; + }; + }; + }; + + home.packages = [ cfg.package ]; + + xdg.configFile = lib.mkIf (cfg.settings != { }) { + "shpool/config.toml".source = format.generate "config.toml" cfg.settings; + }; + }; +}