diff options
-rw-r--r-- | doc/functions.xml | 39 | ||||
-rw-r--r-- | pkgs/build-support/docker/default.nix | 19 |
2 files changed, 52 insertions, 6 deletions
diff --git a/doc/functions.xml b/doc/functions.xml index 3cfc6884bd26..31b40fb084a3 100644 --- a/doc/functions.xml +++ b/doc/functions.xml @@ -638,6 +638,45 @@ buildImage { <literal>pkgs.cacert</literal> to <varname>contents</varname>. </para> </note> + + <example xml:id="example-pkgs-dockerTools-buildImage-creation-date"> + <title>Impurely Defining a Docker Layer's Creation Date</title> + <para> + Because dates are an impurity, by default + <function>buildImage</function> will use a static date of one + second past the UNIX Epoch. This can be a bit frustrating when + listing docker images in the CLI: + </para> + <screen><![CDATA[ +$ docker image list +REPOSITORY TAG IMAGE ID CREATED SIZE +hello latest 08c791c7846e 48 years ago 25.2MB +]]></screen> + <para> + If you want to trade the purity for a better user experience, + you can set <literal>created</literal> to + <literal>now</literal>. + </para> + <programlisting><![CDATA[ +pkgs.dockerTools.buildImage { + name = "hello"; + tag = "latest"; + created = "now"; + contents = pkgs.hello; + + config.Cmd = [ "/bin/hello" ]; +} +]]></programlisting> + <para> + and now the Docker CLI will display a reasonable date and + sort the images as expected: + </para> + <screen><![CDATA[ +$ docker image list +REPOSITORY TAG IMAGE ID CREATED SIZE +hello latest de2bf4786de6 About a minute ago 25.2MB +]]></screen> + </example> </section> <section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry"> diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 93b715659eb0..0cee1dd2916f 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -450,11 +450,18 @@ rec { baseName = baseNameOf name; # Create a JSON blob of the configuration. Set the date to unix zero. - baseJson = writeText "${baseName}-config.json" (builtins.toJSON { - inherit created config; - architecture = "amd64"; - os = "linux"; - }); + baseJson = let + pure = writeText "${baseName}-config.json" (builtins.toJSON { + inherit created config; + architecture = "amd64"; + os = "linux"; + }); + impure = runCommand "${baseName}-config.json" + { buildInputs = [ jq ]; } + '' + jq ".created = \"$(TZ=utc date --iso-8601="seconds")\"" ${pure} > $out + ''; + in if created == "now" then impure else pure; layer = if runAsRoot == null @@ -577,7 +584,7 @@ rec { currentID=$layerID while [[ -n "$currentID" ]]; do layerChecksum=$(sha256sum image/$currentID/layer.tar | cut -d ' ' -f1) - imageJson=$(echo "$imageJson" | jq ".history |= [{\"created\": \"${created}\"}] + .") + imageJson=$(echo "$imageJson" | jq ".history |= [{\"created\": \"$(jq -r .created ${baseJson})\"}] + .") imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= [\"sha256:$layerChecksum\"] + .") manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= [\"$currentID/layer.tar\"] + .") |