diff options
Diffstat (limited to 'README')
| -rw-r--r-- | README | 115 |
1 files changed, 115 insertions, 0 deletions
@@ -0,0 +1,115 @@ +alpine-qemu-install +=================== +Unattended install of Alpine Linux onto a disk image, driven entirely over the +serial console. No keypresses, no graphics, no interaction. + + +What it does +------------ +Given an Alpine virt ISO and a disk image you created beforehand, the script: + + - extracts the kernel, initramfs, and modloop from the ISO + - builds an apkovl overlay containing the kernel modules and a first-boot + script + - boots that kernel under QEMU with the disk attached as /dev/vda + - runs setup-alpine non-interactively against a pre-baked answer file + - patches the installed root password, SSH key, and serial getty + - powers the guest off when finished + +The disk image is the target. It appears as /dev/vda inside the guest and is +erased. After install the layout is vda1=boot, vda2=swap, vda3=root. + + +Requirements +------------ +On the host: + + - 7z (7zip or p7zip-full; extracting the modloop squashfs needs it) + - GNU tar + - openssl + - qemu-system-x86_64 + +KVM is used automatically when /dev/kvm is writable, otherwise the install +runs under plain emulation (slower, but works). You also need an x86_64 +Alpine virt ISO and a disk image created up front with qemu-img. qcow2 is +recommended: it allocates sparsely and supports snapshots. Any other format +qemu-img writes also works, since QEMU detects it. + + +Usage +----- +Create a disk, then run the install: + + qemu-img create -f qcow2 disk.qcow2 2G + ROOT_PASSWORD=changeme \ + ./alpine-qemu-install alpine-virt-3.20.0-x86_64.iso disk.qcow2 + +The install log streams to your terminal. When it reaches the end the guest +powers off and the script exits. Boot the resulting image however you like, +for example: + + qemu-system-x86_64 -m 1024 -nographic -drive file=disk.qcow2,if=virtio + + +Configuration +------------- +Configuration is by environment variable. Only ROOT_PASSWORD is required. + + - ROOT_PASSWORD root password for the installed system (required) + - ROOT_PUBKEY an authorized_keys line; enables root SSH login + - SSHD openssh, dropbear, or none (default openssh) + - VM_HOSTNAME installed hostname (default alpine) + - APK_MIRROR apk mirror base URL + (default https://dl-cdn.alpinelinux.org/alpine) + - RAM_MB guest memory in MB during install (default 1024) + - SMP guest CPU count during install (default 2) + +The mirror must be reachable during install: setup-alpine fetches packages +before the disk is even partitioned. + + +How it works +------------ +QEMU's vvfat is unreliable for the ~150 MB modloop file, and a failed +modloop mount leaves the initramfs without /lib/modules, so setup-alpine +cannot modprobe, partition, or run post-install scripts. To avoid that path, +the script unpacks the modloop squashfs on the host and ships the modules +inside the apkovl overlay instead. Only one small file goes on the vvfat +drive: the apkovl tarball itself. + +The first-boot work runs from /etc/local.d/autoinstall.start via the default +runlevel's local service. It removes itself before setup-disk copies the +overlay onto the target, so the trigger never fires on the installed system. + + +Debugging +--------- +The install is fully visible. QEMU runs with -nographic, so everything the +first-boot script does is logged to ttyS0, which is your terminal. The script +runs under set -x, so each command is printed before it runs. + +QEMU runs with -no-reboot, so on success or failure the guest stays down and +the full log remains on screen. To leave QEMU manually, press Ctrl-a then x. + +The guest reports distinct success and failure values through qemu's +isa-debug-exit device. The script exits 0 only when the guest reported +completion, 3 when the first-boot script failed, and 1 when qemu stopped +without any result, including a manual Ctrl-a x. + +Common failures: + + - "need 7z" or "need qemu-system-x86_64": install the missing host tool. + - "modloop layout changed": install 7zip or p7zip-full, or the ISO changed + and the modloop extraction needs updating. + - "/dev/vda did not appear": the disk image was not attached or is missing. + - apk fetch errors: the mirror is unreachable or APK_MIRROR is wrong. + + +Security +-------- +ROOT_PASSWORD is hashed on the host; openssl reads it on stdin, so the +plaintext never reaches the guest, the apkovl, the set -x install log, or +a process listing. The hash is kept out of the log too, but any crypt hash +can be attacked offline, so pick a real password for images you keep. Root +SSH login is key-only: ROOT_PUBKEY installs the key, and Alpine's default +PermitRootLogin prohibit-password refuses password logins over SSH. |