]>
Commit | Line | Data |
---|---|---|
1 | { | |
2 | description = "A free software to take back control of your videos"; | |
3 | inputs.myuids = { | |
4 | url = "path:../myuids"; | |
5 | }; | |
6 | inputs.flake-utils.url = "github:numtide/flake-utils"; | |
7 | inputs.nixpkgs.url = "github:NixOS/nixpkgs"; | |
8 | inputs.peertube = { | |
9 | url = "github:Chocobozzz/PeerTube/v3.0.1"; | |
10 | flake = false; | |
11 | }; | |
12 | ||
13 | outputs = { self, myuids, nixpkgs, peertube, flake-utils }: flake-utils.lib.eachSystem ["x86_64-linux"] (system: | |
14 | let | |
15 | pkgs = import nixpkgs { inherit system; overlays = [ | |
16 | (self: super: { nodejs = self.nodejs-12_x; }) | |
17 | ]; }; | |
18 | inherit (pkgs) callPackage stdenv jq youtube-dl fetchurl nodePackages yarn2nix-moretea; | |
19 | ||
20 | patchedSource = stdenv.mkDerivation { | |
21 | pname = "peertube"; | |
22 | version = peertube.rev; | |
23 | src = peertube; | |
24 | phases = [ "unpackPhase" "patchPhase" "installPhase" ]; | |
25 | patches = [ ./fix_yarn_lock.patch ]; | |
26 | installPhase = '' | |
27 | mkdir $out | |
28 | cp -a . $out/ | |
29 | ''; | |
30 | }; | |
31 | yarnModulesConfig = { | |
32 | bcrypt = { | |
33 | buildInputs = [ nodePackages.node-pre-gyp ]; | |
34 | postInstall = let | |
35 | bcrypt_version = "5.0.0"; | |
36 | bcrypt_lib = fetchurl { | |
37 | url = "https://github.com/kelektiv/node.bcrypt.js/releases/download/v${bcrypt_version}/bcrypt_lib-v${bcrypt_version}-napi-v3-linux-x64-glibc.tar.gz"; | |
38 | sha256 = "0j3p2px1xb17sw3gpm8l4apljajxxfflal1yy552mhpzhi21wccn"; | |
39 | }; | |
40 | in | |
41 | '' | |
42 | if [ "${bcrypt_version}" != "$(cat package.json | ${jq}/bin/jq -r .version)" ]; then | |
43 | echo "Mismatching version please update bcrypt in derivation" | |
44 | false | |
45 | fi | |
46 | mkdir -p lib/binding && tar -C lib/binding -xf ${bcrypt_lib} | |
47 | patchShebangs ../node-pre-gyp | |
48 | npm run install | |
49 | ''; | |
50 | }; | |
51 | utf-8-validate = { | |
52 | buildInputs = [ nodePackages.node-gyp-build ]; | |
53 | }; | |
54 | youtube-dl = { | |
55 | postInstall = '' | |
56 | mkdir bin | |
57 | ln -s ${youtube-dl}/bin/youtube-dl bin/youtube-dl | |
58 | cat > bin/details <<EOF | |
59 | {"version":"${youtube-dl.version}","path":null,"exec":"youtube-dl"} | |
60 | EOF | |
61 | ''; | |
62 | }; | |
63 | }; | |
64 | mkYarnModules' = args: (yarn2nix-moretea.mkYarnModules args).overrideAttrs(old: { | |
65 | # This hack permits to workaround the fact that the yarn.lock | |
66 | # file doesn't respect the semver requirements | |
67 | buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase; | |
68 | }); | |
69 | ||
70 | server = callPackage ./server.nix { | |
71 | inherit yarnModulesConfig mkYarnModules'; | |
72 | sources = patchedSource; | |
73 | }; | |
74 | client = callPackage ./client.nix { | |
75 | inherit server yarnModulesConfig mkYarnModules'; | |
76 | sources = patchedSource; | |
77 | }; | |
78 | ||
79 | in rec { | |
80 | packages.peertube = callPackage ./. { inherit server client; src = patchedSource; }; | |
81 | defaultPackage = packages.peertube; | |
82 | legacyPackages.peertube = packages.peertube; | |
83 | checks = { | |
84 | build = defaultPackage; | |
85 | } // pkgs.lib.optionalAttrs (builtins.elem system pkgs.lib.systems.doubles.linux) { | |
86 | test = | |
87 | let testing = import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; }; | |
88 | in testing.makeTest { | |
89 | nodes = { | |
90 | client = { pkgs, ... }: {}; | |
91 | ||
92 | server = { pkgs, ... }: { | |
93 | imports = [ self.nixosModule ]; | |
94 | config.networking.firewall.allowedTCPPorts = [ 8888 ]; | |
95 | config.services.redis.enable = true; | |
96 | config.services.postgresql = { | |
97 | enable = true; | |
98 | initialScript = pkgs.writeText "peertube.sql" '' | |
99 | CREATE ROLE "peertube" WITH LOGIN PASSWORD 'peertube'; | |
100 | CREATE DATABASE "peertube_prod" WITH OWNER "peertube" | |
101 | TEMPLATE template0 | |
102 | LC_COLLATE = "C" | |
103 | LC_CTYPE = "C"; | |
104 | \c peertube_prod | |
105 | CREATE EXTENSION unaccent; | |
106 | CREATE EXTENSION pg_trgm; | |
107 | ''; | |
108 | }; | |
109 | config.services.peertube.enable = true; | |
110 | config.services.peertube.configFile = pkgs.writeText "peertube.conf" '' | |
111 | listen: | |
112 | hostname: '0.0.0.0' | |
113 | port: 8888 | |
114 | webserver: | |
115 | https: false | |
116 | hostname: 'localhost.tld' | |
117 | port: 8888 | |
118 | database: | |
119 | hostname: 'localhost' | |
120 | port: 5432 | |
121 | suffix: '_prod' | |
122 | username: 'peertube' | |
123 | password: 'peertube' | |
124 | pool: | |
125 | max: 5 | |
126 | redis: | |
127 | socket: 'localhost' | |
128 | auth: null | |
129 | db: 0 | |
130 | storage: | |
131 | tmp: '/var/lib/peertube/storage/tmp/' | |
132 | avatars: '/var/lib/peertube/storage/avatars/' | |
133 | videos: '/var/lib/peertube/storage/videos/' | |
134 | streaming_playlists: '/var/lib/peertube/storage/streaming-playlists/' | |
135 | redundancy: '/var/lib/peertube/storage/videos/' | |
136 | logs: '/var/lib/peertube/storage/logs/' | |
137 | previews: '/var/lib/peertube/storage/previews/' | |
138 | thumbnails: '/var/lib/peertube/storage/thumbnails/' | |
139 | torrents: '/var/lib/peertube/storage/torrents/' | |
140 | captions: '/var/lib/peertube/storage/captions/' | |
141 | cache: '/var/lib/peertube/storage/cache/' | |
142 | plugins: '/var/lib/peertube/storage/plugins/' | |
143 | client_overrides: '/var/lib/peertube/storage/client-overrides/' | |
144 | ''; | |
145 | }; | |
146 | }; | |
147 | testScript = '' | |
148 | start_all() | |
149 | server.wait_for_unit("peertube.service") | |
150 | server.wait_for_open_port(8888) | |
151 | client.succeed("curl http://server:8888") | |
152 | client.succeed("curl http://server:8888/client/fr-FR/index.html") | |
153 | ''; | |
154 | }; | |
155 | }; | |
156 | } | |
157 | ) // rec { | |
158 | overlays = { | |
159 | peertube = final: prev: { | |
160 | peertube = self.defaultPackage."${final.system}"; | |
161 | }; | |
162 | }; | |
163 | overlay = overlays.peertube; | |
164 | nixosModule = { lib, pkgs, config, ... }: | |
165 | let | |
166 | name = "peertube"; | |
167 | cfg = config.immaeServices.peertube; | |
168 | in | |
169 | { | |
170 | options.immaeServices.peertube = { | |
171 | enable = lib.mkEnableOption "Enable Peertube’s service"; | |
172 | user = lib.mkOption { | |
173 | type = lib.types.str; | |
174 | default = name; | |
175 | description = "User account under which Peertube runs"; | |
176 | }; | |
177 | group = lib.mkOption { | |
178 | type = lib.types.str; | |
179 | default = name; | |
180 | description = "Group under which Peertube runs"; | |
181 | }; | |
182 | dataDir = lib.mkOption { | |
183 | type = lib.types.path; | |
184 | default = "/var/lib/${name}"; | |
185 | description = '' | |
186 | The directory where Peertube stores its data. | |
187 | ''; | |
188 | }; | |
189 | configFile = lib.mkOption { | |
190 | type = lib.types.path; | |
191 | description = '' | |
192 | The configuration file path for Peertube. | |
193 | ''; | |
194 | }; | |
195 | package = lib.mkOption { | |
196 | type = lib.types.package; | |
197 | default = pkgs.peertube; | |
198 | description = '' | |
199 | Peertube package to use. | |
200 | ''; | |
201 | }; | |
202 | # Output variables | |
203 | systemdStateDirectory = lib.mkOption { | |
204 | type = lib.types.str; | |
205 | # Use ReadWritePaths= instead if varDir is outside of /var/lib | |
206 | default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; | |
207 | lib.strings.removePrefix "/var/lib/" cfg.dataDir; | |
208 | description = '' | |
209 | Adjusted Peertube data directory for systemd | |
210 | ''; | |
211 | readOnly = true; | |
212 | }; | |
213 | }; | |
214 | ||
215 | config = lib.mkIf cfg.enable { | |
216 | nixpkgs.overlays = [ self.overlay ]; | |
217 | users.users = lib.optionalAttrs (cfg.user == name) { | |
218 | "${name}" = { | |
219 | uid = myuids.lib.uids.peertube; | |
220 | group = cfg.group; | |
221 | description = "Peertube user"; | |
222 | home = cfg.dataDir; | |
223 | useDefaultShell = true; | |
224 | }; | |
225 | }; | |
226 | users.groups = lib.optionalAttrs (cfg.group == name) { | |
227 | "${name}" = { | |
228 | gid = myuids.lib.gids.peertube; | |
229 | }; | |
230 | }; | |
231 | ||
232 | systemd.services.peertube = { | |
233 | description = "Peertube"; | |
234 | wantedBy = [ "multi-user.target" ]; | |
235 | after = [ "network.target" "postgresql.service" ]; | |
236 | wants = [ "postgresql.service" ]; | |
237 | ||
238 | environment.NODE_CONFIG_DIR = "${cfg.dataDir}/config"; | |
239 | environment.NODE_ENV = "production"; | |
240 | environment.NPM_CONFIG_LOGS_DIR = "${cfg.dataDir}/npm_logs"; | |
241 | environment.NPM_CONFIG_CACHE = "${cfg.dataDir}/npm_cache"; | |
242 | environment.HOME = cfg.package; | |
243 | ||
244 | path = [ pkgs.nodejs pkgs.yarn pkgs.bashInteractive pkgs.ffmpeg pkgs.openssl ]; | |
245 | ||
246 | script = '' | |
247 | install -m 0750 -d ${cfg.dataDir}/config | |
248 | ln -sf ${cfg.configFile} ${cfg.dataDir}/config/production.yaml | |
249 | ln -sf ${cfg.package}/config/default.yaml ${cfg.dataDir}/config/default.yaml | |
250 | exec npm run start | |
251 | ''; | |
252 | ||
253 | serviceConfig = { | |
254 | User = cfg.user; | |
255 | Group = cfg.group; | |
256 | WorkingDirectory = cfg.package; | |
257 | StateDirectory = cfg.systemdStateDirectory; | |
258 | StateDirectoryMode = 0750; | |
259 | PrivateTmp = true; | |
260 | ProtectHome = true; | |
261 | ProtectControlGroups = true; | |
262 | Restart = "always"; | |
263 | Type = "simple"; | |
264 | TimeoutSec = 60; | |
265 | }; | |
266 | ||
267 | unitConfig.RequiresMountsFor = cfg.dataDir; | |
268 | }; | |
269 | }; | |
270 | }; | |
271 | ||
272 | }; | |
273 | } |