at 25.11-pre 4.0 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7 8let 9 cfg = config.services.olivetin; 10 11 settingsFormat = pkgs.formats.yaml { }; 12in 13 14{ 15 meta.maintainers = with lib.maintainers; [ defelo ]; 16 17 options.services.olivetin = { 18 enable = lib.mkEnableOption "OliveTin"; 19 20 package = lib.mkPackageOption pkgs "olivetin" { }; 21 22 user = lib.mkOption { 23 type = lib.types.str; 24 description = "The user account under which OliveTin runs."; 25 default = "olivetin"; 26 }; 27 28 group = lib.mkOption { 29 type = lib.types.str; 30 description = "The group under which OliveTin runs."; 31 default = "olivetin"; 32 }; 33 34 path = lib.mkOption { 35 type = 36 with lib.types; 37 listOf (oneOf [ 38 package 39 str 40 ]); 41 description = '' 42 Packages added to the service's {env}`PATH`. 43 ''; 44 defaultText = lib.literalExpression '' 45 with pkgs; [ bash ] 46 ''; 47 }; 48 49 settings = lib.mkOption { 50 description = '' 51 Configuration of OliveTin. See <https://docs.olivetin.app/config.html> for more information. 52 ''; 53 default = { }; 54 55 type = lib.types.submodule { 56 freeformType = settingsFormat.type; 57 58 options = { 59 ListenAddressSingleHTTPFrontend = lib.mkOption { 60 type = lib.types.str; 61 description = '' 62 The address to listen on for the internal "microproxy" frontend. 63 ''; 64 default = "127.0.0.1:8000"; 65 example = "0.0.0.0:8000"; 66 }; 67 }; 68 }; 69 }; 70 71 extraConfigFiles = lib.mkOption { 72 type = lib.types.listOf lib.types.path; 73 default = [ ]; 74 example = [ "/run/secrets/olivetin.yaml" ]; 75 description = '' 76 Config files to merge into the settings defined in [](#opt-services.olivetin.settings). 77 This is useful to avoid putting secrets into the nix store. 78 See <https://docs.olivetin.app/config.html> for more information. 79 ''; 80 }; 81 }; 82 83 config = lib.mkIf cfg.enable { 84 services.olivetin = { 85 path = with pkgs; [ bash ]; 86 }; 87 88 systemd.services.olivetin = { 89 description = "OliveTin"; 90 91 wantedBy = [ "multi-user.target" ]; 92 93 wants = [ 94 "network-online.target" 95 "local-fs.target" 96 ]; 97 after = [ 98 "network-online.target" 99 "local-fs.target" 100 ]; 101 102 inherit (cfg) path; 103 104 preStart = '' 105 tmp="$(mktemp -d)" 106 trap 'rm -rf "$tmp"' EXIT 107 cd "$tmp" 108 109 cp ${settingsFormat.generate "olivetin-config.yaml" cfg.settings} config.yaml 110 chmod +w config.yaml 111 for ((i=0; i < ${toString (lib.length cfg.extraConfigFiles)}; i++)); do 112 ${lib.getExe pkgs.yq} -yi ' 113 def merge($y): 114 . as $x | 115 if ($x | type == "object") and ($y | type == "object") then 116 $x + $y + with_entries(select(.key | in($y)) | .key as $key | .value |= merge($y[$key])) 117 elif ($x | type == "array") and ($y | type == "array") then 118 $x + $y 119 else 120 $y 121 end; 122 merge($f | fromjson) 123 ' config.yaml --rawfile f <(${lib.getExe pkgs.yq} -c . "$CREDENTIALS_DIRECTORY/config-$i.yaml") 124 done 125 chmod -w config.yaml 126 127 mkdir -p /run/olivetin/config 128 mv config.yaml /run/olivetin/config/config.yaml 129 ''; 130 131 serviceConfig = { 132 User = cfg.user; 133 Group = cfg.group; 134 RuntimeDirectory = "olivetin"; 135 Restart = "always"; 136 137 LoadCredential = lib.imap0 (i: path: "config-${toString i}.yaml:${path}") cfg.extraConfigFiles; 138 139 ExecStart = "${lib.getExe cfg.package} -configdir /run/olivetin/config"; 140 }; 141 }; 142 143 users.users = lib.mkIf (cfg.user == "olivetin") { 144 olivetin = { 145 group = cfg.group; 146 isSystemUser = true; 147 }; 148 }; 149 150 users.groups = lib.mkIf (cfg.group == "olivetin") { olivetin = { }; }; 151 }; 152}