From 2db92243e748bba726e9d829f89f65dd5bf16afd Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 31 Jul 2019 01:45:09 +0100 Subject: feat(nix): Support package set imports from different sources This extends the package set import mechanism in build-registry-image.nix with several different options: 1. Importing a nixpkgs channel from Github (the default, pinned to nixos-19.03) 2. Importing a custom Nix git repository. This uses builtins.fetchGit and can thus rely on git/SSH configuration in the environment (such as keys) 3. Importing a local filesystem path As long as the repository pointed at is either a checkout of nixpkgs, or nixpkgs overlaid with custom packages this will work. A special syntax has been defined for how these three options are passed in, but users should not need to concern themselves with it as it will be taken care of by the server component. This relates to #3. --- tools/nixery/build-registry-image.nix | 62 ++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'tools') 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 -- cgit 1.4.1