1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.lxd-image-server;
9 format = pkgs.formats.toml { };
10
11 location = "/var/www/simplestreams";
12in
13{
14 options = {
15 services.lxd-image-server = {
16 enable = lib.mkEnableOption "lxd-image-server";
17
18 group = lib.mkOption {
19 type = lib.types.str;
20 description = "Group assigned to the user and the webroot directory.";
21 default = "nginx";
22 example = "www-data";
23 };
24
25 settings = lib.mkOption {
26 type = format.type;
27 description = ''
28 Configuration for lxd-image-server.
29
30 Example see <https://github.com/Avature/lxd-image-server/blob/master/config.toml>.
31 '';
32 default = { };
33 };
34
35 nginx = {
36 enable = lib.mkEnableOption "nginx";
37 domain = lib.mkOption {
38 type = lib.types.str;
39 description = "Domain to use for nginx virtual host.";
40 example = "images.example.org";
41 };
42 };
43 };
44 };
45
46 config = lib.mkMerge [
47 (lib.mkIf (cfg.enable) {
48 users.users.lxd-image-server = {
49 isSystemUser = true;
50 group = cfg.group;
51 };
52 users.groups.${cfg.group} = { };
53
54 environment.etc."lxd-image-server/config.toml".source = format.generate "config.toml" cfg.settings;
55
56 services.logrotate.settings.lxd-image-server = {
57 files = "/var/log/lxd-image-server/lxd-image-server.log";
58 frequency = "daily";
59 rotate = 21;
60 create = "755 lxd-image-server ${cfg.group}";
61 compress = true;
62 delaycompress = true;
63 copytruncate = true;
64 };
65
66 systemd.tmpfiles.rules = [
67 "d /var/www/simplestreams 0755 lxd-image-server ${cfg.group}"
68 ];
69
70 systemd.services.lxd-image-server = {
71 wantedBy = [ "multi-user.target" ];
72 after = [ "network.target" ];
73
74 description = "LXD Image Server";
75
76 script = ''
77 ${pkgs.lxd-image-server}/bin/lxd-image-server init
78 ${pkgs.lxd-image-server}/bin/lxd-image-server watch
79 '';
80
81 serviceConfig = {
82 User = "lxd-image-server";
83 Group = cfg.group;
84 DynamicUser = true;
85 LogsDirectory = "lxd-image-server";
86 RuntimeDirectory = "lxd-image-server";
87 ExecReload = "${pkgs.lxd-image-server}/bin/lxd-image-server reload";
88 ReadWritePaths = [ location ];
89 };
90 };
91 })
92 # this is separate so it can be enabled on mirrored hosts
93 (lib.mkIf (cfg.nginx.enable) {
94 # https://github.com/Avature/lxd-image-server/blob/master/resources/nginx/includes/lxd-image-server.pkg.conf
95 services.nginx.virtualHosts = {
96 "${cfg.nginx.domain}" = {
97 forceSSL = true;
98 enableACME = lib.mkDefault true;
99
100 root = location;
101
102 locations = {
103 "/streams/v1/" = {
104 index = "index.json";
105 };
106
107 # Serve json files with content type header application/json
108 "~ \\.json$" = {
109 extraConfig = ''
110 add_header Content-Type application/json;
111 '';
112 };
113
114 "~ \\.tar.xz$" = {
115 extraConfig = ''
116 add_header Content-Type application/octet-stream;
117 '';
118 };
119
120 "~ \\.tar.gz$" = {
121 extraConfig = ''
122 add_header Content-Type application/octet-stream;
123 '';
124 };
125
126 # Deny access to document root and the images folder
127 "~ ^/(images/)?$" = {
128 return = "403";
129 };
130 };
131 };
132 };
133 })
134 ];
135}