feat: allow setting DOCKER_BIN path for docker execution

This change allows operators to specify a DOCKER_BIN environment variable. This will specify a binary to run when executing docker, which is useful in cases where the 'docker' command being run must be modified in a way that would otherwise be invasive to Dokku, but minimalistic if done within a wrapper.
This commit is contained in:
Jose Diaz-Gonzalez
2019-05-29 00:08:02 -04:00
parent 0e03c82139
commit 785d9b4937
33 changed files with 155 additions and 106 deletions

View File

@@ -136,7 +136,7 @@ func DirectoryExists(filePath string) bool {
// DockerInspect runs an inspect command with a given format against a container id
func DockerInspect(containerID, format string) (output string, err error) {
b, err := sh.Command("docker", "inspect", "--format", format, containerID).Output()
b, err := sh.Command(DockerBin(), "inspect", "--format", format, containerID).Output()
if err != nil {
return "", err
}
@@ -253,7 +253,7 @@ func IsImageHerokuishBased(image string) bool {
}
dockerGlobalArgs := os.Getenv("DOKKU_GLOBAL_RUN_ARGS")
parts := []string{"docker", "run", dockerGlobalArgs, "--entrypoint=\"/bin/sh\"", dockerArgs, image, "-c", "\"test -f /exec\""}
parts := []string{DockerBin(), "run", dockerGlobalArgs, "--entrypoint=\"/bin/sh\"", dockerArgs, image, "-c", "\"test -f /exec\""}
var dockerCmdParts []string
for _, str := range parts {
@@ -339,11 +339,21 @@ func VerifyAppName(appName string) (err error) {
// VerifyImage returns true if docker image exists in local repo
func VerifyImage(image string) bool {
imageCmd := NewShellCmd(strings.Join([]string{"docker inspect", image}, " "))
imageCmd := NewShellCmd(strings.Join([]string{DockerBin(), "inspect", image}, " "))
imageCmd.ShowOutput = false
return imageCmd.Execute()
}
// DockerBin returns a string which contains a path to the current docker binary
func DockerBin() string {
dockerBin := os.Getenv("DOCKER_BIN")
if dockerBin == "" {
dockerBin = "docker"
}
return dockerBin
}
//PlugnTrigger fire the given plugn trigger with the given args
func PlugnTrigger(triggerName string, args ...string) error {
shellArgs := make([]interface{}, len(args)+2)

View File

@@ -171,7 +171,7 @@ dokku_container_log_verbose_quiet() {
OIFS=$IFS
IFS=$'\n'
local line
for line in $(docker logs "$CID" 2>&1); do
for line in $("$DOCKER_BIN" logs "$CID" 2>&1); do
dokku_log_verbose_quiet "$line"
done
IFS=$OIFS
@@ -203,7 +203,7 @@ verify_app_name() {
verify_image() {
declare desc="verify image existence"
local IMAGE="$1"
if (docker inspect "$IMAGE" &>/dev/null); then
if "$DOCKER_BIN" inspect "$IMAGE" &>/dev/null; then
return 0
else
return 1
@@ -282,7 +282,7 @@ get_running_image_tag() {
verify_app_name "$APP"
local CIDS=($(get_app_container_ids "$APP"))
local RUNNING_IMAGE_TAG=$(docker inspect -f '{{ .Config.Image }}' "${CIDS[0]}" 2>/dev/null | awk -F: '{ print $2 }' || echo '')
local RUNNING_IMAGE_TAG=$("$DOCKER_BIN" inspect -f '{{ .Config.Image }}' "${CIDS[0]}" 2>/dev/null | awk -F: '{ print $2 }' || echo '')
echo "$RUNNING_IMAGE_TAG"
}
@@ -296,13 +296,13 @@ is_image_herokuish_based() {
fi
# due to how the build process works, all herokuish images have the Environment variable USER=herokuishuser
USER_VALUE="$(docker inspect -f '{{range .Config.Env}}{{if eq . "USER=herokuishuser" }}{{println .}}{{end}}{{end}}' "$IMAGE")"
USER_VALUE="$("$DOCKER_BIN" inspect -f '{{range .Config.Env}}{{if eq . "USER=herokuishuser" }}{{println .}}{{end}}{{end}}' "$IMAGE")"
[[ "$USER_VALUE" == "" ]] && return 1
return 0
}
get_docker_version() {
CLIENT_VERSION_STRING="$(docker version -f="{{ .Client.Version }}")"
CLIENT_VERSION_STRING="$("$DOCKER_BIN" version -f="{{ .Client.Version }}")"
echo "$CLIENT_VERSION_STRING"
}
@@ -376,19 +376,19 @@ copy_from_image() {
if is_image_herokuish_based "$IMAGE"; then
WORKDIR="/app"
else
WORKDIR="$(docker inspect -f '{{.Config.WorkingDir}}' "$IMAGE")"
WORKDIR="$("$DOCKER_BIN" inspect -f '{{.Config.WorkingDir}}' "$IMAGE")"
fi
if [[ -n "$WORKDIR" ]]; then
SRC_FILE="${WORKDIR}/${SRC_FILE}"
fi
fi
local CID=$(docker create "$DOKKU_GLOBAL_RUN_ARGS" "$IMAGE")
if ! docker cp "$CID:$SRC_FILE" "$DST_DIR"; then
docker rm -f "$CID" &>/dev/null
local CID=$("$DOCKER_BIN" create "$DOKKU_GLOBAL_RUN_ARGS" "$IMAGE")
if ! "$DOCKER_BIN" cp "$CID:$SRC_FILE" "$DST_DIR"; then
"$DOCKER_BIN" rm -f "$CID" &>/dev/null
return 1
fi
docker rm -f "$CID" &>/dev/null
"$DOCKER_BIN" rm -f "$CID" &>/dev/null
else
return 1
fi
@@ -470,7 +470,7 @@ is_container_running() {
local CONTAINER_STATUS
dokku_log_warn "Deprecated: common#is_container_status"
CONTAINER_STATUS=$(docker inspect -f '{{.State.Running}}' "$CID" || true)
CONTAINER_STATUS=$("$DOCKER_BIN" inspect -f '{{.State.Running}}' "$CID" || true)
if [[ "$CONTAINER_STATUS" == "true" ]]; then
return 0
@@ -483,7 +483,7 @@ is_container_status() {
declare desc="return 0 if given docker container id is in given state"
local CID=$1
local TEMPLATE="{{.State.$2}}"
local CONTAINER_STATUS=$(docker inspect -f "$TEMPLATE" "$CID" 2>/dev/null || true)
local CONTAINER_STATUS=$("$DOCKER_BIN" inspect -f "$TEMPLATE" "$CID" 2>/dev/null || true)
if [[ "$CONTAINER_STATUS" == "true" ]]; then
return 0
@@ -529,9 +529,9 @@ dokku_build() {
case "$IMAGE_SOURCE_TYPE" in
herokuish)
DOKKU_IMAGE="$(config_get "$APP" DOKKU_IMAGE || echo "$DOKKU_IMAGE")"
cid=$(tar -c . | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app")
test "$(docker wait "$cid")" -eq 0
docker commit "$cid" "$IMAGE" >/dev/null
cid=$(tar -c . | "$DOCKER_BIN" run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app")
test "$("$DOCKER_BIN" wait "$cid")" -eq 0
"$DOCKER_BIN" commit "$cid" "$IMAGE" >/dev/null
[[ -d $DOKKU_APP_CACHE_DIR ]] || mkdir -p "$DOKKU_APP_CACHE_DIR"
plugn trigger pre-build-buildpack "$APP"
@@ -543,10 +543,10 @@ dokku_build() {
declare -a ARG_ARRAY
eval "ARG_ARRAY=($DOCKER_ARGS)"
# shellcheck disable=SC2086
cid=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -v $DOKKU_APP_HOST_CACHE_DIR:/cache -e CACHE_PATH=/cache "${ARG_ARRAY[@]}" $IMAGE /build)
docker attach "$cid"
test "$(docker wait "$cid")" -eq 0
docker commit "$cid" "$IMAGE" >/dev/null
cid=$("$DOCKER_BIN" run $DOKKU_GLOBAL_RUN_ARGS -d -v $DOKKU_APP_HOST_CACHE_DIR:/cache -e CACHE_PATH=/cache "${ARG_ARRAY[@]}" $IMAGE /build)
"$DOCKER_BIN" attach "$cid"
test "$("$DOCKER_BIN" wait "$cid")" -eq 0
"$DOCKER_BIN" commit "$cid" "$IMAGE" >/dev/null
plugn trigger post-build-buildpack "$APP"
;;
@@ -574,7 +574,7 @@ dokku_build() {
eval "ARG_ARRAY=($DOCKER_ARGS)"
# shellcheck disable=SC2086
docker build "${ARG_ARRAY[@]}" $DOKKU_DOCKER_BUILD_OPTS -t $IMAGE .
"$DOCKER_BIN" build "${ARG_ARRAY[@]}" $DOKKU_DOCKER_BUILD_OPTS -t $IMAGE .
plugn trigger post-build-dockerfile "$APP"
;;
@@ -600,14 +600,14 @@ dokku_release() {
herokuish)
plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG"
if [[ -n $(config_export global) ]]; then
cid=$(config_export global | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh")
test "$(docker wait "$cid")" -eq 0
docker commit "$cid" "$IMAGE" >/dev/null
cid=$(config_export global | "$DOCKER_BIN" run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh")
test "$("$DOCKER_BIN" wait "$cid")" -eq 0
"$DOCKER_BIN" commit "$cid" "$IMAGE" >/dev/null
fi
if [[ -n $(config_export app "$APP") ]]; then
cid=$(config_export app "$APP" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh")
test "$(docker wait "$cid")" -eq 0
docker commit "$cid" "$IMAGE" >/dev/null
cid=$(config_export app "$APP" | "$DOCKER_BIN" run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh")
test "$("$DOCKER_BIN" wait "$cid")" -eq 0
"$DOCKER_BIN" commit "$cid" "$IMAGE" >/dev/null
fi
plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG"
;;
@@ -713,15 +713,15 @@ docker_cleanup() {
# delete all non-running containers
# shellcheck disable=SC2046
docker rm $(docker ps -a -f "status=exited" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true
"$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=exited" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true
# delete all dead containers
# shellcheck disable=SC2046
docker rm $(docker ps -a -f "status=dead" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true
"$DOCKER_BIN" rm $("$DOCKER_BIN" ps -a -f "status=dead" -f "label=$DOKKU_CONTAINER_LABEL" -q) &>/dev/null || true
# delete unused images
# shellcheck disable=SC2046
docker rmi $(docker images -f 'dangling=true' -q) &>/dev/null &
"$DOCKER_BIN" rmi $("$DOCKER_BIN" images -f 'dangling=true' -q) &>/dev/null &
}
get_available_port() {
@@ -797,7 +797,7 @@ get_exposed_ports_from_image() {
local IMAGE="$1"
verify_image "$IMAGE"
# shellcheck disable=SC2016
local DOCKER_IMAGE_EXPOSED_PORTS="$(docker inspect -f '{{range $key, $value := .Config.ExposedPorts}}{{$key}} {{end}}' "$IMAGE")"
local DOCKER_IMAGE_EXPOSED_PORTS="$("$DOCKER_BIN" inspect -f '{{range $key, $value := .Config.ExposedPorts}}{{$key}} {{end}}' "$IMAGE")"
echo "$DOCKER_IMAGE_EXPOSED_PORTS"
}
@@ -805,7 +805,7 @@ get_entrypoint_from_image() {
declare desc="return .Config.Entrypoint from passed image name"
local IMAGE="$1"
verify_image "$IMAGE"
local DOCKER_IMAGE_ENTRYPOINT="$(docker inspect --format '{{range .Config.Entrypoint}}{{.}} {{end}}' "$IMAGE")"
local DOCKER_IMAGE_ENTRYPOINT="$("$DOCKER_BIN" inspect --format '{{range .Config.Entrypoint}}{{.}} {{end}}' "$IMAGE")"
echo "ENTRYPOINT $DOCKER_IMAGE_ENTRYPOINT"
}
@@ -813,7 +813,7 @@ get_cmd_from_image() {
declare desc="return .Config.Cmd from passed image name"
local IMAGE="$1"
verify_image "$IMAGE"
local DOCKER_IMAGE_CMD="$(docker inspect --format '{{range .Config.Cmd}}{{.}} {{end}}' "$IMAGE")"
local DOCKER_IMAGE_CMD="$("$DOCKER_BIN" inspect --format '{{range .Config.Cmd}}{{.}} {{end}}' "$IMAGE")"
DOCKER_IMAGE_CMD="${DOCKER_IMAGE_CMD/\/bin\/sh -c/}"
echo "CMD $DOCKER_IMAGE_CMD"
}
@@ -851,7 +851,7 @@ get_container_ports() {
local cid
for cid in $APP_CIDS; do
local container_ports="$(docker port "$cid" | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')"
local container_ports="$("$DOCKER_BIN" port "$cid" | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')"
done
echo "$container_ports"