Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package openQA for openSUSE:Factory checked 
in at 2025-09-03 21:08:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openQA (Old)
 and      /work/SRC/openSUSE:Factory/.openQA.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openQA"

Wed Sep  3 21:08:52 2025 rev:739 rq:1302611 version:5.1756905114.bb4fa746

Changes:
--------
--- /work/SRC/openSUSE:Factory/openQA/openQA.changes    2025-09-01 
17:17:46.713894844 +0200
+++ /work/SRC/openSUSE:Factory/.openQA.new.1977/openQA.changes  2025-09-03 
21:09:26.069715354 +0200
@@ -1,0 +2,16 @@
+Wed Sep 03 14:13:20 UTC 2025 - ok...@suse.com
+
+- Update to version 5.1756905114.bb4fa746:
+  * Fix syntax error in nginx config
+  * Mark unconfigured api route log as uncoverable statement
+  * Increase test coverage for lib/OpenQA/WebAPI/Description.pm
+  * parser: ktap: Don't write diagnostic data into $subtest_name
+  * Extend tests for configuring subdomain to serve files
+  * Avoid job terminated unexpectedly with signal handler in delete needles
+  * Allow configuring subdomain for serving logs/assets more securely
+  * Do not invoke Mojo::IOLoop->remove twice
+  * Add support for Bearer token authentication
+  * Worker::Engines::isotovideo: Simplify using more Mojo::File
+  * Worker::Engines::isotovideo: Remove obsolete comment
+
+-------------------------------------------------------------------

Old:
----
  openQA-5.1756479924.9488e2cc.obscpio

New:
----
  openQA-5.1756905114.bb4fa746.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openQA-client-test.spec ++++++
--- /var/tmp/diff_new_pack.fzhazQ/_old  2025-09-03 21:09:27.633781446 +0200
+++ /var/tmp/diff_new_pack.fzhazQ/_new  2025-09-03 21:09:27.637781615 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-client
 Name:           %{short_name}-test
-Version:        5.1756479924.9488e2cc
+Version:        5.1756905114.bb4fa746
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-devel-test.spec ++++++
--- /var/tmp/diff_new_pack.fzhazQ/_old  2025-09-03 21:09:27.665782798 +0200
+++ /var/tmp/diff_new_pack.fzhazQ/_new  2025-09-03 21:09:27.665782798 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-devel
 Name:           %{short_name}-test
-Version:        5.1756479924.9488e2cc
+Version:        5.1756905114.bb4fa746
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-test.spec ++++++
--- /var/tmp/diff_new_pack.fzhazQ/_old  2025-09-03 21:09:27.689783813 +0200
+++ /var/tmp/diff_new_pack.fzhazQ/_new  2025-09-03 21:09:27.693783982 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA
 Name:           %{short_name}-test
-Version:        5.1756479924.9488e2cc
+Version:        5.1756905114.bb4fa746
 Release:        0
 Summary:        Test package for openQA
 License:        GPL-2.0-or-later

++++++ openQA-worker-test.spec ++++++
--- /var/tmp/diff_new_pack.fzhazQ/_old  2025-09-03 21:09:27.717784996 +0200
+++ /var/tmp/diff_new_pack.fzhazQ/_new  2025-09-03 21:09:27.721785164 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-worker
 Name:           %{short_name}-test
-Version:        5.1756479924.9488e2cc
+Version:        5.1756905114.bb4fa746
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA.spec ++++++
--- /var/tmp/diff_new_pack.fzhazQ/_old  2025-09-03 21:09:27.757786686 +0200
+++ /var/tmp/diff_new_pack.fzhazQ/_new  2025-09-03 21:09:27.761786855 +0200
@@ -97,7 +97,7 @@
 %define devel_requires %devel_no_selenium_requires chromedriver
 
 Name:           openQA
-Version:        5.1756479924.9488e2cc
+Version:        5.1756905114.bb4fa746
 Release:        0
 Summary:        The openQA web-frontend, scheduler and tools
 License:        GPL-2.0-or-later
@@ -593,6 +593,8 @@
 %dir %{_sysconfdir}/nginx
 %dir %{_sysconfdir}/nginx/vhosts.d
 %config %{_sysconfdir}/nginx/vhosts.d/openqa.conf.template
+%config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-assets.inc
+%config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-endpoints.inc
 %config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-locations.inc
 %config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-upstreams.inc
 # apparmor profile

++++++ openQA-5.1756479924.9488e2cc.obscpio -> 
openQA-5.1756905114.bb4fa746.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/Makefile 
new/openQA-5.1756905114.bb4fa746/Makefile
--- old/openQA-5.1756479924.9488e2cc/Makefile   2025-08-29 17:05:24.000000000 
+0200
+++ new/openQA-5.1756905114.bb4fa746/Makefile   2025-09-03 15:11:54.000000000 
+0200
@@ -124,7 +124,7 @@
        done
 
        install -d -m 755 "$(DESTDIR)"/etc/nginx/vhosts.d
-       for i in openqa-locations.inc openqa-upstreams.inc 
openqa.conf.template; do \
+       for i in openqa-assets.inc openqa-endpoints.inc openqa-locations.inc 
openqa-upstreams.inc openqa.conf.template; do \
                install -m 644 etc/nginx/vhosts.d/$$i 
"$(DESTDIR)"/etc/nginx/vhosts.d ;\
        done
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/dist/rpm/openQA.spec 
new/openQA-5.1756905114.bb4fa746/dist/rpm/openQA.spec
--- old/openQA-5.1756479924.9488e2cc/dist/rpm/openQA.spec       2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/dist/rpm/openQA.spec       2025-09-03 
15:11:54.000000000 +0200
@@ -593,6 +593,8 @@
 %dir %{_sysconfdir}/nginx
 %dir %{_sysconfdir}/nginx/vhosts.d
 %config %{_sysconfdir}/nginx/vhosts.d/openqa.conf.template
+%config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-assets.inc
+%config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-endpoints.inc
 %config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-locations.inc
 %config(noreplace) %{_sysconfdir}/nginx/vhosts.d/openqa-upstreams.inc
 # apparmor profile
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/docs/Client.asciidoc 
new/openQA-5.1756905114.bb4fa746/docs/Client.asciidoc
--- old/openQA-5.1756479924.9488e2cc/docs/Client.asciidoc       2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/docs/Client.asciidoc       2025-09-03 
15:11:54.000000000 +0200
@@ -96,9 +96,9 @@
 The authentication mechanism used by `openqa-cli` was specifically designed to
 allow secure access to the REST API even via unencrypted HTTP connections. But
 when your openQA server has been deployed with HTTPS (and for HTTP connections
-originating from localhost) you can also use plain old Basic authentication
-with a personal access token. That allows for almost any HTTP client to be used
-with openQA.
+originating from localhost) you can also use plain old Basic or Bearer token
+authentication with a personal access token. That allows for almost any HTTP
+client to be used with openQA.
 
 This access token is made up of your username, and the same key/secret combo
 the `openqa-cli` authentication mechanism uses. All you have to do is combine
@@ -111,6 +111,16 @@
     https://openqa.example.com/api/v1/assets/1
 ----
 
+And for HTTP clients that don't support Basic authentication or where the use
+of plain HTTP headers might be more convenient, you can also send the
+personal access token in the form of a Bearer token.
+
+[source,sh]
+----
+curl -H 'Authorization: Bearer arthur:1234567890ABCDEF:ABCDEF1234567890'\
+    -X DELETE https://openqa.example.com/api/v1/assets/1
+----
+
 == Features
 
 Many of the `openqa-cli api` features are designed to be similar to other
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa-assets.inc 
new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa-assets.inc
--- old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa-assets.inc       
1970-01-01 01:00:00.000000000 +0100
+++ new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa-assets.inc       
2025-09-03 15:11:54.000000000 +0200
@@ -0,0 +1,12 @@
+alias /var/lib/openqa/share/factory/;
+## Optional to require authentication for asset downloads
+#auth_request /api/v1/auth;
+autoindex          on;
+tcp_nopush         on;
+sendfile           on;
+sendfile_max_chunk 1m;
+
+# Enforce download of assets so HTML assets cannot highjack session
+# note: Can be disabled when using the alternative of making a redirect to a
+#       different subdomain mentioned in "openqa-locations.inc".
+add_header Content-Disposition 'attachment; filename="$1"';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa-endpoints.inc 
new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa-endpoints.inc
--- old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa-endpoints.inc    
1970-01-01 01:00:00.000000000 +0100
+++ new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa-endpoints.inc    
2025-09-03 15:11:54.000000000 +0200
@@ -0,0 +1,68 @@
+root /usr/share/openqa/public;
+
+client_max_body_size 0;
+
+# The "client_body_buffer_size" value should usually be larger
+# than the UPLOAD_CHUNK_SIZE used by openQA workers, so there is
+# no excessive buffering to disk
+client_body_buffer_size 2m;
+
+# Default is exact which would need an exact match of Last-Modified
+if_modified_since before;
+
+## Optional to make use of auth_request to require authentication for asset 
downloads
+#location /api/v1/auth {
+#    internal;
+#    proxy_pass http://webui;
+#    tcp_nodelay        on;
+#    proxy_read_timeout 900;
+#    proxy_send_timeout 900;
+#    proxy_pass_request_body off;
+#    proxy_set_header Content-Length "";
+#    proxy_set_header Host $host;
+#    proxy_set_header X-Original-URI $request_uri;
+#    proxy_set_header X-Forwarded-Host $host:$server_port;
+#    proxy_set_header X-Forwarded-Server $host;
+#    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+#    proxy_set_header X-Forwarded-Proto $scheme;
+#}
+
+## Optional faster image downloads for large deployments
+#location /image {
+#    alias /var/lib/openqa/images/;
+#    tcp_nopush         on;
+#    sendfile           on;
+#    sendfile_max_chunk 1m;
+#}
+
+location /api/v1/ws/ {
+    proxy_pass http://websocket;
+    proxy_http_version 1.1;
+    proxy_read_timeout 3600;
+    proxy_send_timeout 3600;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection "upgrade";
+    proxy_set_header Host $host;
+}
+
+location /liveviewhandler/ {
+    proxy_pass http://livehandler;
+    proxy_http_version 1.1;
+    proxy_read_timeout 3600;
+    proxy_send_timeout 3600;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection "upgrade";
+    proxy_set_header Host $host;
+}
+
+location / {
+    proxy_pass "http://webui";;
+    tcp_nodelay        on;
+    proxy_read_timeout 900;
+    proxy_send_timeout 900;
+    proxy_set_header Host $host;
+    proxy_set_header X-Forwarded-Host $host:$server_port;
+    proxy_set_header X-Forwarded-Server $host;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header X-Forwarded-Proto $scheme;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa-locations.inc 
new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa-locations.inc
--- old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa-locations.inc    
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa-locations.inc    
2025-09-03 15:11:54.000000000 +0200
@@ -1,82 +1,10 @@
-root /usr/share/openqa/public;
-
-client_max_body_size 0;
-
-# The "client_body_buffer_size" value should usually be larger
-# than the UPLOAD_CHUNK_SIZE used by openQA workers, so there is
-# no excessive buffering to disk
-client_body_buffer_size 2m;
-
-# Default is exact which would need an exact match of Last-Modified
-if_modified_since before;
-
 ## Optional faster assets downloads for large deployments
 #location /assets {
-#    alias /var/lib/openqa/share/factory/;
-#    # Optional to require authentication for asset downloads
-#    #auth_request /api/v1/auth;
-#    autoindex          on;
-#    tcp_nopush         on;
-#    sendfile           on;
-#    sendfile_max_chunk 1m;
+#    include vhosts.d/openqa-assets.inc;
 #
-#    # Enforce download of assets so HTML assets cannot highjack session
-#    add_header Content-Disposition 'attachment; filename="$1"';
-#}
-
-## Optional to make use of auth_request to require authentication for asset 
downloads
-#location /api/v1/auth {
-#    internal;
-#    proxy_pass http://webui;
-#    tcp_nodelay        on;
-#    proxy_read_timeout 900;
-#    proxy_send_timeout 900;
-#    proxy_pass_request_body off;
-#    proxy_set_header Content-Length "";
-#    proxy_set_header Host $host;
-#    proxy_set_header X-Original-URI $request_uri;
-#    proxy_set_header X-Forwarded-Host $host:$server_port;
-#    proxy_set_header X-Forwarded-Server $host;
-#    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-#    proxy_set_header X-Forwarded-Proto $scheme;
-#}
-
-## Optional faster image downloads for large deployments
-#location /image {
-#    alias /var/lib/openqa/images/;
-#    tcp_nopush         on;
-#    sendfile           on;
-#    sendfile_max_chunk 1m;
+#    ## Alternatively, make a redirect to a different subdomain in accordance
+#    ## with the file_subdomain in openQA config
+#    #return 301 http://file.$host$request_uri;
 #}
 
-location /api/v1/ws/ {
-    proxy_pass http://websocket;
-    proxy_http_version 1.1;
-    proxy_read_timeout 3600;
-    proxy_send_timeout 3600;
-    proxy_set_header Upgrade $http_upgrade;
-    proxy_set_header Connection "upgrade";
-    proxy_set_header Host $host;
-}
-
-location /liveviewhandler/ {
-    proxy_pass http://livehandler;
-    proxy_http_version 1.1;
-    proxy_read_timeout 3600;
-    proxy_send_timeout 3600;
-    proxy_set_header Upgrade $http_upgrade;
-    proxy_set_header Connection "upgrade";
-    proxy_set_header Host $host;
-}
-
-location / {
-    proxy_pass "http://webui";;
-    tcp_nodelay        on;
-    proxy_read_timeout 900;
-    proxy_send_timeout 900;
-    proxy_set_header Host $host;
-    proxy_set_header X-Forwarded-Host $host:$server_port;
-    proxy_set_header X-Forwarded-Server $host;
-    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-    proxy_set_header X-Forwarded-Proto $scheme;
-}
+include vhosts.d/openqa-endpoints.inc;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa.conf.template 
new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa.conf.template
--- old/openQA-5.1756479924.9488e2cc/etc/nginx/vhosts.d/openqa.conf.template    
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/etc/nginx/vhosts.d/openqa.conf.template    
2025-09-03 15:11:54.000000000 +0200
@@ -17,3 +17,27 @@
 #    ssl_certificate_key /etc/dehydrated/certs/openqa.example.com/privkey.pem;
 #    include vhosts.d/openqa-locations.inc;
 #}
+
+# Provide different servers for serving assets under a different subdomain
+# (enable these in accordance to "Optional faster asset downloads …" in
+# "openqa-locations.inc")
+#server {
+#    listen       80;
+#    listen       [::]:80;
+#    # Set server_name in accordance with the file_subdomain in openQA config
+#    server_name  file.openqa.example.com;
+#    location /assets {
+#        include vhosts.d/openqa-assets.inc;
+#    }
+#    include vhosts.d/openqa-endpoints.inc;
+#}
+#server {
+#    listen       443;
+#    listen       [::]:443;
+#    # Set server_name in accordance with the file_subdomain in openQA config
+#    server_name  file.openqa.example.com;
+#    location /assets {
+#        include vhosts.d/openqa-assets.inc;
+#    }
+#    include vhosts.d/openqa-endpoints.inc;
+#}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/etc/openqa/openqa.ini 
new/openQA-5.1756905114.bb4fa746/etc/openqa/openqa.ini
--- old/openQA-5.1756479924.9488e2cc/etc/openqa/openqa.ini      2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/etc/openqa/openqa.ini      2025-09-03 
15:11:54.000000000 +0200
@@ -56,9 +56,17 @@
 ##   avoid potentially malicious JavaScript code from hijacking the user 
session.
 ## * Set to "insecure-browsing" so these files can be browsed directly. This is
 ##   insecure as potentially malicious JavaScript can hijack the user session.
+## * Set to "subdomain:…" to let openQA redirect these files to another
+##   subdomain, e.g. "subdomain:file" will redirect file downloads from e.g.
+##   "example.openqa.org" to "file.example.openqa.org". The files will no 
longer
+##   be served as attachments to HTML files can be browsed conveniently and
+##   securely from that subdomain.
 ## note: Does *not* affect files served via a reverse proxy. The default NGINX
 ##       config contained by the openQA repo shows how to enforce a download
-##       prompt for assets served via NGINX.
+##       prompt for assets served via NGINX. It also shows how to setup
+##       redirections to a different subdomain which is a little bit more 
config
+##       effort and you also need to make sure your certificate is valid for
+##       this subdomain.
 #file_security_policy = download-prompt
 
 ## space-separated list of domains recognized by job labeling
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Parser/Format/KTAP.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Parser/Format/KTAP.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Parser/Format/KTAP.pm   
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Parser/Format/KTAP.pm   
2025-09-03 15:11:54.000000000 +0200
@@ -48,7 +48,7 @@
     $self->test or return;
 
     my $line = $result->as_string;
-    return unless $line =~ /^#\s*(?<status>ok|not ok)\s+\d+\s+(?<name>.+)/;
+    return unless $line =~ /^#\s*(?<status>ok|not ok)\s+\d+\s+(?<name>[^#]*)/;
     my ($status, $subtest_name) = @+{qw(status name)};
 
     my $has_todo = $line =~ /#\s*TODO\b/i;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Setup.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Setup.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Setup.pm        2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Setup.pm        2025-09-03 
15:11:54.000000000 +0200
@@ -72,6 +72,7 @@
             # deprecated alternate for git_auto_commit below
             scm => undef,
             hsts => 365,
+            file_subdomain => undef,
             audit_enabled => 1,
             max_rss_limit => 0,
             profiling_enabled => 0,
@@ -307,7 +308,10 @@
 }
 
 sub _validate_security_policy ($app, $config) {
-    if ($config->{file_security_policy} !~ 
m/^(download-prompt|insecure-browsing)$/) {
+    if ($config->{file_security_policy} =~ 
m/^(download-prompt|insecure-browsing|subdomain:(.+))$/) {
+        if (defined(my $subdomain = $2)) { $config->{file_subdomain} = 
"$subdomain." }
+    }
+    else {
         $config->{file_security_policy} = 'download-prompt';
         $app->log->warn('Invalid file_security_policy specified, defaulting to 
"download-prompt"');
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Controller/Auth.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Controller/Auth.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Controller/Auth.pm       
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Controller/Auth.pm       
2025-09-03 15:11:54.000000000 +0200
@@ -10,9 +10,9 @@
 use Mojo::URL;
 
 sub check ($self) {
-    if ($self->app->config->{no_localhost_auth}) {
-        return 1 if $self->is_local_request;
-    }
+    my $config = $self->app->config;
+    return 1 if $config->{no_localhost_auth} && $self->is_local_request;
+    return 0 if $self->via_subdomain($config->{global}->{file_subdomain});
 
     my $req = $self->req;
     my $headers = $req->headers;
@@ -46,6 +46,12 @@
 sub auth ($self) {
     my $log = $self->app->log;
 
+    # Prevent authentication via file subdomain (where potentially untrusted 
HTML is served)
+    if ($self->via_subdomain($self->config->{global}->{file_subdomain})) {
+        $self->render(json => {error => 'Forbidden via file subdomain'}, 
status => 403);
+        return 0;
+    }
+
     # Browser with a logged in user
     my ($user, $reason) = (undef, 'Not authorized');
     if ($user = $self->current_user) {
@@ -56,7 +62,10 @@
     else {
 
         # Personal access token
-        if (my $userinfo = $self->req->url->to_abs->userinfo) {
+        if (($self->req->headers->authorization // '') =~ /^Bearer\s+(.+)$/) {
+            ($user, $reason) = $self->_token_auth($reason, $1);
+        }
+        elsif (my $userinfo = $self->req->url->to_abs->userinfo) {
             ($user, $reason) = $self->_token_auth($reason, $userinfo);
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Controller/Running.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Controller/Running.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Controller/Running.pm    
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Controller/Running.pm    
2025-09-03 15:11:54.000000000 +0200
@@ -111,9 +111,7 @@
     my $close_connection = sub ($self) {
         my $worker_id = $worker->id;
         log_debug "Connection to worker with ID $worker_id will be closed 
because $logfile changed";
-        Mojo::IOLoop->remove($timer_id);
         $self->finish;
-        close $log;
     };
     $timer_id = Mojo::IOLoop->recurring(
         TEXT_STREAMING_INTERVAL() => sub (@) {
@@ -143,7 +141,11 @@
         });
 
     # Stop monitoring the logfile when the connection closes
-    $self->on(finish => sub (@) { Mojo::IOLoop->remove($timer_id); });
+    $self->on(
+        finish => sub (@) {
+            Mojo::IOLoop->remove($timer_id);
+            close $log;
+        });
 }
 
 sub livelog ($self) {
@@ -196,7 +198,6 @@
     # setup a function to stop streaming again
     my $timer_id;
     my $close_connection = sub ($self, @) {
-        Mojo::IOLoop->remove($timer_id);
         $self->finish;
     };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Controller/Session.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Controller/Session.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Controller/Session.pm    
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Controller/Session.pm    
2025-09-03 15:11:54.000000000 +0200
@@ -53,8 +53,11 @@
 sub create {
     my ($self) = @_;
     my $ref = $self->req->headers->referrer;
-    my $auth_method = $self->app->config->{auth}->{method};
+    my $config = $self->app->config;
+    my $auth_method = $config->{auth}->{method};
     my $auth_module = "OpenQA::WebAPI::Auth::$auth_method";
+    return $self->render(text => 'Forbidden via file subdomain', status => 403)
+      if $self->via_subdomain($config->{global}->{file_subdomain});
 
     # prevent redirecting loop when referrer is login page
     $ref = 'index' if !$ref or $ref eq $self->url_for('login');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Plugin/SharedHelpers.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Plugin/SharedHelpers.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Shared/Plugin/SharedHelpers.pm  
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Shared/Plugin/SharedHelpers.pm  
2025-09-03 15:11:54.000000000 +0200
@@ -21,6 +21,7 @@
     $app->helper(is_admin => \&_is_admin);
     $app->helper(is_local_request => \&_is_local_request);
     $app->helper(render_specific_not_found => \&_render_specific_not_found);
+    $app->helper(via_subdomain => \&_via_subdomain);
 }
 
 # returns the isotovideo command server web socket URL and the VNC argument 
for the given job or undef if not available
@@ -79,4 +80,9 @@
     return $c->render(status => 404, text => "$title - $error_message");
 }
 
+sub _via_subdomain ($c, $subdomain) {
+    return 0 unless defined $subdomain;
+    return index($c->req->url->to_abs->host, $subdomain) == 0;
+}
+
 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Task/Needle/Delete.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Task/Needle/Delete.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Task/Needle/Delete.pm   
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Task/Needle/Delete.pm   
2025-09-03 15:11:54.000000000 +0200
@@ -2,20 +2,23 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 package OpenQA::Task::Needle::Delete;
-use Mojo::Base 'Mojolicious::Plugin';
+use Mojo::Base 'Mojolicious::Plugin', -signatures;
 
 use OpenQA::Utils;
 use Scalar::Util 'looks_like_number';
 use Time::Seconds 'ONE_HOUR';
+use OpenQA::Task::SignalGuard;
 
 sub register {
     my ($self, $app) = @_;
     $app->minion->add_task(delete_needles => sub { _delete_needles($app, @_) 
});
 }
 
-sub _delete_needles {
-    my ($app, $minion_job, $args) = @_;
-
+sub _delete_needles ($app, $minion_job, $args) {
+    # SignalGuard will prevent the delete task to interrupt with no recovery,
+    # instead will retry once the gru server returned up and running. The popup
+    # on the frontend will wait until the retried job finished.
+    my $signal_guard = OpenQA::Task::SignalGuard->new($minion_job);
     my $schema = $app->schema;
     my $needles = $schema->resultset('Needles');
     my $user = $schema->resultset('Users')->find($args->{user_id});
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/WebAPI/Controller/File.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/WebAPI/Controller/File.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/WebAPI/Controller/File.pm       
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/WebAPI/Controller/File.pm       
2025-09-03 15:11:54.000000000 +0200
@@ -108,7 +108,8 @@
     return $self->reply->not_found if $path =~ qr/\.\./;
 
     my $file = path(assetdir(), $path)->to_string;
-    $self->_set_headers($file);
+    my $is_text = $self->_set_headers($file);
+    return if $self->_redirect_if_configured($is_text);
     return $self->reply->not_found unless -f $file && -r _;
     $self->reply->file($file);
 }
@@ -146,19 +147,41 @@
 
 sub _set_headers ($self, $path) {
     my $filename = basename($path);
-    # guess content type from extension
     my $headers = $self->res->headers;
-    return $headers->content_type('application/octet-stream') unless $filename 
=~ m/\.([^\.]+)$/;
-    my $ext = $1;
-    my $as_attachment = 1;
-    if (my $filetype = $self->app->types->type($ext)) {
-        $headers->content_type($filetype);
-        $headers->header('X-Content-Type-Options', 'nosniff') if $filetype =~ 
qr|^text/plain;?|;
-        my $allow_insecure = 
$self->app->config->{global}->{file_security_policy} ne 'download-prompt';
-        $as_attachment = 0 if ($allow_insecure || $filetype !~ m|html|) && 
$ext ne 'iso';
+    my $is_text = 0;
+    if ($filename =~ m/\.([^\.]+)$/) {
+        # guess content type from extension
+        my $ext = $1;
+        my $as_attachment = 1;
+        if (my $filetype = $self->app->types->type($ext)) {
+            $headers->content_type($filetype);
+            if ($filetype =~ qr|^text/plain;?|) {
+                $headers->header('X-Content-Type-Options', 'nosniff');
+                $is_text = 1;
+            }
+            my $allow_insecure = 
$self->app->config->{global}->{file_security_policy} ne 'download-prompt';
+            $as_attachment = 0 if ($allow_insecure || $filetype !~ m|html|) && 
$ext ne 'iso';
+        }
+        # force saveAs
+        $headers->content_disposition("attachment; filename=$filename;") if 
$as_attachment;
     }
-    # force saveAs
-    $headers->content_disposition("attachment; filename=$filename;") if 
$as_attachment;
+    else {
+        $headers->content_type('application/octet-stream');
+    }
+    return $is_text;
+}
+
+sub _redirect_if_configured ($self, $is_text) {
+    # skip harmless text files as the viewer doesn't follow redirects and 
those files are not problematic anyway
+    return 0 if $is_text || !defined(my $subdomain = 
$self->app->config->{global}->{file_subdomain});
+    # redirect to configured subdomain so potentially dangerious HTML files 
cannot use the current session
+    my $url = $self->req->url->to_abs;
+    my $host = $url->host;
+    # skip if already redirected
+    return 0 unless index($host, $subdomain) == -1;
+    $url->host($subdomain . $host);
+    $self->redirect_to($url);
+    return 1;
 }
 
 sub _serve_static ($self, $asset) {
@@ -170,7 +193,9 @@
     return $self->reply->not_found unless $asset;
     $log->debug('found ' . pp($asset));
 
-    $self->_set_headers($asset->path) if blessed $asset && 
$asset->isa('Mojo::Asset::File');
+    my $is_text = blessed $asset && $asset->isa('Mojo::Asset::File') && 
$self->_set_headers($asset->path);
+    return 1 if $self->_redirect_if_configured($is_text);
+
     $static->serve_asset($self, $asset);
     return !!$self->rendered;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/WebAPI/Description.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/WebAPI/Description.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/WebAPI/Description.pm   
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/WebAPI/Description.pm   
2025-09-03 15:11:54.000000000 +0200
@@ -55,7 +55,7 @@
             log_warning('get_pod_from_controllers: could not parse file: ['
                   . $ctrlrpath->child($controllers{$ctrl})->to_string
                   . '] for POD. Error: ['
-                  . $tree->error()
+                  . $parser->error()
                   . ']');
             next;
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm       
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/WebAPI/Plugin/ObsRsync.pm       
2025-09-03 15:11:54.000000000 +0200
@@ -44,7 +44,9 @@
     die("ssh-keygen is not available. Aborting.\n") unless which('ssh-keygen');
 
     if (!$plugin_r) {
-        $app->log->error('Routes not configured, plugin ObsRsync will be 
disabled') unless $plugin_r;
+        # uncoverable statement
+        $app->log->error('Routes not configured, plugin ObsRsync will be 
disabled')
+          unless $plugin_r;
     }
     else {
         $app->helper('obs_rsync.home' => sub { 
shift->app->config->{obs_rsync}->{home} });
@@ -155,7 +157,9 @@
     }
 
     if (!$plugin_api_r) {
-        $app->log->error('API routes not configured, plugin ObsRsync will not 
have API configured') unless $plugin_r;
+        # uncoverable statement
+        $app->log->error('API routes not configured, plugin ObsRsync will not 
have API configured')
+          unless $plugin_r;
     }
     else {
         $plugin_api_r->get('/obs_rsync')->name('plugin_obs_rsync_api_list')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Worker/Engines/isotovideo.pm 
new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Worker/Engines/isotovideo.pm
--- old/openQA-5.1756479924.9488e2cc/lib/OpenQA/Worker/Engines/isotovideo.pm    
2025-08-29 17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/lib/OpenQA/Worker/Engines/isotovideo.pm    
2025-09-03 15:11:54.000000000 +0200
@@ -51,14 +51,7 @@
 
 sub _save_vars ($pooldir, $vars) {
     die 'cannot get environment variables!\n' unless $vars;
-    my $fn = $pooldir . '/vars.json';
-    unlink "$pooldir/vars.json" if -e "$pooldir/vars.json";
-    open(my $fd, '>', $fn) or die "can not write vars.json: $!\n";
-    fcntl($fd, F_SETLKW, pack('ssqql', F_WRLCK, 0, 0, 0, $$)) or die "cannot 
lock vars.json: $!\n";
-    truncate($fd, 0) or die "cannot truncate vars.json: $!\n";
-
-    print $fd Cpanel::JSON::XS->new->pretty(1)->encode(\%$vars);
-    close($fd);
+    path($pooldir, 
'vars.json')->spew(Cpanel::JSON::XS->new->pretty(1)->encode(\%$vars));
 }
 
 sub detect_asset_keys ($vars) {
@@ -294,20 +287,10 @@
     log_info('+++ setup notes +++', channels => 'autoinst');
     log_info(sprintf("Running on $hostname:%d ($sysname $release $version 
$machine)", $instance),
         channels => 'autoinst');
-
     log_error('Failed enabling subreaper mode', channels => 'autoinst') unless 
session->subreaper;
-
-    # XXX: this should come from the worker table. Only included
-    # here for convenience when looking at the pool of
-    # debugging.
     my $job_settings = $job_info->{settings};
-    for my $i (qw(QEMUPORT VNC OPENQA_HOSTNAME)) {
-        $job_settings->{$i} = $ENV{$i};
-    }
-    if (open(my $fh, '>', 'job.json')) {
-        print $fh Cpanel::JSON::XS->new->pretty(1)->encode($job_info);
-        close $fh;
-    }
+    $job_settings->{$_} = $ENV{$_} for qw(QEMUPORT VNC OPENQA_HOSTNAME);
+    
path('job.json')->spew(Cpanel::JSON::XS->new->pretty(1)->encode($job_info));
 
     # pass worker instance and worker id to isotovideo
     # both used to create unique MAC and TAP devices if needed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/t/31-api_descriptions.t 
new/openQA-5.1756905114.bb4fa746/t/31-api_descriptions.t
--- old/openQA-5.1756479924.9488e2cc/t/31-api_descriptions.t    2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/t/31-api_descriptions.t    2025-09-03 
15:11:54.000000000 +0200
@@ -2,13 +2,31 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 use Test::Most;
+use Test::MockModule;
 use Test::Warnings ':report_warnings';
+use Test::Output qw(combined_like);
 # no OpenQA::Test::TimeLimit for this trivial test
 
+use File::Temp qw(tempdir);
+use Mojo::File qw(path);
+
 use Mojo::Base 'Mojolicious', -signatures;
 
 use_ok('OpenQA::WebAPI::Description', qw(get_pod_from_controllers 
set_api_desc));
 my $app = Mojolicious->new;
 get_pod_from_controllers($app);
 
+my $mock = Test::MockModule->new('Pod::POM');
+my $app_home = tempdir();
+my $route = 
$app->routes->any('/*wathever')->add_child($app->routes->any('/child')->to(controller
 => 'Main'));
+
+$mock->redefine(parse_file => undef);
+path($app_home . 
'/lib/OpenQA/WebAPI/Controller/API/V1/')->make_path->child('Main.pm')->touch;
+$app->home($app_home);
+
+combined_like {
+    get_pod_from_controllers($app, $route)
+}
+qr/\[WARN\].*get_pod_from_controllers/, 'Warning when file does not exist';
+
 done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/t/api/03-auth.t 
new/openQA-5.1756905114.bb4fa746/t/api/03-auth.t
--- old/openQA-5.1756479924.9488e2cc/t/api/03-auth.t    2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/t/api/03-auth.t    2025-09-03 
15:11:54.000000000 +0200
@@ -12,6 +12,7 @@
 use Test::Warnings qw(:all :report_warnings);
 use Mojo::URL;
 use Mojo::Util qw(encode hmac_sha1_sum);
+use OpenQA::Shared::Controller::Auth;
 use OpenQA::Test::TimeLimit '10';
 use OpenQA::Test::Case;
 use OpenQA::Test::Client 'client';
@@ -213,6 +214,28 @@
 
     # Valid access token (again)
     
$t->$userinfo('artie:ARTHURKEY01:EXCALIBUR')->delete_ok('/api/v1/assets/1')->status_is(404);
+
+    subtest 'Bearer token' => sub {
+        subtest 'Valid token' => sub {
+            $t->post_ok('/api/v1/feature' => {Authorization => 'Bearer 
lance:LANCELOTKEY01:MANYPEOPLEKNOW'} => form =>
+                  {version => 100})->status_is(200);
+        };
+
+        subtest 'Invalid username' => sub {
+            $t->post_ok('/api/v1/feature' => {Authorization => 'Bearer 
invalid:LANCELOTKEY01:MANYPEOPLEKNOW'} => form =>
+                  {version => 100})->status_is(403)->json_is({error => 
'invalid personal access token'});
+        };
+
+        subtest 'Invalid key' => sub {
+            $t->post_ok('/api/v1/feature' => {Authorization => 'Bearer 
lance:LANCELOTKEY02:MANYPEOPLEKNOW'} => form =>
+                  {version => 100})->status_is(403)->json_is({error => 
'invalid personal access token'});
+        };
+
+        subtest 'Invalid secret' => sub {
+            $t->post_ok('/api/v1/feature' => {Authorization => 'Bearer 
lance:LANCELOTKEY01:MANYPEOPLEKNOWS'} => form =>
+                  {version => 100})->status_is(403)->json_is({error => 
'invalid personal access token'});
+        };
+    };
 };
 
 subtest 'personal access token (with reverse proxy)' => sub {
@@ -250,4 +273,23 @@
       ->json_is({error => 'invalid personal access token'});
 };
 
+subtest 'auth forbidden via subdomain' => sub {
+    my $rendered;
+    my $req = Mojo::Message::Request->new;
+    $req->url->parse('http://foobar.openqa.de/test/42');
+    my $controller_mock = Test::MockModule->new('Mojolicious::Controller');
+    $controller_mock->redefine(req => $req);
+    $controller_mock->redefine(render => sub ($c, @args) { $rendered = [@args] 
});
+    my $c = OpenQA::Shared::Controller::Auth->new(app => $t->app, req => $req);
+    $c->config->{global}->{file_subdomain} = 'foobar.';
+    is $c->auth, 0, 'auth denied via subdomain';
+    my %expected_json = (error => 'Forbidden via file subdomain');
+    my @expected = (json => \%expected_json, status => 403);
+    is_deeply $rendered, \@expected, 'expected error and status';
+    $req->url->parse('http://openqa.de/test/42');
+    is $c->auth, 0, 'auth denied via regular domain';
+    $expected_json{error} = 'no api key';
+    is_deeply $rendered, \@expected, 'normal auth error via regular domain';
+};
+
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/t/config.t 
new/openQA-5.1756905114.bb4fa746/t/config.t
--- old/openQA-5.1756479924.9488e2cc/t/config.t 2025-08-29 17:05:24.000000000 
+0200
+++ new/openQA-5.1756905114.bb4fa746/t/config.t 2025-09-03 15:11:54.000000000 
+0200
@@ -333,6 +333,10 @@
     $config{file_security_policy} = 'wrong';
     combined_like { OpenQA::Setup::_validate_security_policy($app, \%config) } 
qr/Invalid.*security/, 'warning logged';
     is $config{file_security_policy}, 'download-prompt', 'default to 
"download-prompt" on invalid value';
+    is $config{file_subdomain}, undef, 'file_subdomain not populated yet';
+    $config{file_security_policy} = 'subdomain:foo';
+    OpenQA::Setup::_validate_security_policy($app, \%config);
+    is $config{file_subdomain}, 'foo.', 'file_subdomain populated via 
"subdomain:"';
 };
 
 subtest 'Multiple config files' => sub {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1756479924.9488e2cc/t/ui/07-file.t 
new/openQA-5.1756905114.bb4fa746/t/ui/07-file.t
--- old/openQA-5.1756479924.9488e2cc/t/ui/07-file.t     2025-08-29 
17:05:24.000000000 +0200
+++ new/openQA-5.1756905114.bb4fa746/t/ui/07-file.t     2025-09-03 
15:11:54.000000000 +0200
@@ -141,4 +141,12 @@
 
$t->get_ok('/assets/hdd/foo.qcow2')->status_is(200)->content_type_is('application/octet-stream');
 $t->get_ok('/assets/repo/testrepo/doesnotexist')->status_is(404);
 
+subtest 'redirection to different subdomain' => sub {
+    my $config = $t->app->config->{global};
+    $config->{file_security_policy} = 'subdomain:file';
+    $config->{file_subdomain} = 'file.';
+    $t->get_ok('/assets/repo/testrepo/README.html')->status_is(302);
+    $t->header_like(Location => 
qr|^http://file\.[^/]*/assets/repo/testrepo/README.html$|);
+};
+
 done_testing();

++++++ openQA.obsinfo ++++++
--- /var/tmp/diff_new_pack.fzhazQ/_old  2025-09-03 21:09:45.734546324 +0200
+++ /var/tmp/diff_new_pack.fzhazQ/_new  2025-09-03 21:09:45.738546494 +0200
@@ -1,5 +1,5 @@
 name: openQA
-version: 5.1756479924.9488e2cc
-mtime: 1756479924
-commit: 9488e2cc713a2fe405429668d2a46e27295223b4
+version: 5.1756905114.bb4fa746
+mtime: 1756905114
+commit: bb4fa7461f44b3a626444a170616cc04952a97a1
 

Reply via email to