Files
ccc/entrypoint.sh
T
2026-11-05 19:49:53 +05:00

65 lines
1.9 KiB
Bash
Executable File

#!/bin/sh
# Prepend the sandbox system prompt so Claude knows it is containerised and asks
# the user to run host-side commands. Skipped for subcommands and for
# --help/--version, which do not take the flag.
#
# With CCC_DIND=1 (and --privileged), a Docker daemon is started inside the
# container first so Claude gets its own docker, isolated from the host's.
set -e
PROMPT_FILE=/etc/ccc/sandbox-prompt.md
DIND_PROMPT_FILE=/etc/ccc/sandbox-prompt-dind.md
DIND_LOG=/var/log/dockerd.log
start_dind() {
# cgroup v2: move ourselves out of the root cgroup and delegate all
# controllers, otherwise dockerd cannot create cgroups for its containers.
# Same trick as the official docker:dind entrypoint.
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
mkdir -p /sys/fs/cgroup/init
xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs 2>/dev/null || :
sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
> /sys/fs/cgroup/cgroup.subtree_control 2>/dev/null || :
fi
dockerd > "$DIND_LOG" 2>&1 &
i=0
until docker info > /dev/null 2>&1; do
i=$((i + 1))
if [ "$i" -ge 30 ] || ! kill -0 "$!" 2>/dev/null; then
echo "ccc: dockerd failed to start (is the container --privileged?). Last log lines:" >&2
tail -n 20 "$DIND_LOG" >&2
return 1
fi
sleep 1
done
}
DIND_OK=
if [ "$CCC_DIND" = 1 ]; then
if start_dind; then
DIND_OK=1
else
echo "ccc: continuing without docker-in-docker" >&2
fi
fi
case "$1" in
agents|attach|auth|auto-mode|doctor|gateway|import|install|logs|mcp|plugin|plugins|project|respawn|rm|setup-token|stop|kill|ultrareview|update|upgrade|-h|--help|-v|--version)
exec claude "$@"
;;
esac
if [ -r "$PROMPT_FILE" ]; then
PROMPT="$(cat "$PROMPT_FILE")"
if [ -n "$DIND_OK" ] && [ -r "$DIND_PROMPT_FILE" ]; then
PROMPT="$PROMPT
$(cat "$DIND_PROMPT_FILE")"
fi
exec claude --append-system-prompt "$PROMPT" "$@"
fi
exec claude "$@"