Skip to content

Commit

Permalink
plumb through exec instead of assuming /bin/sh (#290)
Browse files Browse the repository at this point in the history
instead of assuming `CMD` is a shell script, just use `exec`.

this means we can support any valid `CMD`, with the downside that shell
scripts will now need to set their own setopts. we trade some
transparency for more compatibility and control.

this also cleans up the scripts logging a bit, and adds a `socat`
registry proxy to support local registries for the dind driver. the
`socat` works almost identically to how containerd mirroring is done
with the k3sindocker driver.
  • Loading branch information
joshrwolf authored Feb 3, 2025
1 parent 8b1b32b commit a86196e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 35 deletions.
92 changes: 57 additions & 35 deletions cmd/entrypoint/kodata/entrypoint-wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,42 +1,63 @@
#!/bin/sh
set -eu

info() {
printf '%s [INFO] %s\n' "$(date "+%Y-%m-%dT%H:%M:%S")" "$1" >&2
}

warn() {
printf '%s [WARN] %s\n' "$(date "+%Y-%m-%dT%H:%M:%S")" "$1" >&2
}

error() {
printf '%s [ERROR] %s\n' "$(date "+%Y-%m-%dT%H:%M:%S")" "$1" >&2
}

# Print usage and exit with error
usage() {
echo "Usage: $0 <test-script-path>"
echo "Environment variables:"
echo " IMAGETEST_DRIVER: Type of test environment (docker_in_docker, k3s_in_docker)"
error "Usage: $0 <test-script-path>"
error "Environment variables:"
error " IMAGETEST_DRIVER: Type of test environment (docker_in_docker, k3s_in_docker)"
exit 1
}

# Validate that a test script exists and is executable.
# This function is used by all drivers to ensure consistent validation.
# Arguments:
# $1: Path to the test script
validate_test_script() {
script_path="$1"
validate_cmd() {
cmdarg="$1"

if [ ! -f "$script_path" ]; then
echo "Error: Test script '$script_path' does not exist"
exit 1
# Only try to do validations if cmdarg is a file (presumably a script of sorts)
if [ -f "$cmdarg" ]; then
if [ ! -x "$cmdarg" ]; then
chmod +x "$cmdarg" || warn "Failed to make script executable"
fi
fi
}

init_registry_proxy() {
case "${IMAGETEST_REGISTRY}" in
"localhost:"*)
info "Attempting to start registry proxy"

if [ ! -x "$script_path" ]; then
echo "Warning: Test script '$script_path' is not executable, attempting to set execute permission"
if ! chmod +x "$script_path"; then
echo "Error: Failed to make test script executable"
exit 1
port=$(echo "$IMAGETEST_REGISTRY" | sed -n 's/^localhost:\([0-9]\+\).*/\1/p')
if [ -n "${port}" ]; then
info "Detected localhost and port ${port}, starting registry proxy"

# Start a non-forked socat process to proxy localhost to dockers magic dns
setsid socat -d -lf /tmp/local-registry-proxy.log TCP-LISTEN:"${port}",fork,reuseaddr TCP:host.docker.internal:"${port}" </dev/null >/dev/null 2>&1 &
fi
echo "Successfully made test script executable"
fi
;;
esac
}

# Initialize and manage a Docker-in-Docker environment.
# This function handles the Docker daemon startup and monitoring.
# Arguments:
# $1: Path to the test script (already validated)
init_docker_in_docker() {
test_script="$1"
cmd="$1"
timeout=30
log_dir="/var/log/docker"

Expand All @@ -47,74 +68,75 @@ init_docker_in_docker() {
/usr/bin/dockerd-entrypoint.sh dockerd >"$log_dir/dockerd.log" 2>&1 &

# Wait for Docker to be ready
echo "Waiting for Docker daemon to be ready..."
info "Waiting for Docker daemon to be ready..."
while [ "$timeout" -gt 0 ]; do
if docker version >/dev/null 2>&1; then
echo "Docker daemon is ready"
info "Docker daemon is ready"
break
fi
timeout=$((timeout - 1))
echo "Waiting... ($timeout seconds remaining)"
info "Waiting... ($timeout seconds remaining)"
sleep 1
done

if [ "$timeout" -le 0 ]; then
echo "Error: Docker daemon failed to start"
error "Docker daemon failed to start"
exit 1
fi

# Execute test script with strict shell options
exec /bin/sh -euxc ". $test_script"
# Maybe start a registry proxy
init_registry_proxy

exec "$cmd"
}

# Initialize and manage a K3s-in-Docker environment.
# Arguments:
# $1: Path to the test script (already validated)
init_k3s_in_docker() {
test_script="$1"
cmd="$1"

# Ensure required environment variables are set
if [ -z "${POD_NAME-}" ] || [ -z "${POD_NAMESPACE-}" ]; then
echo "Error: POD_NAME and POD_NAMESPACE environment variables must be set"
error "POD_NAME and POD_NAMESPACE environment variables must be set"
exit 1
fi

echo "Waiting for pod ${POD_NAME} to be ready..."
if ! kubectl wait --for=condition=Ready=true pod/${POD_NAME} -n "${POD_NAMESPACE}" --timeout=60s; then
echo "Error: Pod ${POD_NAME} failed to become ready"
info "Waiting for pod ${POD_NAME} to be ready..."
if ! kubectl wait --for=condition=Ready=true pod/"${POD_NAME}" -n "${POD_NAMESPACE}" --timeout=60s; then
error "Pod ${POD_NAME} failed to become ready"
exit 1
fi

# Execute test script with strict shell options
exec /bin/sh -euxc ". $test_script"
exec "$cmd"
}

# Validate command-line arguments
if [ $# -ne 1 ]; then
usage
fi

test_script="$1"
cmd="$1"

# Make sure IMAGETEST_DRIVER is set
if [ -z "${IMAGETEST_DRIVER-}" ]; then
echo "Error: IMAGETEST_DRIVER environment variable not set"
error "IMAGETEST_DRIVER environment variable not set"
usage
fi

# Validate the test script first, regardless of driver
validate_test_script "$test_script"
validate_cmd "$cmd"

# Initialize the appropriate driver
case "$IMAGETEST_DRIVER" in
docker_in_docker)
init_docker_in_docker "$test_script"
init_docker_in_docker "$cmd"
;;
k3s_in_docker)
init_k3s_in_docker "$test_script"
init_k3s_in_docker "$cmd"
;;
*)
echo "Error: Unknown driver '$IMAGETEST_DRIVER'"
error "Unknown driver '$IMAGETEST_DRIVER'"
usage
;;
esac
2 changes: 2 additions & 0 deletions internal/provider/tests_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ func (t *TestsResource) do(ctx context.Context, data *TestsResourceModel) (ds di
}
envs["IMAGES"] = string(imgsResolvedData)
envs["IMAGETEST_DRIVER"] = string(data.Driver)
envs["IMAGETEST_REGISTRY"] = t.repo.RegistryStr()
envs["IMAGETEST_REPO"] = t.repo.String()

if os.Getenv("IMAGETEST_SKIP_TEARDOWN_ON_FAILURE") != "" || os.Getenv("IMAGETEST_SKIP_TEARDOWN") != "" {
envs["IMAGETEST_PAUSE_ON_ERROR"] = "true"
Expand Down

0 comments on commit a86196e

Please sign in to comment.