summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kreutz <mail@skreutz.com>2020-05-31 18:11:30 +0200
committerStefan Kreutz <mail@skreutz.com>2020-05-31 18:11:30 +0200
commitfc15f9e66f790137e0c2e9c1ab1c759d10d12d44 (patch)
tree2acefd1cb23a51b6403eb92a5923ab15f238a777
parent0a0e111167f544b5ac660bc7629be9bb9b34b91f (diff)
downloadautoinstall-openbsd-on-qemu-fc15f9e66f790137e0c2e9c1ab1c759d10d12d44.tar
Review
-rw-r--r--.gitignore6
-rw-r--r--README.md89
-rw-r--r--boot.conf3
-rw-r--r--disklabel11
-rw-r--r--install.conf15
-rwxr-xr-xinstall.site5
-rwxr-xr-xrun235
7 files changed, 217 insertions, 147 deletions
diff --git a/.gitignore b/.gitignore
index c5110f7..872a24b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
-.openbsd-vm
-openbsd-vm.qcow2
+mirror
+tftp
+site
+disk.qcow2
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d4b40bc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,89 @@
+# Auto-install OpenBSD on QEMU
+
+This repository hosts a POSIX shell script to auto-install OpenBSD/amd64 6.6 to
+copy-on-write disk image using QEMU. The script is intended to run on Linux. If
+you already have a running OpenBSD installation, you should consider to use
+OpenBSD's own hypervisor [vmm(4)](https://man.openbsd.org/vmm) instead of QEMU
+as described in the [OpenBSD FAQ](https://www.openbsd.org/faq/faq16.html) and
+in this [blog post](https://eradman.com/posts/autoinstall-openbsd.html).
+
+The script will:
+
+* Download and verify the official installation image and file sets.
+* Create and serve a TFTP boot environment.
+* Create an [autoinstall(8)](https://man.openbsd.org/autoinstall) configuration file including your public ssh key.
+* Create and boot a copy-on-write disk image.
+
+## Prerequisites
+
+The script depends on the following tools:
+
+* [QEMU](https://www.qemu.org/)
+* [curl](https://curl.haxx.se/)
+* Portable [signify](https://github.com/aperezdc/signify)
+* [rsync](https://rsync.samba.org/)
+* Portable [OpenSSH](https://www.openssh.com/portable.html)
+* [socat](http://www.dest-unreach.org/socat/)
+
+The following command installs these dependencies on Arch Linux:
+
+ sudo pacman -S qemu curl signify rsync openssh socat
+
+## Usage
+
+Execute the following command to auto-install OpenBSD/amd64 6.6 to a new disk
+image `disk.qcow2` in the current directory.
+
+ ./run
+
+When prompted, run the following command to serve `./mirror/` at
+http://127.0.0.1:8080/:
+
+ python -m http.server --directory ./mirror --bind 127.0.0.1 8080
+
+You can override the following environment variable defaults if necessary:
+
+* `DISK_FILE=disk.qcow2`
+* `DISK_SIZE=160G`
+* `CPU_COUNT=6`
+* `MEMORY_SIZE=4G`
+
+For example:
+
+ CPU_COUNT=1 ./run
+
+## Virtual network
+
+The script creates a virtual network, `10.0.2.0/24`, with the following
+addresses:
+
+* Host at `10.0.2.2`
+* Nameserver at `10.0.2.3`
+* Guest at `10.0.2.15`
+
+The script also redirects host host port `2222` to guest port `22` (ssh) and
+host port `80` (actually `10.0.2.1` port `80`) to host port `8080`.
+
+## Secure shell
+
+Pass the following options to ssh or scp to connect to the guest machine:
+
+ ssh \
+ -o "StrictHostKeyChecking no" \
+ -o "UserKnownHostsFile /dev/null" \
+ -o "Port 2222" \
+ puffy@127.0.0.1
+
+For example, the following command forwards port `3000` on the host to port
+`80` on the guest:
+
+ ssh \
+ -o "StrictHostKeyChecking no" \
+ -o "UserKnownHostsFile /dev/null" \
+ -o "Port 2222" \
+ -N \
+ -L 127.0.0.1:3000:127.0.0.1:80 \
+ puffy@127.0.0.1
+
+Press `C-a x` to stop the guest machine.
+Press `C-a h` to show other options.
diff --git a/boot.conf b/boot.conf
deleted file mode 100644
index b7daacc..0000000
--- a/boot.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-stty com0 115200
-set tty com0
-boot tftp:/bsd.rd
diff --git a/disklabel b/disklabel
deleted file mode 100644
index eb4c5ea..0000000
--- a/disklabel
+++ /dev/null
@@ -1,11 +0,0 @@
-/ 2G
-swap 8G
-/tmp 1G
-/var 1G
-/var/www 100G
-/usr 2G
-/usr/X11R6 500M
-/usr/local 4G
-/usr/src 1M
-/usr/obj 1M
-/home 4G
diff --git a/install.conf b/install.conf
deleted file mode 100644
index a417f93..0000000
--- a/install.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-Change the default console to com0 = yes
-Which speed should com0 use = 115200
-System hostname = openbsd-vm
-Password for root = *************
-Allow root ssh login = no
-Setup a user = puffy
-Password for user = *************
-What timezone are you in = UTC
-Location of sets = http
-HTTP Server = 10.0.2.1
-Unable to connect using https. Use http instead = yes
-URL to autopartitioning template for disklabel = http://10.0.2.1/disklabel
-Set name(s) = site66.tgz
-Checksum test for site66.tgz failed. Continue anyway = yes
-Unverified sets: site66.tgz. Continue without verification = yes
diff --git a/install.site b/install.site
deleted file mode 100755
index 512974f..0000000
--- a/install.site
+++ /dev/null
@@ -1,5 +0,0 @@
-#! /bin/ksh
-set -o errexit
-echo "https://cdn.openbsd.org/pub/OpenBSD" > /etc/installurl
-echo "permit nopass keepenv :wheel" > /etc/doas.conf
-#echo "syspatch && shutdown -r now" >> /etc/rc.firsttime
diff --git a/run b/run
index 55ea44f..a4400af 100755
--- a/run
+++ b/run
@@ -1,46 +1,6 @@
#! /bin/sh
-# Auto-install OpenBSD/amd64 6.6 to a QEMU guest machine.
-#
-# Run the following command to serve the OpenBSD mirror at
-# http://127.0.0.1:8080:
-#
-# python3 -m http.server \
-# --directory ./openbsd-vm/mirror \
-# --bind 127.0.0.1 8080
-#
-# Pass the following options to ssh or scp to connect to the guest machine:
-#
-# ssh \
-# -o "StrictHostKeyChecking no" \
-# -o "UserKnownHostsFile /dev/null" \
-# -o "Port 2222" \
-# puffy@127.0.0.1
-#
-# For example, the following command forwards port 8080 on the host to port 80
-# on the guest:
-#
-# ssh \
-# -o "StrictHostKeyChecking no" \
-# -o "UserKnownHostsFile /dev/null" \
-# -o "Port 2222" \
-# -N \
-# -L 127.0.0.1:8080:127.0.0.1:80 \
-# puffy@127.0.0.1
-#
-# Press C-a x to stop the guest machine. Press C-a h to show other options.
-#
-# The virtual network:
-#
-# network = 10.0.2.0/24
-# host = 10.0.2.2
-# nameserver = 10.0.2.3
-# guest = 10.0.2.15-31
-#
-# Port forwardings:
-#
-# 10.0.2.1:80 -> host:8080
-# host:2222 -> guest:22
+# Auto-install OpenBSD/amd64 6.6 to a copy-on-write disk image using QEMU.
#
# Copyright (c) 2020 Stefan Kreutz <mail@skreutz.com>
@@ -48,97 +8,150 @@ set -o errexit
set -o nounset
set -o xtrace
-# Set parameters.
-VM_FILE="${VM_FILE-openbsd-vm.qcow2}"
+# Set default parameters.
+DISK_FILE="${DISK_FILE-disk.qcow2}"
DISK_SIZE="${DISK_SIZE-160G}"
CPU_COUNT="${CPU_COUNT-6}"
MEMORY_SIZE="${MEMORY_SIZE-4G}"
-# Remove existing virtual machine if configuration changed.
-if [ -e "${VM_FILE}" ] ;
+# Check dependencies.
+for cmd in qemu-img qemu-system-x86_64 curl signify rsync ssh socat ;
+do
+ command -v "${cmd}"
+done
+
+# Download and verify official installation image and file sets.
+mkdir -p mirror/pub/OpenBSD/6.6
+if [ ! -e mirror/pub/OpenBSD/6.6/openbsd-66-base.pub ] ;
then
- vm_created="$( stat -c %W "${VM_FILE}" )"
- for f in boot.conf disklabel install.conf install.site
- do
- if [ "${vm_created}" -lt "$( stat -c %Y "$f" )" ] ;
- then
- ( >&2 printf "%s changed. Recreating virtual machine." "$f" )
- rm "${VM_FILE}"
- fi
- done
+ curl \
+ --output mirror/pub/OpenBSD/6.6/openbsd-66-base.pub \
+ --silent \
+ https://ftp.openbsd.org/pub/OpenBSD/6.6/openbsd-66-base.pub
+fi
+if [ ! -d mirror/pub/OpenBSD/6.6/amd64 ] ;
+then
+ mkdir -p tmp
+ rsync --recursive --delete --quiet \
+ rsync://ftp.halifax.rwth-aachen.de/openbsd/6.6/amd64/ \
+ tmp/
+ ( cd tmp && \
+ signify -C -q -p ../mirror/pub/OpenBSD/6.6/openbsd-66-base.pub -x SHA256.sig )
+ mv tmp mirror/pub/OpenBSD/6.6/amd64
fi
-if [ ! -e "${VM_FILE}" ] ;
+# Create autoinstall configuration if not exists.
+if [ ! -e mirror/install.conf ] ;
then
+ ssh_pub_key="$( cat ~/.ssh/id_rsa.pub )"
+ cat << EOF > mirror/install.conf
+Change the default console to com0 = yes
+Which speed should com0 use = 115200
+System hostname = openbsd
+Password for root = *************
+Allow root ssh login = no
+Setup a user = puffy
+Password for user = *************
+Public ssh key for user = ${ssh_pub_key}
+What timezone are you in = UTC
+Location of sets = http
+HTTP Server = 10.0.2.1
+Unable to connect using https. Use http instead = yes
+URL to autopartitioning template for disklabel = http://10.0.2.1/disklabel
+Set name(s) = site66.tgz
+Checksum test for site66.tgz failed. Continue anyway = yes
+Unverified sets: site66.tgz. Continue without verification = yes
+EOF
+fi
- # Download and verify OpenBSD/amd64 6.6 installation images and file sets.
- mkdir -p .openbsd-vm/mirror/pub/OpenBSD/6.6
- if [ ! -e .openbsd-vm/mirror/pub/OpenBSD/6.6/openbsd-66-base.pub ] ;
- then
- curl \
- --output .openbsd-vm/mirror/pub/OpenBSD/6.6/openbsd-66-base.pub \
- --silent \
- https://ftp.openbsd.org/pub/OpenBSD/6.6/openbsd-66-base.pub
- fi
- if [ ! -d .openbsd-vm/mirror/pub/OpenBSD/6.6/amd64 ] ;
- then
- mkdir -p .openbsd-vm/tmp
- rsync --recursive --delete --quiet \
- rsync://ftp.halifax.rwth-aachen.de/openbsd/6.6/amd64/ \
- .openbsd-vm/tmp/
- ( cd .openbsd-vm/tmp && \
- signify -C -q -p ../mirror/pub/OpenBSD/6.6/openbsd-66-base.pub -x SHA256.sig )
- mv .openbsd-vm/tmp .openbsd-vm/mirror/pub/OpenBSD/6.6/amd64
- fi
+# Create disklabel configuration if not exists.
+if [ ! -e mirror/disklabel ] ;
+then
+ cat << EOF > mirror/disklabel
+/ 2G
+swap 8G
+/tmp 1G
+/var 1G
+/var/www 100G
+/usr 2G
+/usr/X11R6 500M
+/usr/local 4G
+/usr/src 1M
+/usr/obj 1M
+/home 4G
+EOF
+fi
- # Create site-specific file set.
- if [ ! -x install.site ] ;
- then
- chmod +x install.site
- fi
- rm -f .openbsd-vm/mirror/pub/OpenBSD/6.6/amd64/site66.tgz
- tar -czf .openbsd-vm/mirror/pub/OpenBSD/6.6/amd64/site66.tgz install.site
- ( cd .openbsd-vm/mirror/pub/OpenBSD/6.6/amd64 && ls -l > index.txt )
+# Create site-specific file set if not exists.
+if [ ! -d site ] ;
+then
+ mkdir site
+ cat << EOF > site/install.site
+#! /bin/ksh
+set -o errexit
+echo "https://cdn.openbsd.org/pub/OpenBSD" > /etc/installurl
+echo "permit nopass keepenv :wheel" > /etc/doas.conf
+#echo "syspatch && shutdown -r now" >> /etc/rc.firsttime
+EOF
+ chmod +x site/install.site
+fi
- # Add public ssh key to install.conf.
- cp install.conf .openbsd-vm/mirror/
- if ! grep -q -e "^Public ssh key for user" install.conf ;
- then
- ssh_pub_key="$( cat ~/.ssh/id_rsa.pub )"
- echo "Public ssh key for user = ${ssh_pub_key}" \
- >> .openbsd-vm/mirror/install.conf
- fi
+# Package site-specific file set if not exists or changed.
+site_dir_changed="$( find site -exec stat -c %Y {} \; | sort -r | head -n 1 )"
+if [ ! -e mirror/pub/OpenBSD/6.6/amd64/site66.tgz ] || [ "$( stat -c %Y mirror/pub/OpenBSD/6.6/amd64/site66.tgz )" -lt "${site_dir_changed}" ] ;
+then
+ rm -f mirror/pub/OpenBSD/6.6/amd64/site66.tgz
+ ( cd site && tar -czf ../mirror/pub/OpenBSD/6.6/amd64/site66.tgz . )
+ ( cd mirror/pub/OpenBSD/6.6/amd64 && ls -l > index.txt )
+fi
- # Copy disklabel template.
- cp disklabel .openbsd-vm/mirror/
+# Create TFTP directory if not exists.
+if [ ! -d tftp ] ;
+then
+ mkdir tftp
+ ln -s ../mirror/pub/OpenBSD/6.6/amd64/pxeboot tftp/auto_install
+ ln -s ../mirror/pub/OpenBSD/6.6/amd64/bsd.rd tftp/bsd.rd
+ mkdir tftp/etc
+ cat << EOF > tftp/etc/boot.conf
+stty com0 115200
+set tty com0
+boot tftp:/bsd.rd
+EOF
+fi
- # Wait until the HTTP server is online.
- #
- while [ ! "$( curl --silent --location --write-out '%{http_code}\n' --output /dev/null http://127.0.0.1:8080/install.conf )" = 200 ] ;
+# Remove existing disk image if configuration changed.
+if [ -e "${DISK_FILE}" ] ;
+then
+ vm_created="$( stat -c %W "${DISK_FILE}" )"
+ for f in mirror/install.conf mirror/disklabel mirror/pub/OpenBSD/6.6/amd64/site66.tgz tftp/etc/boot.conf
do
- ( >&2 printf "Please serve the directory ./openbsd-vm/mirror at http://127.0.0.1:8080.\n" )
- sleep 5
+ if [ "${vm_created}" -lt "$( stat -c %Y "$f" )" ] ;
+ then
+ ( >&2 printf "%s changed. Recreating virtual machine." "$f" )
+ rm "${DISK_FILE}"
+ fi
done
+fi
- # Collect files to be served over TFTP.
- rm -rf .openbsd-vm/tftp
- mkdir .openbsd-vm/tftp
- ln -s ../mirror/pub/OpenBSD/6.6/amd64/pxeboot .openbsd-vm/tftp/auto_install
- ln -s ../mirror/pub/OpenBSD/6.6/amd64/bsd.rd .openbsd-vm/tftp/bsd.rd
- mkdir .openbsd-vm/tftp/etc
- cp boot.conf .openbsd-vm/tftp/etc/
-
- # Create copy-on-write disk image.
- qemu-img create -f qcow2 "${VM_FILE}" "${DISK_SIZE}"
-
+# Create disk image if not exists.
+if [ ! -e "${DISK_FILE}" ] ;
+then
+ qemu-img create -f qcow2 "${DISK_FILE}" "${DISK_SIZE}"
fi
-# Auto-install guest machine.
+# Wait until ./mirror is served at http://127.0.0.1:8080/.
+while [ ! "$( curl --silent --location --write-out '%{http_code}\n' --output /dev/null http://127.0.0.1:8080/install.conf )" = 200 ] ;
+do
+ ( >&2 printf "Please serve the directory ./mirror/ at http://127.0.0.1:8080/.\n" )
+ sleep 5
+done
+
+# Auto-install OpenBSD.
qemu-system-x86_64 \
-enable-kvm \
-m "${MEMORY_SIZE}" \
-smp "cpus=${CPU_COUNT}" \
-device e1000,netdev=n1 \
- -netdev "user,id=n1,hostname=openbsd-vm,tftp-server-name=10.0.2.1,tftp=.openbsd-vm/tftp,bootfile=auto_install,hostfwd=tcp::2222-:22,guestfwd=tcp:10.0.2.1:80-cmd:socat - tcp:127.0.0.1:8080" \
- -drive "file=${VM_FILE},media=disk,if=virtio" \
+ -netdev "user,id=n1,hostname=openbsd-vm,tftp-server-name=10.0.2.1,tftp=tftp,bootfile=auto_install,hostfwd=tcp::2222-:22,guestfwd=tcp:10.0.2.1:80-cmd:socat - tcp:127.0.0.1:8080" \
+ -drive "file=${DISK_FILE},media=disk,if=virtio" \
-nographic
Generated by cgit. See skreutz.com for my tech blog and contact information.