about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-11-05T12·57+0000
committerVincent Ambo <github@tazj.in>2019-11-09T15·35+0000
commit3c2de4c037b52d20476a9c47d53a0e456229ae55 (patch)
tree3f2e444f21aed55d0b9144d50067320a9af0a59c
parent7afbc912ceff01044b291388d1e0f567ac24bdef (diff)
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
-rw-r--r--tools/nixery/build-image/build-image.nix8
-rw-r--r--tools/nixery/server/builder/builder.go24
-rw-r--r--tools/nixery/server/manifest/manifest.go7
3 files changed, 33 insertions, 6 deletions
diff --git a/tools/nixery/build-image/build-image.nix b/tools/nixery/build-image/build-image.nix
index d4df707a8a3a..eb14d52424bc 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 59158037e443..c726b137fc33 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 11fef3ff0d0c..0d36826fb7e5 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,