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