From 17b05acec06e3692d8f902e00603b726a2805d62 Mon Sep 17 00:00:00 2001 From: Dominik Heidler Date: Fri, 17 Jan 2025 12:21:44 +0100 Subject: [PATCH] Add jobs API option "follow" to return latest clone of queried job Ticket: https://progress.opensuse.org/issues/175305 --- lib/OpenQA/WebAPI/Controller/API/V1/Job.pm | 43 ++++++++++++++++++++-- lib/OpenQA/WebAPI/Plugin/Helpers.pm | 6 +-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm b/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm index 462b173a723..0be31221350 100644 --- a/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm +++ b/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm @@ -453,9 +453,25 @@ sub show ($self) { my $job_id = int($self->stash('jobid')); my $details = $self->stash('details') || 0; my $check_assets = !!$self->param('check_assets'); - my $job = $self->schema->resultset('Jobs')->find($job_id, {prefetch => 'settings'}); - return $self->reply->not_found unless $job; + my $follow = $self->param('follow'); # follow job clones and report most recent result for given id + + my @cloned_as; + my $job; + while (1) { + return unless $job = $self->find_job_or_render_not_found($job_id, {prefetch => 'settings'}); + if ($follow && $job->clone_id) { + push(@cloned_as, $job->clone_id); + $job_id = $job->clone_id; + next; + } + last; + } $job = $job->to_hash(assets => 1, check_assets => $check_assets, deps => 1, details => $details, parent_group => 1); + if ($job_id != $self->stash('jobid')) { + # if follow=1 return cloned job with original id + # but indicate clone chain in cloned_as + $job->{cloned_as} = \@cloned_as; + } $self->render(json => {job => $job}); } @@ -597,9 +613,28 @@ interested in the status. =cut sub get_status ($self) { + my $follow = $self->param('follow'); # follow job clones and report most recent result for given id my @fields = qw(id state result blocked_by_id); - return unless my $job = $self->find_job_or_render_not_found($self->stash('jobid')); - $self->render(json => {map { $_ => $job->$_ } @fields}); + my $query_jobid = $self->stash('jobid'); + my @cloned_as; + my $job; + while (1) { + return unless $job = $self->find_job_or_render_not_found($query_jobid); + if ($follow && $job->clone_id) { + push(@cloned_as, $job->clone_id); + $query_jobid = $job->clone_id; + next; + } + last; + } + my $json = {map { $_ => $job->$_ } @fields}; + if ($query_jobid != $self->stash('jobid')) { + # if follow=1 return cloned job with original id + # but indicate clone chain in cloned_as + $json->{id} = $self->stash('jobid'); + $json->{cloned_as} = \@cloned_as; + } + $self->render(json => $json); } =over 4 diff --git a/lib/OpenQA/WebAPI/Plugin/Helpers.pm b/lib/OpenQA/WebAPI/Plugin/Helpers.pm index 2f33c82f64f..21752f6a082 100644 --- a/lib/OpenQA/WebAPI/Plugin/Helpers.pm +++ b/lib/OpenQA/WebAPI/Plugin/Helpers.pm @@ -522,10 +522,8 @@ sub _param_hash ($c, $name) { return @$values ? {map { $_ => 1 } @$values} : undef; } -sub _find_job_or_render_not_found { - my ($c, $job_id) = @_; - - my $job = $c->schema->resultset('Jobs')->find(int($job_id)); +sub _find_job_or_render_not_found ($c, $job_id, $query_settings = {}) { + my $job = $c->schema->resultset('Jobs')->find(int($job_id), $query_settings); return $job if $job; $c->render(json => {error => 'Job does not exist'}, status => 404); return undef;