Skip to content

Commit

Permalink
Merge branch '0.1.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
predatorray committed Jun 30, 2020
2 parents c4d38ae + fae4ccf commit 7016633
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 39 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ kubectl-tmux_exec --help

Flag | Usage
--- | ---
`-V`<br>`--version` | Print the version information
`-l`<br>`--selector` | Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)<br>You must either use `--selector` or `--file` option.
`-f`<br>`--file` | Read pod names line-by-line from a file.<br>You must either use `--selector` or `--file` option.
`-c`<br>`--container` | Container name. If omitted, the first container in the pod will be chosen
Expand All @@ -87,7 +88,7 @@ Flag | Usage
`-d`<br>`--detach` | Make the Tmux session detached
`--remain-on-exit` | Remain Tmux window on exit
`--select-layout` | One of the five Tmux preset layouts: even-horizontal, even-vertical, main-horizontal, main-vertical, or tiled.
`-V`<br>`--version` | Print the version information
`--session-mode` | Where tmux is opened: auto, new-session, current-session

The usage of these options is also available by `--help`.

Expand Down
44 changes: 37 additions & 7 deletions bin/kubectl-tmux_exec
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ set -euf -o pipefail
# Stack Overflow: https://stackoverflow.com/a/246128/1122665
SOURCE="${BASH_SOURCE[0]}"
while [[ -h "$SOURCE" ]]; do
PROG_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$PROG_DIR/$SOURCE"
PROG_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$PROG_DIR/$SOURCE"
done
PROG_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"

Expand Down Expand Up @@ -63,6 +63,12 @@ declare -ra TMUX_LAYOUTS=(
'tiled'
)

declare -ra SESSION_MODES=(
'auto'
'new-session'
'current-session'
)

function usage() {
cat << EOF
Execute a command in all containers that match the label selector using Tmux.
Expand All @@ -87,6 +93,10 @@ Options:
-l, --selector: Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
-f, --file: Read pod names line-by-line from a file
-d, --detach=false: Make the Tmux session detached
--session-mode=auto: Where tmux is opened:
new-session (always in a new session no matter whether there is an existing or not)
current-session (re-use the current session)
auto ('current-session' if there is an existing one, otherwise 'new-session')
--remain-on-exit=false: Remain Tmux window on exit
--select-layout=tiled: One of the five Tmux preset layouts: even-horizontal, even-vertical, main-horizontal,
main-vertical, or tiled.
Expand Down Expand Up @@ -157,7 +167,7 @@ function array_contains() {
function main() {
local opts
opts=$(ggetopt -o hVitdc:l:f:"$(printf '%s:' "${KUBECTL_SHORT_OPTS[@]}")" --long \
help,version,stdin,tty,detach,container:,selector:,remain-on-exit,select-layout:,file:,"$(printf '%s:,' "${KUBECTL_LONG_OPTS[@]}")","$(printf '%s,' "${KUBECTL_NOARG_LONG_OPTS[@]}")" -- "$@")
help,version,stdin,tty,detach,container:,selector:,remain-on-exit,select-layout:,session-mode:,file:,"$(printf '%s:,' "${KUBECTL_LONG_OPTS[@]}")","$(printf '%s,' "${KUBECTL_NOARG_LONG_OPTS[@]}")" -- "$@")
eval set -- $opts

local selector
Expand All @@ -167,6 +177,7 @@ function main() {
local tmux_layout='tiled'
local pod_list_file
local tmux_detach=0
local session_mode='auto'
while [[ $# -gt 0 ]]; do
local opt="$1"
case "${opt}" in
Expand Down Expand Up @@ -202,6 +213,10 @@ function main() {
shift
tmux_layout="$1"
;;
--session-mode)
shift
session_mode="$1"
;;
-f|--file)
shift
pod_list_file="$1"
Expand Down Expand Up @@ -250,7 +265,11 @@ function main() {
if [[ -z "${tmux_layout}" ]] || ! array_contains "${tmux_layout}" "${TMUX_LAYOUTS[@]}"; then
error_and_exit "Unknown layout: ${tmux_layout}"
fi


if [[ -z "${session_mode}" ]] || ! array_contains "${session_mode}" "${SESSION_MODES[@]}"; then
error_and_exit "Unknown session mode: ${session_mode}"
fi

local commands=("$@")

local kubectl_exec_opts='-i -t'
Expand Down Expand Up @@ -294,10 +313,21 @@ function main() {
for pod in "${pods[@]}"; do
local cmd="kubectl ${kubectl_opts[@]:-} exec ${kubectl_exec_opts} ${pod} -- ${exec_cmd_str}"
if [[ "${#tmux_commands[@]}" -eq 0 ]]; then
local open_command
if [[ "${session_mode}" == 'new-session' ]]; then
open_command='new-session'
elif [[ "${session_mode}" == 'current-session' ]]; then
open_command='new-window'
elif [[ -z "${TMUX:-}" ]]; then
open_command='new-session'
else
open_command='new-window'
fi

if [[ "${tmux_detach}" -eq 0 ]]; then
tmux_commands+=('new-session' "${cmd}" ';')
tmux_commands+=("${open_command}" "${cmd}" ';')
else
tmux_commands+=('new-session' '-d' "${cmd}" ';')
tmux_commands+=("${open_command}" '-d' "${cmd}" ';')
fi
else
tmux_commands+=('split-window' "${cmd}" ';')
Expand Down
33 changes: 2 additions & 31 deletions test/exec-one-pod.bats
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,12 @@

load test-helper

readonly POD_NAME='alpine'
readonly POD_APP_LABEL='alpine'

function setup() {
kubectl apply -f - << EOF
apiVersion: v1
kind: Pod
metadata:
name: ${POD_NAME}
labels:
app: ${POD_APP_LABEL}
spec:
containers:
- name: alpine
image: alpine
command:
- sleep
- infinite
EOF
local pod_status=''
local retries=30
while [[ "${pod_status}" != 'Running' ]]; do
sleep 1
pod_status="$(kubectl get pods "${POD_NAME}" -o custom-columns=':status.phase' --no-headers)"
echo "The pod status is ${pod_status}."
(( --retries )) || {
echo 'Timed out.'
exit 1
}
done
setup_one_pod
}

function teardown() {
kubectl delete pod "${POD_NAME}"
sleep 1
teardown_one_pod
}

@test "Exec one pod by label" {
Expand Down
25 changes: 25 additions & 0 deletions test/nested-tmux.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bats

load test-helper

function setup() {
setup_one_pod
}

function teardown() {
teardown_one_pod
tmux kill-server || true
}

@test "Reuse tmux session" {
tmux new-session -d bin/kubectl-tmux_exec -l app="${POD_APP_LABEL}" sh
[ "$(tmux ls | wc -l)" -eq 1 ]
}

@test "Nest tmux session" {
tmux new-session -d bin/kubectl-tmux_exec -l app="${POD_APP_LABEL}" --session-mode new-session sh
sleep 2
local tmux_exit_code=0
tmux ls || tmux_exit_code="$?"
[ "${tmux_exit_code}" -eq 1 ]
}
37 changes: 37 additions & 0 deletions test/test-helper.bash
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,41 @@ function wait_until_no_sessions() {
}
sleep 1
done
}

readonly POD_NAME='alpine'
readonly POD_APP_LABEL='alpine'

function setup_one_pod() {
kubectl apply -f - << EOF
apiVersion: v1
kind: Pod
metadata:
name: ${POD_NAME}
labels:
app: ${POD_APP_LABEL}
spec:
containers:
- name: alpine
image: alpine
command:
- sleep
- infinite
EOF
local pod_status=''
local retries=30
while [[ "${pod_status}" != 'Running' ]]; do
sleep 1
pod_status="$(kubectl get pods "${POD_NAME}" -o custom-columns=':status.phase' --no-headers)"
echo "The pod status is ${pod_status}."
(( --retries )) || {
echo 'Timed out.'
exit 1
}
done
}

function teardown_one_pod() {
kubectl delete pod "${POD_NAME}"
sleep 5
}

0 comments on commit 7016633

Please sign in to comment.