forked from iiab/iiab-factory
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iiab
executable file
·622 lines (529 loc) · 31.3 KB
/
iiab
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
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
#!/bin/bash
# Copied from: https://github.com/iiab/iiab-factory/blob/master/iiab
# To install Internet-in-a-Box (IIAB) 8.1 / pre-release onto Raspberry Pi OS,
# Ubuntu 22.04+, Linux Mint 21+ or Debian 12+, run this 1-line installer:
#
# curl iiab.io/install.txt | bash
# 1. WARNING: NOOBS IS *NOT* SUPPORTED, as its partitioning is very different.
# On a Raspberry Pi, WE RECOMMEND YOU INSTALL THE LATEST RASPBERRY PI OS:
# https://www.raspberrypi.com/documentation/computers/getting-started.html
# To attempt IIAB 8.1 on another Linux see the manual/legacy instructions:
# https://github.com/iiab/iiab/wiki/IIAB-Installation#do-everything-from-scratch
# 2. An Ethernet cable is HIGHLY RECOMMENDED during installation, as this is
# more reliable than WiFi (and faster!) WARNING: IF YOU CONNECT YOUR IIAB'S
# INTERNAL WIFI TO THE INTERNET OVER 5 GHz, YOU'LL PREVENT OLDER LAPTOPS/
# PHONES/TABLETS (WHICH REQUIRE 2.4 GHz) FROM CONNECTING TO YOUR IIAB'S
# INTERNAL HOTSPOT. See: "wifi_up_down: True" in /etc/iiab/local_vars.yml
# 3. Run 'sudo raspi-config' on Raspberry Pi, to set LOCALISATION OPTIONS
# 4. OPTIONAL: if you have slow/pricey Internet, pre-position KA Lite's
# mandatory 0.9 GB English Pack (en.zip) within /tmp -- you can grab it from
# https://pantry.learningequality.org/downloads/ka-lite/0.17/content/contentpacks/en.zip
# 5. Follow on-screen instructions (TYPE 'sudo iiab' TO RESUME IF EVER NECESS!)
# 6. Within about 1-2 hours, it will announce that INTERNET-IN-A-BOX (IIAB)
# SOFTWARE INSTALL IS COMPLETE, prompting you to reboot...TO ADD CONTENT!
# Thanks For Building Your Own Library To Serve One & All
#
# DRAFT IIAB 8.1 Release Notes:
# https://github.com/iiab/iiab/wiki/IIAB-8.1-Release-Notes
#
# SPECIAL THANKS to countries + communities + volunteers who worked non-stop
# to bring about IIAB 8.1! https://internet-in-a-box.org/contributing.html
#
# IIAB Dev Team
# http://FAQ.IIAB.IO
set -e # Exit on error (avoids snowballing)
export DEBIAN_FRONTEND=noninteractive # Bypass (most!) interactive questions
FLAGDIR=/etc/iiab/install-flags
APTPATH=/usr/bin # Avoids problematic /usr/local/bin/apt on Linux Mint
FAST=false # YOUR OWN RISK: Fewer security & user education prompts.
MFABT=false # As above BUT bypasses editing of local_vars.yml + apt updates.
# When you have no time to read the MFABT book: "Move Fast and Break Things:
# How Facebook, Google, and Amazon Cornered Culture and Undermined Democracy"
REPO_BOUNDARY=1561 # iiab/iiab's lowest PR as of October 2020
pr_changes_local_vars=false
clones_and_pulls_done=false
if [[ $(id -un) != "root" ]]; then
echo -e "\nPlease run: sudo iiab\n"
exit 1
fi
if [[ $1 == "-f" || $1 == "--fast" ]]; then
# EXAMPLE: 'curl iiab.io/fast.txt | bash [-s 361 2604 2607]' AND 'sudo iiab -f' TO CONTINUE
FAST=true
shift
elif [[ $1 == "-r" || $1 == "--risky" ]]; then
# EXAMPLE: 'curl iiab.io/risky.txt | bash [-s 361 2604 2607]' AND 'sudo iiab -r' TO CONTINUE
FAST=true
MFABT=true
shift
fi
mkdir -p $FLAGDIR # Which also creates /etc/iiab for the step just below
# Save CLI params (PR #s) for Section J. so 'sudo iiab' continues after reboots
if [ $# -ne 0 ]; then
printf '%s\n' "$@" >> /etc/iiab/pr-queue
fi
# 1. Subroutine for B. Returns true (0) if username ($1) exists with password ($2)
command -v grep &> /dev/null ||
$APTPATH/apt -y install grep # AVOID UX CLUTTER+DELAYS: 5 MORE BELOW
command -v perl &> /dev/null ||
$APTPATH/apt -y install perl # AVOID UX CLUTTER+DELAYS: 4 MORE BELOW
check_user_pwd() {
# 2021-08-28: New OS's use 'yescrypt' so use Perl instead of Python (#2949)
# This also helps avoid parsing the (NEW) 4th sub-field in $y$j9T$SALT$HASH
field2=$(grep "^$1:" /etc/shadow | cut -d: -f2)
[[ $(perl -e "print crypt('$2', '$field2')") == $field2 ]]
}
# 2. Subroutine for Sections A. and G. Returns any IIAB variable value -- SEE:
# https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F
# 2021-08-28: bash scripts using default_vars.yml &/or local_vars.yml
# https://github.com/iiab/iiab-factory/blob/master/iiab#L119
# https://github.com/iiab/iiab/blob/master/scripts/iiab-apps-to-be-installed#L5
# https://github.com/iiab/iiab/blob/master/roles/remoteit/templates/iiab-remoteit#L8
# https://github.com/iiab/iiab/blob/master/roles/firmware/templates/iiab-check-firmware#L10
# https://github.com/iiab/iiab/blob/master/roles/network/templates/gateway/iiab-gen-iptables#L48
# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L23-L39
# https://github.com/iiab/iiab/blob/master/roles/openvpn/templates/iiab-support READS+WRITES TO local_vars.yml (INCL NON-BOOLEAN)
iiab_var_value() {
v1=$(grep "^$1:\s" /opt/iiab/iiab/vars/default_vars.yml 2> /dev/null | tail -1 | sed "s/^$1:\s\+//; s/#.*//; s/\s*$//; s/^\(['\"]\)\(.*\)\1$/\2/")
v2=$(grep "^$1:\s" /etc/iiab/local_vars.yml 2> /dev/null | tail -1 | sed "s/^$1:\s\+//; s/#.*//; s/\s*$//; s/^\(['\"]\)\(.*\)\1$/\2/")
[[ $v2 != "" ]] && echo $v2 || echo $v1 # [ "$v2" ] ALSO WORKS
}
# 3. Subroutine for C. and F. Clone 3 IIAB repos
clone-repos() { # PREREQ: 'apt update'
echo -e "\n\nDOWNLOAD (CLONE) IIAB'S 3 KEY REPOS INTO /opt/iiab ..."
command -v git &> /dev/null ||
$APTPATH/apt -y install git # AVOID UX CLUTTER+DELAYS: 3 MORE BELOW
mkdir -p /opt/iiab
cd /opt/iiab
echo
if [ -d iiab ]; then
echo -e "REPO EXISTS? Consider 'cd /opt/iiab/iiab; git pull'"
else
git clone https://github.com/iiab/iiab
fi
echo
if [ -d iiab-admin-console ]; then
echo -e "REPO EXISTS? Consider 'cd /opt/iiab/iiab-admin-console; git pull'"
else
git clone https://github.com/iiab/iiab-admin-console
fi
echo
if [ -d iiab-factory ]; then
echo -e "REPO EXISTS? Consider 'cd /opt/iiab/iiab-factory; git pull'"
else
git clone https://github.com/iiab/iiab-factory
fi
}
# 4. Subroutine for C. and F. Install optional PR's
pull-prs() {
echo -e "\n\nINSTALL PR's FROM iiab/iiab OR iiab/iiab-admin-console -- USAGE EXAMPLES:\n"
echo -e " sudo iiab 361 2604 2607"
echo -e " curl iiab.io/install.txt | bash -s 361 2604 2607\n"
if [ -s /etc/iiab/pr-queue ]; then # Set an email address for 'git pull' if one isn't yet set
git config --get user.email 1> /dev/null ||
git config --global user.email "albert@einstein.edu"
echo -e "\nYour git email is set to: \e[1m$(git config --get user.email)\e[0m"
echo -e 'Change this by running: sudo git config --global user.email "you@example.com"'
command -v jq &> /dev/null || {
echo
$APTPATH/apt -y install jq # Or grep/sed to avoid 3+ sec delay
}
fi
# Similar to 'for pr in "$@"' but survives reboots:
while [ -s /etc/iiab/pr-queue ]; do # Test that file exists & is non-empty
pr=$(head -1 /etc/iiab/pr-queue) # Try the next PR, from top of queue
if ! [[ "$pr" =~ ^[1-9][0-9]*$ ]]; then
echo -e "\n\e[1mInvalid PR number:\e[0m $pr\n"
echo -n "Delete it from top of /etc/iiab/pr-queue and continue? [Y/n] "
read -n 1 -r ans < /dev/tty
echo
[[ $ans == "n" || $ans == "N" ]] && # [[ $ans =~ ^[nN]$ ]]
exit 1
sed -i '1d' /etc/iiab/pr-queue # Delete 1st line
continue
fi
if (( pr >= REPO_BOUNDARY )); then
repo=iiab
else
repo=iiab-admin-console
fi
http_code=$(curl -sH "Accept: application/vnd.github.v3" https://api.github.com/repos/iiab/$repo/pulls/$pr -w "%{http_code}" -o /tmp/iiab-pr.json)
if [[ $http_code != "200" ]]; then
echo -e "\n\e[41;1mCOULD NOT FIND PR #$pr (https://github.com/iiab/$repo/pull/$pr)\e[0m\n"
echo -en "\e[41;1mHTTP ERROR: $http_code\e[0m\e[1m "
[[ $http_code == "403" ]] &&
echo -en "(DID YOU REQUEST 60+ PR's IN ONE HOUR?)"
[[ $http_code == "404" ]] &&
echo -en "(IS #$pr AN ISSUE, RATHER THAN A PR?)"
echo -e "\n"
cat /tmp/iiab-pr.json # GitHub sometimes includes an English explanation of the error, and URL, e.g. https://developer.github.com/v3/#rate-limiting
echo
curl -IsH "Accept: application/vnd.github.v3" https://api.github.com/repos/iiab/$repo/pulls/$pr # HTTP headers typically reveal a lot more!
echo -n "Delete it from top of /etc/iiab/pr-queue and continue? [Y/n] "
read -n 1 -r ans < /dev/tty
echo
[[ $ans == "n" || $ans == "N" ]] && # [[ $ans =~ ^[nN]$ ]]
exit 1
sed -i '1d' /etc/iiab/pr-queue # Delete 1st line
continue
fi
title=$(jq -r '.title' /tmp/iiab-pr.json)
account=$(jq -r '.head.label' /tmp/iiab-pr.json | cut -d: -f1)
repo2=$(jq -r '.head.repo.name' /tmp/iiab-pr.json) # 2021-11-22: For PR's created from oddly named forks (instead of "iiab" or "iiab-admin-console" !)
branch=$(jq -r '.head.label' /tmp/iiab-pr.json | cut -d: -f2)
commit_8chars=$(jq -r '.head.sha' /tmp/iiab-pr.json | cut -c1-8)
files_changed=$(jq -r '.changed_files' /tmp/iiab-pr.json)
echo -e "\nPR #$pr: cd /opt/iiab/$repo"
cd /opt/iiab/$repo
#git checkout -b POTLUCK master || true # If test branch name/norm in future...for both repos?
local_branch_old=$(git branch --show-current)
if [[ $local_branch_old == "master" || $local_branch_old == "main" ]]; then
#local_branch_new=$pr # e.g. "2604"
if [[ $branch == "master" || $branch == "main" ]]; then
local_branch_new="$pr-$branch" # e.g. "2604-main"
else
local_branch_new=$branch # e.g. "huge-speedup"
fi
else
#local_branch_new="$local_branch_old-$pr" # e.g. "2604-2607-3173"
local_branch_new="$local_branch_old--$branch" # e.g. "huge-speedup--qa--docs"
fi
echo -e "git checkout -b \e[1m$local_branch_new\e[0m"
git checkout -b $local_branch_new # FAILS IF (1) branch name's also master/main (2) branch name > 250 chars (branch names > 244 chars cannot be pushed)
echo -e "git pull --no-edit --no-rebase --set-upstream https://github.com/$account/$repo2 $branch" # Or $repo2.git
git pull --no-edit --no-rebase --set-upstream https://github.com/$account/$repo2 $branch || {
echo -e "\n\e[1mgit exit/error code:\e[0m $?\n" # if hides err code
echo -n "Delete it from top of /etc/iiab/pr-queue and continue? [Y/n] "
read -n 1 -r ans < /dev/tty
echo
if [[ $ans == "n" || $ans == "N" ]]; then # [[ $ans =~ ^[nN]$ ]]
exit 1
fi
sed -i '1d' /etc/iiab/pr-queue # Delete 1st line
continue
}
sed -i '1d' /etc/iiab/pr-queue # Delete 1st line
echo "$(date '+%F %T %Z') #$pr $files_changed $commit_8chars https://github.com/$account/$repo2 $branch \"$title\"" >> /etc/iiab/pr-list-pulled # For iiab-diagnostics
done
}
# # Ask for password change if pi/raspberry default remains
# if check_user_pwd "pi" "raspberry"; then
# echo -e "\n\n\e[41;1mRaspberry Pi's are COMPROMISED often if the default password is not changed!\e[0m\n"
#
# echo -n "What password do you want for GNU/Linux user 'pi' ? "
# read ans < /dev/tty # Whines but doesn't change password if [Enter]
# echo pi:"$ans" | chpasswd || true # Overrides 'set -e'
# fi
# A. Create user 'iiab-admin' (or any other, some prefer 'pi' or 'ubuntu') as
# nec, with the default password. If customizing this is important to you,
# please pre-position /etc/iiab/local_vars.yml specifying the 3 vars below.
IIAB_ADMIN_USER=$(iiab_var_value iiab_admin_user)
[[ $IIAB_ADMIN_USER == "" ]] &&
IIAB_ADMIN_USER="iiab-admin"
IIAB_ADMIN_PUBLISHED_PWD=$(iiab_var_value iiab_admin_published_pwd)
[[ $IIAB_ADMIN_PUBLISHED_PWD == "" ]] &&
IIAB_ADMIN_PUBLISHED_PWD="g0adm1n"
if ! [[ $(iiab_var_value iiab_admin_user_install) =~ ^[fF]alse$ ]]; then
if ! id -u "$IIAB_ADMIN_USER" &> /dev/null; then
/usr/sbin/useradd "$IIAB_ADMIN_USER"
echo "$IIAB_ADMIN_USER":"$IIAB_ADMIN_PUBLISHED_PWD" | chpasswd
fi
fi
# B. If 'iiab-admin' (or equivalent) use default password, prompt for change
if check_user_pwd "$IIAB_ADMIN_USER" "$IIAB_ADMIN_PUBLISHED_PWD"; then
echo -e "\n\n\e[41;1mDANGER: User '$IIAB_ADMIN_USER' has public password '$IIAB_ADMIN_PUBLISHED_PWD' per http://FAQ.IIAB.IO\e[0m\n"
echo -e "This is for login to Internet-in-a-Box's Admin Console (http://box.lan/admin)"
echo -e "Technical Details: https://github.com/iiab/iiab/blob/master/roles/iiab-admin"
if ! $($FAST); then
echo -en "\nWhat password do you want for GNU/Linux user '$IIAB_ADMIN_USER' ? "
read ans < /dev/tty # Whines but doesn't change password if [Enter]
echo "$IIAB_ADMIN_USER":"$ans" | chpasswd || true # Overrides 'set -e'
fi
fi
if [ -f $FLAGDIR/iiab-complete ]; then
echo -e "\n\nIIAB INSTALLATION (/usr/sbin/iiab) IS ALREADY COMPLETE -- per existence of:"
echo -e "$FLAGDIR/iiab-complete -- nothing to do.\n"
exit 0
fi
# C. Position & customize /etc/iiab/local_vars.yml
command -v wget &> /dev/null ||
$APTPATH/apt -y install wget # AVOID UX CLUTTER+DELAYS: 4 MORE ABOVE
command -v nano &> /dev/null ||
$APTPATH/apt -y install nano # AVOID UX CLUTTER+DELAYS: 5 MORE ABOVE
if [ -f /etc/iiab/local_vars.yml ]; then
# FUTURE: Test if their local_vars.yml is sufficiently version-compatible ?
echo -e "\n\n EXISTING /etc/iiab/local_vars.yml is being used to install Internet-in-a-Box\n"
echo -e " 🚂 🚃 🚄 🚅 🚆 🚇 🚈 🚉 🚊 🚋 🚌 🚍 🚎 🚏 🚐 🚑 🚒 🚚 🚛 🚜 🚞 🚟 🚠 🚡 🚲\n"
echo -e " Google 'local_vars.yml' to learn more!"
else
echo -e "\n\nInstalling Internet-in-a-Box requires /etc/iiab/local_vars.yml\n"
echo -e "PLEASE PICK (1) 🚵 SMALL (2) 🚢🚣 MEDIUM or (3) 🚂🚃🚃 LARGE (NEEDS 2+ GB RAM)."
echo -e "Or try (m) for 🚑 MEDICAL.\n"
echo -e 'See "What services (IIAB apps) are suggested during installation?" and'
echo -e '"What can I do with E-books and Internet-in-a-Box?" in http://FAQ.IIAB.IO\n'
echo -e "WARNING: This Can Take More Than An Hour, depending on Internet speed, CPU,"
echo -e "temperature, and the speed of your microSD card.\n"
echo -n "Please type 1, 2, 3 or m: "
read -n 1 -r local_vars_size < /dev/tty
echo; echo
case $local_vars_size in
0)
local_vars_src_file=local_vars_unittest.yml
;;
1)
local_vars_src_file=local_vars_small.yml
;;
3)
local_vars_src_file=local_vars_large.yml
;;
m)
local_vars_src_file=local_vars_medical.yml
;;
n)
local_vars_src_file=local_vars_none.yml
;;
*)
local_vars_src_file=local_vars_medium.yml
;;
esac
# Quick pre-scan for any PR(s) that change user-specified local_vars.yml
if [ -s /etc/iiab/pr-queue ]; then # Test that file exists & is non-empty
while read pr; do
if (( pr < REPO_BOUNDARY )); then
continue
fi
# https://docs.github.com/en/rest/pulls/pulls#list-pull-requests-files
http_code=$(curl -sH "Accept: application/vnd.github.v3" https://api.github.com/repos/iiab/iiab/pulls/$pr/files -w "%{http_code}" -o /tmp/iiab-pr-files.json)
if [[ $http_code == "200" ]]; then
#jq -r '.[].filename' /tmp/iiab-pr-files.json > /tmp/iiab-pr-filelist
#if grep -q "^vars/$local_vars_src_file$" /tmp/iiab-pr-filelist; then
# Defer jq install til later for smooth UX: (grep works w/o apt delays!)
if grep -q '^\s*"filename": "vars/'$local_vars_src_file'",$' /tmp/iiab-pr-files.json; then
pr_changes_local_vars=true
break
fi
fi
done < /etc/iiab/pr-queue
fi
if $($pr_changes_local_vars); then
echo -e "\n \e[44;1m \e[0m"
echo -e " \e[44;1m At least one PR will change your local_vars.yml \e[0m"
echo -e " \e[44;1m \e[0m"
echo -e " \e[44;1m SO LET'S CLONE & PULL FIRST (1-2 min) \e[0m"
echo -e " \e[44;1m \e[0m\n\n"
$APTPATH/apt update # -q useless; -qq too quiet (an option if optimizing later nec)
clone-repos
pull-prs
clones_and_pulls_done=true
elif [ -s /etc/iiab/pr-queue ]; then # Test that file exists & is non-empty
echo -e "\n\e[1m PR's will not change your local_vars.yml\e[0m"
echo
echo -e "\e[1m So it's safe to edit local_vars.yml BEFORE cloning & pulling\e[0m\n\n"
fi
# Copy or download local_vars.yml + edit it optionally
if [ -f /opt/iiab/iiab/vars/$local_vars_src_file ]; then
cp /opt/iiab/iiab/vars/$local_vars_src_file /etc/iiab/local_vars.yml
echo
else
wget -O /etc/iiab/local_vars.yml https://github.com/iiab/iiab/raw/master/vars/$local_vars_src_file
fi
if ! $($MFABT); then
echo -en "\nEdit /etc/iiab/local_vars.yml to customize your Internet-in-a-Box? [Y/n] "
read -n 1 -r ans < /dev/tty
echo
if [[ $ans != "n" && $ans != "N" ]]; then # ! [[ $ans =~ ^[nN]$ ]]
echo -e "\n1) PLEASE RUN: sudo nano /etc/iiab/local_vars.yml\n"
echo -e "2) NEED HELP? Type CTRL+G to learn...the nano editor\n"
echo -e "3) After you're done editing, RUN 'sudo iiab' TO CONTINUE!\n"
exit 0
fi
fi
fi
# D. Mandate OS SECURITY/UPDATES if 'apt update' has any (THEN REBOOT, AS NEC)
# Educate implementer while waiting for 'apt update'
echo -e "\n\n ██████████████████████████████████████████████████████████████████████████████"
echo -e " ██ ██"
echo -e " ██ RUN 'sudo iiab' IF THIS INSTALL SCRIPT EVER FAILS, TO TRY TO CONTINUE! ██"
echo -e " ██ ██"
echo -e " ██████████████████████████████████████████████████████████████████████████████"
if ! $($MFABT); then
echo -e "\n\n'apt update' is checking for OS updates, \e[1mwhich may force a reboot...\e[0m\n"
# echo -e "2019-07-11 TEMP WORKAROUND FOR RASPBIAN BUSTER'S testing->stable apt GLITCH...\nDetails @ https://github.com/iiab/iiab/issues/1856\n"
# apt -y update || true # Overrides 'set -e'
# echo -e "\nNOW THE REAL 'apt update' WILL RUN...\n"
#$APTPATH/apt -qq update > /tmp/apt.stdout 2> /tmp/apt.stderr; rc=$(echo $?) || true # Overrides 'set -e'
#if (( $(wc -c < /tmp/apt.stderr) > 82 )); then # apt.stderr typically contains exactly 82 characters when there are no errors, no matter the primary locale, i.e. 3-line file "\nWARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n\n" ...OR... in other cases more than 82, e.g. many lines of errors when apt is busy/locked/offline/etc
# 2022-10-28: BEWARE 'apt -qq update 2> /tmp/apt.stderr' would behave very differently (i.e. if STDIN isn't being redirected, then [1] /tmp/apt.stderr DOESN'T contain 82-char warning "\nWARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n\n" and [2] /tmp/apt.stderr DOES contain ANSI color escape codes, which grep [BELOW] would need to scan for using https://unix.stackexchange.com/questions/324835/grep-for-an-ansi-escape-code)
#if grep -q '^E: ' /tmp/apt.stderr; then # We ignore '^W: ' warnings and '^N: ' notices (per: https://unix.stackexchange.com/questions/590027/what-does-the-error-line-prefix-w-mean-like-from-apt-get-or-other-similar) to avoid 'sudo iiab' holdups arising from {MongoDB, Yarn, etc} "Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg)"
#if [[ $rc != "0" ]]; then # apt's Return Code simpler (than both conditions above!)
if ! $APTPATH/apt -qq update > /tmp/apt.stdout 2> /tmp/apt.stderr; then # Simpler than all 3 above!
echo -e "'apt update' FAILED. VERIFY YOU'RE ONLINE and resolve all errors below:\n"
cat /tmp/apt.stderr
exit 1
elif grep -q 'apt list --upgradable' /tmp/apt.stdout; then # apt.stdout typically contains {"All packages are up to date.\n" [even if primary locale is French & Hindi!], "Todos los paquetes están actualizados.\n", "所有软件包均为最新。\n"} ...OR... {"5 packages can be upgraded. Run 'apt list --upgradable' to see them.\n" [even if primary locale is French & Hindi!], "Se puede actualizar 1 paquete. Ejecute «apt list --upgradable» para verlo.\n", "有 1 个软件包可以升级。请执行 ‘apt list --upgradable’ 来查看它们。\n"}
cat /tmp/apt.stdout # e.g. "5 packages can be upgraded. Run 'apt list --upgradable' to see them.\n"
echo -e "\nYour OS will now be upgraded...this takes time. THEN IT WILL REBOOT (IF NEC!)\n"
if ! $($FAST); then
echo -n "Hit any key to confirm you'll RUN 'sudo iiab' AFTER IT REBOOTS: "
read -n 1 -r ans < /dev/tty
echo; echo
fi
$APTPATH/apt -y dist-upgrade
else
cat /tmp/apt.stdout # "All packages are up to date.\n"
if ! $($FAST); then
echo -ne "\nHit any key to confirm you'll TRY TO RERUN 'sudo iiab' IF THERE IS A PROBLEM: "
read -n 1 -r ans < /dev/tty
echo; echo
fi
fi
# 2021-09-03 #2975: Is a reboot needed? We check after reboot too, safeguarding
# against users (or apt above, or unattended-upgrades) spontaneously AGAIN apt
# updating /boot e.g. kernel AT ANYTIME -- also many weeks could have passed.
bootupTime=$(($(date +%s) - $(cut -d. -f1 /proc/uptime))) # Seconds since...
bootDirLastModFile=$(date +%s -r "/boot/$(ls -t /boot | head -1)") # 1970-01-01
# Works w/o RTC (real-time clock, i.e. battery) because:
# Both 'apt' installs to /boot and IIAB installs require Internet (e.g. NTP).
if (( bootupTime < bootDirLastModFile )); then
reboot
exit 0 # Nec to avoid bogus continuation & misleading output below
fi
fi
##############################################################################
################### MAIN INTERACTIVE STUFF (ABOVE) DONE!!! ###################
##############################################################################
# E. If microSD, lower reserve disk space from ~5% to 2%
# if [ -f /proc/device-tree/model ] && grep -qi raspberry /proc/device-tree/model; then
if [ -e /dev/mmcblk0p2 ]; then
echo -e "\n\nFound microSD card /dev/mmcblk0p2: Lower its reserve disk space from ~5% to 2%\n"
tune2fs -m 2 /dev/mmcblk0p2
fi
# F. For a smoother + tighter UX in above interactive portion
if ! $($clones_and_pulls_done); then
clone-repos
pull-prs
fi
# G. Install Ansible + 2 IIAB repos
echo -e "\n\nINSTALL ANSIBLE + CORE IIAB SOFTWARE + ADMIN CONSOLE / CONTENT PACK MENUS...\n"
if [ -f $FLAGDIR/iiab-ansible-complete ]; then
echo -e "ANSIBLE INSTALLATION IS ALREADY COMPLETE -- per existence of:"
echo -e "$FLAGDIR/iiab-ansible-complete\n"
echo -e "To upgrade Ansible, you can run: sudo /opt/iiab/iiab/scripts/ansible\n\n"
else
echo -e "Install Ansible..."
/opt/iiab/iiab/scripts/ansible
touch $FLAGDIR/iiab-ansible-complete
fi
echo -e "\n┌──────────────────────────────────────────────────────────────────────────────┐"
echo -e "│ │"
echo -e "│ NOW INSTALL IIAB SOFTWARE! If glitches arise (connectivity or otherwise) │"
echo -e "│ │"
echo -e "│ PLEASE TRY TO CONTINUE BY RE-RUNNING PARENT SCRIPT 'sudo iiab' -- or run │"
echo -e "│ │"
echo -e "│ child script ./iiab-install -- both avoid repeating any of the 9 stages. │"
echo -e "│ │"
echo -e "└──────────────────────────────────────────────────────────────────────────────┘"
cd /opt/iiab/iiab/
./iiab-install # "$@"
if [ -f $FLAGDIR/iiab-admin-console-complete ]; then
echo -e "ADMIN CONSOLE INSTALLATION IS ALREADY COMPLETE -- per existence of:"
echo -e "$FLAGDIR/iiab-admin-console-complete\n"
elif [[ $(iiab_var_value admin_console_install) =~ ^[fF]alse$ ]]; then
echo -e "LET'S NOT TRY TO INSTALL ADMIN CONSOLE -- because:"
echo -e "'admin_console_install: False' is likely in /etc/iiab/local_vars.yml\n"
else
echo -e "Install Admin Console... (also runs iiab-get-kiwix-cat to d/l Kiwix catalog,"
echo -e "and installs Dynamic Menuing for /library/www/html/home/index.html)\n"
cd /opt/iiab/iiab-admin-console
./install
touch $FLAGDIR/iiab-admin-console-complete
fi
if [[ $(iiab_var_value admin_console_enabled) =~ ^[fF]alse$ ]]; then
echo -e "'admin_console_enabled: False' is likely in /etc/iiab/local_vars.yml"
echo -e "...so let's try to DISABLE & STOP Admin Console's iiab-cmdsrv.service\n"
systemctl disable iiab-cmdsrv || true # Overrides 'set -e'
systemctl stop iiab-cmdsrv || true # Overrides 'set -e'
else
echo -e "'admin_console_enabled: False' isn't in /etc/iiab/local_vars.yml"
echo -e "...so let's try to ENABLE & START Admin Console's iiab-cmdsrv.service\n"
systemctl enable iiab-cmdsrv || true # Overrides 'set -e'
systemctl start iiab-cmdsrv || true # Overrides 'set -e'
fi
# H. KA Lite prep
if [ -d /library/ka-lite ]; then
echo -e "\n\nKA LITE REQUIRES 2 THINGS...\n"
echo -e "Register with KA Lite - just the anonymous registration...\n"
# /usr/bin/kalite venv wrapper invokes 'export KALITE_HOME=/library/ka-lite'
if [ ! -f $FLAGDIR/kalite-zone-complete ]; then
echo -e "Now running 'kalite manage generate_zone' ...\n"
kalite manage generate_zone || true # Overrides 'set -e'
touch $FLAGDIR/kalite-zone-complete
else
echo -e "'kalite manage generate_zone' IS ALREADY COMPLETE -- per existence of:"
echo -e "$FLAGDIR/kalite-zone-complete\n"
fi
echo -e "\nInstall KA Lite's mandatory 0.9 GB English Pack... (en.zip)\n"
if [ ! -f $FLAGDIR/kalite-en.zip-complete ]; then
#echo -e 'Now retrieving it...\n'
cd /tmp
if [ -f en.zip ]; then
if [ $(wc -c < en.zip) -ne 929916955 ]; then
echo -e "\nERROR: /tmp/en.zip must be 929,916,955 bytes to proceed.\n" >&2
exit 1
else
echo -e "\nUsing existing /tmp/en.zip whose 929,916,955 byte size is correct!\n"
fi
else
wget https://pantry.learningequality.org/downloads/ka-lite/0.17/content/contentpacks/en.zip
fi
echo -e 'Now installing /tmp/en.zip into /library/ka-lite/content/*\n'
kalite manage retrievecontentpack local en en.zip
touch $FLAGDIR/kalite-en.zip-complete
fi
fi
# WARNING: /tmp/en.zip (and all stuff in /tmp) is auto-deleted during reboots
# NEW WAY ABOVE - since 2018-07-03 - installs KA Lite's mandatory English Pack
#
# kalite manage retrievecontentpack download en
# OLD WAY ABOVE - fails w/ sev ISPs per https://github.com/iiab/iiab/issues/871
# I. Start BitTorrent downloads, e.g. if /etc/iiab/local_vars.yml requested any
if $(systemctl -q is-active transmission-daemon) && ! $(ischroot -t); then
echo -e "\n\nSTARTING BITTORRENT DOWNLOAD(S) for KA Lite...Please Monitor: http://box:9091\n"
transmission-remote -n Admin:changeme -t all --start
fi
touch $FLAGDIR/iiab-complete
# J. Educate Implementers prior to rebooting!
echo -e "\n\n ┌───────────────────────────────────────────────────────────┐"
echo -e " │ │"
echo -e " │ INTERNET-IN-A-BOX (IIAB) SOFTWARE INSTALL IS COMPLETE │"
echo -e " │ │"
echo -e " └───────────────────────────────────────────────────────────┘\n"
echo -e "(1A) A couple minutes after you reboot (below) try to connect any laptop to"
echo -e 'Wi-Fi hotspot "Internet in a Box". If this works, verify that you can browse'
echo -e "to http://box or http://box.lan or http://10.10.10.10\n"
echo -e "(1B) IF THOSE 3 DON'T WORK, try http://box.local from any device connected to"
echo -e "your usual network. Or try http://localhost from your IIAB itself!\n"
echo -e "(1C) IF ALL 5 ABOVE DON'T WORK, ask the person who set up the network/router"
echo -e "in your building for the IP address of your IIAB, so you can browse to it"
echo -e "using (something like) http://192.168.0.100 -- FOR NOW, IP ADDRESS(ES) ARE:\n\e[1m"
hostname -I
echo -e '\e[0m\n(2) ADD CONTENT using http://box.lan/admin (changing "box.lan" to be as above!)'
echo -e 'PLEASE READ "What are the default passwords?" and "How do I customize my'
echo -e 'Internet-in-a-Box home page?" at http://FAQ.IIAB.IO\n'
echo -e "(3) Please run the 'iiab-diagnostics' command, to generate a URL summarizing"
echo -e "your IIAB configuration, for volunteers seeking to help you. We strongly"
echo -e "encourage you to share this URL also when connecting with others in the IIAB"
echo -e "global community, learning from other initiatives in your region and beyond!\n"
#echo -e "(3) If you're installing IIAB over Wi-Fi (instead of Ethernet) remember to run"
#echo -e "'iiab-hotspot-on' at the VERY END, when you're ready to ACTIVATE YOUR IIAB's"
#echo -e "INTERNAL WI-FI HOTSPOT. CAUTION: this permanently kills your IIAB's Internet"
#echo -e "(over Wi-Fi anyway) until you later run 'iiab-hotspot-off'. CAVEAT: these"
#echo -e "two commands only work with Raspberry Pi as of 2019-09-30.\n"
if ! $(ischroot -t); then
echo -ne "HIT [Enter] TO REBOOT, CONFIRMING YOU'VE" '"photographed" THE ABOVE PARAGRAPHS: '
read ans < /dev/tty
# Sets hostname, improves RTC + memory mgmt, starts BitTorrents if needed, etc!
reboot
else
echo -ne "IIAB Done"
exit 0
fi