53 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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 "$@" |