alasio 7.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 +123 -46
- 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 +51 -12
- package/dist/cli/src/cluster/k3s.js.map +1 -1
- package/dist/cli/src/cluster/node.js +115 -33
- 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/init.js +54 -4
- package/dist/cli/src/commands/init.js.map +1 -1
- package/dist/cli/src/commands/lake.js +40 -6
- package/dist/cli/src/commands/lake.js.map +1 -1
- package/dist/cli/src/commands/restore-filer-store.js +40 -8
- package/dist/cli/src/commands/restore-filer-store.js.map +1 -1
- package/dist/cli/src/commands/status.js +216 -20
- 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 +24 -9
- 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 +119 -17
- 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 +11 -5
- package/dist/cli/src/kube/api.js.map +1 -1
- package/dist/cli/src/kube/apply.js +16 -73
- package/dist/cli/src/kube/apply.js.map +1 -1
- package/dist/cli/src/kube/rollout.js +84 -26
- package/dist/cli/src/kube/rollout.js.map +1 -1
- package/dist/cli/src/lake.js +124 -0
- package/dist/cli/src/lake.js.map +1 -0
- package/dist/cli/src/manifests/admission.js +381 -223
- package/dist/cli/src/manifests/admission.js.map +1 -1
- package/dist/cli/src/manifests/alasio.js +79 -362
- 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 +250 -135
- 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 +256 -92
- 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 +15 -8
- package/dist/cli/src/manifests/index.js.map +1 -1
- package/dist/cli/src/manifests/keda.js +2 -1
- package/dist/cli/src/manifests/keda.js.map +1 -1
- package/dist/cli/src/manifests/lake.js +350 -73
- package/dist/cli/src/manifests/lake.js.map +1 -1
- package/dist/cli/src/manifests/log.js +316 -0
- package/dist/cli/src/manifests/log.js.map +1 -0
- package/dist/cli/src/manifests/neon.js +128 -49
- package/dist/cli/src/manifests/neon.js.map +1 -1
- package/dist/cli/src/manifests/network-policies.js +263 -100
- package/dist/cli/src/manifests/network-policies.js.map +1 -1
- package/dist/cli/src/manifests/node-agent.js +24 -8
- 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/webhook.js +102 -0
- package/dist/cli/src/manifests/webhook.js.map +1 -0
- 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 +155 -0
- package/dist/cli/src/neon-storage.js.map +1 -0
- package/dist/cli/src/release.js +9 -6
- package/dist/cli/src/release.js.map +1 -1
- package/dist/cli/src/secrets.js +45 -4
- package/dist/cli/src/secrets.js.map +1 -1
- package/dist/cli/src/target.js +1 -1
- package/dist/cli/src/target.js.map +1 -1
- package/dist/cli/src/telegram.js +56 -10
- package/dist/cli/src/telegram.js.map +1 -1
- package/dist/cli/src/webhook.js +182 -0
- package/dist/cli/src/webhook.js.map +1 -0
- package/dist/cluster/node/pins.json +12 -2
- package/dist/neon/control/branches.js +126 -21
- package/dist/neon/control/branches.js.map +1 -1
- package/dist/neon/control/endpoints.js +9 -0
- package/dist/neon/control/endpoints.js.map +1 -1
- package/dist/neon/control/jwt.js +16 -3
- package/dist/neon/control/jwt.js.map +1 -1
- package/dist/neon/control/secrets.js +51 -7
- 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 +19 -69
- package/dist/src/kube/sandbox-shape.js.map +1 -1
- package/dist/src/node-agent/names.js +118 -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/telegram/deliveries.js +40 -0
- package/dist/src/telegram/deliveries.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 -319
- 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 -143
- package/dist/src/kube/config.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/manifests/common.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../../src/manifests/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -117,8 +117,8 @@ const Alasio = Schema.Struct({
|
|
|
117
117
|
});
|
|
118
118
|
/**
|
|
119
119
|
* alasio's telemetry: everything (alasio's, its harnesses', bayma's, the lake's and the
|
|
120
|
-
* stack's) goes through the stack's collector to the lake, and to
|
|
121
|
-
* one is set.
|
|
120
|
+
* stack's) goes through the stack's collector, by the log, to the lake, and to
|
|
121
|
+
* otlpEndpoint too when one is set.
|
|
122
122
|
*/
|
|
123
123
|
const Telemetry = Schema.Struct({
|
|
124
124
|
/** Where the collector also sends all it receives; empty sends it to the lake alone. */
|
|
@@ -128,18 +128,22 @@ const Telemetry = Schema.Struct({
|
|
|
128
128
|
headersSecret: defaulted(OptionalSecretName, ""),
|
|
129
129
|
headersKey: defaulted(NonEmpty, "headers"),
|
|
130
130
|
resourceAttributes: defaulted(Schema.String, ""),
|
|
131
|
-
/** The port
|
|
131
|
+
/** The port the sandbox service's receiver takes session sandboxes' telemetry on. */
|
|
132
132
|
receiverPort: defaulted(Schema.Int.check(Schema.isBetween({ minimum: 1024, maximum: 65535 }, { message: "must be a port from 1024 to 65535" })), 4318),
|
|
133
133
|
/** How many days of telemetry the lake keeps. */
|
|
134
134
|
retentionDays: defaulted(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1, { message: "must be at least 1" })), 30),
|
|
135
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* The stack's collector, through which all of it goes, in two parts on one image
|
|
137
|
+
* (images.collector): its gateway, which every producer exports to and which writes it to
|
|
138
|
+
* the log, scaling on its CPU where min and max are apart; and its scraper, one replica,
|
|
139
|
+
* which scrapes the stack and exports what it scrapes to the gateway.
|
|
140
|
+
*/
|
|
136
141
|
collector: defaulted(Schema.Struct({
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}),
|
|
142
|
-
resources: Resources({ requests: { cpu: "50m", memory: "128Mi" }, limits: { memory: "512Mi" } }),
|
|
142
|
+
gateway: defaulted(Schema.Struct({
|
|
143
|
+
scaling: Scaling({ min: 1, max: 1 }, { floor: true, scaled: true }),
|
|
144
|
+
resources: Resources({ requests: { cpu: "50m", memory: "96Mi" }, limits: { memory: "512Mi" } }),
|
|
145
|
+
}), {}),
|
|
146
|
+
scraper: defaulted(Schema.Struct({ resources: Resources({ requests: { cpu: "50m", memory: "128Mi" }, limits: { memory: "512Mi" } }) }), {}),
|
|
143
147
|
}), {}),
|
|
144
148
|
});
|
|
145
149
|
/**
|
|
@@ -147,8 +151,44 @@ const Telemetry = Schema.Struct({
|
|
|
147
151
|
* (sessions.runtimeClassName), by the node agent on each node sessions run on.
|
|
148
152
|
*/
|
|
149
153
|
const Snapshots = Schema.Struct({
|
|
150
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* How long a session's bayma runs no exec before its sandbox is snapshotted and its pod let
|
|
156
|
+
* go: a duration such as 5m. Until then its pod is evicted by no drain, and its node is
|
|
157
|
+
* removed by no node autoscaler (cli/src/manifests/disruption.ts boundBudget), so a drain
|
|
158
|
+
* waits this long after a session's last exec, and longer for a session that goes on working.
|
|
159
|
+
*/
|
|
151
160
|
releaseAfter: defaulted(Schema.String.check(Schema.makeFilter((duration) => (durationSeconds(duration) ?? 0) > 0 || "must be a duration such as 5m")), "5m"),
|
|
161
|
+
/**
|
|
162
|
+
* How often a session whose execs run is snapshotted live, its sandbox running on, from
|
|
163
|
+
* that long after they began: the snapshot its pod, ended where it is, is restored from,
|
|
164
|
+
* while bayma's state generation is still the one it caught. A duration such as 10m.
|
|
165
|
+
*/
|
|
166
|
+
liveEvery: defaulted(Schema.String.check(Schema.makeFilter((duration) => (durationSeconds(duration) ?? 0) > 0 || "must be a duration such as 10m")), "10m"),
|
|
167
|
+
/**
|
|
168
|
+
* How long a session's bayma holds its stop when its pod is ended by other than alasio,
|
|
169
|
+
* as a drain, another eviction through the API server (a preemption's, a NoExecute
|
|
170
|
+
* taint's) or a deletion ends it, for alasio to snapshot it first as it releases a session
|
|
171
|
+
* (bayma's --stop-wait-ms): its pod's grace period is this and 30 s more for bayma's own
|
|
172
|
+
* stop. More than 15 s, as alasio looks for ending pods every 15 s, and at most 10m, as a
|
|
173
|
+
* drain waits on each pod. The node agents run as a DaemonSet, which a drain leaves in
|
|
174
|
+
* place. Each node snapshots two such sessions at a time, the others waiting their turn; one
|
|
175
|
+
* whose snapshot fails, or whose turn comes once its bayma holds its stop no more, comes
|
|
176
|
+
* back from bayma's checkpoints. A pod that ends where it is, with no grace or the kubelet's
|
|
177
|
+
* own, as its sandbox's crash, an OOM kill, an eviction for the node's pressure, soft or
|
|
178
|
+
* hard, or a graceful shutdown of its node ends it, takes no snapshot: the kubelet deletes
|
|
179
|
+
* no pod first, and says why it ends one only once it has ended. The next turn brings it
|
|
180
|
+
* back from its live snapshot while that still holds it, and otherwise from bayma's
|
|
181
|
+
* checkpoints. A pod deleted outright, as kubectl delete --force or the removal of its Node
|
|
182
|
+
* deletes it, or one ended that alasio is not running to see, as on a single node that a
|
|
183
|
+
* drain empties of alasio too, the gateway releases as broken, and the next turn binds
|
|
184
|
+
* another, whose bayma starts from its checkpoints, moving on from its live snapshot, which
|
|
185
|
+
* no restore takes after. A duration
|
|
186
|
+
* such as 60s.
|
|
187
|
+
*/
|
|
188
|
+
stopWait: defaulted(Schema.String.check(Schema.makeFilter((duration) => {
|
|
189
|
+
const seconds = durationSeconds(duration) ?? 0;
|
|
190
|
+
return (seconds > 15 && seconds <= 600) || "must be a duration of more than 15s and at most 10m, such as 60s";
|
|
191
|
+
})), "60s"),
|
|
152
192
|
/** The most of snapshots each node keeps on its disk, for restores there. */
|
|
153
193
|
nodeCache: defaulted(Size, "5Gi"),
|
|
154
194
|
/**
|
|
@@ -160,17 +200,91 @@ const Snapshots = Schema.Struct({
|
|
|
160
200
|
*/
|
|
161
201
|
nodeAgent: defaulted(Schema.Struct({ resources: Resources({ requests: { cpu: "20m", memory: "160Mi" }, limits: { memory: "512Mi" } }) }), {}),
|
|
162
202
|
});
|
|
203
|
+
/**
|
|
204
|
+
* The webhook intake (./webhook.ts), the one thing of alasio's the internet reaches,
|
|
205
|
+
* which Telegram delivers each environment's bot's updates to, on `port` of
|
|
206
|
+
* `publicAddress`, over HTTPS with a certificate of its own that alasio uploads to
|
|
207
|
+
* Telegram as it registers each bot. How it is reached its target makes (`exposure`,
|
|
208
|
+
* alasio's own to say): on this machine's address, from k3s on it, which then needs
|
|
209
|
+
* `publicAddress` to be that address, and binds it alone, leaving the machine's other
|
|
210
|
+
* addresses' port to whatever has it; on its node's, in Docker, whose port the machine
|
|
211
|
+
* maps; or through a LoadBalancer Service. `publicAddress` is the address Telegram is told,
|
|
212
|
+
* which its certificate is made for: the machine's, or the LoadBalancer's, or a name of
|
|
213
|
+
* either. On a machine's or a node's address it runs one replica. `sources` are the
|
|
214
|
+
* networks it takes its port from on this machine's address or a LoadBalancer's, its
|
|
215
|
+
* NetworkPolicy's and the LoadBalancer's: Telegram's, as its Bot API's guide to webhooks
|
|
216
|
+
* lists them (core.telegram.org/bots/webhooks), which Telegram may change; a change shows
|
|
217
|
+
* in each bot's getWebhookInfo as a last error, which alasio logs and alasio status says,
|
|
218
|
+
* each pointing here, where it is set.
|
|
219
|
+
*/
|
|
220
|
+
const Webhook = Schema.Struct({
|
|
221
|
+
publicAddress: defaulted(matching(/^(|(\d{1,3}\.){3}\d{1,3}|[a-z0-9]([-a-z0-9.]{0,251}[a-z0-9])?)$/u, "must be an IPv4 address or a host name, or empty"), ""),
|
|
222
|
+
/** One of the ports Telegram delivers to. */
|
|
223
|
+
port: defaulted(Schema.Literals([443, 80, 88, 8443]), 443),
|
|
224
|
+
exposure: defaulted(Schema.Literals(["hostAddress", "node", "loadBalancer"]), "node"),
|
|
225
|
+
sources: defaulted(Schema.Array(matching(/^[0-9.]+\/[0-9]{1,2}$/u, "must be an IPv4 CIDR")).check(Schema.isMinLength(1, { message: "must list a network at least" })), ["149.154.160.0/20", "91.108.4.0/22"]),
|
|
226
|
+
scaling: Scaling({ min: 1, max: 1 }, { floor: true, scaled: false }),
|
|
227
|
+
resources: Resources({ requests: { cpu: "10m", memory: "48Mi" }, limits: { memory: "192Mi" } }),
|
|
228
|
+
});
|
|
229
|
+
/**
|
|
230
|
+
* The least memory the log's broker is given: the heap of 512 MiB it is run at (./log.ts),
|
|
231
|
+
* and the JVM's own beside it.
|
|
232
|
+
*/
|
|
233
|
+
export const LOG_MEMORY = "768Mi";
|
|
234
|
+
/** A segment of the log's partitions at most: what its retention deletes at once, a closed one. */
|
|
235
|
+
export const LOG_SEGMENT_BYTES = 64 * 1024 * 1024;
|
|
236
|
+
/** How many partitions the log's telemetry topics have together: three topics, of as many as the lake's intake runs replicas at most. */
|
|
237
|
+
const telemetryPartitions = (config) => 3 * Math.max(1, config.lake.intake.scaling.max);
|
|
238
|
+
/**
|
|
239
|
+
* How many bytes each partition of the log's telemetry topics keeps at most: three
|
|
240
|
+
* quarters of a node's volume shared among them, the rest Telegram's topics' and KRaft's,
|
|
241
|
+
* less the segment each writes beside those it keeps, as retention deletes closed segments
|
|
242
|
+
* alone.
|
|
243
|
+
*/
|
|
244
|
+
/** How much longer than the filer store's backups go back the log keeps its records: the day a restore and the lake's reconciliation take, and more. */
|
|
245
|
+
export const LOG_RETENTION_MARGIN_HOURS = 24;
|
|
246
|
+
/**
|
|
247
|
+
* How far back the filer store's backups go, in hours: `keep` of them, taken on `schedule`
|
|
248
|
+
* at a fixed minute of every hour, of every Nth hour, or of a fixed hour each day; null for a
|
|
249
|
+
* schedule of another form, which is not known so.
|
|
250
|
+
*/
|
|
251
|
+
export function filerStoreBackupHours({ schedule, keep }) {
|
|
252
|
+
const [minute = "", hour = "", ...rest] = schedule.trim().split(/\s+/u);
|
|
253
|
+
if (rest.length !== 3 || rest.some((field) => field !== "*") || !/^[0-9]+$/u.test(minute))
|
|
254
|
+
return null;
|
|
255
|
+
const every = hour === "*" ? 1 : /^\*\/([1-9][0-9]*)$/u.exec(hour)?.[1];
|
|
256
|
+
if (every !== undefined)
|
|
257
|
+
return Number(every) * keep;
|
|
258
|
+
return /^[0-9]+$/u.test(hour) ? 24 * keep : null;
|
|
259
|
+
}
|
|
260
|
+
export function telemetryRetentionBytes(config) {
|
|
261
|
+
return Math.floor((memoryBytes(config.log.storage.size) * 3) / 4 / telemetryPartitions(config)) - LOG_SEGMENT_BYTES;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* The log (./log.ts), beside Neon: Apache Kafka in KRaft, its partitions' segments on a
|
|
265
|
+
* volume of each of its nodes, which KRaft's metadata, its principals and ACLs among it,
|
|
266
|
+
* is on too. Its nodes are brokers and KRaft's controllers both, 1, or 3 in a quorum, their
|
|
267
|
+
* count set as the log is made and never changed after, as KRaft's voters are fixed. It is
|
|
268
|
+
* a buffer, not a store: what it holds is kept for `retention`, within its volume, the lake
|
|
269
|
+
* keeping what is read from it. That is also what the lake's telemetry is refilled from where
|
|
270
|
+
* the lake loses files, as a restore of the filer store's oldest backup loses what was written
|
|
271
|
+
* since (filerStoreBackupHours): so it keeps them, and a day more, LOG_RETENTION_MARGIN_HOURS.
|
|
272
|
+
*/
|
|
273
|
+
const Log = Schema.Struct({
|
|
274
|
+
scaling: Scaling({ min: 1, max: 1 }, { floor: true, scaled: false, most: 3 }),
|
|
275
|
+
retention: defaulted(matching(/^[1-9][0-9]*h$/u, "must be a number of hours, such as 24h"), "72h"),
|
|
276
|
+
storage: Storage("4Gi"),
|
|
277
|
+
resources: Resources({ requests: { cpu: "100m", memory: "512Mi" }, limits: { memory: "1Gi" } }),
|
|
278
|
+
});
|
|
163
279
|
const Sessions = Schema.Struct({
|
|
164
280
|
enabled: defaulted(Schema.Boolean, true),
|
|
165
281
|
namespace: defaulted(Namespace, "alasio-sessions"),
|
|
166
282
|
createNamespace: defaulted(Schema.Boolean, true),
|
|
167
283
|
/** The RuntimeClass sessions run under; empty runs them under the cluster's default runtime. */
|
|
168
284
|
runtimeClassName: defaulted(Schema.String, "gvisor"),
|
|
169
|
-
/** A new session's
|
|
170
|
-
storage:
|
|
285
|
+
/** A new session's workspace: its quota, of workspace storage. */
|
|
286
|
+
storage: defaulted(Schema.Struct({ size: defaulted(Size, "10Gi") }), {}),
|
|
171
287
|
resources: Resources({ requests: { cpu: "250m", memory: "512Mi" }, limits: { cpu: "2", memory: "2Gi" } }),
|
|
172
|
-
/** Whether a session's pod waits until NetworkPolicy confines it. */
|
|
173
|
-
egressGate: defaulted(Schema.Boolean, true),
|
|
174
288
|
/** The resolvers sessions with internet access use. */
|
|
175
289
|
fullModeNameservers: defaulted(Schema.Array(Schema.String.check(Schema.makeFilter((address) => isIPv4(address) || "must be an IPv4 address"))).check(Schema.isMinLength(1, { message: "must list from one to three resolvers" }), Schema.isMaxLength(3, { message: "must list from one to three resolvers" })), ["1.1.1.1", "8.8.8.8"]),
|
|
176
290
|
/** What sessions with internet access may not reach. */
|
|
@@ -178,17 +292,29 @@ const Sessions = Schema.Struct({
|
|
|
178
292
|
nodeSelector: NodeSelector,
|
|
179
293
|
tolerations: Tolerations,
|
|
180
294
|
snapshots: defaulted(Snapshots, {}),
|
|
295
|
+
/**
|
|
296
|
+
* The sandbox pools' free pods, of each of a session's internets (cli/src/manifests/
|
|
297
|
+
* sandbox-gateway.ts): `min` kept running before any is bound, more made, to `max`, for
|
|
298
|
+
* the binds that wait for one.
|
|
299
|
+
*/
|
|
300
|
+
pools: Scaling({ min: 1, max: 10 }, { floor: false, scaled: true }),
|
|
301
|
+
/** The sandbox gateway, which binds a session's workspace to a pool's pod. */
|
|
302
|
+
gateway: defaulted(Schema.Struct({ resources: Resources({ requests: { cpu: "20m", memory: "96Mi" }, limits: { memory: "256Mi" } }) }), {}),
|
|
303
|
+
/** The session telemetry receiver, which bound pods' bayma exports to. */
|
|
304
|
+
receiver: defaulted(Schema.Struct({ resources: Resources({ requests: { cpu: "20m", memory: "96Mi" }, limits: { memory: "256Mi" } }) }), {}),
|
|
181
305
|
});
|
|
306
|
+
/** The bayma the host profile's folder instances run, as this release pins it. */
|
|
307
|
+
export const HOST_BAYMA_IMAGE = {
|
|
308
|
+
repository: "ghcr.io/eaucoin/bayma",
|
|
309
|
+
tag: "0.14.6",
|
|
310
|
+
digest: "sha256:13b6943969e77e5681a47d53ccd77850ef755f2c0ed280d8e39db97851f79e42",
|
|
311
|
+
};
|
|
182
312
|
const Host = Schema.Struct({
|
|
183
313
|
/** The host profile: folder workspaces on the machine's own files. Privileged, for a single-node cluster the operator owns. */
|
|
184
314
|
enabled: defaulted(Schema.Boolean, false),
|
|
185
315
|
namespace: defaulted(Namespace, "alasio-host"),
|
|
186
316
|
createNamespace: defaulted(Schema.Boolean, true),
|
|
187
|
-
baymaImage: Image(
|
|
188
|
-
repository: "ghcr.io/eaucoin/bayma",
|
|
189
|
-
tag: "0.13.0",
|
|
190
|
-
digest: "sha256:840bfbbb660c5a0fefb562448db2ee93ceef3715142e538c7717ef9c34f3acc1",
|
|
191
|
-
}),
|
|
317
|
+
baymaImage: Image(HOST_BAYMA_IMAGE),
|
|
192
318
|
/** The operator's user and home, which alasio and each folder's bayma run as and in. */
|
|
193
319
|
uid: defaulted(Id, 1000),
|
|
194
320
|
gid: defaulted(Id, 1000),
|
|
@@ -196,6 +322,8 @@ const Host = Schema.Struct({
|
|
|
196
322
|
home: defaulted(AbsolutePath, "/home/operator"),
|
|
197
323
|
/** Where folder workspaces' bayma keeps its state, under a mount. */
|
|
198
324
|
stateRoot: defaulted(AbsolutePath, "/home/operator/.alasio/bayma"),
|
|
325
|
+
/** How long a folder conversation's instance runs no exec before it is released, its REPL sessions saved whole as it stops (src/gateway/folders.ts). */
|
|
326
|
+
releaseAfter: defaulted(Schema.String.check(Schema.makeFilter((duration) => (durationSeconds(duration) ?? 0) > 0 || "must be a duration such as 1h")), "1h"),
|
|
199
327
|
mounts: defaulted(Schema.Array(HostMount), []),
|
|
200
328
|
/** The directory folder workspaces are created under, a path of the mounts; empty leaves alasio's default. */
|
|
201
329
|
workspaceRoot: defaulted(matching(/^(|\/.*)$/u, "must be an absolute path, or empty"), ""),
|
|
@@ -210,7 +338,10 @@ const NeonStored = (size, resources) => defaulted(Schema.Struct({ storage: Stora
|
|
|
210
338
|
const NeonService = (resources) => defaulted(Schema.Struct({ resources: Resources(resources) }), {});
|
|
211
339
|
const Neon = Schema.Struct({
|
|
212
340
|
enabled: defaulted(Schema.Boolean, true),
|
|
213
|
-
/**
|
|
341
|
+
/**
|
|
342
|
+
* Without Neon, alasio's database: a Secret with `url`, `lake-verifier` and `harness-verifier`, the SCRAM verifiers
|
|
343
|
+
* of the lake role's password and the harness host's.
|
|
344
|
+
*/
|
|
214
345
|
external: defaulted(Schema.Struct({ existingSecret: defaulted(OptionalSecretName, "") }), {}),
|
|
215
346
|
image: Image({
|
|
216
347
|
repository: "neondatabase/neon",
|
|
@@ -236,7 +367,15 @@ const Neon = Schema.Struct({
|
|
|
236
367
|
storage: Storage("20Gi"),
|
|
237
368
|
resources: Resources({ requests: { cpu: "50m", memory: "64Mi" }, limits: { memory: "1Gi" } }),
|
|
238
369
|
}), {}),
|
|
239
|
-
pageserver:
|
|
370
|
+
pageserver: defaulted(Schema.Struct({
|
|
371
|
+
/**
|
|
372
|
+
* How many pageservers serve the tenant's shards: a count, each registering itself
|
|
373
|
+
* with the storage controller, which keeps it; lowered, alasio up refuses, saying so.
|
|
374
|
+
*/
|
|
375
|
+
scaling: Scaling({ min: 1, max: 1 }, { floor: true, scaled: false }),
|
|
376
|
+
storage: Storage("50Gi"),
|
|
377
|
+
resources: Resources({ requests: { cpu: "100m", memory: "256Mi" }, limits: { memory: "4Gi" } }),
|
|
378
|
+
}), {}),
|
|
240
379
|
storageController: NeonService({ requests: { cpu: "20m", memory: "64Mi" }, limits: { memory: "512Mi" } }),
|
|
241
380
|
storageBroker: NeonService({ requests: { cpu: "20m", memory: "32Mi" }, limits: { memory: "256Mi" } }),
|
|
242
381
|
controllerDb: NeonStored("2Gi", { requests: { cpu: "50m", memory: "64Mi" }, limits: { memory: "512Mi" } }),
|
|
@@ -255,6 +394,14 @@ const Neon = Schema.Struct({
|
|
|
255
394
|
suspendAfter: defaulted(Schema.String.check(Schema.makeFilter((duration) => (durationSeconds(duration) ?? 0) >= 60 || "must be a duration of 1m or more, such as 5m")), "5m"),
|
|
256
395
|
resources: Resources({ requests: { cpu: "250m", memory: "384Mi" }, limits: { memory: "4Gi" } }),
|
|
257
396
|
}), {}),
|
|
397
|
+
/**
|
|
398
|
+
* How many shards the storage controller splits alasio's tenant into, across the
|
|
399
|
+
* pageservers: a power of two, at most 16. A split is one-way, as Neon merges no shards:
|
|
400
|
+
* raised, the tenant is split; lowered, alasio up refuses, saying so.
|
|
401
|
+
*/
|
|
402
|
+
shards: defaulted(Schema.Int.check(Schema.makeFilter((shards) => (shards >= 1 && shards <= 16 && (shards & (shards - 1)) === 0) || "must be a power of two from 1 to 16")), 1),
|
|
403
|
+
/** Each branch's read replica, which its lake loads from, beside its primary: smaller, as it serves the loader alone. */
|
|
404
|
+
readReplica: defaulted(Schema.Struct({ resources: Resources({ requests: { cpu: "100m", memory: "192Mi" }, limits: { memory: "1Gi" } }) }), {}),
|
|
258
405
|
/**
|
|
259
406
|
* A daily logical dump of alasio's database to the object store, and a copy of
|
|
260
407
|
* JuiceFS's newest dump of workspace storage's metadata beside it; of each, the last
|
|
@@ -398,50 +545,23 @@ export function durationSeconds(duration) {
|
|
|
398
545
|
return null;
|
|
399
546
|
return Number(match[1] ?? 0) * 3600 + Number(match[2] ?? 0) * 60 + Number(match[3] ?? 0);
|
|
400
547
|
}
|
|
401
|
-
/** A component of JuiceFS's CSI driver: its resources. */
|
|
402
|
-
const CsiComponent = (resources) => defaulted(Schema.Struct({ resources: Resources(resources) }), {});
|
|
403
548
|
/**
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
549
|
+
* The cron schedule of something done every `duration`: of whole minutes, 5 or more, that
|
|
550
|
+
* divide an hour, at those minutes of each hour; of whole hours that divide a day, on the
|
|
551
|
+
* hour, at those hours of each day; null for another, which no cron line keeps evenly. Pure, for tests.
|
|
407
552
|
*/
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
tag: "ce-v1.4.1",
|
|
421
|
-
digest: "sha256:ab99388a397fe52575fdeb84a9e017c3c594a6b07d63966cd4805bbf6f172673",
|
|
422
|
-
}),
|
|
423
|
-
registrarImage: Image({
|
|
424
|
-
repository: "registry.k8s.io/sig-storage/csi-node-driver-registrar",
|
|
425
|
-
tag: "v2.9.0",
|
|
426
|
-
digest: "sha256:cd21e19cd8bbd5bc56f1b4f1398a436e7897da2995d6d036c9729be3f4e456e6",
|
|
427
|
-
}),
|
|
428
|
-
resizerImage: Image({
|
|
429
|
-
repository: "registry.k8s.io/sig-storage/csi-resizer",
|
|
430
|
-
tag: "v1.9.0",
|
|
431
|
-
digest: "sha256:f1f352df97874442624fcef23eab04aa038f66cb0e361212f6ec09e92998184d",
|
|
432
|
-
}),
|
|
433
|
-
livenessProbeImage: Image({
|
|
434
|
-
repository: "registry.k8s.io/sig-storage/livenessprobe",
|
|
435
|
-
tag: "v2.11.0",
|
|
436
|
-
digest: "sha256:82adbebdf5d5a1f40f246aef8ddbee7f89dea190652aefe83336008e69f9a89f",
|
|
437
|
-
}),
|
|
438
|
-
controller: CsiComponent({ requests: { cpu: "20m", memory: "64Mi" }, limits: { memory: "512Mi" } }),
|
|
439
|
-
node: CsiComponent({ requests: { cpu: "20m", memory: "64Mi" }, limits: { memory: "512Mi" } }),
|
|
440
|
-
/** Each mount pod's: no CPU limit, which JuiceFS advises against below 4, and memory for its buffer and cache index. */
|
|
441
|
-
mountPod: CsiComponent({ requests: { cpu: "20m", memory: "128Mi" }, limits: { memory: "1Gi" } }),
|
|
442
|
-
/** One mount pod per node for every workspace rather than one per workspace: less memory, and a crash reaches each workspace on the node. */
|
|
443
|
-
shareMountPod: defaulted(Schema.Boolean, false),
|
|
444
|
-
});
|
|
553
|
+
export function everyIntervalCron(duration) {
|
|
554
|
+
const seconds = durationSeconds(duration);
|
|
555
|
+
if (seconds === null || seconds < 300 || seconds % 60 !== 0)
|
|
556
|
+
return null;
|
|
557
|
+
const minutes = seconds / 60;
|
|
558
|
+
if (minutes < 60)
|
|
559
|
+
return 60 % minutes === 0 ? `*/${minutes} * * * *` : null;
|
|
560
|
+
const hours = minutes / 60;
|
|
561
|
+
if (!Number.isInteger(hours) || 24 % hours !== 0)
|
|
562
|
+
return null;
|
|
563
|
+
return hours === 24 ? "0 0 * * *" : `0 */${hours} * * *`;
|
|
564
|
+
}
|
|
445
565
|
/** Valkey, the file system's metadata engine. */
|
|
446
566
|
const Valkey = Schema.Struct({
|
|
447
567
|
image: Image(VALKEY_IMAGE),
|
|
@@ -452,40 +572,30 @@ const Valkey = Schema.Struct({
|
|
|
452
572
|
resources: Resources({ requests: { cpu: "20m", memory: "64Mi" }, limits: { memory: "768Mi" } }),
|
|
453
573
|
});
|
|
454
574
|
/**
|
|
455
|
-
* Workspace storage: each
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
* made with either way.
|
|
575
|
+
* Workspace storage: each session's workspace a directory of one JuiceFS file system, its
|
|
576
|
+
* metadata in a Valkey of alasio's own and its data in the object store's `workspaces`
|
|
577
|
+
* bucket, which each node mounts whole (./sandbox-gateway.ts workspaceMount). The sandbox
|
|
578
|
+
* service runs on it alone.
|
|
460
579
|
*/
|
|
461
580
|
const WorkspaceStorage = Schema.Struct({
|
|
462
581
|
enabled: defaulted(Schema.Boolean, true),
|
|
463
582
|
/** The file system's name, which its data is kept under in the bucket. */
|
|
464
583
|
name: defaulted(matching(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/u, "must be a JuiceFS file system name"), "workspaces"),
|
|
465
|
-
/** The StorageClass of its volumes, which sessions' claims are of unless sessions.storage names another. */
|
|
466
|
-
storageClassName: defaulted(matching(NAME, "must be a StorageClass name"), "alasio-workspaces"),
|
|
467
584
|
/** How many days a deleted file is kept in the file system's trash, 0 for none; set as the file system is first made. */
|
|
468
585
|
trashDays: defaulted(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0, { message: "must be 0 or more" })), 1),
|
|
469
|
-
/** How often
|
|
470
|
-
backupInterval: defaulted(Schema.String.check(Schema.makeFilter((duration) => (
|
|
586
|
+
/** How often the file system's metadata is dumped to its bucket's meta/ (./workspace-storage.ts metadataDump): a schedule a cron line keeps, as everyIntervalCron says. */
|
|
587
|
+
backupInterval: defaulted(Schema.String.check(Schema.makeFilter((duration) => everyIntervalCron(duration) !== null || "must be 5m or more, of whole minutes that divide an hour or whole hours that divide a day, such as 1h")), "1h"),
|
|
471
588
|
/** Each mount's read cache on its node's disk, in MiB. */
|
|
472
589
|
cacheSizeMiB: defaulted(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0, { message: "must be 0 or more" })), 1024),
|
|
473
|
-
|
|
590
|
+
/** JuiceFS's command line, Community Edition, which its admin jobs run: of the version the nodes' mount is (../../../Dockerfile). */
|
|
591
|
+
image: Image({
|
|
592
|
+
repository: "juicedata/mount",
|
|
593
|
+
tag: "ce-v1.4.1",
|
|
594
|
+
digest: "sha256:ab99388a397fe52575fdeb84a9e017c3c594a6b07d63966cd4805bbf6f172673",
|
|
595
|
+
}),
|
|
474
596
|
valkey: defaulted(Valkey, {}),
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const AgentSandbox = Schema.Struct({
|
|
478
|
-
enabled: defaulted(Schema.Boolean, true),
|
|
479
|
-
image: defaulted(Schema.Struct({
|
|
480
|
-
repository: defaulted(NonEmpty, "registry.k8s.io/agent-sandbox/agent-sandbox-controller"),
|
|
481
|
-
tag: defaulted(Schema.String, "v1.0.5"),
|
|
482
|
-
digest: defaulted(Digest, "sha256:28a9cbdbfd6ac0a4e5c7e9261ace1aa30ee2da681cb640dccdfed98e8dd9d98b"),
|
|
483
|
-
pullPolicy: defaulted(PullPolicy, "IfNotPresent"),
|
|
484
|
-
}), {}),
|
|
485
|
-
resources: Resources({ requests: { cpu: "20m", memory: "32Mi" }, limits: { memory: "256Mi" } }),
|
|
486
|
-
nodeSelector: NodeSelector,
|
|
487
|
-
tolerations: Tolerations,
|
|
488
|
-
affinity: Affinity,
|
|
597
|
+
/** Each node's mount of the file system, which the node agent attaches session workspaces from (./sandbox-gateway.ts). */
|
|
598
|
+
mount: defaulted(Schema.Struct({ resources: Resources({ requests: { cpu: "50m", memory: "128Mi" }, limits: { memory: "1Gi" } }) }), {}),
|
|
489
599
|
});
|
|
490
600
|
/** A container of a controller alasio installs: its pinned image and its resources. */
|
|
491
601
|
const ControllerContainer = (image, resources) => defaulted(Schema.Struct({ image: Image(image), resources: Resources(resources) }), {});
|
|
@@ -546,6 +656,13 @@ function completeness(config) {
|
|
|
546
656
|
if (!config.neon.enabled && !config.neon.external.existingSecret) {
|
|
547
657
|
return { path: ["neon", "external", "existingSecret"], issue: "is required when neon.enabled is false" };
|
|
548
658
|
}
|
|
659
|
+
const { webhook } = config;
|
|
660
|
+
if (webhook.exposure === "hostAddress" && webhook.publicAddress && !/^(\d{1,3}\.){3}\d{1,3}$/u.test(webhook.publicAddress)) {
|
|
661
|
+
return { path: ["webhook", "publicAddress"], issue: "must be this machine's public IPv4 address, which Telegram delivers to and the webhook intake binds alone: alasio init finds it" };
|
|
662
|
+
}
|
|
663
|
+
if (webhook.exposure !== "loadBalancer" && webhook.scaling.min > 1) {
|
|
664
|
+
return { path: ["webhook", "scaling"], issue: "must be 1 where the webhook intake binds its node's port, which one pod holds" };
|
|
665
|
+
}
|
|
549
666
|
if (config.neon.enabled && !config.objectStore.bundled.enabled) {
|
|
550
667
|
if (!config.objectStore.external.endpoint)
|
|
551
668
|
return { path: ["objectStore", "external", "endpoint"], issue: "is required when objectStore.bundled.enabled is false" };
|
|
@@ -581,6 +698,26 @@ function completeness(config) {
|
|
|
581
698
|
issue: `must be at least ${memoryText(NODE_AGENT_MEMORY_FLOOR)}: the node agent's own memory, and what a restore holds written and not yet on the disk`,
|
|
582
699
|
};
|
|
583
700
|
}
|
|
701
|
+
if (config.log.scaling.min === 2)
|
|
702
|
+
return { path: ["log", "scaling"], issue: "must be 1 or 3: two of KRaft's voters elect no leader once one is gone" };
|
|
703
|
+
if (memoryBytes(config.log.resources.limits["memory"] ?? "0") < memoryBytes(LOG_MEMORY)) {
|
|
704
|
+
return { path: ["log", "resources", "limits", "memory"], issue: `must be at least ${LOG_MEMORY}: a heap of 512 MiB, and the JVM's own` };
|
|
705
|
+
}
|
|
706
|
+
const backedUp = bundled.enabled && bundled.filerStore.backups.enabled ? filerStoreBackupHours(bundled.filerStore.backups) : null;
|
|
707
|
+
if (backedUp !== null && Number(config.log.retention.slice(0, -1)) < backedUp + LOG_RETENTION_MARGIN_HOURS) {
|
|
708
|
+
return {
|
|
709
|
+
path: ["log", "retention"],
|
|
710
|
+
issue: `must be at least ${backedUp + LOG_RETENTION_MARGIN_HOURS}h: the filer store's backups go back ${backedUp}h (objectStore.bundled.filerStore.backups), ` +
|
|
711
|
+
`a restore of the oldest loses the lake's telemetry written since, which the log refills only while it holds it, and a day more`,
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
if (telemetryRetentionBytes(config) < LOG_SEGMENT_BYTES) {
|
|
715
|
+
const least = Math.ceil((telemetryPartitions(config) * 2 * LOG_SEGMENT_BYTES * 4) / 3);
|
|
716
|
+
return {
|
|
717
|
+
path: ["log", "storage", "size"],
|
|
718
|
+
issue: `must be at least ${memoryText(least)}: each of the telemetry topics' ${telemetryPartitions(config)} partitions keeps a segment of ${memoryText(LOG_SEGMENT_BYTES)} at least beside the one it writes, in three quarters of it`,
|
|
719
|
+
};
|
|
720
|
+
}
|
|
584
721
|
if (config.autoscaling.headroom.scaling.min > 0 && !config.autoscaling.preemption) {
|
|
585
722
|
return { path: ["autoscaling", "headroom", "scaling"], issue: "must be 0 when autoscaling.preemption is false, as no pod takes a placeholder's place then" };
|
|
586
723
|
}
|
|
@@ -592,6 +729,9 @@ const InstallStruct = Schema.Struct({
|
|
|
592
729
|
agent: Image(IMAGES.agent),
|
|
593
730
|
lake: Image(IMAGES.lake),
|
|
594
731
|
grafana: Image(IMAGES.grafana),
|
|
732
|
+
log: Image(IMAGES.log),
|
|
733
|
+
collector: Image(IMAGES.collector),
|
|
734
|
+
webhook: Image(IMAGES.webhook),
|
|
595
735
|
pullPolicy: defaulted(PullPolicy, "IfNotPresent"),
|
|
596
736
|
}), {}),
|
|
597
737
|
/** Pull Secrets for private registries, in alasio's namespace and the sessions and host ones. */
|
|
@@ -604,11 +744,36 @@ const InstallStruct = Schema.Struct({
|
|
|
604
744
|
neon: defaulted(Neon, {}),
|
|
605
745
|
objectStore: defaulted(ObjectStore, {}),
|
|
606
746
|
workspaceStorage: defaulted(WorkspaceStorage, {}),
|
|
607
|
-
|
|
747
|
+
log: defaulted(Log, {}),
|
|
748
|
+
webhook: defaulted(Webhook, {}),
|
|
749
|
+
/**
|
|
750
|
+
* The analytics lake, in DuckLake: its loader, which loads it from Neon while alasio says
|
|
751
|
+
* it wrote transcripts and sleeps otherwise; its maintenance, main's, in passes on a
|
|
752
|
+
* schedule; its readers, main's, which Grafana and alasio lake read it through, scaled on
|
|
753
|
+
* the queries waiting on them, never below one; and its telemetry intake, which writes
|
|
754
|
+
* what the log holds of the stack's telemetry to it, scaled on how much is waiting there,
|
|
755
|
+
* to none while nothing is.
|
|
756
|
+
*/
|
|
608
757
|
lake: defaulted(Schema.Struct({
|
|
609
758
|
enabled: defaulted(Schema.Boolean, true),
|
|
610
|
-
|
|
611
|
-
|
|
759
|
+
loader: defaulted(Schema.Struct({
|
|
760
|
+
/** None while nothing is left to load, which KEDA wakes; one, never two, as a load is not parallel. At one, it never sleeps, and needs no KEDA. */
|
|
761
|
+
scaling: Scaling({ min: 0, max: 1 }, { floor: false, scaled: true, most: 1 }),
|
|
762
|
+
resources: Resources({ requests: { cpu: "100m", memory: "512Mi" }, limits: { memory: "1536Mi" } }),
|
|
763
|
+
}), {}),
|
|
764
|
+
maintenance: defaulted(Schema.Struct({
|
|
765
|
+
/** When its daily pass runs, away from Neon's backup; the telemetry's files are merged hourly besides. */
|
|
766
|
+
schedule: defaulted(Schema.String.check(Schema.isMinLength(9, { message: "must be a cron schedule" })), "17 2 * * *"),
|
|
767
|
+
resources: Resources({ requests: { cpu: "50m", memory: "256Mi" }, limits: { memory: "1Gi" } }),
|
|
768
|
+
}), {}),
|
|
769
|
+
query: defaulted(Schema.Struct({
|
|
770
|
+
scaling: Scaling({ min: 1, max: 1 }, { floor: true, scaled: true }),
|
|
771
|
+
resources: Resources({ requests: { cpu: "50m", memory: "128Mi" }, limits: { memory: "1Gi" } }),
|
|
772
|
+
}), {}),
|
|
773
|
+
intake: defaulted(Schema.Struct({
|
|
774
|
+
scaling: Scaling({ min: 0, max: 2 }, { floor: false, scaled: true }),
|
|
775
|
+
resources: Resources({ requests: { cpu: "50m", memory: "256Mi" }, limits: { memory: "1Gi" } }),
|
|
776
|
+
}), {}),
|
|
612
777
|
}), {}),
|
|
613
778
|
/**
|
|
614
779
|
* Grafana, with the lake: dashboards and alerts on it, alerting through the Telegram bot;
|
|
@@ -622,7 +787,6 @@ const InstallStruct = Schema.Struct({
|
|
|
622
787
|
}), {}),
|
|
623
788
|
/** NetworkPolicies confining sessions, folder workspaces' bayma and Neon. */
|
|
624
789
|
networkPolicies: defaulted(Schema.Struct({ enabled: defaulted(Schema.Boolean, true) }), {}),
|
|
625
|
-
agentSandbox: defaulted(AgentSandbox, {}),
|
|
626
790
|
autoscaling: defaulted(Autoscaling, {}),
|
|
627
791
|
});
|
|
628
792
|
/** The install configuration: what the config file holds, every key left out its default. */
|