1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
#! /bin/sh
# Auto-install OpenBSD/amd64 6.7 on QEMU.
#
# Copyright (c) 2020 Stefan Kreutz <mail@skreutz.com>
set -o errexit
set -o nounset
# Accept parameters from environment.
SSH_KEY="${SSH_KEY-${HOME}/.ssh/id_rsa.pub}"
HTTPS_MIRROR="${HTTPS_MIRROR-https://ftp.openbsd.org/pub/OpenBSD/}"
RSYNC_MIRROR="${RSYNC_MIRROR-rsync://ftp.halifax.rwth-aachen.de/openbsd/}"
DISK_FILE="${DISK_FILE-disk.qcow2}"
DISK_SIZE="${DISK_SIZE-24G}"
CPU_COUNT="${CPU_COUNT-4}"
MEMORY_SIZE="${MEMORY_SIZE-4G}"
# Fail early on missing dependencies.
for cmd in qemu-img qemu-system-x86_64 curl signify rsync ssh socat ;
do
if ! command -v "${cmd}" >/dev/null ;
then
( >&2 printf "command not found: %s\\n" "${cmd}" )
exit 1
fi
done
# Fetch base public key from trusted HTTPS mirror.
mkdir -p mirror/pub/OpenBSD/6.7
if [ ! -e mirror/pub/OpenBSD/6.7/openbsd-67-base.pub ] ;
then
curl \
--silent \
--output mirror/pub/OpenBSD/6.7/openbsd-67-base.pub \
"${HTTPS_MIRROR}6.7/openbsd-67-base.pub"
fi
# Fetch kernel, PXE bootstrap program, and file sets from untrusted
# rsync mirror.
if [ ! -d mirror/pub/OpenBSD/6.7/amd64 ] ;
then
mkdir -p tmp
rsync --recursive --delete --quiet \
"${RSYNC_MIRROR}6.7/amd64/SHA256" \
"${RSYNC_MIRROR}6.7/amd64/SHA256.sig" \
"${RSYNC_MIRROR}6.7/amd64/bsd" \
"${RSYNC_MIRROR}6.7/amd64/bsd.*" \
"${RSYNC_MIRROR}6.7/amd64/pxeboot" \
"${RSYNC_MIRROR}6.7/amd64/*67.tgz" \
tmp/
( cd tmp && signify -C -q \
-p ../mirror/pub/OpenBSD/6.7/openbsd-67-base.pub \
-x SHA256.sig \
-- bsd bsd.* pxeboot *67.tgz )
mv tmp mirror/pub/OpenBSD/6.7/amd64
fi
# Create autoinstall configuration if not exists.
if [ ! -e mirror/install.conf ] ;
then
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 = $( cat "${SSH_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) = site67.tgz
Checksum test for site67.tgz failed. Continue anyway = yes
Unverified sets: site67.tgz. Continue without verification = yes
EOF
fi
# Create disklabel configuration if not exists.
if [ ! -e mirror/disklabel ] ;
then
cat << EOF > mirror/disklabel
/ 2G
swap 8G
/tmp 1G
/var 1G
/usr 2G
/usr/X11R6 500M
/usr/local 4G
/usr/src 1M
/usr/obj 1M
/home 4G
EOF
fi
# 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
# 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.7/amd64/site67.tgz ] || [ "$( stat -c %Y mirror/pub/OpenBSD/6.7/amd64/site67.tgz )" -lt "${site_dir_changed}" ] ;
then
rm -f mirror/pub/OpenBSD/6.7/amd64/site67.tgz
( cd site && tar -czf ../mirror/pub/OpenBSD/6.7/amd64/site67.tgz . )
( cd mirror/pub/OpenBSD/6.7/amd64 && ls -l > index.txt )
fi
# Create TFTP directory if not exists.
if [ ! -d tftp ] ;
then
mkdir tftp
ln -s ../mirror/pub/OpenBSD/6.7/amd64/pxeboot tftp/auto_install
ln -s ../mirror/pub/OpenBSD/6.7/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
# 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.7/amd64/site67.tgz tftp/etc/boot.conf
do
if [ "${vm_created}" -lt "$( stat -c %Y "$f" )" ] ;
then
( >&2 printf "%s changed. Recreating virtual machine." "$f" )
rm "${DISK_FILE}"
fi
done
fi
# Create disk image if not exists.
if [ ! -e "${DISK_FILE}" ] ;
then
qemu-img create -f qcow2 "${DISK_FILE}" "${DISK_SIZE}"
fi
# 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=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
|