about summary refs log tree commit diff
path: root/tools/nixery/build-image/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'tools/nixery/build-image/default.nix')
-rw-r--r--tools/nixery/build-image/default.nix71
1 files changed, 61 insertions, 10 deletions
diff --git a/tools/nixery/build-image/default.nix b/tools/nixery/build-image/default.nix
index 4962e07deee9..cff403995884 100644
--- a/tools/nixery/build-image/default.nix
+++ b/tools/nixery/build-image/default.nix
@@ -16,25 +16,76 @@
 # moves the files needed to call the Nix builds at runtime in the
 # correct locations.
 
-{ buildGoPackage, lib, nix, writeShellScriptBin }:
+{ pkgs ? import <nixpkgs> { }, self ? ./.
 
-let
-  group-layers = buildGoPackage {
+  # Because of the insanity occuring below, this function must mirror
+  # all arguments of build-image.nix.
+, tag ? null, name ? null, packages ? null, maxLayers ? null, pkgSource ? null
+}@args:
+
+with pkgs; rec {
+  groupLayers = buildGoPackage {
     name = "group-layers";
     goDeps = ./go-deps.nix;
-    src = ./.;
-
     goPackagePath = "github.com/google/nixery/group-layers";
 
+    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+    #                    WARNING: HERE BE DRAGONS!                    #
+    #                                                                 #
+    # The hack below is used to break evaluation purity. The issue is #
+    # that Nixery's build instructions (the default.nix in the folder #
+    # above this one) must build a program that can invoke Nix at     #
+    # runtime, with a derivation that needs a program tracked in this #
+    # source tree (`group-layers`).                                   #
+    #                                                                 #
+    # Simply installing that program in the $PATH of Nixery does not  #
+    # work, because the runtime Nix builds use their own isolated     #
+    # environment.                                                    #
+    #                                                                 #
+    # I first attempted to naively copy the sources into the Nix      #
+    # store, so that Nixery could build `group-layers` when it starts #
+    # up - however those sources are not available to a nested Nix    #
+    # build because they're not part of the context of the nested     #
+    # invocation.                                                     #
+    #                                                                 #
+    # Nix has several primitives under `builtins.` that can break     #
+    # evaluation purity, these (namely readDir and readFile) are used #
+    # below to break out of the isolated environment and reconstruct  #
+    # the source tree for `group-layers`.                             #
+    #                                                                 #
+    # There might be a better way to do this, but I don't know what   #
+    # it is.                                                          #
+    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+    src = runCommand "group-layers-srcs" { } ''
+      mkdir -p $out
+      ${with builtins;
+      let
+        files =
+          (attrNames (lib.filterAttrs (_: t: t != "symlink") (readDir self)));
+        commands =
+          map (f: "cp ${toFile f (readFile "${self}/${f}")} $out/${f}") files;
+      in lib.concatStringsSep "\n" commands}
+    '';
+
     meta = {
-      description = "Tool to group a set of packages into container image layers";
+      description =
+        "Tool to group a set of packages into container image layers";
       license = lib.licenses.asl20;
       maintainers = [ lib.maintainers.tazjin ];
     };
   };
 
+  buildImage = import ./build-image.nix
+    ({ inherit groupLayers; } // (lib.filterAttrs (_: v: v != null) args));
+
   # Wrapper script which is called by the Nixery server to trigger an
-  # actual image build.
-in writeShellScriptBin "nixery-build-image" ''
-  exec ${nix}/bin/nix-build --show-trace --no-out-link "$@" ${./build-image.nix}
-''
+  # actual image build. This exists to avoid having to specify the
+  # location of build-image.nix at runtime.
+  wrapper = writeShellScriptBin "nixery-build-image" ''
+    exec ${nix}/bin/nix-build \
+      --show-trace \
+      --no-out-link "$@" \
+      --argstr self "${./.}" \
+      -A buildImage ${./.}
+  '';
+}