Skip to content

Instantly share code, notes, and snippets.

@ggrandes
Last active November 26, 2019 19:47
Show Gist options
  • Save ggrandes/091f8ebae850731f3d9c to your computer and use it in GitHub Desktop.
Save ggrandes/091f8ebae850731f3d9c to your computer and use it in GitHub Desktop.
Clustered commands (ssh/rsync)
#!/bin/bash
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Original Source:
# https://gist.github.com/ggrandes/091f8ebae850731f3d9c
#
# Clustered commands (ssh/rsync)
#
# v1.0, 2015.05.25, ggrandes
#
# /etc/ssh/ssh_config:
# Host *
# ControlMaster auto
# ControlPath /dev/shm/.ssh-mux_%r@%h:%p
# ControlPersist 600
# CheckHostIP no
# Protocol 2
# AddressFamily inet
#
# /etc/ssh/sshd_config:
# TCPKeepAlive yes
# UseDNS no
# DebianBanner no
# ClientAliveCountMax 5
# ClientAliveInterval 60
#
docluster() {
local config="/etc/clusternodes.conf"
# Read Nodes
local line nodes=''
while read line; do {
nodes="$nodes $line"
} done < $config
# Default Params
local verbose=y
local skip_local=n
local connect_timeout=30
local mode=ssh
#
local NO_COLOUR="\033[0m"
local LIGHT_BLUE="\033[1;34m"
local RED="\033[0;31m"
local CYAN="\033[1;36m"
local WHITE="\033[1;37m"
local SEP="------------------------------------"
# Parse Params
local p
for p in "$@"; do {
case "$p" in
-h|--help)
echo "Usage: $FUNCNAME [options] --mode=ssh [--] <command>"
echo " or $FUNCNAME [options] --mode=rsync [--] [rsync-options] <SRC-DIR> [<SRC-DIR>]... <DEST-DIR>"
echo
echo "Options:"
echo " -h|--help"
echo " -v|--verbose"
echo " -q|--quiet"
echo " --skip-local"
echo " --connect-timeout=<seconds>"
echo " --nodes=<node1,node2,...>"
echo " --mode=<ssh|rsync>"
echo " --skip-local[=<y|n>]"
echo
echo "Defaults (global):"
echo " --mode=$mode"
echo " --nodes=${nodes// /,}"
echo " --connect-timeout=$connect_timeout"
echo " --verbose"
echo
echo "Defaults (when --mode=rsync):"
echo " --skip-local"
return
;;
-v|--verbose)
verbose=y
shift
;;
-q|--quiet)
verbose=n
shift
;;
--skip-local|--skip-local=y)
skip_local=y
shift
;;
--skip-local=n)
skip_local=n
shift
;;
--connect-timeout=*)
connect_timeout=${p#--connect-timeout=}
shift
;;
--nodes=*)
nodes="${p#--nodes=}"
nodes="${nodes//,/ }"
shift
;;
--mode=*)
mode="${p#--mode=}"
[ "$mode" = "rsync" ] &&
skip_local=y
shift
;;
--) shift; break; ;;
-*) shift; ;;
*) break; ;;
esac
} done
# Execute
local rsync_dest=
[ "$mode" = "rsync" ] && {
rsync_dest="${@:$#}"
set -- "${@:1:$[$# - 1]}"
}
local node
for node in $nodes; do {
[ $# -gt 0 ] || { echo "Invalid params: use --help for help" && break; }
if [ "$HOSTNAME" = "$node" ]; then
[ "$skip_local" = "y" ] && continue
[ "$verbose" = "y" ] &&
echo -e "${LIGHT_BLUE}${SEP} --${CYAN} $node ${LIGHT_BLUE}--\t--${WHITE} LOCAL ${LIGHT_BLUE}--${NO_COLOUR}"
[ "$mode" = "ssh" ] &&
"$@"
[ "$mode" = "rsync" ] &&
rsync --protect-args -e "ssh -q -o BatchMode=true -o ConnectTimeout=$connect_timeout" "$@" "$rsync_dest"
else
[ "$verbose" = "y" ] &&
echo -e "${LIGHT_BLUE}${SEP} --${CYAN} $node ${LIGHT_BLUE}--\t--${WHITE} REMOTE ${LIGHT_BLUE}--${NO_COLOUR}"
[ "$mode" = "ssh" ] && {
local p q=''
for p in "$@"; do {
q="$q \"$p\""
} done
ssh -qt -o BatchMode=true -o ConnectTimeout=$connect_timeout $node "$q"
}
[ "$mode" = "rsync" ] &&
rsync --protect-args -e "ssh -q -o BatchMode=true -o ConnectTimeout=$connect_timeout" "$@" $node:"$rsync_dest"
fi
} done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment