diff --git a/corepkgs/unpack-channel.nix b/corepkgs/unpack-channel.nix
index bbc54c7d1..57d5a09a0 100644
--- a/corepkgs/unpack-channel.nix
+++ b/corepkgs/unpack-channel.nix
@@ -6,19 +6,23 @@ let
''
mkdir $out
cd $out
- ${bzip2} -d < $src | ${tar} xf - --warning=no-timestamp
+ ${bzip2} -d < $src | ${tar} xf - --warning=no-timestamp
mv * $out/$channelName
+ if [ -n "$binaryCacheURL" ]; then
+ mkdir $out/binary-caches
+ echo -n "$binaryCacheURL" > $out/binary-caches/$channelName
+ fi
'';
in
-{ name, channelName, src }:
+{ name, channelName, src, binaryCacheURL ? "" }:
derivation {
system = builtins.currentSystem;
builder = shell;
args = [ "-e" builder ];
- inherit name channelName src;
+ inherit name channelName src binaryCacheURL;
PATH = "${nixBinDir}:${coreutils}";
diff --git a/doc/manual/conf-file.xml b/doc/manual/conf-file.xml
index c09d46206..ae167fb78 100644
--- a/doc/manual/conf-file.xml
+++ b/doc/manual/conf-file.xml
@@ -329,6 +329,18 @@ build-use-chroot = /dev /proc /bin
+ binary-caches-files
+
+ A list of names of files that will be read to
+ obtain additional binary cache URLs. The default is
+ /nix/var/nix/profiles/per-user/root/channels/binary-caches/*,
+ which ensures that Nix will use the binary caches corresponding to
+ the channels installed by root. Do not set this option to read
+ files created by untrusted users!
+
+
+
+
trusted-binary-caches
A list of URLs of binary caches, separated by
diff --git a/scripts/download-from-binary-cache.pl.in b/scripts/download-from-binary-cache.pl.in
index f7f1f7346..76306405c 100644
--- a/scripts/download-from-binary-cache.pl.in
+++ b/scripts/download-from-binary-cache.pl.in
@@ -176,6 +176,16 @@ sub getAvailableCaches {
($Nix::Config::config{"binary-caches"}
// ($Nix::Config::storeDir eq "/nix/store" ? "http://nixos.org/binary-cache" : ""));
+ my $urlsFiles = $Nix::Config::config{"binary-cache-files"}
+ // "/nix/var/nix/profiles/per-user/root/channels/binary-caches/*";
+ foreach my $urlFile (glob $urlsFiles) {
+ next unless -f $urlFile;
+ open FILE, "<$urlFile" or die "cannot open ‘$urlFile’\n";
+ my $url = ; chomp $url;
+ close FILE;
+ push @urls, strToList($url);
+ }
+
# Allow Nix daemon users to override the binary caches to a subset
# of those listed in the config file. Note that ‘untrusted-*’
# denotes options passed by the client.
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
index e7a4b0900..e057cc916 100755
--- a/scripts/nix-channel.in
+++ b/scripts/nix-channel.in
@@ -22,7 +22,7 @@ my $nixDefExpr = "$home/.nix-defexpr";
my $userName = getpwuid($<) or die "cannot figure out user name";
my $profile = "$Nix::Config::stateDir/profiles/per-user/$userName/channels";
mkpath(dirname $profile, 0, 0755);
-
+
my %channels;
@@ -77,20 +77,14 @@ sub removeChannel {
# channels.
sub update {
my @channelNames = @_;
-
+
readChannels;
- # Create the manifests directory if it doesn't exist.
- mkdir $manifestDir, 0755 unless -e $manifestDir;
-
- # Do we have write permission to the manifests directory?
- die "$0: you do not have write permission to `$manifestDir'!\n" unless -W $manifestDir;
-
# Download each channel.
my $exprs = "";
foreach my $name (keys %channels) {
next if scalar @channelNames > 0 && ! grep { $_ eq $name } @{channelNames};
-
+
my $url = $channels{$name};
my $origUrl = "$url/MANIFEST";
@@ -101,11 +95,20 @@ sub update {
die "$0: unable to check `$url'\n" if $? != 0;
$headers =~ s/\r//g;
$url = $1 if $headers =~ /^Location:\s*(.*)\s*$/m;
-
- # Pull the channel manifest.
- $ENV{'NIX_ORIG_URL'} = $origUrl;
- system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
- or die "cannot pull manifest from `$url'\n";
+
+ # Check if the channel advertises a binary cache.
+ my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`;
+ my $extraAttrs = "";
+ if ($? == 0 && $binaryCacheURL ne "") {
+ $extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
+ } else {
+ # No binary cache, so pull the channel manifest.
+ mkdir $manifestDir, 0755 unless -e $manifestDir;
+ die "$0: you do not have write permission to `$manifestDir'!\n" unless -W $manifestDir;
+ $ENV{'NIX_ORIG_URL'} = $origUrl;
+ system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
+ or die "cannot pull manifest from `$url'\n";
+ }
# Download the channel tarball.
my $fullURL = "$url/nixexprs.tar.bz2";
@@ -120,7 +123,7 @@ sub update {
my $cname = $name;
$cname .= $1 if basename($url) =~ /(-\d.*)$/;
- $exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; }' ";
+ $exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; $extraAttrs }' ";
}
# Unpack the channel tarballs into the Nix store and install them
@@ -189,7 +192,7 @@ while (scalar @ARGV) {
update(@ARGV);
last;
}
-
+
elsif ($arg eq "--help") {
usageError;
}
@@ -198,7 +201,7 @@ while (scalar @ARGV) {
print "nix-channel (Nix) $Nix::Config::version\n";
exit 0;
}
-
+
else {
die "unknown argument `$arg'; try `--help'";
}