-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrbc
executable file
·159 lines (137 loc) · 5.27 KB
/
rbc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/bash
RBC_VERSION="1.3"
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
EMAIL_OWNER=0
QUIET=0
REBOOT_ALLOWED=0
REBOOT_REQUIRED=0
SUMMARY=0
SYSLOG=0
MANUAL_REBOOT=1
REBOOT_DOW="X"
die () {
printf "Error, exiting: " 1>&2
echo "$@" 1>&2
exit 255
}
syslogit () {
logger -t rbc -p auth.warning -f "${1}"
}
usage () {
printf "%s" "$0" 1>&2
printf " usage summary:\n" 1>&2
printf " -h: (or --help) print usage summary\n" 1>&2
printf " -l: log to SYSLOG facilities\n" 1>&2
printf " -m: email reboots@localhost (set the alias to email externally)\n" 1>&2
printf " -q: suppress output to STDOUT\n" 1>&2
printf " -r: reboot the system in 30 minutes if reboot is required, SYSLOG is forced\n" 1>&2
printf " -s: print a one line status summary in CSV, with the following format\n"
printf " hostname, OS release, uptime, auto-reboot disabled, RBC status code, reboot day of week\n" 1>&2
printf " -V: display version and exit\n" 1>&2
printf " EXIT codes:\n" 1>&2
printf "%14s %-70s\n" "0:" "reboot not required" 1>&2
printf "%14s %-70s\n" "1:" "reboot required, kernel only" 1>&2
printf "%14s %-70s\n" "2:" "reboot required, processes only" 1>&2
printf "%14s %-70s\n" "3:" "reboot required, kernel & processes" 1>&2
printf "%14s %-70s\n" "254:" "printed help summary and exited" 1>&2
printf "%14s %-70s\n" "255:" "failed to run due to other error" 1>&2
}
version () {
printf "RBC version ${RBC_VERSION}\n"
}
email_owner () {
[ $REBOOT_REQUIRED -eq 0 ] && SUBJECT="${HOSTNAME}: reboot not required"
[ $REBOOT_REQUIRED -eq 1 ] && SUBJECT="${HOSTNAME}: reboot requried"
if [[ $REBOOT_ALLOWED -eq 1 && $REBOOT_REQUIRED -eq 1 ]]; then
SUBJECT="*** ${HOSTNAME} will reboot in 30 minutes ***"
fi
mail -s "${SUBJECT}" reboots@localhost < "${1}"
}
for X in mail hostname lsof wc column awk rpm sed head uname dd tr cut date logger shutdown; do
which "${X}" >/dev/null 2>&1 || die "required application ${X} not found"
done
DATEY="$(date +%Y%m%d-%H%M%S)"
HOSTNAME="$(hostname -s)"
TMPFILE=/tmp/"$(dd if=/dev/urandom bs=1 count=256 2>/dev/null |tr -c -d '0-9a-f' |cut -c-7)"
for X in ${1:+"$@"}; do
case "${X}" in
(-h|--help)
usage
exit 254
;;
(-V|--version)
version
exit 0
;;
-l)
SYSLOG=1
;;
-m)
EMAIL_OWNER=1
;;
-q)
QUIET=1
;;
-r)
REBOOT_ALLOWED=1
SYSLOG=1
;;
-s)
QUIET=1
SUMMARY=1
;;
*)
usage
die "invalid parameter: ${X}"
;;
esac
done
[ "$TMPFILE" == "/tmp/" ] && die
echo "### ${HOSTNAME}: Reboot automation notice: ${DATEY} ###" > "${TMPFILE}"
lsof +c0 -b -d DEL 2>/dev/null | \
grep -v '\s/SYSV\|/\[aio\]$\|/dev/shm/.\+\|DEL.\+/tmp/.\+\|/var/lib/sss/mc/\(initgroups\|passwd\)' | \
grep -v 'DEL.*\.config/dconf/user$\|DEL.*/run/user/.*/dconf/user$\|pulseaudio.*DEL.*/run/user' | \
grep -v 'Xwayland.*DEL.*/run/user/[0-9]\|java.*DEL.*/var/crashplan/jna-.*tmp$\|caja.*DEL.*gvfs-metadata' | \
grep -v 'tuned.*DEL.*/ffi\|DEL.*/memfd:pulseaudio\|DEL.*/var/lib/sss/mc/.' | \
grep -v 'firewalld.*DEL.*/ffi\|rhsmd.*DEL.*/ffi\|DEL.*/memfd:xorg\|DEL.*/memfd:dbus' | \
grep -v 'DEL.*/memfd:xshmfence\|DEL.*/#[0-9]*\|DEL.*/i915\|memfd:\(mozilla-ipc\|pipewire\)' | \
grep -v 'DEL.*/memfd:libffi\|DEL.*/home/.*/.local/share/gvfs-metadata|DEL.*/jenkins/.cache/' | \
grep -v '/.cache/JNA/temp/\|/usr/lib/fontconfig/cache/\|/usr/share/.*\.cache' | \
awk 'NR==1 || !/dev\/zero/ {print $2,$1,$4,$NF}' | column -t >> "${TMPFILE}"
if [ "$(wc -l < ${TMPFILE})" -gt 2 ]; then
(( REBOOT_REQUIRED+=2 ))
else
echo "### ${HOSTNAME}: Reboot automation notice: ${DATEY} ###" > "${TMPFILE}"
fi
C_KERN="kernel-$(uname -r)"
A_KERN="$(rpm -q --last kernel |head -1 |sed 's|\s\+.*$||')"
if [ "$A_KERN" != "$C_KERN" ]; then
(( REBOOT_REQUIRED++ ))
printf "Running %s, but %s available\n" "$C_KERN" "$A_KERN" >> "${TMPFILE}"
fi
echo "### ${HOSTNAME}: End of reboot automation notice: ${DATEY} ###" >> "${TMPFILE}"
[ $REBOOT_REQUIRED -eq 0 ] && printf "\t %s: Reboot is not required.\n" "${HOSTNAME}" > "${TMPFILE}"
[ $SYSLOG -eq 1 ] && syslogit "${TMPFILE}"
[ $EMAIL_OWNER -eq 1 ] && email_owner "${TMPFILE}"
[ $QUIET -eq 0 ] && cat "${TMPFILE}"
[ -f "${TMPFILE}" ] && rm -f "${TMPFILE}"
if [ $REBOOT_REQUIRED -ne 0 ]; then
[ $REBOOT_ALLOWED -eq 1 ] && shutdown -r +30 "System reboot is required. To cancel use shutdown -c. But don't because this system needs to be rebooted"
fi
if [ $SUMMARY -eq 1 ] ; then
if [ -f /etc/cron.d/auto-reboot ] ; then
if grep -q '^\s*[0-9].*/usr/.*/\?sbin/rbc.*-r.*$' /etc/cron.d/auto-reboot 2>&1 ; then MANUAL_REBOOT=0 ; fi
if [ $MANUAL_REBOOT -eq 0 ] ; then REBOOT_DOW="$( awk '{ print $5 }' < /etc/cron.d/auto-reboot)" ; fi
fi
# get the following the hard way since RHEL 6 uptime does not have the -s flag :(
UPSINCE=$(date -d @$(( $(date +%s) - $(sed 's|\..*$||' /proc/uptime) )) +%Y-%m-%d\ %H:%M:%S)
printf "%s,%s,%s,%s,%s,%s,%s\n" \
"${HOSTNAME}" \
"$(sed 's|[Rr]ed.*inux|RHEL|;s|\s*[Ss]erver||;s|release\s*||' /etc/redhat-release)" \
"$(uname -r |sed 's|\.[^.]*$||;s|\.[^.]*$||')" \
"${UPSINCE}" \
"${MANUAL_REBOOT}" \
"${REBOOT_REQUIRED}" \
"${REBOOT_DOW}"
fi
exit $REBOOT_REQUIRED