Skip to content

Commit d1d387a

Browse files
committed
feat: podman kubedock enhancement
Signed-off-by: Mattia Mascia <[email protected]>
1 parent 4a1e80b commit d1d387a

File tree

6 files changed

+301
-3
lines changed

6 files changed

+301
-3
lines changed

base/ubi9/Dockerfile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,14 @@ RUN KUBEDOCK_ARCH="linux_amd64" && \
145145
COPY --chown=0:0 kubedock_setup.sh /usr/local/bin/kubedock_setup
146146

147147
# Configure Podman wrapper
148-
ENV PODMAN_WRAPPER_PATH=/usr/bin/podman.wrapper
149-
ENV ORIGINAL_PODMAN_PATH=/usr/bin/podman.orig
148+
COPY --chown=0:0 kubedock_setup.sh /usr/local/bin/kubedock_setup
149+
ENV PODMAN_WRAPPER_PATH=/usr/bin/podman.wrapper \
150+
ORIGINAL_PODMAN_PATH=/usr/bin/podman.orig
150151
COPY --chown=0:0 podman-wrapper.sh "${PODMAN_WRAPPER_PATH}"
152+
COPY --chown=0:0 podman-compose-down-wrapper.sh "/usr/bin/podman-compose-down-wrapper.sh"
153+
COPY --chown=0:0 podman-interactive-wrapper.sh "/usr/bin/podman-interactive-wrapper.sh"
151154
RUN mv /usr/bin/podman "${ORIGINAL_PODMAN_PATH}"
155+
COPY --chown=0:0 docker.sh "/usr/bin/docker"
152156

153157
COPY --chown=0:0 entrypoint.sh /
154158
COPY --chown=0:0 .stow-local-ignore /home/tooling/

base/ubi9/docker.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/sh
2+
3+
[ -e /etc/containers/nodocker ] || \
4+
echo "Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg." >&2
5+
if [ "${KUBEDOCK_ENABLED:-false}" = "true" ]; then
6+
exec /usr/bin/podman.wrapper "$@"
7+
else
8+
exec /usr/bin/podman "$@"
9+
fi

base/ubi9/kubedock_setup.sh

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,28 @@ if [ "${KUBEDOCK_ENABLED:-false}" = "true" ]; then
2525
if [ -f $KUBECONFIG ]; then
2626
echo "Kubeconfig found."
2727

28-
KUBEDOCK_PARAMS=${KUBEDOCK_PARAMS:-"--reverse-proxy --kubeconfig $KUBECONFIG"}
28+
echo "Fix Kubeconfig permission."
29+
attempts=5
30+
while [ $attempts -gt 0 ]; do
31+
if [ -f /home/user/.kube/config ]; then
32+
chmod 600 /home/user/.kube/config
33+
break
34+
else
35+
echo "Config file not found. Retrying..."
36+
attempts=$((attempts - 1))
37+
sleep 5
38+
fi
39+
done
40+
41+
if [ -z "$KUBEDOCK_PARAMS" ]; then
42+
KUBEDOCK_PARAMS="--reverse-proxy --kubeconfig $KUBECONFIG"
43+
if [ -n "$REQUEST_CPU" ] && [ -n "$REQUEST_MEMORY" ]; then
44+
KUBEDOCK_PARAMS="$KUBEDOCK_PARAMS --request-cpu=$REQUEST_CPU --request-memory=$REQUEST_MEMORY"
45+
fi
46+
if [ -n "$REAPER_KEEPMAX" ]; then
47+
KUBEDOCK_PARAMS="$KUBEDOCK_PARAMS --reapmax=$REAPER_KEEPMAX"
48+
fi
49+
fi
2950

3051
echo "Starting kubedock with params \"${KUBEDOCK_PARAMS}\"..."
3152

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# This script is a wrapper for 'podman compose down' or 'docker compose down'
5+
# It removes the containers/services defined in the docker-compose file using 'podman rm'
6+
# This is needed when running with kubedock, as 'compose down' cannot shut down pods directly
7+
8+
usage() {
9+
echo "Usage: $0 [OPTIONS] [SERVICES]"
10+
echo " OPTIONS: Options for docker-compose down (e.g., -f docker-compose.yml)"
11+
echo " SERVICES: Optional list of services to remove"
12+
exit 1
13+
}
14+
15+
# Parse options and service names
16+
COMPOSE_FILE="docker-compose.yml"
17+
OPTIONS=()
18+
SERVICES=()
19+
while [[ $# -gt 0 ]]; do
20+
case "$1" in
21+
-f|--file)
22+
if [[ -n "${2:-}" ]]; then
23+
COMPOSE_FILE="$2"
24+
OPTIONS+=("$1" "$2")
25+
shift 2
26+
else
27+
echo "Error: Missing argument for $1"
28+
usage
29+
fi
30+
;;
31+
--file=*)
32+
COMPOSE_FILE="${1#*=}"
33+
OPTIONS+=("$1")
34+
shift
35+
;;
36+
-h|--help)
37+
usage
38+
;;
39+
-*)
40+
OPTIONS+=("$1")
41+
shift
42+
;;
43+
*)
44+
SERVICES+=("$1")
45+
shift
46+
;;
47+
esac
48+
done
49+
50+
# If no -f/--file was provided, support both docker-compose.yml and docker-compose.yaml
51+
if [[ "${COMPOSE_FILE}" == "docker-compose.yml" ]]; then
52+
if [[ -f "docker-compose.yml" ]]; then
53+
COMPOSE_FILE="docker-compose.yml"
54+
elif [[ -f "docker-compose.yaml" ]]; then
55+
COMPOSE_FILE="docker-compose.yaml"
56+
else
57+
echo "Error: No docker-compose.yml or docker-compose.yaml found in the current directory."
58+
exit 1
59+
fi
60+
fi
61+
62+
if [[ ! -f "$COMPOSE_FILE" ]]; then
63+
echo "Error: Compose file '$COMPOSE_FILE' not found."
64+
exit 1
65+
fi
66+
67+
# Get service names from compose file if none specified
68+
if [[ ${#SERVICES[@]} -eq 0 ]]; then
69+
# Try to use yq if available, else fallback to grep/sed/awk
70+
if command -v yq >/dev/null 2>&1; then
71+
mapfile -t SERVICES < <(yq '.services | keys | .[]' "$COMPOSE_FILE")
72+
else
73+
# Fallback: extract service names by finding top-level keys under 'services:'
74+
mapfile -t SERVICES < <(awk '/services:/ {flag=1; next} /^[^[:space:]]/ {flag=0} flag && /^[[:space:]]+[a-zA-Z0-9_-]+:/ {gsub(":",""); print $1}' "$COMPOSE_FILE" | sed 's/^[[:space:]]*//')
75+
fi
76+
fi
77+
78+
if [[ ${#SERVICES[@]} -eq 0 ]]; then
79+
echo "No services found in compose file '$COMPOSE_FILE'."
80+
exit 0
81+
fi
82+
83+
# Compose container name: <current-dir>-<service-name>-1
84+
PROJECT_NAME="$(basename "$PWD")"
85+
86+
echo "Removing services: ${SERVICES[*]}"
87+
for svc in "${SERVICES[@]}"; do
88+
# Try to get container_name from compose file
89+
CONTAINER_NAME=""
90+
if command -v yq >/dev/null 2>&1; then
91+
CONTAINER_NAME=$(yq ".services.${svc}.container_name // \"\"" "$COMPOSE_FILE" | tr -d '"')
92+
fi
93+
if [[ -z "$CONTAINER_NAME" ]]; then
94+
CONTAINER_NAME="${PROJECT_NAME}-${svc}-1"
95+
fi
96+
# Check if the container exists
97+
if ! podman ps -a --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
98+
echo "No container found for service '$svc' (expected name: $CONTAINER_NAME)"
99+
continue
100+
fi
101+
echo "Removing container: $CONTAINER_NAME"
102+
podman rm -f "$CONTAINER_NAME"
103+
done
104+
105+
echo "All specified services have been removed."
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# This script transparently replaces problematic 'podman run -it ...' invocations
5+
# with a workaround for kubedock compatibility:
6+
# podman exec -it $(podman run -d --rm [OPTIONS] IMAGE tail -f /dev/null) [COMMAND]
7+
8+
usage() {
9+
echo "Usage: $0 run [OPTIONS] IMAGE [COMMAND] [ARG...]"
10+
exit 1
11+
}
12+
13+
ARGS=( "$@" )
14+
if [[ "${ARGS[0]:-}" != "run" ]]; then
15+
usage
16+
fi
17+
18+
RUN_OPTS=()
19+
IMAGE=""
20+
CMD_ARGS=()
21+
22+
skip_next=0
23+
found_image=0
24+
for ((i=1; i<${#ARGS[@]}; i++)); do
25+
arg="${ARGS[$i]}"
26+
if [[ $skip_next -eq 1 ]]; then
27+
# Only skip for --tty/--interactive with space value
28+
RUN_OPTS+=("$arg")
29+
skip_next=0
30+
continue
31+
fi
32+
if [[ $found_image -eq 0 ]]; then
33+
# Remove all forms of interactive/tty options for internal run
34+
case "$arg" in
35+
-i|-t|-it|-ti)
36+
continue
37+
;;
38+
--tty|--interactive)
39+
# skip this and the next arg if it does not start with '-'
40+
if [[ $((i+1)) -lt ${#ARGS[@]} && "${ARGS[$((i+1))]}" != "-"* ]]; then
41+
skip_next=1
42+
fi
43+
continue
44+
;;
45+
--tty=*|--interactive=*)
46+
continue
47+
;;
48+
# Options that take a value
49+
-u|--user)
50+
RUN_OPTS+=("$arg")
51+
RUN_OPTS+=("$(id -u)")
52+
skip_next=1
53+
continue
54+
;;
55+
--user=*)
56+
RUN_OPTS+=("--user=$(id -u)")
57+
continue
58+
;;
59+
-v|--volume|-e|--env|-w|--workdir|--name|--hostname|--entrypoint|--add-host|--device|--label|--network|--cap-add|--cap-drop|--security-opt|--tmpfs|--ulimit|--mount|--publish|--expose|--dns|--dns-search|--dns-option|--mac-address|--memory|--memory-swap|--cpu-shares|--cpus|--cpu-period|--cpu-quota|--cpu-rt-runtime|--cpu-rt-period|--cpuset-cpus|--cpuset-mems|--blkio-weight|--blkio-weight-device|--device-read-bps|--device-write-bps|--device-read-iops|--device-write-iops|--shm-size|--sysctl|--log-driver|--log-opt|--restart|--stop-signal|--stop-timeout|--health-cmd|--health-interval|--health-retries|--health-timeout|--health-start-period|--userns|--cgroup-parent|--pid|--ipc|--uts|--runtime|--storage-opt|--tmpfs|--volume-driver|--volumes-from|--env-file|--add-host|--security-opt|--device|--group-add|--init|--isolation|--kernel-memory|--label|--log-driver|--log-opt|--memory-reservation|--memory-swappiness|--oom-kill-disable|--oom-score-adj|--pids-limit|--privileged|--publish-all|--read-only|--restart|--sig-proxy|--stop-signal|--tmpfs|--ulimit|--userns|--uts|--volume|--workdir)
60+
RUN_OPTS+=("$arg")
61+
skip_next=1
62+
continue
63+
;;
64+
--*=*)
65+
# long option with value, e.g. --workdir=/foo
66+
# filter out --tty= and --interactive=
67+
if [[ "$arg" == --tty=* || "$arg" == --interactive=* ]]; then
68+
continue
69+
fi
70+
if [[ "$arg" == --user=* ]]; then
71+
RUN_OPTS+=("--user=$(id -u)")
72+
continue
73+
fi
74+
RUN_OPTS+=("$arg")
75+
continue
76+
;;
77+
--)
78+
found_image=1
79+
continue
80+
;;
81+
-*)
82+
# Handle combined short options, e.g. -itv, -tiv, etc.
83+
# Remove i and t, keep the rest
84+
if [[ "$arg" =~ ^-([it]+)$ ]]; then
85+
# skip if only i/t/it/ti
86+
continue
87+
elif [[ "$arg" =~ ^-([it]+)(.+)$ ]]; then
88+
rest="${BASH_REMATCH[2]}"
89+
if [[ -n "$rest" ]]; then
90+
RUN_OPTS+=("-$rest")
91+
fi
92+
continue
93+
else
94+
RUN_OPTS+=("$arg")
95+
continue
96+
fi
97+
;;
98+
*)
99+
IMAGE="$arg"
100+
found_image=1
101+
continue
102+
;;
103+
esac
104+
else
105+
CMD_ARGS+=("$arg")
106+
fi
107+
done
108+
# Remove duplicate --rm if present
109+
has_rm=0
110+
for opt in "${RUN_OPTS[@]}"; do
111+
if [[ "$opt" == "--rm" ]]; then
112+
has_rm=1
113+
break
114+
fi
115+
done
116+
117+
118+
FINAL_RUN_OPTS=("${RUN_OPTS[@]}")
119+
if [[ $has_rm -eq 0 ]]; then
120+
FINAL_RUN_OPTS+=("--rm")
121+
fi
122+
123+
if [[ -z "$IMAGE" ]]; then
124+
echo "Error: Could not determine image name in podman run command."
125+
usage
126+
fi
127+
128+
# Print the command for debug
129+
# echo podman run -d "${FINAL_RUN_OPTS[@]}" "$IMAGE" tail -f /dev/null
130+
131+
CONTAINER_ID=$(podman run -d "${FINAL_RUN_OPTS[@]}" "$IMAGE" tail -f /dev/null)
132+
133+
if [[ ${#CMD_ARGS[@]} -eq 0 ]]; then
134+
CMD_ARGS=(bash)
135+
fi
136+
137+
exec podman exec -it "$CONTAINER_ID" "${CMD_ARGS[@]}"
138+
cd ..

base/ubi9/podman-wrapper.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ KUBEDOCK_SUPPORTED_COMMANDS=${KUBEDOCK_SUPPORTED_COMMANDS:-"run ps exec cp logs
66

77
PODMAN_ARGS=( "$@" )
88

9+
# Check for 'compose down' command and delegate to the special wrapper
10+
if [[ "${PODMAN_ARGS[0]:-}" == "compose" && "${PODMAN_ARGS[1]:-}" == "down" ]]; then
11+
# Forward all args after 'compose down' to the wrapper
12+
exec "/usr/bin/podman-compose-down-wrapper.sh" "${PODMAN_ARGS[@]:2}"
13+
fi
14+
15+
# Intercept 'podman run' with interactive/tty flags and delegate to the interactive wrapper
16+
if [[ "${PODMAN_ARGS[0]:-}" == "run" ]]; then
17+
has_interactive=0
18+
has_tty=0
19+
for arg in "${PODMAN_ARGS[@]}"; do
20+
case "$arg" in
21+
-i|--interactive) has_interactive=1 ;;
22+
-t|--tty) has_tty=1 ;;
23+
esac
24+
done
25+
if [[ $has_interactive -eq 1 && $has_tty -eq 1 ]]; then
26+
exec "/usr/bin/podman-interactive-wrapper.sh" "${PODMAN_ARGS[@]}"
27+
fi
28+
fi
29+
930
TRUE=0
1031
FALSE=1
1132

0 commit comments

Comments
 (0)