* download-using-manifests: use the Perl bindings.
This commit is contained in:
parent
b1eb8f4249
commit
1749a7b0ae
3 changed files with 45 additions and 38 deletions
|
@ -12,7 +12,11 @@ our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
|
||||||
|
|
||||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||||
|
|
||||||
our @EXPORT = qw(isValidPath topoSortPaths computeFSClosure followLinksToStorePath exportPaths);
|
our @EXPORT = qw(
|
||||||
|
isValidPath queryReferences queryPathInfo queryDeriver queryPathHash
|
||||||
|
topoSortPaths computeFSClosure followLinksToStorePath exportPaths
|
||||||
|
hashPath
|
||||||
|
);
|
||||||
|
|
||||||
our $VERSION = '0.15';
|
our $VERSION = '0.15';
|
||||||
|
|
||||||
|
|
|
@ -159,3 +159,14 @@ void exportPaths(int fd, int sign, ...)
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
croak(e.what());
|
croak(e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SV * hashPath(char * algo, int base32, char * path)
|
||||||
|
PPCODE:
|
||||||
|
try {
|
||||||
|
Hash h = hashPath(parseHashType(algo), path).first;
|
||||||
|
string s = base32 ? printHash32(h) : printHash(h);
|
||||||
|
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||||
|
} catch (Error & e) {
|
||||||
|
croak(e.what());
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use strict;
|
use strict;
|
||||||
use Nix::Config;
|
use Nix::Config;
|
||||||
use Nix::Manifest;
|
use Nix::Manifest;
|
||||||
|
use Nix::Store;
|
||||||
use POSIX qw(strftime);
|
use POSIX qw(strftime);
|
||||||
use File::Temp qw(tempdir);
|
use File::Temp qw(tempdir);
|
||||||
|
|
||||||
|
@ -19,14 +20,8 @@ my $fast = 1;
|
||||||
my $dbh = updateManifestDB();
|
my $dbh = updateManifestDB();
|
||||||
|
|
||||||
|
|
||||||
sub isValidPath {
|
# $hashCache->{$algo}->{$path} yields the $algo-hash of $path.
|
||||||
my $p = shift;
|
my $hashCache;
|
||||||
if ($fast) {
|
|
||||||
return -e $p;
|
|
||||||
} else {
|
|
||||||
return system("$Nix::Config::binDir/nix-store --check-validity '$p' 2> /dev/null") == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub parseHash {
|
sub parseHash {
|
||||||
|
@ -101,15 +96,17 @@ sub computeSmallestDownload {
|
||||||
|
|
||||||
foreach my $patch (@{$patchList}) {
|
foreach my $patch (@{$patchList}) {
|
||||||
if (isValidPath($patch->{basePath})) {
|
if (isValidPath($patch->{basePath})) {
|
||||||
# !!! this should be cached
|
|
||||||
my ($baseHashAlgo, $baseHash) = parseHash $patch->{baseHash};
|
my ($baseHashAlgo, $baseHash) = parseHash $patch->{baseHash};
|
||||||
my $format = "--base32";
|
|
||||||
$format = "" if $baseHashAlgo eq "md5";
|
my $hash = $hashCache->{$baseHashAlgo}->{$patch->{basePath}};
|
||||||
my $hash = $fast && $baseHashAlgo eq "sha256"
|
if (!defined $hash) {
|
||||||
? `$Nix::Config::binDir/nix-store -q --hash "$patch->{basePath}"`
|
$hash = $fast && $baseHashAlgo eq "sha256"
|
||||||
: `$Nix::Config::binDir/nix-hash --type '$baseHashAlgo' $format "$patch->{basePath}"`;
|
? queryPathHash($patch->{basePath})
|
||||||
chomp $hash;
|
: hashPath($baseHashAlgo, $baseHashAlgo ne "md5", $patch->{basePath});
|
||||||
$hash =~ s/.*://;
|
$hash =~ s/.*://;
|
||||||
|
$hashCache->{$baseHashAlgo}->{$patch->{basePath}} = $hash;
|
||||||
|
}
|
||||||
|
|
||||||
next if $hash ne $baseHash;
|
next if $hash ne $baseHash;
|
||||||
}
|
}
|
||||||
push @queue, $patch->{basePath};
|
push @queue, $patch->{basePath};
|
||||||
|
@ -257,7 +254,7 @@ open LOGFILE, ">>$logFile" or die "cannot open log file $logFile";
|
||||||
my $date = strftime ("%F %H:%M:%S UTC", gmtime (time));
|
my $date = strftime ("%F %H:%M:%S UTC", gmtime (time));
|
||||||
print LOGFILE "$$ get $targetPath $date\n";
|
print LOGFILE "$$ get $targetPath $date\n";
|
||||||
|
|
||||||
print "\n*** Trying to download/patch `$targetPath'\n";
|
print STDERR "\n*** Trying to download/patch `$targetPath'\n";
|
||||||
|
|
||||||
|
|
||||||
# Compute the shortest path.
|
# Compute the shortest path.
|
||||||
|
@ -281,7 +278,7 @@ sub downloadFile {
|
||||||
$ENV{"PRINT_PATH"} = 1;
|
$ENV{"PRINT_PATH"} = 1;
|
||||||
$ENV{"QUIET"} = 1;
|
$ENV{"QUIET"} = 1;
|
||||||
my ($hash, $path) = `$Nix::Config::binDir/nix-prefetch-url '$url'`;
|
my ($hash, $path) = `$Nix::Config::binDir/nix-prefetch-url '$url'`;
|
||||||
die "download of `$url' failed" . ($! ? ": $!" : "") unless $? == 0;
|
die "download of `$url' failed" . ($! ? ": $!" : "") . "\n" unless $? == 0;
|
||||||
chomp $path;
|
chomp $path;
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
@ -293,17 +290,17 @@ while (scalar @path > 0) {
|
||||||
my $u = $edge->{start};
|
my $u = $edge->{start};
|
||||||
my $v = $edge->{end};
|
my $v = $edge->{end};
|
||||||
|
|
||||||
print "\n*** Step $curStep/$maxStep: ";
|
print STDERR "\n*** Step $curStep/$maxStep: ";
|
||||||
|
|
||||||
if ($edge->{type} eq "present") {
|
if ($edge->{type} eq "present") {
|
||||||
print "using already present path `$v'\n";
|
print STDERR "using already present path `$v'\n";
|
||||||
print LOGFILE "$$ present $v\n";
|
print LOGFILE "$$ present $v\n";
|
||||||
|
|
||||||
if ($curStep < $maxStep) {
|
if ($curStep < $maxStep) {
|
||||||
# Since this is not the last step, the path will be used
|
# Since this is not the last step, the path will be used
|
||||||
# as a base to one or more patches. So turn the base path
|
# as a base to one or more patches. So turn the base path
|
||||||
# into a NAR archive, to which we can apply the patch.
|
# into a NAR archive, to which we can apply the patch.
|
||||||
print " packing base path...\n";
|
print STDERR " packing base path...\n";
|
||||||
system("$Nix::Config::binDir/nix-store --dump $v > $tmpNar") == 0
|
system("$Nix::Config::binDir/nix-store --dump $v > $tmpNar") == 0
|
||||||
or die "cannot dump `$v'";
|
or die "cannot dump `$v'";
|
||||||
}
|
}
|
||||||
|
@ -311,17 +308,17 @@ while (scalar @path > 0) {
|
||||||
|
|
||||||
elsif ($edge->{type} eq "patch") {
|
elsif ($edge->{type} eq "patch") {
|
||||||
my $patch = $edge->{info};
|
my $patch = $edge->{info};
|
||||||
print "applying patch `$patch->{url}' to `$u' to create `$v'\n";
|
print STDERR "applying patch `$patch->{url}' to `$u' to create `$v'\n";
|
||||||
|
|
||||||
print LOGFILE "$$ patch $patch->{url} $patch->{size} $patch->{baseHash} $u $v\n";
|
print LOGFILE "$$ patch $patch->{url} $patch->{size} $patch->{baseHash} $u $v\n";
|
||||||
|
|
||||||
# Download the patch.
|
# Download the patch.
|
||||||
print " downloading patch...\n";
|
print STDERR " downloading patch...\n";
|
||||||
my $patchPath = downloadFile "$patch->{url}";
|
my $patchPath = downloadFile "$patch->{url}";
|
||||||
|
|
||||||
# Apply the patch to the NAR archive produced in step 1 (for
|
# Apply the patch to the NAR archive produced in step 1 (for
|
||||||
# the already present path) or a later step (for patch sequences).
|
# the already present path) or a later step (for patch sequences).
|
||||||
print " applying patch...\n";
|
print STDERR " applying patch...\n";
|
||||||
system("$Nix::Config::libexecDir/bspatch $tmpNar $tmpNar2 $patchPath") == 0
|
system("$Nix::Config::libexecDir/bspatch $tmpNar $tmpNar2 $patchPath") == 0
|
||||||
or die "cannot apply patch `$patchPath' to $tmpNar";
|
or die "cannot apply patch `$patchPath' to $tmpNar";
|
||||||
|
|
||||||
|
@ -331,7 +328,7 @@ while (scalar @path > 0) {
|
||||||
} else {
|
} else {
|
||||||
# This was the last patch. Unpack the final NAR archive
|
# This was the last patch. Unpack the final NAR archive
|
||||||
# into the target path.
|
# into the target path.
|
||||||
print " unpacking patched archive...\n";
|
print STDERR " unpacking patched archive...\n";
|
||||||
system("$Nix::Config::binDir/nix-store --restore $v < $tmpNar2") == 0
|
system("$Nix::Config::binDir/nix-store --restore $v < $tmpNar2") == 0
|
||||||
or die "cannot unpack $tmpNar2 into `$v'";
|
or die "cannot unpack $tmpNar2 into `$v'";
|
||||||
}
|
}
|
||||||
|
@ -341,13 +338,13 @@ while (scalar @path > 0) {
|
||||||
|
|
||||||
elsif ($edge->{type} eq "narfile") {
|
elsif ($edge->{type} eq "narfile") {
|
||||||
my $narFile = $edge->{info};
|
my $narFile = $edge->{info};
|
||||||
print "downloading `$narFile->{url}' into `$v'\n";
|
print STDERR "downloading `$narFile->{url}' into `$v'\n";
|
||||||
|
|
||||||
my $size = $narFile->{size} || -1;
|
my $size = $narFile->{size} || -1;
|
||||||
print LOGFILE "$$ narfile $narFile->{url} $size $v\n";
|
print LOGFILE "$$ narfile $narFile->{url} $size $v\n";
|
||||||
|
|
||||||
# Download the archive.
|
# Download the archive.
|
||||||
print " downloading archive...\n";
|
print STDERR " downloading archive...\n";
|
||||||
my $narFilePath = downloadFile "$narFile->{url}";
|
my $narFilePath = downloadFile "$narFile->{url}";
|
||||||
|
|
||||||
if ($curStep < $maxStep) {
|
if ($curStep < $maxStep) {
|
||||||
|
@ -356,7 +353,7 @@ while (scalar @path > 0) {
|
||||||
or die "cannot unpack `$narFilePath' into `$v'";
|
or die "cannot unpack `$narFilePath' into `$v'";
|
||||||
} else {
|
} else {
|
||||||
# Unpack the archive into the target path.
|
# Unpack the archive into the target path.
|
||||||
print " unpacking archive...\n";
|
print STDERR " unpacking archive...\n";
|
||||||
system("$Nix::Config::bzip2 -d < '$narFilePath' | $Nix::Config::binDir/nix-store --restore '$v'") == 0
|
system("$Nix::Config::bzip2 -d < '$narFilePath' | $Nix::Config::binDir/nix-store --restore '$v'") == 0
|
||||||
or die "cannot unpack `$narFilePath' into `$v'";
|
or die "cannot unpack `$narFilePath' into `$v'";
|
||||||
}
|
}
|
||||||
|
@ -376,20 +373,15 @@ if (defined $finalNarHash) {
|
||||||
|
|
||||||
# The hash in the manifest can be either in base-16 or base-32.
|
# The hash in the manifest can be either in base-16 or base-32.
|
||||||
# Handle both.
|
# Handle both.
|
||||||
my $extraFlag =
|
my $hash2 = hashPath($hashAlgo, $hashAlgo eq "sha256" && length($hash) != 64, $targetPath);
|
||||||
($hashAlgo eq "sha256" && length($hash) != 64)
|
|
||||||
? "--base32" : "";
|
|
||||||
|
|
||||||
my $hash2 = `$Nix::Config::binDir/nix-hash --type $hashAlgo $extraFlag $targetPath`
|
die "hash mismatch in downloaded path $targetPath; expected $hash, got $hash2\n"
|
||||||
or die "cannot compute hash of path `$targetPath'";
|
|
||||||
chomp $hash2;
|
|
||||||
|
|
||||||
die "hash mismatch in downloaded path $targetPath; expected $hash, got $hash2"
|
|
||||||
if $hash ne $hash2;
|
if $hash ne $hash2;
|
||||||
} else {
|
} else {
|
||||||
die "cannot check integrity of the downloaded path since its hash is not known";
|
die "cannot check integrity of the downloaded path since its hash is not known\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print STDERR "\n";
|
||||||
print LOGFILE "$$ success\n";
|
print LOGFILE "$$ success\n";
|
||||||
close LOGFILE;
|
close LOGFILE;
|
||||||
|
|
Loading…
Reference in a new issue