summary refs log tree commit diff
path: root/bin/enter
blob: 77d79e3e33531c86c533b72888c4fc1f79fabf34 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/sh
set -e
[ -n "$DEBUG" ] && set -x

target=
img=""
dockerfile="${PWD}/Dockerfile"
priv=
opts=
become=
verbose=
cwd=$PWD
no_tty=

usage() {
	printf "usage: %s OPTIONS -- [ARGS]\n" "$(basename "$0")"
	printf "\n"
	printf "  -t TARGET\n"
	printf "  -i IMAGE\n"
	printf "  -f DOCKERFILE\n"
	printf "  -o EXTRA OPTIONS\n"
	printf "  -D (run privileged)\n"
	printf "  -B (don't reassign uid/gid)\n"
	printf "  -v (be verbose)\n"
	printf "  -c CWD\n"
	printf "  -T (not tty)\n"
	printf "\n"
	printf "Enter the container defined in Dockerfile, with \$PWD mounted at /src\n"
	exit 2
}

while getopts t:i:f:o:c:vBDTh o; do
	case $o in
		t) target="$OPTARG" ;;
		i) img="$OPTARG" ;;
		f) dockerfile="$OPTARG" ;;
		o) opts="$OPTARG" ;;
		c) cwd="$OPTARG" ;;
		D) priv=1 ;;
		B) become=1 ;;
		v) verbose=1 ;;
		T) no_tty=1 ;;
		h | ?) usage ;;
	esac
done
shift $((OPTIND - 1))

if [ -z "$img" ]; then
	name="$(basename "$dockerfile" | cut -d'.' -f1 | tr '[:upper:]' '[:lower:]')" # support <name>.Dockerfile
	scope="$(basename "$(dirname "$(readlink -f -- "$dockerfile")")" | tr '[:upper:]' '[:lower:]')"
	# fall back to directory name
	[ "$name" = "Dockerfile" ] && name="$scope"
	img="${scope}/${name}"

	# allow setting this to some non-file value to skip building
	# > enter -i alpine -f none
	# for a quick alpine based container with $PWD mounted in
	[ -f "$dockerfile" ] \
		&& docker build --tag="$img" --target="$target" --file="$dockerfile" "$PWD"
fi

extra_args=
[ -n "$become" ] && extra_args="${extra_args} "
[ -n "$priv" ] && {
	extra_args="${extra_args} \
		--tmpfs=/run --tmpfs=/sys/fs/cgroup \
		--sysctl=net.ipv4.ip_forward=1 \
		--security-opt=apparmor:unconfined --security-opt=seccomp:unconfined \
		--cap-add NET_ADMIN --cap-add SYS_ADMIN --cap-add SYS_RESOURCE \
		--tmpfs=/var/lib/docker"
}
# make the container transparent
[ -z "$priv" ] && {
	extra_args="${extra_args} \
		--privileged \
		--mount=type=bind,src=${HOME},target=${HOME},ro \
		--network=host"
}

[ -n "$opts" ] && extra_args="${extra_args} ${opts}"

[ -z "$become" ] \
	&& extra_args="${extra_args} --user="$(id -u):$(id -g)""

[ -z "$no_tty" ] \
	&& extra_args="${extra_args} --tty"

ep="sh"
[ -n "$1" ] && {
	ep="$1"
	shift
}

[ -n "$verbose" ] && { set -x; }

cname=$(mktemp --dry-run enterXXXX)
exec docker run --name "$cname" --rm -i \
	--uts host \
	--entrypoint="$ep" \
	--mount=type=bind,src="$cwd",dst=/src -w /src $extra_args "$img" $@