fix: wire webinstaller to archinstall 4.x config schema
Walking-skeleton install on a real VM surfaced two archinstall 4.x schema breakages that the wizard hit only at runtime: - `use_entire_disk` was removed as a `config_type`. Now builds a full `default_layout` disk_config by calling `suggest_single_disk_layout` (forced ext4 + no separate /home, which bypasses its interactive prompts) and serializing the returned DeviceModification. - Credentials keys renamed to plaintext sentinels: `!root-password` and `!password`. Users with neither `!password` nor `enc_password` are silently dropped by `User.parse_arguments` — which is why the first real install booted but wouldn't log in. Also rolls in Robert's UX feedback quick-wins: `(Recommended)` prefix on the default boot entry across GRUB/syslinux/systemd-boot, and less-jargon hints on the step-1 hostname/username fields. iso/README loses three stale bullets that described pre-15b876c behaviour. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
15b876c70a
commit
51cdf460d9
4 changed files with 58 additions and 13 deletions
|
|
@ -49,8 +49,5 @@ mDNS (`proksi.local`) via avahi is installed but not yet wired. First milestone
|
|||
## Known rough edges
|
||||
|
||||
- **Disk space**: the first time you build on a fresh host, the squashfs/xorriso steps need ~15 GB free. If the host's LVM-root is smaller, `xorriso` silently dies at the very end with "Image size exceeds free space on media".
|
||||
- **Flask `/` route** returns "Hello World" instead of redirecting to `/install/step1`. Harmless but surprising; will be cleaned up when we wire up screens 4–8.
|
||||
- **No HTTPS yet**. The Furtka plan is "local CA + green padlock on `https://proksi.local`" — that's a later milestone. For now, plain HTTP.
|
||||
- **archinstall is not invoked**. The wizard collects input but doesn't write to disk yet. Still a walking skeleton, not an installer.
|
||||
- **Drive list includes `/dev/loop0` and `/dev/sr0`**. `/dev/loop0` is the live ISO's own squashfs mounted in RAM; `/dev/sr0` is the CD-ROM itself. Both appear as install targets, which is wrong. Filter lives in `webinstaller/drives.py` and hasn't been added yet.
|
||||
- **GRUB menu still says "Arch Linux install medium"**. We inherit releng's bootloader config. Cosmetic, fix when we care about end-user polish.
|
||||
|
|
|
|||
10
iso/build.sh
10
iso/build.sh
|
|
@ -55,6 +55,16 @@ find "$PROFILE_WORK/grub" "$PROFILE_WORK/syslinux" "$PROFILE_WORK/efiboot" \
|
|||
| xargs -0 sed -i \
|
||||
-e 's/Arch Linux install medium/Furtka Live Installer/g'
|
||||
|
||||
# Mark the default entry as (Recommended) so first-time users know which to
|
||||
# pick. Targets the main entry only — speech/accessibility variants stay
|
||||
# unlabeled to avoid suggesting they're the normal choice.
|
||||
sed -i 's/^title Furtka Live Installer (%ARCH%, UEFI)$/title (Recommended) Furtka Live Installer (%ARCH%, UEFI)/' \
|
||||
"$PROFILE_WORK/efiboot/loader/entries/01-archiso-linux.conf"
|
||||
sed -i 's/^MENU LABEL Furtka Live Installer (%ARCH%, BIOS)$/MENU LABEL (Recommended) Furtka Live Installer (%ARCH%, BIOS)/' \
|
||||
"$PROFILE_WORK/syslinux/archiso_sys-linux.cfg"
|
||||
sed -i "/--id 'archlinux'/s/menuentry \"Furtka Live Installer/menuentry \"(Recommended) Furtka Live Installer/" \
|
||||
"$PROFILE_WORK/grub/grub.cfg" "$PROFILE_WORK/grub/loopback.cfg"
|
||||
|
||||
mkdir -p "$PROFILE_WORK/airootfs/opt/furtka"
|
||||
cp -a "$REPO_ROOT/webinstaller/." "$PROFILE_WORK/airootfs/opt/furtka/"
|
||||
rm -rf "$PROFILE_WORK/airootfs/opt/furtka/__pycache__"
|
||||
|
|
|
|||
|
|
@ -57,24 +57,52 @@ def validate_step1(form):
|
|||
return errors, values
|
||||
|
||||
|
||||
def build_disk_config(boot_drive):
|
||||
# archinstall 4.x dropped the `use_entire_disk` shortcut — `default_layout`
|
||||
# now requires fully-specified partitions. We call suggest_single_disk_layout
|
||||
# with ext4 + no separate /home, which short-circuits its interactive prompts.
|
||||
import asyncio
|
||||
|
||||
from archinstall.lib.disk.device_handler import device_handler
|
||||
from archinstall.lib.disk.disk_menu import suggest_single_disk_layout
|
||||
from archinstall.lib.models.device import (
|
||||
DiskLayoutConfiguration,
|
||||
DiskLayoutType,
|
||||
FilesystemType,
|
||||
)
|
||||
|
||||
device_handler.load_devices()
|
||||
device = device_handler.get_device(Path(boot_drive))
|
||||
if device is None:
|
||||
raise RuntimeError(f"archinstall could not resolve device {boot_drive!r}")
|
||||
|
||||
device_mod = asyncio.run(
|
||||
suggest_single_disk_layout(
|
||||
device,
|
||||
filesystem_type=FilesystemType.Ext4,
|
||||
separate_home=False,
|
||||
)
|
||||
)
|
||||
layout = DiskLayoutConfiguration(
|
||||
config_type=DiskLayoutType.Default,
|
||||
device_modifications=[device_mod],
|
||||
)
|
||||
return layout.json()
|
||||
|
||||
|
||||
def build_archinstall_config(s):
|
||||
return {
|
||||
"archinstall-language": "English",
|
||||
"timezone": "Europe/Berlin",
|
||||
"ntp": True,
|
||||
"bootloader": "Systemd-boot",
|
||||
"disk_config": {
|
||||
"config_type": "use_entire_disk",
|
||||
"device": s["boot_drive"],
|
||||
"filesystem": "ext4",
|
||||
},
|
||||
"disk_config": build_disk_config(s["boot_drive"]),
|
||||
"hostname": s["hostname"],
|
||||
"kernels": ["linux"],
|
||||
"packages": ["docker", "docker-compose", "vim", "git", "htop", "curl"],
|
||||
"profile": {"type": "server"},
|
||||
"services": ["docker"],
|
||||
"network_config": {"type": "iso"},
|
||||
"users": [{"username": s["username"], "sudo": True, "groups": ["docker"]}],
|
||||
"ssh": True,
|
||||
"audio_config": None,
|
||||
"locale_config": {
|
||||
|
|
@ -85,9 +113,19 @@ def build_archinstall_config(s):
|
|||
|
||||
|
||||
def build_archinstall_creds(s):
|
||||
# archinstall 4.x expects `!root-password` and `!password` (plaintext
|
||||
# sentinels). Users with neither `!password` nor `enc_password` are
|
||||
# silently dropped by User.parse_arguments — hence login failures.
|
||||
return {
|
||||
"root_password": s["password"],
|
||||
"users": [{"username": s["username"], "password": s["password"]}],
|
||||
"!root-password": s["password"],
|
||||
"users": [
|
||||
{
|
||||
"username": s["username"],
|
||||
"!password": s["password"],
|
||||
"sudo": True,
|
||||
"groups": ["docker"],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@
|
|||
<div class="field">
|
||||
<label for="hostname">Hostname</label>
|
||||
<input type="text" id="hostname" name="hostname" required value="{{ values.hostname }}" autocomplete="off" />
|
||||
<span class="hint">Lowercase letters, digits, hyphens. Used on the local network.</span>
|
||||
<span class="hint">The name your server shows up as on your home network. Lowercase letters, numbers, and dashes only.</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="username">Admin username</label>
|
||||
<input type="text" id="username" name="username" required value="{{ values.username }}" autocomplete="username" />
|
||||
<span class="hint">Linux user account with sudo + docker access.</span>
|
||||
<span class="hint">Your login name on the server. You'll use this to sign in after installation.</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password">Password</label>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue