at 25.11-pre 2.7 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 inherit (lib) 10 concatStringsSep 11 isBool 12 mapAttrs 13 mkEnableOption 14 mkIf 15 mkOption 16 mkPackageOption 17 mkRenamedOptionModule 18 types 19 ; 20 21 cfg = config.services.redlib; 22 23 args = concatStringsSep " " ([ 24 "--port ${toString cfg.port}" 25 "--address ${cfg.address}" 26 ]); 27 28 boolToString' = b: if b then "on" else "off"; 29in 30{ 31 imports = [ 32 (mkRenamedOptionModule 33 [ 34 "services" 35 "libreddit" 36 ] 37 [ 38 "services" 39 "redlib" 40 ] 41 ) 42 ]; 43 44 options = { 45 services.redlib = { 46 enable = mkEnableOption "Private front-end for Reddit"; 47 48 package = mkPackageOption pkgs "redlib" { }; 49 50 address = mkOption { 51 default = "0.0.0.0"; 52 example = "127.0.0.1"; 53 type = types.str; 54 description = "The address to listen on"; 55 }; 56 57 port = mkOption { 58 default = 8080; 59 example = 8000; 60 type = types.port; 61 description = "The port to listen on"; 62 }; 63 64 openFirewall = mkOption { 65 type = types.bool; 66 default = false; 67 description = "Open ports in the firewall for the redlib web interface"; 68 }; 69 70 settings = lib.mkOption { 71 type = lib.types.submodule { 72 freeformType = 73 with types; 74 attrsOf ( 75 nullOr (oneOf [ 76 bool 77 int 78 str 79 ]) 80 ); 81 options = { }; 82 }; 83 default = { }; 84 description = '' 85 See [GitHub](https://github.com/redlib-org/redlib/tree/main?tab=readme-ov-file#configuration) for available settings. 86 ''; 87 }; 88 }; 89 }; 90 91 config = mkIf cfg.enable { 92 systemd.packages = [ cfg.package ]; 93 systemd.services.redlib = { 94 wantedBy = [ "default.target" ]; 95 environment = mapAttrs (_: v: if isBool v then boolToString' v else toString v) cfg.settings; 96 serviceConfig = 97 { 98 ExecStart = [ 99 "" 100 "${lib.getExe cfg.package} ${args}" 101 ]; 102 } 103 // ( 104 if (cfg.port < 1024) then 105 { 106 AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; 107 CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; 108 } 109 else 110 { 111 # A private user cannot have process capabilities on the host's user 112 # namespace and thus CAP_NET_BIND_SERVICE has no effect. 113 PrivateUsers = true; 114 } 115 ); 116 }; 117 118 networking.firewall = mkIf cfg.openFirewall { 119 allowedTCPPorts = [ cfg.port ]; 120 }; 121 }; 122 123 meta = { 124 maintainers = with lib.maintainers; [ Guanran928 ]; 125 }; 126}