]> arthur.barton.de Git - netdata.git/blob - installer/functions.sh
5c81f88b5fc251b64ad9a842ae59e7dc1dbeb27d
[netdata.git] / installer / functions.sh
1 # no shebang necessary - this is a library to be sourced
2
3 # -----------------------------------------------------------------------------
4 # checking the availability of commands
5
6 which_cmd() {
7     which "${1}" 2>/dev/null || \
8         command -v "${1}" 2>/dev/null
9 }
10
11 check_cmd() {
12     which_cmd "${1}" >/dev/null 2>&1 && return 0
13     return 1
14 }
15
16
17 # -----------------------------------------------------------------------------
18
19 setup_terminal() {
20     # Is stderr on the terminal? If not, then fail
21     test -t 2 || return 1
22
23     if [ ! -z "$TPUT_CMD" ]
24     then
25         if [ $[$($TPUT_CMD colors 2>/dev/null)] -ge 8 ]
26         then
27             # Enable colors
28             COLOR_RESET="\e[0m"
29             COLOR_BLACK="\e[30m"
30             COLOR_RED="\e[31m"
31             COLOR_GREEN="\e[32m"
32             COLOR_YELLOW="\e[33m"
33             COLOR_BLUE="\e[34m"
34             COLOR_PURPLE="\e[35m"
35             COLOR_CYAN="\e[36m"
36             COLOR_WHITE="\e[37m"
37             COLOR_BGBLACK="\e[40m"
38             COLOR_BGRED="\e[41m"
39             COLOR_BGGREEN="\e[42m"
40             COLOR_BGYELLOW="\e[43m"
41             COLOR_BGBLUE="\e[44m"
42             COLOR_BGPURPLE="\e[45m"
43             COLOR_BGCYAN="\e[46m"
44             COLOR_BGWHITE="\e[47m"
45             COLOR_BOLD="\e[1m"
46             COLOR_DIM="\e[2m"
47             COLOR_UNDERLINED="\e[4m"
48             COLOR_BLINK="\e[5m"
49             COLOR_INVERTED="\e[7m"
50         fi
51     fi
52
53     return 0
54 }
55 TPUT_CMD="$(which_cmd tput)"
56 setup_terminal
57
58 progress() {
59     printf >&2 " --- ${COLOR_DIM}${COLOR_BOLD}${*}${COLOR_RESET} --- \n"
60 }
61
62 # -----------------------------------------------------------------------------
63
64 netdata_banner() {
65     local   l1="  ^"                                                                            \
66             l2="  |.-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-"  \
67             l3="  |   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'   '-'  "  \
68             l4="  +----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--->" \
69             sp="                                                                              " \
70             netdata="netdata" start end msg="${*}" chartcolor="${COLOR_DIM}"
71
72     [ ${#msg} -lt ${#netdata} ] && msg="${msg}${sp:0:$(( ${#netdata} - ${#msg}))}"
73     [ ${#msg} -gt $(( ${#l2} - 20 )) ] && msg="${msg:0:$(( ${#l2} - 23 ))}..."
74
75     start="$(( ${#l2} / 2 - 4 ))"
76     [ $(( start + ${#msg} + 4 )) -gt ${#l2} ] && start=$((${#l2} - ${#msg} - 4))
77     end=$(( ${start} + ${#msg} + 4 ))
78
79     echo >&2
80     echo >&2 -e "${chartcolor}${l1}${COLOR_RESET}"
81     echo >&2 -e "${chartcolor}${l2:0:start}${sp:0:2}${COLOR_RESET}${COLOR_BOLD}${COLOR_GREEN}${netdata}${COLOR_RESET}${chartcolor}${sp:0:$((end - start - 2 - ${#netdata}))}${l2:end:$((${#l2} - end))}${COLOR_RESET}"
82     echo >&2 -e "${chartcolor}${l3:0:start}${sp:0:2}${COLOR_RESET}${COLOR_BOLD}${COLOR_CYAN}${msg}${COLOR_RESET}${chartcolor}${sp:0:2}${l3:end:$((${#l2} - end))}${COLOR_RESET}"
83     echo >&2 -e "${chartcolor}${l4}${COLOR_RESET}"
84     echo >&2
85 }
86
87 # -----------------------------------------------------------------------------
88 # portable service command
89
90 service_cmd="$(which_cmd service)"
91 systemctl_cmd="$(which_cmd systemctl)"
92 service() {
93     local cmd="${1}" action="${2}"
94
95     if [ ! -z "${service_cmd}" ]
96     then
97         run "${service_cmd}" "${cmd}" "${action}"
98         return $?
99     elif [ ! -z "${systemctl_cmd}" ]
100     then
101         run "${systemctl_cmd}" "${action}" "${cmd}"
102         return $?
103     fi
104     return 1
105 }
106
107 # -----------------------------------------------------------------------------
108
109 run_logfile="/dev/null"
110 run() {
111     local user="${USER}" dir="$(basename "${PWD}")" info info_console
112
113     if [ "${UID}" = "0" ]
114         then
115         info="[root ${dir}]# "
116         info_console="[${COLOR_DIM}${dir}${COLOR_RESET}]# "
117     else
118         info="[${user} ${dir}]$ "
119         info_console="[${COLOR_DIM}${dir}${COLOR_RESET}]$ "
120     fi
121
122     printf >> "${run_logfile}" "${info}"
123     printf >> "${run_logfile}" "%q " "${@}"
124     printf >> "${run_logfile}" " ... "
125
126     printf >&2 "${info_console}${COLOR_BOLD}${COLOR_YELLOW}"
127     printf >&2 "%q " "${@}"
128     printf >&2 "${COLOR_RESET}\n"
129
130     "${@}"
131
132     local ret=$?
133     if [ ${ret} -ne 0 ]
134         then
135         printf >&2 "${COLOR_BGRED}${COLOR_WHITE}${COLOR_BOLD} FAILED ${COLOR_RESET}\n\n"
136         printf >> "${run_logfile}" "FAILED with exit code ${ret}\n"
137     else
138         printf >&2 "${COLOR_BGGREEN}${COLOR_WHITE}${COLOR_BOLD} OK ${COLOR_RESET}\n\n"
139         printf >> "${run_logfile}" "OK\n"
140     fi
141
142     return ${ret}
143 }
144
145 portable_add_user() {
146     local username="${1}"
147
148     getent passwd "${username}" > /dev/null 2>&1
149     [ $? -eq 0 ] && return 0
150
151     echo >&2 "Adding ${username} user account ..."
152
153     local nologin="$(which nologin 2>/dev/null || command -v nologin 2>/dev/null || echo '/bin/false')"
154
155     # Linux
156     if check_cmd useradd
157     then
158         run useradd -r -g "${username}" -c "${username}" -s "${nologin}" -d / "${username}" && return 0
159     fi
160
161     # FreeBSD
162     if check_cmd pw
163     then
164         run pw useradd "${username}" -d / -g "${username}" -s "${nologin}" && return 0
165     fi
166
167     # BusyBox
168     if check_cmd adduser
169     then
170         run adduser -D -G "${username}" "${username}" && return 0
171     fi
172
173     echo >&2 "Failed to add ${username} user account !"
174
175     return 1
176 }
177
178 portable_add_group() {
179     local groupname="${1}"
180
181     getent group "${groupname}" > /dev/null 2>&1
182     [ $? -eq 0 ] && return 0
183
184     echo >&2 "Adding ${groupname} user group ..."
185
186     # Linux
187     if check_cmd groupadd
188     then
189         run groupadd -r "${groupname}" && return 0
190     fi
191
192     # FreeBSD
193     if check_cmd pw
194     then
195         run pw groupadd "${groupname}" && return 0
196     fi
197
198     # BusyBox
199     if check_cmd addgroup
200     then
201         run addgroup "${groupname}" && return 0
202     fi
203
204     echo >&2 "Failed to add ${groupname} user group !"
205     return 1
206 }
207
208 portable_add_user_to_group() {
209     local groupname="${1}" username="${2}"
210
211     getent group "${groupname}" > /dev/null 2>&1
212     [ $? -ne 0 ] && return 1
213
214     # find the user is already in the group
215     local users=$(getent group "${groupname}" | cut -d ':' -f 4)
216     if [[ ",${users}," =~ ,${username}, ]]
217         then
218         # username is already there
219         return 0
220     else
221         # username is not in group
222         echo >&2 "Adding ${username} user to the ${groupname} group ..."
223
224         # Linux
225         if check_cmd usermod
226         then
227             run usermod -a -G "${groupname}" "${username}" && return 0
228         fi
229
230         # FreeBSD
231         if check_cmd pw
232         then
233             run pw groupmod "${groupname}" -m "${username}" && return 0
234         fi
235
236         # BusyBox
237         if check_cmd addgroup
238         then
239             run addgroup "${username}" "${groupname}" && return 0
240         fi
241
242         echo >&2 "Failed to add user ${username} to group ${groupname} !"
243         return 1
244     fi
245 }
246
247 iscontainer() {
248     # man systemd-detect-virt
249     local cmd=$(which_cmd systemd-detect-virt)
250     if [ ! -z "${cmd}" -a -x "${cmd}" ]
251         then
252         "${cmd}" --container >/dev/null 2>&1 && return 0
253     fi
254
255     # /proc/1/sched exposes the host's pid of our init !
256     # http://stackoverflow.com/a/37016302
257     local pid=$( cat /proc/1/sched | head -n 1 | { IFS='(),#:' read name pid th threads; echo $pid; } )
258     local p=$(( pid + 0 ))
259     [ ${pid} -ne 1 ] && return 0
260
261     # lxc sets environment variable 'container'
262     [ ! -z "${container}" ] && return 0
263
264     # docker creates /.dockerenv
265     # http://stackoverflow.com/a/25518345
266     [ -f "/.dockerenv" ] && return 0
267
268     # ubuntu and debian supply /bin/running-in-container
269     # https://www.apt-browse.org/browse/ubuntu/trusty/main/i386/upstart/1.12.1-0ubuntu4/file/bin/running-in-container
270     if [ -x "/bin/running-in-container" ]
271         then
272         "/bin/running-in-container" >/dev/null 2>&1 && return 0
273     fi
274
275     return 1
276 }
277
278 issystemd() {
279     local pids p myns ns systemctl
280
281     # if the directory /etc/systemd/system does not exit, it is not systemd
282     [ ! -d /etc/systemd/system ] && return 1
283
284     # if there is no systemctl command, it is not systemd
285     systemctl=$(which systemctl 2>/dev/null || command -v systemctl 2>/dev/null)
286     [ -z "${systemctl}" -o ! -x "${systemctl}" ] && return 1
287
288     # if pid 1 is systemd, it is systemd
289     [ "$(basename $(readlink /proc/1/exe) 2>/dev/null)" = "systemd" ] && return 0
290
291     # if systemd is not running, it is not systemd
292     pids=$(pidof systemd 2>/dev/null)
293     [ -z "${pids}" ] && return 1
294
295     # check if the running systemd processes are not in our namespace
296     myns="$(readlink /proc/self/ns/pid 2>/dev/null)"
297     for p in ${pids}
298     do
299         ns="$(readlink /proc/${p}/ns/pid 2>/dev/null)"
300
301         # if pid of systemd is in our namespace, it is systemd
302         [ ! -z "${myns}" && "${myns}" = "${ns}" ] && return 0
303     done
304
305     # else, it is not systemd
306     return 1
307 }