nfvbenchvm: add option to use local nfvbench code
[nfvbench.git] / nfvbenchvm / dib / build-image.sh
1 #!/bin/bash
2 #
3 # A shell script to build the VPP VM image or NFVbench+TRex VM image using diskinage-builder
4 #
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
8
9 # Stop on error (see https://wizardzines.com/comics/bash-errors/)
10 set -euo pipefail
11
12 DEBUG=no
13 verify_only=0
14 build_generator=0
15 build_loopvm=0
16 __prefix__=""
17
18 # Artifact URL
19 gs_url=artifacts.opnfv.org/nfvbench/images
20
21 # image version number
22 __version__=0.15
23 loopvm_image_name=nfvbenchvm_centos-$__version__
24 generator_image_name=nfvbenchvm_centos-generator-$__version__
25
26 # Default values for nfvbenchvm dib element variables
27 export DIB_NFVBENCH_CODE_ORIGIN=opnfv-gerrit
28
29
30 # ----------------------------------------------------------------------------
31 # Parse command line options and configure the script
32 # ----------------------------------------------------------------------------
33
34 usage() {
35     cat <<EOF
36 $(basename $0) - build NFVbench VM images
37 Usage:
38     $(basename $0) [OPTIONS]
39
40 OPTIONS
41     -l: build NFVbench loop VM image
42     -g: build NFVbench generator image
43     -v: verify only (build but do not push to google storage)
44     -s: use local nfvbench code instead of cloning from OPNFV gerrit
45         (only relevant for NFVbench generator image)
46
47     -t: enable debug trace (set -x + DIB_DEBUG_TRACE=1)
48     -d: start debug shell in image chroot in case of build error
49     -h: show this help message
50 EOF
51     exit 1
52 }
53
54 while getopts ":lgvstdh" opt; do
55     case $opt in
56         l)
57             build_loopvm=1
58             ;;
59         g)
60             build_generator=1
61             ;;
62         v)
63             verify_only=1
64             ;;
65         s)
66             export DIB_NFVBENCH_CODE_ORIGIN=static
67             ;;
68         t)
69             set -x
70             export DIB_DEBUG_TRACE=1
71             ;;
72         d)
73             DEBUG=yes
74             ;;
75         h)
76             usage
77             exit 0
78             ;;
79         ?)
80             usage
81             exit 1
82             ;;
83     esac
84 done
85
86
87 # Build all VM images if the image to build is not specified on the CLI
88 if [[ $build_generator -eq 0 ]] && [[ $build_loopvm -eq 0 ]]; then
89     build_generator=1
90     build_loopvm=1
91 fi
92
93 if [[ "${DIB_NFVBENCH_CODE_ORIGIN}" == "static" ]] && [[ $build_generator -eq 0 ]]; then
94     echo "Error: option -s is only relevant to the build of the generator image"
95     exit 1
96 fi
97
98
99 # ----------------------------------------------------------------------------
100 # Copy local nfvbench code to elements/nfvbenchvm/static/opt/nfvbench
101 # ----------------------------------------------------------------------------
102
103 function copy_local_nfvbench_code_to_static_dir {
104     echo "Copy local nfvbench code to elements/nfvbenchvm/static/opt"
105     # Create elements/nfvbenchvm/static/opt/ directory if it does not exist and
106     # move there
107     pushd $(dirname $0)/elements/nfvbenchvm/static
108     [ -d opt ] || mkdir opt
109     cd opt
110
111     # Remove nfvbench code if it is already there
112     [ -d nfvbench ] && rm -rf nfvbench
113
114     # Use git to "copy" the local nfvbench code.
115     # This will include all the committed changes of the current branch.
116     git clone ../../../../../.. nfvbench
117
118     # Go back to the current directory when this function was called
119     popd
120 }
121
122
123 # ----------------------------------------------------------------------------
124 # Configure and start the nfvbenchvm image build
125 # ----------------------------------------------------------------------------
126
127 function build_image {
128     # if image exists skip building
129     echo "Checking if image exists in google storage..."
130     if  command -v gsutil >/dev/null; then
131        if gsutil -q stat gs://$gs_url/$1.qcow2; then
132            echo "Image already exists at http://$gs_url/$1.qcow2"
133            echo "Build is skipped"
134            exit 0
135        fi
136        echo "Image does not exist in google storage, starting build..."
137        echo
138     else
139        echo "Cannot check image availability in OPNFV artifact repository (gsutil not available)"
140     fi
141
142     # check if image is already built locally
143     if [ -f $1.qcow2 ]; then
144         echo "Image $1.qcow2 already exists locally"
145     else
146         # install diskimage-builder
147         if [ -d dib-venv ]; then
148            . dib-venv/bin/activate
149         else
150            python3 -m venv dib-venv
151            . dib-venv/bin/activate
152            pip install diskimage-builder==3.16.0
153         fi
154
155         # Add nfvbenchvm_centos elements directory to the DIB elements path
156         export ELEMENTS_PATH=`pwd`/elements
157
158         # canned user/password for direct login
159         export DIB_DEV_USER_USERNAME=nfvbench
160         export DIB_DEV_USER_PASSWORD=nfvbench
161         export DIB_DEV_USER_PWDLESS_SUDO=Y
162
163         # Set the data sources to have ConfigDrive only
164         export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive"
165
166         # Configure VPP REPO
167         export DIB_YUM_REPO_CONF=$ELEMENTS_PATH/nfvbenchvm/fdio-release.repo
168
169         # Use ELRepo to have latest kernel
170         # only for loop vm image
171         if [ $1 = $loopvm_image_name ]; then
172            export DIB_USE_ELREPO_KERNEL=True
173            export DIB_DEV_IMAGE=loopvm
174         else
175            export DIB_USE_ELREPO_KERNEL=False
176            export DIB_DEV_IMAGE=generator
177            # get current git branch to build image with current code
178            export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
179            # retrieve TREX_VER from Dockerfile
180            export TREX_VER=$(awk '/ENV TREX_VER/ {print $3}' ../../docker/Dockerfile | sed 's/"//g' | sed 's/\r//g')
181         fi
182
183         # Specify CentOS version
184         export DIB_RELEASE=7
185
186         # Debug on error: if an error occurs during the build, disk-image-create
187         # will drop us in a Bash inside the chroot, and we will be able to inspect
188         # the current state of the image.
189         if [[ "${DEBUG}" == "yes" ]]; then
190             export break=after-error
191         fi
192
193         echo "Building $1.qcow2..."
194         time disk-image-create -o $1 centos nfvbenchvm
195     fi
196
197     ls -l $1.qcow2
198
199     if [ $verify_only -eq 1 ]; then
200         echo "Image verification SUCCESS"
201         echo "NO upload to google storage (-v)"
202     else
203         if command -v gsutil >/dev/null; then
204             echo "Uploading $1.qcow2..."
205             gsutil cp $1.qcow2 gs://$gs_url/$1.qcow2
206             echo "You can access to image at http://$gs_url/$1.qcow2"
207         else
208             echo "Cannot upload new image to the OPNFV artifact repository (gsutil not available)"
209             exit 1
210         fi
211     fi
212 }
213
214
215 # ----------------------------------------------------------------------------
216 # Main program
217 # ----------------------------------------------------------------------------
218
219 if [ $build_loopvm -eq 1 ]; then
220     echo "Build loop VM image"
221     build_image $loopvm_image_name
222 fi
223
224 if [ $build_generator -eq 1 ]; then
225     echo "Build generator image"
226
227     if [[ "${DIB_NFVBENCH_CODE_ORIGIN}" == "static" ]]; then
228         echo "Use local nfvbench code"
229         copy_local_nfvbench_code_to_static_dir
230
231         # Append nfvbench version number to the image name:
232         # during development, this is useful to distinguish the development
233         # images from the latest published image.
234         #
235         # To avoid confusion, we use the same versioning as nfvbench (see
236         # nfvbench/__init__.py), although "git describe" would give us a better
237         # number with respect to uniqueness.  So we will typically get something
238         # like "5.0.4.dev31" where "5.0.4" is the latest annotated tag ("5.0.3")
239         # plus one and where dev31 indicates the number of commits (31) since
240         # that tag.
241         nfvbench_version=$(python -c 'import pbr.version; print(pbr.version.VersionInfo("nfvbench").version_string_with_vcs())')
242         generator_image_name="${generator_image_name}-${nfvbench_version}"
243     fi
244
245     build_image $generator_image_name
246 fi