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