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:
@ -22,7 +22,8 @@ use Hydra::Helper::CatalystUtils;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(
|
||||
fetchInput evalJobs checkBuild inputsToArgs
|
||||
restartBuild getPrevJobsetEval
|
||||
restartBuild getPrevJobsetEval updateDeclarativeJobset
|
||||
handleDeclarativeJobsetBuild
|
||||
);
|
||||
|
||||
|
||||
@ -467,4 +468,66 @@ sub checkBuild {
|
||||
};
|
||||
|
||||
|
||||
sub updateDeclarativeJobset {
|
||||
my ($db, $project, $jobsetName, $declSpec) = @_;
|
||||
|
||||
my @allowed_keys = qw(
|
||||
enabled
|
||||
hidden
|
||||
description
|
||||
nixexprinput
|
||||
nixexprpath
|
||||
checkinterval
|
||||
schedulingshares
|
||||
enableemail
|
||||
emailoverride
|
||||
keepnr
|
||||
);
|
||||
my %update = ( name => $jobsetName );
|
||||
foreach my $key (@allowed_keys) {
|
||||
$update{$key} = $declSpec->{$key};
|
||||
delete $declSpec->{$key};
|
||||
}
|
||||
txn_do($db, sub {
|
||||
my $jobset = $project->jobsets->update_or_create(\%update);
|
||||
$jobset->jobsetinputs->delete;
|
||||
while ((my $name, my $data) = each %{$declSpec->{"inputs"}}) {
|
||||
my $input = $jobset->jobsetinputs->create(
|
||||
{ name => $name,
|
||||
type => $data->{type},
|
||||
emailresponsible => $data->{emailresponsible}
|
||||
});
|
||||
$input->jobsetinputalts->create({altnr => 0, value => $data->{value}});
|
||||
}
|
||||
delete $declSpec->{"inputs"};
|
||||
die "invalid keys in declarative specification file\n" if (%{$declSpec});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
sub handleDeclarativeJobsetBuild {
|
||||
my ($db, $project, $build) = @_;
|
||||
|
||||
eval {
|
||||
my $id = $build->id;
|
||||
die "Declarative jobset build $id failed" unless $build->buildstatus == 0;
|
||||
my $declPath = ($build->buildoutputs)[0]->path;
|
||||
my $declText = read_file($declPath)
|
||||
or die "Couldn't read declarative specification file $declPath: $!";
|
||||
my $declSpec = decode_json($declText);
|
||||
txn_do($db, sub {
|
||||
my @kept = keys %$declSpec;
|
||||
push @kept, ".jobsets";
|
||||
$project->jobsets->search({ name => { "not in" => \@kept } })->update({ enabled => 0, hidden => 1 });
|
||||
while ((my $jobsetName, my $spec) = each %$declSpec) {
|
||||
updateDeclarativeJobset($db, $project, $jobsetName, $spec);
|
||||
}
|
||||
});
|
||||
};
|
||||
$project->jobsets->find({ name => ".jobsets" })->update({ errormsg => $@, errortime => time, fetcherrormsg => undef })
|
||||
if defined $@;
|
||||
|
||||
};
|
||||
|
||||
|
||||
1;
|
||||
|
@ -264,7 +264,7 @@ Readonly our $inputNameRE => "(?:[A-Za-z_][A-Za-z0-9-_]*)";
|
||||
|
||||
sub parseJobsetName {
|
||||
my ($s) = @_;
|
||||
$s =~ /^($projectNameRE):($jobsetNameRE)$/ or die "invalid jobset specifier ‘$s’\n";
|
||||
$s =~ /^($projectNameRE):(\.?$jobsetNameRE)$/ or die "invalid jobset specifier ‘$s’\n";
|
||||
return ($1, $2);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user