Skip to content

Instantly share code, notes, and snippets.

@deardooley
Created March 21, 2015 16:30
Show Gist options
  • Select an option

  • Save deardooley/f5512a966ddad73b19eb to your computer and use it in GitHub Desktop.

Select an option

Save deardooley/f5512a966ddad73b19eb to your computer and use it in GitHub Desktop.
figexec - Bash script to add docker exec support for fig orchestrations
#!/bin/bash
######################################################################
#
# figexec
#
# Author: Rion Dooley <[email protected]>
# Description:
# This script emulates the functionality one would expect if `docker exec`
# functionality were supported in fig. Simply run this from your project
# folder and you will be able to exec commands by specifying just the
# service name. If multiple services are scaled up, you can use the
# --scalar argument to specify a particular container.
#
# By default this script will run
#
# docker exec -it <projectname>_web_1 /bin/bash
#
# giving you an interactive shell inside the web container. No particular
# reason for this as the default other than it's what I use most.
#
######################################################################
scalar=1
tty="true"
interactive="true"
out() {
local message="$@"
printf '%b\n' "$message";
}
die() { out "$@"; exit 1; } >&2
# Set a trap for cleaning up in case of errors or when script exits.
rollback() {
stty echo
die
}
# A non-destructive exit for when the script exits naturally.
safe_exit() {
trap - INT TERM EXIT
exit
}
# Set our rollback function for unexpected exits.
#trap rollback INT TERM EXIT
# Print usage
usage() {
echo -n "$(basename $0) [OPTIONS]...
$(basename $0) [OPTIONS]... [SERVICE]
$(basename $0) [OPTIONS]... [SERVICE] [COMMAND]
Runs docker exec on a fig service. This command should be run within the
same directory as the fig file that started the services. It will ignore
the project portion of the service names and just focus on the component
and scalar values. The default command is '/bin/bash'. The default service
name is 'web'. If you have scaled a particular service that you want to
exec, use the scalar option to select the scaled instance of that service.
Options:
-s, --scalar=1 Selects the service with the given scalar in case
multiple services of a given type have been started
using 'fig scale'. ex. project_web_1 has scalar=1,
project_web_5 has scalar=5.
-i, --interactive=true Run 'docker exec' in interactive mode
-t, --tty=true Add a tty to the interactive session
-h, --help Display this help and exit
"
}
main() {
if [[ "$#" -eq 0 ]]; then
SERVICE_NAME=web
CMD=/bin/bash
elif [[ "$#" -eq 1 ]]; then
SERVICE_NAME=$1
CMD=/bin/bash
elif [[ "$#" -eq 2 ]]; then
SERVICE_NAME=$1
CMD=$2
else
out "Invalid number of arguments"
usage
die
fi
if [[ -z "$SERVICE_NAME" ]]; then
SERVICE_NAME=web
fi
if [[ -z "$CMD" ]]; then
CMD=/bin/bash
fi
matches=($(fig ps | grep -v "Exit " | awk '{print $1}' | grep "${SERVICE_NAME}_${scalar}"))
if [[ "${#matches[@]}" -eq 0 ]]; then
die "No service named \"$SERVICE_NAME\" is currently running"
elif [[ "${#matches[@]}" -eq 1 ]]; then
SERVICE=$matches[0]
else
die "Multiple instances of the \"$SERVICE_NAME\" service with scalar $scalar are currently running. Please use docker exec manually"
fi
args=''
execcmd="docker exec --interactive=$interactive --tty=$tty $matches $CMD"
echo "Running $execcmd"
sh -c "$execcmd"
}
# Read the options and set stuff
while [[ $1 = -?* ]]; do
case $1 in
-h|--help) usage >&2; safe_exit ;;
-s|--scaler) shift; scaler=$1 ;;
-t|--tty) shift; tty=$1 ;;
-i|--interactive) shift; interactive=$1 ;;
--endopts) shift; break ;;
*) die "invalid option: $1" ;;
esac
shift
done
main $@
# This has to be run last not to rollback changes we've made.
safe_exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment