2 # vim:noet:sw=4:ts=4:ft=sh
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
18 [ -n "$__AUTOCOM_LIB_TMUX_INC__" ] && return || __AUTOCOM_LIB_TMUX_INC__=1
20 source "$(dirname "$BASH_SOURCE")/log.inc"
22 TMUX_SESSION_PREFIX="tmux-session-"
23 TMUX_TMPDIR="/tmp/tmp_console"
24 TMUX_SESSION="${TMUX_SESSION_PREFIX}deploy"
25 TMUX_LOGDIR="/var/log/ironic/console_logs/"
26 TMUX_RC_FILE="$(dirname "$BASH_SOURCE")/tmux.conf"
32 TMUX="" tmux -C -f "$TMUX_RC_FILE" \
33 attach-session -t "$TMUX_SESSION" \; \
34 select-window -t "$name" \; \
35 pipe-pane -o "exec cat>>\"$TMUX_LOGDIR/$name.log\"" \; \
37 || crit "Failed to start logging tmux window '%s'." "$name"
40 tmux_session_env_set()
42 local tmpdir="${1:-$TMUX_TMPDIR}"
47 TMUX_TMPDIR="$tmpdir" tmux -f "$TMUX_RC_FILE" set-environment ${session:+-t "$session"} "$name" "$value" \
48 || crit "Failed to set session '%s' environment variable '%s' to '%s'." "$session" "$name" "$value"
53 tmux_session_env_set "" "$TMUX_SESSION" "$@"
56 tmux_session_env_get()
58 local tmpdir="${1:-$TMUX_TMPDIR}"
63 output="$(TMUX_TMPDIR="$tmpdir" tmux 2>/dev/null -f "$TMUX_RC_FILE" show-environment ${session:+-t "$session"} "$name")" || :
65 echo "${output#$name=}"
70 tmux_session_env_get "" "$TMUX_SESSION" "$@"
78 debug "Starting new tmux session with window '%s'." "$name"
80 tmux -f "$TMUX_RC_FILE" new-session -s "$TMUX_SESSION" -d -n "$name" "$(printf "'%s' " "$@")" \
81 || crit "Failed to start a new tmux session with '%s' running in it." "$name"
83 tmux_log_start "$name"
88 local tmpdir="${1:-$TMUX_TMPDIR}"
90 debug "Listing tmux sessions found from the temporary directory '%s'." "$tmpdir"
92 TMUX_TMPDIR="$tmpdir" tmux ${TMUX_RC_FILE:+-f "$TMUX_RC_FILE"} list-sessions -F '#{session_name}' 2> /dev/null
95 tmux_session_is_running()
97 tmux -f "$TMUX_RC_FILE" has-session -t "$TMUX_SESSION" &>/dev/null
100 _tmux_cmd_title_is_new()
104 debug "Checking that a tmux window with name '%s' is not already running." "$name"
106 ! tmux_cmd_is_running "$name"
113 debug "Checking if a command with the name '%s' exists." "$name"
115 tmux_cmd_list | grep -q "^$name\$"
123 debug "Fetching pid of tmux command '%s'." "$name"
125 output="$(tmux -f "$TMUX_RC_FILE" list-windows -t "$TMUX_SESSION" -F '#{window_name}-pid=#{pane_pid}')" \
126 || crit "Failed to list tmux session's windows."
128 pid="$(grep -m1 "^${name}-pid=" <<< "$output")"
130 [ -n "$pid" ] || return 1
140 debug "Executing '%s' in a new tmux window." "$name"
142 ! tmux_cmd_exists "$name" \
143 || crit "A command with the name '%s' already exists." "$name"
145 tmux -f "$TMUX_RC_FILE" new-window -n "$name" -d "/bin/bash -c \"sleep .2 ; $(printf "'%s' " "$@") ; echo \\\"@@@@@ autocom:tmux_cmd:exit_value: \\\$? @@@@@\\\" ; sleep 1\" " \
146 || crit "Failed to execute command '%s' / '%s'." "$name" "$*"
148 tmux_log_start "$name"
155 debug "Listing tmux commands / windows in session '%s'." "$TMUX_SESSION"
157 tmux -f "$TMUX_RC_FILE" list-windows -F '#{window_name}' \
158 || crit "Failed to list tmux session's windows."
163 local foreground name new_prefix
165 [ "$1" != "--foreground" ] \
166 || { foreground="set-option exit-unattached on ;" ; shift ; }
171 debug "Attaching %sto window '%s' in session '%s' with prefix '%s'." \
172 "${foreground:+"with foreground option "}" "$name" "$SESSION_ID" "$new_prefix"
174 tmux_cmd_exists "$name" \
178 new-session -t "$TMUX_SESSION" -s "${TMUX_SESSION/$TMUX_SESSION_PREFIX/$new_prefix}" \; \
179 select-window ${name:+-t "$name"} \; \
181 set destroy-unattached on \; \
183 set-window-option remain-on-exit off \
184 || crit "Failed to attach to session %s's window '%s' with new prefix '%s'." "$SESSION_ID" "$name" "$new_prefix"
196 tmux_cmd_is_running "$1" \
197 || crit "Executing '%s' in a tmux window seems to have failed soon after starting." "$1"
204 debug "Killing '%s' from a tmux session." "$name"
206 tmux -f "$TMUX_RC_FILE" kill-window -t "$name"
213 tmux_kill_try "$name" \
214 || crit "Failed to kill '%s' from the tmux session." "$name"
217 tmux_get_window_count()
219 tmux_cmd_list | wc -l
222 tmux_cmd_is_running()
226 debug "Checking whether '%s' is running in tmux." "$name"
228 tmux -f "$TMUX_RC_FILE" list-windows -F "#{window_name}-dead=#{pane_dead}" \
229 | grep -q "^$name-dead=0\$"
234 debug "Counting dead tmux windows."
236 tmux -f "$TMUX_RC_FILE" list-windows -F "window-is-dead=#{pane_dead}" \
237 | grep -c "^window-is-dead=1\$"
240 tmux_cmd_exit_status()
244 debug "Checking whether '%s' has returned an error." "$name"
246 ! tmux_cmd_is_running "$name" \
247 || crit "Cannot check if command returned an error; command is still running."
249 e="$(tmux -f "$TMUX_RC_FILE" capture-pane -t "$name" -p | grep -o '@@@@@ autocom:tmux_cmd:exit_value: [0-9]\+ @@@@@' | grep -o '[0-9]\+')"
251 [[ "$e" =~ ^[0-9]+$ ]] \
252 || crit "Command %s's exit status '%s' doesn't look like a number." "$name" "$e"
259 export TMUX_TMPDIR="$1"
260 export TMUX_SESSION="${TMUX_SESSION_PREFIX}$2"
261 export TMUX_LOGDIR="$3"
262 export TMUX_RC_FILE="$4"
264 debug "Initializing tmux session '%s': tmpdir='%s', logdir='%s'" \
265 "$TMUX_SESSION" "$TMUX_TMPDIR" "$TMUX_LOGDIR"
267 mkdir -p "$TMUX_TMPDIR" \
268 || crit "Failed to create tmux's temporary directory '%s'." "$TMUX_TMPDIR"
270 mkdir -p "$TMUX_LOGDIR" \
271 || crit "Failed to create tmux's log file directory."
274 tmux_kill_other_sessions()
276 local session sessions
278 debug "Killing other tmux sessions than '%s' (that are still related to the same autocom session)." \
281 sessions="$(tmux_list_sessions)" \
282 || crit "Failed to get a list of sessions to kill."
284 sessions="$(echo "$sessions" | grep "${TMUX_SESSION/$TMUX_SESSION_PREFIX/}")" \
285 || crit "No tmux sessions found for the running autocom session."
287 sessions="$(echo "$sessions" | grep -v "$TMUX_SESSION")" \
288 || debug "No other tmux sessions in this autocom session."
290 for session in $sessions
292 tmux -f "$TMUX_RC_FILE" kill-session -t "$session" \
293 || crit "Failed to kill tmux session '%s'." "$session"
297 tmux_kill_other_windows()
302 && debug "Killing all other tmux windows than '%s'." "$name" \
303 || debug "Killing all other tmux windows."
305 tmux -f "$TMUX_RC_FILE" kill-window -a ${name:+-t "$name"}
308 tmux_session_uninit()
312 debug "Uninitializing tmux session (name='%s')." "$name"
314 tmux_kill_other_sessions
315 tmux_kill_other_windows "$name"
318 tmux_set_alternate_prefix()
322 TMUX_SESSION_PREFIX="${prefix}-"