drop the "/nix/store". I.e. instead of
http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest/nar/nix/store/99djmii6l4yw9gn07zxqabh8z58pp84c-libmspack-0.0.20040308alpha.drv
we now have
http://hydra.nixos.org/nar/99djmii6l4yw9gn07zxqabh8z58pp84c-libmspack-0.0.20040308alpha.drv
The main reason is that this is much faster, since we don't need to
get all the channel data (which isn't used anyway for NAR
generation). This speeds up downloading a NAR from the Nixpkgs
channel by > 2 seconds.
* Drop "Hydra::View::" from view names to get rid of an ugly warning.
177 lines
5.5 KiB
Perl
177 lines
5.5 KiB
Perl
package Hydra::Controller::Root;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use base 'Hydra::Base::Controller::ListBuilds';
|
|
use Hydra::Helper::Nix;
|
|
use Hydra::Helper::CatalystUtils;
|
|
|
|
|
|
# Put this controller at top-level.
|
|
__PACKAGE__->config->{namespace} = '';
|
|
|
|
|
|
sub begin :Private {
|
|
my ($self, $c) = @_;
|
|
$c->stash->{curUri} = $c->request->uri;
|
|
$c->stash->{version} = $ENV{"HYDRA_RELEASE"} || "<devel>";
|
|
$c->stash->{nixVersion} = $ENV{"NIX_RELEASE"} || "<devel>";
|
|
|
|
$c->stash->{nrRunningBuilds} = $c->model('DB::BuildSchedulingInfo')->search({ busy => 1 }, {})->count();
|
|
$c->stash->{nrQueuedBuilds} = $c->model('DB::BuildSchedulingInfo')->count();
|
|
|
|
}
|
|
|
|
|
|
sub index :Path :Args(0) {
|
|
my ($self, $c) = @_;
|
|
$c->stash->{template} = 'overview.tt';
|
|
$c->stash->{projects} = [$c->model('DB::Projects')->search(isAdmin($c) ? {} : {hidden => 0}, {order_by => 'name'})];
|
|
$c->stash->{newsItems} = [$c->model('DB::NewsItems')->search({}, { order_by => ['createtime DESC'], rows => 5 })];
|
|
}
|
|
|
|
|
|
sub login :Local {
|
|
my ($self, $c) = @_;
|
|
|
|
my $username = $c->request->params->{username} || "";
|
|
my $password = $c->request->params->{password} || "";
|
|
|
|
if ($username && $password) {
|
|
if ($c->authenticate({username => $username, password => $password})) {
|
|
$c->response->redirect(
|
|
defined $c->flash->{afterLogin}
|
|
? $c->flash->{afterLogin}
|
|
: $c->uri_for('/'));
|
|
return;
|
|
}
|
|
$c->stash->{errorMsg} = "Bad username or password.";
|
|
}
|
|
|
|
$c->stash->{template} = 'login.tt';
|
|
}
|
|
|
|
|
|
sub logout :Local {
|
|
my ($self, $c) = @_;
|
|
$c->logout;
|
|
$c->response->redirect($c->uri_for('/'));
|
|
}
|
|
|
|
|
|
sub queue :Local {
|
|
my ($self, $c) = @_;
|
|
$c->stash->{template} = 'queue.tt';
|
|
$c->stash->{queue} = [$c->model('DB::Builds')->search(
|
|
{finished => 0}, {join => ['schedulingInfo', 'project'] , order_by => ["priority DESC", "timestamp"], '+select' => ['project.enabled', 'schedulingInfo.priority', 'schedulingInfo.disabled', 'schedulingInfo.busy'], '+as' => ['enabled', 'priority', 'disabled', 'busy'] })];
|
|
$c->stash->{flashMsg} = $c->flash->{buildMsg};
|
|
}
|
|
|
|
sub timeline :Local {
|
|
my ($self, $c) = @_;
|
|
my $pit = time();
|
|
$c->stash->{pit} = $pit;
|
|
$pit = $pit-(24*60*60)-1;
|
|
|
|
$c->stash->{template} = 'timeline.tt';
|
|
$c->stash->{builds} = [$c->model('DB::Builds')->search(
|
|
{finished => 1, stoptime => { '>' => $pit } }
|
|
, { join => 'resultInfo'
|
|
, order_by => ["starttime"]
|
|
, '+select' => [ 'resultInfo.starttime', 'resultInfo.stoptime', 'resultInfo.buildstatus' ]
|
|
, '+as' => [ 'starttime', 'stoptime', 'buildstatus' ]
|
|
})];
|
|
}
|
|
|
|
# Hydra::Base::Controller::ListBuilds needs this.
|
|
sub get_builds : Chained('/') PathPart('') CaptureArgs(0) {
|
|
my ($self, $c) = @_;
|
|
$c->stash->{allBuilds} = $c->model('DB::Builds');
|
|
$c->stash->{jobStatus} = $c->model('DB')->resultset('JobStatus');
|
|
$c->stash->{allJobsets} = $c->model('DB::Jobsets');
|
|
$c->stash->{allJobs} = $c->model('DB::Jobs');
|
|
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceeded');
|
|
$c->stash->{channelBaseName} = "everything";
|
|
}
|
|
|
|
|
|
sub robots_txt : Path('robots.txt') {
|
|
my ($self, $c) = @_;
|
|
|
|
sub uri_for {
|
|
my ($controller, $action, @args) = @_;
|
|
return $c->uri_for($c->controller($controller)->action_for($action), @args)->path;
|
|
}
|
|
|
|
sub channelUris {
|
|
my ($controller, $bindings) = @_;
|
|
return
|
|
( uri_for($controller, 'closure', $bindings, "*")
|
|
, uri_for($controller, 'manifest', $bindings)
|
|
, uri_for($controller, 'nar', $bindings, "*")
|
|
, uri_for($controller, 'pkg', $bindings, "*")
|
|
, uri_for($controller, 'nixexprs', $bindings)
|
|
, uri_for($controller, 'channel_contents', $bindings)
|
|
);
|
|
}
|
|
|
|
# Put actions that are expensive or not useful for indexing in
|
|
# robots.txt. Note: wildcards are not universally supported in
|
|
# robots.txt, but apparently Google supports them.
|
|
my @rules =
|
|
( uri_for('Build', 'buildtimedeps', ["*"])
|
|
, uri_for('Build', 'runtimedeps', ["*"])
|
|
, uri_for('Build', 'deps', ["*"])
|
|
, uri_for('Build', 'view_nixlog', ["*"], "*")
|
|
, uri_for('Build', 'view_log', ["*"], "*")
|
|
, uri_for('Build', 'view_log', ["*"])
|
|
, channelUris('Root', ["*"])
|
|
, channelUris('Project', ["*", "*"])
|
|
, channelUris('Jobset', ["*", "*", "*"])
|
|
, channelUris('Job', ["*", "*", "*", "*"])
|
|
, channelUris('Build', ["*"])
|
|
);
|
|
|
|
$c->stash->{'plain'} = { data => "User-agent: *\n" . join('', map { "Disallow: $_\n" } @rules) };
|
|
$c->forward('Hydra::View::Plain');
|
|
}
|
|
|
|
|
|
sub default :Path {
|
|
my ($self, $c) = @_;
|
|
notFound($c, "Page not found.");
|
|
}
|
|
|
|
|
|
sub end : ActionClass('RenderView') {
|
|
my ($self, $c) = @_;
|
|
|
|
if (scalar @{$c->error}) {
|
|
$c->stash->{template} = 'error.tt';
|
|
$c->stash->{errors} = $c->error;
|
|
if ($c->response->status >= 300) {
|
|
$c->stash->{httpStatus} =
|
|
$c->response->status . " " . HTTP::Status::status_message($c->response->status);
|
|
}
|
|
$c->clear_errors;
|
|
}
|
|
}
|
|
|
|
|
|
sub nar :Local :Args(1) {
|
|
my ($self, $c, $path) = @_;
|
|
|
|
$path = "/nix/store/$path";
|
|
|
|
if (!isValidPath($path)) {
|
|
$c->response->status(410); # "Gone"
|
|
error($c, "Path " . $path . " is no longer available.");
|
|
}
|
|
|
|
$c->stash->{current_view} = 'NixNAR';
|
|
$c->stash->{storePath} = $path;
|
|
}
|
|
|
|
|
|
1;
|