aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/Makefile.am3
-rw-r--r--scripts/copy-from-other-stores.pl.in82
2 files changed, 84 insertions, 1 deletions
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index fa66e5894..6a6226ebe 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 000000000..4f829108b
--- /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 (<INFO>) {
+ 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; }