diff --git a/tools/nixery/build-registry-image.nix b/tools/nixery/build-registry-image.nix index 0d61f3b71..931507113 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