From 37f70984645b4fc5e6ed9f30a858ba6fbf402441 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 29 Jun 2012 18:28:52 -0400 Subject: [PATCH] First attempt at the manifest-less substituter --- .gitignore | 1 + perl/lib/Nix/Config.pm.in | 1 + scripts/Makefile.am | 8 +- scripts/download-from-binary-cache.pl.in | 118 +++++++++++++++++++++++ 4 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 scripts/download-from-binary-cache.pl.in diff --git a/.gitignore b/.gitignore index d7f151507f..bcc7a79f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ Makefile.in /scripts/GeneratePatches.pm /scripts/download-using-manifests.pl /scripts/copy-from-other-stores.pl +/scripts/download-from-binary-cache.pl /scripts/find-runtime-roots.pl /scripts/build-remote.pl /scripts/nix-reduce-build diff --git a/perl/lib/Nix/Config.pm.in b/perl/lib/Nix/Config.pm.in index 5adc1ffba9..64aaccd7cd 100644 --- a/perl/lib/Nix/Config.pm.in +++ b/perl/lib/Nix/Config.pm.in @@ -6,6 +6,7 @@ $stateDir = $ENV{"NIX_STATE_DIR"} || "@localstatedir@/nix"; $manifestDir = $ENV{"NIX_MANIFESTS_DIR"} || "@localstatedir@/nix/manifests"; $logDir = $ENV{"NIX_LOG_DIR"} || "@localstatedir@/log/nix"; $confDir = $ENV{"NIX_CONF_DIR"} || "@sysconfdir@/nix"; +$storeDir = $ENV{"NIX_STORE_DIR"} || "@storedir@"; $bzip2 = "@bzip2@"; $xz = "@xz@"; diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 18a59dbdb6..506b1aeb45 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -7,17 +7,14 @@ noinst_SCRIPTS = nix-profile.sh \ find-runtime-roots.pl build-remote.pl nix-reduce-build \ copy-from-other-stores.pl nix-http-export.cgi -nix-pull nix-push: download-using-manifests.pl - -install-exec-local: download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl +install-exec-local: download-using-manifests.pl copy-from-other-stores.pl download-from-binary-cache.pl find-runtime-roots.pl $(INSTALL) -d $(DESTDIR)$(sysconfdir)/profile.d $(INSTALL_DATA) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh $(INSTALL) -d $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix $(INSTALL) -d $(DESTDIR)$(libexecdir)/nix/substituters - $(INSTALL_PROGRAM) download-using-manifests.pl $(DESTDIR)$(libexecdir)/nix/substituters - $(INSTALL_PROGRAM) copy-from-other-stores.pl $(DESTDIR)$(libexecdir)/nix/substituters + $(INSTALL_PROGRAM) download-using-manifests.pl copy-from-other-stores.pl download-from-binary-cache.pl $(DESTDIR)$(libexecdir)/nix/substituters $(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix include ../substitute.mk @@ -29,6 +26,7 @@ EXTRA_DIST = nix-collect-garbage.in \ nix-build.in \ download-using-manifests.pl.in \ copy-from-other-stores.pl.in \ + download-from-binary-cache.pl.in \ nix-copy-closure.in \ find-runtime-roots.pl.in \ build-remote.pl.in \ diff --git a/scripts/download-from-binary-cache.pl.in b/scripts/download-from-binary-cache.pl.in new file mode 100644 index 0000000000..ccd28eafc6 --- /dev/null +++ b/scripts/download-from-binary-cache.pl.in @@ -0,0 +1,118 @@ +#! @perl@ -w @perlFlags@ + +use strict; +use Nix::Config; +use Nix::Store; + +my @binaryCacheUrls = ("file:///tmp/binary-cache"); + +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) { + print STDERR "GOT CURL REPLY ", $? >> 8, "\n"; + return undef; + } + my ($storePath2, $url, $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 "CompressedHash") { $fileHash = $2; } + elsif ($1 eq "CompressedSize") { $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 + , 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 = hashString("sha256", 1, $storePath); + + cache: foreach my $binaryCacheUrl (@binaryCacheUrls) { + my $info = getInfoFrom($storePath, $pathHash, $binaryCacheUrl); + return $info if defined $info; + } + + return undef; +} + +sub downloadBinary { + my ($storePath) = @_; + + my $pathHash = hashString("sha256", 1, $storePath); + + cache: foreach my $binaryCacheUrl (@binaryCacheUrls) { + my $info = getInfoFrom($storePath, $pathHash, $binaryCacheUrl); + if (defined $info) { + if (system("$Nix::Config::curl --fail --location $binaryCacheUrl/$info->{url} | $Nix::Config::xz -d | $Nix::Config::binDir/nix-store --restore $storePath") == 0) { + return 1; + } + } + } + + return 0; +} + +if ($ARGV[0] eq "--query") { + + while () { + my $cmd = $_; chomp $cmd; + + if ($cmd eq "have") { + my $storePath = ; 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 = ; 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; + exit 1 unless downloadBinary($storePath); +} + +else { + die; +}