]>
Commit | Line | Data |
---|---|---|
a9f52ec5 IB |
1 | { |
2 | inputs.flake-utils.url = "github:numtide/flake-utils"; | |
3 | inputs.nixpkgs.url = "github:NixOS/nixpkgs"; | |
4 | ||
5 | description = "Pastebin-like service"; | |
6 | ||
7 | outputs = { self, flake-utils, nixpkgs }: flake-utils.lib.eachDefaultSystem (system: | |
8 | let | |
9 | pkgs = import nixpkgs { inherit system; overlays = []; }; | |
10 | in rec { | |
11 | hydraJobs = checks; | |
12 | checks = pkgs.lib.optionalAttrs (builtins.elem system pkgs.lib.systems.doubles.linux) { | |
13 | test = | |
14 | let testing = import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; }; | |
15 | in testing.makeTest { | |
16 | nodes = { | |
17 | server = { pkgs, ... }: { | |
18 | imports = [ self.nixosModule ]; | |
19 | config = { | |
20 | environment.systemPackages = [ pkgs.curl ]; | |
21 | services.httpd = { | |
22 | enable = true; | |
23 | adminAddr = "foo@example.org"; | |
24 | extraConfig = '' | |
25 | ProxyPass / unix:///run/paste/gunicorn.sock|http://localhost/ | |
26 | ProxyPassReverse / unix:///run/paste/gunicorn.sock|http://localhost/ | |
27 | ''; | |
28 | }; | |
29 | services.paste.enable = true; | |
30 | }; | |
31 | }; | |
32 | }; | |
33 | testScript = '' | |
34 | start_all() | |
35 | server.wait_for_unit("httpd.service") | |
36 | server.wait_for_unit("paste.service") | |
37 | server.wait_until_succeeds("[ -S /run/paste/gunicorn.sock ]", 10) | |
38 | server.succeed("curl -f http://localhost/") | |
39 | server.succeed("curl -f http://localhost/ | grep -q 'Get the source'") | |
40 | ''; | |
41 | }; | |
42 | }; | |
43 | }) // rec { | |
44 | nixosModule = { config, lib, pkgs, ... }: | |
45 | let | |
46 | cfg = config.services.paste; | |
47 | in { | |
1a64deeb IB |
48 | # Necessary for situations where flake gets included multiple times |
49 | key = builtins.hashString "sha256" (builtins.path { path = self.sourceInfo.outPath; name = "source"; }); | |
a9f52ec5 IB |
50 | options = { |
51 | services.paste = { | |
52 | enable = lib.mkOption { | |
53 | type = lib.types.bool; | |
54 | default = false; | |
55 | description = "Whether to enable the pastebin service"; | |
56 | }; | |
57 | ||
58 | dataDir = lib.mkOption { | |
59 | type = lib.types.path; | |
60 | default = "/var/lib/paste"; | |
61 | description = '' | |
62 | The directory where Paste stores its data. | |
63 | ''; | |
64 | }; | |
65 | ||
66 | socketsDir = lib.mkOption { | |
67 | type = lib.types.str; | |
68 | default = "/run/paste"; | |
69 | description = "Socket which is used for communication with Paste."; | |
70 | }; | |
71 | ||
72 | webDirectory = lib.mkOption { | |
73 | type = lib.types.nullOr lib.types.str; | |
74 | default = null; | |
75 | description = "Subdirectory url to which the app will be served"; | |
76 | }; | |
77 | ||
78 | # Output variables | |
79 | systemdStateDirectory = lib.mkOption { | |
80 | type = lib.types.str; | |
81 | # Use ReadWritePaths= instead if varDir is outside of /var/lib | |
82 | default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; | |
83 | lib.strings.removePrefix "/var/lib/" cfg.dataDir; | |
84 | description = '' | |
85 | Adjusted paste data directory for systemd | |
86 | ''; | |
87 | readOnly = true; | |
88 | }; | |
89 | systemdRuntimeDirectory = lib.mkOption { | |
90 | type = lib.types.str; | |
91 | # Use ReadWritePaths= instead if socketsDir is outside of /run | |
92 | default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; | |
93 | lib.strings.removePrefix "/run/" cfg.socketsDir; | |
94 | description = '' | |
95 | Adjusted paste sockets directory for systemd | |
96 | ''; | |
97 | readOnly = true; | |
98 | }; | |
99 | sockets = lib.mkOption { | |
100 | type = lib.types.attrsOf lib.types.path; | |
101 | default = { | |
102 | pid = "${cfg.socketsDir}/gunicorn.pid"; | |
103 | gunicorn = "${cfg.socketsDir}/gunicorn.sock"; | |
104 | }; | |
105 | readOnly = true; | |
106 | description = '' | |
107 | Paste sockets | |
108 | ''; | |
109 | }; | |
110 | }; | |
111 | }; | |
112 | ||
113 | config = lib.mkIf cfg.enable { | |
114 | systemd.services.paste = { | |
115 | description = "Pastebin like service"; | |
116 | after = [ "network.target" ]; | |
117 | wantedBy = [ "multi-user.target" ]; | |
118 | ||
119 | serviceConfig = { | |
120 | Environment = pkgs.lib.optionals (cfg.webDirectory != null) [ "SCRIPT_NAME=${cfg.webDirectory}" ]; | |
121 | Type = "simple"; | |
122 | User = config.services.httpd.user; | |
123 | ExecStart = let | |
124 | python = pkgs.python3.withPackages (p: [p.gunicorn p.flask p.pygments p.python_magic ]); | |
125 | in | |
126 | "${python}/bin/gunicorn -w4 -p ${cfg.sockets.pid} -e PASTE_DIRECTORY=${cfg.dataDir} --bind unix:${cfg.sockets.gunicorn} --chdir ${./paste} paste:app"; | |
127 | Restart = "always"; | |
128 | RestartSec = "5s"; | |
129 | PIDFile = cfg.sockets.pid; | |
130 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | |
131 | StateDirectory = cfg.systemdStateDirectory; | |
132 | StandardOutput = "journal"; | |
133 | StandardError = "inherit"; | |
134 | }; | |
135 | ||
136 | }; | |
137 | }; | |
138 | }; | |
139 | }; | |
140 | } |