@norskvideo/ctl-product-template-schema 0.1.61 → 0.1.62
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 +7 -4
- package/package.json +1 -1
- package/workdir-path.js +23 -10
package/index.js
CHANGED
|
@@ -601,11 +601,14 @@ const ProductTemplateFileSchema = z.object({
|
|
|
601
601
|
// subpath) turns this into tar bytes at the paths below.
|
|
602
602
|
//
|
|
603
603
|
// `workflow`, `components` and `dashboards` are known top-level paths in the
|
|
604
|
-
// v1 tar format. The runner detects studio in the compose stack and
|
|
605
|
-
// all three
|
|
606
|
-
// to declare the mounts.
|
|
604
|
+
// v1 tar format. The runner detects studio in the compose stack and places
|
|
605
|
+
// all three in the studio container automatically — products don't need
|
|
606
|
+
// to declare the mounts. workflow.yml is COPIED into the working directory on
|
|
607
|
+
// every launch (a single-file bind under /data is refused by OrbStack and
|
|
608
|
+
// Docker Desktop); the template stays authoritative, so a Studio save of it
|
|
609
|
+
// lasts only until the next launch.
|
|
607
610
|
//
|
|
608
|
-
// workflow.yml → /data/studio-save-files/workflow.yml (
|
|
611
|
+
// workflow.yml → /data/studio-save-files/workflow.yml (copied)
|
|
609
612
|
// components/<name>/ → /usr/src/app/plugins/<name>/ (RO)
|
|
610
613
|
// dashboards/<name>/ → /data/studio-save-files/<name>/dashboards/ (RO)
|
|
611
614
|
//
|
package/package.json
CHANGED
package/workdir-path.js
CHANGED
|
@@ -10,14 +10,19 @@
|
|
|
10
10
|
// Two separate hazards, deliberately not conflated:
|
|
11
11
|
// escape — `../../etc/x` writes outside the workdir. A hole.
|
|
12
12
|
// shadowing — a file written UNDER one of the runner's read-only bind
|
|
13
|
-
// mounts is on disk and invisible to the container
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*
|
|
13
|
+
// mounts is on disk and invisible to the container, and a file
|
|
14
|
+
// at a path the launch writes itself is never the one used.
|
|
15
|
+
// Not a security problem, but a miserable one to debug, so it
|
|
16
|
+
// is refused at upload time rather than discovered at runtime.
|
|
17
|
+
/** Files the launch writes into the working directory itself. The product
|
|
18
|
+
* template's workflow.yml is copied to the path Studio's `server.document`
|
|
19
|
+
* names on every launch (norsk-ctl's workflow-sync.ts; it used to be a
|
|
20
|
+
* read-only single-file bind, which OrbStack and Docker Desktop refuse), so an
|
|
21
|
+
* operator asset there is replaced or skipped and never opened. */
|
|
22
|
+
const RUNNER_WRITTEN_FILES = ["studio-save-files/workflow.yml"];
|
|
23
|
+
/** Runner-managed read-only directory mount points inside the working
|
|
24
|
+
* directory (override-generator.ts); anything beneath them is shadowed. */
|
|
19
25
|
const READONLY_MOUNTS = {
|
|
20
|
-
file: ["studio-save-files/workflow.yml"],
|
|
21
26
|
dir: [".norsk"],
|
|
22
27
|
/** `studio-save-files/<anything>/dashboards` — the per-workflow dashboard mount. */
|
|
23
28
|
pattern: [/^studio-save-files\/[^/]+\/dashboards(\/|$)/],
|
|
@@ -46,9 +51,17 @@ export function checkWorkdirPath(raw) {
|
|
|
46
51
|
message: `'${path}' lands under the read-only mount '${mount}', where it would be on disk but invisible to the container`,
|
|
47
52
|
},
|
|
48
53
|
});
|
|
49
|
-
for (const file of
|
|
50
|
-
if (path === file)
|
|
51
|
-
return
|
|
54
|
+
for (const file of RUNNER_WRITTEN_FILES) {
|
|
55
|
+
if (path === file) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
problem: {
|
|
59
|
+
kind: "shadowed",
|
|
60
|
+
message: `'${path}' is where each launch copies the product template's workflow.yml, so an asset there would never be the one Studio opens`,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
52
65
|
for (const dir of READONLY_MOUNTS.dir)
|
|
53
66
|
if (path === dir || path.startsWith(`${dir}/`))
|
|
54
67
|
return shadowed(dir);
|