This commit is contained in:
Eelco Dolstra 2008-11-10 10:18:50 +00:00
parent f4a44db664
commit 8f42bf303f
16 changed files with 129 additions and 47 deletions

View file

@ -29,6 +29,7 @@ sub getBuild {
sub index :Path :Args(0) { sub index :Path :Args(0) {
my ( $self, $c ) = @_; my ( $self, $c ) = @_;
$c->stash->{template} = 'index.tt'; $c->stash->{template} = 'index.tt';
$c->stash->{jobs} = [$c->model('DB::Jobs')->all];
$c->stash->{projects} = [$c->model('DB::Projects')->all]; $c->stash->{projects} = [$c->model('DB::Projects')->all];
$c->stash->{allBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "timestamp DESC"})]; $c->stash->{allBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "timestamp DESC"})];
# Get the latest build for each unique job. # Get the latest build for each unique job.

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 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:G17vptu+2rEUXbsqVtoXzQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xP97YDrN7Bm2B/BlbQJ7fQ
# 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

@ -21,8 +21,8 @@ __PACKAGE__->set_primary_key("build", "logphase");
__PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" }); __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xvWlrugDQD11vH+7f91K0A # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:pt0CJFX1pP9Z2TjqrTjTkw
# 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

@ -21,8 +21,8 @@ __PACKAGE__->set_primary_key("build", "path");
__PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" }); __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SMsT6htcybeWNHhv82+ilA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3NKUaF4u4H6ZmIRCeva8yA
# 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

@ -38,6 +38,16 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("id"); __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to(
"project",
"HydraFrontend::Schema::Projects",
{ name => "project" },
);
__PACKAGE__->belongs_to(
"jobset",
"HydraFrontend::Schema::Jobsets",
{ name => "jobset", project => "project" },
);
__PACKAGE__->has_many( __PACKAGE__->has_many(
"inputs", "inputs",
"HydraFrontend::Schema::Inputs", "HydraFrontend::Schema::Inputs",
@ -55,8 +65,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nfVureYYGM1V/NHroQA5Tw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:8s5Z03ugocOVb021EwGVag
__PACKAGE__->has_many(dependents => 'HydraFrontend::Schema::Inputs', 'dependency'); __PACKAGE__->has_many(dependents => 'HydraFrontend::Schema::Inputs', 'dependency');

View file

@ -35,8 +35,8 @@ __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" }); __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3PAsUD+79bZk4vGeSyyACg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:AzV6B/6CCrroPlO32n2p3A
__PACKAGE__->belongs_to("dependency", "HydraFrontend::Schema::Builds", { id => "dependency" }); __PACKAGE__->belongs_to("dependency", "HydraFrontend::Schema::Builds", { id => "dependency" });

View file

@ -14,6 +14,10 @@ __PACKAGE__->add_columns(
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"priority", "priority",
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"busy",
{ data_type => "integer", is_nullable => 0, size => undef },
"locker",
{ data_type => "text", is_nullable => 0, size => undef },
"project", "project",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"jobset", "jobset",
@ -30,10 +34,20 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("id"); __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to(
"project",
"HydraFrontend::Schema::Projects",
{ name => "project" },
);
__PACKAGE__->belongs_to(
"jobset",
"HydraFrontend::Schema::Jobsets",
{ name => "jobset", project => "project" },
);
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:T8O0XTTOZXapWpJbzjKLTw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:GubRofAmJ/sbJbjyV3aKSQ
# 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

@ -6,7 +6,7 @@ use warnings;
use base 'DBIx::Class'; use base 'DBIx::Class';
__PACKAGE__->load_components("Core"); __PACKAGE__->load_components("Core");
__PACKAGE__->table("jobSetInputAlts"); __PACKAGE__->table("jobsetInputAlts");
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
"project", "project",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -33,8 +33,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:DzEHCDlnponciGmGASknlg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZjjWLbAWExxOqsDz41A3KA
# 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

@ -6,7 +6,7 @@ use warnings;
use base 'DBIx::Class'; use base 'DBIx::Class';
__PACKAGE__->load_components("Core"); __PACKAGE__->load_components("Core");
__PACKAGE__->table("jobSetInputs"); __PACKAGE__->table("jobsetInputs");
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
"project", "project",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -43,8 +43,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Lm2oIWEUSHFICYMX2qmTfw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:6hzbFjPWQ872UxFhhpxjFg
# 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

@ -6,7 +6,7 @@ use warnings;
use base 'DBIx::Class'; use base 'DBIx::Class';
__PACKAGE__->load_components("Core"); __PACKAGE__->load_components("Core");
__PACKAGE__->table("jobSets"); __PACKAGE__->table("jobsets");
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
"name", "name",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -20,6 +20,14 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("project", "name"); __PACKAGE__->set_primary_key("project", "name");
__PACKAGE__->has_many(
"builds",
"HydraFrontend::Schema::Builds",
{
"foreign.jobset" => "self.name",
"foreign.project" => "self.project",
},
);
__PACKAGE__->belongs_to( __PACKAGE__->belongs_to(
"project", "project",
"HydraFrontend::Schema::Projects", "HydraFrontend::Schema::Projects",
@ -38,10 +46,18 @@ __PACKAGE__->has_many(
"foreign.project" => "self.project", "foreign.project" => "self.project",
}, },
); );
__PACKAGE__->has_many(
"jobs",
"HydraFrontend::Schema::Jobs",
{
"foreign.jobset" => "self.name",
"foreign.project" => "self.project",
},
);
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:EmATMMeNmMd2AI8lVzcLFA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:oRV4yw0DWG5PI0agcM7QHA
# 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

@ -12,15 +12,25 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("name"); __PACKAGE__->set_primary_key("name");
__PACKAGE__->has_many(
"builds",
"HydraFrontend::Schema::Builds",
{ "foreign.project" => "self.name" },
);
__PACKAGE__->has_many( __PACKAGE__->has_many(
"jobsets", "jobsets",
"HydraFrontend::Schema::Jobsets", "HydraFrontend::Schema::Jobsets",
{ "foreign.project" => "self.name" }, { "foreign.project" => "self.name" },
); );
__PACKAGE__->has_many(
"jobs",
"HydraFrontend::Schema::Jobs",
{ "foreign.project" => "self.name" },
);
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 10:30:11
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZifQocKoHOPRrJQSPggZ+w # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9SeEXSEOH1ocrdkoa7fx5Q
# 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

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Hydra Overview" %] [% WRAPPER layout.tt title="Hydra Overview" %]
[% USE date %] [% USE date %]
<h1>Job <tt>[% build.project %]:[% build.attrname %]</tt> build [% id %]</h1> <h1>Job <tt>[% build.project.name %]:[% build.attrname %]</tt> build [% id %]</h1>
<h2>Information</h2> <h2>Information</h2>
@ -13,11 +13,11 @@
</tr> </tr>
<tr> <tr>
<th>Project:</th> <th>Project:</th>
<td><a href="[% c.uri_for('/project' build.project) %]"><tt>[% build.project %]</tt></a></td> <td><a href="[% c.uri_for('/project' build.project.name) %]"><tt>[% build.project.name %]</tt></a></td>
</tr> </tr>
<tr> <tr>
<th>Jobset:</th> <th>Jobset:</th>
<td><tt>[% build.jobset %]</tt></td> <td><tt>[% build.jobset.name %]</tt></td>
</tr> </tr>
<tr> <tr>
<th>Job name:</th> <th>Job name:</th>
@ -87,7 +87,7 @@
<td><tt>[% input.type %]</tt></td> <td><tt>[% input.type %]</tt></td>
<td> <td>
[% IF input.type == "build" %] [% IF input.type == "build" %]
<a href="[% c.uri_for('/build' input.dependency.id) %]">Job <tt>[% input.dependency.project %]:[% input.dependency.attrname %]</tt> build [% input.dependency.id %]</a> <a href="[% c.uri_for('/build' input.dependency.id) %]">Job <tt>[% input.dependency.project.name %]:[% input.dependency.attrname %]</tt> build [% input.dependency.id %]</a>
[% ELSIF input.type == "string" %] [% ELSIF input.type == "string" %]
<tt>"[% input.value %]"</tt> <tt>"[% input.value %]"</tt>
[% ELSE %] [% ELSE %]
@ -153,7 +153,7 @@
<tbody> <tbody>
[% FOREACH input IN build.dependents -%] [% FOREACH input IN build.dependents -%]
<tr> <tr>
<td><a href="[% c.uri_for('/build' input.build.id) %]">Job <tt>[% input.build.project %]:[% input.build.attrname %]</tt> build [% input.build.id %]</a></td> <td><a href="[% c.uri_for('/build' input.build.id) %]">Job <tt>[% input.build.project.name %]:[% input.build.attrname %]</tt> build [% input.build.id %]</a></td>
<td><tt>[% input.name %]</tt></td> <td><tt>[% input.name %]</tt></td>
<td><tt>[% input.build.system %]</tt></td> <td><tt>[% input.build.system %]</tt></td>
<td>[% date.format(input.build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% date.format(input.build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>

View file

@ -1,4 +1,25 @@
[% WRAPPER layout.tt title="Hydra Overview" %] [% WRAPPER layout.tt title="Hydra Overview" %]
[% USE date %]
<h1>Queue</h1>
<table class="tablesorter">
<thead>
<tr><th>Priority</th><th>Project</th><th>Job</th><th>System</th><th>Timestamp</th><th>Description</th></tr>
</thead>
<tbody>
[% FOREACH job IN jobs -%]
<tr>
<td>[% job.priority %]</td>
<td><tt>[% job.project.name %]</tt></td>
<td><tt>[% job.jobset.name %]</tt></td>
<td><tt>[% job.system %]</tt></td>
<td>[% date.format(job.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>
<td>[% job.description %]</td>
</tr>
[% END -%]
</tbody>
</table>
<h1>Job status</h1> <h1>Job status</h1>

View file

@ -9,8 +9,8 @@
[% END %] [% END %]
</td> </td>
<td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td> <td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td>
<td><a href="[% c.uri_for('/project' build.project) %]"><tt>[% build.project %]</tt></a></td> <td><a href="[% c.uri_for('/project' build.project.name) %]"><tt>[% build.project.name %]</tt></a></td>
<td><a href="[% c.uri_for('/job' build.project build.attrname) %]"><tt>[% build.attrname %]</tt></a></td> <td><a href="[% c.uri_for('/job' build.project.name build.attrname) %]"><tt>[% build.attrname %]</tt></a></td>
<td><tt>[% build.system %]</tt></td> <td><tt>[% build.system %]</tt></td>
<td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>
<td>[% build.description %]</td> <td>[% build.description %]</td>

View file

@ -4,7 +4,7 @@ create table builds (
-- Info about the inputs. -- Info about the inputs.
project text not null, -- !!! foreign key project text not null, -- !!! foreign key
jobSet text not null, -- !!! foreign key jobset text not null, -- !!! foreign key
attrName text not null, attrName text not null,
-- Info about the build result. -- Info about the build result.
@ -16,7 +16,10 @@ create table builds (
errorMsg text, -- error message in case of a Nix failure errorMsg text, -- error message in case of a Nix failure
startTime integer, -- in Unix time, 0 = used cached build result startTime integer, -- in Unix time, 0 = used cached build result
stopTime integer, stopTime integer,
system text not null system text not null,
foreign key (project) references projects(name), -- ignored by sqlite
foreign key (project, jobset) references jobsets(project, name) -- ignored by sqlite
); );
@ -28,7 +31,7 @@ create table inputs (
build integer, build integer,
job integer, job integer,
-- Copied from the jobSetInputs from which the build was created. -- Copied from the jobsetinputs from which the build was created.
name text not null, name text not null,
type text not null, type text not null,
uri text, uri text,
@ -83,29 +86,29 @@ create table projects (
-- A jobset consists of a set of inputs (e.g. SVN repositories), one -- A jobset consists of a set of inputs (e.g. SVN repositories), one
-- of which contains a Nix expression containing an attribute set -- of which contains a Nix expression containing an attribute set
-- describing build jobs. -- describing build jobs.
create table jobSets ( create table jobsets (
name text not null, name text not null,
project text not null, project text not null,
description text, description text,
nixExprInput text not null, -- name of the jobSetInput containing the Nix expression nixExprInput text not null, -- name of the jobsetInput containing the Nix expression
nixExprPath text not null, -- relative path of the Nix expression nixExprPath text not null, -- relative path of the Nix expression
primary key (project, name), primary key (project, name),
foreign key (project) references projects(name) on delete cascade, -- ignored by sqlite foreign key (project) references projects(name) on delete cascade, -- ignored by sqlite
foreign key (project, name, nixExprInput) references jobSetInputs(project, job, name) foreign key (project, name, nixExprInput) references jobsetInputs(project, job, name)
); );
create table jobSetInputs ( create table jobsetInputs (
project text not null, project text not null,
jobset text not null, jobset text not null,
name text not null, name text not null,
type text not null, -- "svn", "cvs", "path", "file", "string" type text not null, -- "svn", "cvs", "path", "file", "string"
primary key (project, jobset, name), primary key (project, jobset, name),
foreign key (project, jobset) references jobSets(project, name) on delete cascade -- ignored by sqlite foreign key (project, jobset) references jobsets(project, name) on delete cascade -- ignored by sqlite
); );
create table jobSetInputAlts ( create table jobsetInputAlts (
project text not null, project text not null,
jobset text not null, jobset text not null,
input text not null, input text not null,
@ -118,7 +121,7 @@ create table jobSetInputAlts (
value text, -- for type == 'string' value text, -- for type == 'string'
primary key (project, jobset, input, altnr), primary key (project, jobset, input, altnr),
foreign key (project, jobset, input) references jobSetInputs(project, jobset, name) on delete cascade -- ignored by sqlite foreign key (project, jobset, input) references jobsetInputs(project, jobset, name) on delete cascade -- ignored by sqlite
); );
@ -128,14 +131,20 @@ create table jobs (
priority integer not null, priority integer not null,
busy integer not null, -- true means someone is building this job now
locker text not null, -- !!! hostname/pid of the process building this job?
-- Info about the inputs. -- Info about the inputs.
project text not null, -- !!! foreign key project text not null, -- !!! foreign key
jobSet text not null, -- !!! foreign key jobset text not null, -- !!! foreign key
attrName text not null, attrName text not null,
-- What this job will build. -- What this job will build.
description text, description text,
drvPath text not null, drvPath text not null,
outPath text not null, outPath text not null,
system text not null system text not null,
foreign key (project) references projects(name), -- ignored by sqlite
foreign key (project, jobset) references jobsets(project, name) -- ignored by sqlite
); );

View file

@ -16,7 +16,7 @@ sub isValidPath {
sub buildJob { sub buildJob {
my ($project, $jobset, $jobName, $drvPath, $outPath, $usedInputs, $system) = @_; my ($project, $jobset, $jobName, $description, $drvPath, $outPath, $usedInputs, $system) = @_;
if (scalar($db->resultset('Builds')->search({project => $project->name, jobset => $jobset->name, attrname => $jobName, outPath => $outPath})) > 0) { if (scalar($db->resultset('Builds')->search({project => $project->name, jobset => $jobset->name, attrname => $jobName, outPath => $outPath})) > 0) {
print " already done\n"; print " already done\n";
@ -58,6 +58,7 @@ sub buildJob {
, project => $project->name , project => $project->name
, jobset => $jobset->name , jobset => $jobset->name
, attrname => $jobName , attrname => $jobName
, description => $description
, drvpath => $drvPath , drvpath => $drvPath
, outpath => $outPath , outpath => $outPath
, iscachedbuild => $isCachedBuild , iscachedbuild => $isCachedBuild
@ -175,17 +176,17 @@ sub checkJob {
my $infoXml = `nix-env -f $nixExprPath --query --available "*" --attr-path --out-path --drv-path --meta --xml --system-filter "*" --attr $jobName $extraArgs` my $infoXml = `nix-env -f $nixExprPath --query --available "*" --attr-path --out-path --drv-path --meta --xml --system-filter "*" --attr $jobName $extraArgs`
or die "cannot get information about the job: $?"; or die "cannot get information about the job: $?";
my $info = XMLin($infoXml, KeyAttr => ['attrPath', 'name']) my $info = XMLin($infoXml, ForceArray => 1, KeyAttr => ['attrPath', 'name'])
or die "cannot parse XML output"; or die "cannot parse XML output";
my $job = $info->{item}; my $job = $info->{item}->{$jobName};
die if !defined $job || $job->{attrPath} ne $jobName; die if !defined $job;
my $description = defined $job->{meta}->{description} ? $job->{meta}->{description}->{value} : ""; my $description = defined $job->{meta}->{description} ? $job->{meta}->{description}->{value} : "";
die unless $job->{drvPath} eq $drvPath; die unless $job->{drvPath} eq $drvPath;
my $outPath = $job->{outPath}; my $outPath = $job->{outPath};
buildJob($project, $jobset, $jobName, $drvPath, $outPath, $inputInfo, $job->{system}); buildJob($project, $jobset, $jobName, $description, $drvPath, $outPath, $inputInfo, $job->{system});
}; };