lix/scripts/nix-pack-closure.in
Eelco Dolstra e4d4969ae9 * 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
2006-01-12 15:17:51 +00:00

67 lines
1.8 KiB
Text

#! @perl@ -w
# This tool computes the closure of a path (using "nix-store --query
# --requisites") and puts the contents of each path in the closure in
# a big NAR archive that can be installed on another Nix installation
# using "nix-unpack-closure".
# 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'"; }
mkdir "$tmpDir/contents", 0777 or die;
mkdir "$tmpDir/references", 0777 or die;
mkdir "$tmpDir/derivers", 0777 or die;
my %storePaths;
while (@ARGV) {
my $storePath = shift @ARGV;
# Get the closure of this path.
my $pid = open(READ,
"$binDir/nix-store --query --requisites " .
"--force-realise '$storePath'|") or die;
while (<READ>) {
chomp;
die "bad: $_" unless /^\//;
$storePaths{$_} = "";
}
close READ or die "nix-store failed: $?";
}
foreach my $storePath (sort(keys %storePaths)) {
print STDERR "packing `$storePath'...\n";
$storePath =~ /\/([^\/]+)$/;
my $name = $1;
system("$binDir/nix-store --dump '$storePath' > $tmpDir/contents/$name") == 0
or die "nix-store --dump failed on `$storePath': $?";
system("$binDir/nix-store --query --references '$storePath' > $tmpDir/references/$name") == 0
or die "nix-store --query --references failed on `$storePath': $?";
system("$binDir/nix-store --query --deriver '$storePath' > $tmpDir/derivers/$name") == 0
or die "nix-store --query --deriver failed on `$storePath': $?";
}
# Write a NAR archive of everything to standard output.
system("nix-store --dump '$tmpDir'") == 0
or die "nix-store --dump failed";