From f6ae4479ea712a7f478a4e0dce92bd06b6f75370 Mon Sep 17 00:00:00 2001 From: Christian Kemper Date: Mon, 21 Nov 2022 12:10:07 +0000 Subject: [PATCH 1/5] dockerTools: allowing architecture to be specified ... for buildImage, buildLayeredImage and streamLayeredImage, adding docs and tests. --- doc/builders/images/dockertools.section.md | 4 ++++ nixos/tests/docker-tools.nix | 14 ++++++++++++++ pkgs/build-support/docker/default.nix | 14 ++++++++------ pkgs/build-support/docker/examples.nix | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/doc/builders/images/dockertools.section.md b/doc/builders/images/dockertools.section.md index 6203b3786bfa..dfc012b80c5a 100644 --- a/doc/builders/images/dockertools.section.md +++ b/doc/builders/images/dockertools.section.md @@ -62,6 +62,8 @@ The above example will build a Docker image `redis/latest` from the given base i - `config` is used to specify the configuration of the containers that will be started off the built image in Docker. The available options are listed in the [Docker Image Specification v1.2.0](https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions). +- `architecture` is _optional_ and used to specify the image architecture, this is useful for multi-architecture builds that don't need cross compiling. If not specified it will default to `hostPlatform`. + - `diskSize` is used to specify the disk size of the VM used to build the image in megabytes. By default it's 1024 MiB. - `buildVMMemorySize` is used to specify the memory size of the VM to build the image in megabytes. By default it's 512 MiB. @@ -141,6 +143,8 @@ Create a Docker image with many of the store paths being on their own layer to i `config` _optional_ +`architecture` is _optional_ and used to specify the image architecture, this is useful for multi-architecture builds that don't need cross compiling. If not specified it will default to `hostPlatform`. + : Run-time configuration of the container. A full list of the options are available at in the [Docker Image Specification v1.2.0](https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions). *Default:* `{}` diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index e76a46131929..71ef9ecc5d7b 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -419,6 +419,20 @@ import ./make-test-python.nix ({ pkgs, ... }: { "docker rmi layered-image-with-path", ) + with subtest("Ensure correct architecture is present in manifests."): + docker.succeed( + "docker load --input='${examples.build-image-with-architecture}'", + "docker inspect ${examples.build-image-with-architecture} " + + "| ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture'", + "docker rmi build-image-with-architecture", + ) + docker.succeed( + "${examples.layered-image-with-architecture} | docker load", + "docker inspect ${examples.layered-image-with-architecture} " + + "| ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture'", + "docker rmi layered-image-with-architecture", + ) + with subtest("etc"): docker.succeed("${examples.etc} | docker load") docker.succeed("docker run --rm etc | grep localhost") diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index c6ab4589aefa..bc1b58a684fe 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -101,8 +101,8 @@ rec { , imageDigest , sha256 , os ? "linux" - , arch ? defaultArch - + , # Image architecture, defaults to the architecture of the `hostPlatform` when unset + arch ? defaultArch # This is used to set name to the pulled image , finalImageName ? imageName # This used to set a tag to the pulled image @@ -514,6 +514,8 @@ rec { keepContentsDirlinks ? false , # Docker config; e.g. what command to run on the container. config ? null + , # Image architecture, defaults to the architecture of the `hostPlatform` when unset + architecture ? defaultArch , # Optional bash script to run on the files prior to fixturizing the layer. extraCommands ? "" , uid ? 0 @@ -546,8 +548,7 @@ rec { baseJson = let pure = writeText "${baseName}-config.json" (builtins.toJSON { - inherit created config; - architecture = defaultArch; + inherit created config architecture; preferLocalBuild = true; os = "linux"; }); @@ -838,6 +839,8 @@ rec { contents ? [ ] , # Docker config; e.g. what command to run on the container. config ? { } + , # Image architecture, defaults to the architecture of the `hostPlatform` when unset + architecture ? defaultArch , # Time of creation of the image. Passing "now" will make the # created date be the time of building. created ? "1970-01-01T00:00:01Z" @@ -869,8 +872,7 @@ rec { streamScript = writePython3 "stream" { } ./stream_layered_image.py; baseJson = writeText "${baseName}-base.json" (builtins.toJSON { - inherit config; - architecture = defaultArch; + inherit config architecture; os = "linux"; }); diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index 71c3574963c8..80661c1a7d9a 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -700,6 +700,21 @@ rec { contents = [ pkgs.bashInteractive ./test-dummy ]; }; + build-image-with-architecture = buildImage { + name = "build-image-with-architecture"; + tag = "latest"; + architecture = "arm64"; + # Not recommended. Use `buildEnv` between copy and packages to avoid file duplication. + copyToRoot = [ pkgs.bashInteractive ./test-dummy ]; + }; + + layered-image-with-architecture = pkgs.dockerTools.streamLayeredImage { + name = "layered-image-with-architecture"; + tag = "latest"; + architecture = "arm64"; + contents = [ pkgs.bashInteractive ./test-dummy ]; + }; + # ensure that caCertificates builds image-with-certs = buildImage { name = "image-with-certs"; From 3e28f972fc389b9a4659cc70de7257dfd9022546 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 7 Dec 2022 14:07:47 +0100 Subject: [PATCH 2/5] dockerTools: refactor, rename internal variable > has to fit its domain, which is the OCI spec, which uses > `architecture`. The `defaultArch` and `GOARCH` names are irrelevant. --- pkgs/build-support/docker/default.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index bc1b58a684fe..48c780e2dbe4 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -74,7 +74,7 @@ let # Reference: https://github.com/opencontainers/image-spec/blob/master/config.md#properties # For the mapping from Nixpkgs system parameters to GOARCH, we can reuse the # mapping from the go package. - defaultArch = go.GOARCH; + defaultArchitecture = go.GOARCH; in rec { @@ -102,7 +102,7 @@ rec { , sha256 , os ? "linux" , # Image architecture, defaults to the architecture of the `hostPlatform` when unset - arch ? defaultArch + arch ? defaultArchitecture # This is used to set name to the pulled image , finalImageName ? imageName # This used to set a tag to the pulled image @@ -515,7 +515,7 @@ rec { , # Docker config; e.g. what command to run on the container. config ? null , # Image architecture, defaults to the architecture of the `hostPlatform` when unset - architecture ? defaultArch + architecture ? defaultArchitecture , # Optional bash script to run on the files prior to fixturizing the layer. extraCommands ? "" , uid ? 0 @@ -840,7 +840,7 @@ rec { , # Docker config; e.g. what command to run on the container. config ? { } , # Image architecture, defaults to the architecture of the `hostPlatform` when unset - architecture ? defaultArch + architecture ? defaultArchitecture , # Time of creation of the image. Passing "now" will make the # created date be the time of building. created ? "1970-01-01T00:00:01Z" From afe2d0bb8b10de5f335952581a29c6d1f8929d21 Mon Sep 17 00:00:00 2001 From: Christian Kemper Date: Thu, 8 Dec 2022 14:36:29 +0000 Subject: [PATCH 3/5] fix docker inspect image reference --- nixos/tests/docker-tools.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index 71ef9ecc5d7b..bf0a511da2f6 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -422,13 +422,13 @@ import ./make-test-python.nix ({ pkgs, ... }: { with subtest("Ensure correct architecture is present in manifests."): docker.succeed( "docker load --input='${examples.build-image-with-architecture}'", - "docker inspect ${examples.build-image-with-architecture} " + "docker inspect build-image-with-architecture " + "| ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture'", "docker rmi build-image-with-architecture", ) docker.succeed( "${examples.layered-image-with-architecture} | docker load", - "docker inspect ${examples.layered-image-with-architecture} " + "docker inspect layered-image-with-architecture " + "| ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture'", "docker rmi layered-image-with-architecture", ) From 454d2307ae193a5c26c4e61b7f4690abae710f9f Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 8 Dec 2022 22:29:10 +0100 Subject: [PATCH 4/5] nixosTests.docker-tools: Fix nginx test --- pkgs/build-support/docker/examples.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index 80661c1a7d9a..5784e650dc2e 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -92,7 +92,7 @@ rec { ]; extraCommands = '' - mkdir -p tmp + mkdir -p tmp/nginx_client_body # nginx still tries to read this directory even if error_log # directive is specifying another file :/ From cf7b358d69e2aaf330fd4219d2b552a250365645 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 8 Dec 2022 22:29:19 +0100 Subject: [PATCH 5/5] nixosTests.docker-tools: Fix syntax This may be unnecessary, but I'm not waiting for the tests again. --- nixos/tests/docker-tools.nix | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index bf0a511da2f6..98704ecb2fb6 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -420,18 +420,18 @@ import ./make-test-python.nix ({ pkgs, ... }: { ) with subtest("Ensure correct architecture is present in manifests."): - docker.succeed( - "docker load --input='${examples.build-image-with-architecture}'", - "docker inspect build-image-with-architecture " - + "| ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture'", - "docker rmi build-image-with-architecture", - ) - docker.succeed( - "${examples.layered-image-with-architecture} | docker load", - "docker inspect layered-image-with-architecture " - + "| ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture'", - "docker rmi layered-image-with-architecture", - ) + docker.succeed(""" + docker load --input='${examples.build-image-with-architecture}' + docker inspect build-image-with-architecture \ + | ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture' + docker rmi build-image-with-architecture + """) + docker.succeed(""" + ${examples.layered-image-with-architecture} | docker load + docker inspect layered-image-with-architecture \ + | ${pkgs.jq}/bin/jq -er '.[] | select(.Architecture=="arm64").Architecture' + docker rmi layered-image-with-architecture + """) with subtest("etc"): docker.succeed("${examples.etc} | docker load")