-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathinstall-netkit-jh.sh
378 lines (305 loc) · 11.5 KB
/
install-netkit-jh.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
#!/usr/bin/env bash
# Copyright 2020-2022 Max Barstow, Adam Bromiley, Edwin Foudil, Joshua
# Hawking, Peter Norris - Warwick Manufacturing Group, University of
# Warwick.
#
# This file is part of Netkit.
#
# Netkit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Netkit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Netkit. If not, see <http://www.gnu.org/licenses/>.
# Download and install Netkit-JH in the user's home directory.
###############################################################################
# Write install-netkit-jh's usage line to standard output.
# Usage:
# usage_line
###############################################################################
usage_line() {
echo "Usage: $SCRIPTNAME [OPTION]..."
}
###############################################################################
# Write install-netkit-jh's usage as a full dialog or a "try --help".
# Usage:
# usage STATUS
# Arguments:
# $1 - status code to exit with. When zero, usage will write to standard
# output and describe all options (for --help). Else, it will write to
# standard error and be a brief usage and try-help message.
# Returns:
# None - exits with a status code of STATUS
###############################################################################
usage() {
local status=$1
if [ "$status" -ne 0 ]; then
usage_line 1>&2
try_help
exit "$status"
fi
cat << END_OF_HELP
$(usage_line)
Install Netkit-JH $nk_version.
By default, the pre-built core of Netkit and its filesystem and kernel is
downloaded from the project's GitHub repository to the system's /tmp directory.
The archives are then extracted to the Netkit install directory
(\$HOME/netkit-jh/) and the shell's rc file is set accordingly to add the
install to PATH.
--backup-dir=DIR path to store a backup of the existing Netkit
installation
--download-dir=DIR download directory
--download-url=URL specify the directory to download the files from
as a URL
--no-download do not download pre-built Netkit modules if they are not
found inside the download directory
--no-packages do not download dependencies from APT
--target-dir=DIR directory to install Netkit to
For development purposes, the user may already have the pre-built components on
their system. The following options are provided for such a scenario (note that
DIR should be structured as if it were the install directory. As an example,
when using the --kernel-files option DIR must have a subdirectory named
kernel/):
--core-files=DIR path to core files if they have already been downloaded
and extracted
--fs-files=DIR path to filesystem files if they have already been
downloaded and extracted
--kernel-files=DIR path to kernel files if they have already been
downloaded and extracted
Miscellaneous:
$(help_option)
$(version_option)
END_OF_HELP
exit "$status"
}
# Exit on a failed (non-zero return code) install command
set -e
SCRIPTNAME=$(basename -- "$0")
# ANSI color escape sequences
color_normal=$'\033[0m'
color_bold=$'\033[1m'
# Variable is initialised by Makefile
nk_version="VERSION_NUMBER"
install_dir="$HOME/netkit-jh"
backup_dir="$install_dir-$(date '+%F_%H-%M-%S')"
download_dir="/tmp"
download_url="https://github.com/netkit-jh/netkit-jh-build/releases/download/$nk_version/"
# Get command line options
long_opts="backup-dir:,core-files:,download-dir:,download-url:,fs-files:,help,\
kernel-files:,no-download,no-packages,target-dir:"
short_opts=""
if ! getopt_opts=$(getopt --name "$SCRIPTNAME" --options "$short_opts" --longoptions "$long_opts" -- "$@"); then
# getopt will output the errorneous command-line argument
usage 1
fi
# (Safely) set positional parameters to those reordered by getopt
eval set -- "$getopt_opts"
while true; do
case $1 in
--backup-dir)
backup_dir=$(readlink --canonicalize-missing -- "$2")
shift
;;
--core-files)
existing_core_files=$(readlink --canonicalize-missing -- "$2")
shift
;;
--download-dir)
download_dir=$(readlink --canonicalize-missing -- "$2")
shift
;;
--download-url)
download_url=$2
shift
;;
--fs-files)
existing_fs_files=$(readlink --canonicalize-missing -- "$2")
shift
;;
--help)
usage 0
;;
--kernel-files)
existing_kernel_files=$(readlink --canonicalize-missing -- "$2")
shift
;;
--no-download)
no_download=1
;;
--no-packages)
no_packages=1
;;
--target-dir)
install_dir=$(readlink --canonicalize-missing -- "$2")
shift
;;
--version)
echo "Netkit version: $nk_version"
exit 0
;;
--)
shift
break
;;
*)
echo 1>&2 "$SCRIPTNAME: Unknown error parsing command line arguments"
usage 1
;;
esac
shift
done
# Check for further arguments
if [ $# -gt 0 ]; then
echo 1>&2 "$SCRIPTNAME: Too many arguments"
usage 1
fi
if [ -d "$install_dir/" ]; then
# Backup existing directory
echo "$install_dir: Directory exists; renaming to $backup_dir so contents are not disturbed"
mv -- "$install_dir/" "$backup_dir/"
else
unset backup_dir
fi
mkdir --parents -- "$install_dir"
# Check whether they've specified extracted files
if [ -n "$existing_kernel_files" ] && [ -n "$existing_fs_files" ] && [ -n "$existing_core_files" ]; then
cp --archive -- "$existing_kernel_files/." "$install_dir/"
cp --archive -- "$existing_fs_files/." "$install_dir/"
cp --archive -- "$existing_core_files/." "$install_dir/"
else
release_files_sha256="release-$nk_version.sha256"
release_files=(
"netkit-core-$nk_version.tar.bz2"
"netkit-fs-$nk_version.tar.bz2"
"netkit-kernel-$nk_version.tar.bz2"
)
mkdir --parents -- "$download_dir"
for file in "${release_files[@]}" "$release_files_sha256"; do
if [ -f "$download_dir/$file" ]; then
echo "$download_dir/$file: file already exists; skipping"
continue
elif [ -n "$no_download" ]; then
echo 1>&2 "$download_dir/$file: file does not exist and download has been disabled"
exit 1
fi
wget --show-progress --output-document "$download_dir/$file" -- "$download_url/$file"
done
# Verify SHA-256 digests of each file. Files that failed the check will be
# wrote to standard output of the subshell and hence into the corrupt_files
# variable.
corrupt_files=$(
cd -- "$download_dir" || exit 1
sha256sum --check --quiet "release-$nk_version.sha256" 2> /dev/null |
cut -d ":" -f 1
)
if [ -n "$corrupt_files" ]; then
echo 1>&2 "$SCRIPTNAME: $corrupt_files: File checksums failed verification; try downloading again"
exit 1
fi
for file in "${release_files[@]}"; do
# Extract the downloaded archives. The '--strip-components' option
# removes the root netkit-jh/ directory.
tar \
--bzip2 \
--extract \
--verbose \
--directory "$install_dir" \
--strip-components 1 \
--file "$download_dir/$file"
done
fi
# Start and end delimeters for Netkit-related stuff in the shell's rc file
rc_section_header="#=== NETKIT VARIABLES ==="
rc_section_footer="#=== NETKIT VARIABLES END ==="
# Environment variable definitions required for Netkit to run
nk_env_var_defs="export NETKIT_HOME=\"$install_dir\"
export MANPATH=\"\$MANPATH:\$NETKIT_HOME/man\"
export PATH=\"\$PATH:\$NETKIT_HOME/bin\""
rc_files=(
"$HOME/.bashrc"
"$HOME/.zshrc"
)
# Append Netkit additions to Bash and Zsh "run commands" files.
for rc_file in "${rc_files[@]}"; do
[ ! -f "$rc_file" ] && continue
# Backup existing rc file
rc_file_bak="${rc_file}_$(date '+%F_%H-%M-%S').bak"
cp -- "$rc_file" "$rc_file_bak"
# Strip all content between the Netkit rc section header and footer
sed --in-place "/^$rc_section_header/,/^$rc_section_footer/d;" "$rc_file"
# Append Netkit additions to the rc file
printf "%s\n" "$rc_section_header" >> "$rc_file"
# Environment variable definitions
printf "%s\n" "$nk_env_var_defs" >> "$rc_file"
if [ "$(basename -- "$rc_file")" = ".bashrc" ]; then
# Source the Bash completion scripts if operating on .bashrc
cat << 'EOF' >> "$rc_file"
for file in "$NETKIT_HOME/bash-completion/completions/"*; do
. "$file"
done
unset file
EOF
fi
# Terminate section with footer
printf "%s\n\n" "$rc_section_footer" >> "$rc_file"
done
# Ubuntu (and similar) distributions prevent .bashrc from running in a
# non-interactive shell. So here we can just evaluate the environment variables
# export commands
eval "$nk_env_var_defs"
# Download and install dependencies from APT
if [ -z "$no_packages" ]; then
dependencies=(
"bash" # Required by every Netkit script
"binutils" # For objdump in 4_check_architecture.sh
"coreutils" # readlink, sha256sum, stdbuf, etc
"curl" # For update checking in lstart
"iproute2" # Interface management in manage_tuntap
"iptables" # To manage TUN/TAP traffic
"jq" # For update checking via the GitHub API
"lsof" # To find unused virtual network hubs
"make" # Parallel lab start
"man-db" # For viewing Netkit-JH man pages
"util-linux" # kill, getopt, mount, etc (should already be installed)
"xterm" # Default terminal emulator for Netkit
)
echo "Installing packages required to run Netkit-JH"
sudo apt-get update
sudo apt-get install "${dependencies[@]}"
fi
# Restore existing configuration file, if exists
if [ -n "$backup_dir" ]; then
netkit_conf="$backup_dir/netkit.conf"
echo "Restoring previous configuration ($netkit_conf)"
if ! cp -- "$netkit_conf" "$install_dir"; then
echo 1>&2 "$SCRIPTNAME: $netkit_conf: File does not exist; ignoring"
fi
fi
echo "${color_bold}Netkit-JH is now installed$color_normal"
# Verify system and Netkit install directory. We only exit if the return code
# is 255 (an error not a warning). Also note that set -e is used in this
# script.
echo "Checking configuration..."
if ! "$install_dir/setup_scripts/check_configuration.sh"; then
[ $? -eq 255 ] && exit 1
fi
# Encourage user to set environment variables for the current terminal
cat << END_OF_DIALOG
${color_bold}To use Netkit-JH now, open a new terminal window or run:$color_normal
source ~/.bashrc
(or .zshrc if using Zsh).
It is recommended to change the terminal emulator that Netkit uses, since the
default is xterm (an old but portable emulator). This can be done with the
following command:
"$install_dir/setup_scripts/change_terminal.sh"
or by manually setting TERM_TYPE in one of the configuration files:
(user) "$HOME/.netkit/netkit.conf"
(install) "$install_dir/netkit.conf"
(system) /etc/netkit.conf
END_OF_DIALOG