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