From 15f39aba8ceb2dabc4f019bd1c985ca9d13bfdb4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 12 Jul 2008 18:58:24 +0000 Subject: [PATCH] * Quick prototype of a substituter that copies paths from other Nix stores (typically remote Nix stores mounted via e.g. NFS, or the Nix store on the NixOS installation CD). Example use: $ sshfs foo@example.org:/ /mnt $ NIX_OTHER_STORES=/mnt/nix \ NIX_SUBSTITUTERS=.../copy-from-other-stores.pl \ nix-env -i foo This will be especially useful for the installation CD since it doesn't require a manifest for the CD contents. --- scripts/Makefile.am | 3 +- scripts/copy-from-other-stores.pl.in | 82 ++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 scripts/copy-from-other-stores.pl.in diff --git a/scripts/Makefile.am b/scripts/Makefile.am index fa66e58949..6a6226ebe7 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -9,7 +9,7 @@ noinst_SCRIPTS = nix-profile.sh generate-patches.pl \ nix-pull nix-push: readmanifest.pm readconfig.pm download-using-manifests.pl -install-exec-local: readmanifest.pm download-using-manifests.pl find-runtime-roots.pl +install-exec-local: readmanifest.pm download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl $(INSTALL) -d $(DESTDIR)$(sysconfdir)/profile.d $(INSTALL_PROGRAM) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh $(INSTALL) -d $(DESTDIR)$(libexecdir)/nix @@ -31,6 +31,7 @@ EXTRA_DIST = nix-collect-garbage.in \ readconfig.pm.in \ nix-build.in \ download-using-manifests.pl.in \ + copy-from-other-stores.pl.in \ generate-patches.pl.in \ nix-pack-closure.in nix-unpack-closure.in \ nix-copy-closure.in \ diff --git a/scripts/copy-from-other-stores.pl.in b/scripts/copy-from-other-stores.pl.in new file mode 100644 index 0000000000..4f829108b0 --- /dev/null +++ b/scripts/copy-from-other-stores.pl.in @@ -0,0 +1,82 @@ +#! @perl@ -w + +use strict; +use File::Basename; + +#print STDERR "FOO: @ARGV\n"; + +die unless defined $ENV{"NIX_OTHER_STORES"}; +my @remoteStores = split ':', $ENV{"NIX_OTHER_STORES"}; + + +sub findStorePath { + my $storePath = shift; + + my $storePathName = basename $storePath; + #print STDERR "GET $storePath\n"; + + foreach my $store (@remoteStores) { + # Determine whether $storePath exists by looking for the + # existence of the info file, and if so, get store path info + # from that file. This rather breaks abstraction: we should + # be using `nix-store' for that. But right now there is no + # good way to tell nix-store to access a store mounted under a + # different location (there's $NIX_STORE, but that only works + # if the remote store is mounted under its "real" location). + my $infoFile = "$store/var/nix/db/info/$storePathName"; + my $storePath2 = "$store/store/$storePathName"; + if (-f $infoFile && -e $storePath2) { + #print STDERR "FOUND IN $infoFile\n"; + return ($infoFile, $storePath2); + } + } +} + + +if ($ARGV[0] eq "--query-paths") { + # !!! not implemented yet; needed for `nix-env -qas' +} + + +elsif ($ARGV[0] eq "--query-info") { + shift @ARGV; + + foreach my $storePath (@ARGV) { + + (my $infoFile) = findStorePath $storePath; + #print STDERR "XXX $infoFile\n"; + + my $deriver = ""; + my @references = (); + + open INFO, "<$infoFile" or die "cannot read info file $infoFile\n"; + while () { + chomp; + #print STDERR "GOT $_\n"; + /^([\w-]+): (.*)$/ or die "bad info file"; + my $key = $1; + my $value = $2; + if ($key eq "Deriver") { $deriver = $value; } + elsif ($key eq "References") { @references = split ' ', $value; } + } + close INFO; + + print "$storePath\n"; + print "$deriver\n"; + print scalar @references, "\n"; + print "$_\n" foreach @references; + } +} + + +elsif ($ARGV[0] eq "--substitute") { + die unless scalar @ARGV == 2; + my $storePath = $ARGV[1]; + (my $infoFile, my $sourcePath) = findStorePath $storePath; + print "\n*** Copying `$storePath' from `$sourcePath'\n\n"; + system("nix-store --dump $sourcePath | nix-store --restore $storePath") == 0 + or die "cannot copy `$sourcePath' to `$storePath'"; +} + + +else { die; }