Adding required pre-requites libs to build prox VNF
[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 net-tools wget gcc unzip \
179                 libpcap-dev libncurses-dev libedit-dev pciutils liblua5.2-dev libncursesw5-dev
180         touch .download
181 }
182
183 download_dpdk_zip()
184 {
185         echo "Download DPDK zip"
186         file_name=".agree"
187         if [ ! -e "$file_name" ]; then
188                 echo "Please choose option '2.Agree to download' first"
189                 return
190         fi
191         DPDK_DOWNLOAD="http://dpdk.org/browse/dpdk/snapshot/dpdk-$DPDK_RTE_VER.zip"
192         rm -rf $DPDK_DIR
193         if [ ! -e ${DPDK_DOWNLOAD##*/} ] ; then
194                 wget ${DPDK_DOWNLOAD}
195         fi
196         unzip -o ${DPDK_DOWNLOAD##*/}
197         mv $VNF_CORE/dpdk-$DPDK_RTE_VER $VNF_CORE/dpdk
198 }
199
200 install_dpdk()
201 {
202         echo "Build DPDK"
203
204         if [ ! -d "$DPDK_DIR" ]; then
205      echo "Please choose option '4 Download DPDK zip'"
206      return
207         fi
208
209         export RTE_TARGET=x86_64-native-linuxapp-gcc
210
211         pushd $DPDK_DIR
212
213         if [ $DPDK_RTE_VER == "16.04" ] ; then
214                 echo "Apply dpdk custom patches..."
215                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-link-management.patch
216                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch
217                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch
218                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch
219                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/disable-acl-debug-logs.patch
220                         patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/set-log-level-to-info.patch
221         fi
222
223         make -j install T=$RTE_TARGET
224         if [ $? -ne 0 ] ; then
225                 echo "Failed to build dpdk, please check the errors."
226                 return
227         fi
228         sudo modinfo igb_uio
229         if [ $? -ne 0 ] ; then
230                 sudo $MODPROBE -v uio
231                 sudo $INSMOD $RTE_TARGET/kmod/igb_uio.ko
232                 sudo cp -f $RTE_TARGET/kmod/igb_uio.ko /lib/modules/$(uname -r)
233                 echo "uio" | sudo tee -a /etc/modules
234                 echo "igb_uio" | sudo tee -a /etc/modules
235                 sudo depmod
236         fi
237         popd
238 }
239
240 setup_hugepages()
241 {
242         #----
243         Pages=16
244         if [[ "$HUGEPGSZ" = "2048kB" ]] ; then
245                 Pages=8192
246         fi
247         if [ ! "`grep nr_hugepages /etc/sysctl.conf`" ] ; then
248                 echo "vm.nr_hugepages=$Pages" | sudo tee /etc/sysctl.conf
249         fi
250         sudo sysctl -p
251
252         sudo service procps start
253
254         grep -s '/dev/hugepages' /proc/mounts
255         if [ $? -ne 0 ] ; then
256                 echo "Creating /mnt/huge and mounting as hugetlbfs"
257                 sudo mkdir -p /mnt/huge
258                 sudo mount -t hugetlbfs nodev /mnt/huge
259                 echo "nodev /mnt/huge hugetlbfs defaults 0 0" | sudo tee -a /etc/fstab > /dev/null
260         fi
261 }
262
263 step_3()
264 {
265         TITLE="Build VNFs"
266         CONFIG_NUM=1
267                                 TEXT[1]="Build all VNFs (vACL, vCGNAPT, vFW, UDP_Replay)"
268         FUNC[1]="build_vnfs"
269 }
270
271 build_vnfs()
272 {
273
274         if [ ! -d "$DPDK_DIR" ]; then
275      echo "Please choose option '4 Download DPDK zip'"
276      return
277         fi
278
279         if [ ! -d "$DPDK_DIR/x86_64-native-linuxapp-gcc" ]; then
280      echo "Please choose option '5 Build and Install DPDK'"
281      return
282         fi
283
284         export RTE_SDK=$DPDK_DIR
285         export RTE_TARGET=x86_64-native-linuxapp-gcc
286         pushd $VNF_CORE
287         make clean
288         make || { echo -e "\nVNF: Make failed\n"; }
289         popd
290 }
291
292 #--- Add non intractive option to build vnfs
293 if [[ "$1" = "--silient" ]];then
294                 DPDK_VER=("" "16.04" "16.11" "17.02" "17.05")
295                 member="$2"
296                 for item in "${DPDK_VER[@]}"; do
297                           if [[ "$member" == "$item" ]]; then
298                         DPDK_RTE_VER="$member"
299                     fi
300     done
301     pushd $VNF_CORE
302
303     echo "Install required libraries..."
304     touch .agree
305     install_libs
306
307     echo "Download dpdk for VNF build..."
308     download_dpdk_zip
309
310     echo "Build dpdk..."
311     install_dpdk
312
313     echo "Setup hugepages..."
314     setup_hugepages
315
316     echo "build VNFS..."
317     build_vnfs
318
319     popd
320     exit
321 fi
322
323 SETUP_PROXY="setup_http_proxy"
324 STEPS[1]="step_1"
325 STEPS[2]="step_2"
326 STEPS[3]="step_3"
327
328 QUIT=0
329
330 clear
331
332 echo -n "Checking for user permission.. "
333 sudo -n true
334 if [ $? -ne 0 ]; then
335    echo "Password-less sudo user must run this script" 1>&2
336    exit 1
337 fi
338 echo "Done"
339 clear
340
341 while [ "$QUIT" == "0" ]; do
342         OPTION_NUM=1
343         for s in $(seq ${#STEPS[@]}) ; do
344                 ${STEPS[s]}
345
346                 echo "----------------------------------------------------------"
347                 echo " Step $s: ${TITLE}"
348                 echo "----------------------------------------------------------"
349
350                 for i in $(seq ${#TEXT[@]}) ; do
351                         echo "[$OPTION_NUM] ${TEXT[i]}"
352                         OPTIONS[$OPTION_NUM]=${FUNC[i]}
353                         let "OPTION_NUM+=1"
354                 done
355
356                 # Clear TEXT and FUNC arrays before next step
357                 unset TEXT
358                 unset FUNC
359
360                 echo ""
361         done
362
363         echo "[$OPTION_NUM] Exit Script"
364         OPTIONS[$OPTION_NUM]="quit"
365         echo ""
366         echo -n "Option: "
367         read our_entry
368         echo ""
369         ${OPTIONS[our_entry]} ${our_entry}
370
371         if [ "$QUIT" == "0" ] ; then
372                 echo
373                 echo -n "Press enter to continue ..."; read
374                 clear
375                 continue
376                 exit
377         fi
378         echo "Installation successfully complete."
379 done