summaryrefslogtreecommitdiff
path: root/scripts/build_sandbox.sh
blob: 4366cd45ef0a9415e7780b81b3ba0ac10acb1082 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/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

# exit with warning if container-based sandboxing is disabled
# note this includes the case where sandbox-exec (seatbelt) is used
# this happens most commonly when user runs `npm run build:all` without enabling sandboxing
if ! scripts/sandbox_command.sh -q || [ "$(scripts/sandbox_command.sh)" == "sandbox-exec" ]; then
    echo "WARNING: container-based sandboxing is disabled (see README.md#sandboxing)"
    exit 0
fi

CMD=$(scripts/sandbox_command.sh)
echo "using $CMD for sandboxing"

BASE_IMAGE=gemini-cli-sandbox
CUSTOM_IMAGE=''
BASE_DOCKERFILE=Dockerfile
CUSTOM_DOCKERFILE=''

SKIP_NPM_INSTALL_BUILD=false
while getopts "sf:i:" opt; do
    case ${opt} in
    s) SKIP_NPM_INSTALL_BUILD=true ;;
    f)
        CUSTOM_DOCKERFILE=$OPTARG
        ;;
    i)
        CUSTOM_IMAGE=$OPTARG
        ;;
    \?)
        echo "usage: $(basename "$0") [-s] [-f <dockerfile>]"
        echo "  -s: skip npm install + npm run build"
        echo "  -f <dockerfile>: use <dockerfile> for custom image"
        echo "  -i <image>: use <image> name for custom image"
        exit 1
        ;;
    esac
done
shift $((OPTIND - 1))

# npm install + npm run build unless skipping via -s option
if [ "$SKIP_NPM_INSTALL_BUILD" = false ]; then
    npm install
    npm run build --workspaces
fi

# prepare global installation files for prod builds
# 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 core
echo "packing @gemini-code/core ..."
rm -f packages/core/dist/gemini-code-core-*.tgz
npm pack -w @gemini-code/core --pack-destination ./packages/core/dist &>/dev/null
# give node user (used during installation, see Dockerfile) access to these files
chmod 755 packages/*/dist/gemini-code-*.tgz

# redirect build output to /dev/null unless VERBOSE is set
BUILD_STDOUT="/dev/null"
if [ -n "${VERBOSE:-}" ]; then
    BUILD_STDOUT="/dev/stdout"
fi

# initialize build arg array from BUILD_SANDBOX_FLAGS
read -r -a build_args <<<"${BUILD_SANDBOX_FLAGS:-}"

build_image() {
    local -n build_args=$1

    if [[ "$CMD" == "podman" ]]; then
        # use empty --authfile to skip unnecessary auth refresh overhead
        $CMD build --authfile=<(echo '{}') "${build_args[@]}" >$BUILD_STDOUT
    elif [[ "$CMD" == "docker" ]]; then
        # use config directory to skip unnecessary auth refresh overhead
        $CMD --config=".docker" buildx build "${build_args[@]}" >$BUILD_STDOUT
    else
        $CMD build "${build_args[@]}" >$BUILD_STDOUT
    fi
}

# build container images & prune older unused images

echo "building $BASE_IMAGE ... (can be slow first time)"
base_image_build_args=(${build_args[@]})
base_image_build_args+=(-f "$BASE_DOCKERFILE" -t "$BASE_IMAGE" .)
build_image base_image_build_args
echo "built $BASE_IMAGE"

if [[ -n "$CUSTOM_DOCKERFILE" && -n "$CUSTOM_IMAGE" ]]; then
    echo "building $CUSTOM_IMAGE ... (can be slow first time)"
    custom_image_build_args=(${build_args[@]})
    custom_image_build_args+=(-f "$CUSTOM_DOCKERFILE" -t "$CUSTOM_IMAGE" .)
    build_image custom_image_build_args
    echo "built $CUSTOM_IMAGE"
fi

$CMD image prune -f >/dev/null