@molecule/api-code-sandbox-docker 1.1.1 → 1.1.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/provider.d.ts.map +1 -1
- package/dist/provider.js +53 -0
- package/package.json +4 -4
package/dist/provider.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAcV,eAAe,EAOhB,MAAM,4BAA4B,CAAA;AAoBnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA4K9C;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ9D;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAcV,eAAe,EAOhB,MAAM,4BAA4B,CAAA;AAoBnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA4K9C;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ9D;AAyED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,EAAE;IACJ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IACjC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;IACrC,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAA;CAC1D,GACA,OAAO,CAAC,CAAC,CAAC,CA2BZ;AAg9CD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,eAAe,CAErE"}
|
package/dist/provider.js
CHANGED
|
@@ -190,6 +190,41 @@ export function resolvePublishPorts(ports) {
|
|
|
190
190
|
}
|
|
191
191
|
return [...new Set(ports)];
|
|
192
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Give an imported tree to whoever owns the sandbox's workspace root.
|
|
195
|
+
*
|
|
196
|
+
* Docker's putArchive preserves the tar's uid/gid — 0 — while the sandbox runs
|
|
197
|
+
* as the image's USER. Everything the sandbox does afterwards is done by that
|
|
198
|
+
* user, so an unrepaired import is a tree it cannot write.
|
|
199
|
+
*
|
|
200
|
+
* It has to be done from here, and as root: an ordinary exec runs as the same
|
|
201
|
+
* non-root user and `chown` answers "Operation not permitted" (which a pipe
|
|
202
|
+
* then hides behind exit 0 — that is how the repair went unnoticed).
|
|
203
|
+
*
|
|
204
|
+
* @param dockerApi - The provider's API client, bound by the caller.
|
|
205
|
+
* @param containerId - The sandbox to repair.
|
|
206
|
+
* @param path - The absolute path that was just imported.
|
|
207
|
+
*/
|
|
208
|
+
async function chownImportedTree(dockerApi, containerId, path) {
|
|
209
|
+
try {
|
|
210
|
+
const created = (await dockerApi(`/containers/${containerId}/exec`, 'POST', {
|
|
211
|
+
// `|| true` so an image whose workspace root is already the running user
|
|
212
|
+
// (or a path that vanished) is a no-op rather than a thrown import.
|
|
213
|
+
Cmd: ['sh', '-c', `chown -R --reference=/workspace ${shellQuote(path)} || true`],
|
|
214
|
+
User: 'root',
|
|
215
|
+
AttachStdout: false,
|
|
216
|
+
AttachStderr: false,
|
|
217
|
+
}));
|
|
218
|
+
if (created?.Id) {
|
|
219
|
+
await dockerApi(`/exec/${created.Id}/start`, 'POST', { Detach: false, Tty: false });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (_error) {
|
|
223
|
+
// Intentional noop: best-effort repair. A daemon that refuses a root exec
|
|
224
|
+
// leaves the tree exactly as the tar delivered it — the behaviour before
|
|
225
|
+
// this existed — and an import must not fail over it.
|
|
226
|
+
}
|
|
227
|
+
}
|
|
193
228
|
/**
|
|
194
229
|
* Available memory in bytes, or `null` when it cannot be read.
|
|
195
230
|
*
|
|
@@ -1011,6 +1046,24 @@ class DockerSandboxProvider {
|
|
|
1011
1046
|
download: (p, timeoutMs) => provider.dockerDownload(p, timeoutMs),
|
|
1012
1047
|
upload: (p, body, timeoutMs) => provider.dockerUpload(p, body, timeoutMs),
|
|
1013
1048
|
}, containerId, path, archive);
|
|
1049
|
+
// Docker's putArchive preserves the tar's uid/gid, which is 0, while the
|
|
1050
|
+
// sandbox runs as the image's USER (`node`, uid 1000). Without this the
|
|
1051
|
+
// imported tree belongs to a user nothing runs as: the executor cannot
|
|
1052
|
+
// write a file it just received, npm install cannot touch node_modules,
|
|
1053
|
+
// and Vite cannot create `node_modules/.vite-temp/…`, so the dev server
|
|
1054
|
+
// never starts.
|
|
1055
|
+
//
|
|
1056
|
+
// A caller cannot repair it afterwards — an ordinary exec runs as that
|
|
1057
|
+
// same non-root user and `chown` answers "Operation not permitted". The
|
|
1058
|
+
// repair has to happen here, on a root exec, which is a docker-ism and
|
|
1059
|
+
// belongs in the docker bond. (E2B has no equivalent step: it extracts
|
|
1060
|
+
// with --no-same-owner, so files already arrive on the executor's user.)
|
|
1061
|
+
//
|
|
1062
|
+
// `--reference=/workspace` takes the answer from the image itself
|
|
1063
|
+
// rather than naming a user, so it is correct for a root-based image
|
|
1064
|
+
// and a non-root one alike. Best-effort: a failure here must not fail
|
|
1065
|
+
// the import, and on an already-correct tree it is a no-op.
|
|
1066
|
+
await chownImportedTree((p, method, body) => provider.dockerApi(p, method, body), containerId, path);
|
|
1014
1067
|
},
|
|
1015
1068
|
onFileChange(_cb) {
|
|
1016
1069
|
let active = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/api-code-sandbox-docker",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Docker-based code sandbox container provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
],
|
|
30
30
|
"license": "Apache-2.0",
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@molecule/api-bond": "1.0.
|
|
33
|
-
"@molecule/api-code-sandbox": "1.2.
|
|
32
|
+
"@molecule/api-bond": "1.0.2",
|
|
33
|
+
"@molecule/api-code-sandbox": "1.2.1",
|
|
34
34
|
"@types/node": "26.1.2",
|
|
35
35
|
"typescript": "6.0.3",
|
|
36
36
|
"vitest": "4.1.11"
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"url": "https://github.com/molecule-dev/molecule.git",
|
|
51
51
|
"directory": "packages/api/bonds/code-sandbox/docker"
|
|
52
52
|
},
|
|
53
|
-
"homepage": "https://
|
|
53
|
+
"homepage": "https://www.molecule.dev/packages/api-code-sandbox-docker",
|
|
54
54
|
"bugs": "https://github.com/molecule-dev/molecule/issues",
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|