@jr2/cli 0.3.0 → 0.5.1
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/README.md +4 -3
- package/bin/jr2.js +3 -3
- package/manifests/operator.yaml +265 -23
- package/package.json +5 -5
- package/src/agents-md.ts +149 -0
- package/src/assembly.ts +432 -0
- package/src/build.ts +145 -290
- package/src/cli.ts +20 -41
- package/src/client.ts +144 -33
- package/src/command-table.ts +641 -0
- package/src/commands/check.ts +37 -0
- package/src/commands/down.ts +7 -16
- package/src/commands/gc.ts +2 -11
- package/src/commands/init.ts +82 -19
- package/src/commands/kit.ts +6 -11
- package/src/commands/logs.ts +13 -9
- package/src/commands/run.ts +70 -17
- package/src/commands/runs.ts +83 -6
- package/src/commands/send.ts +22 -23
- package/src/commands/status.ts +134 -22
- package/src/commands/up.ts +1704 -386
- package/src/commands/version.ts +26 -25
- package/src/deploy.ts +880 -101
- package/src/effector-image.ts +133 -0
- package/src/index.ts +26 -0
- package/src/instance-check.ts +309 -0
- package/src/instance.ts +3 -9
- package/src/kit-version.ts +27 -17
- package/src/kube.ts +439 -70
- package/src/nodes.ts +33 -2
- package/src/output.ts +1 -1
- package/src/repo-sweep.ts +1 -1
- package/src/sweep.ts +30 -15
package/src/output.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type Io = {
|
|
|
24
24
|
kubeAdmin?: KubeAdmin;
|
|
25
25
|
/** Override the image build port; default → pnpm + docker + kind subprocesses. */
|
|
26
26
|
build?: BuildPort;
|
|
27
|
-
/** Override `jr2 up`
|
|
27
|
+
/** Override the Instance typecheck of `jr2 up` and `jr2 check` (ADR-0050); default → the Instance's own `tsc`. */
|
|
28
28
|
typecheck?: TypecheckPort;
|
|
29
29
|
/** Where kit-checkout detection starts walking up from (ADR-0038); default → the CLI's own
|
|
30
30
|
* module directory, which is the whole signal: a checkout resolves the kit sources, an npm
|
package/src/repo-sweep.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// no Repos — the one read that may answer "none" — while any other failure throws and the caller
|
|
12
12
|
// sweeps nothing.
|
|
13
13
|
|
|
14
|
-
import { ANNOTATION_REPO_LAST_ATTACHED, LABEL_REPO_BOUND } from "@jr2/orchestrator";
|
|
14
|
+
import { ANNOTATION_REPO_LAST_ATTACHED, LABEL_REPO_BOUND } from "@jr2/orchestrator/internal";
|
|
15
15
|
import { LABEL_INSTANCE } from "./deploy.ts";
|
|
16
16
|
import { isMissingResourceType, type KubeAdmin } from "./kube.ts";
|
|
17
17
|
import { activity, type Io } from "./output.ts";
|
package/src/sweep.ts
CHANGED
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
// is not this instance's garbage):
|
|
8
8
|
// 1. the `jr2-images` ConfigMap of every jr2 instance (namespaces labeled `jr2.dev/instance`) — what
|
|
9
9
|
// FUTURE Sandboxes will be provisioned with;
|
|
10
|
-
// 2. every Sandbox CR's `spec.image
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
10
|
+
// 2. every Sandbox CR's `spec.image`, sidecar, init container and `image` volume in those
|
|
11
|
+
// namespaces — a parked Workspace must survive a pod restart, and `imagePullPolicy:
|
|
12
|
+
// IfNotPresent` cannot re-pull a local tag;
|
|
13
|
+
// 3. every pod's container and `image` volume refs in those namespaces plus `jr2-system` — what is
|
|
14
|
+
// actually running (orchestrator, Instance Harness, Custodians, Sandboxes, operator), mid-roll
|
|
15
|
+
// pods INCLUDED, without naming Deployments one by one.
|
|
15
16
|
// The keep set is their union. "Kit images are never pruned" is not a rule here: a kit ref is kept
|
|
16
17
|
// because some instance's map or pod names it, and collects like anything else when the last
|
|
17
18
|
// instance leaves the cluster.
|
|
@@ -23,12 +24,13 @@
|
|
|
23
24
|
// all: a cluster with no Sandbox CRD holds no Sandbox CRs, so that read's "none" is complete (see
|
|
24
25
|
// `listSandboxes`).
|
|
25
26
|
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
27
|
+
// Written down so nobody adds a name filter to "fix" it (ADR-0039): the host keep set only sees the
|
|
28
|
+
// CURRENT context's roots, so a converge to a different cluster — a second checkout's, or this
|
|
29
|
+
// one's — can lose a host image it built and has not used yet. `jr2 up` answers that itself: a tag
|
|
30
|
+
// it counted on and finds missing is rebuilt (BuildKit-cached seconds) and the use retried.
|
|
31
|
+
// Re-introducing a name filter would resurrect the exact primitive this ADR deletes.
|
|
30
32
|
|
|
31
|
-
import { IMAGES_CONFIGMAP, IMAGES_KEY } from "@jr2/orchestrator";
|
|
33
|
+
import { IMAGES_CONFIGMAP, IMAGES_KEY } from "@jr2/orchestrator/internal";
|
|
32
34
|
import { formatBytes, mergeSweeps, sweepHost, sweepNodes, type BuildPort, type SweepResult } from "./build.ts";
|
|
33
35
|
import { LABEL_INSTANCE, OPERATOR_NAMESPACE } from "./deploy.ts";
|
|
34
36
|
import { isMissingResourceType, type KubeAdmin } from "./kube.ts";
|
|
@@ -53,13 +55,18 @@ export type Roots = { keep: Set<string>; namespaces: string[] };
|
|
|
53
55
|
|
|
54
56
|
type NamespacedObject = { metadata: { name: string; namespace?: string } };
|
|
55
57
|
type ConfigMapObject = NamespacedObject & { data?: Record<string, string> };
|
|
56
|
-
type SandboxObject = NamespacedObject & {
|
|
58
|
+
type SandboxObject = NamespacedObject & {
|
|
59
|
+
spec?: { image?: string; sidecars?: ContainerSpec[]; initContainers?: ContainerSpec[]; volumes?: VolumeSpec[] };
|
|
60
|
+
};
|
|
57
61
|
type ContainerSpec = { image?: string };
|
|
62
|
+
/** Only an `image` volume names a ref: every Sandbox's `/opt/jr2` is one, of the harness image (ADR-0037). */
|
|
63
|
+
type VolumeSpec = { image?: { reference?: string } };
|
|
58
64
|
type PodObject = NamespacedObject & {
|
|
59
65
|
spec?: {
|
|
60
66
|
containers?: ContainerSpec[];
|
|
61
67
|
initContainers?: ContainerSpec[];
|
|
62
68
|
ephemeralContainers?: ContainerSpec[];
|
|
69
|
+
volumes?: VolumeSpec[];
|
|
63
70
|
};
|
|
64
71
|
};
|
|
65
72
|
|
|
@@ -93,18 +100,20 @@ export async function readRoots(kube: KubeAdmin, ctx: { context?: string } = {})
|
|
|
93
100
|
}
|
|
94
101
|
|
|
95
102
|
// 2. what a parked Workspace's pod will be recreated with — the Sandbox Image AND every sidecar's
|
|
96
|
-
// ref. The CR always carries the Custodian as a sidecar (sandbox-
|
|
103
|
+
// ref. The CR always carries the Custodian as a sidecar (sandbox-kube.ts), and its ref is not
|
|
97
104
|
// covered by the other roots: a running Sandbox is deliberately never re-imaged, so an `up` that
|
|
98
105
|
// moved the Custodian's pin leaves the CR naming the OLD one while the map names the new. If that pod
|
|
99
106
|
// is then lost (node restart, eviction, drain), the recreated one pulls the CR's sidecar ref —
|
|
100
|
-
// and `IfNotPresent` cannot re-pull a local tag a sweep took.
|
|
107
|
+
// and `IfNotPresent` cannot re-pull a local tag a sweep took. The same holds for the harness ref: it
|
|
108
|
+
// reaches the pod only as the `runtime` image volume (ADR-0037), never as a container's image.
|
|
101
109
|
const sandboxes = await listSandboxes(kube, ctx);
|
|
102
110
|
for (const sandbox of sandboxes) {
|
|
103
111
|
if (!instanceNs.has(sandbox.metadata.namespace ?? "")) continue;
|
|
104
112
|
if (sandbox.spec?.image) keep.add(sandbox.spec.image);
|
|
105
|
-
for (const
|
|
106
|
-
if (
|
|
113
|
+
for (const c of [...(sandbox.spec?.sidecars ?? []), ...(sandbox.spec?.initContainers ?? [])]) {
|
|
114
|
+
if (c.image) keep.add(c.image);
|
|
107
115
|
}
|
|
116
|
+
for (const ref of volumeRefs(sandbox.spec?.volumes)) keep.add(ref);
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
// 3. what is running right now — plus the operator, which lives in the shared `jr2-system`.
|
|
@@ -116,11 +125,17 @@ export async function readRoots(kube: KubeAdmin, ctx: { context?: string } = {})
|
|
|
116
125
|
for (const c of [...(spec.containers ?? []), ...(spec.initContainers ?? []), ...(spec.ephemeralContainers ?? [])]) {
|
|
117
126
|
if (c.image) keep.add(c.image);
|
|
118
127
|
}
|
|
128
|
+
for (const ref of volumeRefs(spec.volumes)) keep.add(ref);
|
|
119
129
|
}
|
|
120
130
|
|
|
121
131
|
return { keep, namespaces };
|
|
122
132
|
}
|
|
123
133
|
|
|
134
|
+
/** The refs a volume list mounts as `image` volumes — invisible to a read of containers alone. */
|
|
135
|
+
function volumeRefs(volumes: VolumeSpec[] | undefined): string[] {
|
|
136
|
+
return (volumes ?? []).flatMap((v) => (v.image?.reference ? [v.image.reference] : []));
|
|
137
|
+
}
|
|
138
|
+
|
|
124
139
|
/**
|
|
125
140
|
* Root #2's read, with the ONE degradation the fail-closed rule allows: a cluster that has no
|
|
126
141
|
* `sandboxes.core.jr2.dev` resource type can hold no Sandbox CRs, so "no Sandboxes" is the complete
|