diff --git a/mirror-nixos-branch.pl b/mirror-nixos-branch.pl index 4483852..9c37fc6 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 $TMPDIR = $ENV{'TMPDIR'} // "/tmp"; -my $filesCache = "${TMPDIR}/nixos-files.sqlite"; +my $channelsDir = "/data/releases/channels"; +my $filesCache = "/data/releases/nixos-files.sqlite"; my $bucketName = "nix-releases"; $ENV{'GIT_DIR'} = "/home/hydra-mirror/nixpkgs-channels"; @@ -66,27 +66,22 @@ 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 $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)) { +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")) { print STDERR "release already exists\n"; } else { - my $tmpDir = "$TMPDIR/release-$channelName/$releaseName"; + my $tmpDir = "/data/releases/tmp/release-$channelName/$releaseName"; File::Path::make_path($tmpDir); write_file("$tmpDir/src-url", $evalUrl); @@ -206,18 +201,28 @@ if ($bucket->head_key($releasePrefix)) { File::Path::remove_tree($tmpDir); } -# Prevent concurrent writes to the repo. -open(my $lockfile, ">>", "$TMPDIR/lock"); -flock($lockfile, LOCK_EX) or die "cannot acquire repo lock\n"; +# 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; # 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 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"; +flock($lockfile, LOCK_UN) or die "cannot release channels lock\n";