forked from vivocoin/docker
/
setup-aio.sh
498 lines (467 loc) · 10.2 KB
/
setup-aio.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
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
#!/bin/bash
RPCUSERNAME=
RPCPASSWORD=
# only modify these option if you know what you are doing or you have been asked to
VIVONETPORT=12845
VIVORPCPORT=9998
BINDIP=
MODE="env" # if you use a docker swarm setup, write "swarm" here
# !!! ONLY FOR DEBUGGING !!!
DEBUG=0
function checkip()
{
local OCTET1=$(echo $1 | cut -d. -f1)
local OCTET2=$(echo $1 | cut -d. -f2)
local OCTET3=$(echo $1 | cut -d. -f3)
local OCTET4=$(echo $1 | cut -d. -f4)
if [ $OCTET1 -lt 0 ] || [ $OCTET1 -gt 255 ]
then
echo "Invalid first IP octet, <0 or >255"
return 1
fi
if [ $OCTET2 -lt 0 ] || [ $OCTET2 -gt 255 ]
then
echo "Invalid second IP octet, <0 or >255"
return 1
fi
if [ $OCTET3 -lt 0 ] || [ $OCTET3 -gt 255 ]
then
echo "Invalid third IP octet, <0 or >255"
return 1
fi
if [ $OCTET4 -lt 0 ] || [ $OCTET4 -gt 255 ]
then
echo "Invalid fourth IP octet, <0 or >255"
return 1
fi
return 0
}
function isrouteable()
{
if ! checkip $1
then
echo "Invlid IP address given"
return 1
fi
local OCTET1=$(echo $1 | cut -d. -f1)
local OCTET2=$(echo $1 | cut -d. -f2)
local OCTET3=$(echo $1 | cut -d. -f3)
local OCTET4=$(echo $1 | cut -d. -f4)
# 0.0.0.0 - 0.255.255.255
if [ "$OCTET1" = "0" ]
then
return 1
# 10.0.0.0 - 10.255.255.255 RFC1918
elif [ "$OCTET1" = "10" ]
then
return 1
# 100.64.0.0 - 10.127.255.255
elif [ "$OCTET1" = "100" ]
then
if [ $OCTET2 -ge 64 ] && [ $OCTET2 -le 127 ]
then
return 1
fi
# 127.0.0.0 - 127.255.255.255 AKA Loopback
elif [ "$OCTET1" = "127" ]
then
return 1
# 169.254.0.0 - 169.254.255.255 AKA Link-Local (APIPA)
elif [ "$OCTET1" = "169" ]
then
if [ "$OCTET2" = "254" ]
then
return 1
fi
# 172.16.0.0 - 172.31.255.255 RFC1918
elif [ "$OCTET1" = "172" ]
then
if [ $OCTET2 -ge 16 ] && [ $OCTET2 -le 31 ]
then
return 1
fi
# 192.0.0.0 - 192.255.255.255 multiple
elif [ "$OCTET1" = "192" ]
then
if [ "$OCTET2" = "0" ]
then
# 192.0.0.0 - 192.0.0.255
if [ "$OCTET3" = "0" ]
then
return 1
# 192.0.2.0 - 192.0.2.255 TEST-NET-1
elif [ "$OCTET3" = "2" ]
then
return 1
fi
elif [ "$OCTET2" = "88" ]
then
# 192.88.99.0 - 192.88.99.255 6to4 anycast
if [ "$OCTET3" = "99" ]
then
return 1
fi
# 192.168.0.0 - 192.168.255.255 RFC1918
elif [ "$OCTET2" = "168" ]
then
return 1
fi
# 198.0.0.0 - 198.255.255.255 multiple
elif [ "$OCTET1" = "198" ]
then
# 198.18.0.0 - 198.19.0.0
if [ $OCTET2 -ge 18 ] && [ $OCTET2 -le 19 ]
then
return 1
# 198.51.100.0 - 192.51.100.255 TEST-NET-2
elif [ "$OCTET2" = "51" ]
then
if [ "$OCTET3" = "100" ]
then
return 1
fi
fi
# 203.0.113.0 - 203.0.113.255 TEST-NET-3
elif [ "$OCTET1" = "203" ]
then
if [ "$OCTET2" = "0" ]
then
if [ "$OCTET3" = "113" ]
then
return 1
fi
fi
# 224.0.0.0 - 239.255.255.255 multicast
elif [ $OCTET1 -ge 224 ] && [ $OCTET1 -le 239 ]
then
return 1
# 240.0.0.0 - 255.255.255.255
elif [ $OCTET1 -ge 240 ] && [ $OCTET1 -le 255 ]
then
return 1
fi
return 0
}
function checkport()
{
local IP=$1
local PORT=$2
local NOBAIL=$3
if ! checkip $IP
then
echo "Invlid IP address given"
return 1
fi
local NSOUT=$(netstat -lnt 2>/dev/null | grep ":$PORT")
# nothing is listening on $PORT
if [ "$NSOUT" = "" ]
then
return 0
else
# something is litening on $IP:$PORT
if echo $NSOUT | grep ${IP}:${PORT} &>/dev/null
then
return 1
# something is litening on 0.0.0.0:$PORT
elif echo $NSOUT | grep "0.0.0.0:${PORT}" &>/dev/null
then
if [ "$NOBAIL" = "" ]
then
echo "Something using \"$PORT\" on all IP addresses, bailing"
echo "If you already have a masternode, specify \"bind=externalip:$VIVONETPORT\" in the currently running masternode's vivo.conf and restart it"
exit 1
else
return 1
fi
# $IP:$PORT free
else
return 0
fi
fi
}
function discoverip()
{
local HTTPOUT=$(wget http://canihazip.com/s -O - 2>/dev/null)
if [ "$HTTPOUT" = "" ]
then
return
fi
if ! checkport $HTTPOUT $VIVONETPORT 1>&2
then
return
else
echo $HTTPOUT
fi
}
if [ ! "$UID" = 0 ]
then
echo "This script must be run as root"
exit 1
fi
# check dependencies
if ! which docker &>/dev/null
then
echo "docker not installed"
echo "If you want to install docker press enter, otherwise press Ctrl+C"
read < /proc/self/fd/2
wget -q http://get.docker.com/ -O - | sh
fi
if ! which docker-init &>/dev/null
then
echo "docker-init not found in PATH"
echo "You may have an older version of docker which doesnt include tini as an init"
echo "Please install a newer version of docker or put docker-init in PATH"
exit 1
fi
EXIP=
BIND=0.0.0.0
if [ ! "$BINDIP" = "" ]
then
if ! checkip $BINDIP
then
echo "Invalid IP address given to configuration"
exit 1
fi
BIND=$BINDIP
if ! isrouteable $BIND
then
echo "Bind IP is not routable, discovering external IP..."
EXIP=$(discoverip)
if ! checkip $EXIP
then
echo "Could not detect external IP"
EXIP=
else
echo "Using external IP: $EXIP"
fi
fi
else
# detect external IP if any
IFIPS=
IFIPCNT=0
CMDOUT=$(ip a || ifconfig)
for ip in $(echo "$CMDOUT" | grep 'inet ' | tr -s ' ' | cut -d' ' -f3 | cut -d/ -f1)
do
if ! isrouteable $ip
then
echo "Non-routable IP: $ip"
continue
fi
if ! checkport $ip $VIVONETPORT
then
echo "IP already occupied: $ip"
continue
fi
if [ "$IFIPS" = "" ]
then
IFIPS=$ip
else
IFIPS="$IFIPS $ip"
fi
IFIPCNT=$(($IFIPCNT + 1))
done
# do we have an IP or are we behind NAT?
HASIP=0
if [ "$IFIPCNT" = "0" ]
then
echo "No external IP addresses found attached to network interfaces, trying to find actual external IP..."
HTTPOUT=$(wget http://canihazip.com/s -O - 2>/dev/null)
if [ "$HTTPOUT" = "" ]
then
echo "Failed to detect external IP"
elif ! checkport $HTTPOUT $VIVONETPORT
then
echo "Detected external IP is in use or invalid"
else
echo "Detected external IP: $HTTPOUT"
IFIPCNT=1
IFIPS=$HTTPOUT
fi
else
HASIP=1
fi
if [ $IFIPCNT -eq 0 ]
then
echo "No free external IP address found on your system, please provide your external IP:"
while :
do
echo -n "External IP: "
read EXIP < /proc/self/fd/2
if ! isroutable $EXIP
then
echo "IP address \"$EXIP\" is not routeable on the Internet"
continue
elif ! checkport $EXIP $VIVONETPORT
then
echo "IP address \"$EXIP\" already used"
continue
else
echo "Using provided IP: $EXIP"
break
fi
done
elif [ $IFIPCNT -eq 1 ]
then
EXIP=$IFIPS
echo "Only 1 usable external IP address found, using \"$EXIP\""
if [ ! "$HASIP" = "0" ]
then
BIND=$EXIP
fi
else
echo "Multiple external IP addresses detected, choose which you want to use for hosting VIVO"
while :
do
CNT=0
for ip in $IFIPS
do
CNT=$(($CNT + 1))
echo "$CNT) $ip"
done
echo -n "Your choice: "
read CHOICE < /proc/self/fd/2
CNT=0
IPCHOICE=
for ip in $IFIPS
do
CNT=$(($CNT + 1))
if [ "$CNT" = "$CHOICE" ]
then
IPCHOICE=$ip
fi
done
if [ "$IPCHOICE" = "" ]
then
echo "Invalid choice, try again"
else
echo "You chose $IPCHOICE"
EXIP=$IPCHOICE
BIND=$IPCHOICE
break
fi
done
fi
fi
while :
do
if ! checkport 127.0.0.1 $VIVORPCPORT true
then
VIVORPCPORT=$(($VIVORPCPORT + 1))
else
break
fi
done
MNPK=
echo "Please generate a masternode private key and copy it here:"
while :
do
if [ ! "$DEBUG" = 0 ]
then
MNPK=7eJ7wzphM58uhEW8Uvcii6uweKf2pgZHiuHSiX41RRR6RctTiaS
break
fi
echo -n "MNPK: "
read MNPK < /proc/self/fd/2
if [ ! "$(echo -n $MNPK | wc -c)" = "51" ]
then
echo "Invalid masternode private key given, try again"
else
echo "OK"
break
fi
done
echo
echo
if [ "$RPCUSERNAME" = "" ]
then
USERNAME=$(</dev/urandom tr -dc '12345qwertQWERTasdfgASDFGzxcvbZXCVB' | head -c10)
echo "Generated RPC username: $USERNAME"
else
USERNAME=$RPCUSERNAME
echo "Given RPC username: $USERNAME"
fi
if [ "$RPCPASSWORD" = "" ]
then
PASSWORD=$(</dev/urandom tr -dc '12345qwertQWERTasdfgASDFGzxcvbZXCVB' | head -c20)
echo "Generated RPC password: $PASSWORD"
else
PASSWORD=$RPCPASSWORD
echo "Given RPC password: $PASSWORD"
fi
MNPRIVKEY=$MNPK
echo "Masternode private key: $MNPRIVKEY"
EXTERNALIP=$EXIP
echo "Used external IP: $EXTERNALIP"
echo "Used bind address: $BIND"
DAEMONIMAGE="vivocoin/aio"
PUBLICATION="-p $BIND:12845:12845 -p 127.0.0.1:$VIVORPCPORT:9998"
echo "VIVO RPC port: $VIVORPCPORT"
DAEMONIDX=1
DOCKERPARAMS=
if [ "$MODE" = "swarm" ] && ! docker secret ls &>/dev/null
then
MODE="env"
fi
if [ "$MODE" = "swarm" ]
then
# rpcuser=
if [ "$(docker secret ls | grep vivo-rpcuser)" = "" ]
then
echo $USERNAME | docker secret create vivo-rpcuser -
fi
DOCKERPARAMS="$DOCKERPARAMS --secret vivo-rpcuser"
# rpcpassword=
if [ "$(docker secret ls | grep vivo-rpcpass)" = "" ]
then
echo $PASSWORD | docker secret create vivo-rpcpass -
fi
DOCKERPARAMS="$DOCKERPARAMS --secret vivo-rpcpass"
# masternodeprivkey=
if [ "$(docker secret ls | grep vivo-mnprivkey)" = "" ]
then
echo $MNPRIVKEY | docker secret create vivo-mnprivkey -
fi
DOCKERPARAMS="$DOCKERPARAMS --secret vivo-mnprivkey"
# externalip=
if [ "$(docker secret ls | grep vivo-externalip)" = "" ]
then
echo $EXTERNALIP | docker secret create vivo-externalip -
fi
DOCKERPARAMS="$DOCKERPARAMS --secret vivo-externalip"
while :
do
if docker service ls | grep "vivo-mn-$DAEMONIDX" &>/dev/null
then
DAEMONIDX=$(($DAEMONIDX + 1))
else
break
fi
done
DAEMONNAME="vivo-mn-$DAEMONIDX"
echo "docker container name: $DAEMONNAME"
VOLUME="vivo-mndata-$DAEMONIDX:/vivo"
docker service create $DOCKERPARAMS --name $DAEMONNAME --hostname $DAEMONNAME -v $VOLUME $PUBLICATION $DAEMONIMAGE
else
# rpcuser=
DOCKERPARAMS="$DOCKERPARAMS -e VIVO_RPCUSER=$USERNAME"
# rpcpassword=
DOCKERPARAMS="$DOCKERPARAMS -e VIVO_RCPPASSWORD=$PASSWORD"
# masternodeprivkey=
DOCKERPARAMS="$DOCKERPARAMS -e VIVO_MNPRIVKEY=$MNPRIVKEY"
# externalip=
DOCKERPARAMS="$DOCKERPARAMS -e VIVO_EXTERNALIP=$EXTERNALIP"
while :
do
if docker ps -a | grep "vivo-mn-$DAEMONIDX" &>/dev/null
then
DAEMONIDX=$(($DAEMONIDX + 1))
else
break
fi
done
DAEMONNAME="vivo-mn-$DAEMONIDX"
echo "docker container name: $DAEMONNAME"
VOLUME="vivo-mndata-$DAEMONIDX:/vivo"
docker create $DOCKERPARAMS --name $DAEMONNAME --hostname $DAEMONNAME -v $VOLUME $PUBLICATION $DAEMONIMAGE
docker start $DAEMONNAME
fi