summaryrefslogtreecommitdiff
path: root/run
blob: 9a0a3b818cde9641bf63e676b306c1099075b6ce (plain)
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
172
173
174
175
176
177
178
179
180
#! /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"
  printf "Fetched base public key from %s\\n" "${HTTPS_MIRROR}"
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
  printf "Fetching installation files ...\\n"
  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
  printf "Fetched kernel, PXE bootstrap program, and file sets from %s\\n" "${RSYNC_MIRROR}"
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
  printf "Created example response file for autoinstall(8) at ./mirror/install.conf\\n"
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
  printf "Created example disklabel(8) template at ./mirror/disklabel.conf\\n"
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
  printf "Created example site-specific file set at ./site\\n"
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
  printf "Created example boot(8) configuration at ./tftp/etc/boot.conf\\n"
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
      printf "Re-creating virtual machine due to changed configuration: %s\\n" "$f"
      rm "${DISK_FILE}"
    fi
  done
fi

# Create disk image if not exists.
if [ ! -e "${DISK_FILE}" ]
then
  qemu-img create -q -f qcow2 "${DISK_FILE}" "${DISK_SIZE}"
  printf "Created %s copy-on-write disk image at %s\\n" "${DISK_SIZE}" "${DISK_FILE}"
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.
printf "Starting virtual machine ...\\n"
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 STDIO TCP4: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.