@norskvideo/ctl-product-template-schema 0.1.11 → 0.1.13
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.d.ts +148 -0
- package/index.js +66 -0
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -48,6 +48,56 @@ export declare const ProductTemplateSideloadSchema: z.ZodObject<{
|
|
|
48
48
|
llmVenv: z.ZodOptional<z.ZodBoolean>;
|
|
49
49
|
}, z.core.$strip>;
|
|
50
50
|
export type ProductTemplateSideload = z.infer<typeof ProductTemplateSideloadSchema>;
|
|
51
|
+
export declare const ProductTemplateRequirementsSchema: z.ZodObject<{
|
|
52
|
+
capacity: z.ZodOptional<z.ZodObject<{
|
|
53
|
+
mode: z.ZodEnum<{
|
|
54
|
+
default: "default";
|
|
55
|
+
fixed: "fixed";
|
|
56
|
+
required: "required";
|
|
57
|
+
}>;
|
|
58
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
}, z.core.$strip>>;
|
|
60
|
+
cores: z.ZodOptional<z.ZodObject<{
|
|
61
|
+
mode: z.ZodEnum<{
|
|
62
|
+
default: "default";
|
|
63
|
+
fixed: "fixed";
|
|
64
|
+
required: "required";
|
|
65
|
+
}>;
|
|
66
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
67
|
+
}, z.core.$strip>>;
|
|
68
|
+
gpu: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
mode: z.ZodEnum<{
|
|
70
|
+
default: "default";
|
|
71
|
+
fixed: "fixed";
|
|
72
|
+
required: "required";
|
|
73
|
+
}>;
|
|
74
|
+
value: z.ZodOptional<z.ZodObject<{
|
|
75
|
+
capacity: z.ZodOptional<z.ZodNumber>;
|
|
76
|
+
model: z.ZodOptional<z.ZodString>;
|
|
77
|
+
}, z.core.$strip>>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
80
|
+
mode: z.ZodEnum<{
|
|
81
|
+
default: "default";
|
|
82
|
+
fixed: "fixed";
|
|
83
|
+
required: "required";
|
|
84
|
+
}>;
|
|
85
|
+
value: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
86
|
+
name: z.ZodString;
|
|
87
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
attributeMatches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
89
|
+
}, z.core.$strip>>>;
|
|
90
|
+
}, z.core.$strip>>;
|
|
91
|
+
hostPorts: z.ZodOptional<z.ZodObject<{
|
|
92
|
+
mode: z.ZodEnum<{
|
|
93
|
+
default: "default";
|
|
94
|
+
fixed: "fixed";
|
|
95
|
+
required: "required";
|
|
96
|
+
}>;
|
|
97
|
+
value: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
98
|
+
}, z.core.$strip>>;
|
|
99
|
+
}, z.core.$strip>;
|
|
100
|
+
export type ProductTemplateRequirements = z.infer<typeof ProductTemplateRequirementsSchema>;
|
|
51
101
|
export declare const ProductTemplateManifestSchema: z.ZodObject<{
|
|
52
102
|
productTemplateSchemaVersion: z.ZodLiteral<1>;
|
|
53
103
|
productName: z.ZodString;
|
|
@@ -106,6 +156,55 @@ export declare const ProductTemplateManifestSchema: z.ZodObject<{
|
|
|
106
156
|
default: z.ZodOptional<z.ZodNumber>;
|
|
107
157
|
}, z.core.$strip>>;
|
|
108
158
|
}, z.core.$strip>>;
|
|
159
|
+
requirements: z.ZodOptional<z.ZodObject<{
|
|
160
|
+
capacity: z.ZodOptional<z.ZodObject<{
|
|
161
|
+
mode: z.ZodEnum<{
|
|
162
|
+
default: "default";
|
|
163
|
+
fixed: "fixed";
|
|
164
|
+
required: "required";
|
|
165
|
+
}>;
|
|
166
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
167
|
+
}, z.core.$strip>>;
|
|
168
|
+
cores: z.ZodOptional<z.ZodObject<{
|
|
169
|
+
mode: z.ZodEnum<{
|
|
170
|
+
default: "default";
|
|
171
|
+
fixed: "fixed";
|
|
172
|
+
required: "required";
|
|
173
|
+
}>;
|
|
174
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
175
|
+
}, z.core.$strip>>;
|
|
176
|
+
gpu: z.ZodOptional<z.ZodObject<{
|
|
177
|
+
mode: z.ZodEnum<{
|
|
178
|
+
default: "default";
|
|
179
|
+
fixed: "fixed";
|
|
180
|
+
required: "required";
|
|
181
|
+
}>;
|
|
182
|
+
value: z.ZodOptional<z.ZodObject<{
|
|
183
|
+
capacity: z.ZodOptional<z.ZodNumber>;
|
|
184
|
+
model: z.ZodOptional<z.ZodString>;
|
|
185
|
+
}, z.core.$strip>>;
|
|
186
|
+
}, z.core.$strip>>;
|
|
187
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
188
|
+
mode: z.ZodEnum<{
|
|
189
|
+
default: "default";
|
|
190
|
+
fixed: "fixed";
|
|
191
|
+
required: "required";
|
|
192
|
+
}>;
|
|
193
|
+
value: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
194
|
+
name: z.ZodString;
|
|
195
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
196
|
+
attributeMatches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
197
|
+
}, z.core.$strip>>>;
|
|
198
|
+
}, z.core.$strip>>;
|
|
199
|
+
hostPorts: z.ZodOptional<z.ZodObject<{
|
|
200
|
+
mode: z.ZodEnum<{
|
|
201
|
+
default: "default";
|
|
202
|
+
fixed: "fixed";
|
|
203
|
+
required: "required";
|
|
204
|
+
}>;
|
|
205
|
+
value: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
206
|
+
}, z.core.$strip>>;
|
|
207
|
+
}, z.core.$strip>>;
|
|
109
208
|
allocatedPorts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
110
209
|
param: z.ZodString;
|
|
111
210
|
protocol: z.ZodEnum<{
|
|
@@ -224,6 +323,55 @@ export declare const ProductTemplateMaterialsSchema: z.ZodObject<{
|
|
|
224
323
|
default: z.ZodOptional<z.ZodNumber>;
|
|
225
324
|
}, z.core.$strip>>;
|
|
226
325
|
}, z.core.$strip>>;
|
|
326
|
+
requirements: z.ZodOptional<z.ZodObject<{
|
|
327
|
+
capacity: z.ZodOptional<z.ZodObject<{
|
|
328
|
+
mode: z.ZodEnum<{
|
|
329
|
+
default: "default";
|
|
330
|
+
fixed: "fixed";
|
|
331
|
+
required: "required";
|
|
332
|
+
}>;
|
|
333
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
334
|
+
}, z.core.$strip>>;
|
|
335
|
+
cores: z.ZodOptional<z.ZodObject<{
|
|
336
|
+
mode: z.ZodEnum<{
|
|
337
|
+
default: "default";
|
|
338
|
+
fixed: "fixed";
|
|
339
|
+
required: "required";
|
|
340
|
+
}>;
|
|
341
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
342
|
+
}, z.core.$strip>>;
|
|
343
|
+
gpu: z.ZodOptional<z.ZodObject<{
|
|
344
|
+
mode: z.ZodEnum<{
|
|
345
|
+
default: "default";
|
|
346
|
+
fixed: "fixed";
|
|
347
|
+
required: "required";
|
|
348
|
+
}>;
|
|
349
|
+
value: z.ZodOptional<z.ZodObject<{
|
|
350
|
+
capacity: z.ZodOptional<z.ZodNumber>;
|
|
351
|
+
model: z.ZodOptional<z.ZodString>;
|
|
352
|
+
}, z.core.$strip>>;
|
|
353
|
+
}, z.core.$strip>>;
|
|
354
|
+
capabilities: z.ZodOptional<z.ZodObject<{
|
|
355
|
+
mode: z.ZodEnum<{
|
|
356
|
+
default: "default";
|
|
357
|
+
fixed: "fixed";
|
|
358
|
+
required: "required";
|
|
359
|
+
}>;
|
|
360
|
+
value: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
361
|
+
name: z.ZodString;
|
|
362
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
363
|
+
attributeMatches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
364
|
+
}, z.core.$strip>>>;
|
|
365
|
+
}, z.core.$strip>>;
|
|
366
|
+
hostPorts: z.ZodOptional<z.ZodObject<{
|
|
367
|
+
mode: z.ZodEnum<{
|
|
368
|
+
default: "default";
|
|
369
|
+
fixed: "fixed";
|
|
370
|
+
required: "required";
|
|
371
|
+
}>;
|
|
372
|
+
value: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
373
|
+
}, z.core.$strip>>;
|
|
374
|
+
}, z.core.$strip>>;
|
|
227
375
|
allocatedPorts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
228
376
|
param: z.ZodString;
|
|
229
377
|
protocol: z.ZodEnum<{
|
package/index.js
CHANGED
|
@@ -138,6 +138,69 @@ export const ProductTemplateSideloadSchema = z
|
|
|
138
138
|
}),
|
|
139
139
|
})
|
|
140
140
|
.meta({ id: "ProductTemplateSideload", outputId: "ProductTemplateSideload" });
|
|
141
|
+
// Placement requirements guidance (requirements-authoring.md). Each dimension
|
|
142
|
+
// the placer reasons over — capacity (vCPUs), cores, GPU, capabilities, host
|
|
143
|
+
// ports — is optionally declared with a `mode`:
|
|
144
|
+
// fixed — pinned; the operator can't change it (value required).
|
|
145
|
+
// default — a pre-filled starting value the operator may override.
|
|
146
|
+
// required — the product can't know it (e.g. a runtime-authored Studio
|
|
147
|
+
// workflow); the operator MUST supply it at create (value forbidden).
|
|
148
|
+
// An absent dimension is never asked for. The manifest only offers guidance;
|
|
149
|
+
// authoritative values are resolved at create time (template-baked or
|
|
150
|
+
// operator-entered) and projected into the job's JobRequirements.
|
|
151
|
+
const ProductTemplateRequirementModeSchema = z.enum(["fixed", "default", "required"]);
|
|
152
|
+
// Wrap a dimension's value schema with the mode/value contract: fixed/default
|
|
153
|
+
// must carry a value, required must not (the operator supplies it).
|
|
154
|
+
function requirementDimension(value, hasValue = () => true) {
|
|
155
|
+
return z.object({ mode: ProductTemplateRequirementModeSchema, value: value.optional() }).superRefine((d, ctx) => {
|
|
156
|
+
if (d.mode === "required" && d.value !== undefined) {
|
|
157
|
+
ctx.addIssue({
|
|
158
|
+
code: "custom",
|
|
159
|
+
path: ["value"],
|
|
160
|
+
message: "a `required` dimension must not declare a value — the operator supplies it at create",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const present = d.value !== undefined && hasValue(d.value);
|
|
164
|
+
if ((d.mode === "fixed" || d.mode === "default") && !present) {
|
|
165
|
+
ctx.addIssue({
|
|
166
|
+
code: "custom",
|
|
167
|
+
path: ["value"],
|
|
168
|
+
message: "a `fixed`/`default` dimension must declare a value",
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const ProductTemplateCapabilityRequirementSchema = z.object({
|
|
174
|
+
name: z.string(),
|
|
175
|
+
count: z.number().int().min(1).optional().meta({ description: "How many of this capability; default 1" }),
|
|
176
|
+
attributeMatches: z
|
|
177
|
+
.record(z.string(), z.string())
|
|
178
|
+
.optional()
|
|
179
|
+
.meta({ description: "Each key must equal the matched capability's attribute, e.g. { model: 'RTX 4090' }" }),
|
|
180
|
+
});
|
|
181
|
+
const ProductTemplateGpuRequirementSchema = z.object({
|
|
182
|
+
capacity: z.number().positive().optional().meta({ description: "Fractional GPU reference units" }),
|
|
183
|
+
model: z.string().optional().meta({ description: "GPU model match, e.g. 'RTX 4090'" }),
|
|
184
|
+
});
|
|
185
|
+
export const ProductTemplateRequirementsSchema = z
|
|
186
|
+
.object({
|
|
187
|
+
capacity: requirementDimension(z.number().positive()).optional().meta({
|
|
188
|
+
description: "CPU capacity in vCPUs — the primary placement dimension (capacity ≡ vCPUs).",
|
|
189
|
+
}),
|
|
190
|
+
cores: requirementDimension(z.number().int().positive()).optional().meta({
|
|
191
|
+
description: "Pinned cpuset core count (distinct from capacity).",
|
|
192
|
+
}),
|
|
193
|
+
gpu: requirementDimension(ProductTemplateGpuRequirementSchema, (v) => v.capacity !== undefined || v.model !== undefined)
|
|
194
|
+
.optional()
|
|
195
|
+
.meta({ description: "Fractional GPU need (capacity and/or model)." }),
|
|
196
|
+
capabilities: requirementDimension(z.array(ProductTemplateCapabilityRequirementSchema).min(1))
|
|
197
|
+
.optional()
|
|
198
|
+
.meta({ description: "Counted/exclusive hardware & software capabilities (nvidia-gpu, quadra, decklink, …)." }),
|
|
199
|
+
hostPorts: requirementDimension(z.array(z.string().regex(/^\d+\/(tcp|udp)$/i, "canonical PORT/proto token, e.g. 5001/udp")).min(1))
|
|
200
|
+
.optional()
|
|
201
|
+
.meta({ description: "Fixed host sockets the job binds (exclusive)." }),
|
|
202
|
+
})
|
|
203
|
+
.meta({ id: "ProductTemplateRequirements", outputId: "ProductTemplateRequirements" });
|
|
141
204
|
export const ProductTemplateManifestSchema = z
|
|
142
205
|
.object({
|
|
143
206
|
productTemplateSchemaVersion: z.literal(1),
|
|
@@ -161,6 +224,9 @@ export const ProductTemplateManifestSchema = z
|
|
|
161
224
|
advanced: ProductTemplateAdvancedSchema.optional().meta({
|
|
162
225
|
description: "Settings-backed runner knobs the operator may override per instance. Key presence opts the knob into the launch form; `default` pre-fills it (else the runner's daemon-wide default applies).",
|
|
163
226
|
}),
|
|
227
|
+
requirements: ProductTemplateRequirementsSchema.optional().meta({
|
|
228
|
+
description: "Placement requirements guidance. Each dimension (capacity/cores/gpu/capabilities/hostPorts) declares fixed (pinned) / default (pre-filled, overridable) / required (operator must supply at create). Absent dimensions are never asked for. Authoritative values are resolved at create time and drive placement; this is guidance only.",
|
|
229
|
+
}),
|
|
164
230
|
allocatedPorts: z.array(ProductTemplateAllocatedPortSchema).optional().meta({
|
|
165
231
|
description: "Host-port bindings whose value rides a product-template parameter. Opt-in per launch via the param value: absent = closed, 'auto' = allocate a free port from `preferred`, number = use it. When opened the port is published as a managed host binding and surfaced to the containers via compose interpolation. Alongside the per-param scalars the runner sets NORSK_ALLOCATED_PORTS: a JSON object keyed by param, each value {port, protocol, service?}, describing every opened port ('{}' when none opted in; unset when nothing is declared) — so a product needing the allocation as data maps one var instead of folding scalars into JSON via interpolation.",
|
|
166
232
|
}),
|