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