From 3c2de4c037b52d20476a9c47d53a0e456229ae55 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 5 Nov 2019 12:57:10 +0000 Subject: refactor(builder): Parameterise CPU architecture to use for images Adds the CPU architecture to the image configuration. This will make it possible to let users toggle architecture via meta-packages. Relates to #13 --- tools/nixery/build-image/build-image.nix | 8 +++++++- tools/nixery/server/builder/builder.go | 24 +++++++++++++++++++++++- tools/nixery/server/manifest/manifest.go | 7 +++---- 3 files changed, 33 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/nixery/build-image/build-image.nix b/tools/nixery/build-image/build-image.nix index d4df707a8a..eb14d52424 100644 --- a/tools/nixery/build-image/build-image.nix +++ b/tools/nixery/build-image/build-image.nix @@ -25,6 +25,7 @@ # Description of the package set to be used (will be loaded by load-pkgs.nix) srcType ? "nixpkgs", srcArgs ? "nixos-19.03", + system ? "x86_64-linux", importArgs ? { }, # Path to load-pkgs.nix loadPkgs ? ./load-pkgs.nix, @@ -46,7 +47,12 @@ let inherit (pkgs) lib runCommand writeText; - pkgs = import loadPkgs { inherit srcType srcArgs importArgs; }; + pkgs = import loadPkgs { + inherit srcType srcArgs; + importArgs = importArgs // { + inherit system; + }; + }; # deepFetch traverses the top-level Nix package set to retrieve an item via a # path specified in string form. diff --git a/tools/nixery/server/builder/builder.go b/tools/nixery/server/builder/builder.go index 59158037e4..c726b137fc 100644 --- a/tools/nixery/server/builder/builder.go +++ b/tools/nixery/server/builder/builder.go @@ -53,6 +53,22 @@ type State struct { Pop layers.Popularity } +// Architecture represents the possible CPU architectures for which +// container images can be built. +// +// The default architecture is amd64, but support for ARM platforms is +// available within nixpkgs and can be toggled via meta-packages. +type Architecture struct { + // Name of the system tuple to pass to Nix + nixSystem string + + // Name of the architecture as used in the OCI manifests + imageArch string +} + +var amd64 = Architecture{"x86_64-linux", "amd64"} +var arm = Architecture{"aarch64-linux", "arm64"} + // Image represents the information necessary for building a container image. // This can be either a list of package names (corresponding to keys in the // nixpkgs set) or a Nix expression that results in a *list* of derivations. @@ -63,6 +79,10 @@ type Image struct { // Names of packages to include in the image. These must correspond // directly to top-level names of Nix packages in the nixpkgs tree. Packages []string + + // Architecture for which to build the image. Nixery defaults + // this to amd64 if not specified via meta-packages. + Arch *Architecture } // BuildResult represents the data returned from the server to the @@ -96,6 +116,7 @@ func ImageFromName(name string, tag string) Image { Name: strings.Join(pkgs, "/"), Tag: tag, Packages: expanded, + Arch: &amd64, } } @@ -218,6 +239,7 @@ func prepareImage(s *State, image *Image) (*ImageResult, error) { "--argstr", "packages", string(packages), "--argstr", "srcType", srcType, "--argstr", "srcArgs", srcArgs, + "--argstr", "system", image.Arch.nixSystem, } output, err := callNix("nixery-build-image", image.Name, args) @@ -448,7 +470,7 @@ func BuildImage(ctx context.Context, s *State, image *Image) (*BuildResult, erro return nil, err } - m, c := manifest.Manifest(layers) + m, c := manifest.Manifest(image.Arch.imageArch, layers) lw := func(w io.Writer) error { r := bytes.NewReader(c.Config) diff --git a/tools/nixery/server/manifest/manifest.go b/tools/nixery/server/manifest/manifest.go index 11fef3ff0d..0d36826fb7 100644 --- a/tools/nixery/server/manifest/manifest.go +++ b/tools/nixery/server/manifest/manifest.go @@ -33,7 +33,6 @@ const ( configType = "application/vnd.docker.container.image.v1+json" // image config constants - arch = "amd64" os = "linux" fsType = "layers" ) @@ -84,7 +83,7 @@ type ConfigLayer struct { // Outside of this module the image configuration is treated as an // opaque blob and it is thus returned as an already serialised byte // array and its SHA256-hash. -func configLayer(hashes []string) ConfigLayer { +func configLayer(arch string, hashes []string) ConfigLayer { c := imageConfig{} c.Architecture = arch c.OS = os @@ -104,7 +103,7 @@ func configLayer(hashes []string) ConfigLayer { // layer. // // Callers do not need to set the media type for the layer entries. -func Manifest(layers []Entry) (json.RawMessage, ConfigLayer) { +func Manifest(arch string, layers []Entry) (json.RawMessage, ConfigLayer) { // Sort layers by their merge rating, from highest to lowest. // This makes it likely for a contiguous chain of shared image // layers to appear at the beginning of a layer. @@ -123,7 +122,7 @@ func Manifest(layers []Entry) (json.RawMessage, ConfigLayer) { layers[i] = l } - c := configLayer(hashes) + c := configLayer(arch, hashes) m := manifest{ SchemaVersion: schemaVersion, -- cgit 1.4.1