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 " --nic-model NIC model supported by QEMU. 'virtio' is the default." 64 echo 65 echo " Examples:" 66 echo 67 echo " $0 -x http://user:password@host:port fedora37" 68 echo " $0 -s 2048 -n 2 ubuntu2204" 69 echo " $0 -rv freebsd" 70 echo " $0 fedora37" 71 echo " $0 -b /var/lib/libvirt/images/nvme1.img,nvme,/var/lib/libvirt/images/nvme1n1.img fedora37" 72 echo " $0 -b none fedora37" 73 echo 74} 75 76is_valid_nic_model() { 77 local models model 78 79 [[ $SPDK_VAGRANT_PROVIDER == libvirt ]] || return 0 80 81 mapfile -t models < <( 82 "${SPDK_QEMU_EMULATOR:-qemu-system-x86_64}" -nic model=? | grep -v "NIC models:" 83 ) 84 models+=("virtio") 85 86 for model in "${models[@]}"; do 87 [[ $model == "$NIC_MODEL" ]] && return 0 88 done 89 90 echo "NIC model '$NIC_MODEL' is invalid. List of supported models:" >&2 91 printf ' %s\n' "${models[@]}" >&2 92 return 1 93} 94 95# Set up vagrant proxy. Assumes git-bash on Windows 96# https://stackoverflow.com/questions/19872591/how-to-use-vagrant-in-a-proxy-environment 97SPDK_VAGRANT_HTTP_PROXY="" 98 99VERBOSE=0 100HELP=0 101COPY_SPDK_DIR=1 102COPY_SPDK_ARTIFACTS=0 103DRY_RUN=0 104DEPLOY_TEST_VM=0 105SPDK_VAGRANT_DISTRO="distro" 106SPDK_VAGRANT_VMCPU=4 107SPDK_VAGRANT_VMRAM=4096 108SPDK_VAGRANT_PROVIDER="virtualbox" 109SPDK_QEMU_EMULATOR="" 110SPDK_OPENSTACK_NETWORK=0 111OPTIND=1 112NVME_DISKS_TYPE="" 113NVME_DISKS_NAMESPACES="" 114NVME_FILE="" 115NVME_AUTO_CREATE=0 116VAGRANTFILE_DIR="" 117VAGRANT_PASSWORD_AUTH=0 118VAGRANT_PACKAGE_BOX=0 119VAGRANT_HUGE_MEM=0 120VAGRANTFILE=$DIR/Vagrantfile 121FORCE_DISTRO=false 122NFS4_BACKEND=0 123VAGRANT_BOX_VERSION="" 124EXTRA_VAGRANTFILES="" 125NIC_MODEL=virtio 126 127while getopts ":b:n:s:x:p:uvcraldoHNhf-:" opt; do 128 case "${opt}" in 129 -) 130 case "${OPTARG}" in 131 package-box) VAGRANT_PACKAGE_BOX=1 ;; 132 qemu-emulator=*) SPDK_QEMU_EMULATOR="${OPTARG#*=}" ;; 133 vagrantfiles-dir=*) VAGRANTFILE_DIR="${OPTARG#*=}" ;; 134 vagrantfile=*) [[ -n ${OPTARG#*=} ]] && VAGRANTFILE="${OPTARG#*=}" ;; 135 box-version=*) [[ -n ${OPTARG#*=} ]] && VAGRANT_BOX_VERSION="${OPTARG#*=}" ;; 136 extra-vagrantfiles=*) [[ -n ${OPTARG#*=} ]] && EXTRA_VAGRANTFILES="${OPTARG#*=}" ;; 137 nic-model=*) [[ -n ${OPTARG#*=} ]] && NIC_MODEL="${OPTARG#*=}" ;; 138 *) echo "Invalid argument '$OPTARG'" ;; 139 esac 140 ;; 141 x) 142 http_proxy=$OPTARG 143 https_proxy=$http_proxy 144 SPDK_VAGRANT_HTTP_PROXY="${http_proxy}" 145 ;; 146 n) 147 SPDK_VAGRANT_VMCPU=$OPTARG 148 ;; 149 s) 150 SPDK_VAGRANT_VMRAM=$OPTARG 151 ;; 152 p) 153 SPDK_VAGRANT_PROVIDER=$OPTARG 154 ;; 155 v) 156 VERBOSE=1 157 ;; 158 c) 159 NVME_AUTO_CREATE=1 160 ;; 161 r) 162 DRY_RUN=1 163 ;; 164 h) 165 display_help >&2 166 exit 0 167 ;; 168 a) 169 COPY_SPDK_ARTIFACTS=1 170 ;; 171 l) 172 COPY_SPDK_DIR=0 173 ;; 174 d) 175 DEPLOY_TEST_VM=1 176 ;; 177 o) 178 SPDK_OPENSTACK_NETWORK=1 179 ;; 180 b) 181 NVME_FILE+="${OPTARG#*=} " 182 ;; 183 u) 184 VAGRANT_PASSWORD_AUTH=1 185 ;; 186 H) 187 VAGRANT_HUGE_MEM=1 188 ;; 189 f) 190 FORCE_DISTRO=true 191 ;; 192 N) 193 NFS4_BACKEND=1 194 ;; 195 *) 196 echo " Invalid argument: -$OPTARG" >&2 197 echo " Try: \"$0 -h\"" >&2 198 exit 1 199 ;; 200 esac 201done 202 203is_valid_nic_model 204 205shift "$((OPTIND - 1))" # Discard the options and sentinel -- 206 207SPDK_VAGRANT_DISTRO="$*" 208 209case "${SPDK_VAGRANT_DISTRO}" in 210 centos7) ;& 211 ubuntu2[02]04) ;& 212 fedora3[7-8]) ;& 213 freebsd1[2-3]) ;& 214 rocky[89]) ;& 215 arch | clearlinux) ;; 216 *) 217 if [[ $FORCE_DISTRO == false ]]; then 218 echo " Invalid argument \"${SPDK_VAGRANT_DISTRO}\"" >&2 219 echo " Try: \"$0 -h\"" >&2 220 exit 1 221 fi 222 ;; 223esac 224export SPDK_VAGRANT_DISTRO 225 226if [ -z "$NVME_FILE" ]; then 227 TMP="/var/lib/libvirt/images/nvme_disk.img" 228 NVME_DISKS_TYPE="nvme" 229else 230 TMP="" 231 for args in $NVME_FILE; do 232 while IFS=, read -r path type namespace cmb pmr zns ms fdp; do 233 TMP+="$path," 234 if [ -z "$type" ]; then 235 type="nvme" 236 fi 237 NVME_CMB+="$cmb," 238 NVME_PMR+="$pmr," 239 NVME_ZNS+="$zns," 240 NVME_DISKS_TYPE+="$type," 241 NVME_DISKS_NAMESPACES+="$namespace," 242 NVME_MS+="$ms," 243 NVME_FDP+="$fdp," 244 if [ ${NVME_AUTO_CREATE} = 1 ]; then 245 $SPDK_DIR/scripts/vagrant/create_nvme_img.sh -n $path 246 fi 247 done <<< $args 248 done 249fi 250NVME_FILE=$TMP 251 252if [ ${VERBOSE} = 1 ]; then 253 echo 254 echo DIR=${DIR} 255 echo SPDK_DIR=${SPDK_DIR} 256 echo VAGRANT_TARGET=${VAGRANT_TARGET} 257 echo HELP=$HELP 258 echo DRY_RUN=$DRY_RUN 259 echo NVME_FILE=$NVME_FILE 260 echo NVME_DISKS_TYPE=$NVME_DISKS_TYPE 261 echo NVME_AUTO_CREATE=$NVME_AUTO_CREATE 262 echo NVME_DISKS_NAMESPACES=$NVME_DISKS_NAMESPACES 263 echo NVME_CMB=$NVME_CMB 264 echo NVME_PMR=$NVME_PMR 265 echo NVME_ZNS=$NVME_ZNS 266 echo NVME_MS=$NVME_MS 267 echo NVME_FDP=$NVME_FDP 268 echo SPDK_VAGRANT_DISTRO=$SPDK_VAGRANT_DISTRO 269 echo SPDK_VAGRANT_VMCPU=$SPDK_VAGRANT_VMCPU 270 echo SPDK_VAGRANT_VMRAM=$SPDK_VAGRANT_VMRAM 271 echo SPDK_VAGRANT_PROVIDER=$SPDK_VAGRANT_PROVIDER 272 echo SPDK_VAGRANT_HTTP_PROXY=$SPDK_VAGRANT_HTTP_PROXY 273 echo SPDK_QEMU_EMULATOR=$SPDK_QEMU_EMULATOR 274 echo SPDK_OPENSTACK_NETWORK=$SPDK_OPENSTACK_NETWORK 275 echo VAGRANT_PACKAGE_BOX=$VAGRANT_PACKAGE_BOX 276 echo VAGRANTFILE=$VAGRANTFILE 277 echo FORCE_DISTRO=$FORCE_DISTRO 278 echo VAGRANT_BOX_VERSION=$VAGRANT_BOX_VERSION 279 echo EXTRA_VAGRANTFILES=$EXTRA_VAGRANTFILES 280 echo NIC_MODEL=$NIC_MODEL 281 echo 282fi 283 284export SPDK_VAGRANT_HTTP_PROXY 285export SPDK_VAGRANT_VMCPU 286export SPDK_VAGRANT_VMRAM 287export SPDK_DIR 288export SPDK_OPENSTACK_NETWORK 289export COPY_SPDK_DIR 290export COPY_SPDK_ARTIFACTS 291export DEPLOY_TEST_VM 292export NVME_CMB 293export NVME_PMR 294export NVME_ZNS 295export NVME_MS 296export NVME_FDP 297export NVME_DISKS_TYPE 298export NVME_DISKS_NAMESPACES 299export NVME_FILE 300export VAGRANT_PASSWORD_AUTH 301export VAGRANT_HUGE_MEM 302export FORCE_DISTRO 303export VAGRANT_BOX_VERSION 304export EXTRA_VAGRANTFILES 305export NIC_MODEL 306 307if [ -n "$SPDK_VAGRANT_PROVIDER" ]; then 308 provider="--provider=${SPDK_VAGRANT_PROVIDER}" 309fi 310 311if [ -n "$SPDK_VAGRANT_PROVIDER" ]; then 312 export SPDK_VAGRANT_PROVIDER 313fi 314 315if [ -n "$SPDK_QEMU_EMULATOR" ] && [ "$SPDK_VAGRANT_PROVIDER" == "libvirt" ]; then 316 export SPDK_QEMU_EMULATOR 317fi 318 319if [ ${DRY_RUN} = 1 ]; then 320 echo "Environment Variables" 321 printenv SPDK_VAGRANT_DISTRO 322 printenv SPDK_VAGRANT_VMRAM 323 printenv SPDK_VAGRANT_VMCPU 324 printenv SPDK_VAGRANT_PROVIDER 325 printenv SPDK_VAGRANT_HTTP_PROXY 326 printenv SPDK_QEMU_EMULATOR 327 printenv NVME_DISKS_TYPE 328 printenv NVME_AUTO_CREATE 329 printenv NVME_DISKS_NAMESPACES 330 printenv NVME_FILE 331 printenv SPDK_DIR 332 printenv VAGRANT_HUGE_MEM 333 printenv VAGRANTFILE 334 printenv FORCE_DISTRO 335 printenv VAGRANT_BOX_VERSION 336 printenv EXTRA_VAGRANTFILES 337 printenv NIC_MODEL 338fi 339if [ -z "$VAGRANTFILE_DIR" ]; then 340 VAGRANTFILE_DIR="${VAGRANT_TARGET}/${SPDK_VAGRANT_DISTRO}-${SPDK_VAGRANT_PROVIDER}" 341 export VAGRANTFILE_DIR 342fi 343 344if [ -d "${VAGRANTFILE_DIR}" ]; then 345 echo "Error: ${VAGRANTFILE_DIR} already exists!" 346 exit 1 347fi 348 349if [[ ! -f $VAGRANTFILE ]]; then 350 echo "$VAGRANTFILE is not a regular file!" 351 exit 1 352fi 353 354if [ ${DRY_RUN} != 1 ]; then 355 mkdir -vp "${VAGRANTFILE_DIR}" 356 ln -s "$VAGRANTFILE" "${VAGRANTFILE_DIR}/Vagrantfile" 357 pushd "${VAGRANTFILE_DIR}" 358 if [ -n "${http_proxy}" ]; then 359 export http_proxy 360 export https_proxy 361 if echo "$SPDK_VAGRANT_DISTRO" | grep -q freebsd; then 362 cat > ~/vagrant_pkg.conf << EOF 363pkg_env: { 364http_proxy: ${http_proxy} 365} 366EOF 367 fi 368 fi 369 mkdir -p "${VAGRANTFILE_DIR}/output" 370 vagrant up $provider 371 if [ ${VAGRANT_PACKAGE_BOX} == 1 ]; then 372 vagrant ssh -c 'sudo spdk_repo/spdk/scripts/vagrant/update.sh' 373 vagrant halt 374 vagrant package --output spdk_${SPDK_VAGRANT_DISTRO}.box 375 vagrant box add spdk/${SPDK_VAGRANT_DISTRO} spdk_${SPDK_VAGRANT_DISTRO}.box \ 376 && rm spdk_${SPDK_VAGRANT_DISTRO}.box 377 vagrant destroy 378 fi 379 echo "" 380 echo " SUCCESS!" 381 echo "" 382 echo " cd to ${VAGRANTFILE_DIR} and type \"vagrant ssh\" to use." 383 echo " Use vagrant \"suspend\" and vagrant \"resume\" to stop and start." 384 echo " Use vagrant \"destroy\" followed by \"rm -rf ${VAGRANTFILE_DIR}\" to destroy all trace of vm." 385 echo "" 386fi 387