about summary refs log tree commit diff
path: root/tools/nixery/build-registry-image.nix
diff options
context:
space:
mode:
Diffstat (limited to 'tools/nixery/build-registry-image.nix')
-rw-r--r--tools/nixery/build-registry-image.nix62
1 files changed, 57 insertions, 5 deletions
diff --git a/tools/nixery/build-registry-image.nix b/tools/nixery/build-registry-image.nix
index 0d61f3b713f5..9315071135dc 100644
--- a/tools/nixery/build-registry-image.nix
+++ b/tools/nixery/build-registry-image.nix
@@ -34,14 +34,66 @@
   # plenty of room for extension. I believe the actual maximum is
   # 128.
   maxLayers ? 24,
-  # Nix channel to use
-  channel ? "nixos-19.03"
+
+  # 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"
 }:
 
-# Import the specified channel directly from Github.
 let
-  channelUrl = "https://github.com/NixOS/nixpkgs-channels/archive/${channel}.tar.gz";
-  pkgs = import (builtins.fetchTarball channelUrl) {};
+  # 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 (builtins.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 (builtins.stringLength rev) == 40 then {
+      inherit url rev;
+    } else {
+      inherit url;
+      ref = rev;
+    };
+  in import (builtins.fetchGit spec) {};
+
+  importPath = path: import (builtins.toPath path) {};
+
+  source = builtins.split "!" pkgSource;
+  sourceType = builtins.elemAt source 0;
+  pkgs = with builtins;
+    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 builtins.throw("Invalid package set source specification: ${pkgSource}");
 in
 
 # Since this is essentially a re-wrapping of some of the functionality that is