@cloudflare/sandbox 0.12.8 → 0.12.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Dockerfile
CHANGED
|
@@ -5,20 +5,20 @@ ARG NODE_VERSION=24
|
|
|
5
5
|
# cloudflared release — shared across glibc and musl image variants.
|
|
6
6
|
# Bump this together with the architecture-specific checksums below.
|
|
7
7
|
ARG CLOUDFLARED_VERSION=2026.3.0
|
|
8
|
+
# fuse-overlayfs release — backs the copy-on-write layer of restored backups.
|
|
9
|
+
# Pinned upstream because Ubuntu 22.04 ships 1.7.1, which returns EEXIST when
|
|
10
|
+
# a restored directory is deleted, recreated and listed before files are
|
|
11
|
+
# created in it (fixed in 1.15). Switch back to the distro package once the
|
|
12
|
+
# base image ships 1.15 or newer.
|
|
13
|
+
# Bump this together with the architecture-specific checksums below.
|
|
14
|
+
ARG FUSE_OVERLAYFS_VERSION=1.18
|
|
8
15
|
FROM oven/bun:${BUN_VERSION} AS bun-binary
|
|
9
16
|
FROM node:${NODE_VERSION}-slim AS node-runtime
|
|
10
17
|
|
|
11
18
|
# ============================================================================
|
|
12
|
-
#
|
|
13
|
-
# Version pin lives at the top of this Dockerfile as a global ARG, shared
|
|
14
|
-
# by every image variant so they ship the same release.
|
|
19
|
+
# Release downloader — shared base for fetching pinned upstream binaries
|
|
15
20
|
# ============================================================================
|
|
16
|
-
FROM alpine:3.21 AS
|
|
17
|
-
|
|
18
|
-
ARG TARGETARCH
|
|
19
|
-
ARG CLOUDFLARED_VERSION
|
|
20
|
-
ARG CLOUDFLARED_SHA256_AMD64=4a9e50e6d6d798e90fcd01933151a90bf7edd99a0a55c28ad18f2e16263a5c30
|
|
21
|
-
ARG CLOUDFLARED_SHA256_ARM64=0755ba4cbab59980e6148367fcf53a8f3ec85a97deefd63c2420cf7850769bee
|
|
21
|
+
FROM alpine:3.21 AS release-downloader
|
|
22
22
|
|
|
23
23
|
# Inject the host's extra CA bundle when downloading behind a TLS-intercepting
|
|
24
24
|
# proxy (e.g. Cloudflare WARP / Zero Trust). No-op when the secret isn't passed.
|
|
@@ -33,6 +33,18 @@ RUN --mount=type=secret,id=wrangler_ca \
|
|
|
33
33
|
update-ca-certificates; \
|
|
34
34
|
fi
|
|
35
35
|
|
|
36
|
+
# ============================================================================
|
|
37
|
+
# cloudflared (Cloudflare Tunnel daemon) — enables sandbox.tunnels.*
|
|
38
|
+
# Version pin lives at the top of this Dockerfile as a global ARG, shared
|
|
39
|
+
# by every image variant so they ship the same release.
|
|
40
|
+
# ============================================================================
|
|
41
|
+
FROM release-downloader AS cloudflared-binary
|
|
42
|
+
|
|
43
|
+
ARG TARGETARCH
|
|
44
|
+
ARG CLOUDFLARED_VERSION
|
|
45
|
+
ARG CLOUDFLARED_SHA256_AMD64=4a9e50e6d6d798e90fcd01933151a90bf7edd99a0a55c28ad18f2e16263a5c30
|
|
46
|
+
ARG CLOUDFLARED_SHA256_ARM64=0755ba4cbab59980e6148367fcf53a8f3ec85a97deefd63c2420cf7850769bee
|
|
47
|
+
|
|
36
48
|
RUN set -eux; \
|
|
37
49
|
arch="${TARGETARCH:-}"; \
|
|
38
50
|
if [ -z "$arch" ]; then \
|
|
@@ -49,6 +61,32 @@ RUN set -eux; \
|
|
|
49
61
|
chmod +x /cloudflared; \
|
|
50
62
|
/cloudflared --version
|
|
51
63
|
|
|
64
|
+
# ============================================================================
|
|
65
|
+
# fuse-overlayfs — statically linked upstream release for the glibc images
|
|
66
|
+
# ============================================================================
|
|
67
|
+
FROM release-downloader AS fuse-overlayfs-binary
|
|
68
|
+
|
|
69
|
+
ARG TARGETARCH
|
|
70
|
+
ARG FUSE_OVERLAYFS_VERSION
|
|
71
|
+
ARG FUSE_OVERLAYFS_SHA256_AMD64=56b0ae0aeb8abb308b068af2f137ed8d1bd239f4f27e21672ff0def861eea1e8
|
|
72
|
+
ARG FUSE_OVERLAYFS_SHA256_ARM64=82fed736197b2a881a822e5357b488796f654e8371ce8573a1592331510a0133
|
|
73
|
+
|
|
74
|
+
RUN set -eux; \
|
|
75
|
+
arch="${TARGETARCH:-}"; \
|
|
76
|
+
if [ -z "$arch" ]; then \
|
|
77
|
+
arch="$(apk --print-arch)"; \
|
|
78
|
+
fi; \
|
|
79
|
+
case "$arch" in \
|
|
80
|
+
amd64|x86_64) suffix=x86_64; sha="${FUSE_OVERLAYFS_SHA256_AMD64}" ;; \
|
|
81
|
+
arm64|aarch64) suffix=aarch64; sha="${FUSE_OVERLAYFS_SHA256_ARM64}" ;; \
|
|
82
|
+
*) echo "Unsupported arch for fuse-overlayfs: $arch" >&2; exit 1 ;; \
|
|
83
|
+
esac; \
|
|
84
|
+
url="https://github.com/containers/fuse-overlayfs/releases/download/v${FUSE_OVERLAYFS_VERSION}/fuse-overlayfs-${suffix}"; \
|
|
85
|
+
curl -fsSL -o /fuse-overlayfs "$url"; \
|
|
86
|
+
echo "$sha /fuse-overlayfs" | sha256sum -c -; \
|
|
87
|
+
chmod +x /fuse-overlayfs; \
|
|
88
|
+
/fuse-overlayfs --version
|
|
89
|
+
|
|
52
90
|
# Sandbox container images (default and python variants)
|
|
53
91
|
# Multi-stage build optimized for Turborepo monorepo
|
|
54
92
|
|
|
@@ -152,7 +190,6 @@ ENV SANDBOX_VERSION=${SANDBOX_VERSION}
|
|
|
152
190
|
# - fuse3: FUSE filesystem support (replaces legacy fuse, needed by s3fs/squashfuse/fuse-overlayfs)
|
|
153
191
|
# - squashfs-tools: create squashfs archives (mksquashfs)
|
|
154
192
|
# - squashfuse: mount squashfs in userspace (FUSE)
|
|
155
|
-
# - fuse-overlayfs: userspace overlayfs for copy-on-write snapshots
|
|
156
193
|
# Cache-bust: 2 - Clear apt cache to force fresh package list
|
|
157
194
|
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
158
195
|
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
|
@@ -160,7 +197,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
|
160
197
|
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
|
|
161
198
|
rm -rf /var/cache/apt/* /var/lib/apt/lists/* && \
|
|
162
199
|
apt-get update && apt-get install -y --no-install-recommends \
|
|
163
|
-
s3fs fuse3 squashfs-tools squashfuse
|
|
200
|
+
s3fs fuse3 squashfs-tools squashfuse \
|
|
164
201
|
ca-certificates curl wget procps git unzip zip jq file \
|
|
165
202
|
inotify-tools \
|
|
166
203
|
libssl3 zlib1g libbz2-1.0 libreadline8 libsqlite3-0 \
|
|
@@ -173,6 +210,10 @@ RUN sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
|
|
|
173
210
|
# fusermount requires /etc/mtab to locate active mounts
|
|
174
211
|
RUN ln -sf /proc/mounts /etc/mtab
|
|
175
212
|
|
|
213
|
+
# Userspace overlayfs for copy-on-write backup restores
|
|
214
|
+
COPY --from=fuse-overlayfs-binary /fuse-overlayfs /usr/bin/fuse-overlayfs
|
|
215
|
+
RUN fuse-overlayfs --version
|
|
216
|
+
|
|
176
217
|
# Install Node.js from official Node image (defaults to 24 LTS,
|
|
177
218
|
# override via --build-arg NODE_VERSION=<version>)
|
|
178
219
|
COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node
|
package/dist/bridge/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../dist-B_eXrP83.js";
|
|
2
2
|
import "../errors-CpkKPbWC.js";
|
|
3
|
-
import { S as validateTunnelName, r as getSandbox, w as streamFile, x as validatePort, y as SandboxSecurityError } from "../sandbox-
|
|
3
|
+
import { S as validateTunnelName, r as getSandbox, w as streamFile, x as validatePort, y as SandboxSecurityError } from "../sandbox-Co2NYKhX.js";
|
|
4
4
|
import { DurableObject, env, tracing } from "cloudflare:workers";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as isExecResult, f as TraceContext, o as isProcess, s as isProcessStatus, u as createLogger } from "./dist-B_eXrP83.js";
|
|
2
2
|
import "./errors-CpkKPbWC.js";
|
|
3
|
-
import { A as PortClient, B as InvalidBackupConfigError, C as collectFile, D as SandboxClient, E as isPlatformTransientError, F as BackupCreateError, G as SessionTerminatedError, H as ProcessExitedBeforeReadyError, I as BackupExpiredError, L as BackupNotFoundError, M as FileClient, N as CommandClient, O as UtilityClient, P as BackupClient, R as BackupRestoreError, T as isDurableObjectCodeUpdateReset, U as ProcessReadyTimeoutError, V as OperationInterruptedError, W as RPCTransportError, _ as responseToAsyncIterable, a as PREVIEW_PROXY_HEADER, b as sanitizeSandboxId, c as PREVIEW_PROXY_SANDBOX_ID_HEADER, d as BucketUnmountError, f as InvalidMountConfigError, g as parseSSEStream, h as asyncIterableToSSEStream, i as proxyTerminal, j as GitClient, k as ProcessClient, l as PREVIEW_PROXY_TOKEN_HEADER, m as S3FSMountError, n as Sandbox, o as PREVIEW_PROXY_HEADERS, p as MissingCredentialsError, r as getSandbox, s as PREVIEW_PROXY_PORT_HEADER, t as ContainerProxy, u as BucketMountError, v as CodeInterpreter, w as streamFile, x as validatePort, z as ContainerUnavailableError } from "./sandbox-
|
|
3
|
+
import { A as PortClient, B as InvalidBackupConfigError, C as collectFile, D as SandboxClient, E as isPlatformTransientError, F as BackupCreateError, G as SessionTerminatedError, H as ProcessExitedBeforeReadyError, I as BackupExpiredError, L as BackupNotFoundError, M as FileClient, N as CommandClient, O as UtilityClient, P as BackupClient, R as BackupRestoreError, T as isDurableObjectCodeUpdateReset, U as ProcessReadyTimeoutError, V as OperationInterruptedError, W as RPCTransportError, _ as responseToAsyncIterable, a as PREVIEW_PROXY_HEADER, b as sanitizeSandboxId, c as PREVIEW_PROXY_SANDBOX_ID_HEADER, d as BucketUnmountError, f as InvalidMountConfigError, g as parseSSEStream, h as asyncIterableToSSEStream, i as proxyTerminal, j as GitClient, k as ProcessClient, l as PREVIEW_PROXY_TOKEN_HEADER, m as S3FSMountError, n as Sandbox, o as PREVIEW_PROXY_HEADERS, p as MissingCredentialsError, r as getSandbox, s as PREVIEW_PROXY_PORT_HEADER, t as ContainerProxy, u as BucketMountError, v as CodeInterpreter, w as streamFile, x as validatePort, z as ContainerUnavailableError } from "./sandbox-Co2NYKhX.js";
|
|
4
4
|
|
|
5
5
|
//#region src/request-handler.ts
|
|
6
6
|
function createProxyLogger(request) {
|
|
@@ -5322,6 +5322,13 @@ function xmlResponse(body, status = 200) {
|
|
|
5322
5322
|
function normalizeObjectKey(value) {
|
|
5323
5323
|
return value.replace(/^\/+/, "");
|
|
5324
5324
|
}
|
|
5325
|
+
function decodeObjectKey(value) {
|
|
5326
|
+
try {
|
|
5327
|
+
return decodeURIComponent(value);
|
|
5328
|
+
} catch {
|
|
5329
|
+
return value;
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5325
5332
|
function trimTrailingSlashes(s) {
|
|
5326
5333
|
let end = s.length;
|
|
5327
5334
|
while (end > 0 && s[end - 1] === "/") end--;
|
|
@@ -5609,7 +5616,8 @@ const r2EgressHandler = async (request, env$1, ctx) => {
|
|
|
5609
5616
|
const url = new URL(request.url);
|
|
5610
5617
|
const parsed = parsePath(url.pathname);
|
|
5611
5618
|
if (!parsed) return new Response("Bad Request: empty path", { status: 400 });
|
|
5612
|
-
const { bucket: bucketName, key } = parsed;
|
|
5619
|
+
const { bucket: bucketName, key: encodedKey } = parsed;
|
|
5620
|
+
const key = decodeObjectKey(encodedKey);
|
|
5613
5621
|
if (!ctx.params?.buckets || !(bucketName in ctx.params.buckets)) return new Response(`Access to R2 bucket "${bucketName}" is not permitted. Call mountBucket() with this bucket before accessing it.`, { status: 403 });
|
|
5614
5622
|
const bucketParams = ctx.params.buckets[bucketName];
|
|
5615
5623
|
const mountPrefix = normalizeMountPrefix(bucketParams.prefix);
|
|
@@ -5908,6 +5916,10 @@ function isBucketRootProbe(request, realPath, url, bucket) {
|
|
|
5908
5916
|
const method = request.method.toUpperCase();
|
|
5909
5917
|
return (method === "GET" || method === "HEAD") && url.search === "" && getObjectKeyForPath(realPath, bucket) === "";
|
|
5910
5918
|
}
|
|
5919
|
+
function isBucketRootMutation(request, realPath, bucket) {
|
|
5920
|
+
const method = request.method.toUpperCase();
|
|
5921
|
+
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && getObjectKeyForPath(realPath, bucket) === "";
|
|
5922
|
+
}
|
|
5911
5923
|
function deleteDirectoryMarkerCacheEntry(mountId, realPath) {
|
|
5912
5924
|
directoryMarkerCache.delete(getDirectoryMarkerCacheKey(mountId, realPath));
|
|
5913
5925
|
}
|
|
@@ -6031,6 +6043,7 @@ const s3CredentialProxyHandler = async (request, env$1, ctx) => {
|
|
|
6031
6043
|
}
|
|
6032
6044
|
const realUrl = new URL(realPath + (url.search || ""), mount.endpoint);
|
|
6033
6045
|
if (isBucketRootProbe(request, realPath, url, mount.bucket)) return new Response(null, { status: 200 });
|
|
6046
|
+
if (isBucketRootMutation(request, realPath, mount.bucket)) return new Response("Method Not Allowed", { status: 405 });
|
|
6034
6047
|
if (!isRequestWithinMountScope(realPath, url, mount.bucket, mount.prefix)) return new Response("Forbidden: request is outside mounted bucket scope", { status: 403 });
|
|
6035
6048
|
const copySourceError = validateCopySourceWithinMountScope(request.headers, mount.bucket, mount.prefix);
|
|
6036
6049
|
if (copySourceError) return copySourceError;
|
|
@@ -7172,7 +7185,7 @@ function createTunnelsHandler(host) {
|
|
|
7172
7185
|
* This file is auto-updated by .github/changeset-version.ts during releases
|
|
7173
7186
|
* DO NOT EDIT MANUALLY - Changes will be overwritten on the next version bump
|
|
7174
7187
|
*/
|
|
7175
|
-
const SDK_VERSION = "0.12.
|
|
7188
|
+
const SDK_VERSION = "0.12.10";
|
|
7176
7189
|
|
|
7177
7190
|
//#endregion
|
|
7178
7191
|
//#region src/sandbox.ts
|
|
@@ -11553,4 +11566,4 @@ var Sandbox = class Sandbox extends Container {
|
|
|
11553
11566
|
|
|
11554
11567
|
//#endregion
|
|
11555
11568
|
export { PortClient as A, InvalidBackupConfigError as B, collectFile as C, SandboxClient as D, isPlatformTransientError as E, BackupCreateError as F, SessionTerminatedError as G, ProcessExitedBeforeReadyError as H, BackupExpiredError as I, BackupNotFoundError as L, FileClient as M, CommandClient as N, UtilityClient as O, BackupClient as P, BackupRestoreError as R, validateTunnelName as S, isDurableObjectCodeUpdateReset as T, ProcessReadyTimeoutError as U, OperationInterruptedError as V, RPCTransportError as W, responseToAsyncIterable as _, PREVIEW_PROXY_HEADER as a, sanitizeSandboxId as b, PREVIEW_PROXY_SANDBOX_ID_HEADER as c, BucketUnmountError as d, InvalidMountConfigError as f, parseSSEStream as g, asyncIterableToSSEStream as h, proxyTerminal as i, GitClient as j, ProcessClient as k, PREVIEW_PROXY_TOKEN_HEADER as l, S3FSMountError as m, Sandbox as n, PREVIEW_PROXY_HEADERS as o, MissingCredentialsError as p, getSandbox as r, PREVIEW_PROXY_PORT_HEADER as s, ContainerProxy$1 as t, BucketMountError as u, CodeInterpreter as v, streamFile as w, validatePort as x, SandboxSecurityError as y, ContainerUnavailableError as z };
|
|
11556
|
-
//# sourceMappingURL=sandbox-
|
|
11569
|
+
//# sourceMappingURL=sandbox-Co2NYKhX.js.map
|