Enable declarative projects.

This allows fully declarative project specifications. This is best
illustrated by example:

* I create a new project, setting the declarative spec file to
  "spec.json" and the declarative input to a git repo pointing
  at git://github.com/shlevy/declarative-hydra-example.git
* hydra creates a special ".jobsets" jobset alongside the project
* Just before evaluating the ".jobsets" jobset, hydra fetches
  declarative-hydra-example.git, reads spec.json as a jobset spec,
  and updates the jobset's configuration accordingly:
{
    "enabled": 1,
    "hidden": false,
    "description": "Jobsets",
    "nixexprinput": "src",
    "nixexprpath": "default.nix",
    "checkinterval": 300,
    "schedulingshares": 100,
    "enableemail": false,
    "emailoverride": "",
    "keepnr": 3,
    "inputs": {
        "src": { "type": "git", "value": "git://github.com/shlevy/declarative-hydra-example.git", "emailresponsible": false },
        "nixpkgs": { "type": "git", "value": "git://github.com/NixOS/nixpkgs.git release-16.03", "emailresponsible": false }
    }
}
* When the "jobsets" job of the ".jobsets" jobset completes, hydra
  reads its output as a JSON representation of a dictionary of
  jobset specs and creates a jobset named "master" configured
  accordingly (In this example, this is the same configuration as
  .jobsets itself, except using release.nix instead of default.nix):
{
    "enabled": 1,
    "hidden": false,
    "description": "js",
    "nixexprinput": "src",
    "nixexprpath": "release.nix",
    "checkinterval": 300,
    "schedulingshares": 100,
    "enableemail": false,
    "emailoverride": "",
    "keepnr": 3,
    "inputs": {
        "src": { "type": "git", "value": "git://github.com/shlevy/declarative-hydra-example.git", "emailresponsible": false },
        "nixpkgs": { "type": "git", "value": "git://github.com/NixOS/nixpkgs.git release-16.03", "emailresponsible": false }
    }
}
This commit is contained in:
Shea Levy
2016-03-11 18:14:58 -05:00
parent 995f3b21db
commit 4392d3e21d
12 changed files with 168 additions and 4 deletions

View File

@ -14,6 +14,8 @@ use Data::Dump qw(dump);
use Try::Tiny;
use Net::Statsd;
use Time::HiRes qw(clock_gettime CLOCK_REALTIME);
use JSON;
use File::Slurp;
STDOUT->autoflush();
STDERR->autoflush(1);
@ -100,6 +102,23 @@ sub permute {
sub checkJobsetWrapped {
my ($jobset) = @_;
my $project = $jobset->project;
my $jobsetsJobset = length($project->declfile) && $jobset->name eq ".jobsets";
if ($jobsetsJobset) {
my @declInputs = fetchInput($plugins, $db, $project, $jobset, "decl", $project->decltype, $project->declvalue, 0);
my $declInput = @declInputs[0] or die "cannot find the input containing the declarative project specification\n";
die "multiple alternatives for the input containing the declarative project specificaiton are not supported\n"
if scalar @declInputs != 1;
my $declFile = $declInput->{storePath} . "/" . $project->declfile;
my $declText = read_file($declFile)
or die "Couldn't read declarative specification file $declFile: $!\n";
my $declSpec;
eval {
$declSpec = decode_json($declText);
};
die "Declarative specification file $declFile not valid JSON: $@\n" if $@;
updateDeclarativeJobset($db, $project, ".jobsets", $declSpec);
$jobset->discard_changes;
}
my $inputInfo = {};
my $exprType = $jobset->nixexprpath =~ /.scm$/ ? "guile" : "nix";
@ -143,6 +162,11 @@ sub checkJobsetWrapped {
my ($jobs, $nixExprInput) = evalJobs($inputInfo, $exprType, $jobset->nixexprinput, $jobset->nixexprpath);
my $evalStop = clock_gettime(CLOCK_REALTIME);
if ($jobsetsJobset) {
my @keys = keys %$jobs;
die "The .jobsets jobset must only have a single job named 'jobsets'"
unless (scalar @keys) == 1 && $keys[0] eq "jobsets";
}
Net::Statsd::timing("hydra.evaluator.eval_time", int(($evalStop - $evalStart) * 1000));
if ($dryRun) {