Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package openQA for openSUSE:Factory checked in at 2026-07-07 21:01:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openQA (Old) and /work/SRC/openSUSE:Factory/.openQA.new.1982 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openQA" Tue Jul 7 21:01:01 2026 rev:864 rq:1364047 version:5.1783327469.933c54e2 Changes: -------- --- /work/SRC/openSUSE:Factory/openQA/openQA.changes 2026-07-06 12:32:47.148334878 +0200 +++ /work/SRC/openSUSE:Factory/.openQA.new.1982/openQA.changes 2026-07-07 21:02:39.061138462 +0200 @@ -2 +2 @@ -Fri Jul 03 12:05:11 UTC 2026 - [email protected] +Mon Jul 06 08:44:37 UTC 2026 - [email protected] @@ -4 +4,3 @@ -- Update to version 5.1783080295.ebd1693c: +- Update to version 5.1783327469.933c54e2: + * fix(obs_rsync): use scope guards to avoid stalls + * chore(deps): Dependency cron 2026-07-04 @@ -5,0 +8,7 @@ + * feat: request unredacted settings in openqa-clone-job and warn + * feat: allow authenticated operators to fetch unredacted job settings + +------------------------------------------------------------------- +Fri Jul 03 11:09:14 UTC 2026 - [email protected] + +- Update to version 5.1783076943.6691832d: Old: ---- openQA-5.1783080295.ebd1693c.obscpio New: ---- openQA-5.1783327469.933c54e2.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openQA-client-test.spec ++++++ --- /var/tmp/diff_new_pack.VdCHVZ/_old 2026-07-07 21:02:40.325181705 +0200 +++ /var/tmp/diff_new_pack.VdCHVZ/_new 2026-07-07 21:02:40.329181842 +0200 @@ -18,7 +18,7 @@ %define short_name openQA-client Name: %{short_name}-test -Version: 5.1783080295.ebd1693c +Version: 5.1783327469.933c54e2 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA-devel-test.spec ++++++ --- /var/tmp/diff_new_pack.VdCHVZ/_old 2026-07-07 21:02:40.373183348 +0200 +++ /var/tmp/diff_new_pack.VdCHVZ/_new 2026-07-07 21:02:40.373183348 +0200 @@ -18,7 +18,7 @@ %define short_name openQA-devel Name: %{short_name}-test -Version: 5.1783080295.ebd1693c +Version: 5.1783327469.933c54e2 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA-test.spec ++++++ --- /var/tmp/diff_new_pack.VdCHVZ/_old 2026-07-07 21:02:40.413184716 +0200 +++ /var/tmp/diff_new_pack.VdCHVZ/_new 2026-07-07 21:02:40.413184716 +0200 @@ -18,7 +18,7 @@ %define short_name openQA Name: %{short_name}-test -Version: 5.1783080295.ebd1693c +Version: 5.1783327469.933c54e2 Release: 0 Summary: Test package for openQA License: GPL-2.0-or-later ++++++ openQA-worker-test.spec ++++++ --- /var/tmp/diff_new_pack.VdCHVZ/_old 2026-07-07 21:02:40.445185811 +0200 +++ /var/tmp/diff_new_pack.VdCHVZ/_new 2026-07-07 21:02:40.449185948 +0200 @@ -18,7 +18,7 @@ %define short_name openQA-worker Name: %{short_name}-test -Version: 5.1783080295.ebd1693c +Version: 5.1783327469.933c54e2 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ openQA.spec ++++++ --- /var/tmp/diff_new_pack.VdCHVZ/_old 2026-07-07 21:02:40.497187590 +0200 +++ /var/tmp/diff_new_pack.VdCHVZ/_new 2026-07-07 21:02:40.501187727 +0200 @@ -104,7 +104,7 @@ %define devel_requires %devel_no_selenium_requires chromedriver Name: openQA -Version: 5.1783080295.ebd1693c +Version: 5.1783327469.933c54e2 Release: 0 Summary: Framework for automated system-level testing (web-frontend, scheduler and tools) Group: Development/Tools/Other ++++++ openQA-5.1783080295.ebd1693c.obscpio -> openQA-5.1783327469.933c54e2.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/lib/OpenQA/Script/CloneJob.pm new/openQA-5.1783327469.933c54e2/lib/OpenQA/Script/CloneJob.pm --- old/openQA-5.1783080295.ebd1693c/lib/OpenQA/Script/CloneJob.pm 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/lib/OpenQA/Script/CloneJob.pm 2026-07-06 10:44:29.000000000 +0200 @@ -109,8 +109,15 @@ sub clone_job_get_job ($jobid, $url_handler, $options) { my $url = $url_handler->{remote_url}->clone; $url->path("jobs/$jobid"); + $url->query->merge(unredacted => 1); $url->query->merge(check_assets => 1) unless $options->{'ignore-missing-assets'}; my $job = _get_with_retry($url_handler, $url, $jobid, 'job', $options)->{job}; + + if (my @redacted = grep { ($job->{settings}->{$_} // '') eq '[redacted]' } keys %{$job->{settings}}) { + warn "Job $jobid has redacted secrets: " . join(', ', sort @redacted) . "\n"; + warn "These clone as '[redacted]'. Use operator credentials for actual secrets.\n"; + } + print STDERR Cpanel::JSON::XS->new->pretty->encode($job) if $options->{verbose}; $job->{vars} = _get_vars($jobid, $url_handler, $options) if $options->{reproduce}; return $job; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/lib/OpenQA/Shared/Controller/Auth.pm new/openQA-5.1783327469.933c54e2/lib/OpenQA/Shared/Controller/Auth.pm --- old/openQA-5.1783080295.ebd1693c/lib/OpenQA/Shared/Controller/Auth.pm 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/lib/OpenQA/Shared/Controller/Auth.pm 2026-07-06 10:44:29.000000000 +0200 @@ -52,11 +52,22 @@ } sub auth ($self) { + return 1 if $self->_auth; + $self->render(json => {error => $self->stash('auth_error') // 'Not authorized'}, status => 403); + return 0; +} + +sub auth_maybe ($self) { + $self->_auth; + return 1; +} + +sub _auth ($self) { my $log = $self->app->log; # Prevent authentication via file domain (where potentially untrusted HTML is served) if ($self->via_domain($self->config->{global}->{file_domain})) { - $self->render(json => {error => 'Forbidden via file domain'}, status => 403); + $self->stash(auth_error => 'Forbidden via file domain'); return 0; } @@ -66,8 +77,8 @@ if ($self->req->method ne 'GET' && !$self->valid_csrf) { # Invalidate session-based auth if CSRF is missing; fallback to API headers if present $user = undef; - $self->render(json => {error => 'Bad CSRF token!'}, status => 403) and return 0 - unless $self->is_api_request; + $self->stash(auth_error => 'Bad CSRF token!'); + return 0 unless $self->is_api_request; } } @@ -101,7 +112,7 @@ return 1; } - $self->render(json => {error => $reason}, status => 403); + $self->stash(auth_error => $reason); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm --- old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 2026-07-06 10:44:29.000000000 +0200 @@ -452,6 +452,7 @@ my $details = $self->stash('details') || 0; my $check_assets = !!$self->param('check_assets'); my $follow = $self->param('follow'); + my $unredacted = $self->param('unredacted') && $self->is_operator; return unless my $job = $self->find_job_or_render_not_found($job_id, $follow ? {prefetch => 'settings'} : {}); $job = $job->latest_job if $follow; $job = $job->to_hash( @@ -460,6 +461,7 @@ deps => 1, details => $details, parent_group => 1, + unredacted => $unredacted, ); $job->{followed_id} = $job_id if ($job_id != $job->{id}); $self->render(json => {job => $job}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm --- old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI/Plugin/ObsRsync/Task.pm 2026-07-06 10:44:29.000000000 +0200 @@ -24,7 +24,6 @@ return $job->retry({delay => $retry_interval}) if !$retry_max_count || $job->retries < $retry_max_count; - $helper->unlock($project) if $project; return $job->finish( {code => 2, message => "Exceeded retry count $retry_max_count. Consider job will be re-triggered later"}); } @@ -46,18 +45,18 @@ my $helper = $app->obs_rsync; my $home = $helper->home; - if ($job->info && !$job->info->{notes}{project_lock}) { - return _retry_or_finish($job, $helper) unless $helper->lock($project); - $job->note(project_lock => 1); - } + return _retry_or_finish($job, $helper) + unless my $project_guard = $helper->guard($project); + $job->note(project_lock => 1); + my $dirty = 0; try { $dirty = $helper->is_status_dirty($project, 1) } catch ($e) { - return _retry_or_finish($job, $helper, $project, RETRY_INTERVAL_ON_EXCEPTION, RETRY_MAX_COUNT_ON_EXCEPTION); + return _retry_or_finish($job, $helper, undef, RETRY_INTERVAL_ON_EXCEPTION, RETRY_MAX_COUNT_ON_EXCEPTION); } - return _retry_or_finish($job, $helper, $project) if $dirty; + return _retry_or_finish($job, $helper) if $dirty; - return _retry_or_finish($job, $helper, $project) + return _retry_or_finish($job, $helper) unless my $concurrency_guard = $helper->concurrency_guard(); $helper->log_job_id($project, $job->id); @@ -68,7 +67,6 @@ try { IPC::Run::run(\@cmd, \$stdin, \$stdout, \$error); $exit_code = $?; } catch ($e) { $error_from_exception = $e } - $helper->unlock($project); return $job->finish(0) if (!$exit_code); $error ||= $error_from_exception; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm --- old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm 2026-07-06 10:44:29.000000000 +0200 @@ -100,8 +100,6 @@ $app->helper('obs_rsync.log_failure' => \&_log_failure); $app->helper('obs_rsync.concurrency_guard' => \&_concurrency_guard); $app->helper('obs_rsync.guard' => \&_guard); - $app->helper('obs_rsync.lock' => \&_lock); - $app->helper('obs_rsync.unlock' => \&_unlock); # Templates push @{$app->renderer->paths}, @@ -449,14 +447,6 @@ return $c->app->minion->guard('obs_rsync_project_' . $project . '_lock', LOCK_TIMEOUT); } -sub _lock ($c, $project) { - return $c->app->minion->lock('obs_rsync_project_' . $project . '_lock', LOCK_TIMEOUT); -} - -sub _unlock ($c, $project) { - return $c->app->minion->unlock('obs_rsync_project_' . $project . '_lock'); -} - sub _log_job_id ($c, $project, $job_id) { my $home = $c->obs_rsync->home; return _write_to_file(Mojo::File->new($home, $project, '.job_id'), $job_id); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI.pm new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI.pm --- old/openQA-5.1783080295.ebd1693c/lib/OpenQA/WebAPI.pm 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/lib/OpenQA/WebAPI.pm 2026-07-06 10:44:29.000000000 +0200 @@ -79,6 +79,8 @@ = $api_public->under('/')->to('Auth#auth_admin')->name('api_ensure_admin'); my $api_auth_any_user = $api_public->under('/')->to('Auth#auth')->name('api_ensure_user'); + my $api_maybe_auth = $api_public->under('/')->to('Auth#auth_maybe'); + OpenQA::Setup::setup_template_search_path($self); OpenQA::Setup::load_plugins($self, $auth); @@ -293,6 +295,8 @@ my $api_ro = $api_auth_operator->any('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1'); my $api_ra = $api_auth_admin->any('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1'); my $api_public_r = $api_public->any('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1'); + my $api_maybe_auth_r = $api_maybe_auth->any('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1'); + $api_public_r->get('/routes')->name('api_v1_list_routes')->to('routes#list'); push @api_routes, $api_ru, $api_ro, $api_ra, $api_public_r; @@ -327,8 +331,8 @@ $api_ra->delete('/parent_groups/<group_id:num>')->name('apiv1_delete_parent_group')->to('job_group#delete'); # api/v1/jobs - $api_public_r->get('/jobs')->name('apiv1_jobs')->to('job#list'); - $api_public_r->get('/jobs/overview')->name('apiv1_jobs_overview')->to('job#overview'); + $api_maybe_auth_r->get('/jobs')->name('apiv1_jobs')->to('job#list'); + $api_maybe_auth_r->get('/jobs/overview')->name('apiv1_jobs_overview')->to('job#overview'); $api_ro->post('/jobs')->name('apiv1_create_job')->to('job#create'); $api_ro->post('/jobs/cancel')->name('apiv1_cancel_jobs')->to('job#cancel'); $api_ro->post('/jobs/restart')->name('apiv1_restart_jobs')->to('job#restart'); @@ -338,9 +342,10 @@ my $job_r = $api_ro->any('/jobs/<jobid:num>'); push @api_routes, $job_r; - $api_public_r->any('/jobs/<jobid:num>')->name('apiv1_job')->to('job#show'); + $api_maybe_auth_r->any('/jobs/<jobid:num>')->name('apiv1_job')->to('job#show'); $api_public_r->get('/experimental/jobs/<jobid:num>/status')->name('apiv1_get_status')->to('job#get_status'); - $api_public_r->any('/jobs/<jobid:num>/details')->name('apiv1_job')->to('job#show', details => 1); + $api_maybe_auth_r->any('/jobs/<jobid:num>/details')->name('apiv1_job')->to('job#show', details => 1); + $job_r->put('/')->name('apiv1_put_job')->to('job#update'); $job_r->delete('/')->name('apiv1_delete_job')->to('job#destroy'); $job_r->post('/prio')->name('apiv1_job_prio')->to('job#prio'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/t/35-script_clone_job.t new/openQA-5.1783327469.933c54e2/t/35-script_clone_job.t --- old/openQA-5.1783080295.ebd1693c/t/35-script_clone_job.t 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/t/35-script_clone_job.t 2026-07-06 10:44:29.000000000 +0200 @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later use Test::Most; -use Test::Warnings qw(:report_warnings warning); +use Test::Warnings qw(:report_warnings warning warnings); use FindBin; use lib "$FindBin::Bin/lib", "$FindBin::Bin/../external/os-autoinst-common/lib"; @@ -78,20 +78,39 @@ subtest 'getting job' => sub { my $clone_mock = Test::MockModule->new('OpenQA::Script::CloneJob'); $clone_mock->redefine(_handle_unexpected_return_code => sub ($tx) { die 'unexpected return code' }); - my $fake_res = Test::FakeResult->new(is_success => 0, code => 400, json => {FOO => 'bar'}); - my $fake_txn = Test::MockObject->new->set_always(res => $fake_res)->set_always(error => undef); - my $fake_ua = Test::MockObject->new->set_always(build_tx => $fake_txn); - $fake_ua->set_always(max_redirects => $fake_ua); + $clone_mock->redefine( + _get_with_retry => sub ($url_handler, $url, $jobid, $ctx, $options) { + return {job => {settings => {}}} if $ctx eq 'job'; + return {FOO => 'bar'} if $ctx eq 'vars.json of job'; + die "Unexpected ctx: $ctx"; + }); + my %fake_params = (host => 'host', from => 'from', apikey => 'key', apisecret => 'secret'); my $url_handler = OpenQA::Script::CloneJob::create_url_handler(\%fake_params); - $url_handler->{remote} = $fake_ua; $url_handler->{remote_url} = Mojo::URL->new('foo'); my $options = {'ignore-missing-assets' => 1, reproduce => 1}; - throws_ok { clone_job_get_job(42, $url_handler, $options) } qr/unexpected return code/, - 'unexpected return code handled'; - $fake_res->is_success(1)->code(200); + my $job = clone_job_get_job(42, $url_handler, $options); - is_deeply $job, {vars => {FOO => 'bar'}}, 'vars assigned' or always_explain $job; + is_deeply $job, {settings => {}, vars => {FOO => 'bar'}}, 'vars assigned' or always_explain $job; + throws_ok { OpenQA::Script::CloneJob::_get_with_retry(undef, undef, undef, 'invalid', undef) } + qr/Unexpected ctx: invalid/, 'Mock throws on unexpected ctx'; +}; + +subtest 'getting job with redacted secrets' => sub { + my $clone_mock = Test::MockModule->new('OpenQA::Script::CloneJob'); + $clone_mock->redefine( + _get_with_retry => sub { + return {job => {id => 42, settings => {_SECRET_VAR => '[redacted]', NORMAL_VAR => 'visible'}}}; + }); + $clone_mock->redefine(_get_vars => sub { {} }); + + my $url_handler = {remote_url => Mojo::URL->new('http://remote')}; + my $options = {'ignore-missing-assets' => 1}; + + my @w = warnings { clone_job_get_job(42, $url_handler, $options) }; + like $w[0], qr/Job 42 has redacted secrets: _SECRET_VAR/, + 'warning is emitted when settings contain redacted secrets' + or diag explain \@w; }; subtest 'clone job apply settings tests' => sub { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/t/api/04-jobs.t new/openQA-5.1783327469.933c54e2/t/api/04-jobs.t --- old/openQA-5.1783080295.ebd1693c/t/api/04-jobs.t 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/t/api/04-jobs.t 2026-07-06 10:44:29.000000000 +0200 @@ -2045,4 +2045,30 @@ $t->delete_ok('/api/v1/jobs/99937')->status_is(200); $t->get_ok('/api/v1/jobs/99937')->status_is(404); -done_testing(); +subtest 'redacted settings' => sub { + my $job = $jobs->find(99926); + $job->set_property('_SECRET_PASSWORD', 'supersecret'); + + my $t_guest = Test::Mojo->new('OpenQA::WebAPI'); + $t_guest->get_ok('/api/v1/jobs/99926', 'guest: GET /api/v1/jobs/99926')->status_is(200); + is $t_guest->tx->res->json->{job}->{settings}->{_SECRET_PASSWORD}, '[redacted]', 'guest: secrets are redacted'; + + $t->get_ok('/api/v1/jobs/99926', 'operator: GET /api/v1/jobs/99926')->status_is(200); + is $t->tx->res->json->{job}->{settings}->{_SECRET_PASSWORD}, '[redacted]', + 'operator: secrets are redacted by default'; + + $t->get_ok('/api/v1/jobs/99926?unredacted=1', 'operator: GET /api/v1/jobs/99926?unredacted=1')->status_is(200); + is $t->tx->res->json->{job}->{settings}->{_SECRET_PASSWORD}, 'supersecret', + 'operator: secrets are revealed when requested'; + + my $t_non_op = client(Test::Mojo->new('OpenQA::WebAPI'), apikey => 'LANCELOTKEY01', apisecret => 'MANYPEOPLEKNOW'); + $t_non_op->get_ok('/api/v1/jobs/99926?unredacted=1', 'non-operator: GET /api/v1/jobs/99926?unredacted=1') + ->status_is(200); + is $t_non_op->tx->res->json->{job}->{settings}->{_SECRET_PASSWORD}, '[redacted]', + 'non-operator: secrets remain redacted even if requested'; + + $job->settings->find({key => '_SECRET_PASSWORD'})->delete; +}; + +done_testing; + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/t/api/14-plugin_obs_rsync.t new/openQA-5.1783327469.933c54e2/t/api/14-plugin_obs_rsync.t --- old/openQA-5.1783080295.ebd1693c/t/api/14-plugin_obs_rsync.t 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/t/api/14-plugin_obs_rsync.t 2026-07-06 10:44:29.000000000 +0200 @@ -102,13 +102,14 @@ sub lock_test { # use BAIL_OUT because only first failure is important - BAIL_OUT('Cannot lock') unless $helper->lock('Proj1'); - BAIL_OUT('Shouldnt lock') if $helper->lock('Proj1'); - BAIL_OUT('Cannot unlock') unless $helper->unlock('Proj1'); - BAIL_OUT('Cannot lock') unless $helper->lock('Proj1'); - BAIL_OUT('Shouldnt lock') if $helper->lock('Proj1'); - BAIL_OUT('Cannot unlock') unless $helper->unlock('Proj1'); - ok 1, 'lock/unlock behaves as expected'; + my $guard1 = $helper->guard('Proj1'); + BAIL_OUT('Cannot lock via guard') unless $guard1; + BAIL_OUT('Shouldnt lock twice') if $helper->guard('Proj1'); + undef $guard1; + my $guard2 = $helper->guard('Proj1'); + BAIL_OUT('Cannot lock via guard after release') unless $guard2; + undef $guard2; + ok 1, 'guard behaves as expected'; } subtest 'test lock smoke' => sub { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/t/ui/27-plugin_obs_rsync_gru.t new/openQA-5.1783327469.933c54e2/t/ui/27-plugin_obs_rsync_gru.t --- old/openQA-5.1783080295.ebd1693c/t/ui/27-plugin_obs_rsync_gru.t 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/t/ui/27-plugin_obs_rsync_gru.t 2026-07-06 10:44:29.000000000 +0200 @@ -22,7 +22,7 @@ has app => sub { $app }; has retries => 200; sub finish ($self, $result) { $self->{state} = 'finished'; $self->{result} = $result } - sub info (@) { {notes => {project_lock => 1}} } + sub note ($self, @args) { } } # uncoverable statement $t->post_ok('/admin/obs_rsync/Proj1/runs' => $params)->status_is(201, 'trigger rsync'); @@ -52,7 +52,10 @@ }; subtest 'retrying' => sub { - my $obs_rsync = Test::MockObject->new->set_always(home => 'home')->set_true('unlock'); + my $obs_rsync + = Test::MockObject->new->set_always(home => 'home')->set_true('unlock') + ->set_always(guard => Test::MockObject->new)->set_always(retry_interval => 120) + ->set_always(retry_max_count => 200); $obs_rsync->mock(is_status_dirty => sub { die "is_status_dirty failed\n" }); my $job = FakeMinionJob->new(app => Test::MockObject->new->set_always(obs_rsync => $obs_rsync)); OpenQA::WebAPI::Plugin::ObsRsync::Task::run($job, {project => 'foo'}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openQA-5.1783080295.ebd1693c/tools/ci/autoinst.sha new/openQA-5.1783327469.933c54e2/tools/ci/autoinst.sha --- old/openQA-5.1783080295.ebd1693c/tools/ci/autoinst.sha 2026-07-03 14:04:55.000000000 +0200 +++ new/openQA-5.1783327469.933c54e2/tools/ci/autoinst.sha 2026-07-06 10:44:29.000000000 +0200 @@ -1 +1 @@ -dcc97e9540c42f722678e15002d38df1c18f658c \ No newline at end of file +c3cb41daa60ce53156b4c36222a89e14145e7c93 \ No newline at end of file ++++++ openQA.obsinfo ++++++ --- /var/tmp/diff_new_pack.VdCHVZ/_old 2026-07-07 21:02:57.537770563 +0200 +++ /var/tmp/diff_new_pack.VdCHVZ/_new 2026-07-07 21:02:57.557771247 +0200 @@ -1,5 +1,5 @@ name: openQA -version: 5.1783080295.ebd1693c -mtime: 1783080295 -commit: ebd1693c4409720a74ec9d5203ff0ef70c3227d1 +version: 5.1783327469.933c54e2 +mtime: 1783327469 +commit: 933c54e227e654c9db2fc2394abe5ef5f00f2130
