-
Notifications
You must be signed in to change notification settings - Fork 115
Expand file tree
/
Copy pathDockerfile.sandbox
More file actions
126 lines (116 loc) · 8.41 KB
/
Copy pathDockerfile.sandbox
File metadata and controls
126 lines (116 loc) · 8.41 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# Guest image for the agent sandbox microVM (SANDBOX_IMAGE).
#
FROM node:24.21.0-trixie
ARG PLAYWRIGHT_VERSION=1.63.0
# uv 0.12.8 and later segfault under qemu-user x86_64 emulation, which is how
# an arm64 host builds the amd64 platform; 0.12.7 is the newest verified-good
# release, so re-verify a bump there before moving it.
ARG UV_VERSION=0.12.7
ARG PNPM_VERSION=11.24.0
ARG BUN_VERSION=1.4.2
ARG FALLOW_VERSION=3.27.0
ARG RUST_VERSION=1.98.1
ARG GO_VERSION=1.27.1
# Bump TOOLS_CACHEBUST (e.g. via --build-arg) to force a fresh tool install
# without invalidating the rest of the build cache.
ARG TOOLS_CACHEBUST=0
# Shared browser location so the sandbox exec user (SANDBOX_EXEC_USER, default
# "node") can read browsers installed at build time by root.
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
# Lets agent code `require("playwright")` from any working directory without a
# project-local install. Only a resolution fallback; local node_modules wins.
ENV NODE_PATH=/usr/local/lib/node_modules
# msb exec runs commands as a numeric host uid with no /etc/passwd entry, so
# the guest defaults to HOME=/ and every tool that writes per-user state (uv
# and pip caches, git config, gh config, the pnpm store) fails with EACCES.
# PNPM_CONFIG_STORE_DIR pins the pnpm store to a container-internal path:
# pnpm 11 no longer reads npm_config_* env vars, and an unpinned store falls
# back into the bind-mounted project directory, where it floods the host file
# watcher and gets committed.
ENV HOME=/home/ocm-agent
ENV UV_TOOL_BIN_DIR=/opt/agent-tools/bin
ENV PNPM_HOME=/opt/agent-tools
ENV PNPM_CONFIG_STORE_DIR=/home/ocm-agent/.local/share/pnpm/store
ENV RUSTUP_HOME=/usr/local/rustup
ENV CARGO_HOME=/usr/local/cargo
ENV GOBIN=/opt/agent-tools/bin
ENV PATH=/opt/agent-tools:/opt/agent-tools/bin:/usr/local/cargo/bin:/usr/local/go/bin:$PATH
RUN echo "Installing gh and CLI tooling (cachebust=${TOOLS_CACHEBUST})" && \
apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates curl jq less ripgrep sudo tree file procps \
python3-pip python3-venv python-is-python3 \
iproute2 iputils-ping bind9-dnsutils bind9-host net-tools \
netcat-openbsd traceroute lsof rsync && \
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
-o /usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
> /etc/apt/sources.list.d/github-cli.list && \
apt-get update && \
apt-get install -y --no-install-recommends gh && \
rm -rf /var/lib/apt/lists/* && \
rm -f /usr/lib/python3*/EXTERNALLY-MANAGED && \
printf 'Defaults env_keep += "npm_config_prefix"\nALL ALL=(ALL:ALL) NOPASSWD:ALL\n' \
> /etc/sudoers.d/ocm-guest && \
chmod 440 /etc/sudoers.d/ocm-guest && \
visudo -c && \
gh --version
RUN echo "Installing pnpm=${PNPM_VERSION}, bun=${BUN_VERSION}, uv=${UV_VERSION}, fallow=${FALLOW_VERSION} (cachebust=${TOOLS_CACHEBUST})" && \
mkdir -p /home/ocm-agent /opt/agent-tools/bin && \
chmod 1777 /home/ocm-agent /opt/agent-tools /opt/agent-tools/bin && \
npm install -g "pnpm@${PNPM_VERSION}" "fallow@${FALLOW_VERSION}" && \
test "$(pnpm --version)" = "${PNPM_VERSION}" && \
curl -fsSL https://bun.sh/install | BUN_INSTALL=/opt/bun bash -s "bun-v${BUN_VERSION}" && \
chmod -R a+rX /opt/bun && \
ln -sf /opt/bun/bin/bun /opt/bun/bin/bunx && \
ln -s /opt/bun/bin/bun /usr/local/bin/bun && \
ln -s /opt/bun/bin/bun /usr/local/bin/bunx && \
test "$(bun --version)" = "${BUN_VERSION}" && \
curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | UV_INSTALL_DIR=/usr/local/bin UV_NO_MODIFY_PATH=1 sh && \
test "$(uv --version | cut -d' ' -f2)" = "${UV_VERSION}" && \
rm -rf /root/.npm /root/.cache/uv /home/ocm-agent/.cache && \
pnpm --version && bun --version && uv --version && fallow --version | grep -x "fallow ${FALLOW_VERSION}" >/dev/null
RUN echo "Installing rust=${RUST_VERSION} and go=${GO_VERSION} (cachebust=${TOOLS_CACHEBUST})" && \
curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs | \
HOME=/root sh -s -- -y --no-modify-path --profile minimal --default-toolchain "${RUST_VERSION}" && \
test "$(rustc --version | cut -d' ' -f2)" = "${RUST_VERSION}" && \
chmod -R a+w "${RUSTUP_HOME}" "${CARGO_HOME}" && \
curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-$(dpkg --print-architecture).tar.gz" | tar -xzC /usr/local && \
test "$(go version | cut -d' ' -f3)" = "go${GO_VERSION}" && \
cargo --version && go version
RUN echo "Installing playwright=${PLAYWRIGHT_VERSION} chromium (cachebust=${TOOLS_CACHEBUST})" && \
npm install -g "playwright@${PLAYWRIGHT_VERSION}" && \
npx --yes "playwright@${PLAYWRIGHT_VERSION}" install --with-deps chromium && \
chmod -R a+rX "${PLAYWRIGHT_BROWSERS_PATH}" && \
rm -rf /var/lib/apt/lists/* /root/.npm && \
npx --yes "playwright@${PLAYWRIGHT_VERSION}" --version
ENV npm_config_prefix=/opt/agent-tools
# The runtime exec user is a numeric host uid with no /etc/passwd entry, so the
# toolchain is verified as uid 4242, which is absent from this image's passwd
# database. uid 1000 would not do: it is the base image's `node` user, so it
# would exercise the known-user path and pass even if the real one were broken.
# sudo is checked separately as that known user, because sudo refuses unknown
# uids by design and the Manager provisions their passwd entry at runtime.
RUN echo "Verifying guest toolchain as an unknown uid (cachebust=${TOOLS_CACHEBUST})" && \
rm -rf /home/ocm-agent && \
mkdir -p /home/ocm-agent && \
chmod 1777 /home/ocm-agent && \
setpriv --reuid=4242 --regid=4242 --clear-groups bash -euo pipefail -c 'pnpm --version; pm_dir=$(mktemp -d); cd "$pm_dir"; printf "%s" "{\"name\":\"pm-pin-check\",\"packageManager\":\"pnpm@10.12.1\"}" > package.json; pnpm --version | grep -x 10.12.1 >/dev/null; cd /; rm -rf "$pm_dir"; bun --version; bunx --version; uv --version; uvx --version; fallow --version | grep -x "fallow ${FALLOW_VERSION}" >/dev/null; playwright --version; gh --version; jq --version; rg --version; npm install -g --silent cowsay; cowsay -t verify-ok | grep verify-ok >/dev/null; git config --global user.email verify@ocm.local; uv venv /tmp/uv-check >/dev/null; uv pip install --python /tmp/uv-check/bin/python idna >/dev/null; pip3 install --user --force-reinstall --no-deps --quiet idna; rm -rf /tmp/uv-check; for tool in python python3 git curl wget ssh rsync lsof ip ss netstat ping dig host nslookup nc traceroute; do if ! command -v "$tool" >/dev/null; then echo "missing guest tool: $tool"; exit 1; fi; done; python --version' && \
setpriv --reuid=4242 --regid=4242 --clear-groups bash -euo pipefail -c 'rs_dir=$(mktemp -d); cargo new --quiet --vcs none "$rs_dir/rs-check"; cargo build --quiet --manifest-path "$rs_dir/rs-check/Cargo.toml"; "$rs_dir/rs-check/target/debug/rs-check" | grep -x "Hello, world!" >/dev/null; rm -rf "$rs_dir"; go_dir=$(mktemp -d); cd "$go_dir"; go mod init go-check >/dev/null 2>&1; printf "package main\nimport \"fmt\"\nfunc main() { fmt.Println(\"go-ok\") }\n" > main.go; go run . | grep -x go-ok >/dev/null; cd /; rm -rf "$go_dir"' && \
setpriv --reuid=1000 --regid=1000 --clear-groups bash -euo pipefail -c 'sudo -n apt-get update -qq; sudo -n apt-get install -y -qq --no-install-recommends bc; bc --version' && \
rm -rf /home/ocm-agent /opt/agent-tools /var/lib/apt/lists/* "${CARGO_HOME}/registry" && \
mkdir -p /home/ocm-agent /opt/agent-tools/bin && \
chmod 1777 /home/ocm-agent /opt/agent-tools /opt/agent-tools/bin
RUN install -m 0755 -d /etc/apt/keyrings && \
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && \
chmod a+r /etc/apt/keyrings/docker.asc && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
> /etc/apt/sources.list.d/docker.list && \
apt-get update && \
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin && \
rm -rf /var/lib/apt/lists/* && \
docker --version && \
docker buildx version && \
docker compose version
COPY --chmod=0755 scripts/sandbox-dockerd-start.sh /usr/local/bin/ocm-dockerd-start