1{ config, lib, pkgs, ... }:
2
3let
4 cfg = config.services.hydron;
5in with lib; {
6 options.services.hydron = {
7 enable = mkEnableOption "hydron";
8
9 dataDir = mkOption {
10 type = types.path;
11 default = "/var/lib/hydron";
12 example = "/home/okina/hydron";
13 description = "Location where hydron runs and stores data.";
14 };
15
16 interval = mkOption {
17 type = types.str;
18 default = "weekly";
19 example = "06:00";
20 description = ''
21 How often we run hydron import and possibly fetch tags. Runs by default every week.
22
23 The format is described in
24 <citerefentry><refentrytitle>systemd.time</refentrytitle>
25 <manvolnum>7</manvolnum></citerefentry>.
26 '';
27 };
28
29 password = mkOption {
30 type = types.str;
31 default = "hydron";
32 example = "dumbpass";
33 description = "Password for the hydron database.";
34 };
35
36 passwordFile = mkOption {
37 type = types.path;
38 default = "/run/keys/hydron-password-file";
39 example = "/home/okina/hydron/keys/pass";
40 description = "Password file for the hydron database.";
41 };
42
43 postgresArgs = mkOption {
44 type = types.str;
45 description = "Postgresql connection arguments.";
46 example = ''
47 {
48 "driver": "postgres",
49 "connection": "user=hydron password=dumbpass dbname=hydron sslmode=disable"
50 }
51 '';
52 };
53
54 postgresArgsFile = mkOption {
55 type = types.path;
56 default = "/run/keys/hydron-postgres-args";
57 example = "/home/okina/hydron/keys/postgres";
58 description = "Postgresql connection arguments file.";
59 };
60
61 listenAddress = mkOption {
62 type = types.nullOr types.str;
63 default = null;
64 example = "127.0.0.1:8010";
65 description = "Listen on a specific IP address and port.";
66 };
67
68 importPaths = mkOption {
69 type = types.listOf types.path;
70 default = [];
71 example = [ "/home/okina/Pictures" ];
72 description = "Paths that hydron will recursively import.";
73 };
74
75 fetchTags = mkOption {
76 type = types.bool;
77 default = true;
78 description = "Fetch tags for imported images and webm from gelbooru.";
79 };
80 };
81
82 config = mkIf cfg.enable {
83 services.hydron.passwordFile = mkDefault (pkgs.writeText "hydron-password-file" cfg.password);
84 services.hydron.postgresArgsFile = mkDefault (pkgs.writeText "hydron-postgres-args" cfg.postgresArgs);
85 services.hydron.postgresArgs = mkDefault ''
86 {
87 "driver": "postgres",
88 "connection": "user=hydron password=${cfg.password} host=/run/postgresql dbname=hydron sslmode=disable"
89 }
90 '';
91
92 services.postgresql = {
93 enable = true;
94 ensureDatabases = [ "hydron" ];
95 ensureUsers = [
96 { name = "hydron";
97 ensurePermissions = { "DATABASE hydron" = "ALL PRIVILEGES"; };
98 }
99 ];
100 };
101
102 systemd.tmpfiles.rules = [
103 "d '${cfg.dataDir}' 0750 hydron hydron - -"
104 "d '${cfg.dataDir}/.hydron' - hydron hydron - -"
105 "d '${cfg.dataDir}/images' - hydron hydron - -"
106 "Z '${cfg.dataDir}' - hydron hydron - -"
107
108 "L+ '${cfg.dataDir}/.hydron/db_conf.json' - - - - ${cfg.postgresArgsFile}"
109 ];
110
111 systemd.services.hydron = {
112 description = "hydron";
113 after = [ "network.target" "postgresql.service" ];
114 wantedBy = [ "multi-user.target" ];
115
116 serviceConfig = {
117 User = "hydron";
118 Group = "hydron";
119 ExecStart = "${pkgs.hydron}/bin/hydron serve"
120 + optionalString (cfg.listenAddress != null) " -a ${cfg.listenAddress}";
121 };
122 };
123
124 systemd.services.hydron-fetch = {
125 description = "Import paths into hydron and possibly fetch tags";
126
127 serviceConfig = {
128 Type = "oneshot";
129 User = "hydron";
130 Group = "hydron";
131 ExecStart = "${pkgs.hydron}/bin/hydron import "
132 + optionalString cfg.fetchTags "-f "
133 + (escapeShellArg cfg.dataDir) + "/images " + (escapeShellArgs cfg.importPaths);
134 };
135 };
136
137 systemd.timers.hydron-fetch = {
138 description = "Automatically import paths into hydron and possibly fetch tags";
139 after = [ "network.target" "hydron.service" ];
140 wantedBy = [ "timers.target" ];
141
142 timerConfig = {
143 Persistent = true;
144 OnCalendar = cfg.interval;
145 };
146 };
147
148 users = {
149 groups.hydron.gid = config.ids.gids.hydron;
150
151 users.hydron = {
152 description = "hydron server service user";
153 home = cfg.dataDir;
154 group = "hydron";
155 uid = config.ids.uids.hydron;
156 };
157 };
158 };
159
160 imports = [
161 (mkRenamedOptionModule [ "services" "hydron" "baseDir" ] [ "services" "hydron" "dataDir" ])
162 ];
163
164 meta.maintainers = with maintainers; [ chiiruno ];
165}