104 lines
3.0 KiB
Bash
Executable File
104 lines
3.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# Copyright 2025 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
set -euo pipefail
|
|
|
|
if ! scripts/sandbox_command.sh -q; then
|
|
echo "ERROR: sandboxing disabled. See docs to enable sandboxing."
|
|
exit 1
|
|
fi
|
|
|
|
# parse flags
|
|
interactive=false
|
|
while getopts "i" opt; do
|
|
case "$opt" in
|
|
\?)
|
|
echo "usage: sandbox.sh [-i] [sandbox-name-or-index = AUTO] [command... = bash -l]"
|
|
echo " -i: enable interactive mode for custom command (enabled by default for login shell)"
|
|
echo " (WARNING: interactive mode causes stderr to be redirected to stdout)"
|
|
exit 1
|
|
;;
|
|
i)
|
|
interactive=true
|
|
if [ ! -t 0 ]; then
|
|
echo "ERROR: interactive mode (-i) requested without a terminal attached"
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
IMAGE=gemini-cli-sandbox
|
|
CMD=$(scripts/sandbox_command.sh)
|
|
|
|
# list all containers running on sandbox image
|
|
sandboxes=()
|
|
while IFS= read -r line; do
|
|
sandboxes+=("$line")
|
|
done < <($CMD ps --filter "ancestor=$IMAGE" --format "{{.Names}}")
|
|
|
|
# take first argument as sandbox name if it starts with image name or is an integer
|
|
# otherwise require a unique sandbox to be running and take its name
|
|
if [[ "${1:-}" =~ ^$IMAGE(-[0-9]+)?$ ]]; then
|
|
SANDBOX=$1
|
|
shift
|
|
elif [[ "${1:-}" =~ ^[0-9]+$ ]]; then
|
|
SANDBOX=$IMAGE-$1
|
|
shift
|
|
else
|
|
# exit if no sandbox is running
|
|
if [ ${#sandboxes[@]} -eq 0 ]; then
|
|
echo "No sandboxes found. Are you running gemini-cli with sandboxing enabled?"
|
|
exit 1
|
|
fi
|
|
# exit if multiple sandboxes are running
|
|
if [ ${#sandboxes[@]} -gt 1 ]; then
|
|
echo "Multiple sandboxes found:"
|
|
for sandbox in "${sandboxes[@]}"; do
|
|
echo " $sandbox"
|
|
done
|
|
echo "Sandbox name or index (0,1,...) must be specified as first argument"
|
|
exit 1
|
|
fi
|
|
SANDBOX=${sandboxes[0]}
|
|
fi
|
|
|
|
# check that sandbox exists
|
|
if ! [[ " ${sandboxes[*]} " == *" $SANDBOX "* ]]; then
|
|
echo "unknown sandbox $SANDBOX"
|
|
echo "known sandboxes:"
|
|
for sandbox in "${sandboxes[@]}"; do
|
|
echo " $sandbox"
|
|
done
|
|
exit 1
|
|
fi
|
|
|
|
# determine command and args for exec
|
|
if [ $# -gt 0 ]; then
|
|
cmd=(bash -l -c "$(printf '%q ' "$@")") # fixes quoting, e.g. bash -c 'echo $SANDBOX'
|
|
exec_args=()
|
|
if [ "$interactive" = true ]; then
|
|
exec_args=(-it)
|
|
fi
|
|
else
|
|
cmd=(bash -l)
|
|
exec_args=(-it)
|
|
fi
|
|
|
|
# run command in sandbox
|
|
exec_args+=("$SANDBOX" "${cmd[@]}")
|
|
$CMD exec "${exec_args[@]}"
|