Changes to Docker-related files/configuration don't occur in a vacuum. They are made in coordination with changes to the main repository, so it doesn't make sense to track them separately. Note: Removing the 'windows' Docker files completely. No one has has used them in a long, long time. The client build would be broken in there anyways, the image is based on .NET Framework 3.5!
234 lines
6.1 KiB
Bash
Executable File
234 lines
6.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
mount_prefix="$HOME/.spark-dev/mounts"
|
|
|
|
function print_help_and_exit() {
|
|
cat <<EOF
|
|
Start a docker dev container
|
|
Usage: start_docker.sh [OPTIONS] image container
|
|
|
|
Positionals:
|
|
image The image to instantiate
|
|
container The name for the container
|
|
|
|
Options:
|
|
-u,--user USER The user to add in the container (defaults to the current user)
|
|
-p,--pass PASS The password for USER in the container (defaults to USER)
|
|
-i,--image IMAGE The image to instantiate
|
|
-c,--container CONT The name for the container
|
|
-m,--mount MOUNT The name for the folder (outside the container) to create/mount to the home
|
|
directory in the container. Mount folders are added here: $mount_prefix
|
|
--mount-existing Mount the specified dir even if it already exists
|
|
--port <cont_port>:<host_port> OR [<cont_port>:<host_port>,...] Port mapping(s). May be
|
|
specified multiple times.
|
|
-h,--help Print this help message and exit
|
|
|
|
EOF
|
|
exit "$1"
|
|
}
|
|
|
|
|
|
declare docker_user=""
|
|
declare docker_pass=""
|
|
declare image_name=""
|
|
declare cont_name=""
|
|
declare mount_name=""
|
|
declare -i mount_existing=0
|
|
declare -a port_mappings=()
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-u)
|
|
;&
|
|
--user)
|
|
if [[ -z "$2" ]]; then
|
|
echo "User (-u,--user) must be non-empty"
|
|
print_help_and_exit 1
|
|
fi
|
|
docker_user="$2"
|
|
shift 2
|
|
;;
|
|
-p)
|
|
;&
|
|
--pass)
|
|
if [[ -z "$2" ]]; then
|
|
echo "Password (-p,--pass) must be non-empty"
|
|
print_help_and_exit 1
|
|
fi
|
|
docker_pass="$2"
|
|
shift 2
|
|
;;
|
|
-i)
|
|
;&
|
|
--image)
|
|
if [[ -n "$image_name" ]]; then
|
|
echo "Unexpected argument '$1'"
|
|
print_help_and_exit 1
|
|
elif [[ -z "$2" ]]; then
|
|
echo "Image (-i,--image) must be non-empty"
|
|
print_help_and_exit 1
|
|
fi
|
|
image_name="$2"
|
|
shift 2
|
|
;;
|
|
-c)
|
|
;&
|
|
--container)
|
|
if [[ -n "$cont_name" ]]; then
|
|
echo "Unexpected argument '$1'"
|
|
print_help_and_exit 1
|
|
elif [[ -z "$2" ]]; then
|
|
echo "Container (-c,--container) must be non-empty"
|
|
print_help_and_exit 1
|
|
fi
|
|
cont_name="$2"
|
|
shift 2
|
|
;;
|
|
--port)
|
|
# Parse port(s) arg, and append the result to 'port_mappings'
|
|
# Note: port(s) may be specified in bracketed notation:
|
|
# [a:b,c:d,...,y:z]
|
|
next_ports="$(echo "$2" | sed -e 's/\[//g' -e 's/\]//g' -e 's/,/ /g')"
|
|
if [[ "${#port_mappings[@]}" -gt 0 ]]; then
|
|
next_ports=" $next_ports"
|
|
fi
|
|
port_mappings+=("$next_ports")
|
|
shift 2
|
|
;;
|
|
-m)
|
|
;&
|
|
--mount)
|
|
if [[ -z "$2" ]]; then
|
|
echo "Mount (-m,--mount) must be non-empty"
|
|
fi
|
|
mount_name="$2"
|
|
shift 2
|
|
;;
|
|
--mount-existing)
|
|
mount_existing=1
|
|
shift 1
|
|
;;
|
|
-h)
|
|
;&
|
|
--help)
|
|
print_help_and_exit 0
|
|
;;
|
|
*)
|
|
if [[ -z "$1" ]]; then
|
|
echo "Invalid positional argument '$1'"
|
|
print_help_and_exit 1
|
|
elif [[ -z "$image_name" ]]; then
|
|
image_name="$1"
|
|
elif [[ -z "$cont_name" ]]; then
|
|
cont_name="$1"
|
|
else
|
|
echo "Unexpected argument '$1'"
|
|
print_help_and_exit 1
|
|
fi
|
|
shift 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
|
|
if [[ -z "$image_name" ]]; then
|
|
image_name="bluetradingsystems/spark-crypto-dev"
|
|
fi
|
|
|
|
host_name="$(hostname)"
|
|
if [[ -n "$cont_name" ]]; then
|
|
host_name="$host_name.$cont_name"
|
|
fi
|
|
|
|
if [[ -z "$mount_name" ]]; then
|
|
mount_name="$cont_name"
|
|
fi
|
|
|
|
if [[ -z "$mount_name" && -z "$cont_name" ]]; then
|
|
echo "Please specify mount (-m,--mount) and/or container (-c,--container)"
|
|
print_help_and_exit 1
|
|
fi
|
|
|
|
if [[ -z "$docker_user" ]]; then
|
|
docker_user="$USER"
|
|
fi
|
|
|
|
home_src=$mount_prefix/$mount_name
|
|
home_tgt=$HOME
|
|
repo_src=$(git rev-parse --show-superproject-working-tree)
|
|
repo_tgt=$HOME/$(basename "$repo_src")
|
|
working_dir=$HOME
|
|
|
|
if [[ $mount_existing -eq 0 && -e "$home_src" ]]; then
|
|
# Don't overwrite existing dir (might be mounted in another container)
|
|
echo "Mount dir '$home_src' already exists (use --mount-existing to mount an existing directory)"
|
|
print_help_and_exit 1
|
|
fi
|
|
|
|
mkdir -p "$home_src"
|
|
|
|
if [[ "${#port_mappings[@]}" -eq 0 ]]; then
|
|
port_mappings=("8000:8000" "8001:8001" "8002:8002" "8003:8003")
|
|
fi
|
|
|
|
# Adapt port_mappings into args for `docker run` by prepending "-p " to each
|
|
# item
|
|
declare -a docker_port_args=()
|
|
for port_mapping in "${port_mappings[@]}"; do
|
|
docker_port_args+=("-p $port_mapping")
|
|
done
|
|
|
|
echo "Starting container '$cont_name'
|
|
image_name : $image_name
|
|
cont_name : $cont_name
|
|
home_src : $home_src
|
|
home_tgt : $home_tgt
|
|
repo_src : $repo_src
|
|
repo_tgt : $repo_tgt
|
|
working dir : $working_dir
|
|
ports : ${port_mappings[*]}
|
|
"
|
|
|
|
# DON'T wrap $docker_port_args in quotes. We want bash to split args by
|
|
# whitespace
|
|
docker run \
|
|
--net bridge \
|
|
-h "$host_name" \
|
|
-e "TZ=America/New_York" \
|
|
--cap-add=SYS_PTRACE \
|
|
--security-opt seccomp=unconfined \
|
|
--name "$cont_name" \
|
|
-v "$home_src:$home_tgt" \
|
|
-v "$repo_src:$repo_tgt" \
|
|
-w "$working_dir" \
|
|
${docker_port_args[*]} \
|
|
--shm-size=4024m \
|
|
-t \
|
|
-i \
|
|
-d \
|
|
-e DISPLAY="$DISPLAY" \
|
|
"$image_name" \
|
|
bash
|
|
|
|
# Add user w/ same uid and gid as the current user outside of docker, so the
|
|
# user inside the docker has file permissions in the mounted dir.
|
|
docker_group="$docker_user"
|
|
docker_user_uid="$(id -u "$USER")"
|
|
docker_user_gid="$(id -g "$USER")"
|
|
|
|
echo "Adding user in container '$cont_name'
|
|
name : $docker_user
|
|
uid : $docker_user_uid
|
|
gid : $docker_user_gid"
|
|
|
|
if [[ -z "$docker_pass" ]]; then
|
|
docker_pass="$docker_user"
|
|
echo "Giving user '$docker_user' a secure password: $docker_pass"
|
|
fi
|
|
|
|
docker exec -u root -it "$cont_name" groupadd -g "$docker_user_gid" "$docker_group"
|
|
docker exec -u root -it "$cont_name" useradd -u "$docker_user_uid" -g "$docker_user_gid" "$docker_user"
|
|
docker exec -u root -it "$cont_name" usermod --password "$(openssl passwd -1 "$docker_pass")" "$docker_user"
|
|
docker exec -u root -it "$cont_name" usermod -aG sudo "$docker_user"
|
|
docker exec -u root -it "$cont_name" "$repo_tgt/externals/src/emumba/install_emumba-deribit-connector.sh"
|