Script for signing existing .narinfo files in a binary cache
This commit is contained in:
parent
d84441483e
commit
c76fc42d03
101
sign-binary-cache.pl
Executable file
101
sign-binary-cache.pl
Executable file
|
@ -0,0 +1,101 @@
|
|||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i perl -p perl perlPackages.NetAmazonS3 perlPackages.ForksSuper perlPackages.DBDSQLite
|
||||
|
||||
use strict;
|
||||
use Forks::Super 'bg_eval';
|
||||
use List::MoreUtils qw(part);
|
||||
use MIME::Base64;
|
||||
use Net::Amazon::S3;
|
||||
use Nix::Manifest;
|
||||
use Nix::Store;
|
||||
use Nix::Utils;
|
||||
|
||||
my $bucketName = "nix-cache";
|
||||
my $nrProcesses = 16;
|
||||
my $secretKeyFile = "/home/eelco/Misc/Keys/cache.nixos.org-1/secret";
|
||||
|
||||
my $s = readFile $secretKeyFile;
|
||||
chomp $s;
|
||||
my ($keyName, $secretKey) = split ":", $s;
|
||||
die "invalid secret key file ‘$secretKeyFile’\n" unless defined $keyName && defined $secretKey;
|
||||
|
||||
my @files;
|
||||
while (<>) {
|
||||
chomp;
|
||||
push @files, $_;
|
||||
}
|
||||
|
||||
# S3 setup.
|
||||
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die;
|
||||
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die;
|
||||
|
||||
my $s3 = Net::Amazon::S3->new(
|
||||
{ aws_access_key_id => $aws_access_key_id,
|
||||
aws_secret_access_key => $aws_secret_access_key,
|
||||
retry => 1,
|
||||
});
|
||||
|
||||
my $bucket = $s3->bucket($bucketName) or die;
|
||||
|
||||
# Process .narinfos.
|
||||
sub signNarInfo {
|
||||
my ($fn) = @_;
|
||||
|
||||
die unless $fn =~ /\.narinfo$/;
|
||||
|
||||
my $get = $bucket->get_key($fn, "GET");
|
||||
die "failed to get $fn\n" unless defined $get;
|
||||
|
||||
my $contents = $get->{value};
|
||||
|
||||
$contents =~ /^StorePath: (\S+)$/m;
|
||||
die "corrupt NAR info $fn" unless defined $1;
|
||||
my $storePath = $1;
|
||||
|
||||
if ($contents =~ /^Sig:/m) {
|
||||
print STDERR "skipping already signed $fn\n";
|
||||
return;
|
||||
}
|
||||
|
||||
print STDERR "signing $fn...\n";
|
||||
|
||||
my $narInfo = parseNARInfo($storePath, $contents);
|
||||
die "failed to parse NAR info of $fn\n" unless $narInfo;
|
||||
|
||||
# Legacy: convert base16 to base32.
|
||||
my $narHash = $narInfo->{narHash};
|
||||
if (length $narHash != 59) {
|
||||
$narHash = `nix-hash --type sha256 --to-base32 ${\(substr($narHash, 7))}`;
|
||||
chomp $narHash;
|
||||
$narHash = "sha256:$narHash";
|
||||
}
|
||||
|
||||
#print STDERR "$storePath -> $narInfo->{narHash} $narHash $narInfo->{narSize}\n";
|
||||
|
||||
my $refs = [ map { "$Nix::Config::storeDir/$_" } @{$narInfo->{refs}} ];
|
||||
my $fingerprint = fingerprintPath($storePath, $narHash, $narInfo->{narSize}, $refs);
|
||||
#print STDERR "FP = $fingerprint\n";
|
||||
my $sig = encode_base64(signString(decode_base64($secretKey), $fingerprint), "");
|
||||
$contents .= "Sig: $keyName:$sig\n";
|
||||
|
||||
$bucket->add_key($fn, $contents) or die "failed to upload $fn\n";
|
||||
}
|
||||
|
||||
# Fork processes to sign files in parallel.
|
||||
my $i = 0;
|
||||
my @filesPerProcess = part { $i++ % $nrProcesses } @files;
|
||||
my @res;
|
||||
for (my $n = 0; $n < $nrProcesses; $n++) {
|
||||
push @res, bg_eval {
|
||||
foreach my $fn (@{$filesPerProcess[$n]}) {
|
||||
eval {
|
||||
signNarInfo($fn);
|
||||
};
|
||||
warn "$@" if $@;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
foreach my $res (@res) { if ($res) { } }
|
||||
print STDERR "DONE\n";
|
Loading…
Reference in a new issue