kern-sandbox 0.2.38 → 0.2.39
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/index.js +23 -4
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -36,7 +36,7 @@ const crypto = require("crypto");
|
|
|
36
36
|
const zlib = require("zlib");
|
|
37
37
|
const { spawn, spawnSync } = require("child_process");
|
|
38
38
|
|
|
39
|
-
const VERSION = "0.2.
|
|
39
|
+
const VERSION = "0.2.39";
|
|
40
40
|
|
|
41
41
|
const DEFAULT_IMAGE = "python:3.12-slim";
|
|
42
42
|
const WORKSPACE = "/workspace"; // where the persistent workspace is mounted inside every box
|
|
@@ -285,9 +285,22 @@ function pycSourceId(image) {
|
|
|
285
285
|
const root = path.join(cacheHome(), "kern", "images");
|
|
286
286
|
const safe = sanitizeRef(image);
|
|
287
287
|
const h = crypto.createHash("sha256");
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
// THE CONFIG, which changes when ENTRYPOINT/ENV/WORKDIR/USER do.
|
|
289
|
+
h.update(fs.readFileSync(path.join(root, `${safe}.image`)).subarray(0, 4096));
|
|
290
|
+
// THE SENTINEL'S STAMP, NOT ITS BYTES. `.ok` holds the REFERENCE, so its contents are the tag and
|
|
291
|
+
// never move when the tag does: hashing them missed the commonest case there is, a rebuilt rootfs
|
|
292
|
+
// under an unchanged config. Its mtime and length are what kern ITSELF uses to decide an image's
|
|
293
|
+
// content changed, because a re-pull rewrites the sentinel last. Measured: a real re-pull leaves
|
|
294
|
+
// the config byte-identical and moves this.
|
|
295
|
+
const st = fs.statSync(path.join(root, `${safe}.ok`), { bigint: true });
|
|
296
|
+
h.update(`${st.mtimeNs}:${st.size}`);
|
|
297
|
+
// AND THE LAYER MANIFEST FOR A BUILT IMAGE, which names its layers by content. A pulled image has
|
|
298
|
+
// none, and that absence is part of the identity: an image that stops being layered is not the
|
|
299
|
+
// same image.
|
|
300
|
+
try {
|
|
301
|
+
h.update(fs.readFileSync(path.join(root, `${safe}.layers`)).subarray(0, 8192));
|
|
302
|
+
} catch {
|
|
303
|
+
h.update("\0no-layers");
|
|
291
304
|
}
|
|
292
305
|
return h.digest("hex").slice(0, 32);
|
|
293
306
|
} catch {
|
|
@@ -4411,5 +4424,11 @@ module.exports = {
|
|
|
4411
4424
|
_ociCanonicalRef: ociCanonicalRef,
|
|
4412
4425
|
_PYC_BUILD_CODE: PYC_BUILD_CODE,
|
|
4413
4426
|
_pycStartBuild: pycStartBuild,
|
|
4427
|
+
/** Await every build still in flight. FOR TESTS, and it removes a real race rather than masking
|
|
4428
|
+
* one: a test that removes its temp cache home while a background build is still writing into it
|
|
4429
|
+
* fails in `rimraf` with ENOTEMPTY, which is a teardown ordering bug and reads like a product
|
|
4430
|
+
* defect. Measured under the gate, where the machine is busy enough for the build to outlive the
|
|
4431
|
+
* test. */
|
|
4432
|
+
_pycSettle: () => Promise.allSettled([...PYC_BUILDS.values()]),
|
|
4414
4433
|
version: VERSION,
|
|
4415
4434
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kern-sandbox",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.39",
|
|
4
4
|
"description": "Your model writes the code. This runs it where it can't touch your machine: a rootless Linux container, no daemon, no VM, no cloud, no account. A kernel boundary, not a microVM: for deliberately hostile code, use one.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sandbox",
|