tools: Support multiple version of DPDK build
[samplevnf.git] / tools / vnf_build.sh
1 #! /bin/bash
2 #
3 # Copyright (c) 2017 Intel Corporation
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 cd $(dirname ${BASH_SOURCE[0]})/..
19 export VNF_CORE=$PWD
20 echo "------------------------------------------------------------------------------"
21 echo " VNF_CORE exported as $VNF_CORE"
22 echo "------------------------------------------------------------------------------"
23
24 HUGEPGSZ=`cat /proc/meminfo  | grep Hugepagesize | cut -d : -f 2 | tr -d ' '`
25 MODPROBE="/sbin/modprobe"
26 INSMOD="/sbin/insmod"
27 DPDK_DOWNLOAD="Not initialized"
28 DPDK_DIR=$VNF_CORE/dpdk
29 DPDK_RTE_VER="16.04"
30
31 #
32 # Sets QUIT variable so script will finish.
33 #
34 quit()
35 {
36         QUIT=$1
37 }
38
39 # Shortcut for quit.
40 q()
41 {
42         quit
43 }
44
45 setup_http_proxy()
46 {
47         while true; do
48                 echo
49                 read -p "Enter Proxy : " proxy
50                 export http_proxy=$proxy
51                 export https_proxy=$proxy
52                 echo "Acquire::http::proxy \"$http_proxy\";" | sudo tee -a /etc/apt/apt.conf > /dev/null
53                 echo "Acquire::https::proxy \"$http_proxy\";" | sudo tee -a /etc/apt/apt.conf > /dev/null
54
55                 wget -T 20 -t 3 --spider http://www.google.com > /dev/null 2>&1
56                 if [ "$?" != 0 ]; then
57                         echo -e "No Internet connection. Proxy incorrect? Try again"
58                         echo -e "eg: http://<proxy>:<port>"
59                         exit 1
60                 fi
61         return
62         done
63         echo "Network connectivity successful."
64 }
65
66 step_1()
67 {
68         TITLE="Environment setup."
69         CONFIG_NUM=1
70         TEXT[1]="Check OS and network connection"
71         FUNC[1]="setup_env"
72         TEXT[2]="Select DPDK RTE version"
73         FUNC[2]="select_dpdk_rte_ver"
74 }
75 setup_env()
76 {
77         # a. Check for OS dependencies
78         source /etc/os-release
79         if [[ $VERSION_ID != "16.04" ]] ; then
80                 echo "WARNING: It is recommended to use Ubuntu 16.04..Your version is "$VERSION_ID
81         else
82                 echo "Ubuntu 16.04 OS requirement met..."
83         fi
84         echo
85         echo "Checking network connectivity..."
86         # b. Check for internet connections
87         wget -T 20 -t 3 --spider http://www.google.com > /dev/null 2>&1
88         if [ "$?" != 0 ]; then
89                 while true; do
90                         read -p "No Internet connection. Are you behind a proxy (y/n)? " yn
91                         case $yn in
92                                 [Yy]* ) $SETUP_PROXY ; return;;
93                                 [Nn]* ) echo "Please check your internet connection..." ; exit;;
94                                 * ) "Please answer yes or no.";;
95                         esac
96                 done
97         fi
98         echo "Network connectivity successful."
99 }
100 select_dpdk_rte_ver()
101 {
102
103         TITLE="Select the DPDK RTE version"
104         CONFIG_NUM=1
105         echo "[1] DPDK 16.04"
106         echo "[2] DPDK 16.11"
107         echo "[3] DPDK 17.02"
108         echo "[4] DPDK 17.05"
109         echo
110
111         while true; do
112                 read -p "Select DPDK version to be used: " yn
113                         case $yn in
114                                 [1]* ) DPDK_RTE_VER=16.04 ; return;;
115                                 [2]* ) DPDK_RTE_VER=16.11 ; return;;
116                                 [3]* ) DPDK_RTE_VER=17.02 ; return;;
117                                 [4]* ) DPDK_RTE_VER=17.05 ; return;;
118                                 * ) echo " Invalid selection...";;
119                         esac
120         done
121 }
122
123 step_2()
124 {
125         TITLE="Download and Install"
126         CONFIG_NUM=1
127         TEXT[1]="Agree to download"
128         FUNC[1]="get_agreement_download"
129         TEXT[2]="Download packages"
130         FUNC[2]="install_libs"
131         TEXT[3]="Download DPDK zip"
132         FUNC[3]="download_dpdk_zip"
133         TEXT[4]="Build and Install DPDK"
134         FUNC[4]="install_dpdk"
135         TEXT[5]="Setup hugepages"
136         FUNC[5]="setup_hugepages"
137 }
138 get_agreement_download()
139 {
140         echo
141         echo "List of packages needed for VNFs build and installation:"
142         echo "-------------------------------------------------------"
143         echo "1. DPDK version $DPDK_RTE_VER"
144         echo "2. build-essential"
145         echo "3. linux-headers-generic"
146         echo "4. git"
147         echo "5. unzip"
148         echo "6. libpcap-dev"
149         echo "7. make"
150         echo "8. and other library dependencies"
151         while true; do
152                 read -p "We need download above mentioned package. Press (y/n) to continue? " yn
153                 case $yn in
154                         [Yy]* )
155                                 touch .agree
156                                 return;;
157                         [Nn]* ) exit;;
158                         * ) "Please answer yes or no.";;
159                 esac
160         done
161 }
162
163 install_libs()
164 {
165         echo "Install libs needed to build and run VNFs..."
166         file_name=".agree"
167         if [ ! -e "$file_name" ]; then
168                 echo "Please choose option '2.Agree to download' first"
169                 return
170         fi
171         file_name=".download"
172         if [ -e "$file_name" ]; then
173                 clear
174                 return
175         fi
176         sudo apt-get update
177         sudo apt-get -y install build-essential linux-headers-$(uname -r) git unzip libpcap0.8-dev gcc \
178                 make libc6 libc6-dev g++-multilib libzmq3-dev libcurl4-openssl-dev
179         touch .download
180 }
181
182 download_dpdk_zip()
183 {
184         echo "Download DPDK zip"
185         file_name=".agree"
186         if [ ! -e "$file_name" ]; then
187                 echo "Please choose option '2.Agree to download' first"
188                 return
189         fi
190         DPDK_DOWNLOAD="http://dpdk.org/browse/dpdk/snapshot/dpdk-$DPDK_RTE_VER.zip"
191         rm -rf $DPDK_DIR
192         if [ ! -e ${DPDK_DOWNLOAD##*/} ] ; then
193                 wget ${DPDK_DOWNLOAD}
194         fi
195         unzip -o ${DPDK_DOWNLOAD##*/}
196         mv $VNF_CORE/dpdk-$DPDK_RTE_VER $VNF_CORE/dpdk
197 }
198
199 install_dpdk()
200 {
201         echo "Build DPDK"
202
203         if [ ! -d "$DPDK_DIR" ]; then
204      echo "Please choose option '4 Download DPDK zip'"
205      return
206         fi
207
208         export RTE_TARGET=x86_64-native-linuxapp-gcc
209
210         pushd $DPDK_DIR
211
212         if [ $DPDK_RTE_VER == "16.04" ] ; then
213                 echo "Apply dpdk custom patches..."
214                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-link-management.patch
215                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch
216                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch
217                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch
218                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/disable-acl-debug-logs.patch
219                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/set-log-level-to-info.patch
220         fi
221
222         make -j install T=$RTE_TARGET
223         if [ $? -ne 0 ] ; then
224                 echo "Failed to build dpdk, please check the errors."
225                 return
226         fi
227         sudo modinfo igb_uio
228         if [ $? -ne 0 ] ; then
229                 sudo $MODPROBE -v uio
230                 sudo $INSMOD $RTE_TARGET/kmod/igb_uio.ko
231                 sudo cp -f $RTE_TARGET/kmod/igb_uio.ko /lib/modules/$(uname -r)
232                 echo "uio" | sudo tee -a /etc/modules
233                 echo "igb_uio" | sudo tee -a /etc/modules
234                 sudo depmod
235         fi
236         popd
237 }
238
239 setup_hugepages()
240 {
241         #----
242         Pages=16
243         if [[ "$HUGEPGSZ" = "2048kB" ]] ; then
244                 Pages=8192
245         fi
246         if [ ! "`grep nr_hugepages /etc/sysctl.conf`" ] ; then
247                 echo "vm.nr_hugepages=$Pages" | sudo tee /etc/sysctl.conf
248         fi
249         sudo sysctl -p
250
251         sudo service procps start
252
253         grep -s '/dev/hugepages' /proc/mounts
254         if [ $? -ne 0 ] ; then
255                 echo "Creating /mnt/huge and mounting as hugetlbfs"
256                 sudo mkdir -p /mnt/huge
257                 sudo mount -t hugetlbfs nodev /mnt/huge
258                 echo "nodev /mnt/huge hugetlbfs defaults 0 0" | sudo tee -a /etc/fstab > /dev/null
259         fi
260 }
261
262 step_3()
263 {
264         TITLE="Build VNFs"
265         CONFIG_NUM=1
266                                 TEXT[1]="Build all VNFs (vACL, vCGNAPT, vFW, UDP_Replay)"
267         FUNC[1]="build_vnfs"
268 }
269
270 build_vnfs()
271 {
272
273         if [ ! -d "$DPDK_DIR" ]; then
274      echo "Please choose option '4 Download DPDK zip'"
275      return
276         fi
277
278         if [ ! -d "$DPDK_DIR/x86_64-native-linuxapp-gcc" ]; then
279      echo "Please choose option '5 Build and Install DPDK'"
280      return
281         fi
282
283         export RTE_SDK=$DPDK_DIR
284         export RTE_TARGET=x86_64-native-linuxapp-gcc
285         pushd $VNF_CORE
286         make clean
287         make || { echo -e "\nVNF: Make failed\n"; }
288         popd
289 }
290
291 #--- Add non intractive option to build vnfs
292 if [[ "$1" = "--silient" ]];then
293     pushd $VNF_CORE
294
295     echo "Setup proxy if needed..."
296     http_proxy=$2
297     https_proxy=$3
298     if [[ "$http_proxy" != "" ]]; then
299          export http_proxy=$http_proxy
300          export https_proxy=$http_proxy
301     fi
302
303     if [[ "$https_proxy" != "" ]]; then
304          export https_proxy=$https_proxy
305     fi
306
307     echo "Install required libraries..."
308     touch .agree
309     install_libs
310
311     echo "Download dpdk for VNF build..."
312     download_dpdk_zip
313
314     echo "Build dpdk..."
315     install_dpdk
316
317     echo "Setup hugepages..."
318     setup_hugepages
319
320     echo "build VNFS..."
321     build_vnfs
322
323     popd
324     exit
325 fi
326
327 SETUP_PROXY="setup_http_proxy"
328 STEPS[1]="step_1"
329 STEPS[2]="step_2"
330 STEPS[3]="step_3"
331
332 QUIT=0
333
334 clear
335
336 echo -n "Checking for user permission.. "
337 sudo -n true
338 if [ $? -ne 0 ]; then
339    echo "Password-less sudo user must run this script" 1>&2
340    exit 1
341 fi
342 echo "Done"
343 clear
344
345 while [ "$QUIT" == "0" ]; do
346         OPTION_NUM=1
347         for s in $(seq ${#STEPS[@]}) ; do
348                 ${STEPS[s]}
349
350                 echo "----------------------------------------------------------"
351                 echo " Step $s: ${TITLE}"
352                 echo "----------------------------------------------------------"
353
354                 for i in $(seq ${#TEXT[@]}) ; do
355                         echo "[$OPTION_NUM] ${TEXT[i]}"
356                         OPTIONS[$OPTION_NUM]=${FUNC[i]}
357                         let "OPTION_NUM+=1"
358                 done
359
360                 # Clear TEXT and FUNC arrays before next step
361                 unset TEXT
362                 unset FUNC
363
364                 echo ""
365         done
366
367         echo "[$OPTION_NUM] Exit Script"
368         OPTIONS[$OPTION_NUM]="quit"
369         echo ""
370         echo -n "Option: "
371         read our_entry
372         echo ""
373         ${OPTIONS[our_entry]} ${our_entry}
374
375         if [ "$QUIT" == "0" ] ; then
376                 echo
377                 echo -n "Press enter to continue ..."; read
378                 clear
379                 continue
380                 exit
381         fi
382         echo "Installation successfully complete."
383 done