@decocms/sandbox-controller 0.16.1 → 0.16.3
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/dist/index.d.ts +10 -0
- package/dist/index.js +24 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3730,6 +3730,15 @@ interface FreestyleSandboxProviderOptions {
|
|
|
3730
3730
|
image?: string;
|
|
3731
3731
|
/** The org-fs sidecar image. Default: the chart's `orgFs.image`. */
|
|
3732
3732
|
orgFsSidecarImage?: string;
|
|
3733
|
+
/**
|
|
3734
|
+
* What the daemon signs the bot's commits with, as the sandbox-env chart's
|
|
3735
|
+
* `commitSigning` does for pods. Unset leaves commits unsigned. The key goes
|
|
3736
|
+
* into the base snapshot, so code in any of these sandboxes can read it.
|
|
3737
|
+
*/
|
|
3738
|
+
commitSigning?: {
|
|
3739
|
+
email: string;
|
|
3740
|
+
privateKey: string;
|
|
3741
|
+
};
|
|
3733
3742
|
/** Pause a VM after this long without network activity. Default 5 min. */
|
|
3734
3743
|
idleTimeoutSeconds?: number;
|
|
3735
3744
|
/**
|
|
@@ -3760,6 +3769,7 @@ declare class FreestyleSandboxProvider implements SandboxProvider {
|
|
|
3760
3769
|
private readonly image;
|
|
3761
3770
|
private readonly sidecarImage;
|
|
3762
3771
|
private readonly allowUserNamespaces;
|
|
3772
|
+
private readonly commitSigning;
|
|
3763
3773
|
private readonly idleTimeoutSeconds;
|
|
3764
3774
|
private readonly idlePauseMs;
|
|
3765
3775
|
private readonly autoDeleteSeconds;
|
package/dist/index.js
CHANGED
|
@@ -6804,7 +6804,7 @@ var Freestyle = class {
|
|
|
6804
6804
|
// ../sandbox/package.json
|
|
6805
6805
|
var package_default = {
|
|
6806
6806
|
name: "@decocms/sandbox",
|
|
6807
|
-
version: "1.96.
|
|
6807
|
+
version: "1.96.3",
|
|
6808
6808
|
private: true,
|
|
6809
6809
|
type: "module",
|
|
6810
6810
|
description: "Sandbox runtime for isolated Studio tool execution",
|
|
@@ -6888,6 +6888,8 @@ var DEFAULT_SIDECAR_IMAGE = "ghcr.io/decocms/studio/orgfs-sidecar:0.2.0";
|
|
|
6888
6888
|
var HOST_ORG_DIR = "/srv/sandbox/org";
|
|
6889
6889
|
var HOST_CTL_DIR = "/srv/sandbox/orgfs-ctl";
|
|
6890
6890
|
var CTL_DIR = "/run/orgfs";
|
|
6891
|
+
var HOST_SIGNING_KEY = "/srv/sandbox/git-signing-key";
|
|
6892
|
+
var SIGNING_KEY_FILE = "/run/git-signing/key";
|
|
6891
6893
|
var HOST_SETUP = [
|
|
6892
6894
|
`mkdir -p ${HOST_ORG_DIR} ${HOST_CTL_DIR}`,
|
|
6893
6895
|
`grep -q ' ${HOST_ORG_DIR} ' /etc/fstab || printf '%s\\n' '${HOST_ORG_DIR} ${HOST_ORG_DIR} none bind,rshared 0 0' 'tmpfs ${HOST_CTL_DIR} tmpfs uid=1000,gid=1000,mode=0755,size=1m 0 0' >> /etc/fstab`,
|
|
@@ -6924,6 +6926,7 @@ var FreestyleSandboxProvider = class {
|
|
|
6924
6926
|
image;
|
|
6925
6927
|
sidecarImage;
|
|
6926
6928
|
allowUserNamespaces;
|
|
6929
|
+
commitSigning;
|
|
6927
6930
|
idleTimeoutSeconds;
|
|
6928
6931
|
idlePauseMs;
|
|
6929
6932
|
autoDeleteSeconds;
|
|
@@ -6965,6 +6968,7 @@ var FreestyleSandboxProvider = class {
|
|
|
6965
6968
|
this.image = opts.image ?? `ghcr.io/decocms/studio/studio-sandbox-go:${package_default.version}`;
|
|
6966
6969
|
this.sidecarImage = opts.orgFsSidecarImage ?? DEFAULT_SIDECAR_IMAGE;
|
|
6967
6970
|
this.allowUserNamespaces = opts.allowUserNamespaces ?? false;
|
|
6971
|
+
this.commitSigning = opts.commitSigning;
|
|
6968
6972
|
this.idleTimeoutSeconds = opts.idleTimeoutSeconds ?? 5 * 60;
|
|
6969
6973
|
this.idlePauseMs = opts.idlePauseMs ?? 10 * 6e4;
|
|
6970
6974
|
this.autoDeleteSeconds = opts.autoDeleteSeconds ?? 24 * 60 * 60;
|
|
@@ -7031,9 +7035,13 @@ var FreestyleSandboxProvider = class {
|
|
|
7031
7035
|
baseSnapshot() {
|
|
7032
7036
|
const { image, sidecarImage } = this;
|
|
7033
7037
|
const namespaceMode = this.allowUserNamespaces ? "\nuser-namespaces" : "";
|
|
7038
|
+
const signing = this.commitSigning ? `
|
|
7039
|
+
signing
|
|
7040
|
+
${this.commitSigning.email}
|
|
7041
|
+
${this.commitSigning.privateKey}` : "";
|
|
7034
7042
|
const slug = `studio-sandbox-${createHash3("sha256").update(`${image}
|
|
7035
7043
|
${sidecarImage}
|
|
7036
|
-
running${namespaceMode}`).digest("hex").slice(0, 16)}`;
|
|
7044
|
+
running${namespaceMode}${signing}`).digest("hex").slice(0, 16)}`;
|
|
7037
7045
|
if (this.knownSnapshots.has(slug)) return Promise.resolve(slug);
|
|
7038
7046
|
return this.snapshotInflight.run(slug, async () => {
|
|
7039
7047
|
if (await this.snapshotExists(slug)) {
|
|
@@ -7086,9 +7094,21 @@ running${namespaceMode}`).digest("hex").slice(0, 16)}`;
|
|
|
7086
7094
|
APP_ROOT: WORKDIR,
|
|
7087
7095
|
PROXY_PORT: String(DAEMON_PORT),
|
|
7088
7096
|
ORGFS_SIDECAR_CONFIG_PATH: `${CTL_DIR}/config.json`,
|
|
7089
|
-
ORGFS_SIDECAR_STATUS_PATH: `${CTL_DIR}/status.json
|
|
7097
|
+
ORGFS_SIDECAR_STATUS_PATH: `${CTL_DIR}/status.json`,
|
|
7098
|
+
...this.commitSigning && {
|
|
7099
|
+
GIT_SIGNING_KEY_FILE: SIGNING_KEY_FILE,
|
|
7100
|
+
GIT_SIGNING_KEY_EMAIL: this.commitSigning.email
|
|
7101
|
+
}
|
|
7090
7102
|
};
|
|
7091
7103
|
const envFlags = Object.keys(env).map((k) => `-e ${shellQuote(k)}`).join(" ");
|
|
7104
|
+
if (this.commitSigning) {
|
|
7105
|
+
await this.run(
|
|
7106
|
+
vm,
|
|
7107
|
+
`printf '%s' "$GIT_SIGNING_KEY" | sudo sh -c 'umask 377 && cat > ${HOST_SIGNING_KEY} && chown 1000:1000 ${HOST_SIGNING_KEY}'`,
|
|
7108
|
+
{ env: { GIT_SIGNING_KEY: this.commitSigning.privateKey } }
|
|
7109
|
+
);
|
|
7110
|
+
}
|
|
7111
|
+
const signingKeyMount = this.commitSigning ? ` -v ${HOST_SIGNING_KEY}:${SIGNING_KEY_FILE}:ro` : "";
|
|
7092
7112
|
await this.run(
|
|
7093
7113
|
vm,
|
|
7094
7114
|
`sudo sh -c ${shellQuote(HOST_SETUP)} && docker run -d --name ${SIDECAR} --restart=always --privileged --device /dev/fuse -e APP_ROOT=${WORKDIR} -e ORGFS_FEED_IDLE_MS=60000 -v ${HOST_ORG_DIR}:${WORKDIR}/org:rshared -v ${HOST_CTL_DIR}:${CTL_DIR} ${shellQuote(this.sidecarImage)}`,
|
|
@@ -7097,7 +7117,7 @@ running${namespaceMode}`).digest("hex").slice(0, 16)}`;
|
|
|
7097
7117
|
await this.run(
|
|
7098
7118
|
vm,
|
|
7099
7119
|
// Codex's read-only sandbox uses bubblewrap inside this per-user VM.
|
|
7100
|
-
`docker run -d --name ${CONTAINER} --restart=always${this.allowUserNamespaces ? " --security-opt seccomp=unconfined --security-opt apparmor=unconfined" : ""} -p ${DAEMON_PORT}:${DAEMON_PORT} -v ${HOST_ORG_DIR}:${WORKDIR}/org:rslave -v ${HOST_CTL_DIR}:${CTL_DIR} ${envFlags} ${shellQuote(this.image)}`,
|
|
7120
|
+
`docker run -d --name ${CONTAINER} --restart=always${this.allowUserNamespaces ? " --security-opt seccomp=unconfined --security-opt apparmor=unconfined" : ""} -p ${DAEMON_PORT}:${DAEMON_PORT} -v ${HOST_ORG_DIR}:${WORKDIR}/org:rslave -v ${HOST_CTL_DIR}:${CTL_DIR}${signingKeyMount} ${envFlags} ${shellQuote(this.image)}`,
|
|
7101
7121
|
{ env, timeoutMs: IMAGE_PULL_TIMEOUT_MS }
|
|
7102
7122
|
);
|
|
7103
7123
|
}
|