archinstall runs `systemctl enable` over the `services` list *before* custom_commands, so our own unit files (written in custom_commands) didn't exist yet at enable-time and install aborted with "Unit furtka-welcome.service does not exist". Keep `caddy` + `avahi-daemon` in `services` since those are packaged units present right after pacstrap; move `furtka-welcome` + `furtka-status.timer` to a `systemctl enable` call appended to custom_commands so they fire after the unit files land on disk. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
126 lines
4.2 KiB
Python
126 lines
4.2 KiB
Python
from app import (
|
|
build_archinstall_config,
|
|
build_archinstall_creds,
|
|
validate_step1,
|
|
)
|
|
|
|
|
|
def test_validate_step1_accepts_good_input():
|
|
errors, values = validate_step1(
|
|
{
|
|
"hostname": "furtka",
|
|
"username": "daniel",
|
|
"password": "topsecretpw",
|
|
"password2": "topsecretpw",
|
|
"language": "de",
|
|
}
|
|
)
|
|
assert errors == []
|
|
assert values == {
|
|
"hostname": "furtka",
|
|
"username": "daniel",
|
|
"password": "topsecretpw",
|
|
"language": "de",
|
|
}
|
|
|
|
|
|
def test_validate_step1_collects_all_errors():
|
|
errors, _ = validate_step1(
|
|
{
|
|
"hostname": "BAD!",
|
|
"username": "1bad",
|
|
"password": "short",
|
|
"password2": "mismatch",
|
|
"language": "xx",
|
|
}
|
|
)
|
|
assert len(errors) == 5
|
|
|
|
|
|
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",
|
|
"username": "u",
|
|
"password": "pw12345678",
|
|
"language": "pl",
|
|
"boot_drive": "/dev/sda",
|
|
}
|
|
)
|
|
assert cfg["disk_config"] == {"stubbed_device": "/dev/sda"}
|
|
assert cfg["hostname"] == "h"
|
|
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 cfg["custom_commands"][0] == "gpasswd -a u docker"
|
|
|
|
|
|
def test_build_archinstall_config_includes_post_install_bootstrap(monkeypatch):
|
|
# The installed system should come up with a Furtka landing page at
|
|
# http://<hostname>.local. That means caddy + avahi pacstrapped, the
|
|
# matching services enabled, a Caddyfile + index.html written into the
|
|
# target rootfs, and nss-mdns spliced into nsswitch.conf.
|
|
import app as app_module
|
|
|
|
monkeypatch.setattr(app_module, "build_disk_config", lambda d: {"stubbed_device": d})
|
|
|
|
cfg = build_archinstall_config(
|
|
{
|
|
"hostname": "heimserver",
|
|
"username": "u",
|
|
"password": "pw12345678",
|
|
"language": "en",
|
|
"boot_drive": "/dev/sda",
|
|
}
|
|
)
|
|
|
|
for pkg in ("caddy", "avahi", "nss-mdns"):
|
|
assert pkg in cfg["packages"]
|
|
# Packaged units go in `services` (enabled before custom_commands runs);
|
|
# our own units don't exist at that point, so they must be enabled from
|
|
# within custom_commands after the unit files land on disk.
|
|
for svc in ("caddy", "avahi-daemon"):
|
|
assert svc in cfg["services"]
|
|
assert "furtka-welcome" not in cfg["services"]
|
|
assert "furtka-status.timer" not in cfg["services"]
|
|
|
|
joined = "\n".join(cfg["custom_commands"])
|
|
assert "systemctl enable furtka-welcome.service furtka-status.timer" in joined
|
|
for path in (
|
|
"/etc/caddy/Caddyfile",
|
|
"/srv/furtka/www/index.html",
|
|
"/srv/furtka/www/style.css",
|
|
"/srv/furtka/www/status.json",
|
|
"/usr/local/bin/furtka-status",
|
|
"/usr/local/bin/furtka-welcome",
|
|
"/etc/systemd/system/furtka-status.service",
|
|
"/etc/systemd/system/furtka-status.timer",
|
|
"/etc/systemd/system/furtka-welcome.service",
|
|
):
|
|
assert path in joined, f"expected {path} to be written by custom_commands"
|
|
|
|
assert "mdns_minimal" in joined
|
|
assert "nsswitch.conf" in joined
|
|
# The chosen hostname is pinned into the static HTML at install-time.
|
|
assert "s/__HOSTNAME__/heimserver/g" in joined
|
|
|
|
|
|
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": [],
|
|
}
|
|
]
|