diff options
-rw-r--r-- | _drafts/first-release-of-installiso.md | 218 |
1 files changed, 156 insertions, 62 deletions
diff --git a/_drafts/first-release-of-installiso.md b/_drafts/first-release-of-installiso.md index bbaac53..7c6537d 100644 --- a/_drafts/first-release-of-installiso.md +++ b/_drafts/first-release-of-installiso.md @@ -1,11 +1,16 @@ --- title: "First release of installiso" description: "A utility to customize OpenBSD installation images for unattended installation." -published: 2021-07-23 +published: 2021-07-24 --- -One year ago I [posted](/posts/autoinstall-openbsd-on-qemu/) how to script an unattended installation of OpenBSD on the QEMU virtual machine monitor. -The script involved ... TODO; essentially because I treated the installation image as a black box. +<!-- TODO: Test all commands --> +<!-- TODO: Reset git history, tag release, build tarball, and man page --> +<!-- TODO: Test all links --> +<!-- TODO: Update date --> + +One year ago I [posted](/posts/autoinstall-openbsd-on-qemu/) how to script an unattended installation of OpenBSD on the QEMU virtual machine monitor on Linux. +The script involved setting up a complicated network boot environment because I treated the installation image as a black box. Of course, I could have mounted the ISO 9660 image and created a modified image using [`mkisofs(8)`](http://cdrtools.sourceforge.net/private/man/cdrecord/mkisofs.8.html). But I didn't know how to insert the [`autoinstall(8)`](https://man.openbsd.org/OpenBSD-6.9/autoinstall) response file into the RAMDISK kernel in the ISO 9660 image. That was no surprise -- why would anyone need to change an OpenBSD kernel on Linux. @@ -14,83 +19,172 @@ OpenBSD, on the other hand, includes adequate utilities. Thanks to [`vmctl(8)`](https://man.openbsd.org/OpenBSD-6.9/vmctl), [`rdsetroot(8)`](https://man.openbsd.org/OpenBSD-6.9/rdsetroot), and [`mkhybrid(8)`](https://man.openbsd.org/OpenBSD-6.9/mkhybrid), we can modify the ISO 9660 image _and_ the contained RAMDISK kernel. The exact process is a bit tedious so I decided to automate it. The resulting script is more hacky than pretty but it gets the job done and I found it useful enough to give it a name, `installiso`, and release it today. +Currently, it's limited to the _amd64_ architecture, though it should work on other architectures alike. You can download the very first release [here](/files/installiso-0.1.0.tar.gz). +The man page is also viewable [here](/files/installiso.8-0.1.0.html). Feedback appreciated! -<!-- TODO: Add release tarball --> -<!-- TODO: Link or embed HTML man page? --> -In the remainder of this post I'll show how I use `installiso` to create custom OpenBSD installation images for unattended -- and possibly offline -- installation. +In the remainder of this post I'll show how to use `installiso` to create custom OpenBSD installation images for unattended -- and possibly offline -- installation. As an example, I'll show how to create virtual machines on OpenBSD's own virtual machine monitor, [`vmm(4)`](https://man.openbsd.org/OpenBSD-6.9/vmm). +Finally, I'll list the concrete commands necessary to patch an installation image without `installiso` because I would want to know how it works. -For starters, we create an [`autoinstall(8)`](https://man.openbsd.org/OpenBSD-6.9/autoinstall) response file. -Of course, you can skip this step and have the installer mail you the responses recorded during an interactive installation instead. +## Installation + +You can install the `installiso` utility as follows. + + $ ftp https://www.skreutz.com/files/installiso-0.1.0.tar.gz + $ tar -xzf installiso-0.1.0.tar.gz + $ cd installiso-0.1.0/ + $ doas make install + $ man 8 installiso + +Alternatively, you can run `./installiso.ksh` without installation. +## Usage -``` -$ cat >install.conf <<EOF -Change the default console to com0 = yes -Which speed should com0 use = 115200 -System hostname = openbsd-vm -DNS domain name = example.com -Password for root = ************* -Start sshd(8) by default = yes -Allow root ssh login = no -Setup a user = $USER -Full name for user stefan = $( userinfo "$USER" | sed -n 's/^gecos[[:space:]]*\(.*\)$/\1/p' ) -Password for user = ************* -Public ssh key for user = $( cat "$HOME/.ssh/id_rsa.pub" ) -What timezone are you in = UTC -Location of sets = cd0 -Set name(s) = site*.tgz -Directory does not contain SHA256.sig. Continue without verification = yes -EOF -``` - -Next, we create a site-specific file set. - -``` -$ mkdir -p site -$ cat >site/install.site <<EOF -#! /bin/ksh - -set -o errexit - -# Permit user group wheel to run any command as root -# without entering their password using doas(1). -echo "permit nopass keepenv :wheel" > /etc/doas.conf - -# Install packages. -#echo "pkg_add sqlite3" >> /etc/rc.firsttime - -# Patch the base system. -#echo "syspatch && shutdown -r now" >> /etc/rc.firsttime -EOF -``` - -Now we're ready to create the custom installation image using `installiso`. -First, we download and verify the latest development snapshot. -You can also specify the mirror, a specific release, and the [`signify(1)`](https://man.openbsd.org/OpenBSD-6.9/signify) public key if you like. -Then, we insert the prepared response file and file set into the image[^tmpdir]. - - $ installiso -v fetch -o snapshot.iso +Given a response file `install.conf`, and a file-specific file set `site/`, you can download, verify, and customize an official installation image as follows. + + $ installiso -v fetch -r 6.9 $ doas installiso -v \ - patch -i install.conf -s site snapshot.iso custom.iso + patch -i install.conf -s site/ install69.iso custom.iso -Finally, we start a virtual machine off a new disk image and the custom installation image. +You can also specify a mirror, another release or the latest development snapshot, and a [`signify(1)`](https://man.openbsd.org/OpenBSD-6.9/signify) public key if you like. +See the [man page](/files/installiso.8-0.1.0.html). - $ vmctl create -s 10G disk.qcow2 - $ doas vmctl start -c -d disk.qcow2 -m 512M \ - -i 1 -L -r custom.iso tmp +## Example + +You can create a virtual machine on OpenBSD's own virtual machine monitor, [`vmm(4)`](https://man.openbsd.org/OpenBSD-6.9/vmm), as follows. + +First, we create an [`autoinstall(8)`](https://man.openbsd.org/OpenBSD-6.9/autoinstall) response file. +Here, we'll setup a regular user and authorize an [`ssh(1)`](https://man.openbsd.org/OpenBSD-6.9/ssh) public key. +Of course, you can skip this step and have the installer mail you the responses recorded during an interactive installation instead. + + $ cat >install.conf <<EOF + Change the default console to com0 = yes + Which speed should com0 use = 115200 + System hostname = openbsd-vm + DNS domain name = example.com + Password for root = ************* + Start sshd(8) by default = yes + Allow root ssh login = no + Setup a user = $USER + Full name for user $USER = $( userinfo "$USER" | sed -n 's/^gecos[[:space:]]*\(.*\)$/\1/p' ) + Password for user = ************* + Public ssh key for user = $( cat "$HOME/.ssh/id_rsa.pub" ) + What timezone are you in = UTC + Location of sets = cd0 + Set name(s) = site*.tgz + Directory does not contain SHA256.sig. Continue without verification = yes + EOF + +Second, we create a site-specific file set. + + $ mkdir site + $ cat >site/install.site <<EOF + #! /bin/ksh + + set -o errexit + + # Set OpenBSD mirror server used by pkg_add(1) and other commands. + echo "https://cdn.openbsd.org/pub/OpenBSD" > /etc/installurl + + # Permit user group wheel to run any command as root + # without entering their password using doas(1). + echo "permit nopass keepenv :wheel" > /etc/doas.conf + + # Install packages on the first boot. + echo "pkg_add sqlite3" >> /etc/rc.firsttime + EOF + +Third, fetch and patch an installation image as above. + + $ installiso -v fetch -r 6.9 + $ doas installiso -v \ + patch -i install.conf -s site/ install69.iso custom.iso -<!-- TODO: Note vmctl (network) preconditions --> +Forth, we start a virtual machine off a new disk image and the custom installation image. +The OpenBSD FAQ contains a good [introduction](https://www.openbsd.org/faq/faq16.html) to [`vmm(4)`](https://man.openbsd.org/OpenBSD-6.9/vmm). +I assume you've setup the network option 2. + + $ vmctl create -s 10G disk.qcow2 + $ doas vmctl start -c -i 1 -L -m 512M -d disk.qcow2 \ + -r custom.iso tmp -Once the unattended installation completed, we can log in: +Finally, we can log into the new virtual machine once the unattended installation has completed. $ ssh \ -o "StrictHostKeyChecking no" \ -o "UserKnownHostsFile /dev/null" \ 100.64.1.3 +## Disklabel template + +In the above example, the OpenBSD installer allocates all disk space automatically, see [`disklabel(8)`](https://man.openbsd.org/OpenBSD-6.9/disklabel). +You can supply a custom disklabel template instead if you need more control. + +First, create a disklabel template. + + $ cat >disklabel_template <<EOF + / 5G + swap 1G + /home 2G + EOF + +Second, add a corresponding URL to the response file. + + $ echo "URL to autopartitioning template for disklabel = http://100.64.1.2:8080/disklabel_template" >> install.conf + +Finally, serve the file during the unattended installation. + + $ printf 'HTTP/1.0 200 OK\n\n' | + cat - disklabel | + nc -lN 8080 + +## Inner workings + +The `installiso patch` command used above + + $ doas installiso -v \ + patch -i install.conf -s site/ install69.iso custom.iso + +boils down to the following commands, excluding error handling, temporary files, options, etc. + +First, we extract the ISO 9660 image. + + # vnconfig vnd0 install69.iso + # mount -t cd9660 /dev/vnd0c /mnt + # mkdir cd + # tar -C /mnt -c -f - . | tar -C cd -x -p -f - + # umount /mnt + # vnconfig -u vnd0 + +Second, we patch the RAMDISK kernel. + + # gzip -d -o bsd.rd cd/6.9/amd64/bsd.rd + # rdsetroot -x bsd.rd disk.fs + # vnconfig vnd0 disk.fs + # mount /dev/vnd0a" /mnt + # install -o root -g wheel -m 0644 -C \ + install.conf /mnt/auto_install.conf + # umount /mnt + # vnconfig -u vnd0 + # rdsetroot bsd.rd disk.fs + # gzip -9fnq bsd.rd + +Third, we insert the patched kernel and the site-specific file set into the extracted ISO 9660 image. + + # install -o root -g 2000 -m 0755 -C \ + bsd.rd.gz cd/6.9/amd64/bsd.rd + # ( cd site/ && tar -c -z -f ../cd/6.9/amd64/site69.tgz . ) + # ( cd cd/6.9/amd64/ && ls -l > index.txt ) + +Finally, we create the bootable ISO 9660 image. + + # mkhybrid -a -R -T -L -l -d -D -N -o custom.iso \ + -A "Custom OpenBSD 6.9 amd64 Install CD" \ + -b 6.9/amd64/cdbr -c 6.9/amd64/boot.catalog \ + cd + [^tmpdir]: The `installiso` utility may fail due to not enough space in `/tmp`. If so, you can set the `TMPDIR` environment variable of [`mktemp(1)`](https://man.openbsd.org/OpenBSD-6.9/mktemp). |