diff --git a/src/HydraFrontend/lib/HydraFrontend.pm b/src/HydraFrontend/lib/HydraFrontend.pm
index 68688a67..f5e67d7a 100644
--- a/src/HydraFrontend/lib/HydraFrontend.pm
+++ b/src/HydraFrontend/lib/HydraFrontend.pm
@@ -13,7 +13,10 @@ use Catalyst qw/-Debug
/;
our $VERSION = '0.01';
-__PACKAGE__->config( name => 'HydraFrontend' );
+__PACKAGE__->config(
+ name => 'HydraFrontend',
+ default_view => "TT"
+ );
__PACKAGE__->setup();
diff --git a/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm b/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm
index 681c9243..05b8ce9b 100644
--- a/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm
+++ b/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm
@@ -3,6 +3,7 @@ package HydraFrontend::Controller::Root;
use strict;
use warnings;
use parent 'Catalyst::Controller';
+use HydraFrontend::Helper::Nix;
#
# Sets the actions in this controller to be registered with no prefix
@@ -391,7 +392,13 @@ sub closure :Local {
my $product = $build->buildproducts->find({productnr => $productnr});
return error($c, "Build $buildId doesn't have a product $productnr.") if !defined $product;
- return error($c, "Not yet implemented.");
+ return error($c, "Product is not a Nix build.") if $product->type ne "nix-build";
+
+ return error($c, "Path " . $product->path . " is no longer available.") unless HydraFrontend::Helper::Nix::isValidPath($product->path);
+
+ $c->stash->{current_view} = 'HydraFrontend::View::NixClosure';
+ $c->stash->{storePath} = $product->path;
+ $c->stash->{name} = $build->nixname;
}
diff --git a/src/HydraFrontend/lib/HydraFrontend/Helper/Nix.pm b/src/HydraFrontend/lib/HydraFrontend/Helper/Nix.pm
new file mode 100644
index 00000000..908aa990
--- /dev/null
+++ b/src/HydraFrontend/lib/HydraFrontend/Helper/Nix.pm
@@ -0,0 +1,14 @@
+package HydraFrontend::Helper::Nix;
+
+use strict;
+
+
+sub isValidPath {
+ my $path = shift;
+ $SIG{CHLD} = 'DEFAULT'; # !!! work around system() failing if SIGCHLD is ignored
+ return system("nix-store --check-validity $path") == 0;
+}
+
+
+1;
+
diff --git a/src/HydraFrontend/lib/HydraFrontend/View/NixClosure.pm b/src/HydraFrontend/lib/HydraFrontend/View/NixClosure.pm
new file mode 100644
index 00000000..696bce63
--- /dev/null
+++ b/src/HydraFrontend/lib/HydraFrontend/View/NixClosure.pm
@@ -0,0 +1,26 @@
+package HydraFrontend::View::NixClosure;
+
+use strict;
+use base qw/Catalyst::View/;
+use IO::Pipe;
+use POSIX qw(dup2);
+
+sub process {
+ my ( $self, $c ) = @_;
+
+ $c->response->content_type('application/x-nix-export');
+ $c->response->header('Content-Disposition' => 'attachment; filename=' . $c->stash->{name} . '.closure.gz');
+
+ my $storePath = $c->stash->{storePath};
+
+ open(OUTPUT, "nix-store --export `nix-store -qR $storePath` | gzip |");
+
+ my $fh = new IO::Handle;
+ $fh->fdopen(fileno(OUTPUT), "r") or die;
+
+ $c->response->body($fh);
+
+ return 1;
+}
+
+1;
diff --git a/src/HydraFrontend/root/build.tt b/src/HydraFrontend/root/build.tt
index 082c24f2..d65fc0fb 100644
--- a/src/HydraFrontend/root/build.tt
+++ b/src/HydraFrontend/root/build.tt
@@ -1,5 +1,6 @@
[% WRAPPER layout.tt title="Hydra Overview" %]
[% PROCESS common.tt %]
+[% USE HTML %]
[% USE date %]
[% USE mibs=format("%.2f") %]
@@ -205,6 +206,24 @@
Nix build of path [% product.path %]
+ [help]
+
If you have Nix installed on your machine, this build and all + its dependencies can be unpacked into your local Nix store by + doing:
+ +$ gunzip < [% HTML.escape(build.nixname) %].closure.gz | nix-store --import+ + or to download and unpack in one command: + +
$ curl [% c.uri_for('/closure' build.id product.productnr) %] | gunzip | nix-store --import+ +
The package can then be found in the path [% + product.path %]. If you get the error message “imported + archive lacks a signature”, you should make sure that you have + sufficient access rights to the Nix store, e.g., run the + command as root.
+