Skip to content

Instantly share code, notes, and snippets.

@cgwalters
Last active November 22, 2019 20:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgwalters/bf6f5b6f788d01211dbe6cd362309a0d to your computer and use it in GitHub Desktop.
Save cgwalters/bf6f5b6f788d01211dbe6cd362309a0d to your computer and use it in GitHub Desktop.
#!/bin/bash
# Automate an end-to-end run of coreos-installer with the metal image, which then
# boots and writes a success message to a virtio-serial port, which we read on the host.
set -euo pipefail
run_tmp_webserver() {
local statedir=$1
shift
local dir=$1
shift
local tmpf=$(mktemp)
cd ${dir}
env PYTHONUNBUFFERED=1 setpriv --pdeathsig SIGTERM -- python3 -m http.server 0 &>${tmpf} &
cd -
child_pid=$!
local tmpf_snap=$(mktemp)
for x in $(seq 60); do
echo "Waiting for web server ($x/60)..." >&2
# Snapshot the output
cp ${tmpf} ${tmpf_snap}
# If it's non-empty, see whether it matches our regexp
if test -s ${tmpf_snap}; then # py3's http.server prints the http:// address also
sed -e 's,Serving HTTP on 0.0.0.0 port \([0-9]*\)\( (http://[^)]*)\)\? \.\.\.,\1,' < ${tmpf_snap} > ${statedir}/httpd-port
if ! cmp ${tmpf_snap} ${statedir}/httpd-port 1>/dev/null; then
# If so, we've successfully extracted the port
break
fi
fi
sleep 1
done
if [ ! -f ${statedir}/httpd-port ]; then
cat ${statedir}/httpd-output
echo "can't start up httpd"; exit 1
fi
port=$(cat ${statedir}/httpd-port)
echo "http://127.0.0.1:${port}" > ${statedir}/httpd-address
echo "$child_pid" > ${statedir}/httpd-pid
}
set -x
build=${1:-latest}
builddir=builds/${build}/x86_64
buildmeta=${builddir}/meta.json
metalimg=$(jq -er .images.metal.path < ${buildmeta})
instkernel=$(jq -er .images.kernel.path < ${buildmeta})
instinitramfs=$(jq -er .images.initramfs.path < ${buildmeta})
# OK, we seem to have the images. Launch our temporary webserver.
statedir=tmp/coreos-installer-test
rm -rf "${statedir}" && mkdir -p "${statedir}"
tftpdir=${statedir}/tftp
pxeconfigdir=${tftpdir}/pxelinux.cfg
mkdir -p "${pxeconfigdir}"
run_tmp_webserver "${statedir}" "${tftpdir}"
port=$(cat ${statedir}/httpd-port)
case "${metalimg}" in
*.raw) echo "NOTICE: Metal image is not compressed, doing so now temporarily"
gzip -1 < "${builddir}/${metalimg}" > "${tftpdir}/${metalimg}.gz"
metalimg=${metalimg}.gz ;;
*) ln "${builddir}/${metalimg}" "${tftpdir}" ;;
esac
for x in ${instkernel} ${instinitramfs}; do
ln "${builddir}/${x}" "${tftpdir}"
done
cat > ${pxeconfigdir}/default << EOF
DEFAULT pxeboot
TIMEOUT 20
PROMPT 0
LABEL pxeboot
KERNEL ${instkernel}
APPEND ip=dhcp rd.neednet=1 initrd=${instinitramfs} console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=vda coreos.inst.image_url=http://192.168.76.2:${port}/${metalimg} coreos.inst.ignition_url=http://192.168.76.2:${port}/config.ign
IPAPPEND 2
EOF
cp --reflink=auto /usr/share/syslinux/{pxelinux.0,ldlinux.c32} ${tftpdir}
disk=${statedir}/disk.qcow2
qemu-img create -f qcow2 ${disk} 12G
cat > ${tftpdir}/config.ign << EOF
{
"ignition": { "version": "2.2.0" },
"systemd": {
"units": [{
"name": "coreos-test-installer.service",
"enabled": true,
"contents": "[Unit]\nRequires=dev-virtio\\\x2dports-completion.device\nOnFailure=emergency.target\nOnFailureJobMode=isolate\n[Service]\nType=oneshot\nExecStart=/bin/sh -c '/usr/bin/echo coreos-installer-test-OK >/dev/virtio-ports/completion && systemctl poweroff'\n\n[Install]\nRequiredBy=multi-user.target"
}]
},
"storage": {
"files": [
{"path": "/etc/rhcos-no-clevis", "filesystem": "root", "mode": 420, "contents": {"source": "data:,"}}
]
}
}
EOF
jq . < ${tftpdir}/config.ign >/dev/null
completionf=${statedir}/completion.txt
touch "${completionf}"
qemu-system-x86_64 -accel kvm -m 8192 \
-object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 \
-boot once=n -option-rom /usr/share/qemu/pxe-rtl8139.rom \
-device e1000,netdev=mynet0,mac=52:54:00:12:34:56 -netdev user,id=mynet0,net=192.168.76.0/24,dhcpstart=192.168.76.9,tftp=${tftpdir},bootfile=/pxelinux.0 \
-drive if=virtio,file=${disk} \
-device virtio-serial -device virtserialport,chardev=completion,name=completion \
-chardev file,id=completion,path=${completionf}
if ! grep -q 'coreos-installer-test-OK' ${completionf}; then
echo "Failed to receive installer test completion"
cat ${completionf}
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment