@alchemy.run/kubernetes 2.0.0-beta.84 → 2.0.0-beta.85
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/lib/BuiltinAdapters.d.ts +20 -0
- package/lib/BuiltinAdapters.d.ts.map +1 -1
- package/lib/BuiltinAdapters.js +8 -3
- package/lib/BuiltinAdapters.js.map +1 -1
- package/lib/Client.d.ts +17 -0
- package/lib/Client.d.ts.map +1 -1
- package/lib/Client.js +22 -6
- package/lib/Client.js.map +1 -1
- package/lib/ClusterAdapter.d.ts +4 -2
- package/lib/ClusterAdapter.d.ts.map +1 -1
- package/lib/ClusterAdapter.js.map +1 -1
- package/lib/Deployment.d.ts +21 -2
- package/lib/Deployment.d.ts.map +1 -1
- package/lib/Deployment.js +19 -2
- package/lib/Deployment.js.map +1 -1
- package/lib/HelmChart.js +1 -1
- package/lib/HelmChart.js.map +1 -1
- package/lib/Job.d.ts +21 -2
- package/lib/Job.d.ts.map +1 -1
- package/lib/Job.js +18 -1
- package/lib/Job.js.map +1 -1
- package/lib/LocalCluster.js +4 -4
- package/lib/LocalCluster.js.map +1 -1
- package/lib/Manifest.d.ts +9 -0
- package/lib/Manifest.d.ts.map +1 -1
- package/lib/Manifest.js +7 -2
- package/lib/Manifest.js.map +1 -1
- package/lib/internal/helm.js +1 -1
- package/lib/internal/helm.js.map +1 -1
- package/lib/internal/kubeconfig.js +1 -1
- package/lib/internal/kubeconfig.js.map +1 -1
- package/lib/internal/workload.d.ts +1 -1
- package/lib/internal/workload.d.ts.map +1 -1
- package/lib/internal/workload.js.map +1 -1
- package/package.json +8 -8
- package/src/BuiltinAdapters.ts +11 -3
- package/src/Client.ts +39 -8
- package/src/ClusterAdapter.ts +5 -2
- package/src/Deployment.ts +25 -4
- package/src/HelmChart.ts +1 -1
- package/src/Job.ts +23 -3
- package/src/LocalCluster.ts +4 -4
- package/src/Manifest.ts +10 -4
- package/src/internal/helm.ts +1 -1
- package/src/internal/kubeconfig.ts +1 -1
- package/src/internal/workload.ts +2 -1
package/src/Client.ts
CHANGED
|
@@ -36,6 +36,13 @@ import {
|
|
|
36
36
|
type KubernetesObjectRef,
|
|
37
37
|
} from "./Objects.ts";
|
|
38
38
|
|
|
39
|
+
export class KubernetesClientOperationFailed extends Data.TaggedError(
|
|
40
|
+
"KubernetesClientOperationFailed",
|
|
41
|
+
)<{
|
|
42
|
+
readonly message: string;
|
|
43
|
+
readonly cause?: unknown;
|
|
44
|
+
}> {}
|
|
45
|
+
|
|
39
46
|
export class KubernetesApiError extends Data.TaggedError("KubernetesApiError")<{
|
|
40
47
|
method: string;
|
|
41
48
|
path: string;
|
|
@@ -49,6 +56,12 @@ export class KubernetesApiError extends Data.TaggedError("KubernetesApiError")<{
|
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
|
|
59
|
+
/** An object ref that cannot be mapped to a REST path (e.g. a namespaced kind without a namespace). */
|
|
60
|
+
export class KubernetesObjectPathError extends Data.TaggedError("KubernetesObjectPathError")<{
|
|
61
|
+
message: string;
|
|
62
|
+
cause?: unknown;
|
|
63
|
+
}> {}
|
|
64
|
+
|
|
52
65
|
const fieldManager = "alchemy";
|
|
53
66
|
|
|
54
67
|
/** Deadline for auth-header minting and for each HTTP attempt. */
|
|
@@ -81,7 +94,7 @@ export class KubernetesNotFound extends Data.TaggedError("KubernetesNotFound")<{
|
|
|
81
94
|
* becomes `undefined`; auth and HTTP failures stay failures.
|
|
82
95
|
*/
|
|
83
96
|
export const ifClusterExists = <A, E, R>(effect: Effect.Effect<A, ClusterNotFoundError | E, R>) =>
|
|
84
|
-
effect.pipe(Effect.catchTag("Kubernetes.ClusterNotFoundError", () => Effect.
|
|
97
|
+
effect.pipe(Effect.catchTag("Kubernetes.ClusterNotFoundError", () => Effect.undefined));
|
|
85
98
|
|
|
86
99
|
const requestJson = Effect.fn(function* ({
|
|
87
100
|
transport,
|
|
@@ -156,13 +169,21 @@ const requestJson = Effect.fn(function* ({
|
|
|
156
169
|
resume(Effect.fail(error));
|
|
157
170
|
});
|
|
158
171
|
incoming.on("aborted", () => {
|
|
159
|
-
resume(
|
|
172
|
+
resume(
|
|
173
|
+
Effect.fail(
|
|
174
|
+
new KubernetesClientOperationFailed({
|
|
175
|
+
message: `Kubernetes ${method} ${path} response aborted`,
|
|
176
|
+
}),
|
|
177
|
+
),
|
|
178
|
+
);
|
|
160
179
|
});
|
|
161
180
|
incoming.on("end", () => {
|
|
162
181
|
if (incoming.complete === false) {
|
|
163
182
|
resume(
|
|
164
183
|
Effect.fail(
|
|
165
|
-
new
|
|
184
|
+
new KubernetesClientOperationFailed({
|
|
185
|
+
message: `Kubernetes ${method} ${path} response ended before completion`,
|
|
186
|
+
}),
|
|
166
187
|
),
|
|
167
188
|
);
|
|
168
189
|
return;
|
|
@@ -178,7 +199,13 @@ const requestJson = Effect.fn(function* ({
|
|
|
178
199
|
},
|
|
179
200
|
);
|
|
180
201
|
request.on("error", (error) => {
|
|
181
|
-
resume(
|
|
202
|
+
resume(
|
|
203
|
+
Effect.fail(
|
|
204
|
+
error instanceof Error
|
|
205
|
+
? error
|
|
206
|
+
: new KubernetesClientOperationFailed({ message: String(error) }),
|
|
207
|
+
),
|
|
208
|
+
);
|
|
182
209
|
});
|
|
183
210
|
if (prepared.payload !== undefined) request.write(prepared.payload);
|
|
184
211
|
request.end();
|
|
@@ -193,9 +220,9 @@ const requestJson = Effect.fn(function* ({
|
|
|
193
220
|
Effect.timeout(requestTimeout),
|
|
194
221
|
Effect.mapError(
|
|
195
222
|
(error) =>
|
|
196
|
-
new
|
|
197
|
-
`Failed Kubernetes ${method} ${path}: ${error instanceof Error ? error.message : String(error)}`,
|
|
198
|
-
),
|
|
223
|
+
new KubernetesClientOperationFailed({
|
|
224
|
+
message: `Failed Kubernetes ${method} ${path}: ${error instanceof Error ? error.message : String(error)}`,
|
|
225
|
+
}),
|
|
199
226
|
),
|
|
200
227
|
// Transport-level failures (ECONNREFUSED/ECONNRESET/ETIMEDOUT/DNS,
|
|
201
228
|
// the per-attempt deadline) are transient — a fresh managed endpoint's
|
|
@@ -310,7 +337,11 @@ const buildPath = Effect.fn(function* ({
|
|
|
310
337
|
const spec = yield* resolveKindSpec({ transport, input: object });
|
|
311
338
|
return yield* Effect.try({
|
|
312
339
|
try: () => buildKubernetesObjectPathWithSpec(object, spec),
|
|
313
|
-
catch: (error) =>
|
|
340
|
+
catch: (error) =>
|
|
341
|
+
new KubernetesObjectPathError({
|
|
342
|
+
message: error instanceof Error ? error.message : String(error),
|
|
343
|
+
cause: error,
|
|
344
|
+
}),
|
|
314
345
|
});
|
|
315
346
|
});
|
|
316
347
|
|
package/src/ClusterAdapter.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { InlineDockerfile } from "@alchemy.run/docker/Dockerfile";
|
|
2
|
+
import type { DockerfileBuild } from "@alchemy.run/docker/ImageSource";
|
|
2
3
|
import type * as Bundle from "alchemy/Bundle/Bundle";
|
|
3
4
|
import type { ResourceBinding } from "alchemy/Resource";
|
|
4
5
|
import type { ResourceContext } from "alchemy/ResourceContext";
|
|
@@ -170,12 +171,13 @@ export interface WorkloadImageSource {
|
|
|
170
171
|
main?: string;
|
|
171
172
|
handler?: string;
|
|
172
173
|
/**
|
|
173
|
-
* Bundler configuration for `main
|
|
174
|
+
* Bundler configuration for `main`, or Docker build args and secrets for
|
|
175
|
+
* a `context`/`dockerfile` build. Unused bundled code is tree-shaken.
|
|
174
176
|
* `effect`, alchemy, and `@distilled.cloud` are marked pure so unused
|
|
175
177
|
* parts prune more aggressively. List extra packages with
|
|
176
178
|
* `pure.packages`, or disable with `pure: false`.
|
|
177
179
|
*/
|
|
178
|
-
build?: Bundle.BundleConfig;
|
|
180
|
+
build?: Bundle.BundleConfig & DockerfileBuild;
|
|
179
181
|
context?: string;
|
|
180
182
|
dockerfile?: string | InlineDockerfile;
|
|
181
183
|
image?: string;
|
|
@@ -210,6 +212,7 @@ export interface WorkloadIdentityResult {
|
|
|
210
212
|
/** Annotations to stamp on the workload's ServiceAccount object. */
|
|
211
213
|
serviceAccountAnnotations?: Record<string, string>;
|
|
212
214
|
/** Serializable state persisted on the workload's attributes. */
|
|
215
|
+
// oxlint-disable-next-line typescript/no-redundant-type-constituents -- registry type is `never` until cloud packages augment it
|
|
213
216
|
state: IdentityState | undefined;
|
|
214
217
|
}
|
|
215
218
|
|
package/src/Deployment.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { DockerfileBuildOptions } from "@alchemy.run/docker/ImageSource";
|
|
2
|
+
import type * as Bundle from "alchemy/Bundle/Bundle";
|
|
1
3
|
import { isResolved } from "alchemy/Diff";
|
|
2
4
|
import type { Input } from "alchemy/Input";
|
|
3
5
|
import { createPhysicalName } from "alchemy/PhysicalName";
|
|
@@ -174,7 +176,7 @@ export interface BundledDeploymentProps extends DeploymentPropsBase {
|
|
|
174
176
|
/** Named export to load from `main`. @default "default" */
|
|
175
177
|
handler?: string;
|
|
176
178
|
/** Bundler configuration for the entrypoint. */
|
|
177
|
-
build?:
|
|
179
|
+
build?: Bundle.BundleConfig;
|
|
178
180
|
/** Environment Dockerfile (path or inline content). */
|
|
179
181
|
dockerfile?: WorkloadImageSource["dockerfile"];
|
|
180
182
|
/** Build context for a path {@link dockerfile} environment. */
|
|
@@ -182,7 +184,7 @@ export interface BundledDeploymentProps extends DeploymentPropsBase {
|
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
/** Build the user's own Dockerfile (`context` + optional `dockerfile` path). */
|
|
185
|
-
export interface DockerfileDeploymentProps extends DeploymentPropsBase {
|
|
187
|
+
export interface DockerfileDeploymentProps extends DeploymentPropsBase, DockerfileBuildOptions {
|
|
186
188
|
/** Docker build context directory. */
|
|
187
189
|
context?: string;
|
|
188
190
|
/**
|
|
@@ -229,6 +231,7 @@ export interface Deployment extends Resource<
|
|
|
229
231
|
* adapter (on EKS: the pod-identity role + association; on GKE: the
|
|
230
232
|
* Workload Identity principal and the IAM grants applied to it).
|
|
231
233
|
*/
|
|
234
|
+
// oxlint-disable-next-line typescript/no-redundant-type-constituents -- registry type is `never` until cloud packages augment it
|
|
232
235
|
identity: IdentityState | undefined;
|
|
233
236
|
/**
|
|
234
237
|
* Image-registry state provisioned by the cluster platform's adapter
|
|
@@ -252,6 +255,7 @@ export interface Deployment extends Resource<
|
|
|
252
255
|
Providers
|
|
253
256
|
> {}
|
|
254
257
|
|
|
258
|
+
// oxlint-disable-next-line typescript/no-redundant-type-constituents -- registry type is `never` until cloud packages augment it
|
|
255
259
|
export type DeploymentServices = ServerHostService | WorkloadServices;
|
|
256
260
|
|
|
257
261
|
export type DeploymentShape = Main<DeploymentServices>;
|
|
@@ -320,6 +324,23 @@ export interface DeploymentRuntimeContext extends HostRuntimeContext {
|
|
|
320
324
|
* });
|
|
321
325
|
* ```
|
|
322
326
|
*
|
|
327
|
+
* **Example:** Build args and secrets
|
|
328
|
+
* ```typescript
|
|
329
|
+
* // Dockerfile:
|
|
330
|
+
* // ARG NODE_ENV
|
|
331
|
+
* // RUN --mount=type=secret,id=NPM_TOKEN,env=NPM_TOKEN npm ci
|
|
332
|
+
* const api = yield* Kubernetes.Deployment("Api", {
|
|
333
|
+
* cluster,
|
|
334
|
+
* context: "./api",
|
|
335
|
+
* build: {
|
|
336
|
+
* args: { NODE_ENV: "production" },
|
|
337
|
+
* // Mounted only into the RUN step that asks for it; never in the image.
|
|
338
|
+
* secrets: { NPM_TOKEN: Config.Redacted("NPM_TOKEN") },
|
|
339
|
+
* },
|
|
340
|
+
* port: 8080,
|
|
341
|
+
* });
|
|
342
|
+
* ```
|
|
343
|
+
*
|
|
323
344
|
* ### Effect Servers
|
|
324
345
|
* **Example:** Inline Effect server
|
|
325
346
|
* ```typescript
|
|
@@ -538,7 +559,7 @@ export const DeploymentProvider = () =>
|
|
|
538
559
|
hostname ? Effect.succeed(hostname) : Effect.fail(new ServiceNotReady()),
|
|
539
560
|
),
|
|
540
561
|
retryUntilServiceReady,
|
|
541
|
-
Effect.catchTag("Kubernetes.ServiceNotReady", () => Effect.
|
|
562
|
+
Effect.catchTag("Kubernetes.ServiceNotReady", () => Effect.undefined),
|
|
542
563
|
);
|
|
543
564
|
|
|
544
565
|
return {
|
|
@@ -613,7 +634,7 @@ export const DeploymentProvider = () =>
|
|
|
613
634
|
const anchor = (output.kubernetesObjects ?? [])[0];
|
|
614
635
|
if (!anchor) return output;
|
|
615
636
|
const observed = yield* readObject({ transport, object: anchor }).pipe(
|
|
616
|
-
Effect.catchTag("KubernetesNotFound", () => Effect.
|
|
637
|
+
Effect.catchTag("KubernetesNotFound", () => Effect.undefined),
|
|
617
638
|
);
|
|
618
639
|
if (observed === undefined) return undefined;
|
|
619
640
|
return output;
|
package/src/HelmChart.ts
CHANGED
|
@@ -355,7 +355,7 @@ export const HelmChartProvider = () =>
|
|
|
355
355
|
Effect.gen(function* () {
|
|
356
356
|
const key = kubernetesObjectKey(object);
|
|
357
357
|
const observed = yield* readObject({ transport, object }).pipe(
|
|
358
|
-
Effect.catchTag("KubernetesNotFound", () => Effect.
|
|
358
|
+
Effect.catchTag("KubernetesNotFound", () => Effect.undefined),
|
|
359
359
|
);
|
|
360
360
|
if (!observed) return `missing:${key}`;
|
|
361
361
|
// Older rows stored no selection. Re-rendering the chart is
|
package/src/Job.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { DockerfileBuildOptions } from "@alchemy.run/docker/ImageSource";
|
|
2
|
+
import type * as Bundle from "alchemy/Bundle/Bundle";
|
|
1
3
|
import { isResolved } from "alchemy/Diff";
|
|
2
4
|
import * as Output from "alchemy/Output";
|
|
3
5
|
import { createPhysicalName } from "alchemy/PhysicalName";
|
|
@@ -155,7 +157,7 @@ export interface BundledJobProps extends JobPropsBase {
|
|
|
155
157
|
/** Named export to load from `main`. @default "default" */
|
|
156
158
|
handler?: string;
|
|
157
159
|
/** Bundler configuration for the entrypoint. */
|
|
158
|
-
build?:
|
|
160
|
+
build?: Bundle.BundleConfig;
|
|
159
161
|
/** Environment Dockerfile (path or inline content). */
|
|
160
162
|
dockerfile?: WorkloadImageSource["dockerfile"];
|
|
161
163
|
/** Build context for a path {@link dockerfile} environment. */
|
|
@@ -163,7 +165,7 @@ export interface BundledJobProps extends JobPropsBase {
|
|
|
163
165
|
}
|
|
164
166
|
|
|
165
167
|
/** Build the user's own Dockerfile (`context` + optional `dockerfile` path). */
|
|
166
|
-
export interface DockerfileJobProps extends JobPropsBase {
|
|
168
|
+
export interface DockerfileJobProps extends JobPropsBase, DockerfileBuildOptions {
|
|
167
169
|
/** Docker build context directory. */
|
|
168
170
|
context?: string;
|
|
169
171
|
/**
|
|
@@ -207,6 +209,7 @@ export interface Job extends Resource<
|
|
|
207
209
|
* adapter (on EKS: the pod-identity role + association; on GKE: the
|
|
208
210
|
* Workload Identity principal and the IAM grants applied to it).
|
|
209
211
|
*/
|
|
212
|
+
// oxlint-disable-next-line typescript/no-redundant-type-constituents -- registry type is `never` until cloud packages augment it
|
|
210
213
|
identity: IdentityState | undefined;
|
|
211
214
|
/**
|
|
212
215
|
* Image-registry state provisioned by the cluster platform's adapter
|
|
@@ -267,6 +270,23 @@ export interface JobRuntimeContext extends HostRuntimeContext {
|
|
|
267
270
|
* });
|
|
268
271
|
* ```
|
|
269
272
|
*
|
|
273
|
+
* **Example:** Your own Dockerfile with build args and secrets
|
|
274
|
+
* ```typescript
|
|
275
|
+
* // Dockerfile:
|
|
276
|
+
* // ARG NODE_ENV
|
|
277
|
+
* // RUN --mount=type=secret,id=NPM_TOKEN,env=NPM_TOKEN npm ci
|
|
278
|
+
* const migrate = yield* Kubernetes.Job("DbMigrate", {
|
|
279
|
+
* cluster,
|
|
280
|
+
* context: "./migrator",
|
|
281
|
+
* build: {
|
|
282
|
+
* args: { NODE_ENV: "production" },
|
|
283
|
+
* // Mounted only into the RUN step that asks for it; never in the image.
|
|
284
|
+
* secrets: { NPM_TOKEN: Config.Redacted("NPM_TOKEN") },
|
|
285
|
+
* },
|
|
286
|
+
* backoffLimit: 2,
|
|
287
|
+
* });
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
270
290
|
* **Example:** Inline Effect program
|
|
271
291
|
* ```typescript
|
|
272
292
|
* const cluster = yield* Kubernetes.LocalCluster("Cluster", {
|
|
@@ -477,7 +497,7 @@ export const JobProvider = () =>
|
|
|
477
497
|
const observed = yield* readObject({
|
|
478
498
|
transport,
|
|
479
499
|
object: anchor,
|
|
480
|
-
}).pipe(Effect.catchTag("KubernetesNotFound", () => Effect.
|
|
500
|
+
}).pipe(Effect.catchTag("KubernetesNotFound", () => Effect.undefined));
|
|
481
501
|
if (observed === undefined) return undefined;
|
|
482
502
|
return output;
|
|
483
503
|
}),
|
package/src/LocalCluster.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { unownedUnlessPrevious } from "alchemy/AdoptPolicy";
|
|
2
2
|
import { deepEqual, isResolved } from "alchemy/Diff";
|
|
3
3
|
import { createPhysicalName } from "alchemy/PhysicalName";
|
|
4
4
|
import * as Provider from "alchemy/Provider";
|
|
@@ -308,7 +308,7 @@ export const LocalClusterProvider = () =>
|
|
|
308
308
|
detached: false,
|
|
309
309
|
extendEnv: true,
|
|
310
310
|
}).pipe(
|
|
311
|
-
spawner.spawn,
|
|
311
|
+
(command) => spawner.spawn(command),
|
|
312
312
|
Effect.flatMap((child) =>
|
|
313
313
|
Effect.all(
|
|
314
314
|
{
|
|
@@ -559,7 +559,7 @@ export const LocalClusterProvider = () =>
|
|
|
559
559
|
return { action: "replace", deleteFirst: true } as const;
|
|
560
560
|
}
|
|
561
561
|
}),
|
|
562
|
-
read: Effect.fn(function* ({ id, olds, output }) {
|
|
562
|
+
read: Effect.fn(function* ({ id, olds, output, previous }) {
|
|
563
563
|
const name = yield* clusterName(id, olds, output);
|
|
564
564
|
if (!(yield* clusterExists(name))) return undefined;
|
|
565
565
|
const registryInfo = yield* inspectRegistry(`${name}-registry`);
|
|
@@ -574,7 +574,7 @@ export const LocalClusterProvider = () =>
|
|
|
574
574
|
// kind clusters carry no ownership marker; the registry container
|
|
575
575
|
// we start next to them does. Anything else is foreign.
|
|
576
576
|
const owned = yield* hasAlchemyTags(id, registryInfo?.Config?.Labels ?? undefined);
|
|
577
|
-
return owned ? attrs :
|
|
577
|
+
return owned ? attrs : unownedUnlessPrevious(attrs, previous, "name");
|
|
578
578
|
}),
|
|
579
579
|
reconcile: Effect.fn(function* ({ id, news, output, session }) {
|
|
580
580
|
const name = yield* clusterName(id, news, output);
|
package/src/Manifest.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { isResolved } from "alchemy/Diff";
|
|
|
2
2
|
import * as Provider from "alchemy/Provider";
|
|
3
3
|
import { Resource } from "alchemy/Resource";
|
|
4
4
|
import { isPlainObject } from "alchemy/Util/data";
|
|
5
|
+
import * as Data from "effect/Data";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
6
7
|
import {
|
|
7
8
|
applyObject,
|
|
@@ -16,6 +17,11 @@ import { connectionIdentity, connectionOfOutput, tryConnectionOf } from "./inter
|
|
|
16
17
|
import type { KubernetesObjectDefinition, KubernetesObjectRef } from "./Objects.ts";
|
|
17
18
|
import type { Providers } from "./Providers.ts";
|
|
18
19
|
|
|
20
|
+
export class ManifestInvalidProps extends Data.TaggedError("ManifestInvalidProps")<{
|
|
21
|
+
readonly message: string;
|
|
22
|
+
readonly cause?: unknown;
|
|
23
|
+
}> {}
|
|
24
|
+
|
|
19
25
|
/**
|
|
20
26
|
* A literal Kubernetes object: `apiVersion` + `kind` + `metadata`, with the
|
|
21
27
|
* rest of the object's fields (`spec`, `data`, …) carried as-is. Any kind is
|
|
@@ -174,9 +180,9 @@ const toObjectDefinition = (
|
|
|
174
180
|
const name = manifest.metadata?.name;
|
|
175
181
|
if (!name) {
|
|
176
182
|
return Effect.fail(
|
|
177
|
-
new
|
|
178
|
-
`Kubernetes.Manifest requires manifest.metadata.name (got ${manifest.apiVersion}/${manifest.kind})`,
|
|
179
|
-
),
|
|
183
|
+
new ManifestInvalidProps({
|
|
184
|
+
message: `Kubernetes.Manifest requires manifest.metadata.name (got ${manifest.apiVersion}/${manifest.kind})`,
|
|
185
|
+
}),
|
|
180
186
|
);
|
|
181
187
|
}
|
|
182
188
|
return Effect.succeed(manifest as KubernetesObjectDefinition);
|
|
@@ -219,7 +225,7 @@ export const ManifestProvider = () =>
|
|
|
219
225
|
const observed = yield* readObject({
|
|
220
226
|
transport,
|
|
221
227
|
object: output.ref,
|
|
222
|
-
}).pipe(Effect.catchTag("KubernetesNotFound", () => Effect.
|
|
228
|
+
}).pipe(Effect.catchTag("KubernetesNotFound", () => Effect.undefined));
|
|
223
229
|
if (!observed) return undefined;
|
|
224
230
|
const uid = (observed as { metadata?: { uid?: string } }).metadata?.uid;
|
|
225
231
|
const attrs = { ...output, uid };
|
package/src/internal/helm.ts
CHANGED
package/src/internal/workload.ts
CHANGED
|
@@ -57,7 +57,7 @@ export const deepMerge = <T>(base: T, override: unknown): T => {
|
|
|
57
57
|
*/
|
|
58
58
|
export const imagePlatformOf = (
|
|
59
59
|
architecture: "amd64" | "arm64" | undefined,
|
|
60
|
-
connection?: Connection
|
|
60
|
+
connection?: Connection,
|
|
61
61
|
): string =>
|
|
62
62
|
(architecture ?? connection?.architecture) === "arm64" ? "linux/arm64" : "linux/amd64";
|
|
63
63
|
|
|
@@ -320,6 +320,7 @@ export const workloadImageHash = Effect.fn(function* (options: {
|
|
|
320
320
|
});
|
|
321
321
|
|
|
322
322
|
/** The identity-adapter state persisted on workload attributes. */
|
|
323
|
+
// oxlint-disable-next-line typescript/no-redundant-type-constituents -- registry type is `never` until cloud packages augment it
|
|
323
324
|
export type PersistedIdentityState = IdentityState | undefined;
|
|
324
325
|
|
|
325
326
|
/**
|