aboutsummaryrefslogtreecommitdiff
path: root/scripts/nix-unpack-closure.in
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-01-12 15:17:51 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-01-12 15:17:51 +0000
commite4d4969ae929682aea936e035cc24d56949a82ba (patch)
tree1fcddffde869e004096673698a5e18ca87049c2a /scripts/nix-unpack-closure.in
parent5b527901ae625675f525dd65b82f90bcb2001afd (diff)
* New tools nix-pack-closure and nix-unpack-closure. These provide a
useful way to transfer the closure of a store path to another machine. These commands provide functionality previously possible through `nix-push --copy'. However, they are much more convenient in many situations (though possibly less efficient). Example: $ nix-pack-closure /nix/store/hj232g1r...-subversion-1.3.0 > svn.closure (on another machine:) $ nix-unpack-closure < svn.closure Note that Subversion is added to the store, but not installed into a user environment. One should do `nix-env -i /nix/store/hj232g1r...-subversion-1.3.0' for that. Another example: copy the application Azureus to the machine `scratchy' through ssh: $ nix-pack-closure $(which azureus) | ssh scratchy nix-unpack-closure
Diffstat (limited to 'scripts/nix-unpack-closure.in')
-rw-r--r--scripts/nix-unpack-closure.in81
1 files changed, 81 insertions, 0 deletions
diff --git a/scripts/nix-unpack-closure.in b/scripts/nix-unpack-closure.in
new file mode 100644
index 000000000..98c7d84db
--- /dev/null
+++ b/scripts/nix-unpack-closure.in
@@ -0,0 +1,81 @@
+#! @perl@ -w
+
+# This tool unpacks the closures created by "nix-pack-closure" and
+# adds them to the Nix store.
+
+# TODO: make this program "streamy", i.e., don't use a temporary
+# directory.
+
+use strict;
+use POSIX qw(tmpnam);
+
+my $binDir = $ENV{"NIX_BIN_DIR"};
+$binDir = "@bindir@" unless defined $binDir;
+
+my $tmpDir;
+do { $tmpDir = tmpnam(); }
+until mkdir $tmpDir, 0777;
+END { system "rm -rf '$tmpDir'"; }
+
+
+# Unpack the NAR archive on standard input.
+system("nix-store --restore '$tmpDir/unpacked'") == 0
+ or die "nix-store --restore failed";
+
+
+open VALID, ">$tmpDir/validity" or die;
+
+
+# For each path in the closure that is not yet valid, add it to the
+# store. TODO: use proper locking. Or even better, let nix-store do
+# this.
+opendir(DIR, "$tmpDir/unpacked/contents") or die "cannot open directory: $!";
+
+foreach my $name (sort(readdir DIR)) {
+ next if $name eq "." or $name eq "..";
+
+ my $storePath = "/nix/store/$name"; # !!!
+
+ # !!! this really isn't a good validity check!
+ system "/nix/bin/nix-store --check-validity '$storePath' 2> /dev/null";
+ if ($? != 0) {
+ print STDERR "unpacking `$storePath'...\n";
+
+ # !!! race
+ system("rm -rf '$storePath'") == 0
+ or die "cannot remove `$storePath': $?";
+
+ system("$binDir/nix-store --restore '$storePath' < '$tmpDir/unpacked/contents/$name'") == 0
+ or die "nix-store --dump failed on `$storePath': $?";
+
+ print VALID "$storePath\n";
+
+ open DRV, "<$tmpDir/unpacked/derivers/$name" or die;
+ my $deriver = <DRV>;
+ chomp $deriver;
+ $deriver = "" if $deriver eq "unknown-deriver";
+ close DRV;
+
+ my @refs;
+ open REFS, "<$tmpDir/unpacked/references/$name" or die;
+ while (<REFS>) {
+ chomp;
+ push @refs, $_;
+ }
+ close REFS;
+
+ print VALID "$deriver\n";
+
+ print VALID (scalar @refs), "\n";
+ foreach my $ref (@refs) {
+ print VALID "$ref\n";
+ }
+ }
+}
+
+closedir(DIR) or die;
+
+
+# Register the invalid paths as valid.
+system("nix-store --register-validity <'$tmpDir/validity'") == 0
+ or die "nix-store --register-validity failed";