forked from inblockio/aqua-PKC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pkc
executable file
·417 lines (377 loc) · 13.3 KB
/
pkc
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
#!/usr/bin/env bash
set -e
if [ "$EUID" -eq 0 ]; then
echo "Please don't run as root."
exit 1
fi
# For output coloring
LIGHT_GREEN='\033[0;32m'
NC='\033[0m' # No Color
usage() {
cat <<'EOF'
Usage:
pkc <command>
Options:
--help
Commands:
setup Setup the system for the first time and then run the system
stop Gracefully stop the system
start Resume running the system from a stopped state
backup Run the system backup
restore Run the system restore from backup
nuke Destroy containers and delete backup data
EOF
}
usage_setup() {
cat <<'EOF'
Usage:
pkc setup [OPTIONS]
Set up a PKC instance for the first time.
Options:
-w, --wallet-address <your crypto wallet address>
-s, --server <your server name; defaults to http://localhost:9352>
--private disable anonymous page read
--web-public expect --server <mediawiki.domain> --eauth-server <eauth.domain> --le-email <[email protected]>
--empty-wiki setup without default wiki content
--disable-autobackup disable MediaWiki auto backup service
EOF
}
check_wallet_address() {
if [ -z "$WALLET_ADDRESS" ]; then
echo "Error: you must specify the wallet address."
usage_setup
exit 1
fi
# https://ethereum.stackexchange.com/questions/1374/how-can-i-check-if-an-ethereum-address-is-valid
# TODO make this address validation more comprehensive.
if [[ ! "$WALLET_ADDRESS" =~ ^(0x)?[0-9a-fA-F]{40}$ ]]; then
echo "Error: Your wallet address is not a valid Ethereum address."
exit 1
fi
}
check_dependencies() {
local initsys
# Check Docker installation
if [[ ! -x "$(command -v docker)" ]]; then
echo "Error: Docker is not yet installed. Aborting PKC installation." >&2
exit 1
fi
# Check docker-compose installation
if [[ ! -x "$(command -v docker-compose)" ]]; then
echo "Error: docker-compose is not yet installed. Aborting PKC installation." >&2
exit 1
fi
# Check git installation
if [[ ! -x "$(command -v git)" ]]; then
echo "Error: Git is not yet installed. Aborting PKC installation." >&2
exit 1
fi
# Check Docker daemon running
initsys=$(ps 1 | head -n 2 | tail -n 1 | awk '{print $5}')
if [[ $initsys == *"systemd"* ]]; then
echo "systemd init system detected. Ensuring Docker is running..."
sudo systemctl start docker.service
elif [[ $initsys == *"launchd"* ]]; then
echo "launchd init system detected. Ensuring Docker is running..."
if [[ ! "$(docker version)" == *"Engine"* ]]; then
open /Applications/Docker.app
echo "Waiting for Docker Desktop to start..."
fi
local i=1
local sp="/-\|"
echo -n ' '
until [[ "$(docker version 2>/dev/null)" == *"Engine"* ]]; do
# shellcheck disable=SC2059
printf "\b${sp:i++%${#sp}:1}"
sleep 1
done
echo ""
fi
}
ensure_submodules() {
# Ensure submodule dependencies are downloaded
mkdir -p mountPoint/extensions
# Ensure DataAccounting repo exists
if [ ! -d ../DataAccounting ]; then
echo "DataAccounting repo doesn't exist. Downloading..."
# We need to do this line in a subshell so that the current directory is
# not modified.
(cd .. && git clone https://github.com/inblockio/DataAccounting.git)
else
echo "DataAccounting repo exists. But you may want to update it after this setup."
fi
# Ensure MediaWiki_Backup repo exists
if [ ! -d aqua/MediaWiki_Backup ]; then
echo "MediaWiki_Backup repo doesn't exist. Downloading..."
(cd aqua && git clone https://github.com/inblockio/MediaWiki_Backup.git)
else
echo "Updating MediaWiki_Backup repo..."
(cd aqua/MediaWiki_Backup && git pull)
fi
ln -sf "$PWD/aqua/MediaWiki_Backup" mountPoint/MediaWiki_Backup
PARENTDIR="$(dirname "$PWD")"
DEST=mountPoint/extensions/DataAccounting
if [[ -L "$DEST" && -d "$DEST" ]]; then
true
else
echo "Making a symlink for the DataAccounting repo..."
SOURCE="$PARENTDIR/DataAccounting"
echo "Source: $SOURCE"
ln -sf "$SOURCE" "$DEST"
fi
# Download latest PKC-Content repo
git submodule update --init --recursive --remote
}
validate_web_public_detail() {
local pkc_server=$1
local eauth_server=$2
local letsencrypt_email=$3
if [ -z "$pkc_server" ]; then
echo "Error: You specified '--web-public' but didn't specify the MediaWiki server via '--server'"
exit 1
fi
if [[ "$pkc_server" == *"https:"* ]]; then
echo "Error: Your MediaWiki server must not contain the https scheme"
exit 1
fi
if [ -z "$eauth_server" ]; then
echo "Error: You specified '--web-public' but didn't specify the Eauth server via '--eauth-server'"
exit 1
fi
if [[ "$eauth_server" == *"https:"* ]]; then
echo "Error: Your Eauth server must not contain the https scheme"
exit 1
fi
if [ -z "$letsencrypt_email" ]; then
echo "Error: You specified '--web-public' but didn't specify the Let's Encrypt email via '--le-email'"
exit 1
fi
}
setup_proxy_server() {
echo "Setting up Nginx proxy server with Let's Encrypt"
(cd proxy_server && sudo docker-compose up -d)
echo "Sleeping for 3s 💤 💤"
sleep 3
echo "Proxy setup done!"
}
prepare_web_public() {
local pkc_server=$1
local eauth_server=$2
local letsencrypt_email=$3
setup_proxy_server
echo "Applying your domain details"
sed -i "s|MEDIAWIKI_HOST=.*|MEDIAWIKI_HOST=$pkc_server|" .env
sed -i "s|EAUTH_HOST=.*|EAUTH_HOST=$eauth_server|" .env
sed -i "s/LETSENCRYPT_EMAIL=.*/LETSENCRYPT_EMAIL=$letsencrypt_email/" .env
if ! grep -q "proxy_server_net" docker-compose.yml; then
echo " proxy_server_net:" >> docker-compose.yml
echo " external: true" >> docker-compose.yml
sed -i "s/#WEBPUBLICPLACEHOLDER/- proxy_server_net/" docker-compose.yml
fi
}
prepare_dotenv() {
echo '# This file is autogenerated by <pkc setup>' > .env
cat .env.template >> .env
}
do_docker_compose_up_maybe_backup() {
sudo docker-compose up -d
if [ -f .autobackup ]; then
echo "Starting cron for auto-backup"
sudo docker exec micro-pkc-mediawiki service cron start
fi
}
run_setup() {
local web_public=false
local enable_autobackup=true
while [ "$#" -gt 0 ]; do
case "$1" in
-h|--help)
usage_setup
exit 0
;;
-w|--wallet-address)
WALLET_ADDRESS="$2"
shift
shift
;;
-s|--server)
PKC_SERVER="$2"
shift
shift
;;
--eauth-server)
EAUTH_SERVER="$2"
shift
shift
;;
--le-email)
LETSENCRYPT_EMAIL="$2"
shift
shift
;;
--empty-wiki)
empty_wiki=true
shift
;;
--private)
private=true
shift
;;
--web-public)
web_public=true
shift
;;
--disable-autobackup)
enable_autobackup=false
shift
;;
*) # unknown option
usage_setup
exit 0
;;
esac
done
check_dependencies
check_wallet_address
prepare_dotenv
# We persists the option of whether auto-backup is enabled or not in .autobackup.
# TODO: use .env instead
if [ "$enable_autobackup" = true ]; then
touch .autobackup
else
rm -f .autobackup
fi
if [ "$web_public" = true ]; then
validate_web_public_detail "$PKC_SERVER" "$EAUTH_SERVER" "$LETSENCRYPT_EMAIL"
echo "MediaWiki server name: $PKC_SERVER"
echo "Eauth server name: $EAUTH_SERVER"
echo "Let's Encrypt email: $LETSENCRYPT_EMAIL"
prepare_web_public "$PKC_SERVER" "$EAUTH_SERVER" "$LETSENCRYPT_EMAIL"
# Add https:// scheme
PKC_SERVER="https://$PKC_SERVER"
EAUTH_SERVER="https://$EAUTH_SERVER"
else
if [ -z "$PKC_SERVER" ]; then
PKC_SERVER=http://localhost:9352
fi
echo "Server name: $PKC_SERVER"
fi
# Convert wallet address to lower case
# This is because the address returned in Metamask API is in lower case
WALLET_ADDRESS=$(echo "$WALLET_ADDRESS" | tr "\[A-Z\]" "\[a-z\]")
ensure_submodules
echo "Specifying the server name into Eauth"
# use perl to account for cross-OS limitations of sed
# https://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux/14813278#14813278
perl -i -p -e "s|PKC_SERVER|$PKC_SERVER|" .env
echo "Executing docker-compose up -d. Be prepared to type your password."
# Support version 1 / 2 of docker-compose
do_docker_compose_up_maybe_backup
# Sleep; just to be sure that the container has initialized well.
echo "Sleeping for 10 seconds to wait for the database to be ready."
echo "Here's an invitation to grab a ☕ or take a deep breath."
sleep 10
echo "Installing MediaWiki"
# TODO split failure cases and remove || true
sudo docker exec micro-pkc-mediawiki ./aqua/install_pkc.sh \
--wallet-address "$WALLET_ADDRESS" \
--pkc-server "$PKC_SERVER" \
--eauth-server "$EAUTH_SERVER" \
${empty_wiki:+--empty-wiki} \
${private:+--private} || true
# TODO REMOVE THIS ONCE PELITH HAS FIXED THEIR RETRY BUG
sudo docker exec micro-pkc-eauth pkill node
# Prepare auto backup
sudo cp aqua/do_backup_wrapper.sh mountPoint/backup
if [ "$enable_autobackup" = true ]; then
echo "Enabling auto-backup every 30 minutes"
sudo docker exec micro-pkc-mediawiki sh -c '(echo "*/30 * * * * /backup/do_backup_wrapper.sh") | sort - | uniq - | crontab -'
else
echo "Note: auto-backup is disabled"
fi
echo "Done!"
}
restore_all() {
archive_file=$1
# Extract tarball and restore images
docker exec -it micro-pkc-mediawiki /MediaWiki_Backup/extract_and_restore_images.sh -a "/backup/$archive_file" -w /var/www/html
# Restore database
docker exec -it micro-pkc-database /MediaWiki_Backup/restore_database.sh /backup/database.sql.gz
# Clean up database sql file
docker exec -it micro-pkc-database rm /backup/database.sql.gz
# Toggle read-only off
docker exec -it micro-pkc-mediawiki /MediaWiki_Backup/toggle_read_only_off.sh /var/www/html
}
if [ $# -eq 0 ]; then
# If no argument is provided, provide info and exit early.
usage
exit 0
fi
# We don't use getopt because we want to support running micro-pkc on macOS.
# macOS has getopt, but it doesn't have `long` option
# See https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
# https://unix.stackexchange.com/questions/520028/parsing-arguments-with-nested-case-statements
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-h|--help)
usage
exit 0
;;
setup)
shift
run_setup "$@"
break
;;
stop)
sudo docker-compose stop
break
;;
start)
do_docker_compose_up_maybe_backup
break
;;
backup)
sudo docker exec micro-pkc-mediawiki /MediaWiki_Backup/backup.sh \
-p "$(date -u +"%Y-%m-%dT%H-%M-%S_UTC")" -d /backup -w /var/www/html -s -f
echo -e "${LIGHT_GREEN}Done! Your backup is located in ./mountPoint/backup.${NC}"
break
;;
restore)
most_recent=$(ls -t mountPoint/backup/*.tar.gz | head -n 1 | xargs basename)
restore_all "$most_recent"
# A reset is required to flush outdated cache from the system.
sudo docker-compose stop
do_docker_compose_up_maybe_backup
break
;;
nuke)
# Check we are in the micro-PKC repository
current_repository=$(git config --get remote.origin.url)
if [[ "$current_repository" != *"micro-PKC"* ]]; then
echo "pkc nuke must be run from the micro-PKC directory. Aborting..."
exit 1
fi
read -r -p $'Destroying containers and deleting backup data. \n\tAre you sure? 😱 [y/N] ' response
case "$response" in
[yY][eE][sS]|[yY])
echo "💥💥💥💥 Kaaboooom!!!💥💥💥💥"
set -x
sudo docker-compose down
sudo rm -r mountPoint
set +x
echo "🏜️ It's all gone 🏜️"
;;
*)
echo "Aborting..."
exit 0
;;
esac
break
;;
*) # unknown option
usage
exit 0
;;
esac
done