2008-11-25 11:01:42 +00:00
|
|
|
package Hydra::Controller::Root;
|
2008-10-28 10:19:31 +00:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
2009-03-04 10:59:14 +00:00
|
|
|
use base 'Hydra::Base::Controller::ListBuilds';
|
2008-11-25 11:01:42 +00:00
|
|
|
use Hydra::Helper::Nix;
|
2009-02-25 12:03:13 +00:00
|
|
|
use Hydra::Helper::CatalystUtils;
|
2010-12-03 09:40:25 +00:00
|
|
|
use Digest::SHA1 qw(sha1_hex);
|
2009-02-25 10:52:41 +00:00
|
|
|
|
|
|
|
# Put this controller at top-level.
|
2008-10-28 10:19:31 +00:00
|
|
|
__PACKAGE__->config->{namespace} = '';
|
|
|
|
|
|
|
|
|
2008-11-13 09:25:38 +00:00
|
|
|
sub begin :Private {
|
2010-08-31 15:27:46 +00:00
|
|
|
my ($self, $c, @args) = @_;
|
2008-11-13 09:48:10 +00:00
|
|
|
$c->stash->{curUri} = $c->request->uri;
|
2009-03-23 13:52:24 +00:00
|
|
|
$c->stash->{version} = $ENV{"HYDRA_RELEASE"} || "<devel>";
|
2011-04-01 07:40:06 +00:00
|
|
|
$c->stash->{nixVersion} = $ENV{"NIX_RELEASE"} || "<devel>";
|
2010-08-31 15:27:46 +00:00
|
|
|
$c->stash->{curTime} = time;
|
2011-04-18 08:21:27 +00:00
|
|
|
$c->stash->{logo} = $ENV{"HYDRA_LOGO"} ? "/logo" : "/static/images/hydra.png" ;
|
2011-04-19 12:00:54 +00:00
|
|
|
$c->stash->{tracker} = $ENV{"HYDRA_TRACKER"} ;
|
|
|
|
|
2010-08-31 15:37:50 +00:00
|
|
|
if (scalar(@args) == 0 || $args[0] ne "static") {
|
2011-04-18 08:21:27 +00:00
|
|
|
$c->stash->{nrRunningBuilds} = $c->model('DB::BuildSchedulingInfo')->search({ busy => 1 }, {})->count();
|
|
|
|
$c->stash->{nrQueuedBuilds} = $c->model('DB::BuildSchedulingInfo')->count();
|
2010-08-31 15:27:46 +00:00
|
|
|
}
|
2008-11-13 09:25:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-28 10:19:31 +00:00
|
|
|
sub index :Path :Args(0) {
|
2008-11-26 17:43:45 +00:00
|
|
|
my ($self, $c) = @_;
|
2009-04-02 16:15:57 +00:00
|
|
|
$c->stash->{template} = 'overview.tt';
|
2010-06-04 14:43:28 +00:00
|
|
|
$c->stash->{projects} = [$c->model('DB::Projects')->search(isAdmin($c) ? {} : {hidden => 0}, {order_by => 'name'})];
|
2010-04-27 13:29:08 +00:00
|
|
|
$c->stash->{newsItems} = [$c->model('DB::NewsItems')->search({}, { order_by => ['createtime DESC'], rows => 5 })];
|
2011-03-16 13:08:12 +00:00
|
|
|
# $c->stash->{nrbuilds} = [nrbuildsQuery($c, 30, "day", "", "", "", "")];
|
|
|
|
# <img src="http://chart.apis.google.com/chart?cht=bvg&chtt=Nr%20builds%20over%20the%20last%2030%20days&chs=300x100&chd=t:1785,881,2863,2828,1472,2847,1449,5634,1625,1200,1576,700,839,8533,1439,361,991,1337,1234,1322,1883,2146,1553,883,378,1395,1204,527,1147,124&chco=BBCEBB&chds=0,8533&chbh=a&chxt=y&chxr=0,0,8533"/>
|
2008-10-28 10:19:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-26 19:48:04 +00:00
|
|
|
sub login :Local {
|
|
|
|
my ($self, $c) = @_;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2008-11-26 19:48:04 +00:00
|
|
|
my $username = $c->request->params->{username} || "";
|
|
|
|
my $password = $c->request->params->{password} || "";
|
|
|
|
|
2011-08-16 14:51:19 +00:00
|
|
|
if ($username eq "" && $password eq "" && ! defined $c->flash->{referer}) {
|
|
|
|
my $baseurl = $c->uri_for('/');
|
|
|
|
my $refurl = $c->request->referer;
|
|
|
|
$c->flash->{referer} = $refurl if $refurl =~ m/^($baseurl)/;
|
2010-07-06 07:27:55 +00:00
|
|
|
}
|
|
|
|
|
2008-11-26 19:48:04 +00:00
|
|
|
if ($username && $password) {
|
|
|
|
if ($c->authenticate({username => $username, password => $password})) {
|
2011-08-16 14:51:19 +00:00
|
|
|
$c->response->redirect($c->flash->{referer} || $c->uri_for('/'));
|
|
|
|
$c->flash->{referer} = undef;
|
2008-11-26 19:48:04 +00:00
|
|
|
return;
|
2008-11-26 23:25:24 +00:00
|
|
|
}
|
2008-11-26 19:48:04 +00:00
|
|
|
$c->stash->{errorMsg} = "Bad username or password.";
|
|
|
|
}
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2008-11-26 19:48:04 +00:00
|
|
|
$c->stash->{template} = 'login.tt';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub logout :Local {
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
$c->logout;
|
2011-08-16 14:51:19 +00:00
|
|
|
$c->response->redirect($c->request->referer || $c->uri_for('/'));
|
2008-11-26 19:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-26 17:43:45 +00:00
|
|
|
sub queue :Local {
|
2008-11-26 19:48:04 +00:00
|
|
|
my ($self, $c) = @_;
|
2008-11-26 17:43:45 +00:00
|
|
|
$c->stash->{template} = 'queue.tt';
|
|
|
|
$c->stash->{queue} = [$c->model('DB::Builds')->search(
|
2010-01-22 10:29:54 +00:00
|
|
|
{finished => 0}, {join => ['schedulingInfo', 'project'] , order_by => ["priority DESC", "timestamp"], '+select' => ['project.enabled', 'schedulingInfo.priority', 'schedulingInfo.disabled', 'schedulingInfo.busy'], '+as' => ['enabled', 'priority', 'disabled', 'busy'] })];
|
2009-10-26 14:30:42 +00:00
|
|
|
$c->stash->{flashMsg} = $c->flash->{buildMsg};
|
2008-11-26 17:43:45 +00:00
|
|
|
}
|
|
|
|
|
2010-08-31 15:27:46 +00:00
|
|
|
|
2009-12-01 19:15:09 +00:00
|
|
|
sub timeline :Local {
|
|
|
|
my ($self, $c) = @_;
|
2009-12-01 19:17:38 +00:00
|
|
|
my $pit = time();
|
2011-04-01 07:40:06 +00:00
|
|
|
$c->stash->{pit} = $pit;
|
2009-12-01 19:17:38 +00:00
|
|
|
$pit = $pit-(24*60*60)-1;
|
2009-12-01 19:15:09 +00:00
|
|
|
|
|
|
|
$c->stash->{template} = 'timeline.tt';
|
|
|
|
$c->stash->{builds} = [$c->model('DB::Builds')->search(
|
|
|
|
{finished => 1, stoptime => { '>' => $pit } }
|
|
|
|
, { join => 'resultInfo'
|
|
|
|
, order_by => ["starttime"]
|
2011-04-01 07:40:06 +00:00
|
|
|
, '+select' => [ 'resultInfo.starttime', 'resultInfo.stoptime', 'resultInfo.buildstatus' ]
|
|
|
|
, '+as' => [ 'starttime', 'stoptime', 'buildstatus' ]
|
2009-12-01 19:15:09 +00:00
|
|
|
})];
|
|
|
|
}
|
2008-11-26 17:43:45 +00:00
|
|
|
|
2010-08-31 15:27:46 +00:00
|
|
|
|
|
|
|
sub status :Local {
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
$c->stash->{steps} = [ $c->model('DB::BuildSteps')->search(
|
|
|
|
{ 'me.busy' => 1, 'schedulingInfo.busy' => 1 },
|
2011-04-01 07:40:06 +00:00
|
|
|
{ join => [ 'schedulingInfo', 'build' ]
|
|
|
|
, order_by => [ 'machine' ]
|
2010-08-31 15:27:46 +00:00
|
|
|
} ) ];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-04 10:59:14 +00:00
|
|
|
# Hydra::Base::Controller::ListBuilds needs this.
|
|
|
|
sub get_builds : Chained('/') PathPart('') CaptureArgs(0) {
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
$c->stash->{allBuilds} = $c->model('DB::Builds');
|
2009-04-03 15:37:21 +00:00
|
|
|
$c->stash->{jobStatus} = $c->model('DB')->resultset('JobStatus');
|
2009-04-08 22:08:00 +00:00
|
|
|
$c->stash->{allJobsets} = $c->model('DB::Jobsets');
|
|
|
|
$c->stash->{allJobs} = $c->model('DB::Jobs');
|
2009-04-03 15:37:21 +00:00
|
|
|
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceeded');
|
2009-03-04 16:36:23 +00:00
|
|
|
$c->stash->{channelBaseName} = "everything";
|
2009-03-04 10:59:14 +00:00
|
|
|
}
|
|
|
|
|
2009-03-31 13:48:03 +00:00
|
|
|
|
|
|
|
sub robots_txt : Path('robots.txt') {
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
|
2009-03-31 14:14:45 +00:00
|
|
|
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
|
2009-03-31 14:55:47 +00:00
|
|
|
( uri_for($controller, 'closure', $bindings, "*")
|
|
|
|
, uri_for($controller, 'manifest', $bindings)
|
|
|
|
, uri_for($controller, 'pkg', $bindings, "*")
|
|
|
|
, uri_for($controller, 'nixexprs', $bindings)
|
2009-09-30 12:26:51 +00:00
|
|
|
, uri_for($controller, 'channel_contents', $bindings)
|
2009-03-31 14:14:45 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2009-03-31 13:48:03 +00:00
|
|
|
# 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 =
|
2009-03-31 14:55:47 +00:00
|
|
|
( uri_for('Build', 'buildtimedeps', ["*"])
|
|
|
|
, uri_for('Build', 'runtimedeps', ["*"])
|
2010-01-22 14:44:09 +00:00
|
|
|
, uri_for('Build', 'deps', ["*"])
|
2009-04-14 12:40:00 +00:00
|
|
|
, uri_for('Build', 'view_nixlog', ["*"], "*")
|
2010-03-12 08:50:56 +00:00
|
|
|
, uri_for('Build', 'view_log', ["*"], "*")
|
|
|
|
, uri_for('Build', 'view_log', ["*"])
|
2011-01-04 12:50:59 +00:00
|
|
|
, uri_for('Build', 'download', ["*"], "*")
|
2010-07-30 10:17:47 +00:00
|
|
|
, uri_for('Root', 'nar', [], "*")
|
2010-09-03 09:17:54 +00:00
|
|
|
, uri_for('Root', 'status', [])
|
2010-10-19 08:34:13 +00:00
|
|
|
, uri_for('Root', 'all', [])
|
2011-08-25 14:50:31 +00:00
|
|
|
, uri_for('API', 'scmdiff', [])
|
2011-09-26 14:47:55 +00:00
|
|
|
, uri_for('API', 'logdiff', [],"*", "*")
|
2010-10-19 08:34:13 +00:00
|
|
|
, uri_for('Project', 'all', ["*"])
|
2009-03-31 14:14:45 +00:00
|
|
|
, channelUris('Root', ["*"])
|
|
|
|
, channelUris('Project', ["*", "*"])
|
|
|
|
, channelUris('Jobset', ["*", "*", "*"])
|
|
|
|
, channelUris('Job', ["*", "*", "*", "*"])
|
|
|
|
, channelUris('Build', ["*"])
|
2009-03-31 13:48:03 +00:00
|
|
|
);
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2009-03-31 14:55:47 +00:00
|
|
|
$c->stash->{'plain'} = { data => "User-agent: *\n" . join('', map { "Disallow: $_\n" } @rules) };
|
2009-03-31 13:48:03 +00:00
|
|
|
$c->forward('Hydra::View::Plain');
|
|
|
|
}
|
|
|
|
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2008-10-28 10:19:31 +00:00
|
|
|
sub default :Path {
|
2008-11-26 17:43:45 +00:00
|
|
|
my ($self, $c) = @_;
|
2009-02-25 14:34:29 +00:00
|
|
|
notFound($c, "Page not found.");
|
2009-02-13 17:35:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-25 10:52:41 +00:00
|
|
|
sub end : ActionClass('RenderView') {
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
|
|
|
|
if (scalar @{$c->error}) {
|
|
|
|
$c->stash->{template} = 'error.tt';
|
|
|
|
$c->stash->{errors} = $c->error;
|
2009-02-25 16:29:54 +00:00
|
|
|
if ($c->response->status >= 300) {
|
|
|
|
$c->stash->{httpStatus} =
|
|
|
|
$c->response->status . " " . HTTP::Status::status_message($c->response->status);
|
|
|
|
}
|
2009-02-25 10:52:41 +00:00
|
|
|
$c->clear_errors;
|
|
|
|
}
|
|
|
|
}
|
2008-10-28 10:19:31 +00:00
|
|
|
|
|
|
|
|
2010-06-22 12:00:19 +00:00
|
|
|
sub nar :Local :Args(1) {
|
|
|
|
my ($self, $c, $path) = @_;
|
|
|
|
|
2011-03-23 13:03:40 +00:00
|
|
|
$path = ($ENV{NIX_STORE_DIR} || "/nix/store")."/$path";
|
2010-06-22 12:00:19 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-12-03 09:40:25 +00:00
|
|
|
sub change_password : Path('change-password') : Args(0) {
|
|
|
|
my ($self, $c) = @_;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2010-12-03 09:40:25 +00:00
|
|
|
requireLogin($c) if !$c->user_exists;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
|
|
|
$c->stash->{template} = 'change-password.tt';
|
2010-12-03 09:40:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub change_password_submit : Path('change-password/submit') : Args(0) {
|
|
|
|
my ($self, $c) = @_;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2010-12-03 09:40:25 +00:00
|
|
|
requireLogin($c) if !$c->user_exists;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
|
|
|
my $password = $c->request->params->{"password"};
|
2010-12-03 09:40:25 +00:00
|
|
|
my $password_check = $c->request->params->{"password_check"};
|
|
|
|
print STDERR "$password \n";
|
|
|
|
print STDERR "$password_check \n";
|
|
|
|
error($c, "Passwords did not match, go back and try again!") if $password ne $password_check;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
2010-12-03 09:40:25 +00:00
|
|
|
my $hashed = sha1_hex($password);
|
|
|
|
$c->user->update({ password => $hashed}) ;
|
2011-04-01 07:40:06 +00:00
|
|
|
|
|
|
|
$c->res->redirect("/");
|
2010-12-03 09:40:25 +00:00
|
|
|
}
|
2010-06-22 12:00:19 +00:00
|
|
|
|
2011-04-18 08:21:27 +00:00
|
|
|
sub logo :Local {
|
|
|
|
my ($self, $c) = @_;
|
|
|
|
my $path = $ENV{"HYDRA_LOGO"} or die("Logo not set!");
|
|
|
|
$c->serve_static_file($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-28 10:19:31 +00:00
|
|
|
1;
|