at 25.11-pre 4.1 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 utils, 6 ... 7}: 8let 9 cfg = config.services.artalk; 10 settingsFormat = pkgs.formats.json { }; 11in 12{ 13 14 meta = { 15 maintainers = with lib.maintainers; [ moraxyc ]; 16 }; 17 18 options = { 19 services.artalk = { 20 enable = lib.mkEnableOption "artalk, a comment system"; 21 configFile = lib.mkOption { 22 type = lib.types.str; 23 default = "/etc/artalk/config.yml"; 24 description = "Artalk config file path. If it is not exist, Artalk will generate one."; 25 }; 26 allowModify = lib.mkOption { 27 type = lib.types.bool; 28 default = true; 29 description = "allow Artalk store the settings to config file persistently"; 30 }; 31 workdir = lib.mkOption { 32 type = lib.types.str; 33 default = "/var/lib/artalk"; 34 description = "Artalk working directory"; 35 }; 36 user = lib.mkOption { 37 type = lib.types.str; 38 default = "artalk"; 39 description = "Artalk user name."; 40 }; 41 42 group = lib.mkOption { 43 type = lib.types.str; 44 default = "artalk"; 45 description = "Artalk group name."; 46 }; 47 48 package = lib.mkPackageOption pkgs "artalk" { }; 49 settings = lib.mkOption { 50 type = lib.types.submodule { 51 freeformType = settingsFormat.type; 52 options = { 53 host = lib.mkOption { 54 type = lib.types.str; 55 default = "0.0.0.0"; 56 description = '' 57 Artalk server listen host 58 ''; 59 }; 60 port = lib.mkOption { 61 type = lib.types.port; 62 default = 23366; 63 description = '' 64 Artalk server listen port 65 ''; 66 }; 67 }; 68 }; 69 default = { }; 70 description = '' 71 The artalk configuration. 72 73 If you set allowModify to true, Artalk will be able to store the settings in the config file persistently. This section's content will update in the config file after the service restarts. 74 75 Options containing secret data should be set to an attribute set 76 containing the attribute `_secret` - a string pointing to a file 77 containing the value the option should be set to. 78 ''; 79 }; 80 }; 81 }; 82 83 config = lib.mkIf cfg.enable { 84 users.users.artalk = lib.optionalAttrs (cfg.user == "artalk") { 85 description = "artalk user"; 86 isSystemUser = true; 87 group = cfg.group; 88 }; 89 users.groups.artalk = lib.optionalAttrs (cfg.group == "artalk") { }; 90 91 environment.systemPackages = [ cfg.package ]; 92 93 systemd.services.artalk = { 94 after = [ "network.target" ]; 95 wantedBy = [ "multi-user.target" ]; 96 preStart = 97 '' 98 umask 0077 99 ${utils.genJqSecretsReplacementSnippet cfg.settings "/run/artalk/new"} 100 '' 101 + ( 102 if cfg.allowModify then 103 '' 104 [ -e "${cfg.configFile}" ] || ${lib.getExe cfg.package} gen config "${cfg.configFile}" 105 cat "${cfg.configFile}" | ${lib.getExe pkgs.yj} > "/run/artalk/old" 106 ${lib.getExe pkgs.jq} -s '.[0] * .[1]' "/run/artalk/old" "/run/artalk/new" > "/run/artalk/result" 107 cat "/run/artalk/result" | ${lib.getExe pkgs.yj} -r > "${cfg.configFile}" 108 rm /run/artalk/{old,new,result} 109 '' 110 else 111 '' 112 cat /run/artalk/new | ${lib.getExe pkgs.yj} -r > "${cfg.configFile}" 113 rm /run/artalk/new 114 '' 115 ); 116 serviceConfig = { 117 User = cfg.user; 118 Group = cfg.group; 119 Type = "simple"; 120 ExecStart = "${lib.getExe cfg.package} server --config ${cfg.configFile} --workdir ${cfg.workdir} --host ${cfg.settings.host} --port ${builtins.toString cfg.settings.port}"; 121 Restart = "on-failure"; 122 RestartSec = "5s"; 123 ConfigurationDirectory = [ "artalk" ]; 124 StateDirectory = [ "artalk" ]; 125 RuntimeDirectory = [ "artalk" ]; 126 AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; 127 ProtectHome = "yes"; 128 }; 129 }; 130 }; 131}