From 39bdedab9c218ca1e4eb7204e7c1dd085be98635 Mon Sep 17 00:00:00 2001 From: Olcan Date: Mon, 21 Apr 2025 07:50:18 -0700 Subject: [PATCH] seamless sandboxing (just set GEMINI_CODE_SANDBOX=true in .env) (#76) --- package.json | 4 +- scripts/build.sh | 16 ++++++ scripts/build_container.sh | 23 --------- scripts/build_sandbox.sh | 51 +++++++++++++++++++ scripts/clean.sh | 6 +++ scripts/start.sh | 11 +++- .../{start_container.sh => start_sandbox.sh} | 6 ++- 7 files changed, 89 insertions(+), 28 deletions(-) create mode 100755 scripts/build.sh delete mode 100755 scripts/build_container.sh create mode 100755 scripts/build_sandbox.sh create mode 100755 scripts/clean.sh rename scripts/{start_container.sh => start_sandbox.sh} (57%) diff --git a/package.json b/package.json index b0d56370..f7011298 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "packages/*" ], "scripts": { - "build": "npm run build --workspaces", - "clean": "rm -rf node_modules && npm run clean --workspaces", + "build": "scripts/build.sh", + "clean": "scripts/clean.sh", "test": "npm run test --workspaces", "start": "scripts/start.sh", "debug": "scripts/debug.sh", diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 00000000..f4f4ce91 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail + +# npm install if node_modules was removed (e.g. via npm run clean or scripts/clean.sh) +if [ ! -d "node_modules" ]; then + npm install +fi + +# build all workspaces/packages +npm run build --workspaces + +# also build container image if GEMINI_CODE_SANDBOX is set (can be in .env file) +# skip (-s) npm install + build since we did that above +if [[ "${GEMINI_CODE_SANDBOX:-}" =~ ^(1|true)$ ]] || grep -qiE '^GEMINI_CODE_SANDBOX *= *(1|true)' .env; then + scripts/build_sandbox.sh -s +fi diff --git a/scripts/build_container.sh b/scripts/build_container.sh deleted file mode 100755 index a4247d46..00000000 --- a/scripts/build_container.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -euo pipefail - -IMAGE=gemini-code-sandbox - -# use docker if installed, otherwise try to use podman instead -if command -v docker &> /dev/null; then - CMD=docker -elif command -v podman &> /dev/null; then - CMD=podman -else - echo "ERROR: docker or podman must be installed" - exit 1 -fi - -npm install -npm run build -rm -f packages/cli/dist/gemini-code-cli-*.tgz -npm pack -w @gemini-code/cli --pack-destination ./packages/cli/dist -rm -f packages/server/dist/gemini-code-server-*.tgz -npm pack -w @gemini-code/server --pack-destination ./packages/server/dist - -$CMD build -t "$IMAGE" . \ No newline at end of file diff --git a/scripts/build_sandbox.sh b/scripts/build_sandbox.sh new file mode 100755 index 00000000..a34679e9 --- /dev/null +++ b/scripts/build_sandbox.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -euo pipefail + +IMAGE=gemini-code-sandbox + +SKIP_NPM_INSTALL_BUILD=false +while getopts "s" opt; do + case ${opt} in + s) SKIP_NPM_INSTALL_BUILD=true ;; + \?) + echo "usage: $(basename "$0") [-s]" + echo " -s: skip npm install + npm run build" + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +# use docker if installed, otherwise try to use podman instead +if command -v docker &> /dev/null; then + CMD=docker +elif command -v podman &> /dev/null; then + CMD=podman +else + echo "ERROR: missing docker or podman for sandboxing" + exit 1 +fi +echo "using $CMD for sandboxing" + +# npm install + npm run build unless skipping via -s option +if [ "$SKIP_NPM_INSTALL_BUILD" = false ]; then + npm install + npm run build +fi + +# pack cli +echo "packing @gemini-code/cli ..." +rm -f packages/cli/dist/gemini-code-cli-*.tgz +npm pack -w @gemini-code/cli --pack-destination ./packages/cli/dist &> /dev/null + +# pack server +echo "packing @gemini-code/server ..." +rm -f packages/server/dist/gemini-code-server-*.tgz +npm pack -w @gemini-code/server --pack-destination ./packages/server/dist &> /dev/null + +# build container image & prune older unused images +# use empty --authfile to skip unnecessary auth refresh overhead +echo "building $IMAGE ... (can be slow first time)" +$CMD build --authfile <(echo '{}') -t "$IMAGE" . >/dev/null +$CMD image prune -f +echo "built $IMAGE" \ No newline at end of file diff --git a/scripts/clean.sh b/scripts/clean.sh new file mode 100755 index 00000000..1e523087 --- /dev/null +++ b/scripts/clean.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euo pipefail + +# remove npm install/build artifacts +rm -rf node_modules +npm run clean --workspaces diff --git a/scripts/start.sh b/scripts/start.sh index b85a8af0..2c24c61d 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -1,5 +1,14 @@ #!/bin/bash set -euo pipefail +# check build status, write warnings to file for app to display if needed node ./scripts/check-build-status.js -node node_modules/@gemini-code/cli "$@" \ No newline at end of file + +# if GEMINI_CODE_SANDBOX is set (can be in .env file), start in sandbox container +if [[ "${GEMINI_CODE_SANDBOX:-}" =~ ^(1|true)$ ]] || grep -qiE '^GEMINI_CODE_SANDBOX *= *(1|true)' .env; then + echo "Running in sandbox container ..." + scripts/start_sandbox.sh "$@" +else + echo "WARNING: running outside of sandbox. Set GEMINI_CODE_SANDBOX to enable sandbox." + node node_modules/@gemini-code/cli "$@" +fi \ No newline at end of file diff --git a/scripts/start_container.sh b/scripts/start_sandbox.sh similarity index 57% rename from scripts/start_container.sh rename to scripts/start_sandbox.sh index dbdd305d..64964600 100755 --- a/scripts/start_container.sh +++ b/scripts/start_sandbox.sh @@ -11,8 +11,10 @@ if command -v docker &> /dev/null; then elif command -v podman &> /dev/null; then CMD=podman else - echo "ERROR: docker or podman must be installed" + echo "ERROR: missing docker or podman for sandboxing" exit 1 fi -$CMD run -it --rm -v"$PWD:$WORKDIR" --workdir "$WORKDIR" "$IMAGE" node "$CLI_DIST" \ No newline at end of file +# run gemini-code in sandbox container +# use empty --authfile to skip unnecessary auth refresh overhead +$CMD run -it --rm --authfile <(echo '{}') -v"$PWD:$WORKDIR" --workdir "$WORKDIR" "$IMAGE" node "$CLI_DIST" \ No newline at end of file