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