]> arthur.barton.de Git - netdata.git/blob - netdata-installer.sh
netdata-updater.sh now support -f to force re-installation even if git has not been...
[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   .-.   .-.   .-.   .-.   .-.   netdata
680      '-'   '-'   '-'   '-'   '  is installed on this system now!
681
682   enjoy real-time, performance and health monitoring...
683
684 DONE1
685     exit 0
686 fi
687
688 # -----------------------------------------------------------------------------
689 # stop a running netdata
690
691 isnetdata() {
692     [ -z "$1" -o ! -f "/proc/$1/stat" ] && return 1
693     [ "$(cat "/proc/$1/stat" | cut -d '(' -f 2 | cut -d ')' -f 1)" = "netdata" ] && return 0
694     return 1
695 }
696
697 stop_netdata_on_pid() {
698     local pid="$1" ret=0 count=0
699
700     isnetdata $pid || return 0
701
702     printf >&2 "Stopping netdata on pid $pid ..."
703     while [ ! -z "$pid" -a $ret -eq 0 ]
704     do
705         if [ $count -gt 45 ]
706             then
707             echo >&2 "Cannot stop the running netdata on pid $pid."
708             return 1
709         fi
710
711         count=$(( count + 1 ))
712
713         run kill $pid 2>/dev/null
714         ret=$?
715
716         test $ret -eq 0 && printf >&2 "." && sleep 2
717     done
718
719     echo >&2
720     if [ $ret -eq 0 ]
721     then
722         echo >&2 "SORRY! CANNOT STOP netdata ON PID $pid !"
723         return 1
724     fi
725
726     echo >&2 "netdata on pid $pid stopped."
727     return 0
728 }
729
730 stop_all_netdata() {
731     local p
732
733     echo >&2 "Stopping a (possibly) running netdata..."
734
735     for p in $(cat "${NETDATA_RUN_DIR}/netdata.pid" 2>/dev/null) \
736         $(cat /var/run/netdata.pid 2>/dev/null) \
737         $(cat /var/run/netdata/netdata.pid 2>/dev/null) \
738         $(pidof netdata 2>/dev/null)
739     do
740         stop_netdata_on_pid $p
741     done
742 }
743
744 # -----------------------------------------------------------------------------
745 # check netdata for systemd
746
747 issystemd() {
748     # if the directory /etc/systemd/system does not exit, it is not systemd
749     [ ! -d /etc/systemd/system ] && return 1
750
751     # if pid 1 is systemd, it is systemd
752     [ "$(basename $(readlink /proc/1/exe) 2>/dev/null)" = "systemd" ] && return 0
753
754     # if systemd is running, it is systemd
755     pidof systemd >/dev/null 2>&1 && return 0
756
757     # else, it is not systemd
758     return 1
759 }
760
761 started=0
762 if [ "${UID}" -eq 0 ]
763     then
764
765     if issystemd
766     then
767         # systemd is running on this system
768
769         if [ ! -f /etc/systemd/system/netdata.service ]
770         then
771             echo >&2 "Installing systemd service..."
772             run cp system/netdata.service /etc/systemd/system/netdata.service && \
773                 run systemctl daemon-reload && \
774                 run systemctl enable netdata
775         else
776             service netdata stop
777         fi
778
779         stop_all_netdata
780         service netdata restart && started=1
781     fi
782
783     if [ ${started} -eq 0 ]
784     then
785         # check if we can use the system service
786         service netdata stop
787         stop_all_netdata
788         service netdata restart && started=1
789         if [ ${started} -eq 0 ]
790         then
791             service netdata start && started=1
792         fi
793     fi
794 fi
795
796 if [ ${started} -eq 0 ]
797 then
798     # still not started...
799
800     stop_all_netdata
801
802     echo >&2 "Starting netdata..."
803     run ${NETDATA_PREFIX}/usr/sbin/netdata -P ${NETDATA_RUN_DIR}/netdata.pid "${@}"
804     if [ $? -ne 0 ]
805         then
806         echo >&2
807         echo >&2 "SORRY! FAILED TO START NETDATA!"
808         exit 1
809     else
810         echo >&2 "OK. NetData Started!"
811     fi
812
813     echo >&2
814 fi
815
816 # -----------------------------------------------------------------------------
817 # save a config file, if it is not already there
818
819 if [ ! -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ]
820     then
821     echo >&2
822     echo >&2 "-------------------------------------------------------------------------------"
823     echo >&2
824     echo >&2 "Downloading default configuration from netdata..."
825     sleep 5
826
827     # remove a possibly obsolete download
828     [ -f "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ] && rm "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new"
829
830     # disable a proxy to get data from the local netdata
831     export http_proxy=
832     export https_proxy=
833
834     # try wget
835     wget 2>/dev/null -O "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" "http://localhost:${NETDATA_PORT}/netdata.conf"
836     ret=$?
837
838     # try curl
839     if [ $ret -ne 0 -o ! -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ]
840         then
841         curl -s -o "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" "http://localhost:${NETDATA_PORT}/netdata.conf"
842         ret=$?
843     fi
844
845     if [ $ret -eq 0 -a -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ]
846         then
847         mv "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
848         echo >&2 "New configuration saved for you to edit at ${NETDATA_PREFIX}/etc/netdata/netdata.conf"
849
850         if [ "${UID}" -eq 0 ]
851             then
852             chown "${NETDATA_USER}" "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
853         fi
854         chmod 0664 "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
855     else
856         echo >&2 "Cannnot download configuration from netdata daemon using url 'http://localhost:${NETDATA_PORT}/netdata.conf'"
857         [ -f "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new" ] && rm "${NETDATA_PREFIX}/etc/netdata/netdata.conf.new"
858     fi
859 fi
860
861 # -----------------------------------------------------------------------------
862 # Check for KSM
863
864 ksm_is_available_but_disabled() {
865     cat <<KSM1
866
867 -------------------------------------------------------------------------------
868 Memory de-duplication instructions
869
870 You have kernel memory de-duper (called Kernel Same-page Merging,
871 or KSM) available, but it is not currently enabled.
872
873 To enable it run:
874
875 echo 1 >/sys/kernel/mm/ksm/run
876 echo 1000 >/sys/kernel/mm/ksm/sleep_millisecs
877
878 If you enable it, you will save 40-60% of netdata memory.
879
880 KSM1
881 }
882
883 ksm_is_not_available() {
884     cat <<KSM2
885
886 -------------------------------------------------------------------------------
887 Memory de-duplication not present in your kernel
888
889 It seems you do not have kernel memory de-duper (called Kernel Same-page
890 Merging, or KSM) available.
891
892 To enable it, you need a kernel built with CONFIG_KSM=y
893
894 If you can have it, you will save 40-60% of netdata memory.
895
896 KSM2
897 }
898
899 if [ -f "/sys/kernel/mm/ksm/run" ]
900     then
901     if [ $(cat "/sys/kernel/mm/ksm/run") != "1" ]
902         then
903         ksm_is_available_but_disabled
904     fi
905 else
906     ksm_is_not_available
907 fi
908
909 # -----------------------------------------------------------------------------
910 # Check for version.txt
911
912 if [ ! -s web/version.txt ]
913     then
914     cat <<VERMSG
915
916 -------------------------------------------------------------------------------
917 Version update check warning
918
919 The way you downloaded netdata, we cannot find its version. This means the
920 Update check on the dashboard, will not work.
921
922 If you want to have version update check, please re-install it
923 following the procedure in:
924
925 https://github.com/firehol/netdata/wiki/Installation
926
927 VERMSG
928 fi
929
930 # -----------------------------------------------------------------------------
931 # apps.plugin warning
932
933 if [ "${UID}" -ne 0 ]
934     then
935     cat <<SETUID_WARNING
936
937 -------------------------------------------------------------------------------
938 apps.plugin needs privileges
939
940 Since you have installed netdata as a normal user, to have apps.plugin collect
941 all the needed data, you have to give it the access rights it needs, by running
942 either of the following sets of commands:
943
944 To run apps.plugin with escalated capabilities:
945
946     sudo chown root:${NETDATA_USER} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
947     sudo chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
948     sudo setcap cap_dac_read_search,cap_sys_ptrace+ep "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
949
950 or, to run apps.plugin as root:
951
952     sudo chown root "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
953     sudo chmod 4755 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"
954
955 apps.plugin is performing a hard-coded function of data collection for all
956 running processes. It cannot be instructed from the netdata daemon to perform
957 any task, so it is pretty safe to do this.
958
959 SETUID_WARNING
960 fi
961
962 # -----------------------------------------------------------------------------
963 # Keep un-install info
964
965 cat >netdata-uninstaller.sh <<UNINSTALL
966 #!/usr/bin/env bash
967
968 # this script will uninstall netdata
969
970 if [ "\$1" != "--force" ]
971     then
972     echo >&2 "This script will REMOVE netdata from your system."
973     echo >&2 "Run it again with --force to do it."
974     exit 1
975 fi
976
977 echo >&2 "Stopping a possibly running netdata..."
978 for p in \$(pidof netdata); do kill \$p; done
979 sleep 2
980
981 deletedir() {
982     if [ ! -z "\$1" -a -d "\$1" ]
983         then
984         echo
985         echo "Deleting directory '\$1' ..."
986         rm -I -R "\$1"
987     fi
988 }
989
990 if [ ! -z "${NETDATA_PREFIX}" -a -d "${NETDATA_PREFIX}" ]
991     then
992     # installation prefix was given
993
994     deletedir "${NETDATA_PREFIX}"
995
996 else
997     # installation prefix was NOT given
998
999     if [ -f "${NETDATA_PREFIX}/usr/sbin/netdata" ]
1000         then
1001         echo "Deleting ${NETDATA_PREFIX}/usr/sbin/netdata ..."
1002         rm -i "${NETDATA_PREFIX}/usr/sbin/netdata"
1003     fi
1004
1005     deletedir "${NETDATA_PREFIX}/etc/netdata"
1006     deletedir "${NETDATA_PREFIX}/usr/share/netdata"
1007     deletedir "${NETDATA_PREFIX}/usr/libexec/netdata"
1008     deletedir "${NETDATA_PREFIX}/var/lib/netdata"
1009     deletedir "${NETDATA_PREFIX}/var/cache/netdata"
1010     deletedir "${NETDATA_PREFIX}/var/log/netdata"
1011 fi
1012
1013 if [ -f /etc/logrotate.d/netdata ]
1014     then
1015     echo "Deleting /etc/logrotate.d/netdata ..."
1016     rm -i /etc/logrotate.d/netdata
1017 fi
1018
1019 if [ -f /etc/systemd/system/netdata.service ]
1020     then
1021     echo "Deleting /etc/systemd/system/netdata.service ..."
1022     rm -i /etc/systemd/system/netdata.service
1023 fi
1024
1025 getent passwd netdata > /dev/null
1026 if [ $? -eq 0 ]
1027     then
1028     echo
1029     echo "You may also want to remove the user netdata"
1030     echo "by running:"
1031     echo "   userdel netdata"
1032 fi
1033
1034 getent group netdata > /dev/null
1035 if [ $? -eq 0 ]
1036     then
1037     echo
1038     echo "You may also want to remove the group netdata"
1039     echo "by running:"
1040     echo "   groupdel netdata"
1041 fi
1042
1043 getent group docker > /dev/null
1044 if [ $? -eq 0 -a "${NETDATA_ADDED_TO_DOCKER}" = "1" ]
1045     then
1046     echo
1047     echo "You may also want to remove the netdata user from the docker group"
1048     echo "by running:"
1049     echo "   gpasswd -d netdata docker"
1050 fi
1051
1052 UNINSTALL
1053 chmod 750 netdata-uninstaller.sh
1054
1055 # -----------------------------------------------------------------------------
1056
1057 cat <<END
1058
1059
1060 -------------------------------------------------------------------------------
1061
1062 OK. NetData is installed and it is running.
1063
1064 -------------------------------------------------------------------------------
1065
1066 By default netdata listens on all IPs on port ${NETDATA_PORT},
1067 so you can access it with:
1068
1069 http://this.machine.ip:${NETDATA_PORT}/
1070
1071 To stop netdata, just kill it, with:
1072
1073   killall netdata
1074
1075 To start it, just run it:
1076
1077   ${NETDATA_PREFIX}/usr/sbin/netdata
1078
1079
1080 END
1081 echo >&2 "Uninstall script generated: ./netdata-uninstaller.sh"
1082
1083 if [ -d .git ]
1084     then
1085     cat >netdata-updater.sh.new <<REINSTALL
1086 #!/usr/bin/env bash
1087
1088 force=0
1089 [ "\${1}" = "-f" ] && force=1
1090
1091 export PATH="\${PATH}:${PATH}"
1092 export CFLAGS="${CFLAGS}"
1093
1094 INSTALL_UID="${UID}"
1095 if [ "\${INSTALL_UID}" != "\${UID}" ]
1096     then
1097     echo >&2 "This script should be run as user with uid \${INSTALL_UID} but it now runs with uid \${UID}"
1098     exit 1
1099 fi
1100
1101 # make sure we cd to the working directory
1102 cd "${REINSTALL_PWD}" || exit 1
1103
1104 # make sure there is .git here
1105 [ \${force} -eq 0 -a ! -d .git ] && echo >&2 "No git structures found at: ${REINSTALL_PWD} (use -f for force re-install)" && exit 1
1106
1107 # signal netdata to start saving its database
1108 # this is handy if your database is big
1109 pids=\$(pidof netdata)
1110 [ ! -z "\${pids}" ] && kill -USR1 \${pids}
1111
1112 tmp=
1113 if [ -t 2 ]
1114     then
1115     # we are running on a terminal
1116     # open fd 3 and send it to stderr
1117     exec 3>&2
1118 else
1119     # we are headless
1120     # create a temporary file for the log
1121     tmp=\$(mktemp /tmp/netdata-updater-log-XXXXXX.log)
1122     # open fd 3 and send it to tmp
1123     exec 3>\${tmp}
1124 fi
1125
1126 info() {
1127     echo >&3 "\$(date) : INFO: " "\${@}"
1128 }
1129
1130 emptyline() {
1131     echo >&3
1132 }
1133
1134 error() {
1135     echo >&3 "\$(date) : ERROR: " "\${@}"
1136 }
1137
1138 # this is what we will do if it fails (head-less only)
1139 failed() {
1140     error "FAILED TO UPDATE NETDATA : \${1}"
1141
1142     if [ ! -z "\${tmp}" ]
1143     then
1144         cat >&2 "\${tmp}"
1145         rm "\${tmp}"
1146     fi
1147     exit 1
1148 }
1149
1150 get_latest_commit_id() {
1151     git log -1           2>&3 |\\
1152         grep ^commit     2>&3 |\\
1153         head -n 1        2>&3 |\\
1154         cut -d ' ' -f 2  2>&3
1155 }
1156
1157 update() {
1158     [ -z "\${tmp}" ] && info "Running on a terminal - (this script also supports running headless from crontab)"
1159
1160     emptyline
1161
1162     if [ -d .git ]
1163         then
1164         info "Updating netdata source from github..."
1165
1166         last_commit="\$(get_latest_commit_id)"
1167         [ \${force} -eq 0 -a -z "\${last_commit}" ] && failed "CANNOT GET LAST COMMIT ID (use -f for force re-install)"
1168
1169         git pull >&3 2>&3 || failed "CANNOT FETCH LATEST SOURCE (use -f for force re-install)"
1170
1171         new_commit="\$(get_latest_commit_id)"
1172         if [ \${force} -eq 0 ]
1173             then
1174             [ -z "\${new_commit}" ] && failed "CANNOT GET NEW LAST COMMIT ID (use -f for force re-install)"
1175             [ "\${new_commit}" = "\${last_commit}" ] && info "Nothing to be done! (use -f to force re-install)" && exit 0
1176         fi
1177     elif [ \${force} -eq 0 ]
1178         then
1179         failed "CANNOT FIND GIT STRUCTURES IN \$(pwd) (use -f for force re-install)"
1180     fi
1181
1182     emptyline
1183     info "Re-installing netdata..."
1184     ${REINSTALL_COMMAND// --dont-wait/} --dont-wait >&3 2>&3 || failed "FAILED TO COMPILE/INSTALL NETDATA"
1185
1186     [ ! -z "\${tmp}" ] && rm "\${tmp}" && tmp=
1187     return 0
1188 }
1189
1190 # the installer updates this script - so we run and exit in a single line
1191 update && exit 0
1192 ###############################################################################
1193 ###############################################################################
1194 REINSTALL
1195     chmod 755 netdata-updater.sh.new
1196     mv -f netdata-updater.sh.new netdata-updater.sh
1197     echo >&2 "Update script generated   : ./netdata-updater.sh"
1198 elif [ -f "netdata-updater.sh" ]
1199     then
1200     rm "netdata-updater.sh"
1201 fi
1202
1203 cat >&2 <<"DONE"
1204
1205
1206   .-.   .-.   .-.   .-.   .-.   netdata
1207      '-'   '-'   '-'   '-'   '  is installed and is running now!
1208
1209   enjoy real-time, performance and health monitoring...
1210
1211 DONE
1212 exit 0