blob: 9105fa2877bd4b7ca4b840ed1bf3fd4032a01842 [file] [log] [blame]
Junxiao Shi48ada892021-11-04 09:02:21 -06001# -*- Mode:bash; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
3# Copyright (C) 2015-2021, The University of Memphis,
4# Arizona Board of Regents,
5# Regents of the University of California.
6#
7# This file is part of Mini-NDN.
8# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
9#
10# Mini-NDN is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# Mini-NDN is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with Mini-NDN, e.g., in COPYING.md file.
22# If not, see <http://www.gnu.org/licenses/>.
23
24# needed by Python version detection logic in Mininet & Mininet-WiFi install script
25export PYTHON=python3
26
27# DEP_INFO key should match *_VERSION variable name.
28# DEP_INFO entry should have these comma separated fields:
29# [0] local directory name
30# [1] dep name
31# [2] PPA package name
32# [3] GitHub repository (HTTPS)
33# [4] Gerrit repository (repo name only)
34declare -A DEP_INFO
35DEP_INFO=(
36 ["CXX"]="ndn-cxx,ndn-cxx,libndn-cxx-dev,https://github.com/named-data/ndn-cxx.git,ndn-cxx"
37 ["NFD"]="NFD,NFD,nfd,https://github.com/named-data/NFD.git,NFD"
38 ["PSYNC"]="PSync,PSync,libpsync-dev,https://github.com/named-data/PSync.git,PSync"
39 ["NLSR"]="NLSR,NLSR,nlsr,https://github.com/named-data/NLSR.git,NLSR"
40 ["TOOLS"]="ndn-tools,NDN Essential Tools,ndn-tools,https://github.com/named-data/ndn-tools.git,ndn-tools"
41 ["TRAFFIC"]="ndn-traffic-generator,NDN Traffic Generator,ndn-traffic-generator,https://github.com/named-data/ndn-traffic-generator.git,ndn-traffic-generator"
42 ["INFOEDIT"]="infoedit,infoedit,,https://github.com/NDN-Routing/infoedit.git,"
43 ["MININET"]="mininet,Mininet,,https://github.com/mininet/mininet.git,"
44 ["MNWIFI"]="mininet-wifi,Mininet-WiFi,,https://github.com/intrig-unicamp/mininet-wifi.git,"
45)
46
47# command to detect dependency existence
48# if not specified, dependency is assumed to not exist
49declare -A DEP_DETECT
50DEP_DETECT=(
51 ["CXX"]="pkg-config libndn-cxx"
52 ["NFD"]="command -v nfd"
53 ["PSYNC"]="pkg-config PSync"
54 ["NLSR"]="command -v nlsr"
55 ["TOOLS"]="command -v ndnping && command -v ndncatchunks"
56 ["TRAFFIC"]="command -v ndn-traffic-client"
57 ["INFOEDIT"]="command -v infoedit"
58 ["MININET"]="command -v mn && command -v ofdatapath && $PYTHON -m pip show mininet"
59 ["MNWIFI"]="$PYTHON -m pip show mininet-wifi"
60)
61
62# non-Waf build & install command
63build_INFOEDIT() {
64 make -j${NJOBS}
65 $SUDO make install
66}
67build_MININET() {
68 ./util/install.sh -s ${CODEROOT} -nv
69 if ! command -v ofdatapath >/dev/null; then
70 rm -rf ${CODEROOT}/openflow
71 ./util/install.sh -s ${CODEROOT} -f
72 fi
73
74 $SUDO $PYTHON setup.py develop
75 $SUDO cp /usr/local/bin/mn /usr/local/bin/mn.mininet
76}
77build_MNWIFI() {
78 # issue: util/install.sh attempts to patch hostap every time, causing "Assume -R?" prompt
79 # during reinstalls
80 # workaround: revert hostap repository to clean state
81 $SUDO git -C hostap clean -fdx || true
82 $SUDO git -C hostap checkout -- . || true
83
84 # issue: util/install.sh is not using 'sudo' where needed
85 # solution: run whole script in 'sudo'
86 $SUDO env PYTHON="$PYTHON" ./util/install.sh -Wl
87
88 # issue: setup.py reports "Cannot load backend 'TkAgg' which requires the 'tk' interactive
89 # framework, as 'headless' is currently running" when running over SSH
90 # workaround: pretend to have X11 display
91 $SUDO env DISPLAY=:0 $PYTHON setup.py develop
92 $SUDO cp /usr/local/bin/mn /usr/local/bin/mn.wifi
93
94 # make 'mn' command refer to Mininet's version, which does not require X11
95 if [[ -x /usr/local/bin/mn.mininet ]]; then
96 $SUDO cp /usr/local/bin/mn.mininet /usr/local/bin/mn
97 fi
98}
99
100# Waf configure options
101declare -A DEP_WAFOPTS
102DEP_WAFOPTS=(
103 ["NFD"]="--without-websocket"
104 ["PSYNC"]="--with-examples"
105)
106
107# return whether dep is installed
108dep_exists() {
109 if [[ $IGNORE_EXISTING -eq 1 ]]; then
110 return 2
111 fi
112 local DETECT="${DEP_DETECT[$1]}"
113 if [[ -n $DETECT ]] && bash -c "$DETECT" &>/dev/null; then
114 return 0
115 fi
116 return 1
117}
118
119# set to 1 if dep needs downloading
120declare -A NEED_DL
121
122# display prompt on what to do with dep, populate NEED_DL
123dep_prompt() {
124 local INFO=()
125 IFS=',' read -a INFO <<< "${DEP_INFO[$1]}"
126 local VERSION_VAR="$1_VERSION"
127 local VERSION="${!VERSION_VAR}"
128 if [[ -z $VERSION ]]; then
129 VERSION='(default branch)'
130 fi
131 local DLDIR="${CODEROOT}/${INFO[0]}"
132 if dep_exists $1; then
133 echo "Will use existing ${INFO[1]}"
134 elif [[ $PREFER_FROM == ppa ]] && [[ -n ${INFO[2]} ]]; then
135 echo "Will install ${INFO[1]} from named-data PPA"
136 PPA_PKGS+=("${INFO[2]}")
137 elif [[ -d "$DLDIR" ]]; then
138 if [[ $DL_ONLY -ne 1 ]]; then
139 echo "Will install ${INFO[1]} from local checkout ${DLDIR}"
140 fi
141 else
142 NEED_DL[$1]=1
143 if [[ $DL_ONLY -eq 1 ]]; then
144 echo "Will checkout ${INFO[1]} ${VERSION} to ${DLDIR}"
145 else
146 echo "Will download and install ${INFO[1]} ${VERSION}"
147 fi
148 fi
149}
150
151# download dep source code
152dep_checkout() {
153 if [[ ${NEED_DL[$1]} -ne 1 ]]; then
154 return
155 fi
156 local INFO=()
157 IFS=',' read -a INFO <<< "${DEP_INFO[$1]}"
158 local VERSION_VAR="$1_VERSION"
159 local VERSION="${!VERSION_VAR}"
160 local DLDIR="${CODEROOT}/${INFO[0]}"
161
162 if [[ -n ${INFO[4]} ]] && [[ "$VERSION" =~ ^[0-9]+,[0-9]+$ ]]; then
163 local REPO="https://gerrit.named-data.net/${INFO[4]}"
164 local GERRIT_CHANGE=${VERSION%,*}
165 local GERRIT_PATCHSET=${VERSION#*,}
166 echo "Downloading ${INFO[2]} from Gerrit (patchset ${GERRIT_CHANGE},${GERRIT_PATCHSET})"
167 git clone "$REPO" "$DLDIR"
168 git -C "$DLDIR" fetch origin "refs/changes/${GERRIT_CHANGE:(-2)}/${GERRIT_CHANGE}/${GERRIT_PATCHSET}"
169 git -C "$DLDIR" -c advice.detachedHead=false checkout FETCH_HEAD
170 elif [[ -z $VERSION ]]; then
171 echo "Downloading ${INFO[1]} from GitHub (default branch)"
172 git clone "${INFO[3]}" "$DLDIR"
173 elif [[ "$VERSION" =~ @ ]]; then
174 local REPO=${VERSION%@*}
175 local BRANCH=${VERSION#*@}
176 echo "Downloading ${INFO[1]} from ${REPO} (branch ${BRANCH})"
177 git clone "$REPO" "$DLDIR"
178 git -C "$DLDIR" -c advice.detachedHead=false checkout "$BRANCH"
179 else
180 echo "Downloading ${INFO[1]} from GitHub (branch ${VERSION})"
181 git clone "${INFO[3]}" "$DLDIR"
182 git -C "$DLDIR" -c advice.detachedHead=false checkout "$VERSION"
183 fi
184 git submodule update --init --recursive --progress
185}
186
187# install dep from source code
188dep_install() {
189 local INFO=()
190 IFS=',' read -a INFO <<< "${DEP_INFO[$1]}"
191 local DLDIR="${CODEROOT}/${INFO[0]}"
192 if dep_exists $1 || ! [[ -d "$DLDIR" ]]; then
193 return
194 fi
195 pushd "$DLDIR"
196
197 local FN="build_$1"
198 if declare -F $FN >/dev/null; then
199 echo "Installing ${INFO[1]} with custom command"
200 $FN
201 elif [[ -x waf ]]; then
202 echo "Installing ${INFO[1]} with Waf"
203 $PYTHON ./waf configure ${DEP_WAFOPTS[$1]}
204 $PYTHON ./waf -j${NJOBS}
205 $SUDO $PYTHON ./waf install
206 fi
207 popd
208}
209
210if [[ $PPA_AVAIL -ne 1 ]] || [[ $NO_PPA -eq 1 ]]; then
211 PREFER_FROM=source
212fi
213
214# dep install order, excluding ndn-cxx
215DEPLIST=(NFD PSYNC NLSR TOOLS TRAFFIC INFOEDIT MININET)
216if [[ $NO_WIFI -ne 1 ]]; then
217 DEPLIST+=(MNWIFI)
218fi
219
220echo "Will download to ${CODEROOT}"
221echo 'Will install compiler and build tools'
222dep_prompt CXX
223if [[ $CXX_DUMMY_KEYCHAIN -eq 1 ]]; then
224 echo 'Will patch ndn-cxx to use dummy KeyChain'
225fi
226for DEP in "${DEPLIST[@]}"; do
227 dep_prompt $DEP
228done
229if [[ $DL_ONLY -ne 1 ]]; then
230 echo "Will compile with ${NJOBS} parallel jobs"
231 echo "Will install Mini-NDN package"
232fi
233
234if [[ $CONFIRM -ne 1 ]]; then
235 read -p 'Press ENTER to continue or CTRL+C to abort '
236fi
237
238install_pkgs
239
240if [[ -z $SKIPPYTHONCHECK ]]; then
241 PYTHON_VERSION=$($PYTHON --version)
242 SUDO_PYTHON_VERSION=$($SUDO $PYTHON --version)
243 if [[ "$PYTHON_VERSION" != "$SUDO_PYTHON_VERSION" ]]; then
244 cat <<EOT
245In your system, '${PYTHON}' is ${PYTHON_VERSION} and '$SUDO ${PYTHON}' is ${SUDO_PYTHON_VERSION}
246You must manually resolve the conflict, e.g. delete excess Python installation or change $PATH
247To bypass this check, set the environment variable SKIPPYTHONCHECK=1
248EOT
249 exit 1
250 fi
251fi
252
253if ! mkdir -p "${CODEROOT}" 2>/dev/null; then
254 $SUDO mkdir -p "${CODEROOT}"
255 $SUDO chown $(id -u) "${CODEROOT}"
256fi
257dep_checkout CXX
258if [[ $CXX_DUMMY_KEYCHAIN -eq 1 ]]; then
259 echo 'Patching ndn-cxx to use dummy KeyChain'
260 if ! git -C "${CODEROOT}/ndn-cxx" apply --index < "${PKGDEPDIR}/../patches/ndn-cxx-dummy-keychain.patch"; then
261 echo 'Cannot patch ndn-cxx to use dummy KeyChain (possibly already patched)'
262 fi
263fi
264for DEP in "${DEPLIST[@]}"; do
265 dep_checkout $DEP
266done
267
268if [[ $DL_ONLY -eq 1 ]]; then
269 cat <<EOT
270Source code has been downloaded to ${CODEROOT}
271You may make changes or checkout different versions
272Run this script again without --dl-only to install from local checkout
273EOT
274 exit 0
275fi
276
277prepare_ld
278for DEP in CXX "${DEPLIST[@]}"; do
279 dep_install $DEP
280done
281$SUDO ldconfig
282
283DESTDIR=/usr/local/etc/mini-ndn
284$SUDO install -d -m0755 "$DESTDIR"
285find topologies/ -name '*.conf' | xargs $SUDO install -m0644 -t "$DESTDIR/"
286$SUDO $PYTHON setup.py develop
287
288echo 'MiniNDN installation completed successfully'