From e6e095772e045285d67fc1d4e69654614797907b Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Sun, 30 Dec 2018 11:01:03 +0000 Subject: [PATCH] Allow execution of web script Fixes: #2 --- .gitignore | 1 - README.md | 4 ++ bin/rmux | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100755 bin/rmux diff --git a/.gitignore b/.gitignore index 49c2bbe..bb949af 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ dist build eggs parts -bin var sdist develop-eggs diff --git a/README.md b/README.md index a36e43a..f0aea38 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ exit # run df on two remote hosts, syncronized windows HOSTS="node1 node2" rmux df + +# run a script downloaded from the web (installs pip) +rmux -w https://bootstrap.pypa.io/get-pip.py + ``` If you fail to define the ``HOSTS`` variable the tool will default to localhost diff --git a/bin/rmux b/bin/rmux new file mode 100755 index 0000000..87888e6 --- /dev/null +++ b/bin/rmux @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +# Shortcut for creating templated new shell scripts +set -euo pipefail +: ${HOSTS:=localhost} +: ${XPANES_OPT:=-ss} +red=`tput setaf 1` +green=`tput setaf 2` +blue=`tput setaf 4` +bold=`tput bold; tput setaf 7` +reset=`tput sgr0` + +# -- functions --- + +get_abs_path() { + local PARENT_DIR=$(dirname "$1") + cd "$PARENT_DIR" + local ABS_PATH="$(pwd)"/"$(basename "$1")" + cd - >/dev/null + echo "$ABS_PATH" +} + +# --- cli processing --- +POSITIONAL=() +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -w) + WEB_SCRIPT="$2" + shift # past argument + shift # past value + break # anything after url will be passed to remote command + ;; + -h|--help) + shift # past argument + cat < [options] + +General Options: + -h, --help Show help. + --version Displays current version and where it runs from + -w Download script from url and execute it + +The list of hosts is loaded from ${bold}HOSTS${reset} environment variable \ +and when this is not defined it will fallback to using localhost, still even \ +in this case it will use ssh. +EOF + exit 0 + ;; + --version) + shift + echo "rmux ${green}$(python -c 'import rmux; print(rmux.__version__)')${reset} from ${blue}$(get_abs_path `which $0`)${reset}" + exit 0 + ;; + *) # unknown option + POSITIONAL+=("$*") # save it in an array for later + # shift + break + ;; +esac +done +# set -- "${POSITIONAL[@]:-}" # restore positional parameters + +if [ "${HOSTS}" == "localhost" ]; then + &>2 echo "Warning: using localhost fallback, define HOSTS as a space separated list" +fi + +which xpanes >/dev/null || { + >&2 echo "FATAL: xpanes not found, please install it. https://github.com/greymd/tmux-xpanes#installation" + exit 2 +} + +# detect current project based on .git presence +PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) +PROJECT_NAME=$(basename "$PROJECT_ROOT") +REMOTE_DIR=.cache/.rmux/$PROJECT_NAME +if [[ "$PROJECT_ROOT" != "" ]]; then + echo INFO: Found ${green}$PROJECT_NAME${reset} project on ${green}$PROJECT_ROOT${reset} + # generate smart exclude list, based on .gitignore when possible. + # See https://stackoverflow.com/a/15373763/99834 + ( + cd $PROJECT_ROOT + git ls-files --exclude-standard -oi --directory >$PROJECT_ROOT/.git/ignores.tmp + + # if os.path.isfile('.gitignore'): + # self.rsync_params += \ + # '--include .git --exclude-from=.git/ignores.tmp ' + ) + for HOST in $HOSTS; do + set -x + ssh $HOST mkdir -p $REMOTE_DIR + rsync -ah --no-o --no-g --include .git --exclude-from=$PROJECT_ROOT/.git/ignores.tmp $PROJECT_ROOT/ $HOST:$REMOTE_DIR/ + done +fi + + +# >&2 echo "DEBUG: arguments $# : $*" +XPANES_OPT='-ss' + +if [[ "${WEB_SCRIPT:-}" != "" ]]; then + SCRIPT_FILENAME="${WEB_SCRIPT##*/}" + INJECT="curl -s $WEB_SCRIPT > $SCRIPT_FILENAME && chmod +x $SCRIPT_FILENAME && ./$SCRIPT_FILENAME" +fi + + +if [ "$#" -eq 0 ]; then + >&2 echo "INFO: No command specified, just starting ssh sessions" + # COMMAND="cd $REMOTE_DIR; shopt -s execfail; exec -l \"\${SHELL:-sh}\" ls" + COMMAND="\${SHELL:-sh} -i <<< 'cd $REMOTE_DIR;${INJECT:-}; exec