-
Notifications
You must be signed in to change notification settings - Fork 2
/
node-creator
512 lines (394 loc) · 17.9 KB
/
node-creator
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
#!/bin/bash
# declare the variables required for this script
function declareVars() {
# this group will be created for docker
group_to_add=docker
# this is the url for the blockchain archive
blockchain_7zip_url="https://archive.metervalidatorbot.com/archive"
# if this flag is true we will download the chain to bootstrap the node installation
download_chain_flag='false'
# regenerate the public
regenerate_public_key='false'
# if this flag is true we will force remove any related containers that the end user may have attempted to install
# themselves
force_removal_flag='false'
# if this flag is true we will download and install the watchtower container
watchtower_install_flag='false'
# force Y response to all messages
assume_yes='false'
# yes and no options accepted at keyboard prompts
yes_option="y"
no_option="n"
install_directory="$HOME/meter_main_data"
# mega installer package - blank by default
mega_installer_package=''
# by default we will remove the mega application after the script has finished executing
remove_mega_after_archive_download='true'
}
# outputAscii outputs the ascii text
function outputAscii() {
echo "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
0000000000000000|0xffbeddcaa68dc953ee4f3d040ab83cb0ac65498b|000000000000000
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMWNXKOkxdoollllooddxO0XNWMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMWXOdl:,'.................,;cox0XWMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMWN0dc,.............................,cx0NMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMN0d:'.......';:lodxxkkkkkxxdol:,'.......':d0NMMMMMMMMMMMMMMM
MMMMMMMMMMMMWNkc'......':ok0XWWMMMMMMMMMMMMMWWX0xo:'......'ckXMMMMMMMMMMMMM
MMMMMMMMMMMNk:......,lxKNWMMMMMMMMMMMMMMMMMMMMMMMWN0xc'......:kNMMMMMMMMMMM
MMMMMMMMMW0c......:xKWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN0o;.....'c0WMMMMMMMMM
MMMMMMMMXd,.....:kXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXx;.....,xNMMMMMMMM
MMMMMMMKl.....,dXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXd,....'oXMMMMMMM
MMMMMMKc.....c0WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWO:.....lXMMMMMM
MMMMMXl.....lKMMMMMMMMMMMMMMMMNKXMMMMMMMMMMMMMMMWXKNMMMMMMMMWKc....;xNMMMMM
MMMMNd'....lXMMMMMMMMMMMMMMWKx:c0MMMMMMMMMMMWN0xl,c0MMMMMMMMMWXxdxOKNWMMWWW
MMMWO,....:0MMMMMMMMMMMMMNOo,..cKMMMMMMMMWXOo:'...lXMMMMMMMMMMMMMWWXKOO0KNW
MMMXl....'xWMMMMMMMMMMWXxc'....oNMMMWWN0xc,.......oNMMMMMMMWNX0kdolodkKNWMM
MMM0;....cKMMMMMMMMMN0o;......'kWNKkoc;'.........'xWMWNKOxol:,',cdOXWMWWMMM
MMWk,....oNMMMMMMWXkc'........'ldc,........'.....'ldoc;'...';okKWMWX0do0MMM
MMWx'....xWMMMMN0o;....................':dkl'...........;lx0NWMMW0l;'.'xWMM
MMWx'..'lKMMWXkc'.....,:;..........;loxKNWKc........,:dOXWMMMMMMNo....'xWMM
MMMk;;d0WMWKd;....,cdOXKc......':oOXWMMMMWx'....';okKNMMMMMMMMMMXl....'kMMM
MMMX0XWWNOl,..,cdOXWMMM0;...,cx0NWMMMMMMMKc..,cx0NWMMMMMMMMMMMMMK:....;0MMM
MMMMMWKx:,;cdOXWMMMMMMWx;;okXWMMMMMMMMMMWOodOXWMMMMMMMMMMMMMMMMWk'....oNMMM
MMMNOdcldOXWMMMMMMMMMMWK0NWMMMMMMMMMMMMMWNWMMMMMMMMMMMMMMMMMMMM0:....,OWMMM
WN0kkOXWMWNKNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMKc.....oNMMMM
NXXWMMWKxl;,lXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMKl.....cKMMMMM
MMMMMMXo.....c0WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMW0c.....cKMMMMMM
MMMMMMWKl.....,dXWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXx;.....lKMMMMMMM
MMMMMMMMXd,.....:kNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNk:.....,dXMMMMMMMM
MMMMMMMMMW0c......:xXWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKx:......cOWMMMMMMMMM
MMMMMMMMMMMNk:......,okXWMMMMMMMMMMMMMMMMMMMMMMMMMWXkl,......:kNMMMMMMMMMMM
MMMMMMMMMMMMMNkc'......,cdkKNWMMMMMMMMMMMMMMMWNKOdc,......'ckXWMMMMMMMMMMMM
MMMMMMMMMMMMMMMN0o;........';codxkkOOOOOOkxdoc;'........;o0NMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMWXOd:'.............................,cdOXWMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMNKkdc;,..................',:ldOXWMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMWNK0Oxdooolooolooodxk0XNWMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
0000000000000000|0xffbeddcaa68dc953ee4f3d040ab83cb0ac65498b|000000000000000"
}
# this function will return true if the application passed into it exists on the system
function isInstalled()
{
command -v "$1" >/dev/null 2>&1
}
# this function outputs the help text / manual for the -h output
function outputHelpText() {
echo "Below are the possible options to use this tool."
echo "-d will download the chain before your node boots. It speeds up the process considerably."
echo "-f will force remove any existing docker images if you have attempted to install/run them before."
echo "-w will download and install watchtower."
echo "-h will show this prompt."
echo -e "\nPlease note that the options can be chained ie -dfw will chain the above options."
exit
}
# outputs the exit message
function exitMessage() {
outputAscii
echo "~~~~~ Don't forget to open your ports!!"
if [ "$watchtower_install_flag" == 'false' ]; then
echo "~~~~~ You opted not to install Watchtower. Please note this means that you must install updates yourself. Watchtower is advised."
fi
echo "~~~~~ Please consider making a MTR/MTRG donation if this script helped you [ 0xffbeddcaa68dc953ee4f3d040ab83cb0ac65498b ]. It would really help with the hosting costs. Thanks!"
}
installMegaIfRequired() {
if isInstalled mega-version; then
# we dont want to remove mega if it already existed before executing this script
remove_mega_after_archive_download='false'
return 1
elif test -r "/etc/os-release"; then
# source the os-release file
. /etc/os-release
# todo - allow the end user to pass in a defined debian package URL to use
if [ "$VERSION_CODENAME" == "bionic" ]; then
# 18.04
deb="https://mega.nz/linux/MEGAsync/xUbuntu_18.04/amd64/megacmd_1.5.1-1.1_amd64.deb"
elif [ "$VERSION_CODENAME" == "focal" ]; then
# 20.04
deb="https://mega.nz/linux/MEGAsync/xUbuntu_20.04/amd64/megacmd_1.5.1-1.1_amd64.deb"
elif [ "$VERSION_CODENAME" == "bullseye" ]; then
deb="https://mega.nz/linux/MEGAsync/Debian_11/amd64/megacmd_1.5.1-1.1_amd64.deb"
elif [ "$VERSION_CODENAME" == "buster" ]; then
deb="https://mega.nz/linux/MEGAsync/Debian_10.0/amd64/megacmd_1.5.1-1.1_amd64.deb"
else
return 0
fi
else
return 0
fi
# download the package
wget -O ~/mega_debian_package.deb $deb
# attempt to install the package
# DEBIAN_FRONTEND=noninteractive will accept the defaults for any menu prompts
sudo DEBIAN_FRONTEND=noninteractive apt install ~/mega_debian_package.deb -y
# remove the installer
rm ~/mega_debian_package.deb
# required for Mega to start correctly
sudo ldconfig
}
# downloads the 7z archive that contains the blockchain data
function bootstrapChain() {
echo "~~~~~Give the container a minute to boot up... Please wait for 60 seconds"
sleep 1m
echo "Lets see if the folders have been created"
paths=($(find . -name "instance-*"))
printf "%s\n" "${paths[@]}"
node_dir=$paths
cd $node_dir
echo "~~~~~Changed directory to $PWD"
# get the container id
docker_container_id="$(< /tmp/meter_node_cont_id.txt)"
echo "~~~~~Now we will stop the container id:"
docker kill $docker_container_id
echo "~~~~~While the blockchain is downloading, you could spend the time opening ports following point 2(e) of this guide here: https://paolo-g.medium.com/step-by-step-guide-to-creating-a-node-in-meter-mainnet-4cdde1085fbb"
echo "~~~~~Lets download the blockchain data to bootstrap the syncing process"
# assume we won't use mega for the download
use_mega_link_for_download='false'
# install the Mega application - it will be removed if not already installed on the system after the archive is downloaded
installMegaIfRequired
# check if Mega is usable
if isInstalled mega-version; then
# get the url for the latest archive
megaLink=$(wget -q -O - https://archive.metervalidatorbot.com/archive-mega-link)
# make sure we got a response value
if [ megaLink ]; then
echo "Mega Link fetched successfully: [$megaLink]"
echo "We will use Mega to download the mirror - which is much faster"
use_mega_link_for_download='true'
fi
fi
# check if the we can use Mega (if any of the vars below are empty)
if [[ -z $use_mega_link_for_download || -z $megaLink ]]; then
echo "Issue occurred trying to use Mega. Falling back to server mirror for download:"
# fall back to the slower mirror
downloadStatus=$(downloadArchiveViaWget)
if [ "$downloadStatus" -ne 0 ]; then
echo "Failed to download the archive. Please try again."
exit
fi
else
echo "Mega application may take a second to start before the download starts...."
echo "Please wait..."
# trigger the download
sudo mega-get $megaLink instance.7z
# remove the mega application if it was installed by the script
# we do this here instead of above the isInstalled check because the installation may have been attempted, but failed.
if $remove_mega_after_archive_download; then
echo "Removing the Mega application now that the archive is downloaded..."
sudo apt remove -f -y megacmd
fi
fi
echo "~~~~~Please wait - now unpacking the data"
sudo 7z x instance.7z -aoa
echo "~~~~~Deleting the 7z archive now that is is unpacked"
sudo rm instance.7z
docker start meter_main
rm /tmp/meter_node_cont_id.txt
}
# function to download the archive via wget and handle any timeouts
function downloadArchiveViaWget() {
local attempt=0
local max_attempts=100
local archive_download_complete=false
while [[ $archive_download_complete == false && "$attempt" -le "$max_attempts" ]]
do
attempt=$(( $attempt + 1 ))
sudo wget --continue --tries=0 -O instance.7z $blockchain_7zip_url -q --show-progress
if [ $? -eq 0 ]; then
archive_download_complete=true
elif [ "$attempt" -lt "$max_attempts" ]; then
echo -e "~~~~~Intermittent issue occurred whilst downloading archive... please wait..." >&2
sleep 30s
fi
done
# return a value based on the above status
if [ $archive_download_complete == true ]; then
echo 0
else
echo 1
fi
}
# the main function
function main() {
local flag
# output the ASCII art
outputAscii
declareVars
# this string contains the text that will output to the end user before they confirm their choices (if y is not set)
message_for_output=""
while getopts 'dfwhpyi:m:' flag; do
case "${flag}" in
h)
outputHelpText
;;
d)
# lets make sure that the mirror is actually available before setting the flag
if wget --spider $blockchain_7zip_url 2>/dev/null; then
# it looks like the mirror is UP
message_for_output="${message_for_output} ~opted to download the blockchain directly to speed up the syncing process\n"
download_chain_flag='true'
else
# looks like like the mirror is DOWN
message_for_output="${message_for_output} ~IMPORTANT:: You opted to download the blockchain directly, but sadly it appears the mirror is down. The script will still setup your node for you but it will have to sync as normal.\n"
download_chain_flag='false'
fi
;;
f)
message_for_output="${message_for_output} ~opted to force remove any container that has already been installed with the name meter_main\n"
force_removal_flag='true'
;;
p)
message_for_output="${message_for_output} ~opted to regenerate the public key\n"
regenerate_public_key='true'
;;
y)
message_for_output="${message_for_output} ~opted to accept all messages automatically\n"
assume_yes='true'
;;
w) message_for_output="${message_for_output} ~opted to install watchtower that will manage updates for you\n"
watchtower_install_flag='true'
;;
i)
install_directory=${OPTARG}
;;
m)
message_for_output="${message_for_output} ~requested to use ${OPTARG} as the mega installer package\n"
mega_installer_package=${OPTARG}
;;
esac
done
echo "@This script is provided as is without any warranty."
echo "@You are welcome to view the source of this script before executing."
echo "@Feel free to contribute"
echo "@If you have any interest in providing a mirror, please get in touch"
echo "@Twitter - https://twitter.com/DaveDeWire "
echo "@You may need to enter your sudo password during execution."
echo "@Please reach out in the Meter Validators Telegram group if you have any issues"
echo "https://t.me/Meter_IO"
echo "@Please confirm; you have:"
echo -e "${message_for_output}"
if [ "$assume_yes" == 'false' ]; then
mainmenuinput=""
echo Enter Y to continue:
while [[ ( $(echo ${mainmenuinput,,} | xargs) != ${yes_option} && $(echo ${mainmenuinput,,} | xargs) != ${no_option} ) ]]; do
read -n 1 mainmenuinput
done
if [ ${mainmenuinput,,} = ${yes_option} ]; then
echo -e "\n~BEGINNING"
else
echo -e "\nDid not confirm. Exiting"
exit
fi
fi
#groups
if grep -q $group_to_add /etc/group
then
echo "~~~~~group exists already. Not creating"
else
echo "~~~~~Group does not exist. Creating Now."
sudo groupadd $group_to_add
echo "~~~~~Group $group_to_add created"
fi
if groups $USER | grep -q $group_to_add
then
echo "~~~~~{$USER} is in group already. No need to re-add"
else
echo "~~~~~{$USER} Not in group yet adding now"
sudo usermod -aG $group_to_add $USER
echo "~~~~~{$USER} added to group {$group_to_add}"
echo "~When a user is added to a new group, the user must logout and log back in"
echo "~Because this script is designed to be run directly from GitHub, the safest"
echo "~way to do that is to restart the machine. When the machine reboots simply rerun the same command."
echo "~Are you happy to restart now??"
if [ "$assume_yes" == 'false' ]; then
restartconfirmation=""
echo Enter Y to continue:
while [[ ( $(echo ${restartconfirmation,,} | xargs) != ${yes_option} && $(echo ${restartconfirmation,,} | xargs) != ${no_option} ) ]]; do
read -n 1 restartconfirmation
done
else
restartconfirmation="y"
fi
if [ ${restartconfirmation,,} = ${yes_option} ]; then
echo -e "\n~~~~~Restarting now"
sudo reboot now
exit
else
echo -e "\n~~~~~Did not confirm. You will get unexpected results if you re-run without reloading your groups correctly! Exiting"
exit
fi
fi
echo "~~~~~Creating the install folder (if required)"
mkdir -p "$install_directory"
cd "$install_directory"
echo "~~~~~Setting the METER_MAIN_DATA_PATH variable in ~/.bashrc"
#unset in case it has been set previously
unset METER_MAIN_DATA_PATH
#set METER_MAIN_DATA_PATH variable
source <(grep -m 1 "METER_MAIN_DATA_PATH" ~/.bashrc )
#check if variable exists
if [ ! -d "$install_directory" ]; then
echo -e "~~~~~ERROR~~~~~"
echo -e "~~~~~The path provided $install_directory is not valid or could not be created"
echo -e "~~~~~Please check permissions or choose a different directory"
exit
elif [ -z "$METER_MAIN_DATA_PATH" ]; then
echo "$METER_MAIN_DATA_PATH Variable doesnt exist, setting in bashrc"
echo export "METER_MAIN_DATA_PATH=$PWD" >> ~/.bashrc
source <(grep -m 1 "METER_MAIN_DATA_PATH" ~/.bashrc )
elif [ "$METER_MAIN_DATA_PATH" != "$PWD" ]; then
echo -e "~~~~~ERROR~~~~~"
echo -e "$PWD"
echo -e "~~~~~The METER_MAIN_DATA_PATH variable already exists in ~/.bashrc - but contains the wrong value"
echo -e "~~~~~This variable is used to store the location of the data that is required to run a node so that it can be filtered through to docker."
echo -e "~~~~~Please edit ~/.bashrc with a text editor and remove the line:"
echo -e "export METER_MAIN_DATA_PATH=$METER_MAIN_DATA_PATH"
unset METER_MAIN_DATA_PATH
exit
fi
echo "~~~~~Path variable set to:"
echo $METER_MAIN_DATA_PATH
echo "~~~~~Lets install docker.io and 7zip"
sudo apt update -y
sudo apt install sudo docker.io p7zip-full -y
# if -f is passed in, we will force remove
if [ "$force_removal_flag" == 'true' ]; then
# remove container id file if exists
if [ -f "/tmp/meter_node_cont_id.txt" ]; then
echo "~~~~~removing container id file";
rm /tmp/meter_node_cont_id.txt
fi
if [ "$watchtower_install_flag" == 'true' ]; then
echo "~~~~~Attempting to remove any previous references to Watchtower"
docker container rm watchtower -f
fi
# remove the container
docker container rm meter_main -f
fi
if [ "$download_chain_flag" == 'true' ]; then
docker run --cidfile /tmp/meter_node_cont_id.txt --network host --name meter_main --restart always -e NETWORK="main" -v $METER_MAIN_DATA_PATH:/pos -d meterio/mainnet:latest
bootstrapChain
else
echo -e "~~~~~Starting meter_main docker container"
docker run --network host --name meter_main --restart always -e NETWORK="main" -v $METER_MAIN_DATA_PATH:/pos -d meterio/mainnet:latest
fi
# delete the public key if requested - it will be regenerated on boot
if [ "$regenerate_public_key" == 'true' ]; then
rm -f "$install_directory"/public.key
echo -e "~~~~~Restarting meter_main after deleting old public key..."
docker container restart meter_main
fi
if [ "$watchtower_install_flag" == 'true' ]; then
echo -e "~~~~~Installing Watchtower"
docker run -d --name watchtower --restart always -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --include-stopped --revive-stopped --enable-lifecycle-hooks --interval 10 --cleanup meter_main
fi
#output the private key if we can see it
if [ -f "$PWD/public.key" ]; then
echo "~~~~~Here is your public key. You can copy it from here, but make sure when you are setting up the node in the
wallet that you do not have any whitespaces between the strings - it should all be on one line."
cat public.key
fi
exitMessage
}
# trigger the main function
main "$@"