-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathinstall.sh
336 lines (272 loc) · 12.2 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
#!/usr/bin/env bash
set -e
# Try re-running with sudo
[ "$UID" -eq 0 ] || exec sudo bash "$0" "$@"
# Required to do when unit files are changed or removed
function reloadSystemd() {
echo "Reloading systemd manager configuration..."
systemctl daemon-reload
}
SPATH=$(dirname "$0") # Path to the script
REMOTE_URL=https://raw.githubusercontent.com/jacklul/pihole-updatelists # Remote URL that serves raw files from the repository
GIT_BRANCH=master # Git branch to use, user can specify custom branch as first argument
# Install environment detection
SYSTEMD=$({ [ -n "$(pidof systemd)" ] || [ "$(readlink -f /sbin/init)" = "/usr/lib/systemd/systemd" ]; } && echo "1" || echo "0") # Is systemd available?
DOCKER=$(grep -q "docker" /proc/1/cgroup 2> /dev/null && echo "1" || echo "0") # Is this a Docker container?
ENTWARE=$( [ -f /opt/etc/opkg.conf ] && echo "1" || echo "0") # Is this an Entware installation?
# Install paths
BIN_PATH=/usr/local/sbin
ETC_PATH=/etc
VAR_TMP_PATH=/var/tmp
# Install commands (with args)
RM_CMD="rm -vf"
MKDIR_CMD="mkdir -vp"
CP_CMD="cp -v"
MV_CMD="mv -v"
CHMOD_CMD="chmod -v"
# Map old Pi-hole versions to branches
declare -A OLD_VERSION_BRANCH_MAP=(
[5]="pihole-v5"
#[6]="pihole-v6" # when V7 release
)
if [ "$1" == "docker" ]; then # Force Docker install
DOCKER=1
elif [ "$1" == "entware" ]; then # Force Entware install
ENTWARE=1
elif [ "$1" == "systemd" ]; then # Force systemd unit files installation
SYSTEMD=1
elif [ "$1" == "crontab" ]; then # Force crontab installation
SYSTEMD=0
elif [ "$1" != "" ]; then # Install using different branch
GIT_BRANCH=$1
if ! wget -q --spider "$REMOTE_URL/$GIT_BRANCH/install.sh" ; then
echo "Invalid branch: ${GIT_BRANCH}"
exit 1
fi
fi
# Do not install systemd unit files inside Docker container
if [ "$DOCKER" == 1 ]; then
SYSTEMD=0
fi
# Overrides for Entware environment
if [ "$ENTWARE" == 1 ]; then
if [ -z "$BASH_VERSION" ]; then
echo "This script requires Bash shell to run."
exit 1
fi
# Update PATH
PATH=/opt/bin:/opt/sbin:$PATH
# Make sure it will be crontab installation
SYSTEMD=0
# Override paths
BIN_PATH=/opt/usr/sbin
ETC_PATH=/opt/etc
VAR_TMP_PATH=/opt/tmp
# No -v flags on most Busybox implementations!
RM_CMD="rm -f"
MKDIR_CMD="mkdir -p"
CP_CMD="cp"
MV_CMD="mv"
CHMOD_CMD="chmod"
fi
if [ "$1" == "uninstall" ] || [ "$2" == "uninstall" ]; then # Simply remove the files and reload systemd (if available)
$RM_CMD "$BIN_PATH/pihole-updatelists"
$RM_CMD "$ETC_PATH/bash_completion.d/pihole-updatelists"
$RM_CMD "$ETC_PATH/cron.d/pihole-updatelists"
$RM_CMD "$ETC_PATH/systemd/system/pihole-updatelists.service"
$RM_CMD "$ETC_PATH/systemd/system/pihole-updatelists.timer"
if [ -f "$VAR_TMP_PATH/pihole-updatelists.old" ]; then
$RM_CMD "$VAR_TMP_PATH/pihole-updatelists.old"
fi
if [ "$SYSTEMD" == 1 ]; then
reloadSystemd
fi
exit 0
fi
# Some systems might use php-cli instead of php
PHP_CMD=php
command -v php-cli >/dev/null 2>&1 && PHP_CMD=php-cli
# We check some stuff before continuing
command -v $PHP_CMD >/dev/null 2>&1 || { echo "This script requires PHP CLI to run - install 'php-cli' package."; exit 1; }
[[ $($PHP_CMD -v | head -n 1 | cut -d " " -f 2 | cut -f1 -d".") -lt 7 ]] && { echo "Detected PHP version lower than 7.0, make sure php-cli package is up to date!"; exit 1; }
command -v pihole >/dev/null 2>&1 || { echo "Unable to find 'pihole' command, is the Pi-hole even installed?"; exit 1; }
PIHOLE_VERSION="$(pihole version | grep -oP "[vV]ersion is v\K[0-9.]" | head -n 1)"
if [ -z "$PIHOLE_VERSION" ]; then
echo "Failed to detect Pi-hole version, you're continuing at your own risk."
read -rp "Press Enter to continue..."
fi
if [ -n "$PIHOLE_VERSION" ] && [[ -n "${OLD_VERSION_BRANCH_MAP[$PIHOLE_VERSION]}" ]]; then
NEW_BRANCH="${OLD_VERSION_BRANCH_MAP[$PIHOLE_VERSION]}"
echo "You are running Pi-hole V$PIHOLE_VERSION which is not supported on this branch."
echo "This script can automatically fetch and execute the correct install script from '$NEW_BRANCH' branch."
#shellcheck disable=SC2162
read -p "Do you want to proceed? (y/N): " response
if [[ $response =~ ^[Yy](es)?$ ]]; then
exec wget -O - "$REMOTE_URL/$NEW_BRANCH/install.sh" | bash -s "$NEW_BRANCH"
fi
exit 1
fi
if [ "$PIHOLE_VERSION" -ne 6 ]; then
echo "Unsupported Pi-hole version (V$PIHOLE_VERSION) detected, you're continuing at your own risk."
read -rp "Press Enter to continue..."
fi
# Use local files when possible, otherwise install from remote repository
if \
[ "$GIT_BRANCH" == "master" ] && \
[ -f "$SPATH/pihole-updatelists.php" ] && \
[ -f "$SPATH/pihole-updatelists.conf" ] && \
[ -f "$SPATH/pihole-updatelists.service" ] && \
[ -f "$SPATH/pihole-updatelists.timer" ] && \
[ -f "$SPATH/pihole-updatelists.bash" ] \
; then
if [ ! -d "$BIN_PATH" ]; then
$MKDIR_CMD "$BIN_PATH" && $CHMOD_CMD 0755 "$BIN_PATH"
fi
if [ -f "$BIN_PATH/pihole-updatelists" ]; then
if ! cmp -s "$SPATH/pihole-updatelists.php" "$BIN_PATH/pihole-updatelists"; then
echo "Backing up previous version..."
$CP_CMD "$BIN_PATH/pihole-updatelists" "$VAR_TMP_PATH/pihole-updatelists.old" && \
$CHMOD_CMD -x "$VAR_TMP_PATH/pihole-updatelists.old"
fi
fi
$CP_CMD "$SPATH/pihole-updatelists.php" "$BIN_PATH/pihole-updatelists" && \
$CHMOD_CMD +x "$BIN_PATH/pihole-updatelists"
if [ ! -f "$ETC_PATH/pihole-updatelists.conf" ]; then
$CP_CMD "$SPATH/pihole-updatelists.conf" "$ETC_PATH/pihole-updatelists.conf"
fi
if [ "$SYSTEMD" == 1 ]; then
$CP_CMD "$SPATH/pihole-updatelists.service" "$ETC_PATH/systemd/system"
$CP_CMD "$SPATH/pihole-updatelists.timer" "$ETC_PATH/systemd/system"
fi
if type _init_completion >/dev/null 2>&1; then
if [ ! -d "$ETC_PATH/bash_completion.d" ]; then
$MKDIR_CMD "$ETC_PATH/bash_completion.d"
fi
$CP_CMD "$SPATH/pihole-updatelists.bash" "$ETC_PATH/bash_completion.d/pihole-updatelists"
fi
# Convert line endings when dos2unix command is available
if command -v dos2unix >/dev/null 2>&1; then
for file in "$BIN_PATH/pihole-updatelists" "$ETC_PATH/bash_completion.d/pihole-updatelists"; do
[ -f "$file" ] && dos2unix "$file"
done
fi
elif [ "$REMOTE_URL" != "" ] && [ "$GIT_BRANCH" != "" ]; then
if [ ! -d "$BIN_PATH" ]; then
$MKDIR_CMD "$BIN_PATH" && $CHMOD_CMD 0755 "$BIN_PATH"
fi
if [ -f "$BIN_PATH/pihole-updatelists" ]; then
wget -nv -O /tmp/pihole-updatelists.php "$REMOTE_URL/$GIT_BRANCH/pihole-updatelists.php"
if ! cmp -s "/tmp/pihole-updatelists.php" "$BIN_PATH/pihole-updatelists"; then
echo "Backing up previous version..."
$CP_CMD "$BIN_PATH/pihole-updatelists" "$VAR_TMP_PATH/pihole-updatelists.old" && \
$CHMOD_CMD -x "$VAR_TMP_PATH/pihole-updatelists.old"
fi
$MV_CMD /tmp/pihole-updatelists.php "$BIN_PATH/pihole-updatelists" && \
$CHMOD_CMD +x "$BIN_PATH/pihole-updatelists"
else
wget -nv -O "$BIN_PATH/pihole-updatelists" "$REMOTE_URL/$GIT_BRANCH/pihole-updatelists.php" && \
$CHMOD_CMD +x "$BIN_PATH/pihole-updatelists"
fi
if [ ! -f "$ETC_PATH/pihole-updatelists.conf" ]; then
wget -nv -O "$ETC_PATH/pihole-updatelists.conf" "$REMOTE_URL/$GIT_BRANCH/pihole-updatelists.conf"
fi
if [ "$SYSTEMD" == 1 ]; then
wget -nv -O "$ETC_PATH/systemd/system/pihole-updatelists.service" "$REMOTE_URL/$GIT_BRANCH/pihole-updatelists.service"
wget -nv -O "$ETC_PATH/systemd/system/pihole-updatelists.timer" "$REMOTE_URL/$GIT_BRANCH/pihole-updatelists.timer"
fi
if type _init_completion >/dev/null 2>&1; then
if [ ! -d "$ETC_PATH/bash_completion.d" ]; then
$MKDIR_CMD "$ETC_PATH/bash_completion.d"
fi
wget -nv -O "$ETC_PATH/bash_completion.d/pihole-updatelists" "$REMOTE_URL/$GIT_BRANCH/pihole-updatelists.bash"
fi
else
echo "Missing required files for installation!"
exit 1
fi
# Remove old backups in bin directory
if [ -f "$BIN_PATH/pihole-updatelists.old" ]; then
$RM_CMD "$BIN_PATH/pihole-updatelists.old"
fi
# Install schedule related files
if [ "$SYSTEMD" == 1 ]; then
if [ -f "$ETC_PATH/cron.d/pihole-updatelists" ]; then
# Comment out the existing cron job
sed "s/^#*/#/" -i "$ETC_PATH/cron.d/pihole-updatelists"
fi
if ! systemctl -q is-active pihole-updatelists.timer; then
echo "Enabling and starting pihole-updatelists.timer..."
systemctl enable pihole-updatelists.timer && systemctl start pihole-updatelists.timer
else
reloadSystemd
fi
elif [ "$DOCKER" == 0 ]; then
if [ -d "$ETC_PATH/cron.d" ]; then
if [ ! -f "$ETC_PATH/cron.d/pihole-updatelists" ]; then
echo "# Pi-hole's Lists Updater by Jack'lul
# https://github.com/jacklul/pihole-updatelists
#30 3 * * 6 root $BIN_PATH/pihole-updatelists
" > "$ETC_PATH/cron.d/pihole-updatelists"
sed "s/#30 /$((1 + RANDOM % 58)) /" -i "$ETC_PATH/cron.d/pihole-updatelists"
chmod 644 "$ETC_PATH/cron.d/pihole-updatelists"
echo "Created crontab ($ETC_PATH/cron.d/pihole-updatelists)"
fi
else
echo "Missing $ETC_PATH/cron.d directory - crontab will not be installed!"
fi
fi
# Entware related tasks
if [ "$ENTWARE" == 1 ]; then
# While on most systems crontab will accept 644 here, cron in Entware requires 600
chmod 600 "$ETC_PATH/cron.d/pihole-updatelists"
if command -v id >/dev/null 2>&1; then
ROOT_USER="$(id -nu 0 2> /dev/null)"
if [ "$ROOT_USER" != "root" ] && grep -Fq " root " /opt/etc/cron.d/pihole-updatelists; then
echo "Warning: Root user is not called root ($ROOT_USER) - correcting username in crontab..."
sed "s/ root / $ROOT_USER /g" -i /opt/etc/cron.d/pihole-updatelists
fi
fi
fi
# Docker related tasks
if [ "$DOCKER" == 1 ]; then
[ ! -f /usr/bin/php ] && { echo "Missing /usr/bin/php binary - was the 'php' package installed?"; exit 1; }
[ ! -f /usr/bin/start.sh ] && { echo "Missing /usr/bin/start.sh script - not a Pi-hole container?"; exit 1; }
if [ -f "$SPATH/docker.sh" ]; then
cp -v "$SPATH/docker.sh" /usr/bin/pihole-updatelists.sh
elif [ "$REMOTE_URL" != "" ]; then
wget -nv -O /usr/bin/pihole-updatelists.sh "$REMOTE_URL/$GIT_BRANCH/docker.sh"
else
echo "Missing required file (docker.sh) for installation!"
exit 1
fi
chmod -v +x /usr/bin/pihole-updatelists.sh
mkdir -vp /etc/pihole-updatelists
if ! grep -q "pihole-updatelists" /crontab.txt; then
# Use the same schedule string to also have it randomized
CRONTAB=$(sed -n '/pihole updateGravity/s/\(.*\) PATH=.*/\1/p' /crontab.txt)
#shellcheck disable=SC2140
echo "$CRONTAB PATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:\$PATH\" pihole-updatelists.sh run >/var/log/pihole-updatelists-cron.log || cat /var/log/pihole-updatelists-cron.log" >> /crontab.txt
echo "# DO NOT MODIFY THIS FILE - USE 'CRONTAB_STRING' ENVIRONMENT VARIABLE INSTEAD!" >> /crontab.txt
echo "Created crontab entry in /crontab.txt"
fi
if ! grep -q "^#.*pihole updateGravity" crontab.txt; then
sed -e '/pihole updateGravity/ s/^#*/#/' -i /crontab.txt
echo "Disabled default gravity update entry in /crontab.txt"
fi
echo "Modifying /usr/bin/start.sh script..."
sed '/^\s\+ftl_config/a pihole-updatelists.sh config' -i /usr/bin/start.sh
sed '/^\s\+start_cron/i pihole-updatelists.sh cron' -i /usr/bin/start.sh
if
! grep -q "pihole-updatelists.sh config" /usr/bin/start.sh ||
! grep -q "pihole-updatelists.sh cron" /usr/bin/start.sh
then
echo "Modification of /usr/bin/start.sh script failed!"
exit 1
fi
echo "Modifying /usr/bin/bash_functions.sh script..."
sed '/^\s\+pihole -g/a pihole-updatelists.sh run' -i /usr/bin/bash_functions.sh
if ! grep -q "pihole-updatelists.sh run" /usr/bin/bash_functions.sh; then
echo "Modification of /usr/bin/bash_functions.sh script failed!"
exit 1
fi
fi