about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-08-13T22·03+0100
committerVincent Ambo <github@tazj.in>2019-08-13T23·02+0100
commitd9168e3e4d8ee0be01cbe994d171d933af215f2c (patch)
tree9d21cc8f338b74bce486212d526dfb5080753e63
parent3939722063f3d08a547fa98e17aac609f7f765ac (diff)
refactor(build-image): Extract package set loading into helper
Some upcoming changes might require the Nix build to be split into
multiple separate nix-build invocations of different expressions, thus
splitting this out is useful.

It also fixes an issue where `build-image/default.nix` might be called
in an environment where no Nix channels are configured.
-rw-r--r--tools/nixery/build-image/build-image.nix64
-rw-r--r--tools/nixery/build-image/default.nix11
-rw-r--r--tools/nixery/build-image/load-pkgs.nix73
-rw-r--r--tools/nixery/default.nix4
4 files changed, 87 insertions, 65 deletions
diff --git a/tools/nixery/build-image/build-image.nix b/tools/nixery/build-image/build-image.nix
index d68ed6d37844..b67fef6ceb88 100644
--- a/tools/nixery/build-image/build-image.nix
+++ b/tools/nixery/build-image/build-image.nix
@@ -18,9 +18,11 @@
 # registry API.
 
 {
+  # Package set to used (this will usually be loaded by load-pkgs.nix)
+  pkgs,
   # Image Name
   name,
-  # Image tag, the Nix's output hash will be used if null
+  # Image tag, the Nix output's hash will be used if null
   tag ? null,
   # Tool used to determine layer grouping
   groupLayers,
@@ -36,71 +38,13 @@
   # the default here is set to something a little less than that.
   maxLayers ? 96,
 
-  # Configuration for which package set to use when building.
-  #
-  # Both channels of the public nixpkgs repository as well as imports
-  # from private repositories are supported.
-  #
-  # This setting can be invoked with three different formats:
-  #
-  # 1. nixpkgs!$channel (e.g. nixpkgs!nixos-19.03)
-  # 2. git!$repo!$rev (e.g. git!git@github.com:NixOS/nixpkgs.git!master)
-  # 3. path!$path (e.g. path!/var/local/nixpkgs)
-  #
-  # '!' was chosen as the separator because `builtins.split` does not
-  # support regex escapes and there are few other candidates. It
-  # doesn't matter much because this is invoked by the server.
-  pkgSource ? "nixpkgs!nixos-19.03",
   ...
 }:
 
-with builtins; let
-  # If a nixpkgs channel is requested, it is retrieved from Github (as
-  # a tarball) and imported.
-  fetchImportChannel = channel:
-  let url = "https://github.com/NixOS/nixpkgs-channels/archive/${channel}.tar.gz";
-  in import (fetchTarball url) {};
-
-  # If a git repository is requested, it is retrieved via
-  # builtins.fetchGit which defaults to the git configuration of the
-  # outside environment. This means that user-configured SSH
-  # credentials etc. are going to work as expected.
-  fetchImportGit = url: rev:
-  let
-    # builtins.fetchGit needs to know whether 'rev' is a reference
-    # (e.g. a branch/tag) or a revision (i.e. a commit hash)
-    #
-    # Since this data is being extrapolated from the supplied image
-    # tag, we have to guess if we want to avoid specifying a format.
-    #
-    # There are some additional caveats around whether the default
-    # branch contains the specified revision, which need to be
-    # explained to users.
-    spec = if (stringLength rev) == 40 then {
-      inherit url rev;
-    } else {
-      inherit url;
-      ref = rev;
-    };
-  in import (fetchGit spec) {};
-
-  importPath = path: import (toPath path) {};
-
-  source = split "!" pkgSource;
-  sourceType = elemAt source 0;
-  pkgs =
-    if sourceType == "nixpkgs"
-    then fetchImportChannel (elemAt source 2)
-    else if sourceType == "git"
-    then fetchImportGit (elemAt source 2) (elemAt source 4)
-    else if sourceType == "path"
-    then importPath (elemAt source 2)
-    else throw("Invalid package set source specification: ${pkgSource}");
-in
-
 # Since this is essentially a re-wrapping of some of the functionality that is
 # implemented in the dockerTools, we need all of its components in our top-level
 # namespace.
+with builtins;
 with pkgs;
 with dockerTools;
 
diff --git a/tools/nixery/build-image/default.nix b/tools/nixery/build-image/default.nix
index cff403995884..0d3002cb404e 100644
--- a/tools/nixery/build-image/default.nix
+++ b/tools/nixery/build-image/default.nix
@@ -16,14 +16,17 @@
 # moves the files needed to call the Nix builds at runtime in the
 # correct locations.
 
-{ pkgs ? import <nixpkgs> { }, self ? ./.
+{ pkgs ? null, self ? ./.
 
   # 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
+, pkgSource ? "nixpkgs!nixos-19.03"
+, tag ? null, name ? null, packages ? null, maxLayers ? null
 }@args:
 
-with pkgs; rec {
+let pkgs = import ./load-pkgs.nix { inherit pkgSource; };
+in with pkgs; rec {
+
   groupLayers = buildGoPackage {
     name = "group-layers";
     goDeps = ./go-deps.nix;
@@ -76,7 +79,7 @@ with pkgs; rec {
   };
 
   buildImage = import ./build-image.nix
-    ({ inherit groupLayers; } // (lib.filterAttrs (_: v: v != null) args));
+    ({ inherit pkgs groupLayers; } // (lib.filterAttrs (_: v: v != null) args));
 
   # Wrapper script which is called by the Nixery server to trigger an
   # actual image build. This exists to avoid having to specify the
diff --git a/tools/nixery/build-image/load-pkgs.nix b/tools/nixery/build-image/load-pkgs.nix
new file mode 100644
index 000000000000..3e8b450c45d2
--- /dev/null
+++ b/tools/nixery/build-image/load-pkgs.nix
@@ -0,0 +1,73 @@
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Load a Nix package set from a source specified in one of the following
+# formats:
+#
+# 1. nixpkgs!$channel (e.g. nixpkgs!nixos-19.03)
+# 2. git!$repo!$rev (e.g. git!git@github.com:NixOS/nixpkgs.git!master)
+# 3. path!$path (e.g. path!/var/local/nixpkgs)
+#
+# '!' was chosen as the separator because `builtins.split` does not
+# support regex escapes and there are few other candidates. It
+# doesn't matter much because this is invoked by the server.
+{ pkgSource, args ? { } }:
+
+with builtins;
+let
+  # If a nixpkgs channel is requested, it is retrieved from Github (as
+  # a tarball) and imported.
+  fetchImportChannel = channel:
+    let
+      url =
+        "https://github.com/NixOS/nixpkgs-channels/archive/${channel}.tar.gz";
+    in import (fetchTarball url) args;
+
+  # If a git repository is requested, it is retrieved via
+  # builtins.fetchGit which defaults to the git configuration of the
+  # outside environment. This means that user-configured SSH
+  # credentials etc. are going to work as expected.
+  fetchImportGit = url: rev:
+    let
+      # builtins.fetchGit needs to know whether 'rev' is a reference
+      # (e.g. a branch/tag) or a revision (i.e. a commit hash)
+      #
+      # Since this data is being extrapolated from the supplied image
+      # tag, we have to guess if we want to avoid specifying a format.
+      #
+      # There are some additional caveats around whether the default
+      # branch contains the specified revision, which need to be
+      # explained to users.
+      spec = if (stringLength rev) == 40 then {
+        inherit url rev;
+      } else {
+        inherit url;
+        ref = rev;
+      };
+    in import (fetchGit spec) args;
+
+  # No special handling is used for paths, so users are expected to pass one
+  # that will work natively with Nix.
+  importPath = path: import (toPath path) args;
+
+  source = split "!" pkgSource;
+  sourceType = elemAt source 0;
+in if sourceType == "nixpkgs" then
+  fetchImportChannel (elemAt source 2)
+else if sourceType == "git" then
+  fetchImportGit (elemAt source 2) (elemAt source 4)
+else if sourceType == "path" then
+  importPath (elemAt source 2)
+else
+  throw ("Invalid package set source specification: ${pkgSource}")
diff --git a/tools/nixery/default.nix b/tools/nixery/default.nix
index 686c230553f0..734a72d57e0b 100644
--- a/tools/nixery/default.nix
+++ b/tools/nixery/default.nix
@@ -25,7 +25,9 @@ rec {
   nixery-server = callPackage ./server { };
 
   # Implementation of the image building & layering logic
-  nixery-build-image = (import ./build-image { inherit pkgs; }).wrapper;
+  nixery-build-image = (import ./build-image {
+    pkgSource = "path!${<nixpkgs>}";
+  }).wrapper;
 
   # Use mdBook to build a static asset page which Nixery can then
   # serve. This is primarily used for the public instance at