summaryrefslogtreecommitdiffstats
path: root/core/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script
blob: b761794031a08c5d088a35a3d92e91a9299b1b43 (plain) (blame)
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
#!/bin/ash

. /opt/openslx/config || exit 1

# If existent, no session is open. Will contain timestamp of last activity.
# If not existent, at least one user is logged in
CRONFILE="/etc/cron.d/idleaction-shutdown_schedule"
IDLEHINT="/dev/shm/idlehint"
NOW=$(date +%s)

#
# 1) Check for idle timeout
#
if [ -n "${SLX_LOGOUT_TIMEOUT}" ] && [ "${SLX_LOGOUT_TIMEOUT}" -gt 0 ]; then
	# Logout timeout is set, see which users we should kick
	IS_IDLE=yes
	# get all sessions
	SESSIONS=$(loginctl | awk '{print $1}')
	if [ -n "$SESSIONS" ]; then
		TMP="/dev/shm/idlecheck.tmp"
		# Iterate over sessions
		for ses in $SESSIONS; do
			# Get information
			loginctl show-session "$ses" > "$TMP"
			NAME=$(grep '^Name=' "$TMP" | cut -c 6-)
			[ -z "$NAME" ] && continue # No name - should not happen
			export DISPLAY=$(grep '^Display=' "$TMP" | cut -c 9-)
			# X11
			if [ -n "$DISPLAY" ]; then
				# Seems to be x11
				IDLE=
				export XAUTHORITY=$(ps a | grep " $DISPLAY " | grep -o -- '-auth.*$' | grep -m1 -v grep | awk '{print $2}')
				[ -n "$XAUTHORITY" ] && [ -f "$XAUTHORITY" ] && IDLE=$(xprintidle)
				# Now that we have DISPLAY and XAUTHORITY set, xprintidle should work
				if [ -z "$IDLE" ]; then
					# Try user's xauth
					USRHOME=$(/usr/bin/getent passwd "$NAME" | awk -F ':' '{print $6}')
					export XAUTHORITY="$USRHOME/.Xauthority"
					[ -f "$XAUTHORITY" ] && IDLE=$(xprintidle)
				fi
				if [ -n "$IDLE" ]; then
					IDLE=$(( $IDLE / 1000 ))
					if [ -z "$IDLE" ] || [ "$IDLE" -lt "$SLX_LOGOUT_TIMEOUT" ]; then
						IS_IDLE=no
					else
						loginctl terminate-session "$ses"
					fi
				else # xprintidle did not work
					IS_IDLE=no
				fi
				continue # Done with this session, skip normal tty/ssh checks
			fi
			# end X11
			# other sessions
			IDLE=$(grep '^IdleSinceHint=' "$TMP" | cut -c 15-)
			if [ "${#IDLE}" -lt 7 ]; then # wah wah waaaah
				IS_IDLE=no
				continue
			fi
			# divide by 1000000 by chopping of last 6 chars - number might be too large for $(( ))
			IDLE=$(echo "$IDLE" | cut -c "-$(( ${#IDLE} - 6 ))")
			[ "$IDLE" -gt "$NOW" ] && IDLE="$NOW"
			IDLE=$(( $NOW - $IDLE ))
			if [ "$IDLE" -lt "$SLX_LOGOUT_TIMEOUT" ]; then
				IS_IDLE=no
			else
				loginctl terminate-session "$ses"
			fi
			# end other sessions
		done
		rm -f -- "$TMP"
	fi
	if [ "$IS_IDLE" = "yes" ]; then
		[ ! -e "$IDLEHINT" ] && echo "$NOW" > "$IDLEHINT"
	else
		rm -f -- "$IDLEHINT"
	fi
else
	# No logout timeout is set, take shortcut for shutdown timeout (if set)
	if [ -n "$SLX_SHUTDOWN_TIMEOUT" ]; then
		SESSIONS=$(loginctl | wc -l)
		if [ "$SESSIONS" = "0" ]; then
			[ ! -e "$IDLEHINT" ] && echo "$NOW" > "$IDLEHINT"
		else
			rm -f -- "$IDLEHINT"
		fi
	fi
fi

#
# 2) Check for no-session-shutdown timeout
#
if [ -n "${SLX_SHUTDOWN_TIMEOUT}" ] && [ "${SLX_SHUTDOWN_TIMEOUT}" -gt 0 ] && [ -e "$IDLEHINT" ]; then
	IDLE=$(cat "$IDLEHINT")
	[ "$IDLE" -gt "$NOW" ] && IDLE="$NOW"
	IDLE=$(( $NOW - $IDLE ))
	if [ "$IDLE" -gt "$SLX_SHUTDOWN_TIMEOUT" ]; then
		poweroff
	fi
fi

#
# 3) Check for hard scheduled shutdown
#
# A cron file is created dynamically here so there's everything
# in one module and you don't need to repack config.tgz

invalid_time ()
{
	slxlog "idleaction-schedule" "Invalid shutdown time: '$time'. Expected HH:MM format."
	return 0
}

if [ -n "$SLX_SHUTDOWN_SCHEDULE" -o -n "$SLX_REBOOT_SCHEDULE" ] && [ ! -e "$CRONFILE" ]; then
	echo "# OpenSLX: Trigger poweroff at certain time of day" > "$CRONFILE"
	echo "SHELL=/bin/ash" >> "$CRONFILE"
	echo "PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" >> "$CRONFILE"
	echo "" >> "$CRONFILE"
	for time in $SLX_SHUTDOWN_SCHEDULE; do
		HOUR=${time%%:*}
		MINUTE=${time##*:}
		[ -z "$HOUR$MINUTE" ] && invalid_time && continue
		[ "$HOUR" -lt 0 -o "$HOUR" -gt 23 ] && invalid_time && continue
		[ "$MINUTE" -lt 0 -o "$MINUTE" -gt 59 ] && invalid_time && continue
		echo "$MINUTE $HOUR	* * *	root	/opt/openslx/scripts/idleaction-scheduled_action poweroff" >> "$CRONFILE"
	done
	# do it again for SLX_REBOOT_SCHEDULE
	for time in $SLX_REBOOT_SCHEDULE; do
		HOUR=${time%%:*}
		MINUTE=${time##*:}
		[ -z "$HOUR$MINUTE" ] && invalid_time && continue
		[ "$HOUR" -lt 0 -o "$HOUR" -gt 23 ] && invalid_time && continue
		[ "$MINUTE" -lt 0 -o "$MINUTE" -gt 59 ] && invalid_time && continue
		echo "$MINUTE $HOUR	* * *	root	/opt/openslx/scripts/idleaction-scheduled_action reboot" >> "$CRONFILE"
	done
	touch "/etc/cron.d" # Aufs bug where it won't update dir mtime when creating the file within
fi