You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
5.6 KiB
212 lines
5.6 KiB
#!/bin/bash
|
|
|
|
## Bash wrap script to launch the ``compose`` docker with right options.
|
|
##
|
|
##
|
|
|
|
## Launcher
|
|
## - should need minimum requirement to run
|
|
## - no shell libs
|
|
##
|
|
|
|
|
|
|
|
read-0() {
|
|
local eof= IFS=''
|
|
while [ "$1" ]; do
|
|
read -r -d '' -- "$1" || eof=1
|
|
shift
|
|
done
|
|
[ -z "$eof" ]
|
|
}
|
|
|
|
|
|
get_running_compose_containers() {
|
|
## XXXvlab: docker bug: there will be a final newline anyway
|
|
docker ps --filter label="compose.service" --format='{{.ID}}'
|
|
}
|
|
|
|
|
|
get_volumes_for_container() {
|
|
local container="$1"
|
|
|
|
docker inspect \
|
|
--format '{{range $mount := .Mounts}}{{$mount.Source}}{{"\x00"}}{{$mount.Destination}}{{"\x00"}}{{end}}' \
|
|
"$container"
|
|
}
|
|
|
|
|
|
is_volume_used() {
|
|
local volume="$1"
|
|
|
|
while read container_id; do
|
|
while read-0 src dst; do
|
|
[ "$src" == "$volume" ] && return 0
|
|
done < <(get_volumes_for_container "$container_id")
|
|
done < <(get_running_compose_containers)
|
|
return 1
|
|
}
|
|
|
|
|
|
clean_unused_sessions() {
|
|
for f in /var/lib/compose/sessions/*; do
|
|
[ -e "$f" ] || continue
|
|
is_volume_used "$f" && continue
|
|
rm -f "$f"
|
|
done
|
|
}
|
|
|
|
|
|
relink_subdirs() {
|
|
local dir
|
|
for dir in "$@"; do
|
|
[ -L "$dir" ] || continue
|
|
target=$(realpath "$dir")
|
|
[ -d "$target" ] || continue
|
|
docker_run_opts+=("-v" "$target:$dir")
|
|
[ -e "$dir/metadata.yml" ] && continue
|
|
relink_subdirs "$dir"/*
|
|
done
|
|
}
|
|
|
|
|
|
mk_docker_run_options() {
|
|
|
|
docker_run_opts=("-v" "/var/run/docker.sock:/var/run/docker.sock")
|
|
|
|
## CACHE/DATA DIRS
|
|
docker_run_opts+=("-v" "/var/lib/compose:/var/lib/compose")
|
|
docker_run_opts+=("-v" "/var/cache/compose:/var/cache/compose")
|
|
|
|
docker_run_opts+=("-v" "/etc/timezone:/etc/timezone:ro")
|
|
|
|
|
|
## current dir
|
|
if parent=$(while true; do
|
|
[ -e "./compose.yml" ] && {
|
|
echo "$PWD"
|
|
exit 0
|
|
}
|
|
[ "$PWD" == "/" ] && exit 1
|
|
cd ..
|
|
done
|
|
); then
|
|
docker_path=/var/lib/compose/root/$(basename "$parent")
|
|
docker_run_opts+=("-v" "$parent:$docker_path:ro" \
|
|
"-w" "$docker_path")
|
|
fi
|
|
|
|
|
|
##
|
|
## Load config files
|
|
##
|
|
|
|
if [ -z "$DISABLE_SYSTEM_CONFIG_FILE" ]; then
|
|
if [ -r /etc/default/charm ]; then
|
|
docker_run_opts+=("-v" "/etc/default/charm:/etc/default/charm:ro")
|
|
. /etc/default/charm
|
|
fi
|
|
|
|
## XXXvlab: should provide YML config opportunities in possible parent dirs ?
|
|
## userdir ? and global /etc/compose.yml ?
|
|
for cfgfile in /etc/compose.conf /etc/compose.local.conf \
|
|
/etc/default/compose /etc/compose/local.conf; do
|
|
[ -e "$cfgfile" ] || continue
|
|
docker_run_opts+=("-v" "$cfgfile:$cfgfile:ro")
|
|
. "$cfgfile"
|
|
done
|
|
for cfgfile in /etc/default/datastore; do
|
|
[ -e "$cfgfile" ] || continue
|
|
docker_run_opts+=("-v" "$cfgfile:$cfgfile:ro")
|
|
done
|
|
else
|
|
docker_run_opts+=("-e" "DISABLE_SYSTEM_CONFIG_FILE=$DISABLE_SYSTEM_CONFIG_FILE")
|
|
fi
|
|
|
|
|
|
##
|
|
## Checking vars
|
|
##
|
|
|
|
## CHARM_STORE
|
|
CHARM_STORE=${CHARM_STORE:-/srv/charm-store}
|
|
[ -L "$CHARM_STORE" ] && {
|
|
CHARM_STORE=$(readlink "$CHARM_STORE") || exit 1
|
|
}
|
|
docker_run_opts+=("-v" "$CHARM_STORE:/srv/charm-store:ro")
|
|
relink_subdirs /srv/charm-store/*
|
|
|
|
## DEFAULT_COMPOSE_FILE
|
|
if [ "${DEFAULT_COMPOSE_FILE+x}" ]; then
|
|
DEFAULT_COMPOSE_FILE=$(realpath "$DEFAULT_COMPOSE_FILE")
|
|
dirname=$(dirname "$DEFAULT_COMPOSE_FILE")/
|
|
if [ -e "${DEFAULT_COMPOSE_FILE}" ]; then
|
|
docker_run_opts+=("-v" "$dirname:$dirname:ro")
|
|
fi
|
|
fi
|
|
|
|
## COMPOSE_YML_FILE
|
|
if [ "${COMPOSE_YML_FILE+x}" ]; then
|
|
if [ -e "${COMPOSE_YML_FILE}" ]; then
|
|
docker_run_opts+=("-v" "$COMPOSE_YML_FILE:/tmp/compose.yml:ro")
|
|
docker_run_opts+=("-e" "COMPOSE_YML_FILE=/tmp/compose.yml")
|
|
fi
|
|
fi
|
|
|
|
## DATASTORE
|
|
if [ "${DATASTORE+x}" ]; then
|
|
docker_run_opts+=("-v" "$DATASTORE:/srv/datastore/data:rw")
|
|
docker_run_opts+=("-e" "DATASTORE=/srv/datastore/data")
|
|
fi
|
|
|
|
## CONFIGSTORE
|
|
if [ "${CONFIGSTORE+x}" ]; then
|
|
docker_run_opts+=("-v" "$CONFIGSTORE:/srv/datastore/config:rw")
|
|
docker_run_opts+=("-e" "CONFIGSTORE=/srv/datastore/config")
|
|
fi
|
|
|
|
docker_run_opts+=("-v" "$HOME/.docker:/root/.docker")
|
|
|
|
COMPOSE_LAUNCHER_BIN=$(readlink -f "${BASH_SOURCE[0]}")
|
|
|
|
filename=$(mktemp -p /tmp/ -t launch_opts-XXXXXXXXXXXXXXXX)
|
|
{
|
|
printf "%s\0" "${docker_run_opts[@]}"
|
|
} > "$filename"
|
|
sha=$(sha256sum "$filename")
|
|
sha=${sha:0:64}
|
|
dest="/var/lib/compose/sessions/$sha"
|
|
{
|
|
printf "%s\0" "-v" "$dest:$dest"
|
|
printf "%s\0" "-e" "COMPOSE_LAUNCHER_OPTS=$dest"
|
|
printf "%s\0" "-e" "COMPOSE_LAUNCHER_BIN=$COMPOSE_LAUNCHER_BIN"
|
|
} >> "$filename"
|
|
mkdir -p /var/lib/compose/sessions
|
|
mv "$filename" "$dest"
|
|
echo "$dest"
|
|
}
|
|
|
|
|
|
run() {
|
|
docker_run_opts=()
|
|
if [ -z "$COMPOSE_LAUNCHER_OPTS" ]; then
|
|
clean_unused_sessions
|
|
COMPOSE_LAUNCHER_OPTS="$(mk_docker_run_options)"
|
|
fi
|
|
|
|
while read-0 opt; do
|
|
docker_run_opts+=("$opt")
|
|
done < <(cat "$COMPOSE_LAUNCHER_OPTS")
|
|
|
|
COMPOSE_DOCKER_IMAGE=${COMPOSE_DOCKER_IMAGE:-docker.0k.io/compose}
|
|
if [ -t 0 ]; then
|
|
docker_run_opts+=("-i")
|
|
fi
|
|
if [ -t 1 ]; then
|
|
docker_run_opts+=("-t")
|
|
fi
|
|
exec docker run --rm "${docker_run_opts[@]}" "${COMPOSE_DOCKER_IMAGE}" "$@"
|
|
}
|
|
|
|
|
|
run "$@"
|