Merge pull request #201902 from ck3mp3r/dockertools-architecture-in-config-200725

Adding ability to set image architecture when creating OCI images using DockerTools

Changed files
+43 -8
doc
builders
nixos
pkgs
build-support
+4
doc/builders/images/dockertools.section.md
···
- `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.
···
*Default:* `[]`
`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).
+14
nixos/tests/docker-tools.nix
···
"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 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")
docker.succeed("docker run --rm etc | grep localhost")
+9 -7
pkgs/build-support/docker/default.nix
···
# 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 {
···
, imageDigest
, sha256
, os ? "linux"
-
, arch ? defaultArch
-
+
, # Image architecture, defaults to the architecture of the `hostPlatform` when unset
+
arch ? defaultArchitecture
# This is used to set name to the pulled image
, finalImageName ? imageName
# This used to set a tag to the pulled image
···
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 ? defaultArchitecture
, # Optional bash script to run on the files prior to fixturizing the layer.
extraCommands ? ""
, uid ? 0
···
baseJson =
let
pure = writeText "${baseName}-config.json" (builtins.toJSON {
-
inherit created config;
-
architecture = defaultArch;
+
inherit created config architecture;
preferLocalBuild = true;
os = "linux";
});
···
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 ? 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"
···
streamScript = writePython3 "stream" { } ./stream_layered_image.py;
baseJson = writeText "${baseName}-base.json" (builtins.toJSON {
-
inherit config;
-
architecture = defaultArch;
+
inherit config architecture;
os = "linux";
});
+16 -1
pkgs/build-support/docker/examples.nix
···
];
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 :/
···
layered-image-with-path = pkgs.dockerTools.streamLayeredImage {
name = "layered-image-with-path";
tag = "latest";
+
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 ];
};