at 25.11-pre 3.2 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.services.kavita; 10 settingsFormat = pkgs.formats.json { }; 11 appsettings = settingsFormat.generate "appsettings.json" ( 12 { TokenKey = "@TOKEN@"; } // cfg.settings 13 ); 14in 15{ 16 imports = [ 17 (lib.mkChangedOptionModule 18 [ "services" "kavita" "ipAdresses" ] 19 [ "services" "kavita" "settings" "IpAddresses" ] 20 ( 21 config: 22 let 23 value = lib.getAttrFromPath [ "services" "kavita" "ipAdresses" ] config; 24 in 25 lib.concatStringsSep "," value 26 ) 27 ) 28 (lib.mkRenamedOptionModule [ "services" "kavita" "port" ] [ "services" "kavita" "settings" "Port" ]) 29 ]; 30 31 options.services.kavita = { 32 enable = lib.mkEnableOption "Kavita reading server"; 33 34 user = lib.mkOption { 35 type = lib.types.str; 36 default = "kavita"; 37 description = "User account under which Kavita runs."; 38 }; 39 40 package = lib.mkPackageOption pkgs "kavita" { }; 41 42 dataDir = lib.mkOption { 43 default = "/var/lib/kavita"; 44 type = lib.types.str; 45 description = "The directory where Kavita stores its state."; 46 }; 47 48 tokenKeyFile = lib.mkOption { 49 type = lib.types.path; 50 description = '' 51 A file containing the TokenKey, a secret with at 512+ bits. 52 It can be generated with `head -c 64 /dev/urandom | base64 --wrap=0`. 53 ''; 54 }; 55 56 settings = lib.mkOption { 57 default = { }; 58 description = '' 59 Kavita configuration options, as configured in {file}`appsettings.json`. 60 ''; 61 type = lib.types.submodule { 62 freeformType = settingsFormat.type; 63 64 options = { 65 Port = lib.mkOption { 66 default = 5000; 67 type = lib.types.port; 68 description = "Port to bind to."; 69 }; 70 71 IpAddresses = lib.mkOption { 72 default = "0.0.0.0,::"; 73 type = lib.types.commas; 74 description = '' 75 IP Addresses to bind to. The default is to bind to all IPv4 and IPv6 addresses. 76 ''; 77 }; 78 }; 79 }; 80 }; 81 }; 82 83 config = lib.mkIf cfg.enable { 84 systemd.services.kavita = { 85 description = "Kavita"; 86 wantedBy = [ "multi-user.target" ]; 87 after = [ "network.target" ]; 88 preStart = '' 89 install -m600 ${appsettings} ${lib.escapeShellArg cfg.dataDir}/config/appsettings.json 90 ${pkgs.replace-secret}/bin/replace-secret '@TOKEN@' \ 91 ''${CREDENTIALS_DIRECTORY}/token \ 92 '${cfg.dataDir}/config/appsettings.json' 93 ''; 94 serviceConfig = { 95 WorkingDirectory = cfg.dataDir; 96 LoadCredential = [ "token:${cfg.tokenKeyFile}" ]; 97 ExecStart = lib.getExe cfg.package; 98 Restart = "always"; 99 User = cfg.user; 100 }; 101 }; 102 103 systemd.tmpfiles.rules = [ 104 "d '${cfg.dataDir}' 0750 ${cfg.user} ${cfg.user} - -" 105 "d '${cfg.dataDir}/config' 0750 ${cfg.user} ${cfg.user} - -" 106 ]; 107 108 users = { 109 users.${cfg.user} = { 110 description = "kavita service user"; 111 isSystemUser = true; 112 group = cfg.user; 113 home = cfg.dataDir; 114 }; 115 groups.${cfg.user} = { }; 116 }; 117 }; 118 119 meta.maintainers = with lib.maintainers; [ misterio77 ]; 120}