3 # A shell script to build the VPP VM image or NFVbench+TRex VM image using diskinage-builder
5 # The following packages must be installed prior to using this script:
6 # Ubuntu: sudo apt-get -y install python3 python3-venv qemu-utils kpartx
7 # CentOS: sudo yum install -y python3 qemu-img kpartx
9 # Stop on error (see https://wizardzines.com/comics/bash-errors/)
19 gs_url=artifacts.opnfv.org/nfvbench/images
21 # image version number
22 __loopvm_version__=0.16
23 __generator_version__=0.15
24 loopvm_image_name=nfvbenchvm_centos-$__loopvm_version__
25 generator_image_name=nfvbenchvm_centos-generator-$__generator_version__
27 # Default values for nfvbenchvm dib element variables
28 export DIB_NFVBENCH_CODE_ORIGIN=opnfv-gerrit
31 # ----------------------------------------------------------------------------
32 # Parse command line options and configure the script
33 # ----------------------------------------------------------------------------
37 $(basename $0) - build NFVbench VM images
39 $(basename $0) [OPTIONS]
42 -l: build NFVbench loop VM image
43 -g: build NFVbench generator image
44 -v: verify only (build but do not push to google storage)
45 -s: use local nfvbench code instead of cloning from OPNFV gerrit
46 (only relevant for NFVbench generator image)
48 -t: enable debug trace (set -x + DIB_DEBUG_TRACE=1)
49 -d: start debug shell in image chroot in case of build error
50 -h: show this help message
55 while getopts ":lgvstdh" opt; do
67 export DIB_NFVBENCH_CODE_ORIGIN=static
71 export DIB_DEBUG_TRACE=1
88 # Build all VM images if the image to build is not specified on the CLI
89 if [[ $build_generator -eq 0 ]] && [[ $build_loopvm -eq 0 ]]; then
94 if [[ "${DIB_NFVBENCH_CODE_ORIGIN}" == "static" ]] && [[ $build_generator -eq 0 ]]; then
95 echo "Error: option -s is only relevant to the build of the generator image"
100 # ----------------------------------------------------------------------------
101 # Copy local nfvbench code to elements/nfvbenchvm/static/opt/nfvbench
102 # ----------------------------------------------------------------------------
104 function copy_local_nfvbench_code_to_static_dir {
105 echo "Copy local nfvbench code to elements/nfvbenchvm/static/opt"
106 # Create elements/nfvbenchvm/static/opt/ directory if it does not exist and
108 pushd $(dirname $0)/elements/nfvbenchvm/static
109 [ -d opt ] || mkdir opt
112 # Remove nfvbench code if it is already there
113 [ -d nfvbench ] && rm -rf nfvbench
115 # Use git to "copy" the local nfvbench code.
116 # This will include all the committed changes of the current branch.
117 git clone ../../../../../.. nfvbench
119 # Go back to the current directory when this function was called
124 # ----------------------------------------------------------------------------
125 # Configure and start the nfvbenchvm image build
126 # ----------------------------------------------------------------------------
128 function build_image {
129 # if image exists skip building
130 echo "Checking if image exists in google storage..."
131 if command -v gsutil >/dev/null; then
132 if gsutil -q stat gs://$gs_url/$1.qcow2; then
133 echo "Image already exists at https://$gs_url/$1.qcow2"
134 echo "Build is skipped"
137 echo "Image does not exist in google storage, starting build..."
140 echo "Cannot check image availability in OPNFV artifact repository (gsutil not available)"
143 # check if image is already built locally
144 if [ -f $1.qcow2 ]; then
145 echo "Image $1.qcow2 already exists locally"
147 # install diskimage-builder
148 if [ -d dib-venv ]; then
149 . dib-venv/bin/activate
151 python3 -m venv dib-venv
152 . dib-venv/bin/activate
153 pip install diskimage-builder==3.16.0
156 # Add nfvbenchvm_centos elements directory to the DIB elements path
157 export ELEMENTS_PATH=`pwd`/elements
159 # canned user/password for direct login
160 export DIB_DEV_USER_USERNAME=nfvbench
161 export DIB_DEV_USER_PASSWORD=nfvbench
162 export DIB_DEV_USER_PWDLESS_SUDO=Y
164 # Set the data sources to have ConfigDrive only
165 export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive"
168 export DIB_YUM_REPO_CONF=$ELEMENTS_PATH/nfvbenchvm/fdio-release.repo
170 # Use ELRepo to have latest kernel
171 # only for loop vm image
172 if [ $1 = $loopvm_image_name ]; then
173 export DIB_USE_ELREPO_KERNEL=True
174 export DIB_DEV_IMAGE=loopvm
176 export DIB_USE_ELREPO_KERNEL=False
177 export DIB_DEV_IMAGE=generator
178 # get current git branch to build image with current code
179 export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
180 # retrieve TREX_VER from Dockerfile
181 export TREX_VER=$(awk '/ENV TREX_VER/ {print $3}' ../../docker/Dockerfile | sed 's/"//g' | sed 's/\r//g')
184 # Specify CentOS version
187 # Debug on error: if an error occurs during the build, disk-image-create
188 # will drop us in a Bash inside the chroot, and we will be able to inspect
189 # the current state of the image.
190 if [[ "${DEBUG}" == "yes" ]]; then
191 export break=after-error
194 echo "Building $1.qcow2..."
195 time disk-image-create -o $1 centos nfvbenchvm
200 if [ $verify_only -eq 1 ]; then
201 echo "Image verification SUCCESS"
202 echo "NO upload to google storage (-v)"
204 if command -v gsutil >/dev/null; then
205 echo "Uploading $1.qcow2..."
206 gsutil cp $1.qcow2 gs://$gs_url/$1.qcow2
207 echo "You can access to image at https://$gs_url/$1.qcow2"
209 echo "Cannot upload new image to the OPNFV artifact repository (gsutil not available)"
216 # ----------------------------------------------------------------------------
218 # ----------------------------------------------------------------------------
220 if [ $build_loopvm -eq 1 ]; then
221 echo "Build loop VM image"
222 build_image $loopvm_image_name
225 if [ $build_generator -eq 1 ]; then
226 echo "Build generator image"
228 if [[ "${DIB_NFVBENCH_CODE_ORIGIN}" == "static" ]]; then
229 echo "Use local nfvbench code"
230 copy_local_nfvbench_code_to_static_dir
232 # Append nfvbench version number to the image name:
233 # during development, this is useful to distinguish the development
234 # images from the latest published image.
236 # To avoid confusion, we use the same versioning as nfvbench (see
237 # nfvbench/__init__.py), although "git describe" would give us a better
238 # number with respect to uniqueness. So we will typically get something
239 # like "5.0.4.dev31" where "5.0.4" is the latest annotated tag ("5.0.3")
240 # plus one and where dev31 indicates the number of commits (31) since
242 nfvbench_version=$(python -c 'import pbr.version; print(pbr.version.VersionInfo("nfvbench").version_string_with_vcs())')
243 generator_image_name="${generator_image_name}-${nfvbench_version}"
246 build_image $generator_image_name