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