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