1{
2 stdenv,
3 lib,
4 coreutils,
5 bash,
6 gnutar,
7 writeText,
8}:
9let
10 stripScheme = builtins.replaceStrings [ "https://" "http://" ] [ "" "" ];
11 stripNixStore = s: lib.removePrefix "${builtins.storeDir}/" s;
12in
13{
14 name,
15 registry ? "https://registry-1.docker.io/v2/",
16 repository ? "library",
17 imageName,
18 tag,
19 imageLayers,
20 imageConfig,
21 image ? "${stripScheme registry}/${repository}/${imageName}:${tag}",
22}:
23
24# Make sure there are *no* slashes in the repository or container
25# names since we use these to make the output derivation name for the
26# nix-store path.
27assert null == lib.findFirst (c: "/" == c) null (lib.stringToCharacters repository);
28assert null == lib.findFirst (c: "/" == c) null (lib.stringToCharacters imageName);
29
30let
31 # Abuse paths to collapse possible double slashes
32 repoTag0 = builtins.toString (/. + "/${stripScheme registry}/${repository}/${imageName}");
33 repoTag1 = lib.removePrefix "/" repoTag0;
34
35 layers = builtins.map stripNixStore imageLayers;
36
37 manifest = writeText "manifest.json" (
38 builtins.toJSON [
39 {
40 Config = stripNixStore imageConfig;
41 Layers = layers;
42 RepoTags = [ "${repoTag1}:${tag}" ];
43 }
44 ]
45 );
46
47 repositories = writeText "repositories" (
48 builtins.toJSON {
49 ${repoTag1} = {
50 ${tag} = lib.last layers;
51 };
52 }
53 );
54
55 imageFileStorePaths = writeText "imageFileStorePaths.txt" (
56 lib.concatStringsSep "\n" ((lib.unique imageLayers) ++ [ imageConfig ])
57 );
58in
59stdenv.mkDerivation {
60 builder = ./fetchdocker-builder.sh;
61 buildInputs = [ coreutils ];
62 preferLocalBuild = true;
63
64 inherit
65 name
66 imageName
67 repository
68 tag
69 ;
70 inherit
71 bash
72 gnutar
73 manifest
74 repositories
75 ;
76 inherit imageFileStorePaths;
77
78 passthru = {
79 inherit image;
80 };
81}