alasio 8.0.0 → 9.0.0
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/dist/cli/src/api-server.js +18 -0
- package/dist/cli/src/api-server.js.map +1 -0
- package/dist/cli/src/branches.js +61 -20
- package/dist/cli/src/branches.js.map +1 -1
- package/dist/cli/src/cluster/docker.js +25 -10
- package/dist/cli/src/cluster/docker.js.map +1 -1
- package/dist/cli/src/cluster/host.js +33 -7
- package/dist/cli/src/cluster/host.js.map +1 -1
- package/dist/cli/src/cluster/k3s.js +43 -11
- package/dist/cli/src/cluster/k3s.js.map +1 -1
- package/dist/cli/src/cluster/node.js +107 -32
- package/dist/cli/src/cluster/node.js.map +1 -1
- package/dist/cli/src/cluster/stargz.js +55 -0
- package/dist/cli/src/cluster/stargz.js.map +1 -0
- package/dist/cli/src/commands/branch.js +5 -4
- package/dist/cli/src/commands/branch.js.map +1 -1
- package/dist/cli/src/commands/common.js +9 -3
- package/dist/cli/src/commands/common.js.map +1 -1
- package/dist/cli/src/commands/folder.js +14 -0
- package/dist/cli/src/commands/folder.js.map +1 -0
- package/dist/cli/src/commands/status.js +64 -12
- package/dist/cli/src/commands/status.js.map +1 -1
- package/dist/cli/src/commands/uninstall.js +8 -9
- package/dist/cli/src/commands/uninstall.js.map +1 -1
- package/dist/cli/src/commands/up.js +11 -3
- package/dist/cli/src/commands/up.js.map +1 -1
- package/dist/cli/src/commands/upgrade.js +1 -1
- package/dist/cli/src/commands/upgrade.js.map +1 -1
- package/dist/cli/src/commands.js +2 -1
- package/dist/cli/src/commands.js.map +1 -1
- package/dist/cli/src/config.js +4 -1
- package/dist/cli/src/config.js.map +1 -1
- package/dist/cli/src/cpu-baseline.js +8 -4
- package/dist/cli/src/cpu-baseline.js.map +1 -1
- package/dist/cli/src/folders.js +67 -0
- package/dist/cli/src/folders.js.map +1 -0
- package/dist/cli/src/gateway-calls.js +58 -0
- package/dist/cli/src/gateway-calls.js.map +1 -0
- package/dist/cli/src/install.js +77 -29
- package/dist/cli/src/install.js.map +1 -1
- package/dist/cli/src/kept-releases.js +27 -20
- package/dist/cli/src/kept-releases.js.map +1 -1
- package/dist/cli/src/kube/api.js +2 -3
- package/dist/cli/src/kube/api.js.map +1 -1
- package/dist/cli/src/kube/apply.js +15 -72
- package/dist/cli/src/kube/apply.js.map +1 -1
- package/dist/cli/src/kube/rollout.js +28 -16
- package/dist/cli/src/kube/rollout.js.map +1 -1
- package/dist/cli/src/manifests/admission.js +342 -223
- package/dist/cli/src/manifests/admission.js.map +1 -1
- package/dist/cli/src/manifests/alasio.js +58 -394
- package/dist/cli/src/manifests/alasio.js.map +1 -1
- package/dist/cli/src/manifests/branch.js +10 -26
- package/dist/cli/src/manifests/branch.js.map +1 -1
- package/dist/cli/src/manifests/collector.js +60 -44
- package/dist/cli/src/manifests/collector.js.map +1 -1
- package/dist/cli/src/manifests/common.js +32 -2
- package/dist/cli/src/manifests/common.js.map +1 -1
- package/dist/cli/src/manifests/config.js +64 -81
- package/dist/cli/src/manifests/config.js.map +1 -1
- package/dist/cli/src/manifests/disruption.js +10 -0
- package/dist/cli/src/manifests/disruption.js.map +1 -1
- package/dist/cli/src/manifests/folders.js +128 -0
- package/dist/cli/src/manifests/folders.js.map +1 -0
- package/dist/cli/src/manifests/grafana.js +4 -2
- package/dist/cli/src/manifests/grafana.js.map +1 -1
- package/dist/cli/src/manifests/index.js +10 -7
- package/dist/cli/src/manifests/index.js.map +1 -1
- package/dist/cli/src/manifests/lake.js +18 -4
- package/dist/cli/src/manifests/lake.js.map +1 -1
- package/dist/cli/src/manifests/log.js +32 -14
- package/dist/cli/src/manifests/log.js.map +1 -1
- package/dist/cli/src/manifests/neon.js +3 -3
- package/dist/cli/src/manifests/neon.js.map +1 -1
- package/dist/cli/src/manifests/network-policies.js +140 -74
- package/dist/cli/src/manifests/network-policies.js.map +1 -1
- package/dist/cli/src/manifests/node-agent.js +11 -4
- package/dist/cli/src/manifests/node-agent.js.map +1 -1
- package/dist/cli/src/manifests/object-store.js +4 -2
- package/dist/cli/src/manifests/object-store.js.map +1 -1
- package/dist/cli/src/manifests/sandbox-gateway.js +663 -0
- package/dist/cli/src/manifests/sandbox-gateway.js.map +1 -0
- package/dist/cli/src/manifests/scalers.js +16 -5
- package/dist/cli/src/manifests/scalers.js.map +1 -1
- package/dist/cli/src/manifests/sizing.js +16 -8
- package/dist/cli/src/manifests/sizing.js.map +1 -1
- package/dist/cli/src/manifests/valkey.js +11 -5
- package/dist/cli/src/manifests/valkey.js.map +1 -1
- package/dist/cli/src/manifests/vpa.js +3 -1
- package/dist/cli/src/manifests/vpa.js.map +1 -1
- package/dist/cli/src/manifests/workspace-storage.js +174 -89
- package/dist/cli/src/manifests/workspace-storage.js.map +1 -1
- package/dist/cli/src/neon-storage.js +54 -14
- package/dist/cli/src/neon-storage.js.map +1 -1
- package/dist/cli/src/release.js +9 -9
- package/dist/cluster/node/pins.json +9 -4
- package/dist/neon/control/branches.js +6 -6
- package/dist/neon/control/branches.js.map +1 -1
- package/dist/neon/control/secrets.js +14 -3
- package/dist/neon/control/secrets.js.map +1 -1
- package/dist/src/binder/names.js +33 -0
- package/dist/src/binder/names.js.map +1 -0
- package/dist/src/binder/tokens.js +58 -0
- package/dist/src/binder/tokens.js.map +1 -0
- package/dist/src/branch/names.js +12 -2
- package/dist/src/branch/names.js.map +1 -1
- package/dist/src/events/names.js +7 -0
- package/dist/src/events/names.js.map +1 -0
- package/dist/src/gateway/names.js +201 -0
- package/dist/src/gateway/names.js.map +1 -0
- package/dist/src/harness/names.js +49 -0
- package/dist/src/harness/names.js.map +1 -0
- package/dist/src/kube/sandbox-shape.js +8 -68
- package/dist/src/kube/sandbox-shape.js.map +1 -1
- package/dist/src/node-agent/names.js +52 -2
- package/dist/src/node-agent/names.js.map +1 -1
- package/dist/src/sandbox/names.js +12 -20
- package/dist/src/sandbox/names.js.map +1 -1
- package/dist/src/sandbox/otlp-resource.js +173 -0
- package/dist/src/sandbox/otlp-resource.js.map +1 -0
- package/dist/src/sandbox/telemetry.js +43 -0
- package/dist/src/sandbox/telemetry.js.map +1 -0
- package/dist/src/telemetry/config.js +131 -0
- package/dist/src/telemetry/config.js.map +1 -0
- package/dist/src/telemetry/forward.js +154 -0
- package/dist/src/telemetry/forward.js.map +1 -0
- package/package.json +1 -1
- package/dist/cli/src/manifests/agent-sandbox.js +0 -92
- package/dist/cli/src/manifests/agent-sandbox.js.map +0 -1
- package/dist/cli/src/manifests/juicefs-csi.js +0 -320
- package/dist/cli/src/manifests/juicefs-csi.js.map +0 -1
- package/dist/cli/src/manifests/sandboxes.agents.x-k8s.io.json +0 -6295
- package/dist/src/kube/config.js +0 -145
- package/dist/src/kube/config.js.map +0 -1
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
import { WORKSPACE_QUOTAS_USER } from "../../../neon/control/secrets.js";
|
|
1
2
|
import { imageReference } from "../images.js";
|
|
2
|
-
import { componentName, imagePullSecrets, labels, NAMESPACE, restrictedContainer, restrictedPod, script } from "./common.js";
|
|
3
|
+
import { componentName, imagePullSecrets, labels, NAMESPACE, nodeAgentRuns, restrictedContainer, restrictedPod, s3Endpoint, script } from "./common.js";
|
|
4
|
+
import { everyIntervalCron } from "./config.js";
|
|
3
5
|
import { priority } from "./priorities.js";
|
|
4
|
-
import { CSI_DRIVER, juicefsCsiObjects, VOLUME_DRIVER } from "./juicefs-csi.js";
|
|
5
6
|
import { VALKEY_PORT, valkeyObjects, valkeyPassword } from "./valkey.js";
|
|
6
7
|
/** The Secret of the file system's credentials. */
|
|
7
8
|
export const WORKSPACES_CREDENTIALS = componentName("workspaces-juicefs");
|
|
9
|
+
/** The Secret of the node agents' Valkey user, its password and the metadata engine's address as it logs in (neon/control/kube-setup.ts). */
|
|
10
|
+
export const WORKSPACE_QUOTAS = componentName("workspaces-quotas");
|
|
11
|
+
/** What the node agents' Valkey user may do, as Valkey's ACL rules say it. */
|
|
12
|
+
export const QUOTAS_RULES = ["~*", "&*", "+@all", "-@dangerous", "+info"];
|
|
8
13
|
/**
|
|
9
14
|
* The label of alasio's pods that run JuiceFS's command line against the file system, the
|
|
10
15
|
* quota check's and a restore's, which its store policies admit (./network-policies.ts).
|
|
@@ -15,45 +20,17 @@ const QUOTA_CHECK_SCHEDULE = "47 3 * * *";
|
|
|
15
20
|
const COLLECTION_SCHEDULE = "17 4 * * *";
|
|
16
21
|
/** Whom the quota check and the collection run as: nobody, as they write nothing of their own. */
|
|
17
22
|
const NOBODY = 65534;
|
|
18
|
-
/**
|
|
19
|
-
* The directory of the file system a claim of the class is, `<namespace>-<claim>`: of
|
|
20
|
-
* the driver's template's variables in the StorageClass's pathPattern, of the shell's in
|
|
21
|
-
* the clone's script.
|
|
22
|
-
*/
|
|
23
|
-
const volumeDirectory = (namespace, claim) => `${namespace}-${claim}`;
|
|
24
23
|
/** The file system's Valkey's name: its Service's, its StatefulSet's, and its password's Secret's. */
|
|
25
24
|
export const VALKEY = componentName("valkey");
|
|
26
25
|
/** The file system's Valkey's password, as a variable's source. */
|
|
27
26
|
export const VALKEY_PASSWORD = valkeyPassword(VALKEY);
|
|
28
|
-
/** Valkey's address, as
|
|
27
|
+
/** Valkey's address, as what reaches it from another namespace does. */
|
|
29
28
|
export const VALKEY_ADDRESS = `${VALKEY}.${NAMESPACE}.svc.cluster.local:${VALKEY_PORT}`;
|
|
30
|
-
/** The workspaces bucket's URL, path-style, as
|
|
29
|
+
/** The workspaces bucket's URL, path-style, as what reaches it from another namespace does. */
|
|
31
30
|
export function workspacesBucketUrl({ objectStore }) {
|
|
32
31
|
const endpoint = objectStore.bundled.enabled ? `http://${componentName("seaweedfs")}.${NAMESPACE}.svc.cluster.local:8333` : objectStore.external.endpoint.replace(/\/+$/u, "");
|
|
33
32
|
return `${endpoint}/${objectStore.buckets.workspaces}`;
|
|
34
33
|
}
|
|
35
|
-
/** The StorageClass of workspaces' volumes. */
|
|
36
|
-
function storageClass({ workspaceStorage }) {
|
|
37
|
-
const secret = { name: WORKSPACES_CREDENTIALS, namespace: NAMESPACE };
|
|
38
|
-
return {
|
|
39
|
-
apiVersion: "storage.k8s.io/v1",
|
|
40
|
-
kind: "StorageClass",
|
|
41
|
-
metadata: { name: workspaceStorage.storageClassName, labels: labels("workspaces") },
|
|
42
|
-
provisioner: CSI_DRIVER,
|
|
43
|
-
parameters: {
|
|
44
|
-
"csi.storage.k8s.io/provisioner-secret-name": secret.name,
|
|
45
|
-
"csi.storage.k8s.io/provisioner-secret-namespace": secret.namespace,
|
|
46
|
-
"csi.storage.k8s.io/node-publish-secret-name": secret.name,
|
|
47
|
-
"csi.storage.k8s.io/node-publish-secret-namespace": secret.namespace,
|
|
48
|
-
"csi.storage.k8s.io/controller-expand-secret-name": secret.name,
|
|
49
|
-
"csi.storage.k8s.io/controller-expand-secret-namespace": secret.namespace,
|
|
50
|
-
pathPattern: volumeDirectory("${.pvc.namespace}", "${.pvc.name}"),
|
|
51
|
-
},
|
|
52
|
-
reclaimPolicy: "Delete",
|
|
53
|
-
allowVolumeExpansion: true,
|
|
54
|
-
volumeBindingMode: "Immediate",
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
34
|
/**
|
|
58
35
|
* A container of a JuiceFS admin pod, `name`, running `lines` with JuiceFS's command line
|
|
59
36
|
* of the pinned client, the file system's metadata engine's URL in `META_URL`.
|
|
@@ -61,7 +38,7 @@ function storageClass({ workspaceStorage }) {
|
|
|
61
38
|
function adminContainer(config, name, ...lines) {
|
|
62
39
|
return {
|
|
63
40
|
name,
|
|
64
|
-
image: imageReference(config.workspaceStorage.
|
|
41
|
+
image: imageReference(config.workspaceStorage.image),
|
|
65
42
|
imagePullPolicy: "IfNotPresent",
|
|
66
43
|
command: ["/bin/sh", "-c", script("set -eu", ...lines)],
|
|
67
44
|
env: [{ name: "META_URL", valueFrom: { secretKeyRef: { name: WORKSPACES_CREDENTIALS, key: "metaurl" } } }],
|
|
@@ -70,13 +47,13 @@ function adminContainer(config, name, ...lines) {
|
|
|
70
47
|
}
|
|
71
48
|
/**
|
|
72
49
|
* A daily JuiceFS admin task, `component`, whose container `name` runs `lines` restricted
|
|
73
|
-
* as nobody.
|
|
50
|
+
* as nobody.
|
|
74
51
|
*/
|
|
75
52
|
function dailyAdminTask(config, component, schedule, name, ...lines) {
|
|
76
53
|
return {
|
|
77
54
|
apiVersion: "batch/v1",
|
|
78
55
|
kind: "CronJob",
|
|
79
|
-
metadata: { name: componentName(component), namespace: NAMESPACE, labels:
|
|
56
|
+
metadata: { name: componentName(component), namespace: NAMESPACE, labels: labels(component) },
|
|
80
57
|
spec: {
|
|
81
58
|
schedule,
|
|
82
59
|
concurrencyPolicy: "Forbid",
|
|
@@ -102,68 +79,170 @@ function dailyAdminTask(config, component, schedule, name, ...lines) {
|
|
|
102
79
|
};
|
|
103
80
|
}
|
|
104
81
|
/**
|
|
105
|
-
* The
|
|
82
|
+
* The workspaces' usage checked daily against what they hold, and repaired (guide/quota.md
|
|
106
83
|
* "Usage check and fix"): a client that ends unexpectedly loses the usage it had yet to
|
|
107
|
-
* write, after which a
|
|
84
|
+
* write, after which a workspace's quota counts wrongly. Each workspace, as `juicefs quota
|
|
108
85
|
* list` tables it, is checked in turn.
|
|
109
86
|
*/
|
|
110
87
|
function quotaCheck(config) {
|
|
111
88
|
return dailyAdminTask(config, "juicefs-quota-check", QUOTA_CHECK_SCHEDULE, "quota-check", 'quotas=$(juicefs quota list "$META_URL")',
|
|
112
|
-
// The table's rows of
|
|
113
|
-
//
|
|
114
|
-
|
|
89
|
+
// The table's rows of workspaces, the directories of the file system's environments
|
|
90
|
+
// (`/<environment>/<workspace>`, as the node agents make them), not those deleted into its
|
|
91
|
+
// trash, whose first column is their path.
|
|
92
|
+
"printf '%s\\n' \"$quotas\" | awk -F '|' '$2 ~ /^ \\/[^\\/. ][^\\/ ]*\\/[^\\/ ]+ +$/ { gsub(/ /, \"\", $2); print $2 }' | while read -r path; do", ' juicefs quota check "$META_URL" --path "$path" --repair', "done");
|
|
115
93
|
}
|
|
116
94
|
/**
|
|
117
|
-
* The file system collected daily (`juicefs gc --delete`, guide/gc.md): what no
|
|
118
|
-
* holds deleted from the bucket,
|
|
119
|
-
*
|
|
95
|
+
* The file system collected daily (`juicefs gc --compact --delete`, guide/gc.md): what no
|
|
96
|
+
* file holds deleted from the bucket, its trash's expired entries and its files pending
|
|
97
|
+
* deletion with it, chunks of many slices compacted, and the trees of clones that never
|
|
98
|
+
* finished removed, a day after they were begun. A clone builds its tree detached and attaches it only once
|
|
120
99
|
* it is whole, and its client removes it when the clone fails; nothing but this removes
|
|
121
100
|
* one whose client ended first.
|
|
122
101
|
*/
|
|
123
102
|
function collection(config) {
|
|
124
|
-
return dailyAdminTask(config, "juicefs-gc", COLLECTION_SCHEDULE, "gc", 'juicefs gc "$META_URL" --delete');
|
|
103
|
+
return dailyAdminTask(config, "juicefs-gc", COLLECTION_SCHEDULE, "gc", 'juicefs gc "$META_URL" --compact --delete');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* How often the stale clients' sessions are cleaned (staleSessions): the most a lock a dead
|
|
107
|
+
* client held blocks another, past the minute before its session counts as stale.
|
|
108
|
+
*/
|
|
109
|
+
export const STALE_SESSIONS_SCHEDULE = "*/5 * * * *";
|
|
110
|
+
/**
|
|
111
|
+
* How long staleSessions runs its client, in seconds: past two of its refreshes, a
|
|
112
|
+
* heartbeat's each (12 s, ±10%), as its first may come before the cleanups' last mark has
|
|
113
|
+
* aged past 0.9 of a heartbeat, which the cleanup waits for (JuiceFS's pkg/meta base.go
|
|
114
|
+
* refresh and CleanStaleSessions).
|
|
115
|
+
*/
|
|
116
|
+
export const STALE_SESSIONS_RUN_SECONDS = 40;
|
|
117
|
+
/**
|
|
118
|
+
* The sessions of clients that died cleaned, every STALE_SESSIONS_SCHEDULE, one run at a
|
|
119
|
+
* time: what a client's background jobs do, and no mount of the nodes' does. A session
|
|
120
|
+
* counts as stale once its client has sent no heartbeat for five of them (60 s), and a client
|
|
121
|
+
* with background jobs cleans the stale sessions as it refreshes its own, every heartbeat:
|
|
122
|
+
* their locks let go and the files they held open after their deletion freed. So a lock a
|
|
123
|
+
* client that died held blocks another for 60 s and up to a schedule's interval more, and
|
|
124
|
+
* this job's run: seven minutes at most. The client is JuiceFS's S3 gateway, on the
|
|
125
|
+
* pod's loopback, which opens a session with background jobs and needs no FUSE, run for
|
|
126
|
+
* STALE_SESSIONS_RUN_SECONDS: no mount, so nothing of it is anywhere a workspace lives, and
|
|
127
|
+
* no backup of its own (`--backup-meta 0`). Its other background jobs, the trash's expiry and
|
|
128
|
+
* deletions pending, are the daily collection's too, which they overlap harmlessly. The
|
|
129
|
+
* sessions are said as it begins and ends.
|
|
130
|
+
*/
|
|
131
|
+
function staleSessions(config) {
|
|
132
|
+
const component = "juicefs-sessions";
|
|
133
|
+
const sessions = `juicefs status "$META_URL" 2>/dev/null | grep -c '"Sid"' || true`;
|
|
134
|
+
const container = {
|
|
135
|
+
...adminContainer(config, "sessions", `echo "sessions as it begins: $(${sessions})"`,
|
|
136
|
+
// The gateway's own S3 credentials, which nothing reaches it by: random, as it listens on the pod's loopback alone.
|
|
137
|
+
"MINIO_ROOT_USER=maintenance MINIO_ROOT_PASSWORD=$(head -c 18 /dev/urandom | od -An -tx1 | tr -d ' \\n') \\", ' juicefs gateway --no-usage-report --backup-meta 0 --cache-dir /tmp/cache --cache-size 0 "$META_URL" 127.0.0.1:9000 &', "client=$!", `sleep ${STALE_SESSIONS_RUN_SECONDS}`, 'kill -TERM "$client"', 'wait "$client" || true', `echo "sessions as it ends: $(${sessions})"`),
|
|
138
|
+
securityContext: restrictedContainer(),
|
|
139
|
+
env: [{ name: "META_URL", valueFrom: { secretKeyRef: { name: WORKSPACES_CREDENTIALS, key: "metaurl" } } }, { name: "HOME", value: "/tmp" }],
|
|
140
|
+
resources: { requests: { cpu: "50m", memory: "64Mi" }, limits: { memory: "512Mi" } },
|
|
141
|
+
volumeMounts: [{ name: "tmp", mountPath: "/tmp" }],
|
|
142
|
+
};
|
|
143
|
+
return {
|
|
144
|
+
apiVersion: "batch/v1",
|
|
145
|
+
kind: "CronJob",
|
|
146
|
+
metadata: { name: componentName(component), namespace: NAMESPACE, labels: labels(component) },
|
|
147
|
+
spec: {
|
|
148
|
+
schedule: STALE_SESSIONS_SCHEDULE,
|
|
149
|
+
concurrencyPolicy: "Forbid",
|
|
150
|
+
successfulJobsHistoryLimit: 1,
|
|
151
|
+
failedJobsHistoryLimit: 3,
|
|
152
|
+
jobTemplate: {
|
|
153
|
+
spec: {
|
|
154
|
+
backoffLimit: 1,
|
|
155
|
+
activeDeadlineSeconds: 240,
|
|
156
|
+
template: {
|
|
157
|
+
metadata: { labels: { ...labels(component), ...JUICEFS_ADMIN } },
|
|
158
|
+
spec: {
|
|
159
|
+
restartPolicy: "Never",
|
|
160
|
+
...priority("component"),
|
|
161
|
+
...imagePullSecrets(config),
|
|
162
|
+
securityContext: restrictedPod(NOBODY, NOBODY),
|
|
163
|
+
containers: [container],
|
|
164
|
+
volumes: [{ name: "tmp", emptyDir: {} }],
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
125
171
|
}
|
|
172
|
+
/** How many of the metadata's dumps the bucket's meta/ keeps, the newest: a day's, at the default interval. */
|
|
173
|
+
export const DUMPS_KEPT = 24;
|
|
126
174
|
/**
|
|
127
|
-
* The
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* which may end once a clone is in the directory, counting it a second time; so once the
|
|
136
|
-
* clones are done, and the client that charged them has stopped and written what it
|
|
137
|
-
* counted, the usage is counted anew (`juicefs quota check --repair`). The directory is
|
|
138
|
-
* given its source's owner and mode, as kubelet gives a volume whose root is not yet the
|
|
139
|
-
* pod's group that group throughout (fsGroupChangePolicy OnRootMismatch), which would
|
|
140
|
-
* widen every cloned file's mode. On a mount of the whole file system, as a volume's
|
|
141
|
-
* mount pod mounts its directory alone: privileged, as FUSE needs, and as root, to give
|
|
142
|
-
* each file its owner.
|
|
175
|
+
* The file system's metadata dumped to its bucket, every backupInterval, one at a time, as
|
|
176
|
+
* JuiceFS's own backup would have, which no mount takes (the nodes' mount runs with no
|
|
177
|
+
* background job): by `juicefs dump`, its object store's keys left out, then put in meta/ as
|
|
178
|
+
* JuiceFS names its dumps, `dump-YYYY-MM-DD-hhmmss.json.gz` of UTC, which the nightly backup
|
|
179
|
+
* copies the newest of (./neon.ts backup); the dump checked as the gzip it is, and read back
|
|
180
|
+
* of the same size and checksum once put; the dumps but the newest DUMPS_KEPT deleted after.
|
|
181
|
+
* Put by the file system's own keys, which may write its bucket, with the AWS command line
|
|
182
|
+
* of the stack's image.
|
|
143
183
|
*/
|
|
144
|
-
|
|
145
|
-
const component = "
|
|
146
|
-
const
|
|
147
|
-
const
|
|
184
|
+
function metadataDump(config) {
|
|
185
|
+
const component = "juicefs-dump";
|
|
186
|
+
const credential = (name, key) => ({ name, valueFrom: { secretKeyRef: { name: WORKSPACES_CREDENTIALS, key } } });
|
|
187
|
+
const schedule = everyIntervalCron(config.workspaceStorage.backupInterval);
|
|
188
|
+
// The configuration holds its interval to one a cron line keeps.
|
|
189
|
+
if (schedule === null)
|
|
190
|
+
throw new Error(`workspaceStorage.backupInterval ${config.workspaceStorage.backupInterval} is kept by no cron line`);
|
|
191
|
+
const dump = {
|
|
192
|
+
...adminContainer(config, "dump", 'juicefs dump "$META_URL" /dump/dump.json.gz'),
|
|
193
|
+
securityContext: restrictedContainer(),
|
|
194
|
+
// Its metadata held whole, as Valkey's maxmemory bounds it.
|
|
195
|
+
resources: { requests: { cpu: "50m", memory: "128Mi" }, limits: { memory: "1Gi" } },
|
|
196
|
+
volumeMounts: [{ name: "dump", mountPath: "/dump" }],
|
|
197
|
+
};
|
|
198
|
+
const upload = {
|
|
199
|
+
name: "upload",
|
|
200
|
+
image: imageReference(config.neon.image),
|
|
201
|
+
imagePullPolicy: "IfNotPresent",
|
|
202
|
+
command: [
|
|
203
|
+
"/bin/sh",
|
|
204
|
+
"-c",
|
|
205
|
+
script("set -eu", 's3() { aws s3 --endpoint-url "$S3_ENDPOINT" "$@"; }', 'meta="s3://$WORKSPACES_BUCKET/$WORKSPACES_NAME/meta/"', 'gzip -t "$DUMP/dump.json.gz" 2>/dev/null || { echo "the dump is no whole gzip" >&2; exit 1; }', 'name="dump-$(date -u +%Y-%m-%d-%H%M%S).json.gz"', 's3 cp "$DUMP/dump.json.gz" "$meta$name"', 's3 cp "$meta$name" "$DUMP/read.json.gz"', `[ "$(stat -c %s "$DUMP/dump.json.gz")" = "$(stat -c %s "$DUMP/read.json.gz")" ] || { echo "$name in the bucket is not of the dump's size" >&2; exit 1; }`, '[ "$(sha256sum < "$DUMP/dump.json.gz")" = "$(sha256sum < "$DUMP/read.json.gz")" ] || { echo "$name in the bucket is not the dump" >&2; exit 1; }', `s3 ls "$meta" | awk '{print $4}' | grep '^dump-.*\\.json\\.gz$' | sort -r | tail -n +${DUMPS_KEPT + 1} | while read -r old; do s3 rm "$meta$old"; done`, 'echo "dumped the metadata of $WORKSPACES_NAME to $meta$name"'),
|
|
206
|
+
],
|
|
207
|
+
env: [
|
|
208
|
+
{ name: "S3_ENDPOINT", value: s3Endpoint(config) },
|
|
209
|
+
{ name: "WORKSPACES_BUCKET", value: config.objectStore.buckets.workspaces },
|
|
210
|
+
{ name: "WORKSPACES_NAME", value: config.workspaceStorage.name },
|
|
211
|
+
credential("AWS_ACCESS_KEY_ID", "access-key"),
|
|
212
|
+
credential("AWS_SECRET_ACCESS_KEY", "secret-key"),
|
|
213
|
+
{ name: "AWS_DEFAULT_REGION", value: config.objectStore.external.region },
|
|
214
|
+
{ name: "HOME", value: "/tmp" },
|
|
215
|
+
{ name: "DUMP", value: "/dump" },
|
|
216
|
+
],
|
|
217
|
+
securityContext: restrictedContainer(),
|
|
218
|
+
resources: { requests: { cpu: "50m", memory: "64Mi" }, limits: { memory: "512Mi" } },
|
|
219
|
+
volumeMounts: [{ name: "dump", mountPath: "/dump" }, { name: "tmp", mountPath: "/tmp" }],
|
|
220
|
+
};
|
|
148
221
|
return {
|
|
149
222
|
apiVersion: "batch/v1",
|
|
150
|
-
kind: "
|
|
151
|
-
metadata: {
|
|
223
|
+
kind: "CronJob",
|
|
224
|
+
metadata: { name: componentName(component), namespace: NAMESPACE, labels: labels(component) },
|
|
152
225
|
spec: {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
metadata: { labels: { ...labels(component), ...JUICEFS_ADMIN } },
|
|
226
|
+
schedule,
|
|
227
|
+
concurrencyPolicy: "Forbid",
|
|
228
|
+
successfulJobsHistoryLimit: 1,
|
|
229
|
+
failedJobsHistoryLimit: 3,
|
|
230
|
+
jobTemplate: {
|
|
159
231
|
spec: {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
232
|
+
backoffLimit: 2,
|
|
233
|
+
activeDeadlineSeconds: 1800,
|
|
234
|
+
template: {
|
|
235
|
+
metadata: { labels: { ...labels(component), ...JUICEFS_ADMIN } },
|
|
236
|
+
spec: {
|
|
237
|
+
restartPolicy: "Never",
|
|
238
|
+
...priority("component"),
|
|
239
|
+
...imagePullSecrets(config),
|
|
240
|
+
securityContext: restrictedPod(NOBODY, NOBODY),
|
|
241
|
+
initContainers: [dump],
|
|
242
|
+
containers: [upload],
|
|
243
|
+
volumes: [{ name: "dump", emptyDir: {} }, { name: "tmp", emptyDir: {} }],
|
|
244
|
+
},
|
|
245
|
+
},
|
|
167
246
|
},
|
|
168
247
|
},
|
|
169
248
|
},
|
|
@@ -171,17 +250,16 @@ export function cloneJob(config) {
|
|
|
171
250
|
}
|
|
172
251
|
/**
|
|
173
252
|
* Formats the file system, unless it is formatted already, beside Valkey's server, whose
|
|
174
|
-
* pod is ready only once it is
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* `metaurl` names (neon/control/kube-setup.ts), and the object store as JuiceFS's pods do.
|
|
253
|
+
* pod is ready only once it is, so nothing mounts or sets a quota on one not yet formatted.
|
|
254
|
+
* Formatted with the bucket and its keys; it reaches Valkey on its pod's loopback, in the
|
|
255
|
+
* database the file system's `metaurl` names (neon/control/kube-setup.ts), and the object
|
|
256
|
+
* store as the nodes' mount does.
|
|
179
257
|
*/
|
|
180
258
|
function formatter(config) {
|
|
181
259
|
const credential = (name, key) => ({ name, valueFrom: { secretKeyRef: { name: WORKSPACES_CREDENTIALS, key } } });
|
|
182
260
|
return {
|
|
183
261
|
name: "juicefs-format",
|
|
184
|
-
image: imageReference(config.workspaceStorage.
|
|
262
|
+
image: imageReference(config.workspaceStorage.image),
|
|
185
263
|
imagePullPolicy: "IfNotPresent",
|
|
186
264
|
command: [
|
|
187
265
|
"/bin/sh",
|
|
@@ -201,13 +279,20 @@ function formatter(config) {
|
|
|
201
279
|
resources: { requests: { cpu: "10m", memory: "32Mi" }, limits: { memory: "256Mi" } },
|
|
202
280
|
};
|
|
203
281
|
}
|
|
204
|
-
/** Workspace storage's objects, when it is on: Valkey, the
|
|
282
|
+
/** Workspace storage's objects, when it is on: Valkey, and the jobs that do what a mount's background jobs would. */
|
|
205
283
|
export function workspaceStorageObjects(config) {
|
|
206
284
|
if (!config.workspaceStorage.enabled)
|
|
207
285
|
return [];
|
|
208
286
|
const { valkey } = config.workspaceStorage;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
287
|
+
const instance = {
|
|
288
|
+
name: VALKEY,
|
|
289
|
+
component: "valkey",
|
|
290
|
+
...valkey,
|
|
291
|
+
// The node agents', which set workspaces' quotas: every key, but no command Valkey calls
|
|
292
|
+
// dangerous, those that read or change its server whole, but INFO, which JuiceFS reads its
|
|
293
|
+
// settings in.
|
|
294
|
+
...(nodeAgentRuns(config) ? { besideDefault: [{ name: WORKSPACE_QUOTAS_USER, secret: WORKSPACE_QUOTAS, rules: QUOTAS_RULES }] } : {}),
|
|
295
|
+
};
|
|
296
|
+
return [...valkeyObjects(config, instance, [formatter(config)]), quotaCheck(config), collection(config), metadataDump(config), staleSessions(config)];
|
|
212
297
|
}
|
|
213
298
|
//# sourceMappingURL=workspace-storage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-storage.js","sourceRoot":"","sources":["../../../../src/manifests/workspace-storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace-storage.js","sourceRoot":"","sources":["../../../../src/manifests/workspace-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Effect, Schema } from "effect";
|
|
1
|
+
import { Duration, Effect, Schedule, Schema } from "effect";
|
|
2
2
|
import { runIn, runningPod } from "./commands/common.js";
|
|
3
3
|
import { kind, KubeApi } from "./kube/api.js";
|
|
4
|
+
import { awaitReady } from "./kube/rollout.js";
|
|
4
5
|
import { NAMESPACE, neonName } from "./manifests/common.js";
|
|
5
6
|
/** The configuration asks for fewer of Neon's shards than its tenant has: Neon merges none. */
|
|
6
7
|
export class ShardsLowered extends Schema.TaggedError()("ShardsLowered", { configured: Schema.Number, current: Schema.Number }) {
|
|
@@ -26,12 +27,35 @@ export class StorageUnverified extends Schema.TaggedError()("StorageUnverified",
|
|
|
26
27
|
}
|
|
27
28
|
/** The storage controller's container, as its Deployment runs it. */
|
|
28
29
|
const CONTAINER = "storage-controller";
|
|
30
|
+
/**
|
|
31
|
+
* How long a container of Neon's storage that does not answer yet is asked again, at most, and
|
|
32
|
+
* never past what alasio waits for: one its kubelet has not taken back since the cluster's
|
|
33
|
+
* k3s started anew, which a status from before still says runs.
|
|
34
|
+
*/
|
|
35
|
+
export const NOT_YET_ANSWERING_FOR = Duration.minutes(2);
|
|
36
|
+
/**
|
|
37
|
+
* Whether `error`, of an exec, is of its container's not answering yet, rather than of what it
|
|
38
|
+
* ran: its pod not yet taken back by its kubelet, which answers 404, its container not found,
|
|
39
|
+
* or its connection refused.
|
|
40
|
+
*/
|
|
41
|
+
const notYetAnswering = (error) => error._tag === "KubeApiError" && (error.status === 404 || /\b404\b|container not found|ECONNREFUSED|connection refused/iu.test(error.reason));
|
|
42
|
+
/**
|
|
43
|
+
* `command` run in `target`, as runIn runs it, asked again every `wait.poll` while its
|
|
44
|
+
* container does not answer yet, for NOT_YET_ANSWERING_FOR or `wait.timeout`, whichever is
|
|
45
|
+
* shorter; asked once where nothing is waited for.
|
|
46
|
+
*/
|
|
47
|
+
const runAnswered = (target, command, wait) => wait === undefined
|
|
48
|
+
? runIn(target, command)
|
|
49
|
+
: runIn(target, command).pipe(Effect.retry({
|
|
50
|
+
while: notYetAnswering,
|
|
51
|
+
schedule: Schedule.max([Schedule.spaced(wait.poll), Schedule.during(Duration.min(NOT_YET_ANSWERING_FOR, Duration.fromInputUnsafe(wait.timeout)))]),
|
|
52
|
+
}));
|
|
29
53
|
/** Asks the storage controller for `path` of its API, in its pod: what it answered with, by its status. */
|
|
30
|
-
const asked = (pod, path) =>
|
|
54
|
+
const asked = (pod, path, wait) => runAnswered({ namespace: NAMESPACE, pod, container: CONTAINER },
|
|
31
55
|
// The token is the container's own, which the shell's own printf gives curl on its
|
|
32
56
|
// standard input, so it is on no command line; and a storage controller that does not
|
|
33
57
|
// answer holds up for 10 s at most.
|
|
34
|
-
["sh", "-c", 'printf "authorization: Bearer %s\\n" "$CONTROL_PLANE_JWT_TOKEN" | curl -sS --max-time 10 -H @- -w "\\n%{http_code}" "http://127.0.0.1:1234$0"', path]).pipe(Effect.catch((error) => Effect.fail(new StorageUnverified({ reason: error.message }))), Effect.flatMap(({ exitCode, stdout, stderr }) => {
|
|
58
|
+
["sh", "-c", 'printf "authorization: Bearer %s\\n" "$CONTROL_PLANE_JWT_TOKEN" | curl -sS --max-time 10 -H @- -w "\\n%{http_code}" "http://127.0.0.1:1234$0"', path], wait).pipe(Effect.catch((error) => Effect.fail(new StorageUnverified({ reason: error.message }))), Effect.flatMap(({ exitCode, stdout, stderr }) => {
|
|
35
59
|
if (exitCode !== 0)
|
|
36
60
|
return Effect.fail(new StorageUnverified({ reason: `asking it for ${path} failed (exit ${exitCode}): ${stderr.trim() || stdout.trim()}` }));
|
|
37
61
|
const lines = stdout.trimEnd().split("\n");
|
|
@@ -54,33 +78,33 @@ export class StorageDatabaseUnread extends Schema.TaggedError()("StorageDatabase
|
|
|
54
78
|
}
|
|
55
79
|
}
|
|
56
80
|
/** Asks the storage controller's database `sql`, as its own role, in its pod: what it printed. */
|
|
57
|
-
const askedDatabase = (sql) =>
|
|
81
|
+
const askedDatabase = (sql, wait) => runAnswered({ namespace: NAMESPACE, pod: DATABASE_POD, container: "postgres" }, ["psql", "-U", "storage_controller", "-d", "storage_controller", "-Atc", sql], wait).pipe(Effect.catch((error) => Effect.fail(new StorageDatabaseUnread({ reason: error.message }))), Effect.flatMap(({ exitCode, stdout, stderr }) => exitCode === 0 ? Effect.succeed(stdout.trim()) : Effect.fail(new StorageDatabaseUnread({ reason: `psql exited with ${exitCode}: ${stderr.trim() || stdout.trim()}` }))));
|
|
58
82
|
/**
|
|
59
83
|
* Whether the storage controller has registered a pageserver, as its own database says:
|
|
60
84
|
* none where the database never held anything, its claim never bound, as before alasio first
|
|
61
85
|
* runs, or where it holds no table of nodes, or no node in it; then there is nothing to check
|
|
62
86
|
* a configuration against. One whose claim is bound is asked, and must answer.
|
|
63
87
|
*/
|
|
64
|
-
const registered = Effect.gen(function* () {
|
|
88
|
+
const registered = (wait) => Effect.gen(function* () {
|
|
65
89
|
const kube = yield* KubeApi;
|
|
66
90
|
const claim = yield* kube.get({ ...kind("PersistentVolumeClaim"), namespace: NAMESPACE, name: DATABASE_CLAIM });
|
|
67
91
|
if (claim?.status?.phase !== "Bound" && claim?.status?.phase !== "Lost")
|
|
68
92
|
return false;
|
|
69
|
-
if ((yield* askedDatabase("select to_regclass('nodes') is not null")) !== "t")
|
|
93
|
+
if ((yield* askedDatabase("select to_regclass('nodes') is not null", wait)) !== "t")
|
|
70
94
|
return false;
|
|
71
|
-
return (yield* askedDatabase("select exists (select from nodes)")) === "t";
|
|
95
|
+
return (yield* askedDatabase("select exists (select from nodes)", wait)) === "t";
|
|
72
96
|
});
|
|
73
97
|
/**
|
|
74
98
|
* What Neon's storage holds, as the storage controller says it: null only where it has
|
|
75
99
|
* registered no pageserver; StorageUnverified where it has but does not say, as a
|
|
76
100
|
* configuration it would refuse must not slip through then.
|
|
77
101
|
*/
|
|
78
|
-
const storageHeld = Effect.gen(function* () {
|
|
102
|
+
const storageHeld = (wait) => Effect.gen(function* () {
|
|
79
103
|
const kube = yield* KubeApi;
|
|
80
|
-
if (!(yield* registered))
|
|
104
|
+
if (!(yield* registered(wait)))
|
|
81
105
|
return null;
|
|
82
106
|
const pod = yield* runningPod("neon-storage-controller").pipe(Effect.catch((error) => Effect.fail(new StorageUnverified({ reason: error.message }))));
|
|
83
|
-
const nodes = yield* asked(pod, "/control/v1/node");
|
|
107
|
+
const nodes = yield* asked(pod, "/control/v1/node", wait);
|
|
84
108
|
if (nodes.status !== 200 || !nodes.body)
|
|
85
109
|
return yield* new StorageUnverified({ reason: `it answered its pageservers with ${nodes.status}` });
|
|
86
110
|
const pageservers = nodes.body.length;
|
|
@@ -92,18 +116,34 @@ const storageHeld = Effect.gen(function* () {
|
|
|
92
116
|
}));
|
|
93
117
|
if (!tenantId)
|
|
94
118
|
return { shards: 0, pageservers };
|
|
95
|
-
const tenant = yield* asked(pod, `/control/v1/tenant/${tenantId}
|
|
119
|
+
const tenant = yield* asked(pod, `/control/v1/tenant/${tenantId}`, wait);
|
|
96
120
|
if (tenant.status === 404)
|
|
97
121
|
return { shards: 0, pageservers };
|
|
98
122
|
if (tenant.status !== 200 || !tenant.body)
|
|
99
123
|
return yield* new StorageUnverified({ reason: `it answered Neon's tenant with ${tenant.status}` });
|
|
100
124
|
return { shards: tenant.body.shards.length, pageservers };
|
|
101
125
|
});
|
|
102
|
-
/**
|
|
103
|
-
|
|
126
|
+
/** The storage controller and its database, where the installation has them, waited for until they run, within `wait`. */
|
|
127
|
+
const running = (wait) => Effect.gen(function* () {
|
|
128
|
+
const kube = yield* KubeApi;
|
|
129
|
+
const refs = [
|
|
130
|
+
{ ...kind("StatefulSet"), namespace: NAMESPACE, name: neonName("controller-db") },
|
|
131
|
+
{ ...kind("Deployment"), namespace: NAMESPACE, name: neonName("storage-controller") },
|
|
132
|
+
];
|
|
133
|
+
const there = (yield* Effect.forEach(refs, (ref) => Effect.map(kube.get(ref), (object) => (object === null ? [] : [ref])))).flat();
|
|
134
|
+
yield* awaitReady(there, wait);
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* Refuses `settings` where they ask for fewer of Neon's shards or pageservers than its storage
|
|
138
|
+
* holds, as the module says; the storage controller and its database waited for first, within
|
|
139
|
+
* `wait`, where it is given, as alasio is applied.
|
|
140
|
+
*/
|
|
141
|
+
export const checkNeonStorage = Effect.fnUntraced(function* (settings, wait) {
|
|
104
142
|
if (!settings.neon.enabled)
|
|
105
143
|
return;
|
|
106
|
-
|
|
144
|
+
if (wait)
|
|
145
|
+
yield* running(wait);
|
|
146
|
+
const held = yield* storageHeld(wait);
|
|
107
147
|
if (!held)
|
|
108
148
|
return;
|
|
109
149
|
if (held.shards > settings.neon.shards)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neon-storage.js","sourceRoot":"","sources":["../../../src/neon-storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"neon-storage.js","sourceRoot":"","sources":["../../../src/neon-storage.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/src/release.js
CHANGED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
* version and the digests of the images it published here, with tooling/pin-release.ts,
|
|
4
4
|
* before it builds the package; this module holds nothing else.
|
|
5
5
|
*/
|
|
6
|
-
export const VERSION = "
|
|
6
|
+
export const VERSION = "9.0.0";
|
|
7
7
|
/** alasio's own images, tagged with the version and pinned by digest once released. */
|
|
8
8
|
export const IMAGES = {
|
|
9
|
-
alasio: { repository: "ghcr.io/eaucoin/alasio", tag: VERSION, digest: "sha256:
|
|
10
|
-
agent: { repository: "ghcr.io/eaucoin/alasio-agent", tag: VERSION, digest: "sha256:
|
|
11
|
-
lake: { repository: "ghcr.io/eaucoin/alasio-lake", tag: VERSION, digest: "sha256:
|
|
12
|
-
grafana: { repository: "ghcr.io/eaucoin/alasio-grafana", tag: VERSION, digest: "sha256:
|
|
13
|
-
log: { repository: "ghcr.io/eaucoin/alasio-log", tag: VERSION, digest: "sha256:
|
|
14
|
-
collector: { repository: "ghcr.io/eaucoin/alasio-collector", tag: VERSION, digest: "sha256:
|
|
15
|
-
webhook: { repository: "ghcr.io/eaucoin/alasio-webhook", tag: VERSION, digest: "sha256:
|
|
9
|
+
alasio: { repository: "ghcr.io/eaucoin/alasio", tag: VERSION, digest: "sha256:5f9b5b61b08ddbbb396c4f620b3e3b603908b112cb27dc8bea363b4a98260c67" },
|
|
10
|
+
agent: { repository: "ghcr.io/eaucoin/alasio-agent", tag: VERSION, digest: "sha256:1324275685277b95b631b9c5a98b52f26f0d205bb7eb90ad37dfcdfb18a8fdbd" },
|
|
11
|
+
lake: { repository: "ghcr.io/eaucoin/alasio-lake", tag: VERSION, digest: "sha256:8f9b0e90754ea04ba0208610a65d7b39ed3f440527360cd01bf05eeb3ee34cdc" },
|
|
12
|
+
grafana: { repository: "ghcr.io/eaucoin/alasio-grafana", tag: VERSION, digest: "sha256:f79e081bd77cf4f00467d9581c1a833824396880efbefe9fc77905a9de64e960" },
|
|
13
|
+
log: { repository: "ghcr.io/eaucoin/alasio-log", tag: VERSION, digest: "sha256:d470305c7f2cee9ed471b0be3fdd17f5d650a7b9af1179c923d947c793bb841c" },
|
|
14
|
+
collector: { repository: "ghcr.io/eaucoin/alasio-collector", tag: VERSION, digest: "sha256:7b05fd3c2cc53ffdd38089e649a10d5adfc959183c44bb43e9385c1ba8394660" },
|
|
15
|
+
webhook: { repository: "ghcr.io/eaucoin/alasio-webhook", tag: VERSION, digest: "sha256:59b3be576d3aef73455462dcaf917e71db911f3e5ff4415a7eeb1ebe80cfe1e6" },
|
|
16
16
|
};
|
|
17
17
|
/** The node image of the cluster in Docker: k3s with gVisor (cluster/node), pinned like the others. */
|
|
18
|
-
export const NODE_IMAGE = { repository: "ghcr.io/eaucoin/alasio-node", tag: VERSION, digest: "sha256:
|
|
18
|
+
export const NODE_IMAGE = { repository: "ghcr.io/eaucoin/alasio-node", tag: VERSION, digest: "sha256:fefd11d4bedef3d0961b9f11ab043292df1f3b5667199cbfa4a7ba653fe6985c" };
|
|
19
19
|
//# sourceMappingURL=release.js.map
|