Created
March 17, 2024 23:14
-
-
Save xrstf/35955652b4862c9dc7cc71ec4b2cc8dd to your computer and use it in GitHub Desktop.
Drum!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Drum! | |
# | |
# Cause the repeated "docker run --rm -it" always sounds | |
# like "drumit" in my head. | |
# | |
# This script makes it easy to start a container. | |
# | |
# Just running `drum` on its own starts a container using | |
# the DEFAULT_IMAGE below. | |
# | |
# -u assume the same UID/GID in the container as on your host | |
# -U create an image based on given image but with | |
# your user/group added to it, then assuming that | |
# user (a more extreme version of -u) | |
# -m mount the current directory into the container; | |
# by default to /tmp, unless you are inside your GOPATH, | |
# then you working directory is mounted to the /go/... | |
# equivalent in the container | |
# -M like -m, but explicitly specify the mount path | |
# -w sets the working directory to the mount path | |
# -W like -w, but explicitly specify the working directory | |
# -p pull the image before doing anything | |
# -v be more verbose | |
# | |
set -euo pipefail | |
# in case no image was provided, assume this one | |
# (set to empty value to disable defaulting) | |
DEFAULT_IMAGE=ubuntu:latest | |
userMode=none # none, assume (-u), ensure (-U) | |
chdir=false | |
workDir= | |
mount=false | |
mountPath= | |
pull=false | |
verbose=false | |
################################ | |
# CLI parsing magic | |
# thanks to https://stackoverflow.com/a/14203146 | |
################################ | |
usage() { | |
echo "Usage: drum [-u|-U] [-m|-M MOUNT_TO] [-w|-W WORKDIR] IMAGE [-- COMMAND]" | |
} | |
# Reset in case getopts has been used previously in the shell | |
OPTIND=1 | |
while getopts "huUwW:mM:pv" opt; do | |
case "$opt" in | |
h) | |
usage | |
exit | |
;; | |
u) | |
userMode=assume | |
;; | |
U) | |
userMode=ensure | |
;; | |
w) | |
chdir=true | |
workDir= | |
;; | |
W) | |
chdir=true | |
workDir=$OPTARG | |
;; | |
m) | |
mount=true | |
mountPath= | |
;; | |
M) | |
mount=true | |
mountPath=$OPTARG | |
;; | |
p) | |
pull=true | |
;; | |
v) | |
verbose=true | |
;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
[ "${1:-}" = "--" ] && shift | |
image="${1:-}" | |
if [ -z "$image" ]; then | |
image="$DEFAULT_IMAGE" | |
if [ -z "$image" ]; then | |
echo "Error: No image given." | |
usage | |
exit 2 | |
fi | |
else | |
shift | |
fi | |
# echo "userMode=$userMode,workDir='$workDir',mount=$mount,image='$image',pull=$pull,verbose=$verbose,args=$@" | |
################################ | |
# you can open your eyes again | |
################################ | |
if $pull; then | |
if $verbose; then | |
(set -x; docker pull "$image") | |
else | |
docker pull --quiet "$image" | |
fi | |
fi | |
runArgs=( | |
--rm | |
--interactive | |
--tty | |
) | |
if [ $userMode == ensure ]; then | |
tmpdir="$(mktemp -d)" | |
cleanup() { | |
rm -rf -- "$tmpdir" | |
} | |
trap "cleanup" EXIT SIGINT | |
uid=$(id -u) | |
gid=$(id -g) | |
me=$(id -un) | |
dockerfile="$tmpdir/Dockerfile" | |
cat <<EOF > "$dockerfile" | |
FROM $image | |
RUN addgroup --gid $gid $me | |
RUN adduser --uid $uid --gid $gid --gecos "" $me | |
EOF | |
imageName="drum-$image" | |
if $verbose; then | |
(set -x; docker build --tag "$imageName" "$tmpdir") | |
else | |
docker build --tag "$imageName" "$tmpdir" 2>/dev/null | |
fi | |
image="$imageName" | |
# re-use the code below | |
userMode=assume | |
fi | |
if [ $userMode == assume ]; then | |
uid=$(id -u) | |
gid=$(id -g) | |
runArgs+=(--user "$uid:$gid") | |
fi | |
if $mount; then | |
here="$(realpath .)" | |
if [[ "$mountPath" == "" ]]; then | |
here="$(realpath .)" | |
gopath="$(go env GOPATH)" | |
gopathRel="${here##$gopath}" | |
if [[ "$gopathRel" != "$here" ]]; then | |
mountPath="/go$gopathRel" | |
else | |
mountPath="${workDir:-/tmp}" | |
fi | |
# echo "Defaulted mount path to $mountPath." | |
fi | |
runArgs+=(--volume "$here:$mountPath") | |
# unless an explicit workdir was given, mounting the pwd should set | |
# the workdir to the mount path | |
if [[ "$workDir" == "" ]]; then | |
chdir=true | |
workDir="$mountPath" | |
fi | |
fi | |
if $chdir; then | |
if [[ "$workDir" == "" ]]; then | |
echo "Error: Could not determine working directory." | |
usage | |
exit 1 | |
fi | |
runArgs+=(--workdir "$workDir") | |
fi | |
# echo "args: ${runArgs[*]}" | |
if $verbose; then | |
(set -x; exec docker run "${runArgs[@]}" "$image" "$@") | |
else | |
exec docker run "${runArgs[@]}" "$image" "$@" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment