From 763db9879ce48bd817f5b659b6a4168f7b711ec4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 24 Jan 2019 19:07:26 +0100 Subject: [PATCH] Store the channel redirects in S3 --- mirror-nixos-branch.pl | 55 +++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/mirror-nixos-branch.pl b/mirror-nixos-branch.pl index 9c37fc6..4483852 100755 --- a/mirror-nixos-branch.pl +++ b/mirror-nixos-branch.pl @@ -25,8 +25,8 @@ my $channelDirRel = $channelName eq "nixpkgs-unstable" ? "nixpkgs" : "$1/$2"; # Configuration. -my $channelsDir = "/data/releases/channels"; -my $filesCache = "/data/releases/nixos-files.sqlite"; +my $TMPDIR = $ENV{'TMPDIR'} // "/tmp"; +my $filesCache = "${TMPDIR}/nixos-files.sqlite"; my $bucketName = "nix-releases"; $ENV{'GIT_DIR'} = "/home/hydra-mirror/nixpkgs-channels"; @@ -66,22 +66,27 @@ my $evalId = $releaseInfo->{jobsetevals}->[0] or die; my $evalUrl = "https://hydra.nixos.org/eval/$evalId"; my $evalInfo = decode_json(fetch($evalUrl, 'application/json')); my $releasePrefix = "$channelDirRel/$releaseName"; +my $channelRedirect = "channels/$channelName"; my $rev = $evalInfo->{jobsetevalinputs}->{nixpkgs}->{revision} or die; print STDERR "release is ‘$releaseName’ (build $releaseId), eval is $evalId, prefix is $releasePrefix, Git commit is $rev\n"; # Guard against the channel going back in time. -my @releaseUrl = split(/\//, read_file("$channelsDir/$channelName", err_mode => 'quiet') // ""); -my $curRelease = pop @releaseUrl; -my $d = `NIX_PATH= nix-instantiate --eval -E "builtins.compareVersions (builtins.parseDrvName \\"$curRelease\\").version (builtins.parseDrvName \\"$releaseName\\").version"`; -chomp $d; -die "channel would go back in time from $curRelease to $releaseName, bailing out\n" if $d == 1; - -if ($bucket->head_key("$releasePrefix")) { +my $redirect = $bucket->head_key($channelRedirect); +if (defined $redirect->{'x-amz-website-redirect-location'}) { + my $curRelease = basename($redirect->{'x-amz-website-redirect-location'}); + print STDERR "current channel version is $curRelease\n"; + my $d = `NIX_PATH= nix-instantiate --eval -E "builtins.compareVersions (builtins.parseDrvName \\"$curRelease\\").version (builtins.parseDrvName \\"$releaseName\\").version"`; + chomp $d; + die "channel would go back in time from $curRelease to $releaseName, bailing out\n" if $d == 1; + exit if $d == 0; +} + +if ($bucket->head_key($releasePrefix)) { print STDERR "release already exists\n"; } else { - my $tmpDir = "/data/releases/tmp/release-$channelName/$releaseName"; + my $tmpDir = "$TMPDIR/release-$channelName/$releaseName"; File::Path::make_path($tmpDir); write_file("$tmpDir/src-url", $evalUrl); @@ -201,28 +206,18 @@ if ($bucket->head_key("$releasePrefix")) { File::Path::remove_tree($tmpDir); } -# Prevent concurrent writes to the channels directory. -open(my $lockfile, ">>", "$channelsDir/.htaccess.lock"); -flock($lockfile, LOCK_EX) or die "cannot acquire channels lock\n"; - -# Update the channel. -my $htaccess = "$channelsDir/.htaccess-$channelName"; -my $target = "https://releases.nixos.org/$releasePrefix"; -write_file($htaccess, - "Redirect /channels/$channelName $target\n" . - "Redirect /releases/nixos/channels/$channelName $target\n"); - -my $channelLink = "$channelsDir/$channelName"; -if ((read_file($channelLink, err_mode => 'quiet') // "") ne $target) { - write_file("$channelLink.tmp", "$target"); - rename("$channelLink.tmp", $channelLink) or die; -} - -system("cat $channelsDir/.htaccess-nix* > $channelsDir/.htaccess.tmp") == 0 or die; -rename("$channelsDir/.htaccess.tmp", "$channelsDir/.htaccess") or die; +# Prevent concurrent writes to the repo. +open(my $lockfile, ">>", "$TMPDIR/lock"); +flock($lockfile, LOCK_EX) or die "cannot acquire repo lock\n"; # Update the nixpkgs-channels repo. system("git remote update origin >&2") == 0 or die; system("git push channels $rev:refs/heads/$channelName >&2") == 0 or die; -flock($lockfile, LOCK_UN) or die "cannot release channels lock\n"; +flock($lockfile, LOCK_UN) or die "cannot release repo lock\n"; + +# Update the channel redirect. +$bucket->add_key($channelRedirect, "", { + 'x-amz-website-redirect-location' => "/" . $releasePrefix, + 'x-amz-acl' => "public-read" +}) or die "failed to create redirect from $channelRedirect to $releasePrefix\n";