[kde-linux/os-autoinst-distri-kdelinux] /: Add VARIANT env var, construct qualified version

Thomas Duckworth <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 0850ed8186534604ac1085e6642acd973f4de790 by Thomas Duckworth.
Committed on 15/08/2026 at 08:00.
Pushed by tduck into branch 'master'.

Add VARIANT env var, construct qualified version

Adds a VARIANT environment variable, then constructs a qualified version
with it so to differentiate testing-buildstream and testing (+ any
future channels) in openQA. Also ensures all download logic actually
uses the correct edition, rather than defaulting to `testing`.

Also adds CI_PIPELINE_URL to the Settings tab in the web UI.

M  +1    -0    .env.example
M  +3    -1    .gitlab-ci.yml
M  +11   -4    lib/worker/download_image.py
M  +11   -1    lib/worker/job.py
M  +15   -12   lib/worker/job_flow.py
M  +1    -0    mocks/single-instance.yml
M  +2    -0    qa

https://invent.kde.org/kde-linux/os-autoinst-distri-kdelinux/-/commit/0850ed8186534604ac1085e6642acd973f4de790

diff --git a/.env.example b/.env.example
index a8912e0..285a2dc 100644
--- a/.env.example
+++ b/.env.example
@@ -4,3 +4,4 @@ OPENQA_HOST_ADDR=openqa.kde-linux.haraldsitter.eu
 OPENQA_API_KEY=1234567890ABCDEF
 OPENQA_API_SECRET=1234567890ABCDEF
 OPENQA_SCHEME=https
+VARIANT=testing
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 68c1e20..0843fa3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -44,13 +44,15 @@ reuse:
       --workdir $CI_PROJECT_DIR
       --env CI
       --env CI_PROJECT_DIR
+      --env UPSTREAM_CI_PIPELINE_URL
       --env OPENQA_HOST_ADDR
       --env OPENQA_API_KEY
       --env OPENQA_API_SECRET
       --env IMAGE_URL
       --env STAGING_CHANNEL_URL
       --env SYSUPDATE_PUBKEY_B64
-      --env ISO_CHANNEL_URL
+      --env CHANNEL_URL
+      --env VARIANT
       registry.opensuse.org/devel/openqa/containers16.0/openqa_worker:latest
       ./setup.sh ./qa worker $WORKER_ARGS
 
diff --git a/lib/worker/download_image.py b/lib/worker/download_image.py
index 3da79d9..fd3eaa9 100755
--- a/lib/worker/download_image.py
+++ b/lib/worker/download_image.py
@@ -9,7 +9,6 @@ from dataclasses import dataclass
 import re
 from lib.common.log import get_logger
 
-_ISO_CHANNEL_URL = os.environ.get("ISO_CHANNEL_URL", "https://storage.kde.org/kde-linux/testing/")
 _ISO_PATTERN = re.compile(r"kde-linux_(\d{12})\.iso$")
 
 log = get_logger(__name__)
@@ -25,6 +24,14 @@ class Image:
     filename: str
 
 
+def channel_url() -> str:
+    variant = os.environ.get("VARIANT", "testing")
+    return os.environ.get(
+        "CHANNEL_URL",
+        f"https://storage.kde.org/kde-linux/{variant}/",
+    )
+
+
 def download_file(download_url: str, filename: str) -> None:
     log.info(f"Started downloading from: {download_url}")
     with requests.get(download_url, stream=True) as req:
@@ -37,7 +44,7 @@ def download_file(download_url: str, filename: str) -> None:
 
 def _available_images() -> list[Image]:
     checksums_url = parse.urljoin(
-        f"{_ISO_CHANNEL_URL.rstrip('/')}/",
+        f"{channel_url().rstrip('/')}/",
         "SHA256SUMS",
     )
     resp = requests.get(checksums_url)
@@ -58,7 +65,7 @@ def _available_images() -> list[Image]:
 
 
 def _download_image(filename: str) -> str:
-    download_file(parse.urljoin(_ISO_CHANNEL_URL, filename), filename)
+    download_file(parse.urljoin(channel_url(), filename), filename)
     return filename
 
 
@@ -91,7 +98,7 @@ def download_previous(build_version: str) -> str:
 
 def download_specific(build_version: str) -> None:
     filename = f"kde-linux_{build_version}.iso"
-    download_url = parse.urljoin(_ISO_CHANNEL_URL, filename)
+    download_url = parse.urljoin(channel_url(), filename)
     resp = requests.head(download_url)
     if resp.status_code != 200:
         raise DownloadError(f"Specified build not found: {build_version}")
diff --git a/lib/worker/job.py b/lib/worker/job.py
index 392d653..505647a 100644
--- a/lib/worker/job.py
+++ b/lib/worker/job.py
@@ -65,6 +65,7 @@ class JobConfig:
     hdd: Path
     sysext: Path
     build: str
+    variant: str | None
     name: str
     flavor: str
     casedir: Path
@@ -295,7 +296,6 @@ class Job:
 
         settings = {
             "DISTRI": "KDE-Linux",
-            "VERSION": config.build,
             "FLAVOR": config.flavor,
             "ARCH": "x86_64",
             "BUILD": config.build,
@@ -321,6 +321,11 @@ class Job:
             "NICTYPE_USER_OPTIONS": "hostfwd=tcp::2222-:22",
         }
 
+        if config.variant is not None:
+            settings["VERSION"] = f"{config.build}-{config.variant}"
+        else:
+            settings["VERSION"] = f"{config.build}"
+
         if config.live is not None:
             settings.update(
                 {
@@ -355,6 +360,11 @@ class Job:
             # to the only worker there is.
             settings["WORKER_CLASS"] = config.worker_class
 
+        if os.environ.get("CI"):
+            # Set the upstream pipeline URL in CI for reference in the test's settings tab
+            if os.environ.get("UPSTREAM_CI_PIPELINE_URL"):
+                settings["CI_PIPELINE_URL"] = os.environ["UPSTREAM_CI_PIPELINE_URL"]
+
         return settings
 
     def _stage_asset(self, path: Path) -> None:
diff --git a/lib/worker/job_flow.py b/lib/worker/job_flow.py
index 397c0cb..0856090 100644
--- a/lib/worker/job_flow.py
+++ b/lib/worker/job_flow.py
@@ -14,6 +14,7 @@ from lib.common.paths import git_root
 import lib.worker.job
 import lib.worker.sysext
 from lib.worker.download_image import (
+    channel_url,
     download_file,
     download_latest,
     download_previous,
@@ -33,7 +34,7 @@ class JobFlowError(Exception):
 class BuildUnderTest:
     image: Path | None
     output: str
-    version: str
+    build: str
 
 
 class JobFlow:
@@ -116,7 +117,7 @@ def _build_from_image(
     return BuildUnderTest(
         image=image,
         output=output,
-        version=output.rsplit("_", 1)[-1],
+        build=output.rsplit("_", 1)[-1],
     )
 
 
@@ -134,10 +135,10 @@ def _validate_upgrade_base(
     image: Path,
     target: BuildUnderTest,
 ) -> Path:
-    if _version_from_image(image) >= target.version:
+    if _version_from_image(image) >= target.build:
         raise JobFlowError(
             f"Upgrade base {image.name} is not older than target "
-            f"{target.version}"
+            f"{target.build}"
         )
 
     return image
@@ -145,8 +146,7 @@ def _validate_upgrade_base(
 
 def _latest_public_version() -> str:
     response = requests.get(
-        "https://storage.kde.org/"
-        "kde-linux/testing/sysupdate/v2/SHA256SUMS"
+        channel_url().rstrip("/") + "/sysupdate/v2/SHA256SUMS"
     )
     response.raise_for_status()
 
@@ -180,7 +180,7 @@ def _resolve_build_under_test(
         return BuildUnderTest(
             image=None,
             output=f"kde-linux_{version}",
-            version=version,
+            build=version,
         )
 
     image = _find_local_iso(casedir)
@@ -224,7 +224,7 @@ def _resolve_install_image(
 
     # The build under test is a published image, so use the newest local image
     # that is still older than the target when one is available.
-    local_image = _find_local_iso(casedir, older_than=build.version)
+    local_image = _find_local_iso(casedir, older_than=build.build)
     if local_image is not None:
         logger.info(
             "Using existing older image %s as the upgrade base",
@@ -234,7 +234,7 @@ def _resolve_install_image(
 
     logger.info("Downloading previous image for upgrade test")
     with chdir(casedir):
-        image = casedir / download_previous(build.version)
+        image = casedir / download_previous(build.build)
     return _validate_upgrade_base(image, build)
 
 
@@ -350,11 +350,12 @@ def run_jobs(
     flow.run_job(
         lib.worker.job.JobConfig(
             name="install-system",
+            variant=os.environ.get("VARIANT"),
             flavor=live_flavor,
             live=install_image,
             hdd=disk,
             sysext=sysext_image,
-            build=build.version,
+            build=build.build,
             casedir=casedir,
             encrypt=encrypt,
         )
@@ -364,10 +365,11 @@ def run_jobs(
         flow.run_job(
             lib.worker.job.JobConfig(
                 name="upgrade-system",
+                variant=os.environ.get("VARIANT"),
                 flavor=installed_flavor,
                 hdd=disk,
                 sysext=sysext_image,
-                build=build.version,
+                build=build.build,
                 casedir=casedir,
                 upgrade=True,
                 encrypt=encrypt,
@@ -377,10 +379,11 @@ def run_jobs(
     flow.run_job(
         lib.worker.job.JobConfig(
             name="sanity-test",
+            variant=os.environ.get("VARIANT"),
             flavor=installed_flavor,
             hdd=disk,
             sysext=sysext_image,
-            build=build.version,
+            build=build.build,
             casedir=casedir,
             encrypt=encrypt,
         )
diff --git a/mocks/single-instance.yml b/mocks/single-instance.yml
index 62ffaec..55862a9 100644
--- a/mocks/single-instance.yml
+++ b/mocks/single-instance.yml
@@ -19,6 +19,7 @@ services:
       - OPENQA_HOST_ADDR=localhost
       - OPENQA_SCHEME=http
       - MOCK_MODE=1
+      - VARIANT=testing
       - CASEDIR=/casedir
       - PYTHONPATH=/casedir
       - VIRTUAL_ENV=/var/lib/kde-linux-openqa/worker-venv
diff --git a/qa b/qa
index 83f168a..275ce12 100755
--- a/qa
+++ b/qa
@@ -28,6 +28,7 @@ def _parser() -> argparse.ArgumentParser:
     command_parser.add_argument("--hdd", type=Path, required=True)
     command_parser.add_argument("--sysext", type=Path, required=True)
     command_parser.add_argument("--build", required=True)
+    command_parser.add_argument("--variant", required=True)
     command_parser.add_argument("--name", required=True)
     command_parser.add_argument("--flavor", required=True)
     command_parser.add_argument("--group")
@@ -106,6 +107,7 @@ def main() -> None:
             hdd=args.hdd,
             sysext=args.sysext,
             build=args.build,
+            variant=args.variant,
             name=args.name,
             flavor=args.flavor,
             casedir=git_root(),
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.