This repository has been archived by the owner on Sep 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsetup.sh
executable file
·475 lines (425 loc) · 17 KB
/
setup.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
#!/bin/bash
# Variables
KUZZLE_DIR="./kuzzle"
KUZZLE_DOWNLOAD_MANAGER=""
KUZZLE_PUSH_ANALYTICS=""
KUZZLE_CHECK_DOCKER_COMPOSE_YML_HTTP_STATUS_CODE=""
KUZZLE_CHECK_CONNECTIVITY_CMD=""
CURL_OPTS="-sSL"
CURL_PUSH_OPTS="-H Content-Type:application/json --data "
WGET_OPTS="-qO-"
WGET_PUSH_OPTS=" -O- --header=Content-Type:application/json --post-data="
ANALYTICS_URL=${ANALYTICS_URL:-"http://analytics.kuzzle.io/"}
GITTER_URL="https://gitter.im/kuzzleio/kuzzle"
SUPPORT_MAIL="[email protected]"
COMPOSE_YML_URL="https://kuzzle.io/docker-compose.yml"
COMPOSE_YML_PATH=$KUZZLE_DIR/docker-compose.yml
INSTALL_KUZZLE_WITHOUT_DOCKER_URL="https://docs.kuzzle.io/core/2/guides/essentials/installing-kuzzle/#manual-installation"
MIN_DOCKER_VER=1.12.0
MIN_MAX_MAP_COUNT=262144
CONNECT_TO_KUZZLE_MAX_RETRY=${CONNECT_TO_KUZZLE_MAX_RETRY:=60} # in seconds
CONNECT_TO_KUZZLE_WAIT_TIME_BETWEEN_RETRY=1
DOWNLOAD_DOCKER_COMPOSE_YML_MAX_RETRY=3
DOWNLOAD_DOCKER_COMPOSE_RETRY_WAIT_TIME=1 # in seconds
OS=""
SYSTEMD_SERVICE="[Unit]\n
Description=Kuzzle Service\n
After=docker.service\n
Requires=docker.service\n
[Service]\n
Type=simple\n
WorkingDirectory=$PWD/kuzzle\n
ExecStart=$(command -v docker-compose) -f $PWD/$COMPOSE_YML_PATH up\n
ExecStop=$(command -v docker-compose) -f $PWD/$COMPOSE_YML_PATH stop\n
Restart=on-abort\n
[Install]\n
WantedBy=multi-user.target"
SCRIPT_ADD_TO_BOOT="#!/bin/bash
echo -e \"$SYSTEMD_SERVICE\" > /etc/systemd/system/kuzzle.service
systemctl enable kuzzle"
SCRIPT_REMOVE_FROM_BOOT="#!/bin/bash
systemctl disable kuzzle"
# Errors return status
NO_INTERNET=42
NO_DOWNLOAD_MANAGER=43
MISSING_DEPENDENCY=44
ERROR_DOWNLOAD_DOCKER_COMPOSE=45
KUZZLE_NOT_RUNNING_AFTER_INSTALL=46
# Analytics events
EVENT_START_SETUP=start-setup
EVENT_ABORT_SETUP=abort-setup
EVENT_MISSING_DOCKER=missing-docker
EVENT_MISSING_DOCKER_COMPOSE=missing-docker-compose
EVENT_DOCKER_VERSION_MISMATCH=docker-version-mismatch
EVENT_OUT_OF_MEMORY=out-of-memory
EVENT_MISSING_SYSCTL=missing-sysctl
EVENT_WRONG_MAX_MAP_COUNT=wrong-max_map_count
EVENT_ERR_DL_DOCKER_COMPOSE_YML=error-download-dockercomposeyml
EVENT_PULLING_CONTAINERS=pulling-latest-containers
EVENT_PULLED_CONTAINERS=pulled-latest-containers
EVENT_PULL_FAILED=pull-failed
EVENT_STARTING_KUZZLE=starting-kuzzle
EVENT_KUZZLE_FAILED_RUNNING=kuzzle-failed-running
EVENT_KUZZLE_RUNNING=kuzzle-running
# list of colors
# see if it supports colors...
NCOLORS=$(tput colors)
if [ $? -eq 0 ] && [ $NCOLORS -gt 0 ]; then
BOLD=$(tput bold)
RED=$(tput setaf 1)
BLUE=$(tput setaf 6)
NORMAL=$(tput sgr0)
GREEN="$(tput setaf 2)"
fi
# Create kuzzle workspace directory
if [ ! -d $KUZZLE_DIR ]; then
mkdir $KUZZLE_DIR
fi
if [ ! -d $KUZZLE_DIR/script ]; then
mkdir $KUZZLE_DIR/script
fi
os_lookup() {
OSTYPE=$(uname)
case "$OSTYPE" in
"Darwin")
{
OS="OSX"
} ;;
"Linux")
{
# If available, use LSB to identify distribution
if [ -f /etc/lsb-release -o -d /etc/lsb-release.d ]; then
DISTRO=$(awk -F= '/^NAME/{print $2}' /etc/os-release)
else
DISTRO=$(ls -d /etc/[A-Za-z]*[_-][rv]e[lr]* | grep -v "lsb" | cut -d'/' -f3 | cut -d'-' -f1 | cut -d'_' -f1)
fi
OS=$(echo $DISTRO | head -n1 | awk '{print $1;}' | tr 'a-z' 'A-Z' | tr -d '"')
} ;;
*)
{
OS=$OSTYPE
} ;;
esac
}
# Output a text with the selected color (reinit to normal at the end)
write() {
echo -e " $1$2" "$NORMAL"
}
write_error() {
>&2 echo $RED "$1$2" "$NORMAL"
}
write_info() {
echo $BLUE "$1$2" "$NORMAL"
}
write_success() {
echo $GREEN "$1$2" "$NORMAL"
}
write_title() {
echo -e "${BOLD} $1$2" "$NORMAL"
}
prompt_bold() {
echo -n -e "${BOLD} $1$2" "$NORMAL"
}
command_exists() {
command -v "$1" > /dev/null 2>&1
}
set_download_manager() {
if command_exists curl; then
KUZZLE_DOWNLOAD_MANAGER="$(command -v curl) "$CURL_OPTS
KUZZLE_PUSH_ANALYTICS="$(command -v curl) "$CURL_PUSH_OPTS" "
KUZZLE_CHECK_DOCKER_COMPOSE_YML_HTTP_STATUS_CODE="$KUZZLE_DOWNLOAD_MANAGER -w %{http_code} $COMPOSE_YML_URL -o /dev/null"
KUZZLE_CHECK_INTERNET_ACCESS="$KUZZLE_DOWNLOAD_MANAGER -w %{http_code} google.com -o /dev/null"
KUZZLE_CHECK_CONNECTIVITY_CMD="$(command -v curl) -o /dev/null http://localhost:7512"
return 0
elif command_exists wget; then
KUZZLE_DOWNLOAD_MANAGER="$(command -v wget) "$WGET_OPTS
KUZZLE_PUSH_ANALYTICS="$(command -v wget)"$WGET_PUSH_OPTS
KUZZLE_CHECK_DOCKER_COMPOSE_YML_HTTP_STATUS_CODE="$KUZZLE_DOWNLOAD_MANAGER --server-response $COMPOSE_YML_URL 2>&1 | awk '/^ HTTP/{print \$2}' | tail -n 1"
KUZZLE_CHECK_INTERNET_ACCESS="wget -o /dev/null google.com"
KUZZLE_CHECK_CONNECTIVITY_CMD="$(command -v wget) --tries 1 -o /dev/null http://localhost:7512"
return 0
fi
echo
write_error "[✖] This script needs curl or wget installed."
write_error "Please install either one."
echo
exit $NO_DOWNLOAD_MANAGER
}
vercomp () {
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 0
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 1
fi
done
return 0
}
check_internet_access() {
echo
write_info "[ℹ] Checking internet access..."
$KUZZLE_CHECK_INTERNET_ACCESS &> /dev/null
if [ $? -ne 0 ]; then
write_error "[✖] No internet connection. Please ensure that you have internet access."
echo
exit $NO_INTERNET
fi
write_success "[✔] Ok."
}
prerequisite() {
local ERROR=0
echo
write_info "[ℹ] Checking prerequisites..."
# Check if docker is installed
if ! command_exists docker; then
write_error "[✖] This script requires Docker to run Kuzzle. Please install it and re-run this script."
write_error " Please refer to https://docs.docker.com/install for details about how to install Docker."
write_error " If you would like to install Kuzzle without Docker please refer to $INSTALL_KUZZLE_WITHOUT_DOCKER_URL"
write_error " Once Docker is installed make sure it is running before re-running this script."
echo
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_MISSING_DOCKER'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
ERROR=$MISSING_DEPENDENCY
fi
# Check if docker-compose is installed
if ! command_exists docker-compose; then
write_error "[✖] This script requires Docker Compose to run Kuzzle. Please install it and re-run this script"
write_error " If you would like to install Kuzzle without Docker Compose please refer to $INSTALL_KUZZLE_WITHOUT_DOCKER_URL"
echo
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_MISSING_DOCKER_COMPOSE'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
ERROR=$MISSING_DEPENDENCY
fi
# Check if docker version is at least $MIN_DOCKER_VER
if [ $ERROR -eq 0 ]; then
vercomp $(docker -v | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') $MIN_DOCKER_VER
if [ $? -ne 0 ]; then
write_error "[✖] This script requires Docker version $MIN_DOCKER_VER or higher to run Kuzzle"
echo
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_DOCKER_VERSION_MISMATCH'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
ERROR=$MISSING_DEPENDENCY
fi
fi
# check if kuzzle has enough ram
if [ "$OS" != "OSX" ]; then
free_ram=$(grep MemAvailable /proc/meminfo | awk '{ print $2 }')
free_swap=$(grep SwapFree /proc/meminfo | awk '{ print $2 }')
let free_total=$free_ram+$free_swap
if [ $free_total -lt 1433600 ]; then
write_error
write_error "[✖] Not enough memory available to run Kuzzle."
write_error " Kuzzle needs at least 1.4GB of free memory."
write_error " Please consider quitting one or more applications to increase available memory, and then try again."
echo
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_OUT_OF_MEMORY'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
ERROR=$MISSING_DEPENDENCY
fi
fi
# Check if sysctl exists on the machine
if [ "$OS" != "OSX" ]; then
if ! command_exists /sbin/sysctl; then
write_error "[✖] This script needs sysctl to check that your kernel settings meet the Kuzzle requirements."
write_error " Please install sysctl and re-run this script."
echo
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_MISSING_SYSCTL'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
ERROR=$MISSING_DEPENDENCY
else
# Check of vm.max_map_count is at least $MIN_MAX_MAP_COUNT
VM_MAX_MAP_COUNT=$(/sbin/sysctl -n vm.max_map_count)
if [ -z "${VM_MAX_MAP_COUNT}" ] || [ ${VM_MAX_MAP_COUNT} -lt $MIN_MAX_MAP_COUNT ]; then
write_error
write_error "[✖] The current value of the kernel configuration variable vm.max_map_count (${VM_MAX_MAP_COUNT})"
write_error " is lower than that required by Elasticsearch ($MIN_MAX_MAP_COUNT+)."
write_info " In order to run Kuzzle please set the required value by executing the following command (needs root access):"
write_info $BOLD "sysctl -w vm.max_map_count=$MIN_MAX_MAP_COUNT"
write_info " (more at https://www.elastic.co/guide/en/elasticsearch/reference/5.x/vm-max-map-count.html)"
write_info " To make this change persistent please edit the $BLUE$BOLD/etc/sysctl.conf$NORMAL$RED file"
write_info " and add this line: $BLUE$BOLD vm.max_map_count=$MIN_MAX_MAP_COUNT$NORMAL$RED"
echo
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_WRONG_MAX_MAP_COUNT'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
ERROR=$MISSING_DEPENDENCY
fi
fi
fi
if [ $ERROR -ne 0 ]; then
exit $ERROR
fi
write_success "[✔] Ok."
}
download_docker_compose_yml() {
local RETRY=0
echo
write_info "[ℹ] Downloading Kuzzle docker-compose.yml file..."
TEST=$(eval "$KUZZLE_CHECK_DOCKER_COMPOSE_YML_HTTP_STATUS_CODE")
while [ $TEST -ne 200 ];
do
if [ $RETRY -gt $DOWNLOAD_DOCKER_COMPOSE_YML_MAX_RETRY ]; then
write_error "[✖] Cannot download $COMPOSE_YML_URL (HTTP ERROR CODE: $TEST)"
write_error " If the problem persists please contact us at $SUPPORT_MAIL or on gitter at $GITTER_URL."
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_ERR_DL_DOCKER_COMPOSE_YML'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
exit $ERROR_DOWNLOAD_DOCKER_COMPOSE
fi
RETRY=$(expr $RETRY + 1)
sleep $DOWNLOAD_DOCKER_COMPOSE_RETRY_WAIT_TIME
TEST=$(eval "$KUZZLE_CHECK_DOCKER_COMPOSE_YML_HTTP_STATUS_CODE")
done
$KUZZLE_DOWNLOAD_MANAGER $COMPOSE_YML_URL > $COMPOSE_YML_PATH
write_success "[✔] Downloaded."
echo
}
pull_kuzzle() {
write_info "[ℹ] Pulling the latest version of Kuzzle from Dockerhub..."
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_PULLING_CONTAINERS'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
$(command -v docker-compose) -f $COMPOSE_YML_PATH pull
RET=$?
if [ $RET -ne 0 ]; then
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_PULL_FAILED'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
echo
write_error "[✖] The pull failed. Is Docker running?"
write_info " You can try to run Docker by typing"
write_info $BOLD "service docker start"
write_error " or"
write_info $BOLD "dockerd &"
write_error " To learn more, refer to https://docs.docker.com/config/daemon"
exit $RET
fi
write_success "[✔] Pulled."
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_PULLED_CONTAINERS'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
}
run_kuzzle() {
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_STARTING_KUZZLE'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
echo
write_info "[ℹ] Starting Kuzzle..."
$(command -v docker-compose) -f $COMPOSE_YML_PATH up -d
}
check_kuzzle() {
local RETRY=0
echo -n $BLUE"[ℹ] Checking if Kuzzle is running (timeout "
echo -n $(expr $CONNECT_TO_KUZZLE_MAX_RETRY)
echo " seconds)"$NORMAL
while ! $KUZZLE_CHECK_CONNECTIVITY_CMD &> /dev/null
do
if [ $RETRY -gt $CONNECT_TO_KUZZLE_MAX_RETRY ]; then
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_KUZZLE_FAILED_RUNNING'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
>&2 echo
write_error "[✖] Ooops! Something went wrong."
write_error " Kuzzle does not seem to be running"
if [ "$OS" = "OSX" ]; then
write_info "[i] This might be due to a configuration problem linked to Docker For Mac. Please take a look at the following issue:"
write_info "https://stackoverflow.com/questions/41192680/update-max-map-count-for-elasticsearch-docker-container-mac-host"
fi
echo
write "Please feel free to get in touch with our support team by sending"
write "a mail to $SUPPORT_MAIL or by joining our chat room on"
write "Gitter at $GITTER_URL - We'll be glad to help you."
exit $KUZZLE_NOT_RUNNING_AFTER_INSTALL
fi
echo -n "."
sleep 1
RETRY=$(expr $RETRY + 1)
done
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_KUZZLE_RUNNING'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
echo
write_success "[✔] Kuzzle is now running."
echo
}
write_scripts() {
echo "$SCRIPT_ADD_TO_BOOT" > $KUZZLE_DIR/script/add-kuzzle-boot-systemd.sh
chmod +x $KUZZLE_DIR/script/add-kuzzle-boot-systemd.sh
echo "$SCRIPT_REMOVE_FROM_BOOT" > $KUZZLE_DIR/script/remove-kuzzle-boot-systemd.sh
chmod +x $KUZZLE_DIR/script/remove-kuzzle-boot-systemd.sh
}
the_end() {
write_info "You can see Kuzzle stack logs by typing:"
write " docker-compose -f $COMPOSE_YML_PATH logs -f"
write_info "You can stop Kuzzle by typing:"
write " docker-compose -f $COMPOSE_YML_PATH stop"
write_info "You can start Kuzzle by typing:"
write " docker-compose -f $COMPOSE_YML_PATH up -d"
write_info "You can restart Kuzzle by typing:"
write " docker-compose -f $COMPOSE_YML_PATH restart"
write
write_info "Take a look at our docs and learn how to get started at"
write_title "https://docs.kuzzle.io/core/2/guides/getting-started/first-steps/"
}
######## MAIN
if [ "$1" == "--help" ]; then
echo "--help show this help"
echo "--no-run only install Kuzzle, don't run it"
exit 1
fi
if [ ! -f "${KUZZLE_DIR}/uid" ]; then
echo $(LC_CTYPE=C tr -dc A-Fa-f0-9 < /dev/urandom | fold -w 64 | head -n 1) > "${KUZZLE_DIR}/.uid"
FIRST_INSTALL=1
fi
ANALYTICS_UUID=$(cat "${KUZZLE_DIR}/.uid")
clear
echo
write_title "# Kuzzle Setup"
write_title " ============"
echo
write "This script will check for all necessary prerequisites"
write "then install and run Kuzzle."
echo
write "* For more information about the installation process"
write " please refer to http://docs.kuzzle.io/."
write "* Feel free to join us on Gitter at"
write " $GITTER_URL if you need help."
echo
write " ███████████████████████"
write " ██████████████████████████████████████████████████████"
write " █ ▐█ ███ █████ ███"
write " █ █ █ █ █ █████ ▐██████ ███ █████ ██████"
write " █ █ █ █ █ █ ██████ ████ █████ ████"
write " █ ██ █ █ █ ▐█████ █████ █████ ██████"
write " █ █ █ █ █ █ █████ ██████ █████ ██████"
write " █ █ █ █ █ █ ▐████ ███ ██ ███"
write " █ █ █ ███ █████ ████████████████████████████"
write " █ ▐████████████████████████████"
write " ██████████████████████████"
echo
prompt_bold "[❓] Ready to install Kuzzle? (Ctrl + C to abort)"
read vazyGroNaz
set_download_manager
check_internet_access
os_lookup
write_scripts
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_START_SETUP'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
prerequisite
trap abort_setup INT
# send abort-setup event to analytics on SIGINT
abort_setup() {
$KUZZLE_PUSH_ANALYTICS'{"type": "'$EVENT_ABORT_SETUP'", "uid": "'$ANALYTICS_UUID'", "os": "'$OS'"}' $ANALYTICS_URL &> /dev/null
exit 1
}
download_docker_compose_yml
pull_kuzzle
if [ "$1" != "--no-run" ]; then
run_kuzzle
check_kuzzle
fi
echo
write_success $BOLD"[✔] Kuzzle successfully installed"
echo
the_end
echo
exit 0
########## END OF MAIN