xref: /spdk/scripts/vagrant/create_vbox.sh (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1#!/usr/bin/env bash
2
3# create_vbox.sh
4#
5# Creates a virtual box with vagrant in the $PWD.
6#
7# This script creates a subdirectory called $PWD/<distro> and copies the Vagrantfile
8# into that directory before running 'vagrant up'
9
10set -e
11
12VAGRANT_TARGET="$PWD"
13
14DIR="$(cd "$(dirname $0)" && pwd)"
15SPDK_DIR="$(cd "${DIR}/../../" && pwd)"
16
17# The command line help
18display_help() {
19	echo
20	echo " Usage: ${0##*/} [-b nvme-backing-file] [-n <num-cpus>] [-s <ram-size>] [-x <http-proxy>] [-hvrldcufaoH] <distro>"
21	echo
22	echo "  distro = <centos7 | centos8 | ubuntu1604 | ubuntu1804 | ubuntu2004 | ubuntu2204 | fedora33 |"
23	echo "            fedora34 | fedora35 | fedora36 | freebsd11 | freebsd12 | freebsd13 | arch | clearlinux | rocky8>"
24	echo
25	echo "  -s <ram-size> in MB             Default: ${SPDK_VAGRANT_VMRAM}"
26	echo "  -n <num-cpus> 1 to 4            Default: ${SPDK_VAGRANT_VMCPU}"
27	echo "  -x <http-proxy>                 Default: \"${SPDK_VAGRANT_HTTP_PROXY}\""
28	echo "  -p <provider>                   \"libvirt\" or \"virtualbox\". Default: ${SPDK_VAGRANT_PROVIDER}"
29	echo "  -b <nvme-backing-file>          Emulated NVMe options."
30	echo "                                  If no -b option is specified then this option defaults to emulating single"
31	echo "                                  NVMe with 1 namespace and assumes path: /var/lib/libvirt/images/nvme_disk.img"
32	echo "                                  -b option can be used multiple times for attaching multiple files to the VM"
33	echo "                                  Parameters for -b option: <path>,<type>,<ns_path1[:ns_path1:...]>,<cmb>,<pmr_file[:pmr_size]>,<zns>,<ms>"
34	echo "                                  Available types: nvme"
35	echo "                                  Default pmr size: 16M"
36	echo "                                  Default cmb: false"
37	echo "                                  Default zns: false"
38	echo "                                  Default ms: none"
39	echo "                                  type, ns_path, cmb, pmr, zns and ms can be empty"
40	echo "  -c                              Create all above disk, default 0"
41	echo "  -H                              Use hugepages for allocating VM memory. Only for libvirt provider. Default: false."
42	echo "  -u                              Use password authentication to the VM instead of SSH keys."
43	echo "  -l                              Use a local copy of spdk, don't try to rsync from the host."
44	echo "  -a                              Copy spdk/autorun.sh artifacts from VM to host system."
45	echo "  -d                              Deploy a test vm by provisioning all prerequisites for spdk autotest"
46	echo "  -o                              Add network interface for openstack tests"
47	echo "  --qemu-emulator=<path>          Path to custom QEMU binary. Only works with libvirt provider"
48	echo "  --vagrantfiles-dir=<path>       Destination directory to put Vagrantfile into."
49	echo "  --package-box                   Install all dependencies for SPDK and create a local vagrant box version."
50	echo "  --vagrantfile=<path>            Path to a custom Vagrantfile"
51	echo "  --extra-vagrantfiles=<path>     Comma separated list of files to load from within main Vagrantfile"
52	echo "  -r dry-run"
53	echo "  -h help"
54	echo "  -v verbose"
55	echo "  -f                              Force use of given distro, regardless if it's supported by the script or not."
56	echo "  --box-version                   Version of the vagrant box to select for given distro."
57	echo
58	echo " Examples:"
59	echo
60	echo "  $0 -x http://user:password@host:port fedora33"
61	echo "  $0 -s 2048 -n 2 ubuntu16"
62	echo "  $0 -rv freebsd"
63	echo "  $0 fedora33"
64	echo "  $0 -b /var/lib/libvirt/images/nvme1.img,nvme,/var/lib/libvirt/images/nvme1n1.img fedora33"
65	echo "  $0 -b none fedora33"
66	echo
67}
68
69# Set up vagrant proxy. Assumes git-bash on Windows
70# https://stackoverflow.com/questions/19872591/how-to-use-vagrant-in-a-proxy-environment
71SPDK_VAGRANT_HTTP_PROXY=""
72
73VERBOSE=0
74HELP=0
75COPY_SPDK_DIR=1
76COPY_SPDK_ARTIFACTS=0
77DRY_RUN=0
78DEPLOY_TEST_VM=0
79SPDK_VAGRANT_DISTRO="distro"
80SPDK_VAGRANT_VMCPU=4
81SPDK_VAGRANT_VMRAM=4096
82SPDK_VAGRANT_PROVIDER="virtualbox"
83SPDK_QEMU_EMULATOR=""
84SPDK_OPENSTACK_NETWORK=0
85OPTIND=1
86NVME_DISKS_TYPE=""
87NVME_DISKS_NAMESPACES=""
88NVME_FILE=""
89NVME_AUTO_CREATE=0
90VAGRANTFILE_DIR=""
91VAGRANT_PASSWORD_AUTH=0
92VAGRANT_PACKAGE_BOX=0
93VAGRANT_HUGE_MEM=0
94VAGRANTFILE=$DIR/Vagrantfile
95FORCE_DISTRO=false
96VAGRANT_BOX_VERSION=""
97EXTRA_VAGRANTFILES=""
98
99while getopts ":b:n:s:x:p:uvcraldoHhf-:" opt; do
100	case "${opt}" in
101		-)
102			case "${OPTARG}" in
103				package-box) VAGRANT_PACKAGE_BOX=1 ;;
104				qemu-emulator=*) SPDK_QEMU_EMULATOR="${OPTARG#*=}" ;;
105				vagrantfiles-dir=*) VAGRANTFILE_DIR="${OPTARG#*=}" ;;
106				vagrantfile=*) [[ -n ${OPTARG#*=} ]] && VAGRANTFILE="${OPTARG#*=}" ;;
107				box-version=*) [[ -n ${OPTARG#*=} ]] && VAGRANT_BOX_VERSION="${OPTARG#*=}" ;;
108				extra-vagrantfiles=*) [[ -n ${OPTARG#*=} ]] && EXTRA_VAGRANTFILES="${OPTARG#*=}" ;;
109				*) echo "Invalid argument '$OPTARG'" ;;
110			esac
111			;;
112		x)
113			http_proxy=$OPTARG
114			https_proxy=$http_proxy
115			SPDK_VAGRANT_HTTP_PROXY="${http_proxy}"
116			;;
117		n)
118			SPDK_VAGRANT_VMCPU=$OPTARG
119			;;
120		s)
121			SPDK_VAGRANT_VMRAM=$OPTARG
122			;;
123		p)
124			SPDK_VAGRANT_PROVIDER=$OPTARG
125			;;
126		v)
127			VERBOSE=1
128			;;
129		c)
130			NVME_AUTO_CREATE=1
131			;;
132		r)
133			DRY_RUN=1
134			;;
135		h)
136			display_help >&2
137			exit 0
138			;;
139		a)
140			COPY_SPDK_ARTIFACTS=1
141			;;
142		l)
143			COPY_SPDK_DIR=0
144			;;
145		d)
146			DEPLOY_TEST_VM=1
147			;;
148		o)
149			SPDK_OPENSTACK_NETWORK=1
150			;;
151		b)
152			NVME_FILE+="${OPTARG#*=} "
153			;;
154		u)
155			VAGRANT_PASSWORD_AUTH=1
156			;;
157		H)
158			VAGRANT_HUGE_MEM=1
159			;;
160		f)
161			FORCE_DISTRO=true
162			;;
163		*)
164			echo "  Invalid argument: -$OPTARG" >&2
165			echo "  Try: \"$0 -h\"" >&2
166			exit 1
167			;;
168	esac
169done
170
171shift "$((OPTIND - 1))" # Discard the options and sentinel --
172
173SPDK_VAGRANT_DISTRO="$*"
174
175case "${SPDK_VAGRANT_DISTRO}" in
176	centos[78]) ;&
177	ubuntu1[68]04 | ubuntu2[02]04) ;&
178	fedora3[3-6]) ;&
179	freebsd1[1-3]) ;&
180	rocky8) ;&
181	arch | clearlinux) ;;
182	*)
183		if [[ $FORCE_DISTRO == false ]]; then
184			echo "  Invalid argument \"${SPDK_VAGRANT_DISTRO}\"" >&2
185			echo "  Try: \"$0 -h\"" >&2
186			exit 1
187		fi
188		;;
189esac
190export SPDK_VAGRANT_DISTRO
191
192if [ -z "$NVME_FILE" ]; then
193	TMP="/var/lib/libvirt/images/nvme_disk.img"
194	NVME_DISKS_TYPE="nvme"
195else
196	TMP=""
197	for args in $NVME_FILE; do
198		while IFS=, read -r path type namespace cmb pmr zns ms; do
199			TMP+="$path,"
200			if [ -z "$type" ]; then
201				type="nvme"
202			fi
203			NVME_CMB+="$cmb,"
204			NVME_PMR+="$pmr,"
205			NVME_ZNS+="$zns,"
206			NVME_DISKS_TYPE+="$type,"
207			NVME_DISKS_NAMESPACES+="$namespace,"
208			NVME_MS+="$ms,"
209			if [ ${NVME_AUTO_CREATE} = 1 ]; then
210				$SPDK_DIR/scripts/vagrant/create_nvme_img.sh -n $path
211			fi
212		done <<< $args
213	done
214fi
215NVME_FILE=$TMP
216
217if [ ${VERBOSE} = 1 ]; then
218	echo
219	echo DIR=${DIR}
220	echo SPDK_DIR=${SPDK_DIR}
221	echo VAGRANT_TARGET=${VAGRANT_TARGET}
222	echo HELP=$HELP
223	echo DRY_RUN=$DRY_RUN
224	echo NVME_FILE=$NVME_FILE
225	echo NVME_DISKS_TYPE=$NVME_DISKS_TYPE
226	echo NVME_AUTO_CREATE=$NVME_AUTO_CREATE
227	echo NVME_DISKS_NAMESPACES=$NVME_DISKS_NAMESPACES
228	echo NVME_CMB=$NVME_CMB
229	echo NVME_PMR=$NVME_PMR
230	echo NVME_ZNS=$NVME_ZNS
231	echo NVME_MS=$NVME_MS
232	echo SPDK_VAGRANT_DISTRO=$SPDK_VAGRANT_DISTRO
233	echo SPDK_VAGRANT_VMCPU=$SPDK_VAGRANT_VMCPU
234	echo SPDK_VAGRANT_VMRAM=$SPDK_VAGRANT_VMRAM
235	echo SPDK_VAGRANT_PROVIDER=$SPDK_VAGRANT_PROVIDER
236	echo SPDK_VAGRANT_HTTP_PROXY=$SPDK_VAGRANT_HTTP_PROXY
237	echo SPDK_QEMU_EMULATOR=$SPDK_QEMU_EMULATOR
238	echo SPDK_OPENSTACK_NETWORK=$SPDK_OPENSTACK_NETWORK
239	echo VAGRANT_PACKAGE_BOX=$VAGRANT_PACKAGE_BOX
240	echo VAGRANTFILE=$VAGRANTFILE
241	echo FORCE_DISTRO=$FORCE_DISTRO
242	echo VAGRANT_BOX_VERSION=$VAGRANT_BOX_VERSION
243	echo EXTRA_VAGRANTFILES=$EXTRA_VAGRANTFILES
244	echo
245fi
246
247export SPDK_VAGRANT_HTTP_PROXY
248export SPDK_VAGRANT_VMCPU
249export SPDK_VAGRANT_VMRAM
250export SPDK_DIR
251export SPDK_OPENSTACK_NETWORK
252export COPY_SPDK_DIR
253export COPY_SPDK_ARTIFACTS
254export DEPLOY_TEST_VM
255export NVME_CMB
256export NVME_PMR
257export NVME_ZNS
258export NVME_MS
259export NVME_DISKS_TYPE
260export NVME_DISKS_NAMESPACES
261export NVME_FILE
262export VAGRANT_PASSWORD_AUTH
263export VAGRANT_HUGE_MEM
264export FORCE_DISTRO
265export VAGRANT_BOX_VERSION
266export EXTRA_VAGRANTFILES
267
268if [ -n "$SPDK_VAGRANT_PROVIDER" ]; then
269	provider="--provider=${SPDK_VAGRANT_PROVIDER}"
270fi
271
272if [ -n "$SPDK_VAGRANT_PROVIDER" ]; then
273	export SPDK_VAGRANT_PROVIDER
274fi
275
276if [ -n "$SPDK_QEMU_EMULATOR" ] && [ "$SPDK_VAGRANT_PROVIDER" == "libvirt" ]; then
277	export SPDK_QEMU_EMULATOR
278fi
279
280if [ ${DRY_RUN} = 1 ]; then
281	echo "Environment Variables"
282	printenv SPDK_VAGRANT_DISTRO
283	printenv SPDK_VAGRANT_VMRAM
284	printenv SPDK_VAGRANT_VMCPU
285	printenv SPDK_VAGRANT_PROVIDER
286	printenv SPDK_VAGRANT_HTTP_PROXY
287	printenv SPDK_QEMU_EMULATOR
288	printenv NVME_DISKS_TYPE
289	printenv NVME_AUTO_CREATE
290	printenv NVME_DISKS_NAMESPACES
291	printenv NVME_FILE
292	printenv SPDK_DIR
293	printenv VAGRANT_HUGE_MEM
294	printenv VAGRANTFILE
295	printenv FORCE_DISTRO
296	printenv VAGRANT_BOX_VERSION
297	printenv EXTRA_VAGRANTFILES
298fi
299if [ -z "$VAGRANTFILE_DIR" ]; then
300	VAGRANTFILE_DIR="${VAGRANT_TARGET}/${SPDK_VAGRANT_DISTRO}-${SPDK_VAGRANT_PROVIDER}"
301	export VAGRANTFILE_DIR
302fi
303
304if [ -d "${VAGRANTFILE_DIR}" ]; then
305	echo "Error: ${VAGRANTFILE_DIR} already exists!"
306	exit 1
307fi
308
309if [[ ! -f $VAGRANTFILE ]]; then
310	echo "$VAGRANTFILE is not a regular file!"
311	exit 1
312fi
313
314if [ ${DRY_RUN} != 1 ]; then
315	mkdir -vp "${VAGRANTFILE_DIR}"
316	ln -s "$VAGRANTFILE" "${VAGRANTFILE_DIR}/Vagrantfile"
317	pushd "${VAGRANTFILE_DIR}"
318	if [ -n "${http_proxy}" ]; then
319		export http_proxy
320		export https_proxy
321		if echo "$SPDK_VAGRANT_DISTRO" | grep -q freebsd; then
322			cat > ~/vagrant_pkg.conf << EOF
323pkg_env: {
324http_proxy: ${http_proxy}
325}
326EOF
327		fi
328	fi
329	mkdir -p "${VAGRANTFILE_DIR}/output"
330	vagrant up $provider
331	if [ ${VAGRANT_PACKAGE_BOX} == 1 ]; then
332		vagrant ssh -c 'sudo spdk_repo/spdk/scripts/vagrant/update.sh'
333		vagrant halt
334		vagrant package --output spdk_${SPDK_VAGRANT_DISTRO}.box
335		vagrant box add spdk/${SPDK_VAGRANT_DISTRO} spdk_${SPDK_VAGRANT_DISTRO}.box \
336			&& rm spdk_${SPDK_VAGRANT_DISTRO}.box
337		vagrant destroy
338	fi
339	echo ""
340	echo "  SUCCESS!"
341	echo ""
342	echo "  cd to ${VAGRANTFILE_DIR} and type \"vagrant ssh\" to use."
343	echo "  Use vagrant \"suspend\" and vagrant \"resume\" to stop and start."
344	echo "  Use vagrant \"destroy\" followed by \"rm -rf ${VAGRANTFILE_DIR}\" to destroy all trace of vm."
345	echo ""
346fi
347