lix/scripts/download-from-binary-cache.pl.in
Eelco Dolstra 6ec7460af1 Binary caches: use a better key
Use the hash part of the store path as a key rather than a hash of the
store path.  This is enough to get the desired privacy property.
2012-07-02 12:42:58 -04:00

137 lines
4.1 KiB
Perl
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! @perl@ -w @perlFlags@
use strict;
use File::Basename;
use Nix::Config;
use Nix::Store;
my @binaryCacheUrls = split / /, ($ENV{"NIX_BINARY_CACHES"} || "");
sub getInfoFrom {
my ($storePath, $pathHash, $binaryCacheUrl) = @_;
my $infoUrl = "$binaryCacheUrl/$pathHash.narinfo";
#print STDERR "checking $infoUrl...\n";
my $s = `$Nix::Config::curl --fail --silent --location $infoUrl`;
if ($? != 0) {
my $status = $? >> 8;
print STDERR "could not download $infoUrl (curl returned status ", $? >> 8, ")\n"
if $status != 22 && $status != 37;
return undef;
}
my ($storePath2, $url, $compression, $fileHash, $fileSize, $narHash, $narSize, $deriver);
my @refs;
foreach my $line (split "\n", $s) {
$line =~ /^(.*): (.*)$/ or return undef;
if ($1 eq "StorePath") { $storePath2 = $2; }
elsif ($1 eq "URL") { $url = $2; }
elsif ($1 eq "Compression") { $compression = $2; }
elsif ($1 eq "FileHash") { $fileHash = $2; }
elsif ($1 eq "FileSize") { $fileSize = int($2); }
elsif ($1 eq "NarHash") { $narHash = $2; }
elsif ($1 eq "NarSize") { $narSize = int($2); }
elsif ($1 eq "References") { @refs = split / /, $2; }
elsif ($1 eq "Deriver") { $deriver = $2; }
}
if ($storePath ne $storePath2 || !defined $url || !defined $narHash || !defined $narSize) {
print STDERR "bad NAR info file $infoUrl\n";
return undef
}
return
{ url => $url
, compression => ($compression || "bzip2")
, fileHash => $fileHash
, fileSize => $fileSize
, narHash => $narHash
, narSize => $narSize
, refs => [ map { "$Nix::Config::storeDir/$_" } @refs ]
, deriver => "$Nix::Config::storeDir/$deriver"
}
}
sub getInfo {
my ($storePath) = @_;
my $pathHash = substr(basename($storePath), 0, 32);
cache: foreach my $binaryCacheUrl (@binaryCacheUrls) {
my $info = getInfoFrom($storePath, $pathHash, $binaryCacheUrl);
return $info if defined $info;
}
return undef;
}
sub downloadBinary {
my ($storePath) = @_;
my $pathHash = substr(basename($storePath), 0, 32);
cache: foreach my $binaryCacheUrl (@binaryCacheUrls) {
my $info = getInfoFrom($storePath, $pathHash, $binaryCacheUrl);
if (defined $info) {
my $decompressor;
if ($info->{compression} eq "bzip2") { $decompressor = "$Nix::Config::bzip2 -d"; }
elsif ($info->{compression} eq "xz") { $decompressor = "$Nix::Config::xz -d"; }
else {
print STDERR "unknown compression method $info->{compression}\n";
next;
}
if (system("$Nix::Config::curl --fail --location $binaryCacheUrl/$info->{url} | $decompressor | $Nix::Config::binDir/nix-store --restore $storePath") == 0) {
return 1;
}
}
}
return 0;
}
if ($ARGV[0] eq "--query") {
while (<STDIN>) {
my $cmd = $_; chomp $cmd;
if ($cmd eq "have") {
my $storePath = <STDIN>; chomp $storePath;
# FIXME: want to give correct info here, but it's too slow.
print "0\n";
#my $info = getInfo($storePath);
#if (defined $info) { print "1\n"; } else { print "0\n"; }
}
elsif ($cmd eq "info") {
my $storePath = <STDIN>; chomp $storePath;
my $info = getInfo($storePath);
if (defined $info) {
print "1\n";
print $info->{deriver} || "", "\n";
print scalar @{$info->{refs}}, "\n";
print "$_\n" foreach @{$info->{refs}};
print $info->{fileSize} || 0, "\n";
print $info->{narSize}, "\n";
} else {
print "0\n";
}
}
else { die "unknown command `$cmd'"; }
flush STDOUT;
}
}
elsif ($ARGV[0] eq "--substitute") {
my $storePath = $ARGV[1] or die;
if (!downloadBinary($storePath)) {
print STDERR "could not download $storePath from any binary cache\n";
}
}
else {
die;
}