From a777efd4c09121f4d006f8b646e2b43c5cef132e Mon Sep 17 00:00:00 2001 From: Daniel Maksymilian Syrnicki Date: Tue, 14 Apr 2026 18:29:42 +0200 Subject: [PATCH] =?UTF-8?q?ci:=20green=20the=20pipeline=20=E2=80=94=20test?= =?UTF-8?q?s=20match=204.x=20schema,=20build-iso=20hits=20DinD,=20lint=20c?= =?UTF-8?q?lean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three things are broken on origin/main as of 6114cb2, all found in one red CI run: - build-iso workflow couldn't reach docker. forgejo-runner's config sets `docker_host: tcp://docker-in-docker:2375` but that env doesn't propagate into job containers on `runs-on: ubuntu-latest`, and the default job image has no docker CLI. Fix: pin `DOCKER_HOST` on the job and apt-install `docker.io` before invoking `iso/build.sh`. - Two tests asserted on the pre-4.x archinstall schema: `creds["root_password"]` (now `!root-password`) and `cfg["disk_config"]["device"]` / `cfg["users"]` (users moved to creds; disk_config is now a full `default_layout` dict). Rewrote the tests to reflect 4.x reality and monkeypatched `build_disk_config` since its real body imports archinstall, which isn't on CI. - Ruff flagged one line of `PROGRESS_PHASES` at 107 chars — collapsed the column alignment. `ruff format` pulled in a couple of cosmetic expansions in spawn_archinstall and the tests that had been drifting. Co-Authored-By: Claude Opus 4.6 (1M context) --- .forgejo/workflows/build-iso.yml | 11 +++++++++++ tests/test_app.py | 33 +++++++++++++++++++++++--------- tests/test_drives.py | 7 +------ webinstaller/app.py | 28 ++++++++++++++------------- 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/.forgejo/workflows/build-iso.yml b/.forgejo/workflows/build-iso.yml index eee19b8..fde92a1 100644 --- a/.forgejo/workflows/build-iso.yml +++ b/.forgejo/workflows/build-iso.yml @@ -16,9 +16,20 @@ jobs: build-iso: runs-on: ubuntu-latest timeout-minutes: 30 + env: + # forgejo-runner's DinD sidecar is reachable over TCP on the + # `forgejo-runner_default` docker network. The default runner image + # for `ubuntu-latest` doesn't propagate the runner's docker_host + # config into the job env, so we pin it explicitly here. + DOCKER_HOST: tcp://docker-in-docker:2375 steps: - uses: actions/checkout@v4 + - name: Install docker CLI + run: | + apt-get update -qq + apt-get install -y --no-install-recommends docker.io + - name: Build ISO run: ./iso/build.sh diff --git a/tests/test_app.py b/tests/test_app.py index e1cfa19..a80b68c 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -37,7 +37,13 @@ def test_validate_step1_collects_all_errors(): assert len(errors) == 5 -def test_build_archinstall_config_uses_selected_locale(): +def test_build_archinstall_config_uses_selected_locale(monkeypatch): + # build_disk_config imports archinstall lazily; archinstall isn't + # installed in CI (only runs on the live ISO), so stub it out. + import app as app_module + + monkeypatch.setattr(app_module, "build_disk_config", lambda d: {"stubbed_device": d}) + cfg = build_archinstall_config( { "hostname": "h", @@ -47,15 +53,24 @@ def test_build_archinstall_config_uses_selected_locale(): "boot_drive": "/dev/sda", } ) - assert cfg["disk_config"]["device"] == "/dev/sda" + assert cfg["disk_config"] == {"stubbed_device": "/dev/sda"} assert cfg["hostname"] == "h" - assert cfg["users"][0]["username"] == "u" assert cfg["locale_config"]["locale"] == "pl_PL.UTF-8" + # Users moved out of config into creds once we adopted archinstall 4.x's + # `!password` sentinel; config only carries a gpasswd in custom_commands + # so the user lands in the docker group after docker is pacstrapped. + assert "users" not in cfg + assert any("gpasswd -a u docker" in c for c in cfg["custom_commands"]) -def test_build_archinstall_creds_reuses_password_for_root_and_user(): - creds = build_archinstall_creds( - {"username": "u", "password": "pw12345678"} - ) - assert creds["root_password"] == "pw12345678" - assert creds["users"] == [{"username": "u", "password": "pw12345678"}] +def test_build_archinstall_creds_uses_archinstall_sentinel_keys(): + creds = build_archinstall_creds({"username": "u", "password": "pw12345678"}) + assert creds["!root-password"] == "pw12345678" + assert creds["users"] == [ + { + "username": "u", + "!password": "pw12345678", + "sudo": True, + "groups": [], + } + ] diff --git a/tests/test_drives.py b/tests/test_drives.py index 6882284..1d13157 100644 --- a/tests/test_drives.py +++ b/tests/test_drives.py @@ -62,12 +62,7 @@ def test_parse_lsblk_drops_loop_and_rom(monkeypatch): import drives monkeypatch.setattr(drives, "get_drive_health", lambda _: 10) - output = ( - "loop0 2.5G loop\n" - "sr0 1024M rom\n" - "sda 500G disk\n" - "nvme0n1 1T disk\n" - ) + output = "loop0 2.5G loop\nsr0 1024M rom\nsda 500G disk\nnvme0n1 1T disk\n" devices = parse_lsblk_output(output) names = [d["name"] for d in devices] assert names == ["/dev/nvme0n1", "/dev/sda"] diff --git a/webinstaller/app.py b/webinstaller/app.py index 69bf035..e0248d9 100644 --- a/webinstaller/app.py +++ b/webinstaller/app.py @@ -39,17 +39,17 @@ USERNAME_RE = re.compile(r"^[a-z_][a-z0-9_-]{0,31}$") # present in the log. If archinstall changes its stdout wording the bar # stalls on the last recognized phase — the install itself keeps going. PROGRESS_PHASES = [ - ("Wiping partitions", 8, "Preparing your disk"), - ("Creating partitions", 12, "Creating partitions"), - ("Starting installation", 15, "Starting installation"), - ("Waiting for", 18, "Syncing time and packages"), - ("Installing packages: ['base'", 25, "Installing the base system (this takes a while)"), - ("Adding bootloader", 65, "Setting up boot"), - ("Installing packages: ['efibootmgr'", 70, "Setting up boot"), - ("Installing packages: ['docker'", 80, "Installing your apps"), - ("Enabling service", 90, "Turning on services"), - ("Updating /mnt/etc/fstab", 95, "Almost done"), - ("Installation completed without any errors", 100, "Done!"), + ("Wiping partitions", 8, "Preparing your disk"), + ("Creating partitions", 12, "Creating partitions"), + ("Starting installation", 15, "Starting installation"), + ("Waiting for", 18, "Syncing time and packages"), + ("Installing packages: ['base'", 25, "Installing the base system (this takes a while)"), + ("Adding bootloader", 65, "Setting up boot"), + ("Installing packages: ['efibootmgr'", 70, "Setting up boot"), + ("Installing packages: ['docker'", 80, "Installing your apps"), + ("Enabling service", 90, "Turning on services"), + ("Updating /mnt/etc/fstab", 95, "Almost done"), + ("Installation completed without any errors", 100, "Done!"), ] PROGRESS_ERROR_MARKERS = ("Traceback (most recent call last)", "archinstall: error:") @@ -189,8 +189,10 @@ def spawn_archinstall(config_path, creds_path, log_path): return subprocess.Popen( [ "archinstall", - "--config", str(config_path), - "--creds", str(creds_path), + "--config", + str(config_path), + "--creds", + str(creds_path), "--silent", ], stdout=log_fh,