]> arthur.barton.de Git - netdata.git/blob - netdata-installer.sh
netdata-installer.sh banner is not a snake; fixes #1023
[netdata.git] / netdata-installer.sh
1 #!/usr/bin/env bash
2
3 # reload the user profile
4 [ -f /etc/profile ] && . /etc/profile
5
6 export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
7
8 # fix PKG_CHECK_MODULES error
9 if [ -d /usr/share/aclocal ]
10 then
11         ACLOCAL_PATH=${ACLOCAL_PATH-/usr/share/aclocal}
12         export ACLOCAL_PATH
13 fi
14
15 LC_ALL=C
16 umask 022
17
18 # you can set CFLAGS before running installer
19 CFLAGS="${CFLAGS--O3}"
20
21 # keep a log of this command
22 printf "\n# " >>netdata-installer.log
23 date >>netdata-installer.log
24 printf "CFLAGS=\"%s\" " "${CFLAGS}" >>netdata-installer.log
25 printf "%q " "$0" "${@}" >>netdata-installer.log
26 printf "\n" >>netdata-installer.log
27
28 REINSTALL_PWD="${PWD}"
29 REINSTALL_COMMAND="$(printf "%q " "$0" "${@}"; printf "\n")"
30
31 banner() {
32     local   l1="  ^"                                                                      \
33             l2="  |.-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-"  \
34             l3="  |   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'  "  \
35             l4="  +----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--->" \
36             sp="                                                                        " \
37             netdata="netdata" start end msg="${*}"
38
39     [ ${#msg} -lt ${#netdata} ] && msg="${msg}${sp:0:$(( ${#netdata} - ${#msg}))}"
40     [ ${#msg} -gt $(( ${#l2} - 20 )) ] && msg="${msg:0:$(( ${#l2} - 23 ))}..."
41
42     start="$(( ${#l2} / 2 - 4 ))"
43     [ $(( start + ${#msg} + 4 )) -gt ${#l2} ] && start=$((${#l2} - ${#msg} - 4))
44     end=$(( ${start} + ${#msg} + 4 ))
45
46     echo >&2
47     echo >&2 "${l1}"
48     echo >&2 "${l2:0:start}${sp:0:2}${netdata}${sp:0:$((end - start - 2 - ${#netdata}))}${l2:end:$((${#l2} - end))}"
49     echo >&2 "${l3:0:start}${sp:0:2}${msg}${sp:0:2}${l3:end:$((${#l2} - end))}"
50     echo >&2 "${l4}"
51     echo >&2
52 }
53
54 service="$(which service 2>/dev/null || command -v service 2>/dev/null)"
55 systemctl="$(which systemctl 2>/dev/null || command -v systemctl 2>/dev/null)"
56 service() {
57     local cmd="${1}" action="${2}"
58
59     if [ ! -z "${service}" ]
60     then
61         run "${service}" "${cmd}" "${action}"
62         return $?
63     elif [ ! -z "${systemctl}" ]
64     then
65         run "${systemctl}" "${action}" "${cmd}"
66         return $?
67     fi
68     return 1
69 }
70
71 ME="$0"
72 DONOTSTART=0
73 DONOTWAIT=0
74 NETDATA_PREFIX=
75 LIBS_ARE_HERE=0
76
77 usage() {
78     banner "installer command line options"
79     cat <<USAGE
80
81 ${ME} <installer options>
82
83 Valid <installer options> are:
84
85    --install /PATH/TO/INSTALL
86
87         If your give: --install /opt
88         netdata will be installed in /opt/netdata
89
90    --dont-start-it
91
92         Do not (re)start netdata.
93         Just install it.
94
95    --dont-wait
96
97         Do not wait for the user to press ENTER.
98         Start immediately building it.
99
100    --zlib-is-really-here
101    --libs-are-really-here
102
103         If you get errors about missing zlib,
104         or libuuid but you know it is available,
105         you have a broken pkg-config.
106         Use this option to allow it continue
107         without checking pkg-config.
108
109 Netdata will by default be compiled with gcc optimization -O3
110 If you need to pass different CFLAGS, use something like this:
111
112   CFLAGS="<gcc options>" ${ME} <installer options>
113
114 For the installer to complete successfully, you will need
115 these packages installed:
116
117    gcc make autoconf automake pkg-config zlib1g-dev (or zlib-devel)
118    uuid-dev (or libuuid-devel)
119
120 For the plugins, you will at least need:
121
122    curl nodejs
123
124 USAGE
125 }
126
127 md5sum="$(which md5sum 2>/dev/null || command -v md5sum 2>/dev/null)"
128 get_git_config_signatures() {
129     local x s file md5
130
131     [ ! -d "conf.d" ] && echo >&2 "Wrong directory." && return 1
132     [ -z "${md5sum}" -o ! -x "${md5sum}" ] && echo >&2 "No md5sum command." && return 1
133
134     echo >configs.signatures.tmp
135
136     for x in $(find conf.d -name \*.conf)
137     do
138             x="${x/conf.d\//}"
139             echo "${x}"
140             for c in $(git log --follow "conf.d/${x}" | grep ^commit | cut -d ' ' -f 2)
141             do
142                     git checkout ${c} "conf.d/${x}" || continue
143                     s="$(cat "conf.d/${x}" | md5sum | cut -d ' ' -f 1)"
144                     echo >>configs.signatures.tmp "${x}:${s}"
145                     echo "    ${s}"
146             done
147             git checkout HEAD "conf.d/${x}" || break
148     done
149
150     cat configs.signatures.tmp |\
151         grep -v "^$" |\
152         sort -u |\
153         {
154             echo "declare -A configs_signatures=("
155             IFS=":"
156             while read file md5
157             do
158                 echo "  ['${md5}']='${file}'"
159             done
160             echo ")"
161         } >configs.signatures
162
163     rm configs.signatures.tmp
164
165     return 0
166 }
167
168
169 while [ ! -z "${1}" ]
170 do
171     if [ "$1" = "--install" ]
172         then
173         NETDATA_PREFIX="${2}/netdata"
174         shift 2
175     elif [ "$1" = "--zlib-is-really-here" -o "$1" = "--libs-are-really-here" ]
176         then
177         LIBS_ARE_HERE=1
178         shift 1
179     elif [ "$1" = "--dont-start-it" ]
180         then
181         DONOTSTART=1
182         shift 1
183     elif [ "$1" = "--dont-wait" ]
184         then
185         DONOTWAIT=1
186         shift 1
187     elif [ "$1" = "--help" -o "$1" = "-h" ]
188         then
189         usage
190         exit 1
191     elif [ "$1" = "get_git_config_signatures" ]
192         then
193         get_git_config_signatures && exit 0
194         exit 1
195     else
196         echo >&2
197         echo >&2 "ERROR:"
198         echo >&2 "I cannot understand option '$1'."
199         usage
200         exit 1
201     fi
202 done
203
204 banner "real-time performance monitoring, done right!"
205 cat <<BANNER
206
207   You are about to build and install netdata to your system.
208
209   It will be installed at these locations:
210
211    - the daemon    at ${NETDATA_PREFIX}/usr/sbin/netdata
212    - config files  at ${NETDATA_PREFIX}/etc/netdata
213    - web files     at ${NETDATA_PREFIX}/usr/share/netdata
214    - plugins       at ${NETDATA_PREFIX}/usr/libexec/netdata
215    - cache files   at ${NETDATA_PREFIX}/var/cache/netdata
216    - db files      at ${NETDATA_PREFIX}/var/lib/netdata
217    - log files     at ${NETDATA_PREFIX}/var/log/netdata
218    - pid file      at ${NETDATA_PREFIX}/var/run
219
220   This installer allows you to change the installation path.
221   Press Control-C and run the same command with --help for help.
222
223 BANNER
224
225 if [ "${UID}" -ne 0 ]
226     then
227     if [ -z "${NETDATA_PREFIX}" ]
228         then
229         banner "wrong command line options!"
230         cat <<NONROOTNOPREFIX
231
232 Sorry! This will fail!
233
234 You are attempting to install netdata as non-root, but you plan to install it
235 in system paths.
236
237 Please set an installation prefix, like this:
238
239     $0 ${@} --install /tmp
240
241 or, run the installer as root:
242
243     sudo $0 ${@}
244
245 We suggest to install it as root, or certain data collectors will not be able
246 to work. Netdata drops root privileges when running. So, if you plan to keep
247 it, install it as root to get the full functionality.
248
249 NONROOTNOPREFIX
250         exit 1
251
252     else
253         cat <<NONROOT
254
255 IMPORTANT:
256 You are about to install netdata as a non-root user.
257 Netdata will work, but a few data collection modules that
258 require root access will fail.
259
260 If you installing permanently on your system, run the
261 installer like this:
262
263     sudo $0 ${@}
264
265 NONROOT
266     fi
267 fi
268
269 have_autotools=
270 if [ "$(type autoreconf 2> /dev/null)" ]
271 then
272     autoconf_maj_min() {
273         local maj min IFS=.-
274
275         maj=$1
276         min=$2
277
278         set -- $(autoreconf -V | sed -ne '1s/.* \([^ ]*\)$/\1/p')
279         eval $maj=\$1 $min=\$2
280     }
281     autoconf_maj_min AMAJ AMIN
282
283     if [ "$AMAJ" -gt 2 ]
284     then
285         have_autotools=Y
286     elif [ "$AMAJ" -eq 2 -a "$AMIN" -ge 60 ]
287     then
288         have_autotools=Y
289     else
290         echo "Found autotools $AMAJ.$AMIN"
291     fi
292 else
293     echo "No autotools found"
294 fi
295
296 if [ ! "$have_autotools" ]
297 then
298     if [ -f configure ]
299     then
300         echo "Will skip autoreconf step"
301     else
302         banner "autotools v2.60 required"
303         cat <<"EOF"
304
305 -------------------------------------------------------------------------------
306 autotools 2.60 or later is required
307
308 Sorry, you do not seem to have autotools 2.60 or later, which is
309 required to build from the git sources of netdata.
310
311 You can either install a suitable version of autotools and automake
312 or download a netdata package which does not have these dependencies.
313
314 Source packages where autotools have already been run are available
315 here:
316        https://firehol.org/download/netdata/
317
318 The unsigned/master folder tracks the head of the git tree and released
319 packages are also available.
320 EOF
321         exit 1
322     fi
323 fi
324
325 if [ ${DONOTWAIT} -eq 0 ]
326     then
327     if [ ! -z "${NETDATA_PREFIX}" ]
328         then
329         read -p "Press ENTER to build and install netdata to '${NETDATA_PREFIX}' > "
330     else
331         read -p "Press ENTER to build and install netdata to your system > "
332     fi
333 fi
334
335 build_error() {
336     banner "sorry, it failed to build..."
337     cat <<EOF
338
339 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
340
341 Sorry! netdata failed to build...
342
343 You many need to check these:
344
345 1. The package uuid-dev (or libuuid-devel) has to be installed.
346
347    If your system cannot find libuuid, although it is installed
348    run me with the option:  --libs-are-really-here
349
350 2. The package zlib1g-dev (or zlib-devel) has to be installed.
351
352    If your system cannot find zlib, although it is installed
353    run me with the option:  --libs-are-really-here
354
355 3. You need basic build tools installed, like:
356
357    gcc make autoconf automake pkg-config
358
359    Autoconf version 2.60 or higher is required.
360
361 If you still cannot get it to build, ask for help at github:
362
363    https://github.com/firehol/netdata/issues
364
365
366 EOF
367     trap - EXIT
368     exit 1
369 }
370
371 run() {
372     printf >>netdata-installer.log "# "
373     printf >>netdata-installer.log "%q " "${@}"
374     printf >>netdata-installer.log " ... "
375
376     printf >&2 "\n"
377     printf >&2 ":-----------------------------------------------------------------------------\n"
378     printf >&2 "Running command:\n"
379     printf >&2 "\n"
380     printf >&2 "%q " "${@}"
381     printf >&2 "\n"
382
383     "${@}"
384
385     local ret=$?
386     if [ ${ret} -ne 0 ]
387         then
388         printf >>netdata-installer.log "FAILED!\n"
389     else
390         printf >>netdata-installer.log "OK\n"
391     fi
392
393     return ${ret}
394 }
395
396 if [ ${LIBS_ARE_HERE} -eq 1 ]
397     then
398     shift
399     echo >&2 "ok, assuming libs are really installed."
400     export ZLIB_CFLAGS=" "
401     export ZLIB_LIBS="-lz"
402     export UUID_CFLAGS=" "
403     export UUID_LIBS="-luuid"
404 fi
405
406 trap build_error EXIT
407
408 if [ "$have_autotools" ]
409 then
410     run ./autogen.sh || exit 1
411 fi
412
413 run ./configure \
414     --prefix="${NETDATA_PREFIX}/usr" \
415     --sysconfdir="${NETDATA_PREFIX}/etc" \
416     --localstatedir="${NETDATA_PREFIX}/var" \
417     --with-zlib --with-math --with-user=netdata \
418     CFLAGS="${CFLAGS}" || exit 1
419
420 # remove the build_error hook
421 trap - EXIT
422
423 if [ -f src/netdata ]
424     then
425     echo >&2 "Cleaning a possibly old compilation ..."
426     run make clean
427 fi
428
429 echo >&2 "Compiling netdata ..."
430 run make || exit 1
431
432 if [ "${BASH_VERSINFO[0]}" -ge "4" ]
433 then
434     declare -A configs_signatures=()
435     if [ -f "configs.signatures" ]
436         then
437         source "configs.signatures" || echo >&2 "ERROR: Failed to load configs.signatures !"
438     fi
439 fi
440
441 # migrate existing configuration files
442 # for node.d and charts.d
443 if [ -d "${NETDATA_PREFIX}/etc/netdata" ]
444     then
445     # the configuration directory exists
446
447     if [ ! -d "${NETDATA_PREFIX}/etc/netdata/charts.d" ]
448         then
449         run mkdir "${NETDATA_PREFIX}/etc/netdata/charts.d"
450     fi
451
452     # move the charts.d config files
453     for x in apache ap cpu_apps cpufreq example exim hddtemp load_average mem_apps mysql nginx nut opensips phpfpm postfix sensors squid tomcat
454     do
455         for y in "" ".old" ".orig"
456         do
457             if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" -a ! -f "${NETDATA_PREFIX}/etc/netdata/charts.d/${x}.conf${y}" ]
458                 then
459                 run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/charts.d/${x}.conf${y}"
460             fi
461         done
462     done
463
464     if [ ! -d "${NETDATA_PREFIX}/etc/netdata/node.d" ]
465         then
466         run mkdir "${NETDATA_PREFIX}/etc/netdata/node.d"
467     fi
468
469     # move the node.d config files
470     for x in named sma_webbox snmp
471     do
472         for y in "" ".old" ".orig"
473         do
474             if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" -a ! -f "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" ]
475                 then
476                 run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}"
477             fi
478         done
479     done
480 fi
481
482 # backup user configurations
483 installer_backup_suffix="${PID}.${RANDOM}"
484 for x in $(find "${NETDATA_PREFIX}/etc/netdata/" -name '*.conf' -type f)
485 do
486     if [ -f "${x}" ]
487         then
488         # make a backup of the configuration file
489         cp -p "${x}" "${x}.old"
490
491         if [ -z "${md5sum}" -o ! -x "${md5sum}" ]
492             then
493             # we don't have md5sum - keep it
494             cp -p "${x}" "${x}.installer_backup.${installer_backup_suffix}"
495         else
496             # find it relative filename
497             f="${x/*\/etc\/netdata\//}"
498
499             # find its checksum
500             md5="$(cat "${x}" | ${md5sum} | cut -d ' ' -f 1)"
501
502             # copy the original
503             if [ -f "conf.d/${f}" ]
504                 then
505                 cp "conf.d/${f}" "${x}.orig"
506             fi
507
508             if [ "${BASH_VERSINFO[0]}" -ge "4" ]
509             then
510                 if [ "${configs_signatures[${md5}]}" = "${f}" ]
511                 then
512                     # it is a stock version - don't keep it
513                     echo >&2 "File '${x}' is stock version."
514                 else
515                     # edited by user - keep it
516                     echo >&2 "File '${x}' has been edited by user."
517                     cp -p "${x}" "${x}.installer_backup.${installer_backup_suffix}"
518                 fi
519             else
520                 echo >&2 "File '${x}' cannot be check for custom edits."
521                 cp -p "${x}" "${x}.installer_backup.${installer_backup_suffix}"
522             fi
523         fi
524
525     elif [ -f "${x}.installer_backup.${installer_backup_suffix}" ]
526         then
527         rm -f "${x}.installer_backup.${installer_backup_suffix}"
528     fi
529 done
530
531 echo >&2 "Installing netdata ..."
532 run make install || exit 1
533
534 # restore user configurations
535 for x in $(find "${NETDATA_PREFIX}/etc/netdata/" -name '*.conf' -type f)
536 do
537     if [ -f "${x}.installer_backup.${installer_backup_suffix}" ]
538         then
539         cp -p "${x}.installer_backup.${installer_backup_suffix}" "${x}"
540         rm -f "${x}.installer_backup.${installer_backup_suffix}"
541     fi
542 done
543
544 NETDATA_ADDED_TO_DOCKER=0
545 if [ ${UID} -eq 0 ]
546     then
547     getent group netdata > /dev/null
548     if [ $? -ne 0 ]
549         then
550         echo >&2 "Adding netdata user group ..."
551         run groupadd -r netdata
552     fi
553
554     getent passwd netdata > /dev/null
555     if [ $? -ne 0 ]
556         then
557         echo >&2 "Adding netdata user account ..."
558         run useradd -r -g netdata -c netdata -s $(which nologin || echo '/bin/false') -d / netdata
559     fi
560
561     getent group docker > /dev/null
562     if [ $? -eq 0 ]
563         then
564         # find the users in the docker group
565         docker=$(getent group docker | cut -d ':' -f 4)
566         if [[ ",${docker}," =~ ,netdata, ]]
567             then
568             # netdata is already there
569             :
570         else
571             # netdata is not in docker group
572             echo >&2 "Adding netdata user to the docker group (needed to get container names) ..."
573             run usermod -a -G docker netdata
574         fi
575         # let the uninstall script know
576         NETDATA_ADDED_TO_DOCKER=1
577     fi
578
579     if [ -d /etc/logrotate.d -a ! -f /etc/logrotate.d/netdata ]
580         then
581         echo >&2 "Adding netdata logrotate configuration ..."
582         run cp system/netdata.logrotate /etc/logrotate.d/netdata
583     fi
584 fi
585
586
587 # -----------------------------------------------------------------------------
588 # load options from the configuration file
589
590 # create an empty config if it does not exist
591 [ ! -f "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ] && touch "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
592
593 # function to extract values from the config file
594 config_option() {
595     local key="${1}" value="${2}" line=
596
597     if [ -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ]
598         then
599         line="$( grep "^[[:space:]]*${key}[[:space:]]*=[[:space:]]*" "${NETDATA_PREFIX}/etc/netdata/netdata.conf" | head -n 1 )"
600         [ ! -z "${line}" ] && value="$( echo "${line}" | cut -d '=' -f 2 | sed -e "s/^[[:space:]]\+//g" -e "s/[[:space:]]\+$//g" )"
601     fi
602
603     echo "${value}"
604 }
605
606 # user
607 defuser="netdata"
608 [ ! "${UID}" = "0" ] && defuser="${USER}"
609 NETDATA_USER="$( config_option "run as user" "${defuser}" )"
610
611 NETDATA_WEB_USER="$( config_option "web files owner" "${defuser}" )"
612 NETDATA_WEB_GROUP="$( config_option "web files group" "${NETDATA_WEB_USER}" )"
613
614 # debug flags
615 defdebug=0
616 NETDATA_DEBUG="$( config_option "debug flags" ${defdebug} )"
617
618 # port
619 defport=19999
620 NETDATA_PORT="$( config_option "default port" ${defport} )"
621 NETDATA_PORT2="$( config_option "port" ${defport} )"
622
623 if [ "${NETDATA_PORT}" != "${NETDATA_PORT2}" ]
624 then
625     if [ "${NETDATA_PORT2}" != "${defport}" ]
626     then
627         NETDATA_PORT="${NETDATA_PORT2}"
628     fi
629 fi
630
631 # directories
632 NETDATA_LIB_DIR="$( config_option "lib directory" "${NETDATA_PREFIX}/var/lib/netdata" )"
633 NETDATA_CACHE_DIR="$( config_option "cache directory" "${NETDATA_PREFIX}/var/cache/netdata" )"
634 NETDATA_WEB_DIR="$( config_option "web files directory" "${NETDATA_PREFIX}/usr/share/netdata/web" )"
635 NETDATA_LOG_DIR="$( config_option "log directory" "${NETDATA_PREFIX}/var/log/netdata" )"
636 NETDATA_CONF_DIR="$( config_option "config directory" "${NETDATA_PREFIX}/etc/netdata" )"
637 NETDATA_RUN_DIR="${NETDATA_PREFIX}/var/run"
638
639
640 # -----------------------------------------------------------------------------
641 # prepare the directories
642
643 # this is needed if NETDATA_PREFIX is not empty
644 if [ ! -d "${NETDATA_RUN_DIR}" ]
645     then
646     mkdir -p "${NETDATA_RUN_DIR}" || exit 1
647 fi
648
649 echo >&2
650 echo >&2 "Fixing directories (user: ${NETDATA_USER})..."
651 for x in "${NETDATA_WEB_DIR}" "${NETDATA_CONF_DIR}" "${NETDATA_CACHE_DIR}" "${NETDATA_LOG_DIR}" "${NETDATA_LIB_DIR}" "${NETDATA_CONF_DIR}/python.d" "${NETDATA_CONF_DIR}/charts.d" "${NETDATA_CONF_DIR}/node.d"
652 do
653     if [ ! -d "${x}" ]
654         then
655         echo >&2 "Creating directory '${x}'"
656         run mkdir -p "${x}" || exit 1
657     fi
658
659     if [ ${UID} -eq 0 ]
660         then
661         if [ "${x}" = "${NETDATA_WEB_DIR}" ]
662             then
663             run chown -R "${NETDATA_WEB_USER}:${NETDATA_WEB_GROUP}" "${x}" || echo >&2 "WARNING: Cannot change the ownership of the files in directory ${x} to ${NETDATA_WEB_USER}:${NETDATA_WEB_GROUP}..."
664         else
665             run chown -R "${NETDATA_USER}:${NETDATA_USER}" "${x}" || echo >&2 "WARNING: Cannot change the ownership of the files in directory ${x} to ${NETDATA_USER}..."
666         fi
667     fi
668
669     run chmod 0755 "${x}" || echo >&2 "WARNING: Cannot change the permissions of the directory ${x} to 0755..."
670 done
671
672 if [ ${UID} -eq 0 ]
673     then
674     run chown root "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
675     run chmod 0755 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
676     run setcap cap_dac_read_search,cap_sys_ptrace+ep "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
677     if [ $? -ne 0 ]
678         then
679         # fix apps.plugin to be setuid to root
680         run chown root "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
681         run chmod 4755 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
682     fi
683 fi
684
685 # -----------------------------------------------------------------------------
686 # check if we can re-start netdata
687
688 if [ ${DONOTSTART} -eq 1 ]
689     then
690     if [ ! -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ]
691         then
692         echo >&2 "Generating empty config file in: ${NETDATA_PREFIX}/etc/netdata/netdata.conf"
693         echo "# Get config from http://127.0.0.1:${NETDATA_PORT}/netdata.conf" >"${NETDATA_PREFIX}/etc/netdata/netdata.conf"
694
695         if [ "${UID}" -eq 0 ]
696             then
697             chown "${NETDATA_USER}" "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
698         fi
699         chmod 0664 "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
700     fi
701     banner "is installed now!"
702     echo >&2 "  enjoy real-time performance and health monitoring..."
703     exit 0
704 fi
705
706 # -----------------------------------------------------------------------------
707 # stop a running netdata
708
709 isnetdata() {
710     [ -z "$1" -o ! -f "/proc/$1/stat" ] && return 1
711     [ "$(cat "/proc/$1/stat" | cut -d '(' -f 2 | cut -d ')' -f 1)" = "netdata" ] && return 0
712     return 1
713 }
714
715 stop_netdata_on_pid() {
716     local pid="$1" ret=0 count=0
717
718     isnetdata $pid || return 0
719
720     printf >&2 "Stopping netdata on pid $pid ..."
721     while [ ! -z "$pid" -a $ret -eq 0 ]
722     do
723         if [ $count -gt 45 ]
724             then
725             echo >&2 "Cannot stop the running netdata on pid $pid."
726             return 1
727         fi
728
729         count=$(( count + 1 ))
730
731         run kill $pid 2>/dev/null
732         ret=$?
733
734         test $ret -eq 0 && printf >&2 "." && sleep 2
735     done
736
737     echo >&2
738     if [ $ret -eq 0 ]
739     then
740         echo >&2 "SORRY! CANNOT STOP netdata ON PID $pid !"
741         return 1
742     fi
743
744     echo >&2 "netdata on pid $pid stopped."
745     return 0
746 }
747
748 stop_all_netdata() {
749     local p
750
751     echo >&2 "Stopping a (possibly) running netdata..."
752
753     for p in $(cat "${NETDATA_RUN_DIR}/netdata.pid" 2>/dev/null) \
754         $(cat /var/run/netdata.pid 2>/dev/null) \
755         $(cat /var/run/netdata/netdata.pid 2>/dev/null) \
756         $(pidof netdata 2>/dev/null)
757     do
758         stop_netdata_on_pid $p
759     done
760 }
761
762 # -----------------------------------------------------------------------------
763 # check netdata for systemd
764
765 issystemd() {
766     # if the directory /etc/systemd/system does not exit, it is not systemd
767     [ ! -d /etc/systemd/system ] && return 1
768
769     # if pid 1 is systemd, it is systemd
770     [ "$(basename $(readlink /proc/1/exe) 2>/dev/null)" = "systemd" ] && return 0
771
772     # if systemd is running, it is systemd
773     pidof systemd >/dev/null 2>&1 && return 0
774
775     # else, it is not systemd
776     return 1
777 }
778
779 started=0
780 if [ "${UID}" -eq 0 ]
781     then
782
783     if issystemd
784     then
785         # systemd is running on this system
786
787         if [ ! -f /etc/systemd/system/netdata.service ]
788         then
789             echo >&2 "Installing systemd service..."
790             run cp system/netdata.service /etc/systemd/system/netdata.service && \
791                 run systemctl daemon-reload && \
792                 run systemctl enable netdata
793         else
794             service netdata stop
795         fi
796
797         stop_all_netdata
798         service netdata restart && started=1
799     fi
800
801     if [ ${started} -eq 0 ]
802     then
803         # check if we can use the system service
804         service netdata stop
805         stop_all_netdata
806         service netdata restart && started=1
807         if [ ${started} -eq 0 ]
808         then
809             service netdata start && started=1
810         fi
811     fi
812 fi
813
814 if [ ${started} -eq 0 ]
815 then
816     # still not started...
817
818     stop_all_netdata
819
820     echo >&2 "Starting netdata..."
821     run ${NETDATA_PREFIX}/usr/sbin/netdata -P ${NETDATA_RUN_DIR}/netdata.pid "${@}"
822     if [ $? -ne 0 ]
823         then
824         echo >&2
825         echo >&2 "SORRY! FAILED TO START NETDATA!"
826         exit 1
827     else
828         echo >&2 "OK. NetData Started!"
829     fi
830
831     echo >&2
832 fi
833
834 # -----------------------------------------------------------------------------
835 # save a config file, if it is not already there
836
837 if [ ! -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ]
838     then
839     echo >&2
840     echo >&2 "-------------------------------------------------------------------------------"
841     echo >&2
842     echo >&2 "Downloading default configuration from netdata..."
843     sleep 5
844
845     # remove a possibly obsolete download
846     [ -f "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ] && rm "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new"
847
848     # disable a proxy to get data from the local netdata
849     export http_proxy=
850     export https_proxy=
851
852     # try wget
853     wget 2>/dev/null -O "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" "http://localhost:${NETDATA_PORT}/netdata.conf"
854     ret=$?
855
856     # try curl
857     if [ $ret -ne 0 -o ! -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ]
858         then
859         curl -s -o "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" "http://localhost:${NETDATA_PORT}/netdata.conf"
860         ret=$?
861     fi
862
863     if [ $ret -eq 0 -a -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ]
864         then
865         mv "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
866         echo >&2 "New configuration saved for you to edit at ${NETDATA_PREFIX}/etc/netdata/netdata.conf"
867
868         if [ "${UID}" -eq 0 ]
869             then
870             chown "${NETDATA_USER}" "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
871         fi
872         chmod 0664 "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
873     else
874         echo >&2 "Cannnot download configuration from netdata daemon using url 'http://localhost:${NETDATA_PORT}/netdata.conf'"
875         [ -f "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ] && rm "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new"
876     fi
877 fi
878
879 # -----------------------------------------------------------------------------
880 # Check for KSM
881
882 ksm_is_available_but_disabled() {
883     cat <<KSM1
884
885 -------------------------------------------------------------------------------
886 Memory de-duplication instructions
887
888 You have kernel memory de-duper (called Kernel Same-page Merging,
889 or KSM) available, but it is not currently enabled.
890
891 To enable it run:
892
893 echo 1 >/sys/kernel/mm/ksm/run
894 echo 1000 >/sys/kernel/mm/ksm/sleep_millisecs
895
896 If you enable it, you will save 40-60% of netdata memory.
897
898 KSM1
899 }
900
901 ksm_is_not_available() {
902     cat <<KSM2
903
904 -------------------------------------------------------------------------------
905 Memory de-duplication not present in your kernel
906
907 It seems you do not have kernel memory de-duper (called Kernel Same-page
908 Merging, or KSM) available.
909
910 To enable it, you need a kernel built with CONFIG_KSM=y
911
912 If you can have it, you will save 40-60% of netdata memory.
913
914 KSM2
915 }
916
917 if [ -f "/sys/kernel/mm/ksm/run" ]
918     then
919     if [ $(cat "/sys/kernel/mm/ksm/run") != "1" ]
920         then
921         ksm_is_available_but_disabled
922     fi
923 else
924     ksm_is_not_available
925 fi
926
927 # -----------------------------------------------------------------------------
928 # Check for version.txt
929
930 if [ ! -s web/version.txt ]
931     then
932     cat <<VERMSG
933
934 -------------------------------------------------------------------------------
935 Version update check warning
936
937 The way you downloaded netdata, we cannot find its version. This means the
938 Update check on the dashboard, will not work.
939
940 If you want to have version update check, please re-install it
941 following the procedure in:
942
943 https://github.com/firehol/netdata/wiki/Installation
944
945 VERMSG
946 fi
947
948 # -----------------------------------------------------------------------------
949 # apps.plugin warning
950
951 if [ "${UID}" -ne 0 ]
952     then
953     cat <<SETUID_WARNING
954
955 -------------------------------------------------------------------------------
956 apps.plugin needs privileges
957
958 Since you have installed netdata as a normal user, to have apps.plugin collect
959 all the needed data, you have to give it the access rights it needs, by running
960 either of the following sets of commands:
961
962 To run apps.plugin with escalated capabilities:
963
964     sudo chown root:${NETDATA_USER} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
965     sudo chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
966     sudo setcap cap_dac_read_search,cap_sys_ptrace+ep "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
967
968 or, to run apps.plugin as root:
969
970     sudo chown root "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
971     sudo chmod 4755 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
972
973 apps.plugin is performing a hard-coded function of data collection for all
974 running processes. It cannot be instructed from the netdata daemon to perform
975 any task, so it is pretty safe to do this.
976
977 SETUID_WARNING
978 fi
979
980 # -----------------------------------------------------------------------------
981 # Keep un-install info
982
983 cat >netdata-uninstaller.sh <<UNINSTALL
984 #!/usr/bin/env bash
985
986 # this script will uninstall netdata
987
988 if [ "\$1" != "--force" ]
989     then
990     echo >&2 "This script will REMOVE netdata from your system."
991     echo >&2 "Run it again with --force to do it."
992     exit 1
993 fi
994
995 echo >&2 "Stopping a possibly running netdata..."
996 for p in \$(pidof netdata); do kill \$p; done
997 sleep 2
998
999 deletedir() {
1000     if [ ! -z "\$1" -a -d "\$1" ]
1001         then
1002         echo
1003         echo "Deleting directory '\$1' ..."
1004         rm -I -R "\$1"
1005     fi
1006 }
1007
1008 if [ ! -z "${NETDATA_PREFIX}" -a -d "${NETDATA_PREFIX}" ]
1009     then
1010     # installation prefix was given
1011
1012     deletedir "${NETDATA_PREFIX}"
1013
1014 else
1015     # installation prefix was NOT given
1016
1017     if [ -f "${NETDATA_PREFIX}/usr/sbin/netdata" ]
1018         then
1019         echo "Deleting ${NETDATA_PREFIX}/usr/sbin/netdata ..."
1020         rm -i "${NETDATA_PREFIX}/usr/sbin/netdata"
1021     fi
1022
1023     deletedir "${NETDATA_PREFIX}/etc/netdata"
1024     deletedir "${NETDATA_PREFIX}/usr/share/netdata"
1025     deletedir "${NETDATA_PREFIX}/usr/libexec/netdata"
1026     deletedir "${NETDATA_PREFIX}/var/lib/netdata"
1027     deletedir "${NETDATA_PREFIX}/var/cache/netdata"
1028     deletedir "${NETDATA_PREFIX}/var/log/netdata"
1029 fi
1030
1031 if [ -f /etc/logrotate.d/netdata ]
1032     then
1033     echo "Deleting /etc/logrotate.d/netdata ..."
1034     rm -i /etc/logrotate.d/netdata
1035 fi
1036
1037 if [ -f /etc/systemd/system/netdata.service ]
1038     then
1039     echo "Deleting /etc/systemd/system/netdata.service ..."
1040     rm -i /etc/systemd/system/netdata.service
1041 fi
1042
1043 getent passwd netdata > /dev/null
1044 if [ $? -eq 0 ]
1045     then
1046     echo
1047     echo "You may also want to remove the user netdata"
1048     echo "by running:"
1049     echo "   userdel netdata"
1050 fi
1051
1052 getent group netdata > /dev/null
1053 if [ $? -eq 0 ]
1054     then
1055     echo
1056     echo "You may also want to remove the group netdata"
1057     echo "by running:"
1058     echo "   groupdel netdata"
1059 fi
1060
1061 getent group docker > /dev/null
1062 if [ $? -eq 0 -a "${NETDATA_ADDED_TO_DOCKER}" = "1" ]
1063     then
1064     echo
1065     echo "You may also want to remove the netdata user from the docker group"
1066     echo "by running:"
1067     echo "   gpasswd -d netdata docker"
1068 fi
1069
1070 UNINSTALL
1071 chmod 750 netdata-uninstaller.sh
1072
1073 # -----------------------------------------------------------------------------
1074
1075 cat <<END
1076
1077
1078 -------------------------------------------------------------------------------
1079
1080 OK. NetData is installed and it is running.
1081
1082 -------------------------------------------------------------------------------
1083
1084 By default netdata listens on all IPs on port ${NETDATA_PORT},
1085 so you can access it with:
1086
1087 http://this.machine.ip:${NETDATA_PORT}/
1088
1089 To stop netdata, just kill it, with:
1090
1091   killall netdata
1092
1093 To start it, just run it:
1094
1095   ${NETDATA_PREFIX}/usr/sbin/netdata
1096
1097
1098 END
1099 echo >&2 "Uninstall script generated: ./netdata-uninstaller.sh"
1100
1101 if [ -d .git ]
1102     then
1103     cat >netdata-updater.sh.new <<REINSTALL
1104 #!/usr/bin/env bash
1105
1106 force=0
1107 [ "\${1}" = "-f" ] && force=1
1108
1109 export PATH="\${PATH}:${PATH}"
1110 export CFLAGS="${CFLAGS}"
1111
1112 INSTALL_UID="${UID}"
1113 if [ "\${INSTALL_UID}" != "\${UID}" ]
1114     then
1115     echo >&2 "This script should be run as user with uid \${INSTALL_UID} but it now runs with uid \${UID}"
1116     exit 1
1117 fi
1118
1119 # make sure we cd to the working directory
1120 cd "${REINSTALL_PWD}" || exit 1
1121
1122 # make sure there is .git here
1123 [ \${force} -eq 0 -a ! -d .git ] && echo >&2 "No git structures found at: ${REINSTALL_PWD} (use -f for force re-install)" && exit 1
1124
1125 # signal netdata to start saving its database
1126 # this is handy if your database is big
1127 pids=\$(pidof netdata)
1128 [ ! -z "\${pids}" ] && kill -USR1 \${pids}
1129
1130 tmp=
1131 if [ -t 2 ]
1132     then
1133     # we are running on a terminal
1134     # open fd 3 and send it to stderr
1135     exec 3>&2
1136 else
1137     # we are headless
1138     # create a temporary file for the log
1139     tmp=\$(mktemp /tmp/netdata-updater-log-XXXXXX.log)
1140     # open fd 3 and send it to tmp
1141     exec 3>\${tmp}
1142 fi
1143
1144 info() {
1145     echo >&3 "\$(date) : INFO: " "\${@}"
1146 }
1147
1148 emptyline() {
1149     echo >&3
1150 }
1151
1152 error() {
1153     echo >&3 "\$(date) : ERROR: " "\${@}"
1154 }
1155
1156 # this is what we will do if it fails (head-less only)
1157 failed() {
1158     error "FAILED TO UPDATE NETDATA : \${1}"
1159
1160     if [ ! -z "\${tmp}" ]
1161     then
1162         cat >&2 "\${tmp}"
1163         rm "\${tmp}"
1164     fi
1165     exit 1
1166 }
1167
1168 get_latest_commit_id() {
1169     git log -1           2>&3 |\\
1170         grep ^commit     2>&3 |\\
1171         head -n 1        2>&3 |\\
1172         cut -d ' ' -f 2  2>&3
1173 }
1174
1175 update() {
1176     [ -z "\${tmp}" ] && info "Running on a terminal - (this script also supports running headless from crontab)"
1177
1178     emptyline
1179
1180     if [ -d .git ]
1181         then
1182         info "Updating netdata source from github..."
1183
1184         last_commit="\$(get_latest_commit_id)"
1185         [ \${force} -eq 0 -a -z "\${last_commit}" ] && failed "CANNOT GET LAST COMMIT ID (use -f for force re-install)"
1186
1187         git pull >&3 2>&3 || failed "CANNOT FETCH LATEST SOURCE (use -f for force re-install)"
1188
1189         new_commit="\$(get_latest_commit_id)"
1190         if [ \${force} -eq 0 ]
1191             then
1192             [ -z "\${new_commit}" ] && failed "CANNOT GET NEW LAST COMMIT ID (use -f for force re-install)"
1193             [ "\${new_commit}" = "\${last_commit}" ] && info "Nothing to be done! (use -f to force re-install)" && exit 0
1194         fi
1195     elif [ \${force} -eq 0 ]
1196         then
1197         failed "CANNOT FIND GIT STRUCTURES IN \$(pwd) (use -f for force re-install)"
1198     fi
1199
1200     emptyline
1201     info "Re-installing netdata..."
1202     ${REINSTALL_COMMAND// --dont-wait/} --dont-wait >&3 2>&3 || failed "FAILED TO COMPILE/INSTALL NETDATA"
1203
1204     [ ! -z "\${tmp}" ] && rm "\${tmp}" && tmp=
1205     return 0
1206 }
1207
1208 # the installer updates this script - so we run and exit in a single line
1209 update && exit 0
1210 ###############################################################################
1211 ###############################################################################
1212 REINSTALL
1213     chmod 755 netdata-updater.sh.new
1214     mv -f netdata-updater.sh.new netdata-updater.sh
1215     echo >&2 "Update script generated   : ./netdata-updater.sh"
1216 elif [ -f "netdata-updater.sh" ]
1217     then
1218     rm "netdata-updater.sh"
1219 fi
1220
1221 banner "is installed and running now!"
1222 echo >&2 "  enjoy real-time performance and health monitoring..."
1223 echo >&2 
1224 exit 0