docker-scripts/docker-service-exec

53 lines
1.9 KiB
Bash
Executable File

#!/bin/bash
# this command helper depends on key-based (passwordless) SSH access by the current user to each of the docker swarm nodes.
# usage help.
usage()
{
echo
echo "Usage: docker-service-exec [OPTIONS] SERVICE COMMAND [ARG...]"
echo
echo "Run a command in a running swarm service"
echo
echo "Options:
-i, --interactive Keep STDIN open even if not attached
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container"
exit 2
}
# parse the arguments
PARSED_ARGUMENTS=$(getopt -q -a -n docker-service-exec -o iu:w: -l interactive,it,user:,workdir: -- "$@")
VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then
usage
fi
# use below for diagnostics only.
# echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS"
eval set -- "$PARSED_ARGUMENTS"
while :
do
case "$1" in
-i | --it | --interactive) OPT_INTERACTIVE="-it"; shift ;;
-u | --user) OPT_USER="-u $2"; shift 2 ;;
-w | --workdir) OPT_WORKDIR="-w $2"; shift 2 ;;
# -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;;
# If invalid options were passed, then getopt should have reported an error,
# which we checked as VALID_ARGUMENTS when getopt was called...
*)
echo "Unexpected option: $1 - this should not happen."
usage;;
esac
done
# discover docker server vars.
SERVICE_NAME=$1; shift
TASK_ID=$(docker service ps --filter 'desired-state=running' $SERVICE_NAME -q)
NODE_ID=$(docker inspect --format '{{ .NodeID }}' $TASK_ID)
CONTAINER_ID=$(docker inspect --format '{{ .Status.ContainerStatus.ContainerID }}' $TASK_ID)
NODE_HOST=$(docker node inspect --format '{{ .Description.Hostname }}' $NODE_ID)
# connect to the docker host through SSH
export DOCKER_HOST="ssh://$(whoami)@$NODE_HOST.$(hostname -d)"
# execute the command
docker exec $OPT_INTERACTIVE $OPT_USER $OPT_WORKDIR $CONTAINER_ID "$@"