|
|
@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
From 253a07ce8f1f010df19f5a2cd7045e978a4eca01 Mon Sep 17 00:00:00 2001
|
|
|
|
|
|
|
|
From: Astro <astro@spaceboyz.net>
|
|
|
|
|
|
|
|
Date: Thu, 15 Oct 2020 18:07:17 +0200
|
|
|
|
|
|
|
|
Subject: [PATCH 1/2] Add support for local binary cache stores for binary
|
|
|
|
|
|
|
|
cache resources
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
src/lib/Hydra/Controller/Root.pm | 46 +++++++++++++++++++++++---------
|
|
|
|
|
|
|
|
src/lib/Hydra/Helper/Nix.pm | 7 +++++
|
|
|
|
|
|
|
|
2 files changed, 41 insertions(+), 12 deletions(-)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
index 71869ba0..4276f95a 100644
|
|
|
|
|
|
|
|
--- a/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
+++ b/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
@@ -15,6 +15,7 @@ use File::Basename;
|
|
|
|
|
|
|
|
use JSON;
|
|
|
|
|
|
|
|
use List::MoreUtils qw{any};
|
|
|
|
|
|
|
|
use Net::Prometheus;
|
|
|
|
|
|
|
|
+use IO::Handle;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Put this controller at top-level.
|
|
|
|
|
|
|
|
__PACKAGE__->config->{namespace} = '';
|
|
|
|
|
|
|
|
@@ -316,11 +317,7 @@ sub nar :Local :Args(1) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
die if $path =~ /\//;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- if (!isLocalStore) {
|
|
|
|
|
|
|
|
- notFound($c, "There is no binary cache here.");
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
- else {
|
|
|
|
|
|
|
|
+ if (isLocalStore) {
|
|
|
|
|
|
|
|
$path = $Nix::Config::storeDir . "/$path";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gone($c, "Path " . $path . " is no longer available.") unless isValidPath($path);
|
|
|
|
|
|
|
|
@@ -329,13 +326,26 @@ sub nar :Local :Args(1) {
|
|
|
|
|
|
|
|
$c->stash->{current_view} = 'NixNAR';
|
|
|
|
|
|
|
|
$c->stash->{storePath} = $path;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+(.+)") {
|
|
|
|
|
|
|
|
+ $c->response->content_type('application/x-nix-archive');
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ $path = "/" . $1 . "/nar/$path";
|
|
|
|
|
|
|
|
+ my $fh = new IO::Handle;
|
|
|
|
|
|
|
|
+ open $fh, "<:raw", $path;
|
|
|
|
|
|
|
|
+ $c->response->body($fh);
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ else {
|
|
|
|
|
|
|
|
+ notFound($c, "There is no binary cache here.");
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub nix_cache_info :Path('nix-cache-info') :Args(0) {
|
|
|
|
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- if (!isLocalStore) {
|
|
|
|
|
|
|
|
+ if (!isLocalStore && !isLocalBinaryCacheStore) {
|
|
|
|
|
|
|
|
notFound($c, "There is no binary cache here.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -356,14 +366,11 @@ sub nix_cache_info :Path('nix-cache-info') :Args(0) {
|
|
|
|
|
|
|
|
sub narinfo :LocalRegex('^([a-z0-9]+).narinfo$') :Args(0) {
|
|
|
|
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- if (!isLocalStore) {
|
|
|
|
|
|
|
|
- notFound($c, "There is no binary cache here.");
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
+ my $hash = $c->req->captures->[0];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- else {
|
|
|
|
|
|
|
|
- my $hash = $c->req->captures->[0];
|
|
|
|
|
|
|
|
+ die if length($hash) != 32;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- die if length($hash) != 32;
|
|
|
|
|
|
|
|
+ if (isLocalStore) {
|
|
|
|
|
|
|
|
my $path = queryPathFromHashPart($hash);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!$path) {
|
|
|
|
|
|
|
|
@@ -379,6 +386,21 @@ sub narinfo :LocalRegex('^([a-z0-9]+).narinfo$') :Args(0) {
|
|
|
|
|
|
|
|
$c->stash->{storePath} = $path;
|
|
|
|
|
|
|
|
$c->forward('Hydra::View::NARInfo');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+(.+)") {
|
|
|
|
|
|
|
|
+ $c->response->content_type('application/x-nix-archive');
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ my $path = "/" . $1 . "/" . $hash . ".narinfo";
|
|
|
|
|
|
|
|
+ notFound($c, "Redistribution restricted") if isRedistRestricted($path);
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ my $fh = new IO::Handle;
|
|
|
|
|
|
|
|
+ open $fh, "<", $path;
|
|
|
|
|
|
|
|
+ $c->response->body($fh);
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ else {
|
|
|
|
|
|
|
|
+ notFound($c, "There is no binary cache here.");
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lib/Hydra/Helper/Nix.pm b/src/lib/Hydra/Helper/Nix.pm
|
|
|
|
|
|
|
|
index fd7a3170..2b99afa5 100644
|
|
|
|
|
|
|
|
--- a/src/lib/Hydra/Helper/Nix.pm
|
|
|
|
|
|
|
|
+++ b/src/lib/Hydra/Helper/Nix.pm
|
|
|
|
|
|
|
|
@@ -27,6 +27,7 @@ our @EXPORT = qw(
|
|
|
|
|
|
|
|
getStoreUri
|
|
|
|
|
|
|
|
readNixFile
|
|
|
|
|
|
|
|
isLocalStore
|
|
|
|
|
|
|
|
+ isLocalBinaryCacheStore
|
|
|
|
|
|
|
|
cancelBuilds restartBuilds);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -481,4 +482,10 @@ sub isLocalStore {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+sub isLocalBinaryCacheStore {
|
|
|
|
|
|
|
|
+ my $uri = getStoreUri();
|
|
|
|
|
|
|
|
+ return $uri =~ "^file:";
|
|
|
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
1;
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
2.29.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
From 2f8c19772712c507096ba9d39f46bc9dc980332d Mon Sep 17 00:00:00 2001
|
|
|
|
|
|
|
|
From: Astro <astro@spaceboyz.net>
|
|
|
|
|
|
|
|
Date: Tue, 20 Oct 2020 16:05:33 +0200
|
|
|
|
|
|
|
|
Subject: [PATCH 2/2] sign narinfo on the fly
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
src/lib/Hydra/Controller/Root.pm | 43 ++++++++++++++++++++++++++------
|
|
|
|
|
|
|
|
1 file changed, 35 insertions(+), 8 deletions(-)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
index 4276f95a..21ff8a97 100644
|
|
|
|
|
|
|
|
--- a/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
+++ b/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
@@ -10,12 +10,13 @@ use Hydra::View::TT;
|
|
|
|
|
|
|
|
use Digest::SHA1 qw(sha1_hex);
|
|
|
|
|
|
|
|
use Nix::Store;
|
|
|
|
|
|
|
|
use Nix::Config;
|
|
|
|
|
|
|
|
+use Nix::Utils;
|
|
|
|
|
|
|
|
+use Nix::Manifest;
|
|
|
|
|
|
|
|
use Encode;
|
|
|
|
|
|
|
|
use File::Basename;
|
|
|
|
|
|
|
|
use JSON;
|
|
|
|
|
|
|
|
use List::MoreUtils qw{any};
|
|
|
|
|
|
|
|
use Net::Prometheus;
|
|
|
|
|
|
|
|
-use IO::Handle;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Put this controller at top-level.
|
|
|
|
|
|
|
|
__PACKAGE__->config->{namespace} = '';
|
|
|
|
|
|
|
|
@@ -327,7 +328,7 @@ sub nar :Local :Args(1) {
|
|
|
|
|
|
|
|
$c->stash->{storePath} = $path;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+(.+)") {
|
|
|
|
|
|
|
|
+ elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+([^\?]+)") {
|
|
|
|
|
|
|
|
$c->response->content_type('application/x-nix-archive');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$path = "/" . $1 . "/nar/$path";
|
|
|
|
|
|
|
|
@@ -381,21 +382,47 @@ sub narinfo :LocalRegex('^([a-z0-9]+).narinfo$') :Args(0) {
|
|
|
|
|
|
|
|
setCacheHeaders($c, 60 * 60);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
- notFound($c, "Redistribution restricted") if isRedistRestricted($path);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$c->stash->{storePath} = $path;
|
|
|
|
|
|
|
|
$c->forward('Hydra::View::NARInfo');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+(.+)") {
|
|
|
|
|
|
|
|
+ elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+([^\?]+)") {
|
|
|
|
|
|
|
|
$c->response->content_type('application/x-nix-archive');
|
|
|
|
|
|
|
|
+ setCacheHeaders($c, 24 * 60 * 60);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
my $path = "/" . $1 . "/" . $hash . ".narinfo";
|
|
|
|
|
|
|
|
- notFound($c, "Redistribution restricted") if isRedistRestricted($path);
|
|
|
|
|
|
|
|
+ if (!-f $path) {
|
|
|
|
|
|
|
|
+ return notFound($c, "NARInfo not found");
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ my $content = readFile $path;
|
|
|
|
|
|
|
|
+ my %info;
|
|
|
|
|
|
|
|
+ foreach my $line (split "\n", $content) {
|
|
|
|
|
|
|
|
+ return undef unless $line =~ /^(.*): (.*)$/;
|
|
|
|
|
|
|
|
+ $info{$1} = $2;
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ notFound($c, "Redistribution restricted") if isRedistRestricted($info{StorePath});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- my $fh = new IO::Handle;
|
|
|
|
|
|
|
|
- open $fh, "<", $path;
|
|
|
|
|
|
|
|
- $c->response->body($fh);
|
|
|
|
|
|
|
|
+ my $secretKeyFile = $c->config->{binary_cache_secret_key_file};
|
|
|
|
|
|
|
|
+ if (! defined $secretKeyFile && getStoreUri =~ "[\?\&]secret-key=([^\?\&]+)") {
|
|
|
|
|
|
|
|
+ $secretKeyFile = $1;
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ if (defined $secretKeyFile) {
|
|
|
|
|
|
|
|
+ # Optionally, sign the NAR info file
|
|
|
|
|
|
|
|
+ my @refs = map { $Nix::Config::storeDir . "/" . $_ } split(" ", $info{References});
|
|
|
|
|
|
|
|
+ my $fingerprint = fingerprintPath($info{StorePath}, $info{NarHash}, $info{NarSize}, [ @refs ]);
|
|
|
|
|
|
|
|
+ my $secretKey = readFile $secretKeyFile;
|
|
|
|
|
|
|
|
+ my $sig = signString($secretKey, $fingerprint);
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ $content =~ s/^Sig:.+\n//m;
|
|
|
|
|
|
|
|
+ $content .= "Sig: $sig\n";
|
|
|
|
|
|
|
|
+ $c->response->body($content);
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ else {
|
|
|
|
|
|
|
|
+ my $fh = new IO::Handle;
|
|
|
|
|
|
|
|
+ open $fh, "<", $path;
|
|
|
|
|
|
|
|
+ $c->response->body($fh);
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
2.29.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
From e20013bff3c92b21bab6e476489a1508df1cf348 Mon Sep 17 00:00:00 2001
|
|
|
|
|
|
|
|
From: Astro <astro@spaceboyz.net>
|
|
|
|
|
|
|
|
Date: Mon, 22 Feb 2021 00:12:12 +0100
|
|
|
|
|
|
|
|
Subject: [PATCH] check if nar not found
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
src/lib/Hydra/Controller/Root.pm | 4 ++++
|
|
|
|
|
|
|
|
1 file changed, 4 insertions(+)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
index 6be9f2bc..37464c34 100644
|
|
|
|
|
|
|
|
--- a/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
+++ b/src/lib/Hydra/Controller/Root.pm
|
|
|
|
|
|
|
|
@@ -326,6 +326,10 @@ sub nar :Local :Args(1) {
|
|
|
|
|
|
|
|
$c->response->content_type('application/x-nix-archive');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$path = "/" . $1 . "/nar/$path";
|
|
|
|
|
|
|
|
+ if (!-f $path) {
|
|
|
|
|
|
|
|
+ return notFound($c, "NAR not found");
|
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
my $fh = new IO::Handle;
|
|
|
|
|
|
|
|
open $fh, "<:raw", $path;
|
|
|
|
|
|
|
|
$c->response->body($fh);
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
2.30.0
|
|
|
|
|
|
|
|
|