1{ lib, compression, ... }:
2{
3 name = "binary-cache-" + compression;
4 meta.maintainers = with lib.maintainers; [ thomasjm ];
5
6 nodes.machine =
7 { pkgs, ... }:
8 {
9 imports = [ ../modules/installer/cd-dvd/channel.nix ];
10 environment.systemPackages = with pkgs; [
11 openssl
12 python3
13 ];
14
15 # We encrypt the binary cache before putting it on the machine so Nix
16 # doesn't bring any references along.
17 environment.etc."binary-cache.tar.gz.encrypted".source =
18 with pkgs;
19 runCommand "binary-cache.tar.gz.encrypted"
20 {
21 allowReferences = [ ];
22 nativeBuildInputs = [ openssl ];
23 }
24 ''
25 tar -czf tmp.tar.gz -C "${
26 mkBinaryCache {
27 rootPaths = [ hello ];
28 inherit compression;
29 }
30 }" .
31 openssl enc -aes-256-cbc -salt -in tmp.tar.gz -out $out -k mysecretpassword
32 '';
33
34 nix.extraOptions = ''
35 experimental-features = nix-command
36 '';
37 };
38
39 testScript = ''
40 # Decrypt the cache into /tmp/binary-cache.tar.gz
41 machine.succeed("openssl enc -d -aes-256-cbc -in /etc/binary-cache.tar.gz.encrypted -out /tmp/binary-cache.tar.gz -k mysecretpassword")
42
43 # Untar the cache into /tmp/cache
44 machine.succeed("mkdir /tmp/cache")
45 machine.succeed("tar -C /tmp/cache -xf /tmp/binary-cache.tar.gz")
46
47 # Sanity test of cache structure
48 status, stdout = machine.execute("ls /tmp/cache")
49 cache_files = stdout.split()
50 assert ("nix-cache-info" in cache_files)
51 assert ("nar" in cache_files)
52
53 # Nix store ping should work
54 machine.succeed("nix store ping --store file:///tmp/cache")
55
56 # Cache should contain a .narinfo referring to "hello"
57 grepLogs = machine.succeed("grep -l 'StorePath: /nix/store/[[:alnum:]]*-hello-.*' /tmp/cache/*.narinfo")
58
59 # Get the store path referenced by the .narinfo
60 narInfoFile = grepLogs.strip()
61 narInfoContents = machine.succeed("cat " + narInfoFile)
62 import re
63 match = re.match(r"^StorePath: (/nix/store/[a-z0-9]*-hello-.*)$", narInfoContents, re.MULTILINE)
64 if not match: raise Exception("Couldn't find hello store path in cache")
65 storePath = match[1]
66
67 # Make sure the store path doesn't exist yet
68 machine.succeed("[ ! -d %s ] || exit 1" % storePath)
69
70 # Should be able to build hello using the cache
71 logs = machine.succeed("nix-build -A hello '<nixpkgs>' --option require-sigs false --option trusted-substituters file:///tmp/cache --option substituters file:///tmp/cache 2>&1")
72 logLines = logs.split("\n")
73 if not "this path will be fetched" in logLines[0]: raise Exception("Unexpected first log line")
74 def shouldBe(got, desired):
75 if got != desired: raise Exception("Expected '%s' but got '%s'" % (desired, got))
76 shouldBe(logLines[1], " " + storePath)
77 shouldBe(logLines[2], "copying path '%s' from 'file:///tmp/cache'..." % storePath)
78 shouldBe(logLines[3], storePath)
79
80 # Store path should exist in the store now
81 machine.succeed("[ -d %s ] || exit 1" % storePath)
82 '';
83}