remote scwrypts v5 refactor

This commit is contained in:
Wryn (yage) Wagner 2025-02-19 21:58:02 -07:00
parent f11c6dfad6
commit a3410d9b15
Signed by: wrynegade
SSH Key Fingerprint: SHA256:zBGO05Uz1oT7pnehoPelgUmYX632oFjt3MBH0MlEvrs
11 changed files with 191 additions and 181 deletions

View File

@ -2,5 +2,5 @@
##################################################################### #####################################################################
MAIN() { MAIN() {
EDIT "$REMOTE_CONNECTIONS_FILE" utils.io.edit "$REMOTE_CONNECTIONS_FILE"
} }

View File

@ -30,7 +30,7 @@ USAGE__description="
MAIN() { MAIN() {
[ $REMOTE__TARGET ] \ [ $REMOTE__TARGET ] \
|| ERROR 'missing REMOTE__TARGET context; this must be run through scwrypts' \ || echo.error 'missing REMOTE__TARGET context; this must be run through scwrypts' \
|| return 1 || return 1
local CONNECTION_TYPE=ssh local CONNECTION_TYPE=ssh
@ -45,38 +45,38 @@ MAIN() {
do do
local _S=1 local _S=1
case $1 in case $1 in
-t | --type ) ((_S+=1)); CONNECTION_TYPE=$2 ;; ( -t | --type ) ((_S+=1)); CONNECTION_TYPE=$2 ;;
-c | --command ) ((_S+=1)); REMOTE_COMMAND=$2 ;; ( -c | --command ) ((_S+=1)); REMOTE_COMMAND=$2 ;;
-s | --shell ) ((_S+=1)); LOGIN_SHELL=$2 ;; ( -s | --shell ) ((_S+=1)); LOGIN_SHELL=$2 ;;
--no-rc ) LOAD_RC=false ;; ( --no-rc ) LOAD_RC=false ;;
--no-tty ) USE_TTY=false ;; ( --no-tty ) USE_TTY=false ;;
--use-bastion ) ( --use-bastion )
((_S+=1)) ((_S+=1))
USE_BASTION=$2 USE_BASTION=$2
case $USE_BASTION in case $USE_BASTION in
true | false ) ;; ( true | false ) ;;
* ) ERROR "invalid setting for '--use-bastion' (must be 'true' or 'false')" ;; ( * ) echo.error "invalid setting for '--use-bastion' (must be 'true' or 'false')" ;;
esac esac
;; ;;
--force-local-login ) FORCE_LOCAL_LOGIN=true ;; ( --force-local-login ) FORCE_LOCAL_LOGIN=true ;;
* ) ERROR "unknown argument '$1'" ;; * ) echo.error "unknown argument '$1'" ;;
esac esac
[[ $_S -le $# ]] \ [[ $_S -le $# ]] \
&& shift $_S \ && shift $_S \
|| ERROR "missing argument for '$1'" \ || echo.error "missing argument for '$1'" \
|| shift $# || shift $#
done done
CHECK_ERRORS utils.check-errors --fail
########################################## ##########################################
GET_SSH_ARGS() { GET_SSH_ARGS() {
REMOTE__GET_SSH_ARGS \ remote.config.get-ssh-args \
--type $CONNECTION_TYPE \ --type $CONNECTION_TYPE \
--use-tty $USE_TTY \ --use-tty $USE_TTY \
$REMOTE_NAME \ $REMOTE_NAME \
@ -89,14 +89,14 @@ MAIN() {
########################################## ##########################################
local CONNECTION_STRING=$(REMOTE__GET_CONNECTION_STRING $REMOTE_NAME) local CONNECTION_STRING=$(remote.config.get-connection-string $REMOTE_NAME)
[ $CONNECTION_STRING ] \ [ $CONNECTION_STRING ] \
|| FAIL 1 'unable to determine connection string' || FAIL 1 'unable to determine connection string'
########################################## ##########################################
LOGIN_SHELL=$(\ LOGIN_SHELL=$(\
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
"$LOGIN_SHELL" \ "$LOGIN_SHELL" \
".$REMOTE_NAME.shell" \ ".$REMOTE_NAME.shell" \
".default.shell" \ ".default.shell" \
@ -104,7 +104,7 @@ MAIN() {
) )
REMOTE_COMMAND=$(\ REMOTE_COMMAND=$(\
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
"$REMOTE_COMMAND" \ "$REMOTE_COMMAND" \
".sessions.$REMOTE_NAME.$CONNECTION_TYPE.command" \ ".sessions.$REMOTE_NAME.$CONNECTION_TYPE.command" \
".sessions.$REMOTE_NAME.command" \ ".sessions.$REMOTE_NAME.command" \
@ -114,9 +114,9 @@ MAIN() {
[ $REMOTE_COMMAND ] || { [ $REMOTE_COMMAND ] || {
case $CONNECTION_TYPE in case $CONNECTION_TYPE in
tmux ) ( tmux )
local TMUX_SESSION_NAME=$( local TMUX_SESSION_NAME=$(
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
".sessions.$REMOTE_NAME.tmux.session" \ ".sessions.$REMOTE_NAME.tmux.session" \
".default.tmux.session" \ ".default.tmux.session" \
"wryn" \ "wryn" \
@ -135,7 +135,7 @@ MAIN() {
[ $USE_BASTION ] || { [ $USE_BASTION ] || {
USE_BASTION=$(\ USE_BASTION=$(\
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
".sessions.$REMOTE_NAME.bastion.preferred" \ ".sessions.$REMOTE_NAME.bastion.preferred" \
'false' \ 'false' \
; ;
@ -145,15 +145,15 @@ MAIN() {
local BASTION_HOST local BASTION_HOST
[[ $USE_BASTION =~ true ]] && { [[ $USE_BASTION =~ true ]] && {
BASTION_HOST=$(\ BASTION_HOST=$(\
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
".sessions.$REMOTE_NAME.bastion.session" \ ".sessions.$REMOTE_NAME.bastion.session" \
) )
} }
[ $BASTION_HOST ] && { [ $BASTION_HOST ] && {
DEBUG "REMOTE_COMMAND : $REMOTE_COMMAND" echo.debug "REMOTE_COMMAND : $REMOTE_COMMAND"
PASSTHROUGH_COMMAND="$(GET_PASSTHROUGH_PREFIX) connect $REMOTE_NAME --" PASSTHROUGH_COMMAND="$(remote.bastion.get-passthrough-prefix) connect $REMOTE_NAME --"
[ "$REMOTE_COMMAND" ] && PASSTHROUGH_COMMAND+=" -c $(printf "%q " "$REMOTE_COMMAND")" [ "$REMOTE_COMMAND" ] && PASSTHROUGH_COMMAND+=" -c $(printf "%q " "$REMOTE_COMMAND")"
BASTION_TARGET=$REMOTE_NAME REMOTE__TARGET=$BASTION_HOST MAIN --command "$PASSTHROUGH_COMMAND" BASTION_TARGET=$REMOTE_NAME REMOTE__TARGET=$BASTION_HOST MAIN --command "$PASSTHROUGH_COMMAND"
@ -174,7 +174,7 @@ MAIN() {
[ $BASTION_TARGET ] && CONNECTION_TYPE=bastion [ $BASTION_TARGET ] && CONNECTION_TYPE=bastion
DEBUG " echo.debug "
attempting execution: attempting execution:
netpath : $(hostnamectl --static) -> $([ $BASTION_TARGET ] && echo "$BASTION_TARGET -> ")$REMOTE_NAME netpath : $(hostnamectl --static) -> $([ $BASTION_TARGET ] && echo "$BASTION_TARGET -> ")$REMOTE_NAME
type : $CONNECTION_TYPE type : $CONNECTION_TYPE
@ -189,6 +189,6 @@ MAIN() {
;; ;;
esac esac
DEBUG "ssh ${SSH_ARGS[@]} $CONNECTION_STRING \"$REMOTE_COMMAND\"" echo.debug "ssh ${SSH_ARGS[@]} $CONNECTION_STRING \"$REMOTE_COMMAND\""
ssh ${SSH_ARGS[@]} $CONNECTION_STRING "$REMOTE_COMMAND" ssh ${SSH_ARGS[@]} $CONNECTION_STRING "$REMOTE_COMMAND"
} }

View File

@ -1,3 +1,3 @@
GET_PASSTHROUGH_PREFIX() { ${scwryptsmodule}.get-passthrough-prefix() {
echo "source ~/.zshrc &>/dev/null; SUBSCWRYPT=$((SUBSCWRYPT+1)) SCWRYPTS_LOG_LEVEL=$SCWRYPTS_LOG_LEVEL scwrypts" echo "source ~/.zshrc &>/dev/null; SUBSCWRYPT=$((SUBSCWRYPT+1)) SCWRYPTS_LOG_LEVEL=$SCWRYPTS_LOG_LEVEL scwrypts"
} }

View File

@ -4,19 +4,19 @@ DEPENDENCIES+=(yq)
##################################################################### #####################################################################
REMOTE__GET_CONNECTION_STRING() { ${scwryptsmodule}.get-connection-string() {
local REMOTE_NAME="$1" local REMOTE_NAME="$1"
[ $(REMOTE__QUERY_CONNECTION .sessions.$REMOTE_NAME.host) ] \ [ $(remote.config.query-connection .sessions.$REMOTE_NAME.host) ] \
|| ERROR "no such connection $REMOTE_NAME exists" \ || echo.error "no such connection $REMOTE_NAME exists" \
|| return 1 || return 1
local CONNECTION_HOST=$(REMOTE__QUERY_CONNECTION .sessions.$REMOTE_NAME.host) local CONNECTION_HOST=$(remote.config.query-connection .sessions.$REMOTE_NAME.host)
[ $CONNECTION_HOST ] \ [ $CONNECTION_HOST ] \
|| ERROR "connection $REMOTE_NAME is misconfigured; missing 'host' field" \ || echo.error "connection $REMOTE_NAME is misconfigured; missing 'host' field" \
|| return 1 || return 1
local CONNECTION_USER=$(REMOTE__QUERY_CONNECTION .sessions.$REMOTE_NAME.user) local CONNECTION_USER=$(remote.config.query-connection .sessions.$REMOTE_NAME.user)
[ $CONNECTION_USER ] || CONNECTION_USER=$(REMOTE__QUERY_CONNECTION .default.user) [ $CONNECTION_USER ] || CONNECTION_USER=$(remote.config.query-connection .default.user)
[ $CONNECTION_USER ] \ [ $CONNECTION_USER ] \
&& CONNECTION_STRING="${CONNECTION_USER}@${CONNECTION_HOST}" \ && CONNECTION_STRING="${CONNECTION_USER}@${CONNECTION_HOST}" \
@ -26,7 +26,7 @@ REMOTE__GET_CONNECTION_STRING() {
echo $CONNECTION_STRING echo $CONNECTION_STRING
} }
REMOTE__GET_SSH_ARGS() { ${scwryptsmodule}.get-ssh-args() {
local REMOTE_NAME local REMOTE_NAME
local TYPE=ssh local TYPE=ssh
local USE_TTY=true local USE_TTY=true
@ -34,13 +34,13 @@ REMOTE__GET_SSH_ARGS() {
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
case $1 in case $1 in
-t | --type ) TYPE=$2; shift 1 ;; ( -t | --type ) TYPE=$2; shift 1 ;;
--use-tty ) USE_TTY=$2; shift 1 ;; ( --use-tty ) USE_TTY=$2; shift 1 ;;
--no-tty ) USE_TTY=false ;; ( --no-tty ) USE_TTY=false ;;
* ) ( * )
[ $REMOTE_NAME ] && { ERROR "too many args :c"; return 1; } [ $REMOTE_NAME ] && { echo.error "too many args :c"; return 1; }
REMOTE_NAME=$1 REMOTE_NAME=$1
;; ;;
esac esac
@ -53,25 +53,25 @@ REMOTE__GET_SSH_ARGS() {
return 0 return 0
} }
local PORT=$(REMOTE__QUERY_CONNECTION .sessions.$REMOTE_NAME.port) local PORT=$(remote.config.query-connection .sessions.$REMOTE_NAME.port)
[ $PORT ] && { [ $PORT ] && {
case $TYPE in case $TYPE in
ssh | xserver | tmux ) ARGS+=(-p $PORT) ;; ( ssh | xserver | tmux ) ARGS+=(-p $PORT) ;;
scp ) ARGS+=(-P $PORT) ;; # not really in use, just a sample ( scp ) ARGS+=(-P $PORT) ;; # not really in use, just a sample
* ) ( * )
WARNING " WARNING "
port is specified, but I'm not sure whether to use '-p' or '-P' port is specified, but I'm not sure whether to use '-p' or '-P'
if this command fails, try adding your --type to the appropriate if this command fails, try adding your --type to the appropriate
list in '$SCWRYPTS_ROOT__remote/lib/config.module.zsh' list in '$(scwrypts.config.group remote root)/lib/config.module.zsh'
" "
ARGS+=(-p $PORT) ARGS+=(-p $PORT)
;; ;;
esac esac
} }
ARGS+=($(REMOTE__QUERY_CONNECTION .session.$REMOTE_NAME.$TYPE.args)) ARGS+=($(remote.config.query-connection .session.$REMOTE_NAME.$TYPE.args))
[[ $USE_TTY =~ true ]] && ARGS+=(-t) [[ $USE_TTY =~ true ]] && ARGS+=(-t)
@ -80,17 +80,17 @@ REMOTE__GET_SSH_ARGS() {
##################################################################### #####################################################################
REMOTE__QUERY_CONNECTION() { ${scwryptsmodule}.query-connection() {
YQ -oy -r $@ "$REMOTE_CONNECTIONS_FILE" \ utils.yq -oy -r $@ "$REMOTE_CONNECTIONS_FILE" \
| grep -v ^null$ | grep -v ^null$
} }
REMOTE__QUERY_CONNECTION_WITH_FALLBACK() { ${scwryptsmodule}.query-connection-with-fallback() {
while [[ $# -gt 0 ]] && [ ! $QUERY_RESULT ] while [[ $# -gt 0 ]] && [ ! $QUERY_RESULT ]
do do
case $1 in case $1 in
.* ) QUERY_RESULT=$(REMOTE__QUERY_CONNECTION $1) ;; ( .* ) QUERY_RESULT=$(remote.config.query-connection $1) ;;
* ) QUERY_RESULT="$1" ;; # allows raw default value ( * ) QUERY_RESULT="$1" ;; # allows raw default value
esac esac
shift 1 shift 1
done done

View File

@ -0,0 +1,13 @@
#####################################################################
OMNI_SOCKET="omni.socket"
OMNI_LOGDIR="${XDG_STATE_HOME:-${HOME}/.local/state}/wryn/omni"
mkdir -p "${OMNI_LOGDIR}"
${scwryptsmodule}.tmux() {
tmux -L ${OMNI_SOCKET} $@
}
#####################################################################

View File

View File

@ -1,14 +1,12 @@
SCWRYPTS_GROUPS+=(remote) readonly ${scwryptsgroup}__type=zsh
[ $DOTWRYN ] || source "$HOME/.config/wryn/env.zsh" readonly ${scwryptsgroup}__color=$(utils.colors.blue)
export SCWRYPTS_TYPE__remote=zsh #####################################################################
export SCWRYPTS_ROOT__remote="$DOTWRYN/scwrypts/remote"
export SCWRYPTS_COLOR__remote='\033[0;34m'
DEPENDENCIES+=(yq) DEPENDENCIES+=(yq)
REMOTE_CONNECTIONS_FILE="$HOME/.config/wryn/remote-connections.toml" REMOTE_CONNECTIONS_FILE="${XDG_CONFIG_HOME:-${HOME}/.config}/wryn/remote-connections.toml"
SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__remote() { ${scwryptsgroup}.list-available() {
[ -f "$REMOTE_CONNECTIONS_FILE" ] || { [ -f "$REMOTE_CONNECTIONS_FILE" ] || {
mkdir -p "$(dirname -- "$REMOTE_CONNECTIONS_FILE")" &>/dev/null mkdir -p "$(dirname -- "$REMOTE_CONNECTIONS_FILE")" &>/dev/null
echo " echo "
@ -27,20 +25,25 @@ SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__remote() {
echo "tmux/omni" echo "tmux/omni"
echo "configure" echo "configure"
echo "test" echo "test"
} | sed "s|^|$SCWRYPTS_TYPE__remote/|" } | sed "s|^|zsh/|"
} }
SCWRYPTS__GET_RUNSTRING__remote__zsh() { ${scwryptsgroup}.zsh.get-runstring() {
local SCWRYPT_FILENAME local SCWRYPT_FILENAME
case $SCWRYPT_NAME in case $SCWRYPT_NAME in
connect/* ) connect/* )
SCWRYPT_FILENAME="$SCWRYPTS_ROOT__remote/connect" SCWRYPT_FILENAME="$(scwrypts.config.group remote root)/connect"
echo "export REMOTE__TARGET=$(echo $SCWRYPT_NAME | sed 's|^.*connect/||')" echo "export REMOTE__TARGET=$(echo $SCWRYPT_NAME | sed 's|^.*connect/||')"
;; ;;
* ) * )
SCWRYPT_FILENAME="$SCWRYPTS_ROOT__remote/$SCWRYPT_NAME" SCWRYPT_FILENAME="$(scwrypts.config.group remote root)/$SCWRYPT_NAME"
;; ;;
esac esac
SCWRYPTS__GET_RUNSTRING__zsh__generic "$SCWRYPT_FILENAME" scwrypts.get-runstring.zsh.generic
}
remote.config.yq() {
utils.yq -oy -r $@ "${REMOTE_CONNECTIONS_FILE}" \
| grep -v ^null$
} }

View File

@ -34,7 +34,7 @@ MAIN() {
-n | --name ) -n | --name )
((_S+=1)) ((_S+=1))
REMOTE_NAME=$2 REMOTE_NAME=$2
CONNECTION_STRING=$(REMOTE__GET_CONNECTION_STRING $REMOTE_NAME) CONNECTION_STRING=$(remote.config.get-connection-string $REMOTE_NAME)
;; ;;
-s | --connection_string ) -s | --connection_string )
((_S+=1)) ((_S+=1))
@ -44,7 +44,7 @@ MAIN() {
((_S+=1)) ((_S+=1))
TIMEOUT_SECONDS=$2 TIMEOUT_SECONDS=$2
[[ $TIMEOUT_SECONDS -gt 0 ]] \ [[ $TIMEOUT_SECONDS -gt 0 ]] \
|| ERROR "invalid timeout seconds '$TIMEOUT_SECONDS'" || echo.error "invalid timeout seconds '$TIMEOUT_SECONDS'"
;; ;;
-c | --command ) -c | --command )
((_S+=1)) ((_S+=1))
@ -55,31 +55,31 @@ MAIN() {
USE_BASTION=$2 USE_BASTION=$2
case $USE_BASTION in case $USE_BASTION in
true | false ) ;; true | false ) ;;
* ) ERROR "invalid setting for '--use-bastion' (must be 'true' or 'false')" ;; * ) echo.error "invalid setting for '--use-bastion' (must be 'true' or 'false')" ;;
esac esac
;; ;;
* ) ERROR "unrecognized argument '$1'" ;; * ) echo.error "unrecognized argument '$1'" ;;
esac esac
[[ $_S -le $# ]] \ [[ $_S -le $# ]] \
&& shift $_S \ && shift $_S \
|| ERROR "missing argument for '$1'" \ || echo.error "missing argument for '$1'" \
|| shift $# || shift $#
done done
[ $CONNECTION_STRING ] \ [ $CONNECTION_STRING ] \
|| ERROR "unable to determine connection string" || echo.error "unable to determine connection string"
[ $USE_BASTION ] || { [ $USE_BASTION ] || {
USE_BASTION=$(\ USE_BASTION=$(\
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
".sessions.$REMOTE_NAME.bastion.preferred" \ ".sessions.$REMOTE_NAME.bastion.preferred" \
'false' \ 'false' \
; ;
) )
} }
CHECK_ERRORS utils.check-errors --fail
########################################## ##########################################
@ -87,14 +87,14 @@ MAIN() {
local BASTION_HOST local BASTION_HOST
[[ $USE_BASTION =~ true ]] && { [[ $USE_BASTION =~ true ]] && {
BASTION_HOST=$(\ BASTION_HOST=$(\
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \ remote.config.query-connection-with-fallback \
".sessions.$REMOTE_NAME.bastion.session" \ ".sessions.$REMOTE_NAME.bastion.session" \
) )
} }
[[ $USE_BASTION =~ true ]] && { [[ $USE_BASTION =~ true ]] && {
[ $BASTION_HOST ] \ [ $BASTION_HOST ] \
|| ERROR "cannot connect to $REMOTE_NAME; no configured bastion host" \ || echo.error "cannot connect to $REMOTE_NAME; no configured bastion host" \
|| return 1 || return 1
} }
@ -104,29 +104,29 @@ MAIN() {
;; ;;
* ) * )
[[ $USE_BASTION =~ true ]] && { [[ $USE_BASTION =~ true ]] && {
DEBUG "MAIN -n $BASTION_HOST -c \"$(GET_PASSTHROUGH_PREFIX) remote test -- -n $REMOTE_NAME -c \"$COMMAND\"\"" echo.debug "MAIN -n $BASTION_HOST -c \"$(remote.bastion.get-passthrough-prefix) remote test -- -n $REMOTE_NAME -c \"$COMMAND\"\""
BASTION_TARGET="$REMOTE_NAME" MAIN -n $BASTION_HOST -c "$(GET_PASSTHROUGH_PREFIX) remote test -- -n $REMOTE_NAME -c \"$COMMAND\"" BASTION_TARGET="$REMOTE_NAME" MAIN -n $BASTION_HOST -c "$(remote.bastion.get-passthrough-prefix) remote test -- -n $REMOTE_NAME -c \"$COMMAND\""
return $? return $?
} }
CONNECTION_TEST() { CONNECTION_TEST() {
[ $REMOTE_NAME ] && { [ $REMOTE_NAME ] && {
[[ $(REMOTE__QUERY_CONNECTION .sessions.$REMOTE_NAME.enabled) =~ false ]] && { [[ $(remote.config.query-connection .sessions.$REMOTE_NAME.enabled) =~ false ]] && {
return 1 return 1
} }
} }
local REMOTE_ARGS=() local REMOTE_ARGS=()
REMOTE_ARGS+=($(REMOTE__GET_SSH_ARGS --type ssh $REMOTE_NAME)) REMOTE_ARGS+=($(remote.config.get-ssh-args --type ssh $REMOTE_NAME))
REMOTE_ARGS+=(-o BatchMode=yes) REMOTE_ARGS+=(-o BatchMode=yes)
DEBUG "attempting\ntimeout $TIMEOUT_SECONDS ssh $REMOTE_ARGS $CONNECTION_STRING "'\'"\"$COMMAND"'\'"\"" >&2 echo.debug "attempting\ntimeout $TIMEOUT_SECONDS ssh $REMOTE_ARGS $CONNECTION_STRING "'\'"\"$COMMAND"'\'"\"" >&2
timeout --foreground $TIMEOUT_SECONDS ssh ${REMOTE_ARGS[@]} "$CONNECTION_STRING" "$COMMAND" >&2 timeout --foreground $TIMEOUT_SECONDS ssh ${REMOTE_ARGS[@]} "$CONNECTION_STRING" "$COMMAND" >&2
} }
;; ;;
esac esac
[ $REMOTE_NAME ] || REMOTE_NAME=explicit [ $REMOTE_NAME ] || REMOTE_NAME=explicit
STATUS "testing connection $CONNECTION_STRING ($REMOTE_NAME$([ $BASTION_TARGET ] && echo " -> $BASTION_TARGET"))" \ echo.status "testing connection $CONNECTION_STRING ($REMOTE_NAME$([ $BASTION_TARGET ] && echo " -> $BASTION_TARGET"))" \
&& CONNECTION_TEST \ && CONNECTION_TEST \
&& SUCCESS "successfully connected to '$CONNECTION_STRING' ($REMOTE_NAME)" \ && echo.success "successfully connected to '$CONNECTION_STRING' ($REMOTE_NAME)" \
|| ERROR "connection to '$CONNECTION_STRING ($REMOTE_NAME)' failed" \ || echo.error "connection to '$CONNECTION_STRING ($REMOTE_NAME)' failed" \
} }

View File

@ -1,66 +1,56 @@
#!/usr/bin/env zsh #!/usr/bin/env zsh
# #
# works as a standalone zsh script # must work as a standalone zsh script
# #
eval "$(scwrypts --config)" \
&& use omni --group remote \
&& utils.check-environment \
|| { echo 'scwrypts config error; aborting' >&2; sleep 5; return 1; }
##################################################################### #####################################################################
CONNECTIONS_FILE="$HOME/.config/wryn/remote-connections.toml" OMNI_LOGFILE="${OMNI_LOGDIR}/omni.current.txt"
OMNI_LOGDIR="$HOME/.local/share/scwrypts/dotwryn" [ -f "${OMNI_LOGFILE}" ] && {
OMNI_LOGFILE="$HOME/.local/share/scwrypts/dotwryn/omni.current.txt"
[ ! -d "$OMNI_LOGDIR" ] && mkdir -p "$OMNI_LOGDIR"
[ -f "$OMNI_LOGFILE" ] && {
for x in {1..99} for x in {1..99}
do do
[ ! -f "$OMNI_LOGDIR/omni.$x.txt" ] && break [ ! -f "${OMNI_LOGDIR}/omni.${x}.txt" ] && {
mv "${OMNI_LOGFILE}" "${OMNI_LOGDIR}/omni.${x}.txt"
break
}
done done
[ ! -f "$OMNI_LOGDIR/omni.$x.txt" ] && mv "$OMNI_LOGFILE" "$OMNI_LOGDIR/omni.$x.txt"
} }
echo "OMNI MANAGER START : $(date)" > "$OMNI_LOGFILE" echo "OMNI MANAGER START : $(date)" > "${OMNI_LOGFILE}"
OMNI_SOCKET="omni.socket" #####################################################################
OMNI_TMUX() { tmux -L $OMNI_SOCKET $@; }
CONFIG_QUERY() { yq -oy -r $@ "$CONNECTIONS_FILE" | grep -v ^null$; } get-unique-window-id() {
CONNECTED() {
[ $WINDOW_ID ] \
&& echo "\\033[1;32mconnected (window $WINDOW_ID)\\033[0m" >&2 \
|| echo "\\033[1;32mconnected\\033[0m" >&2 \
}
DISCONNECTED() { echo "\\033[1;31mdisconnected\\033[0m" >&2; }
GET_UNIQUE_WINDOW_ID() {
local MODE=use-default local MODE=use-default
local WINDOW_ID="$(eval "echo \$WINDOW_ID__$REMOTE_NAME")" local WINDOW_ID="$(eval echo "\$WINDOW_ID__${REMOTE_NAME}")"
: \ : \
&& [[ $(eval "echo \$CAN_CONNECT__$REMOTE_NAME") =~ true ]] \ && [[ $(eval echo "\$CAN_CONNECT__${REMOTE_NAME}") =~ true ]] \
&& [ $WINDOW_ID ] \ && [ ${WINDOW_ID} ] \
&& echo $WINDOW_ID \ && echo ${WINDOW_ID} \
&& return 0 \ && return 0 \
; ;
unset WINDOW_ID__$REMOTE_NAME &>>"$OMNI_LOGFILE" unset WINDOW_ID__${REMOTE_NAME} &>>"${OMNI_LOGFILE}"
WINDOW_ID="$1" WINDOW_ID="$1"
WINDOW_ID=$(CONFIG_QUERY .sessions.$REMOTE_NAME.id) WINDOW_ID=$(remote.config.yq .sessions.${REMOTE_NAME}.id)
[ $WINDOW_ID ] && MODE=specify-preferred [ ${WINDOW_ID} ] && MODE=specify-preferred
WINDOW_ID_IS_TAKEN() { WINDOW_ID_IS_TAKEN() {
: \ : \
&& [[ $(OMNI_TMUX list-windows -t=omni | grep "^$WINDOW_ID:" | wc -l) -gt 0 ]] \ && [[ $(remote.omni.tmux list-windows -t=omni | grep "^${WINDOW_ID}:" | wc -l) -gt 0 ]] \
&& [[ ! $(OMNI_TMUX list-windows -t=omni | grep "^$WINDOW_ID:" | awk '{print $2;}' =~ ^$REMOTE_NAME$) ]] \ && [[ ! $(remote.omni.tmux list-windows -t=omni | grep "^${WINDOW_ID}:" | awk '{print $2;}' =~ ^${REMOTE_NAME}$) ]] \
; ;
} }
local FALLBACK_STARTING_POINT local FALLBACK_STARTING_POINT
case $MODE in case ${MODE} in
use-default ) FALLBACK_STARTING_POINT=42 ;; use-default ) FALLBACK_STARTING_POINT=42 ;;
specify-preferred ) FALLBACK_STARTING_POINT=69 ;; specify-preferred ) FALLBACK_STARTING_POINT=69 ;;
esac esac
@ -68,78 +58,78 @@ GET_UNIQUE_WINDOW_ID() {
local I=0 local I=0
while WINDOW_ID_IS_TAKEN while WINDOW_ID_IS_TAKEN
do do
echo "$REMOTE_NAME tried to acquire window id $WINDOW_ID, but it is already in-use (trying $(($FALLBACK_STARTING_POINT-$I)))" >&2 echo "${REMOTE_NAME} tried to acquire window id ${WINDOW_ID}, but it is already in-use (trying $((${FALLBACK_STARTING_POINT}-${I})))" >&2
WINDOW_ID=$(($FALLBACK_STARTING_POINT-$I)) WINDOW_ID=$((${FALLBACK_STARTING_POINT}-${I}))
((I+=1)) ((I+=1))
[[ $I -gt 10 ]] && WINDOW_ID= && break [[ ${I} -gt 10 ]] && WINDOW_ID= && break
done done
echo $WINDOW_ID echo ${WINDOW_ID}
} }
##################################################################### #####################################################################
sleep 1 remote.omni.tmux new-window -t=omni-manager -dn 'harakiri' "
OMNI_TMUX new-window -t=omni-manager -dn 'harakiri' " echo 'waiting for omni-manager to close'
while true while true
do do
tmux -L $OMNI_SOCKET list-sessions | grep -v omni-manager | grep -qi omni || {
tmux -L $OMNI_SOCKET kill-session -t omni-manager
}
sleep 5 sleep 5
tmux -L ${OMNI_SOCKET} list-sessions 2>/dev/null | grep -v omni-manager | grep -qi omni || {
echo 'no active sessions detected; killing omni-manager session'
tmux -L ${OMNI_SOCKET} kill-session -t omni-manager
}
done done
" "
while true while true
do do
clear #clear
for REMOTE_NAME in $(CONFIG_QUERY '.sessions | keys | .[]') for REMOTE_NAME in $(remote.config.yq '.sessions | keys | .[]')
do do
WINDOW_ID=$(GET_UNIQUE_WINDOW_ID) WINDOW_ID=$(get-unique-window-id)
export WINDOW_ID__$REMOTE_NAME=$WINDOW_ID export WINDOW_ID__${REMOTE_NAME}=${WINDOW_ID}
OMNI_TMUX list-windows -t=omni | awk '{print $2;}' | grep -q $REMOTE_NAME \ remote.omni.tmux list-windows -t=omni | awk '{print $2;}' | grep -q ${REMOTE_NAME} \
&& continue && continue
printf "testing connection $REMOTE_NAME..." printf "testing connection ${REMOTE_NAME}..."
echo "testing connection $REMOTE_NAME..." &>>"$OMNI_LOGFILE" echo "testing connection ${REMOTE_NAME}..." &>>"${OMNI_LOGFILE}"
scwrypts --name test --group remote --type zsh \ scwrypts --name test --group remote --type zsh \
-- \ -- \
--name $REMOTE_NAME \ --name ${REMOTE_NAME} \
--command 'command -v tmux' \ --command 'command -v tmux' \
&>>"$OMNI_LOGFILE" \ &>>"${OMNI_LOGFILE}" \
&& export CAN_CONNECT__$REMOTE_NAME=true \ && export CAN_CONNECT__${REMOTE_NAME}=true \
|| export CAN_CONNECT__$REMOTE_NAME=false \ || export CAN_CONNECT__${REMOTE_NAME}=false \
; ;
[[ $(eval echo "\$CAN_CONNECT__$REMOTE_NAME") =~ true ]] \ [[ $(eval echo "\$CAN_CONNECT__${REMOTE_NAME}") =~ true ]] \
&& echo " \\033[1;32m✔\\033[0m" >&2 \ && utils.colors.print bright-green " ✔\n" >&2 \
|| { echo " \\033[1;31m✖\\033[0m" >&2; continue; } || { utils.colors.print bright-red " ✖\n" >&2; continue; }
OMNI_TMUX new-window \ remote.omni.tmux new-window \
-t=omni:$WINDOW_ID \ -t=omni:${WINDOW_ID} \
-dn $REMOTE_NAME " -dn ${REMOTE_NAME} "
source ~/.zshrc &>/dev/null source ~/.zshrc &>/dev/null
TMUX='' scwrypts -n connect/$REMOTE_NAME -- --type tmux TMUX='' scwrypts -n connect/${REMOTE_NAME} -- --type tmux
echo 'connection closed' echo 'connection closed'
sleep 2 sleep 2
" "
OMNI_TMUX list-window -t=omni | awk '{print $1;}' | grep -q '99:' && OMNI_TMUX kill-window -t omni:99 remote.omni.tmux list-window -t=omni | awk '{print $1;}' | grep -q '99:' && remote.omni.tmux kill-window -t omni:99
OMNI_TMUX list-windows -t=omni | awk '{print $2;}' | grep -q $REMOTE_NAME \ remote.omni.tmux list-windows -t=omni | awk '{print $2;}' | grep -q ${REMOTE_NAME} \
|| export CAN_CONNECT__$REMOTE_NAME=false || export CAN_CONNECT__${REMOTE_NAME}=false
done done
clear #clear
echo "connections:\n" echo "connections:\n"
local STATUS
{ {
for REMOTE_NAME in $(CONFIG_QUERY '.sessions | keys | .[]') for REMOTE_NAME in $(remote.config.yq '.sessions | keys | .[]')
do do
[[ $(eval "echo \$CAN_CONNECT__$REMOTE_NAME") =~ true ]] \ [[ $(eval echo "\$CAN_CONNECT__${REMOTE_NAME}") =~ true ]] \
&& echo "${REMOTE_NAME}^$(eval "echo \$WINDOW_ID__$REMOTE_NAME")^\\033[1;32mconnected\\033[0m" \ && echo "${REMOTE_NAME}^$(eval echo "\$WINDOW_ID__${REMOTE_NAME}")^$(utils.colors.print bright-green connected)" \
|| echo "${REMOTE_NAME}^-^\\033[1;31mdisconnected\\033[0m" \ || echo "${REMOTE_NAME}^-^$(utils.colors.print bright-red disconnected)" \
; ;
done done
} | column -ts '^' } | column -ts '^'

View File

@ -1,5 +1,10 @@
#!/bin/zsh #!/bin/zsh
#####################################################################
DEPENDENCIES+=(tmux scwrypts) DEPENDENCIES+=(tmux scwrypts)
use omni --group remote
##################################################################### #####################################################################
USAGE__description=" USAGE__description="
@ -12,7 +17,7 @@ USAGE__description="
Switch between connections by using 'M-s' followed by the session ID Switch between connections by using 'M-s' followed by the session ID
number (or use any other default default tmux navigation command). Full number (or use any other default default tmux navigation command). Full
configuration can be found here: configuration can be found here:
- $SCWRYPTS_ROOT__remote/omni/tmux.conf - $(scwrypts.config.group remote root)/omni/tmux.conf
Shut-down the omni-session by pressing 'M-Q' (Q not q! ALT + SHIFT + Q) Shut-down the omni-session by pressing 'M-Q' (Q not q! ALT + SHIFT + Q)
@ -30,7 +35,7 @@ USAGE__description="
##################################################################### #####################################################################
MAIN() { MAIN() {
[[ $TERM =~ tmux ]] && ERROR "\n Cannot run tmux-omni within a tmux session!\n " [[ $TERM =~ tmux ]] && echo.error "\n Cannot run tmux-omni within a tmux session!\n "
local BACKGROUND_LAUNCH=false local BACKGROUND_LAUNCH=false
@ -43,33 +48,34 @@ MAIN() {
esac esac
[[ $_S -le $# ]] \ [[ $_S -le $# ]] \
&& shift $_S \ && shift $_S \
|| ERROR "missing argument for '$1'" \ || echo.error "missing argument for '$1'" \
|| shift $# \ || shift $# \
; ;
done done
CHECK_ERRORS utils.check-errors --fail
local OMNI_SOCKET="omni.socket" local SCWRYPTS_ROOT_REMOTE="$(scwrypts.config.group remote root)"
OMNI_TMUX() { tmux -L $OMNI_SOCKET $@; }
OMNI_TMUX list-sessions 2>/dev/null | grep -v omni-manager | grep -qi omni || { remote.omni.tmux list-sessions 2>/dev/null | grep -v omni-manager | grep -qi omni || {
STATUS "initializing omni server" echo.status "initializing omni server"
OMNI_TMUX kill-session -t=omni-manager >/dev/null 2>&1 remote.omni.tmux kill-session -t=omni-manager >/dev/null 2>&1
OMNI_TMUX -f "$SCWRYPTS_ROOT__remote/tmux/tmux.conf" new -d -s omni \ echo.debug "${SCWRYPTS_ROOT_REMOTE}/tmux/tmux.conf"
"echo searching for first connection...; sleep 30" \; \ remote.omni.tmux -f "${SCWRYPTS_ROOT_REMOTE}/tmux/tmux.conf" new -d -s omni \
split-window "sleep 3; TMUX= tmux -L $OMNI_SOCKET a -t=omni-manager" \; \ "echo searching for first connection...; sleep 10" \; \
split-window "sleep 1; TMUX= tmux -L ${OMNI_SOCKET} a -t=omni-manager" \; \
move-window -t 99 \; move-window -t 99 \;
OMNI_TMUX new -d -s omni-manager "$SCWRYPTS_ROOT__remote/tmux/manager"
remote.omni.tmux new -d -s omni-manager "${SCWRYPTS_ROOT_REMOTE}/tmux/manager"
} }
[[ $BACKGROUND_LAUNCH =~ true ]] && { [[ $BACKGROUND_LAUNCH =~ true ]] && {
SUCCESS "omni server activated" echo.success "omni server activated"
return 0 return 0
} }
STATUS 'connecting to omni server' echo.status 'connecting to omni server'
OMNI_TMUX a -t=omni remote.omni.tmux a -t=omni
} }

View File

@ -57,14 +57,12 @@ bind-key -n M-q send-keys M-q
bind-key -n M-z send-keys M-z bind-key -n M-z send-keys M-z
bind-key -n M-w send-keys C-M-w bind-key -n M-w send-keys C-M-w
bind-key -n M-Q kill-session
unbind-key C-b unbind-key C-b
bind-key C-b send-prefix bind-key C-b send-prefix
set-option -g prefix M-s set-option -g prefix M-s
bind-key M-s send-keys M-s bind-key M-s send-keys M-s
bind-key -n M-Q kill-session bind-key -n M-Q kill-server
# force reload now # force reload now
bind-key -n M-R send-keys -t omni-manager ENTER bind-key -n M-R send-keys -t omni-manager ENTER