* Quick script to mirror Nix channels. Ideally it should be possible
to do this with a `wget -r' but the manifest contains absolute rather than relative URLs, so those have to be rewritten. And since they have to be rewritten anyway, we can add size and hash fields to make the manifest compatible with older version of Nix (and make the download size estimate work). git-svn-id: https://nixos.org/repos/nix/release/trunk/channels@15076 70bd8c7a-acb8-0310-9f0d-9cc1c95dcdbb
This commit is contained in:
commit
a5c419b725
74
mirror-channel.pl
Normal file
74
mirror-channel.pl
Normal file
|
@ -0,0 +1,74 @@
|
|||
use strict;
|
||||
use readmanifest;
|
||||
use File::Basename;
|
||||
use File::stat;
|
||||
use File::Temp qw/tempfile/;
|
||||
|
||||
if (scalar @ARGV != 3) {
|
||||
print STDERR "Syntax: perl mirror-channel.pl <src-channel-url> <dst-channel-url> <dst-channel-dir>\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $srcChannelURL = $ARGV[0];
|
||||
my $dstChannelURL = $ARGV[1];
|
||||
my $dstChannelPath = $ARGV[2];
|
||||
|
||||
die "$dstChannelPath doesn't exist\n" unless -d $dstChannelPath;
|
||||
|
||||
my ($fh, $tmpManifest) = tempfile(UNLINK => 1);
|
||||
print "$tmpManifest\n";
|
||||
system("curl '$srcChannelURL/MANIFEST' > $tmpManifest") == 0 or die;
|
||||
|
||||
# Read the manifest.
|
||||
my %narFiles;
|
||||
my %localPaths;
|
||||
my %patches;
|
||||
|
||||
my $version = readManifest($tmpManifest, \%narFiles, \%localPaths, \%patches);
|
||||
|
||||
%localPaths = ();
|
||||
%patches = (); # not supported yet
|
||||
|
||||
my $size = scalar (keys %narFiles);
|
||||
print "$size store paths in manifest\n";
|
||||
|
||||
# Download every file that we don't already have, and update every URL
|
||||
# to point to the mirror. Also fill in the size and hash fields in
|
||||
# the manifest in order to be compatible with Nix < 0.13.
|
||||
|
||||
while (my ($storePath, $files) = each %narFiles) {
|
||||
foreach my $file (@{$files}) {
|
||||
my $srcURL = $file->{url};
|
||||
my $dstName = basename $srcURL;
|
||||
my $dstFile = "$dstChannelPath/$dstName";
|
||||
my $dstURL = "$dstChannelURL/$dstName";
|
||||
|
||||
$file->{url} = $dstURL;
|
||||
if (! -e $dstFile) {
|
||||
print "downloading $srcURL\n";
|
||||
my $dstFileTmp = "$dstChannelPath/.tmp.$$.nar.$dstName";
|
||||
system("curl '$srcURL' > $dstFileTmp") == 0 or die;
|
||||
rename($dstFileTmp, $dstFile) or die "cannot rename $dstFileTmp";
|
||||
}
|
||||
|
||||
$file->{size} = stat($dstFile)->size or die;
|
||||
|
||||
my $hashFile = "$dstChannelPath/.hash.$dstName";
|
||||
my $hash;
|
||||
if (-e $hashFile) {
|
||||
open HASH, "<$hashFile" or die;
|
||||
$hash = <HASH>;
|
||||
close HASH;
|
||||
} else {
|
||||
$hash = `nix-hash --flat --type sha256 --base32 '$dstFile'` or die;
|
||||
chomp $hash;
|
||||
open HASH, ">$hashFile" or die;
|
||||
print HASH $hash;
|
||||
close HASH;
|
||||
}
|
||||
$file->{hash} = "sha256:$hash";
|
||||
}
|
||||
}
|
||||
|
||||
# Write the new manifest.
|
||||
writeManifest("$dstChannelPath/MANIFEST", \%narFiles, \%patches);
|
Loading…
Reference in a new issue