* For products that are directories (like manuals), allow a default

suffix other than index.html to be declared.  E.g. if a build does

    echo "doc manual $out manual.html" >> $out/nix-support/hydra-build-products

  the default link for the product is

    http://localhost:3000/build/417/download/1/manual.html

  but other files are also accessible, e.g.
    
    http://localhost:3000/build/417/download/1/style.css
This commit is contained in:
Eelco Dolstra 2009-03-06 13:34:53 +00:00
parent dca6b943d0
commit 36fdd7f37f
23 changed files with 61 additions and 41 deletions

View file

@ -80,13 +80,17 @@ sub loadLog {
sub download : Chained('build') PathPart('download') { sub download : Chained('build') PathPart('download') {
my ($self, $c, $productnr, $filename, @path) = @_; my ($self, $c, $productnr, @path) = @_;
my $product = $c->stash->{build}->buildproducts->find({productnr => $productnr}); my $product = $c->stash->{build}->buildproducts->find({productnr => $productnr});
notFound($c, "Build doesn't have a product $productnr.") if !defined $product; notFound($c, "Build doesn't have a product $productnr.") if !defined $product;
notFound($c, "Product " . $product->path . " has disappeared.") unless -e $product->path; notFound($c, "Product " . $product->path . " has disappeared.") unless -e $product->path;
# If the product has a name, then the first path element can be
# ignored (it's the name included in the URL for informational purposes).
shift @path if $product->name;
# Security paranoia. # Security paranoia.
foreach my $elem (@path) { foreach my $elem (@path) {
error($c, "Invalid filename $elem.") if $elem !~ /^$pathCompRE$/; error($c, "Invalid filename $elem.") if $elem !~ /^$pathCompRE$/;
@ -104,6 +108,8 @@ sub download : Chained('build') PathPart('download') {
notFound($c, "File $path does not exist.") if !-e $path; notFound($c, "File $path does not exist.") if !-e $path;
notFound($c, "Path $path is a directory.") if -d $path;
$c->serve_static_file($path); $c->serve_static_file($path);
} }

View file

@ -8,8 +8,8 @@ use base 'DBIx::Class::Schema';
__PACKAGE__->load_classes; __PACKAGE__->load_classes;
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:QcB8T/bY2/Pw34uuYXt2Cw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hRwus0A1vxnFCzQxghFgTw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -36,8 +36,8 @@ __PACKAGE__->belongs_to("build", "Hydra::Schema::Builds", { id => "build" });
__PACKAGE__->belongs_to("dependency", "Hydra::Schema::Builds", { id => "dependency" }); __PACKAGE__->belongs_to("dependency", "Hydra::Schema::Builds", { id => "dependency" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7Th7GxvR7m/DdodQqlmJXQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:H25BhHe9wbU6nj6fSKjZnw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -28,13 +28,15 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"description", "description",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"defaultpath",
{ data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("build", "productnr"); __PACKAGE__->set_primary_key("build", "productnr");
__PACKAGE__->belongs_to("build", "Hydra::Schema::Builds", { id => "build" }); __PACKAGE__->belongs_to("build", "Hydra::Schema::Builds", { id => "build" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:FFVpdoV0vBLhF9yyKJSoTA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:rfkj/A+Li7Q0hWydqtJHAw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -31,8 +31,8 @@ __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" }); __PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CkjyZptB79J32VhDbXhKEg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:wmL9881G+dZrgHKM83dHXw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -27,8 +27,8 @@ __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" }); __PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HeodRHEOs/do8RKwDJhaXg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:6cTj5JovtTmtemvQjWtucQ
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -35,8 +35,8 @@ __PACKAGE__->set_primary_key("id", "stepnr");
__PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" }); __PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kKpIuRMrqdh7m4M5XPIEgg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LyNlkn5XjBnLp7M4ipB/ZQ
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -76,8 +76,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:fGOOscNFEgDZpeVpA6HH0w # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:8U9CmcfeowLJVViKiR3n1g
__PACKAGE__->has_many(dependents => 'Hydra::Schema::BuildInputs', 'dependency'); __PACKAGE__->has_many(dependents => 'Hydra::Schema::BuildInputs', 'dependency');

View file

@ -22,8 +22,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("srcpath", "sha256hash"); __PACKAGE__->set_primary_key("srcpath", "sha256hash");
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0wY3JTSelPQSTbxpNQDJjg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:+F3EiYsvXuOjnGDrkhLxng
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -20,8 +20,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("uri", "revision"); __PACKAGE__->set_primary_key("uri", "revision");
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:eZPs3SB3XZW5BNQOQFrFBw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:O0QvXjOulMVTjhW4rRHkmQ
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -31,8 +31,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:atlyxsSKg41KbDkbCfuvHQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:qXh+0QbMUHIDmQCG9T5qdA
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -43,8 +43,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:85ro4sVmhc3HwAjgoA6p6w # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:TUTdwfhSsFMKBXa/wKenOQ
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -50,8 +50,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:c5PqrzN43jEGGrzKqI6WWQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dVevQ8lPI2/IRpYoJgzLBA
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -45,8 +45,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7iZYMDM+wn+Neud0Fm1ZMA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Q5mSKzMxB9px2ja8NjK/9Q
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -32,8 +32,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Rs3CRPpzFi30sAeHVe1yQA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:+Ky8V3sZIgT22hgF27Y0cw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -29,8 +29,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:PA+dfXHaBsSx9kE1mEZZ9w # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:f+4AnWTJsi4RDfxoJxECgw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -16,8 +16,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("system"); __PACKAGE__->set_primary_key("system");
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:olHboRdtxD6E7Ukr4aCLCA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Af/LU15/hpXngfrBrDMI/A
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -17,8 +17,8 @@ __PACKAGE__->set_primary_key("username", "role");
__PACKAGE__->belongs_to("username", "Hydra::Schema::Users", { username => "username" }); __PACKAGE__->belongs_to("username", "Hydra::Schema::Users", { username => "username" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Q7Nd3wv7Y3184GhkE/pdFA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/yDlbFhRYDzf+0VHzygrhA
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -30,8 +30,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-04 14:50:30 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2009-03-06 14:20:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:z8fRKy//Mx8wqymMgOcrWA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:d7M/Q6OucU9NUCSB5zZK7Q
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -42,7 +42,7 @@
[% FOREACH build IN builds -%] [% FOREACH build IN builds -%]
<tr class="clickable <tr class="clickable
[% IF showSchedulingInfo -%] [% IF showSchedulingInfo -%]
[% IF build.schedulingInfo.busy %]runningBuild[% END %] [% IF build.schedulingInfo.disabled == 1 || build.project.enabled == 0 %]disabledBuild[% END -%] [% IF build.schedulingInfo.busy %]runningBuild[% ELSIF build.schedulingInfo.disabled == 1 || build.project.enabled == 0 %]disabledBuild[% END %]
[% ELSE -%] [% ELSE -%]
[% IF odd %] odd [% END; odd = !odd -%] [% IF odd %] odd [% END; odd = !odd -%]
[% END %]" [% END %]"

View file

@ -6,7 +6,9 @@
[% FOREACH product IN build.buildproducts -%] [% FOREACH product IN build.buildproducts -%]
[% uri = c.uri_for('/build' build.id 'download' product.productnr product.name) %] [% uri = "${c.uri_for('/build' build.id 'download' product.productnr)}"
_ (product.name ? "/" _ product.name : "")
_ (product.defaultpath ? "/" _ product.defaultpath : "") %]
[% SWITCH product.type %] [% SWITCH product.type %]

View file

@ -209,14 +209,17 @@ sub doBuild {
if (-e "$outPath/nix-support/hydra-build-products") { if (-e "$outPath/nix-support/hydra-build-products") {
open LIST, "$outPath/nix-support/hydra-build-products" or die; open LIST, "$outPath/nix-support/hydra-build-products" or die;
while (<LIST>) { while (<LIST>) {
/^([\w\-]+)\s+([\w\-]+)\s+(\S+)$/ or next; /^([\w\-]+)\s+([\w\-]+)\s+(\S+)(\s+(\S+))?$/ or next;
my $type = $1; my $type = $1;
my $subtype = $2 eq "none" ? "" : $2; my $subtype = $2 eq "none" ? "" : $2;
my $path = $3; my $path = $3;
my $defaultPath = $5;
next unless -e $path; next unless -e $path;
my $fileSize, my $sha1, my $sha256; my $fileSize, my $sha1, my $sha256;
# !!! validate $path, $defaultPath
if (-f $path) { if (-f $path) {
my $st = stat($path) or die "cannot stat $path: $!"; my $st = stat($path) or die "cannot stat $path: $!";
$fileSize = $st->size; $fileSize = $st->size;
@ -230,6 +233,8 @@ sub doBuild {
chomp $sha256; chomp $sha256;
} }
my $name = $path eq $outPath ? "" : basename $path;
$db->resultset('BuildProducts')->create( $db->resultset('BuildProducts')->create(
{ build => $build->id { build => $build->id
, productnr => $productnr++ , productnr => $productnr++
@ -239,7 +244,8 @@ sub doBuild {
, filesize => $fileSize , filesize => $fileSize
, sha1hash => $sha1 , sha1hash => $sha1
, sha256hash => $sha256 , sha256hash => $sha256
, name => basename $path , name => $name
, defaultpath => $defaultPath
}); });
} }
close LIST; close LIST;
@ -273,12 +279,15 @@ my $build;
$db->txn_do(sub { $db->txn_do(sub {
$build = $db->resultset('Builds')->find($buildId); $build = $db->resultset('Builds')->find($buildId);
die "build $buildId doesn't exist" unless defined $build; die "build $buildId doesn't exist" unless defined $build;
die "build $buildId already done" if defined $build->resultInfo;
if ($build->schedulingInfo->busy != 0 && $build->schedulingInfo->locker != getppid) { if ($build->schedulingInfo->busy != 0 && $build->schedulingInfo->locker != getppid) {
die "build $buildId is already being built"; die "build $buildId is already being built";
} }
$build->schedulingInfo->busy(1); $build->schedulingInfo->busy(1);
$build->schedulingInfo->locker($$); $build->schedulingInfo->locker($$);
$build->schedulingInfo->update; $build->schedulingInfo->update;
$build->buildsteps->delete_all;
$build->buildproducts->delete_all;
}); });
die unless $build; die unless $build;

View file

@ -140,6 +140,7 @@ create table BuildProducts (
path text, path text,
name text not null, -- generally just the filename part of `path' name text not null, -- generally just the filename part of `path'
description text, -- optionally, some description of this file/directory description text, -- optionally, some description of this file/directory
defaultPath text, -- if `path' is a directory, the default file relative to `path' to be served
primary key (build, productnr), primary key (build, productnr),
foreign key (build) references Builds(id) on delete cascade -- ignored by sqlite foreign key (build) references Builds(id) on delete cascade -- ignored by sqlite
); );