forked from stevelorenz/comnetsemu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.sh
executable file
·398 lines (339 loc) · 12.7 KB
/
install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
#!/usr/bin/env bash
#
# About: ComNetsEmu Installer
# Email: [email protected]
#
# Fail on error
set -e
# Fail on unset var usage
set -o nounset
# Mininet's installer's default assumption.
if [[ $EUID -eq 0 ]]; then
echo "This installer script should be run as a user with sudo permissions, "
echo "not root (Avoid running all commands in the script with root privilege) !"
echo "Please use bash ./install.sh instead of sudo bash ./install.sh"
exit 1
fi
# Set magic variables for current file & dir
# __dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# __file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
####################
# Util Functions #
####################
msg() {
printf '%b\n' "$1" >&2
}
warning() {
declare _type=$1 text=$2
msg "\033[33mWarning:\033[0m ${_type} ${text}"
}
error() {
declare _type=$1 text=$2
msg "\033[31m[✘]\033[0m ${_type} ${text}"
}
function no_dir_exit() {
declare dir=$1
if [ ! -d "$dir" ]; then
error "[INSTALL]" "Directory: $dir does not exit! Exit."
exit 1
fi
}
function check_patch() {
declare patch_path=$1
declare prefix_num=$2
if patch -p"$prefix_num" --dry-run <"$patch_path"; then
patch -p"$prefix_num" <"$patch_path"
else
error "[PATCH]" "Failed to apply the path file: $patch_path ."
exit 1
fi
}
####################
# Main Installer #
####################
DIST=Unknown
ARCH=$(uname -m)
PYTHON=python3
PIP=pip3
if [[ "$ARCH" == "i686" ]]; then
error "[ARCH]" "i386 is not supported."
exit 1
fi
grep Ubuntu /etc/lsb-release &>/dev/null && DIST="Ubuntu"
if [ "$DIST" = "Ubuntu" ]; then
# Truly non-interactive apt-get installation
install='sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q install'
remove='sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q remove'
# pkginst='sudo dpkg -i'
update='sudo apt-get'
addrepo='sudo add-apt-repository'
# Prereqs for this script
if ! lsb_release -v &>/dev/null; then
$install lsb-release
fi
else
error "[DIST]" "The installer currently ONLY supports Ubuntu 20.04 LTS."
exit 1
fi
echo "*** ComNetsEmu Installer ***"
DEFAULT_REMOTE="origin"
# Get the directory containing comnetsemu source code folder
TOP_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
# The name of the comnetsemu source code folder
COMNETSEMU_SRC_DIR="comnetsemu"
# Directory containing external dependencies installed from source
# Dependencies are downloaded into another directory because the current directory is synced to the vagrant VM by default.
# Clone sources into this directory has privileges conflicts with host OS.
EXTERN_DEP_DIR="$TOP_DIR/comnetsemu_dependencies"
# Include the minimal dependencies (used in examples/applications and require potential updates from upstream)
DEPS_INSTALLED_FROM_SRC=(mininet ryu)
# - Installed from source, versions are tags or branch names of dependencies
# For potential fast fixes, patches and extensions, a mirrrored/synced repo of Mininet is used.
MININET_GIT_URL="https://github.com/mininet/mininet.git"
MININET_VER="2.3.0"
RYU_VER="v4.34"
# ComNetsEmu's dependency python packages are listed in ./requirements.txt.
DEPS_VERSIONS=("$MININET_VER" "$RYU_VER")
DEP_INSTALL_FUNCS=(install_mininet_with_deps install_ryu)
echo " - The default git remote name: $DEFAULT_REMOTE"
echo " - The path of the ComNetsEmu source code: $TOP_DIR/$COMNETSEMU_SRC_DIR"
echo " - The directory to download all dependencies: $EXTERN_DEP_DIR"
function usage() {
printf '\nUsage: %s [-abcdhlnouvy]\n\n' "$(basename "$0")" >&2
echo " - Dependencies are installed with package manager (apt, pip) or from sources (git clone)."
echo " - [] in options are used to mark the version (If the tool is installed from source, the version can be a Git commit, branch or tag.)"
echo ""
echo "Options:"
echo " -a: install ComNetsEmu and (A)ll dependencies - good luck!"
echo " -c: install (C)omNetsEmu Python module and dependency packages."
echo " -d: install (D)ocker CE [stable]."
echo " -h: print usage."
echo " -k: install required Linux (K)ernel modules."
echo " -l: install ComNetsEmu and only (L)ight-weight dependencies."
echo " -n: install mi(N)inet with minimal dependencies from source [$MININET_VER] (Python module, OpenvSwitch, Openflow reference implementation 1.0)"
echo " -r: (R)einstall all dependencies for ComNetsEmu."
echo " -u: (U)pgrade ComNetsEmu's Python package and all dependencies. "
echo " -v: install de(V)elopment tools."
echo " -y: install R(Y)u SDN controller [$RYU_VER]."
exit 2
}
function install_kernel_modules() {
echo "Install wireguard kernel module"
# It is now (07.10.2020) in the official repo.
# sudo add-apt-repository -y ppa:wireguard/wireguard
sudo apt-get update
sudo apt-get install -y linux-headers-"$(uname -r)"
sudo apt-get install -y wireguard
}
function install_docker() {
$update update
$remove docker.io containerd runc
$install docker.io
sudo systemctl start docker
sudo systemctl enable docker
}
function upgrade_docker() {
$update update
$install docker.io
}
function upgrade_pip() {
echo "*** Upgrade $PIP to the latest version."
sudo -H $PIP install -U pip
}
function install_mininet_with_deps() {
local mininet_dir="$EXTERN_DEP_DIR/mininet-$MININET_VER"
local mininet_patch_dir="$TOP_DIR/comnetsemu/patch/mininet"
no_dir_exit "$mininet_patch_dir"
mkdir -p "$mininet_dir"
echo "*** Install Mininet and its minimal dependencies."
$install git net-tools
cd "$mininet_dir" || exit
git clone $MININET_GIT_URL
cd mininet || exit
git checkout -b $MININET_VER $MININET_VER
cd util || exit
if [[ $(lsb_release -rs) == "20.04" ]]; then
echo "cgroups-bin is deprected and the new package is cgroups-tools in mininet install script."
sed -i 's/cgroup-bin/cgroup-tools/g' ./install.sh
else
echo "cgroup-bin still supported in Ubuntu 18.04 and below."
fi
PYTHON=python3 ./install.sh -nfvw03
}
function install_comnetsemu() {
echo "*** Install ComNetsEmu"
$install python3 python3-pip
echo "- Install ComNetsEmu dependency packages."
cd "$TOP_DIR/comnetsemu/util" || exit
sudo -H pip3 install -r ./requirements.txt
echo "- Install ComNetsEmu Python package."
cd "$TOP_DIR/comnetsemu" || exit
sudo PYTHON=python3 make install
}
function upgrade_comnetsemu_deps_python_pkgs() {
echo "- Upgrade ComNetsEmu dependency packages."
cd "$TOP_DIR/comnetsemu/util" || exit
sudo -H pip3 install -r ./requirements.txt
}
function install_ryu() {
local ryu_dir="$EXTERN_DEP_DIR/ryu-$RYU_VER"
mkdir -p "$ryu_dir"
echo "*** Install Ryu SDN controller"
$install git gcc "$PYTHON-dev" libffi-dev libssl-dev libxml2-dev libxslt1-dev zlib1g-dev python3-pip
git clone git://github.com/osrg/ryu.git "$ryu_dir/ryu"
cd "$ryu_dir/ryu" || exit
git checkout -b $RYU_VER $RYU_VER
upgrade_pip
sudo -H $PIP install .
}
function install_devs() {
echo "*** Install tools for development"
$install shellcheck
upgrade_pip
echo "- Install dev python packages via PIP."
sudo -H $PIP install pytest ipdb==0.13.2 coverage==5.1 flake8==3.7.9 flake8-bugbear==20.1.4 pylint==2.5.2 black==19.10b0 pytype==2020.6.1
cd "$TOP_DIR/$COMNETSEMU_SRC_DIR/doc" || exit
echo "- Install packages to build HTML documentation."
sudo -H $PIP install -r ./requirements.txt
}
function upgrade_comnetsemu() {
local dep_name
local installed_ver
local req_ver
warning "[Upgrade]" "Have you checked and merged latest updates of the remote repository? ([y]/n)"
read -r -n 1
if [[ ! $REPLY ]] || [[ $REPLY =~ ^[Yy]$ ]]; then
echo "*** Upgrade ComNetsEmu dependencies, the ComNetsEmu's source repository and Python module are not upgraded."
echo ""
echo "- Upgrade dependencies installed with package manager."
upgrade_docker
install_devs
upgrade_comnetsemu_deps_python_pkgs
echo ""
echo "- Upgrade dependencies installed from source"
echo " The upgrade script checks the version flag (format tool_name-version) in $EXTERN_DEP_DIR"
echo " The installer will install new versions (defined as constant variables in this script) if the version flags are not match."
for ((i = 0; i < ${#DEPS_INSTALLED_FROM_SRC[@]}; i++)); do
dep_name=${DEPS_INSTALLED_FROM_SRC[i]}
echo "Step $i: Check and upgrade ${DEPS_INSTALLED_FROM_SRC[i]}"
installed_ver=$(find "$EXTERN_DEP_DIR" -maxdepth 1 -type d -name "${dep_name}-*" | cut -d '-' -f 2-)
req_ver=${DEPS_VERSIONS[i]}
echo "Installed version: ${installed_ver}, requested version: ${req_ver}"
if [[ "${installed_ver}" != "${req_ver}" ]]; then
warning "[Upgrade]" "Upgrade ${dep_name} from ${installed_ver} to ${req_ver}"
sudo rm -rf "$EXTERN_DEP_DIR/${dep_name}-${installed_ver}"
${DEP_INSTALL_FUNCS[i]}
fi
echo ""
done
echo "- Reinstall ComNetsEmu python package with develop mode."
# Check here (https://stackoverflow.com/questions/19048732/python-setup-py-develop-vs-install)
# for difference between install and develop
cd "$TOP_DIR/$COMNETSEMU_SRC_DIR/" || exit
sudo make develop
echo "- Rebuild test containers if there are changes in their Dockerfiles."
cd "$TOP_DIR/$COMNETSEMU_SRC_DIR/test_containers" || exit
bash ./build.sh
echo "- Run removing unused images. This can reduce the disk usage."
docker image prune
else
error "[Upgrade]" "Please check and merge remote updates before upgrading."
fi
}
function reinstall_comnetsemu_deps() {
echo ""
echo "*** Reinstall ComNetsEmu dependencies."
sudo rm -r "$EXTERN_DEP_DIR"
install_kernel_modules
install_mininet_with_deps
install_ryu
install_docker
install_devs
}
# TODO: Extend remove function for all installed packages
function remove_comnetsemu() {
echo "*** Remove function currently under development"
exit 0
# ISSUE: pip uninstall does not uninstall all dependencies of the packages
echo "*** Remove ComNetsEmu and its dependencies"
warning "[REMOVE]" "Try its best to remove all packages and configuration files, not 100% clean."
echo "Remove Docker and docker-py"
$remove docker.io
sudo -H $PIP uninstall -y docker || true
echo "Remove Mininet"
sudo -H $PIP uninstall -y mininet || true
echo "Remove ComNetsEmu"
sudo -H $PIP uninstall -y comnetsemu || true
echo "Remove Ryu SDN controller"
sudo -H $PIP uninstall -y ryu || true
echo "Remove OVS"
mininet_dir="$EXTERN_DEP_DIR/mininet-$MININET_VER"
mkdir -p "$mininet_dir"
./install.sh -r
cd "$mininet_dir/mininet/util" || exit
echo "Remove dependency folder"
sudo rm -rf "$EXTERN_DEP_DIR"
}
function test_install() {
echo "*** Test installation. Used by ../check_installer.sh script."
install_mininet_with_deps
install_ryu
install_docker
install_devs
install_comnetsemu
}
function install_lightweight() {
echo "*** Install ComNetsEmu with only light weight dependencies"
$update update
install_kernel_modules
install_mininet_with_deps
install_ryu
install_docker
# MUST run at the end!
install_comnetsemu
}
function all() {
echo "*** Install ComNetsEmu and all dependencies"
$update update
install_kernel_modules
install_mininet_with_deps
install_ryu
install_docker
install_devs
# MUST run at the end!
install_comnetsemu
}
# Check if source and dependency directory exits
if [[ ! -d "$TOP_DIR/$COMNETSEMU_SRC_DIR" ]]; then
error "[PATH]" "The ComNetsEmu source directory does not exist."
echo " The default path of the ComNetsEmu source code: $TOP_DIR/$COMNETSEMU_SRC_DIR"
echo " You can change the variable COMNETSEMU_SRC_DIR in the script to use customized directory name"
exit 1
fi
if [[ ! -d "$EXTERN_DEP_DIR" ]]; then
warning "[PATH]" "The default dependency directory does not exist."
echo "Create the dependency directory : $EXTERN_DEP_DIR"
mkdir -p "$EXTERN_DEP_DIR"
fi
if [ $# -eq 0 ]; then
usage
else
while getopts 'abcdhklnrtuvy' OPTION; do
case $OPTION in
a) all ;;
c) install_comnetsemu ;;
d) install_docker ;;
h) usage ;;
k) install_kernel_modules ;;
l) install_lightweight ;;
n) install_mininet_with_deps ;;
r) reinstall_comnetsemu_deps ;;
t) test_install ;;
u) upgrade_comnetsemu ;;
v) install_devs ;;
y) install_ryu ;;
*) usage ;;
esac
done
shift "$((OPTIND - 1))"
fi