-
Notifications
You must be signed in to change notification settings - Fork 0
/
iiab-install
executable file
·203 lines (169 loc) · 9.81 KB
/
iiab-install
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
#!/bin/bash -e
# Running from a git repo
# Add cmdline options for passing to ansible
PLAYBOOK=iiab-stages.yml
INVENTORY=ansible_hosts
IIAB_STATE_FILE=/etc/iiab/iiab_state.yml
ARGS="--extra-vars {" # Needs boolean not string so use JSON list. bash forces {...} to '{...}' for Ansible
CWD=`pwd`
OS=`grep ^ID= /etc/os-release | cut -d= -f2`
OS=${OS//\"/} # Remove all '"'
MIN_RPI_KERN=5.4.0 # Do not use 'rpi-update' unless absolutely necessary: https://github.com/iiab/iiab/issues/1993
MIN_ANSIBLE_VER=2.15.12 # 2023-05-22: ansible-core 2.12 EOL per https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix 2022-11-09: Raspberry Pi 3 (and 3 B+ etc?) apparently install (and require?) ansible-core 2.11 for now -- @deldesir can explain more on PR #3419. Historical: Ansible 2.8.3 and 2.8.6 had serious bugs, preventing their use with IIAB.
REINSTALL=false
DEBUG=false
SKIP_ROLE_ON_ERROR=false
usage() {
echo -e "\n\e[1mUse './iiab-install' for regular installs, or to continue an install."
echo -e "Use './iiab-install --risky' to force 'skip_role_on_error: True'"
echo -e "Use './iiab-install --reinstall' to force running all Stages 0-9, followed by the Network Role."
echo -e "Use './iiab-install --debug' to run Stage 0, followed by Stages 3-9, followed by the Network Role."
echo -e "Use './iiab-configure' to run Stage 0, followed by Stages 4-9."
echo -e "Use './runrole' to run Stage 0, followed by a single Stage or Role."
echo -e "Use './iiab-network' to run Stage 0, followed by the Network Role.\e[0m\n"
}
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash/14203146#14203146
while [[ $# -gt 0 ]]; do
case $1 in
--reinstall)
REINSTALL=true
shift
;;
--debug)
DEBUG=true
shift
;;
-r|--risky)
SKIP_ROLE_ON_ERROR=true
shift
;;
*)
usage
exit 1
;;
esac
done
ARGS="$ARGS\"skip_role_on_error\":$SKIP_ROLE_ON_ERROR" # Needs boolean not
# string so use JSON list. Ansible permits these boolean values: (refresher)
# https://github.com/iiab/iiab/blob/master/roles/0-init/tasks/validate_vars.yml#L19-L43
if [ ! -f /etc/iiab/local_vars.yml ]; then
if [ -f /opt/iiab/iiab/vars/local_vars.yml ]; then
echo -e "\nACTION NEEDED: YOUR /opt/iiab/iiab/vars/local_vars.yml IS NO LONGER SUPPORTED.\n" >&2
echo -e "███████████████████ TO MOVE IT TO THE CORRECT LOCATION, RUN: ███████████████████" >&2
echo -e "██ ██" >&2
echo -e "██ mv /opt/iiab/iiab/vars/local_vars.yml /etc/iiab/local_vars.yml ██" >&2
echo -e "██ ██" >&2
echo -e "████████████████████████████████████████████████████████████████████████████████\n" >&2
fi
echo -e "\n\e[1mEXITING: /opt/iiab/iiab/iiab-install REQUIRES /etc/iiab/local_vars.yml\e[0m\n" >&2
echo -e "(1) See http://FAQ.IIAB.IO -> What is local_vars.yml and how do I customize it?" >&2
echo -e "(2) SMALL/MEDIUM/LARGE samples are included in /opt/iiab/iiab/vars" >&2
echo -e "(3) NO TIME FOR DETAILS? RUN INTERNET-IN-A-BOX'S FRIENDLY 1-LINE INSTALLER:\n" >&2
echo -e ' https://download.iiab.io\n' >&2
exit 1
fi
# FUTURE: Test if their local_vars.yml is sufficiently version-compatible !
echo -e "\n\n./iiab-install $* BEGUN IN $CWD\n"
echo -e "local_facts.fact DIAGNOSTICS... (A FEW LINES OF ERRORS/WARNINGS BELOW ARE OK!)\n"
scripts/local_facts.fact # Exit & advise, if OS not supported.
mkdir -p /etc/ansible/facts.d
cp scripts/local_facts.fact /etc/ansible/facts.d/local_facts.fact
echo -e "\nPlaced /etc/ansible/facts.d/local_facts.fact into position.\n"
mkdir -p /etc/iiab/install-flags # MANDATORY since 2022-07-22
echo -e "/etc/iiab/install-flags directory created/verified."
echo -e "(e.g. for PR #3318 netwarn pop-ups, asking you to run iiab-network)\n"
if [ ! -f $PLAYBOOK ]; then
echo "EXITING: IIAB Playbook ""$PLAYBOOK"" not found."
echo "Please run './iiab-install' from /opt/iiab/iiab (top level of git repo)."
exit 1
fi
# Subroutine compares software version numbers. Generates rare false positives
# like "1.0 > 1" and "2.4.0 > 2.4". Avoid risks by structuring conditionals w/
# a consistent # of decimal points e.g. "if version_gt w.x.y.z a.b.c.d; then"
version_gt() { [ "$(printf '%s\n' "$@" | sort -V | head -1)" != "$1" ]; }
# Verify that Raspbian is running a recent enough kernel. As Raspbian
# updates on 4.9.41-v7+ broke bridging, WiFi AP & OpenVPN in Oct/Nov 2017.
CURR_KERN=`uname -r`
echo "Found Kernel ""$CURR_KERN"
if [ "$OS" == "raspbian" ] && version_gt $MIN_RPI_KERN $CURR_KERN ; then
echo -e "\nEXITING: Kernel ""$MIN_RPI_KERN"" or higher required with Raspbian."
echo -e "PLEASE RUN 'apt update' then 'apt install raspberrypi-kernel' then reboot."
echo -e "IF ABSOLUTELY NEC run 'rpi-update' for a PRE-RELEASE kernel, then reboot."
echo -e "IIAB INSTALL INSTRUCTIONS: https://github.com/iiab/iiab/wiki/IIAB-Installation"
exit 1
fi
# Verify that a recent enough version of Ansible is installed. See #449. The
# "include:" command was inconsistently implemented prior to Ansible 2.4.x.x
CURR_ANSIBLE_VER=0
#if [ $(grep ubuntu /etc/apt/sources.list) ]; then # FAILS when multiple lines returned, due to single square brackets
#if grep -q ubuntu /etc/apt/sources.list ; then # Works: bypasses need for "> /dev/null" thanks to "grep -q" (quiet)
#if command -v ansible > /dev/null ; then # Works But Wordy!
#if [[ $(command -v ansible) ]]; then # Also Works! $(...) nests more easily than backticks
#if [[ `which ansible` ]]; then # "which" misses built-in commands like cd, and is RISKY per https://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script
#if [[ `type -P ansible` ]]; then # "type -P" isn't POSIX compliant; it misses built-in commands like "cd"
if [[ $(command -v ansible) ]]; then # "command -v" is POSIX compliant; it catches built-in commands like "cd"
CURR_ANSIBLE_VER=$(ansible --version | head -1 | cut -f 2- -d " " | sed 's/.* \([^ ]*\)\].*/\1/')
# Above works with 'ansible [core 2.11.0rc2]' -- these old ways do not:
#CURR_ANSIBLE_VER=$(ansible --version | head -1 | awk '{print $2}')
#CURR_ANSIBLE_VER=$(ansible --version | head -1 | sed -e 's/.* //')
echo "Found Ansible ""$CURR_ANSIBLE_VER"
fi
if version_gt $MIN_ANSIBLE_VER $CURR_ANSIBLE_VER ; then
echo -e "\nEXITING: ansible-core ""$MIN_ANSIBLE_VER"" or higher required.\n"
echo -e "PLEASE RUN '/opt/iiab/iiab/scripts/ansible' to install the latest Ansible.\n"
echo -e "IIAB INSTALL INSTRUCTIONS: https://github.com/iiab/iiab/wiki/IIAB-Installation"
exit 1
fi
# Stage 0 will always be run. From there on up to Stage 9 we keep a counter
# (in /etc/iiab/iiab.env) of the highest completed Stage. Avoid repetition!
STAGE=0
if [ -f /etc/iiab/iiab.env ]; then
if grep -q STAGE= /etc/iiab/iiab.env ; then
source /etc/iiab/iiab.env
echo "Extracted STAGE=""$STAGE"" (counter) from /etc/iiab/iiab.env"
if ! [ "$STAGE" -eq "$STAGE" ] 2> /dev/null; then
echo -e "\nEXITING: STAGE (counter) value == ""$STAGE"" is non-integer in /etc/iiab/iiab.env"
exit 1
elif [ "$STAGE" -lt 0 ] || [ "$STAGE" -gt 9 ]; then
echo -e "\nEXITING: STAGE (counter) value == ""$STAGE"" is out-of-range in /etc/iiab/iiab.env"
exit 1
fi
fi
if $($REINSTALL); then
STAGE=0
#ARGS="$ARGS"" --extra-vars reinstall=True"
ARGS="$ARGS,\"reinstall\":True" # Needs boolean not string so use JSON list
sed -i 's/^STAGE=.*/STAGE=0/' /etc/iiab/iiab.env
echo "Wrote STAGE=0 (counter) to /etc/iiab/iiab.env"
elif [ "$STAGE" -ge 2 ] && $($DEBUG); then
STAGE=2
sed -i 's/^STAGE=.*/STAGE=2/' /etc/iiab/iiab.env
echo "Wrote STAGE=2 (counter) to /etc/iiab/iiab.env"
elif [ "$STAGE" -eq 9 ]; then
echo -e "\n\e[1mEXITING: STAGE (counter) in /etc/iiab/iiab.env shows Stage 9 Is Already Done.\e[0m"
usage
exit 0 # Allows rerunning https://download.iiab.io/install.txt
fi
fi
if [ "$STAGE" -lt 2 ] && $($DEBUG); then
echo -e "\n'--debug' *ignored* as STAGE (counter) < 2."
fi
# /etc/iiab/iiab_state.yml is mandatory and must be created here. Background:
# Allow iiab-install to read IIAB_STATE_FILE to not repeat installs of previous
# roles that already completed within the stage.
if [ ! -f $IIAB_STATE_FILE ]; then # touch $IIAB_STATE_FILE
echo -e "\nCreating... $IIAB_STATE_FILE"
cat > $IIAB_STATE_FILE << EOF
# DO *NOT* MANUALLY EDIT THIS, THANKS!
# IIAB does NOT currently support uninstalling apps/services.
EOF
fi
echo -e "\nTRY TO RERUN './iiab-install' IF IT FAILS DUE TO CONNECTIVITY ISSUES ETC!\n"
echo -e "\e[1mRunning local Ansible playbooks...\n...Stage 0 will now run\n...followed by Stages $(($STAGE + 1))-9\n...and then the Network Role.\e[0m\n"
export ANSIBLE_LOG_PATH="$CWD""/iiab-install.log"
ansible -m setup -i $INVENTORY localhost --connection=local | grep python
ansible -m setup -i $INVENTORY localhost --connection=local >> /dev/null # So vars are recorded in /opt/iiab/iiab/iiab-install.log
ARGS="$ARGS}"
echo -e "\nNOW RUN: ansible-playbook -i $INVENTORY $PLAYBOOK $ARGS --connection=local\n"
ansible-playbook -i $INVENTORY $PLAYBOOK $ARGS --connection=local
echo -e "./iiab-install $* COMPLETED IN $CWD\n\n"