11#! /bin/bash
2- socket=" /tmp/virtiofs.sock"
32
4- rootfs=" "
5- kernel=" $rootfs /boot/vmlinuz"
6- initram=" $rootfs /boot/initrd.img"
7- cmdline=" rw console=ttyS0 reboot=k panic=1 root=vroot rootfstype=virtiofs rootdelay=30"
8- overlayfs=" /tmp/merged"
9- flist=" "
3+ set -euo pipefail
4+
5+ # constants
6+ readonly SOCKET=" /tmp/virtiofs.sock"
7+ readonly OVERLAYFS=" /tmp/merged"
108
9+ # defaults
10+ cidata=" /tmp/cidata.img"
1111user=" user"
1212pass=" pass"
1313name=" cloud"
14+ cmdline=" rw console=ttyS0 reboot=k panic=1 root=vroot rootfstype=virtiofs rootdelay=30"
1415
16+ # globals
17+ init=" "
18+ kernel=" "
19+ initramfs=" "
1520fspid=0
1621flpid=0
1722
1823fail () {
19- echo " $1 " >&2
24+ echo " Error: $* " >&2
2025 exit 1
2126}
2227
2328usage () {
2429 echo " "
25- echo " Usage: $0 [OPTIONS]"
26- echo " --rootfs Path to the root filesystem image (required)"
27- echo " --user Username for the system (optional)"
28- echo " --pass Password for the user (optional)"
29- echo " --name Hostname for the system (optional)"
30- echo " --init Entrypoint for the system (optional)"
31- echo " "
3230}
3331
34- declare -A options
35- handle_options () {
36-
32+ handle_options () {
3733 while [[ " $# " -gt 0 ]]; do
3834 case $1 in
39- --image|--cidata|--kernel|--initramfs|--init|--user|--pass|--name)
40- options[$1 ]=" $2 "
41- shift 2
42- ;;
43- * )
44- usage
45- exit 1
46- ;;
35+ --image|--cidata|--kernel|--initramfs|--init|--user|--pass|--name|--debug )
36+ options[$1 ]=" $2 "
37+ shift 2
38+ ;;
39+ * )
40+ usage
41+ exit 1
42+ ;;
4743 esac
4844 done
4945}
5046
47+
5148validate () {
52- for tool in virtiofsd cloud-hypervisor mkdosfs rfs1; do
53- which " $tool " & > /dev/null || fail " '$tool ' not found in PATH"
49+ for tool in virtiofsd cloud-hypervisor rfs1; do
50+ command -v " $tool " > /dev/null 2>&1 || fail " '$tool ' not found in PATH"
5451 done
5552
56- [ -z " ${options[--image]} " ] && fail " rootfs image not provided"
53+ if [ ! -z " ${options[--cidata]} " ]; then
54+ command -v mkdosfs > /dev/null 2>&1 || fail " mkdosfs not found in PATH"
55+ fi
56+
57+ if [ -z " ${options[--image]} " ]; then
58+ fail " rootfs image not provided"
59+ fi
5760}
5861
59- cidata=" /tmp/cidata.img"
6062create_cidata () {
61- [[ -f " ${options[--cidata]} " ]] && return
63+ sudo chroot " ${OVERLAYFS} " cloud-init clean
64+
65+ if [[ -f " ${options[--cidata]} " ]]; then
66+ cidata=" ${options[--cidata]} "
67+ return
68+ fi
69+
70+ [ ! -z " ${options[--user]} " ] && user=" ${options[--user]} "
71+ [ ! -z " ${options[--pass]} " ] && pass=" ${options[--pass]} "
72+ [ ! -z " ${options[--name]} " ] && name=" ${options[--name]} "
6273
6374 echo " Creating cidata"
64- # todo: cloud-init clean
6575
6676 rm -f " ${cidata} "
6777 mkdosfs -n CIDATA -C " ${cidata} " 8192
90100cleanup () {
91101 local pids=( " $flpid " " $fspid " )
92102
93- # unmount and remove overlayfs
94- sudo umount " $overlayfs " 2> /dev/null || true
95- sudo rm -rf /tmp/upper /tmp/workdir " $overlayfs " 2> /dev/null || true
103+ sudo umount " ${OVERLAYFS} " 2> /dev/null || true
104+ sudo rm -rf /tmp/upper /tmp/workdir " ${OVERLAYFS} " 2> /dev/null || true
96105
97- # kill any running processes
98106 for pid in " ${pids[@]} " ; do
99107 kill " $pid " 2> /dev/null || true
100108 done
101109}
102- trap cleanup EXIT
103110
104- run_hypervisor () {
111+ boot () {
105112 sudo cloud-hypervisor \
106113 --cpus boot=1,max=1 \
107114 --memory size=1024M,shared=on \
108115 --kernel " ${kernel} " \
109- --initramfs " ${initram } " \
110- --fs tag=vroot,socket=" ${socket } " \
116+ --initramfs " ${initramfs } " \
117+ --fs tag=vroot,socket=" ${SOCKET } " \
111118 --disk path=" ${cidata} " \
112119 --cmdline " ${cmdline} " \
113120 --serial tty \
@@ -117,7 +124,7 @@ run_hypervisor() {
117124prepare_rootfs () {
118125 local image_path=" ${options[--image]} "
119126
120- sudo mkdir -p /tmp/upper /tmp/workdir " $overlayfs "
127+ sudo mkdir -p /tmp/upper /tmp/workdir " ${OVERLAYFS} "
121128
122129 if [[ ${image_path} == * .flist ]]; then
123130 echo " ${image_path} is flist, mounting"
@@ -136,30 +143,26 @@ prepare_rootfs() {
136143 -t overlay \
137144 -o lowerdir=" $rootfs " ,upperdir=/tmp/upper,workdir=/tmp/workdir \
138145 none \
139- " $overlayfs "
146+ " ${OVERLAYFS} "
140147
141148 echo " Starting virtiofs"
142149 sudo virtiofsd \
143- --socket-path=" ${socket } " \
144- --shared-dir=" ${overlayfs } " \
150+ --socket-path=" ${SOCKET } " \
151+ --shared-dir=" ${OVERLAYFS } " \
145152 --cache=never \
146153 &
147154 fspid=$!
148155}
149156
150157prepare_boot () {
151- kernel=" ${options[--kernel]} "
152- if [ -z " $kernel " ]; then
153- kernel=" ${overlayfs} /boot/vmlinuz"
154- fi
158+ kernel=" ${options[--kernel]-} "
159+ kernel=" ${kernel:- " ${OVERLAYFS} /boot/vmlinuz" } "
155160
156- initramfs=" ${options[--initramfs]} "
157- if [ -z " $initramfs " ]; then
158- initramfs=" ${overlayfs} /boot/initrd.img"
159- fi
161+ initramfs=" ${options[--initramfs]-} "
162+ initramfs=" ${initramfs:- " ${OVERLAYFS} /boot/initrd.img" } "
160163
161- init=" ${options[--init]} "
162- if [ ! -z " $init " ]; then
164+ init=" ${options[--init]- } "
165+ if [ -n " $init " ]; then
163166 cmdline=" $cmdline init=$init "
164167 fi
165168
@@ -170,10 +173,38 @@ prepare_boot() {
170173 fi
171174}
172175
176+ # main
177+
178+ # move defaults here
179+ declare -A options=(
180+ [--debug]=" false"
181+ [--cidata]=" "
182+ [--kernel]=" "
183+ [--initramfs]=" "
184+ [--init]=" "
185+ [--user]=" "
186+ [--pass]=" "
187+ [--name]=" "
188+ )
189+
173190handle_options " $@ "
191+
192+ if [[ " ${options[--debug]} " == true ]]; then
193+ set -x
194+ fi
195+
196+ echo " validating requirements"
174197validate
198+
199+ echo " preparing rootfs"
175200prepare_rootfs
201+
202+ echo " preparing boot"
176203prepare_boot
204+
205+ echo " creating cidata"
177206create_cidata
207+ trap cleanup EXIT
178208
179- # run_hypervisor
209+ echo " booting"
210+ boot
0 commit comments