forked from lix-project/hydra
* Support serving products that are directories (such as manuals or
coverage analysis reports).
This commit is contained in:
parent
f9c0996003
commit
b96d304c85
|
@ -163,7 +163,7 @@ sub loadLog {
|
||||||
|
|
||||||
|
|
||||||
sub download :Local {
|
sub download :Local {
|
||||||
my ( $self, $c, $id, $productnr, $filename ) = @_;
|
my ( $self, $c, $id, $productnr, $filename, @path ) = @_;
|
||||||
|
|
||||||
my $build = getBuild($c, $id);
|
my $build = getBuild($c, $id);
|
||||||
return error($c, "Build with ID $id doesn't exist.") if !defined $build;
|
return error($c, "Build with ID $id doesn't exist.") if !defined $build;
|
||||||
|
@ -171,9 +171,29 @@ sub download :Local {
|
||||||
my $product = $build->buildproducts->find({productnr => $productnr});
|
my $product = $build->buildproducts->find({productnr => $productnr});
|
||||||
return error($c, "Build $id doesn't have a product $productnr.") if !defined $product;
|
return error($c, "Build $id doesn't have a product $productnr.") if !defined $product;
|
||||||
|
|
||||||
return error($c, "File " . $product->path . " has disappeared.") unless -e $product->path;
|
return error($c, "Product " . $product->path . " has disappeared.") unless -e $product->path;
|
||||||
|
|
||||||
$c->serve_static_file($product->path);
|
# Security paranoia.
|
||||||
|
foreach my $elem (@path) {
|
||||||
|
if ($elem eq "." || $elem eq ".." || $elem !~ /^[\w\-\.]+$/) {
|
||||||
|
return error($c, "Invalid filename $elem.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $path = $product->path . "/" . join("/", @path);
|
||||||
|
|
||||||
|
# If this is a directory but no "/" is attached, then redirect.
|
||||||
|
if (-d $path && substr($c->request->uri, -1) ne "/") {
|
||||||
|
return $c->res->redirect($c->request->uri . "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = "$path/index.html" if -d $path && -e "$path/index.html";
|
||||||
|
|
||||||
|
if (!-e $path) {
|
||||||
|
return error($c, "File $path does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$c->serve_static_file($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -194,8 +194,10 @@
|
||||||
[% FOREACH product IN build.buildproducts -%]
|
[% FOREACH product IN build.buildproducts -%]
|
||||||
<li>
|
<li>
|
||||||
[% SWITCH product.type %]
|
[% SWITCH product.type %]
|
||||||
|
|
||||||
[% CASE "nix-build" %]
|
[% CASE "nix-build" %]
|
||||||
Nix build of path <tt>[% product.path %]</tt>
|
Nix build of path <tt>[% product.path %]</tt>
|
||||||
|
|
||||||
[% CASE "file" %]
|
[% CASE "file" %]
|
||||||
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||||
[% SWITCH product.subtype %]
|
[% SWITCH product.subtype %]
|
||||||
|
@ -224,8 +226,21 @@
|
||||||
<tr><th>Full path:</th><td><tt>[% product.path %]</tt></td></tr>
|
<tr><th>Full path:</th><td><tt>[% product.path %]</tt></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
[% CASE "report" %]
|
||||||
|
|
||||||
|
<a href="[% c.uri_for('/download' build.id product.productnr product.name) %]">
|
||||||
|
[% SWITCH product.subtype %]
|
||||||
|
[% CASE "coverage" %]
|
||||||
|
Code coverage analysis report
|
||||||
|
[% CASE DEFAULT %]
|
||||||
|
Report of type <tt>[% product.subtype %]</tt>
|
||||||
|
[% END %]
|
||||||
|
</a>
|
||||||
|
|
||||||
[% CASE DEFAULT %]
|
[% CASE DEFAULT %]
|
||||||
Something of type <tt>[% product.type %]</tt>
|
Something of type <tt>[% product.type %]</tt>
|
||||||
|
|
||||||
[% END %]
|
[% END %]
|
||||||
</li>
|
</li>
|
||||||
[% END -%]
|
[% END -%]
|
||||||
|
|
|
@ -178,8 +178,8 @@ tr.runningJob {
|
||||||
|
|
||||||
table.tablesorter {
|
table.tablesorter {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table.tablesorter thead tr .header {
|
table.tablesorter thead tr .header {
|
||||||
background-image: url(/static/js/tablesorter/themes/blue/bg.gif);
|
background-image: url(/static/js/tablesorter/themes/blue/bg.gif);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|
21
src/build.pl
21
src/build.pl
|
@ -221,15 +221,20 @@ sub doBuild {
|
||||||
my $path = $3;
|
my $path = $3;
|
||||||
die unless -e $path;
|
die unless -e $path;
|
||||||
|
|
||||||
my $st = stat($path) or die "cannot stat $path: $!";
|
my $fileSize, my $sha1, my $sha256;
|
||||||
|
|
||||||
my $sha1 = `nix-hash --flat --type sha1 $path`
|
if (-f $path) {
|
||||||
or die "cannot hash $path: $?";;
|
my $st = stat($path) or die "cannot stat $path: $!";
|
||||||
chomp $sha1;
|
$fileSize = $st;
|
||||||
|
|
||||||
|
$sha1 = `nix-hash --flat --type sha1 $path`
|
||||||
|
or die "cannot hash $path: $?";;
|
||||||
|
chomp $sha1;
|
||||||
|
|
||||||
my $sha256 = `nix-hash --flat --type sha256 $path`
|
$sha256 = `nix-hash --flat --type sha256 $path`
|
||||||
or die "cannot hash $path: $?";;
|
or die "cannot hash $path: $?";;
|
||||||
chomp $sha256;
|
chomp $sha256;
|
||||||
|
}
|
||||||
|
|
||||||
$db->resultset('Buildproducts')->create(
|
$db->resultset('Buildproducts')->create(
|
||||||
{ build => $build->id
|
{ build => $build->id
|
||||||
|
@ -237,7 +242,7 @@ sub doBuild {
|
||||||
, type => $type
|
, type => $type
|
||||||
, subtype => $subtype
|
, subtype => $subtype
|
||||||
, path => $path
|
, path => $path
|
||||||
, filesize => $st->size
|
, filesize => $fileSize
|
||||||
, sha1hash => $sha1
|
, sha1hash => $sha1
|
||||||
, sha256hash => $sha256
|
, sha256hash => $sha256
|
||||||
, name => basename $path
|
, name => basename $path
|
||||||
|
|
Loading…
Reference in a new issue