diff options
-rw-r--r-- | flakes/peertube/client.nix | 28 | ||||
-rw-r--r-- | flakes/peertube/fix_yarn_lock.patch | 28 | ||||
-rw-r--r-- | flakes/peertube/flake.lock | 78 | ||||
-rw-r--r-- | flakes/peertube/flake.nix | 306 | ||||
-rw-r--r-- | flakes/peertube/server.nix | 26 |
5 files changed, 466 insertions, 0 deletions
diff --git a/flakes/peertube/client.nix b/flakes/peertube/client.nix new file mode 100644 index 0000000..06383a7 --- /dev/null +++ b/flakes/peertube/client.nix | |||
@@ -0,0 +1,28 @@ | |||
1 | { yarnModulesConfig, mkYarnModules', server, sources, version, nodejs, stdenv }: | ||
2 | rec { | ||
3 | modules = mkYarnModules' rec { | ||
4 | pname = "peertube-client-yarn-modules"; | ||
5 | inherit version; | ||
6 | name = "${pname}-${version}"; | ||
7 | packageJSON = "${sources}/client/package.json"; | ||
8 | yarnLock = "${sources}/client/yarn.lock"; | ||
9 | pkgConfig = yarnModulesConfig; | ||
10 | }; | ||
11 | dist = stdenv.mkDerivation { | ||
12 | pname = "peertube-client"; | ||
13 | inherit version; | ||
14 | src = sources; | ||
15 | buildPhase = '' | ||
16 | ln -s ${server.modules}/node_modules . | ||
17 | cp -a ${modules}/node_modules client/ | ||
18 | chmod -R +w client/node_modules | ||
19 | patchShebangs . | ||
20 | npm run build:client | ||
21 | ''; | ||
22 | installPhase = '' | ||
23 | mkdir $out | ||
24 | cp -a client/dist $out | ||
25 | ''; | ||
26 | buildInputs = [ nodejs ]; | ||
27 | }; | ||
28 | } | ||
diff --git a/flakes/peertube/fix_yarn_lock.patch b/flakes/peertube/fix_yarn_lock.patch new file mode 100644 index 0000000..241e31a --- /dev/null +++ b/flakes/peertube/fix_yarn_lock.patch | |||
@@ -0,0 +1,28 @@ | |||
1 | diff --git a/client/yarn.lock b/client/yarn.lock | ||
2 | index d27cdaec8..26706a9fc 100644 | ||
3 | --- a/client/yarn.lock | ||
4 | +++ b/client/yarn.lock | ||
5 | @@ -5703,7 +5703,8 @@ http-errors@~1.7.2: | ||
6 | |||
7 | "http-node@github:feross/http-node#webtorrent": | ||
8 | version "1.2.0" | ||
9 | - resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974" | ||
10 | + resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13" | ||
11 | + integrity sha1-M/oxLTfwAAsXrNsaUIZWVABBmhM= | ||
12 | dependencies: | ||
13 | chrome-net "^3.3.3" | ||
14 | freelist "^1.0.3" | ||
15 | diff --git a/yarn.lock b/yarn.lock | ||
16 | index 61a2ea05e..c742276c7 100644 | ||
17 | --- a/yarn.lock | ||
18 | +++ b/yarn.lock | ||
19 | @@ -3873,7 +3873,8 @@ http-errors@~1.7.2: | ||
20 | |||
21 | "http-node@github:feross/http-node#webtorrent": | ||
22 | version "1.2.0" | ||
23 | - resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974" | ||
24 | + resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13" | ||
25 | + integrity sha1-M/oxLTfwAAsXrNsaUIZWVABBmhM= | ||
26 | dependencies: | ||
27 | chrome-net "^3.3.3" | ||
28 | freelist "^1.0.3" | ||
diff --git a/flakes/peertube/flake.lock b/flakes/peertube/flake.lock new file mode 100644 index 0000000..b6fc1d0 --- /dev/null +++ b/flakes/peertube/flake.lock | |||
@@ -0,0 +1,78 @@ | |||
1 | { | ||
2 | "nodes": { | ||
3 | "flake-utils": { | ||
4 | "locked": { | ||
5 | "lastModified": 1610051610, | ||
6 | "narHash": "sha256-U9rPz/usA1/Aohhk7Cmc2gBrEEKRzcW4nwPWMPwja4Y=", | ||
7 | "owner": "numtide", | ||
8 | "repo": "flake-utils", | ||
9 | "rev": "3982c9903e93927c2164caa727cd3f6a0e6d14cc", | ||
10 | "type": "github" | ||
11 | }, | ||
12 | "original": { | ||
13 | "owner": "numtide", | ||
14 | "repo": "flake-utils", | ||
15 | "type": "github" | ||
16 | } | ||
17 | }, | ||
18 | "myuids": { | ||
19 | "locked": { | ||
20 | "dir": "flakes/myuids", | ||
21 | "lastModified": 1611091761, | ||
22 | "narHash": "sha256-fE3FBeUxVaMezKjEpepdQW9apOza+0AfBALFhaaD0VA=", | ||
23 | "ref": "master", | ||
24 | "rev": "23f9fdf03a6673dbe334ae33be4f498cc4753191", | ||
25 | "revCount": 802, | ||
26 | "type": "git", | ||
27 | "url": "https://git.immae.eu/perso/Immae/Config/Nix.git" | ||
28 | }, | ||
29 | "original": { | ||
30 | "dir": "flakes/myuids", | ||
31 | "type": "git", | ||
32 | "url": "https://git.immae.eu/perso/Immae/Config/Nix.git" | ||
33 | } | ||
34 | }, | ||
35 | "nixpkgs": { | ||
36 | "locked": { | ||
37 | "lastModified": 1611097871, | ||
38 | "narHash": "sha256-Q6bUkno5JNt0OoyXThFDrKArFBp/GryvJhwEgVzGSuk=", | ||
39 | "owner": "NixOS", | ||
40 | "repo": "nixpkgs", | ||
41 | "rev": "31f5dd3f3655fbedac19f64f77844aa5ed79501c", | ||
42 | "type": "github" | ||
43 | }, | ||
44 | "original": { | ||
45 | "owner": "NixOS", | ||
46 | "repo": "nixpkgs", | ||
47 | "type": "github" | ||
48 | } | ||
49 | }, | ||
50 | "peertube": { | ||
51 | "flake": false, | ||
52 | "locked": { | ||
53 | "lastModified": 1610436329, | ||
54 | "narHash": "sha256-bIXt5bQiBBlNDFXYzcdQA8qp4nse5epUx/XQOguDOX8=", | ||
55 | "owner": "Chocobozzz", | ||
56 | "repo": "PeerTube", | ||
57 | "rev": "69e0e678beb7f1a3b6753eeff585a14f9a61ea86", | ||
58 | "type": "github" | ||
59 | }, | ||
60 | "original": { | ||
61 | "owner": "Chocobozzz", | ||
62 | "ref": "v3.0.1", | ||
63 | "repo": "PeerTube", | ||
64 | "type": "github" | ||
65 | } | ||
66 | }, | ||
67 | "root": { | ||
68 | "inputs": { | ||
69 | "flake-utils": "flake-utils", | ||
70 | "myuids": "myuids", | ||
71 | "nixpkgs": "nixpkgs", | ||
72 | "peertube": "peertube" | ||
73 | } | ||
74 | } | ||
75 | }, | ||
76 | "root": "root", | ||
77 | "version": 7 | ||
78 | } | ||
diff --git a/flakes/peertube/flake.nix b/flakes/peertube/flake.nix new file mode 100644 index 0000000..df6ef4a --- /dev/null +++ b/flakes/peertube/flake.nix | |||
@@ -0,0 +1,306 @@ | |||
1 | { | ||
2 | description = "A free software to take back control of your videos"; | ||
3 | inputs.myuids = { | ||
4 | url = "https://git.immae.eu/perso/Immae/Config/Nix.git"; | ||
5 | type = "git"; | ||
6 | dir = "flakes/myuids"; | ||
7 | }; | ||
8 | inputs.flake-utils.url = "github:numtide/flake-utils"; | ||
9 | inputs.nixpkgs.url = "github:NixOS/nixpkgs"; | ||
10 | inputs.peertube = { | ||
11 | url = "github:Chocobozzz/PeerTube/v3.0.1"; | ||
12 | flake = false; | ||
13 | }; | ||
14 | |||
15 | outputs = { self, myuids, nixpkgs, peertube, flake-utils }: flake-utils.lib.eachSystem ["x86_64-linux"] (system: | ||
16 | let | ||
17 | version = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.peertube.locked.rev; | ||
18 | pkgs = import nixpkgs { inherit system; overlays = [ | ||
19 | (self: super: { nodejs = self.nodejs-12_x; }) | ||
20 | ]; }; | ||
21 | inherit (pkgs) callPackage stdenv jq youtube-dl fetchurl nodePackages yarn2nix-moretea; | ||
22 | |||
23 | patchedSource = stdenv.mkDerivation { | ||
24 | pname = "peertube"; | ||
25 | inherit version; | ||
26 | src = peertube; | ||
27 | phases = [ "unpackPhase" "patchPhase" "installPhase" ]; | ||
28 | patches = [ ./fix_yarn_lock.patch ]; | ||
29 | installPhase = '' | ||
30 | mkdir $out | ||
31 | cp -a . $out/ | ||
32 | ''; | ||
33 | }; | ||
34 | yarnModulesConfig = { | ||
35 | bcrypt = { | ||
36 | buildInputs = [ nodePackages.node-pre-gyp ]; | ||
37 | postInstall = let | ||
38 | bcrypt_version = "5.0.0"; | ||
39 | bcrypt_lib = fetchurl { | ||
40 | 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"; | ||
41 | sha256 = "0j3p2px1xb17sw3gpm8l4apljajxxfflal1yy552mhpzhi21wccn"; | ||
42 | }; | ||
43 | in | ||
44 | '' | ||
45 | if [ "${bcrypt_version}" != "$(cat package.json | ${jq}/bin/jq -r .version)" ]; then | ||
46 | echo "Mismatching version please update bcrypt in derivation" | ||
47 | false | ||
48 | fi | ||
49 | mkdir -p lib/binding && tar -C lib/binding -xf ${bcrypt_lib} | ||
50 | patchShebangs ../node-pre-gyp | ||
51 | npm run install | ||
52 | ''; | ||
53 | }; | ||
54 | utf-8-validate = { | ||
55 | buildInputs = [ nodePackages.node-gyp-build ]; | ||
56 | }; | ||
57 | youtube-dl = { | ||
58 | postInstall = '' | ||
59 | mkdir bin | ||
60 | ln -s ${youtube-dl}/bin/youtube-dl bin/youtube-dl | ||
61 | cat > bin/details <<EOF | ||
62 | {"version":"${youtube-dl.version}","path":null,"exec":"youtube-dl"} | ||
63 | EOF | ||
64 | ''; | ||
65 | }; | ||
66 | }; | ||
67 | mkYarnModules' = args: (yarn2nix-moretea.mkYarnModules args).overrideAttrs(old: { | ||
68 | # This hack permits to workaround the fact that the yarn.lock | ||
69 | # file doesn't respect the semver requirements | ||
70 | buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase; | ||
71 | }); | ||
72 | |||
73 | server = callPackage ./server.nix { | ||
74 | inherit version yarnModulesConfig mkYarnModules'; | ||
75 | sources = patchedSource; | ||
76 | }; | ||
77 | client = callPackage ./client.nix { | ||
78 | inherit server version yarnModulesConfig mkYarnModules'; | ||
79 | sources = patchedSource; | ||
80 | }; | ||
81 | |||
82 | in rec { | ||
83 | packages.peertube = stdenv.mkDerivation rec { | ||
84 | inherit version; | ||
85 | pname = "peertube"; | ||
86 | src = patchedSource; | ||
87 | buildPhase = '' | ||
88 | ln -s ${server.modules}/node_modules . | ||
89 | rm -rf dist && cp -a ${server.dist}/dist dist | ||
90 | rm -rf client/dist && cp -a ${client.dist}/dist client/ | ||
91 | ''; | ||
92 | installPhase = '' | ||
93 | mkdir $out | ||
94 | cp -a * $out | ||
95 | ln -s /tmp $out/.cache | ||
96 | ''; | ||
97 | |||
98 | meta = { | ||
99 | description = "A free software to take back control of your videos"; | ||
100 | |||
101 | longDescription = '' | ||
102 | PeerTube aspires to be a decentralized and free/libre alternative to video | ||
103 | broadcasting services. | ||
104 | PeerTube is not meant to become a huge platform that would centralize | ||
105 | videos from all around the world. Rather, it is a network of | ||
106 | inter-connected small videos hosters. | ||
107 | Anyone with a modicum of technical skills can host a PeerTube server, aka | ||
108 | an instance. Each instance hosts its users and their videos. In this way, | ||
109 | every instance is created, moderated and maintained independently by | ||
110 | various administrators. | ||
111 | You can still watch from your account videos hosted by other instances | ||
112 | though if the administrator of your instance had previously connected it | ||
113 | with other instances. | ||
114 | ''; | ||
115 | |||
116 | license = stdenv.lib.licenses.agpl3Plus; | ||
117 | |||
118 | homepage = "https://joinpeertube.org/"; | ||
119 | |||
120 | platforms = stdenv.lib.platforms.unix; | ||
121 | }; | ||
122 | }; | ||
123 | defaultPackage = packages.peertube; | ||
124 | legacyPackages.peertube = packages.peertube; | ||
125 | checks = { | ||
126 | build = defaultPackage; | ||
127 | } // pkgs.lib.optionalAttrs (builtins.elem system pkgs.lib.systems.doubles.linux) { | ||
128 | test = | ||
129 | let testing = import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; }; | ||
130 | in testing.makeTest { | ||
131 | nodes = { | ||
132 | client = { pkgs, ... }: {}; | ||
133 | |||
134 | server = { pkgs, ... }: { | ||
135 | imports = [ self.nixosModule ]; | ||
136 | config.networking.firewall.allowedTCPPorts = [ 8888 ]; | ||
137 | config.services.redis.enable = true; | ||
138 | config.services.postgresql = { | ||
139 | enable = true; | ||
140 | initialScript = pkgs.writeText "peertube.sql" '' | ||
141 | CREATE ROLE "peertube" WITH LOGIN PASSWORD 'peertube'; | ||
142 | CREATE DATABASE "peertube_prod" WITH OWNER "peertube" | ||
143 | TEMPLATE template0 | ||
144 | LC_COLLATE = "C" | ||
145 | LC_CTYPE = "C"; | ||
146 | \c peertube_prod | ||
147 | CREATE EXTENSION unaccent; | ||
148 | CREATE EXTENSION pg_trgm; | ||
149 | ''; | ||
150 | }; | ||
151 | config.services.peertube.enable = true; | ||
152 | config.services.peertube.configFile = pkgs.writeText "peertube.conf" '' | ||
153 | listen: | ||
154 | hostname: '0.0.0.0' | ||
155 | port: 8888 | ||
156 | webserver: | ||
157 | https: false | ||
158 | hostname: 'localhost.tld' | ||
159 | port: 8888 | ||
160 | database: | ||
161 | hostname: 'localhost' | ||
162 | port: 5432 | ||
163 | suffix: '_prod' | ||
164 | username: 'peertube' | ||
165 | password: 'peertube' | ||
166 | pool: | ||
167 | max: 5 | ||
168 | redis: | ||
169 | socket: 'localhost' | ||
170 | auth: null | ||
171 | db: 0 | ||
172 | storage: | ||
173 | tmp: '/var/lib/peertube/storage/tmp/' | ||
174 | avatars: '/var/lib/peertube/storage/avatars/' | ||
175 | videos: '/var/lib/peertube/storage/videos/' | ||
176 | streaming_playlists: '/var/lib/peertube/storage/streaming-playlists/' | ||
177 | redundancy: '/var/lib/peertube/storage/videos/' | ||
178 | logs: '/var/lib/peertube/storage/logs/' | ||
179 | previews: '/var/lib/peertube/storage/previews/' | ||
180 | thumbnails: '/var/lib/peertube/storage/thumbnails/' | ||
181 | torrents: '/var/lib/peertube/storage/torrents/' | ||
182 | captions: '/var/lib/peertube/storage/captions/' | ||
183 | cache: '/var/lib/peertube/storage/cache/' | ||
184 | plugins: '/var/lib/peertube/storage/plugins/' | ||
185 | client_overrides: '/var/lib/peertube/storage/client-overrides/' | ||
186 | ''; | ||
187 | }; | ||
188 | }; | ||
189 | testScript = '' | ||
190 | start_all() | ||
191 | server.wait_for_unit("peertube.service") | ||
192 | server.wait_for_open_port(8888) | ||
193 | client.succeed("curl http://server:8888") | ||
194 | client.succeed("curl http://server:8888/client/fr-FR/index.html") | ||
195 | ''; | ||
196 | }; | ||
197 | }; | ||
198 | } | ||
199 | ) // { | ||
200 | nixosModule = { lib, pkgs, config, ... }: | ||
201 | let | ||
202 | name = "peertube"; | ||
203 | cfg = config.services.peertube; | ||
204 | in | ||
205 | { | ||
206 | options.services.peertube = { | ||
207 | enable = lib.mkEnableOption "Enable Peertube’s service"; | ||
208 | user = lib.mkOption { | ||
209 | type = lib.types.str; | ||
210 | default = name; | ||
211 | description = "User account under which Peertube runs"; | ||
212 | }; | ||
213 | group = lib.mkOption { | ||
214 | type = lib.types.str; | ||
215 | default = name; | ||
216 | description = "Group under which Peertube runs"; | ||
217 | }; | ||
218 | dataDir = lib.mkOption { | ||
219 | type = lib.types.path; | ||
220 | default = "/var/lib/${name}"; | ||
221 | description = '' | ||
222 | The directory where Peertube stores its data. | ||
223 | ''; | ||
224 | }; | ||
225 | configFile = lib.mkOption { | ||
226 | type = lib.types.path; | ||
227 | description = '' | ||
228 | The configuration file path for Peertube. | ||
229 | ''; | ||
230 | }; | ||
231 | package = lib.mkOption { | ||
232 | type = lib.types.package; | ||
233 | default = self.defaultPackage."${pkgs.system}"; | ||
234 | description = '' | ||
235 | Peertube package to use. | ||
236 | ''; | ||
237 | }; | ||
238 | # Output variables | ||
239 | systemdStateDirectory = lib.mkOption { | ||
240 | type = lib.types.str; | ||
241 | # Use ReadWritePaths= instead if varDir is outside of /var/lib | ||
242 | default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; | ||
243 | lib.strings.removePrefix "/var/lib/" cfg.dataDir; | ||
244 | description = '' | ||
245 | Adjusted Peertube data directory for systemd | ||
246 | ''; | ||
247 | readOnly = true; | ||
248 | }; | ||
249 | }; | ||
250 | |||
251 | config = lib.mkIf cfg.enable { | ||
252 | users.users = lib.optionalAttrs (cfg.user == name) { | ||
253 | "${name}" = { | ||
254 | uid = myuids.lib.uids.peertube; | ||
255 | group = cfg.group; | ||
256 | description = "Peertube user"; | ||
257 | home = cfg.dataDir; | ||
258 | useDefaultShell = true; | ||
259 | }; | ||
260 | }; | ||
261 | users.groups = lib.optionalAttrs (cfg.group == name) { | ||
262 | "${name}" = { | ||
263 | gid = myuids.lib.gids.peertube; | ||
264 | }; | ||
265 | }; | ||
266 | |||
267 | systemd.services.peertube = { | ||
268 | description = "Peertube"; | ||
269 | wantedBy = [ "multi-user.target" ]; | ||
270 | after = [ "network.target" "postgresql.service" ]; | ||
271 | wants = [ "postgresql.service" ]; | ||
272 | |||
273 | environment.NODE_CONFIG_DIR = "${cfg.dataDir}/config"; | ||
274 | environment.NODE_ENV = "production"; | ||
275 | environment.HOME = cfg.package; | ||
276 | |||
277 | path = [ pkgs.nodejs pkgs.bashInteractive pkgs.ffmpeg pkgs.openssl ]; | ||
278 | |||
279 | script = '' | ||
280 | install -m 0750 -d ${cfg.dataDir}/config | ||
281 | ln -sf ${cfg.configFile} ${cfg.dataDir}/config/production.yaml | ||
282 | ln -sf ${cfg.package}/config/default.yaml ${cfg.dataDir}/config/default.yaml | ||
283 | exec npm run start | ||
284 | ''; | ||
285 | |||
286 | serviceConfig = { | ||
287 | User = cfg.user; | ||
288 | Group = cfg.group; | ||
289 | WorkingDirectory = cfg.package; | ||
290 | StateDirectory = cfg.systemdStateDirectory; | ||
291 | StateDirectoryMode = 0750; | ||
292 | PrivateTmp = true; | ||
293 | ProtectHome = true; | ||
294 | ProtectControlGroups = true; | ||
295 | Restart = "always"; | ||
296 | Type = "simple"; | ||
297 | TimeoutSec = 60; | ||
298 | }; | ||
299 | |||
300 | unitConfig.RequiresMountsFor = cfg.dataDir; | ||
301 | }; | ||
302 | }; | ||
303 | }; | ||
304 | |||
305 | }; | ||
306 | } | ||
diff --git a/flakes/peertube/server.nix b/flakes/peertube/server.nix new file mode 100644 index 0000000..1bba06d --- /dev/null +++ b/flakes/peertube/server.nix | |||
@@ -0,0 +1,26 @@ | |||
1 | { yarnModulesConfig, mkYarnModules', sources, version, nodejs, stdenv }: | ||
2 | rec { | ||
3 | modules = mkYarnModules' rec { | ||
4 | pname = "peertube-server-yarn-modules"; | ||
5 | inherit version; | ||
6 | name = "${pname}-${version}"; | ||
7 | packageJSON = "${sources}/package.json"; | ||
8 | yarnLock = "${sources}/yarn.lock"; | ||
9 | pkgConfig = yarnModulesConfig; | ||
10 | }; | ||
11 | dist = stdenv.mkDerivation { | ||
12 | pname = "peertube-server"; | ||
13 | inherit version; | ||
14 | src = sources; | ||
15 | buildPhase = '' | ||
16 | ln -s ${modules}/node_modules . | ||
17 | patchShebangs scripts/build/server.sh | ||
18 | npm run build:server | ||
19 | ''; | ||
20 | installPhase = '' | ||
21 | mkdir $out | ||
22 | cp -a dist $out | ||
23 | ''; | ||
24 | buildInputs = [ nodejs ]; | ||
25 | }; | ||
26 | } | ||