@mark1russell7/kind 0.11.7 → 0.11.9
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 +1 -1
- package/build/index.d.ts +17 -22
- package/build/index.js +71 -134
- package/build/index.js.map +1 -1
- package/build/{judge-DnB9wEwC.d.ts → judge-BBHSeu4i.d.ts} +57 -4
- package/build/{judge-Cs91dOGO.js → judge-ZoLw3AXV.js} +146 -16
- package/build/judge-ZoLw3AXV.js.map +1 -0
- package/build/judge.d.ts +2 -2
- package/build/judge.js +1 -1
- package/package.json +3 -3
- package/build/judge-Cs91dOGO.js.map +0 -1
package/README.md
CHANGED
|
@@ -211,7 +211,7 @@ The plan's `event:clock-jump` has no trigger. A step of CLOCK_REALTIME in the VM
|
|
|
211
211
|
|
|
212
212
|
`predict.ts` gives each band from the declaration, the pod settings and the calibration of the propagation:
|
|
213
213
|
|
|
214
|
-
- **A deletion.** The listener of a leaving pod stays open for its preStop sleep and the hold of `fail readiness`. A connection fails when the rules of its node select the pod after that.
|
|
214
|
+
- **A deletion.** The listener of a leaving pod stays open for its preStop sleep and the hold of `fail readiness`. A connection fails when the rules of its node select the pod after that. The entry `@mark1russell7/service/rules` gives O04 with the hold as data, and `lint()` decides it. Kind gives the drain rules of that entry again (`DRAIN_RULES`, `O04`, `O09`, `O10`, `O16`).
|
|
215
215
|
- **The way that a plan stops a pod.** `stopOf(cell)` reads it from the trigger: a deletion, a liveness restart, a crash, or null when the plan stops no pod. `lintCell()` gives each cell only the drain rules that guard its way (`lintStop()` of the service). A plan that stops no pod gets each drain rule. A crash gets no drain rule, and its finding of `stop` depends.
|
|
216
216
|
- **A pause of kube-proxy** keeps the rules of one node for its hold. The window on that node ends one propagation after the pause. A SYN_SENT entry of an earlier run lives up to 122 s, thus the window also opens up to 122 s before the intake. `predictionText` writes each end of a window with its band, for example `the intake + [-122, 4.605] s`.
|
|
217
217
|
- **A reset from a leaving pod** leaves the conntrack entry of its flow in CLOSE for 10 s, with the NAT to that pod. From 0.1.6, a window can give that life (`afterReset`). Then a request outside the window can fail with the outcome of the rule (`reusesReset`). The condition is a reset of the same client on the same port, up to that life before the request. The catalog gives it to a deletion without a hold, in the modes with the NAT in conntrack.
|
package/build/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as unitOf, $t as secondsOf, A as TriggerV1, An as cidrOverlap, At as restartsAt, B as RunCheck, Bt as stoppingOf, C as KindCellResult, Cn as Workload, Ct as kernelCounts, D as PredictionV1, Dn as KubeProxyMode, Dt as recordsOf, E as LoadSample, En as KindScenario, Et as podsOf, F as KIND_NOISE, Fn as nodeNames, Ft as sliceEmptyOf, G as factsOf, Gt as CLIENT, H as checkRun, Ht as tunnelsOf, I as KindDecision, In as scenario, It as sliceReadyAt, J as observationEnd, Jt as PORT, K as judgeKind, Kt as HEALTH_PORT, L as KindVerdict, Ln as scenarioProblems, Lt as sliceReadyOf, M as upgrade, Mn as goDuration, Mt as signalOf, N as upgradeCell, Nn as kindConfig, Nt as signalsOf, O as RunCheckV1, On as NODE_IMAGES, Ot as requestsOf, P as Deleted, Pn as kubeProxyPatch, Pt as sliceDropOf, Q as reusesReset, Qt as seconds, R as LAST_SLACK, Rt as slicesOf, S as KindCellRecordV1, Sn as WindowPrediction, St as isTunnelState, T as KindVerdictV1, Tn as KindConfig, Tt as podsAt, U as cyclesOf, Ut as ztunnelPodsOf, V as RunFacts, Vt as transitionOf, W as deletionsOf, Wt as ztunnelReplaced, X as propagationSource, Xt as SERVER, Y as propagationOf, Yt as REDIS, Z as referenceOf, Zt as bandOf, _ as ClusterManifest, _n as ResetReuse, _t as deletionOf, a as STAGES, an as Flap, at as PropagationSource, b as FORMAT_V1, bn as Trigger, bt as failuresOf, c as readRecord, cn as KubeletProbe, ct as RulesLine, d as calibrationOf, dn as MeshMode, dt as TCP_STATE, en as showBand, et as updatesOf, f as cellsTable, fn as PodSettings, ft as TunnelLine, g as BandV1, gn as Replica, gt as byNode, h as timeSpread, hn as Reference, ht as byClients, i as quantileOf, in as EdgeProtocol, it as PodLine, j as judge, jn as cidrRange, jt as rulesOf, k as RunFactsV1, kn as NodeImage, kt as restartOf, l as Judged, ln as Mesh, lt as SliceLine, m as predictionText, mn as RedisDeclaration, mt as backendsAt, n as medianInterval, nn as Cycle, nt as HBONE_PORT, o as kindCellRecordSchema, on as KindCell, ot as RecordLine, p as medianText, pn as Prediction, pt as ZtunnelPodLine, q as observationAfter, qt as LOG_LABEL, r as middle, rn as Declaration, rt as Line, s as kindCellRecordV1Schema, sn as KindRun, st as Request, t as RELATIVE, tn as Band, tt as Endpoint, u as TimeSpread, un as MeshFlavor, ut as SocketLine, v as EnvironmentManifest, vn as Stack, vt as dropOf, w as KindCellV1, wn as KUBE_PROXY_MODES, wt as outcomesOf, x as KindCellRecord, xn as TriggerKind, xt as intakeOf, y as FORMAT, yn as Template, yt as emptyOf, z as Propagated, zt as socketsOf } from "./judge-BBHSeu4i.js";
|
|
2
2
|
import { Quantity } from "@mark1russell7/quantity";
|
|
3
|
-
import { CheckFn, Finding, HealthServer, Poll,
|
|
3
|
+
import { CheckFn, Finding, HealthServer, Poll, Scenario, ServiceBuilder, ServiceDescription, Stage, StopWay, Timing, TransportImpl, Verdict } from "@mark1russell7/service";
|
|
4
4
|
import { BuildImage } from "@mark1russell7/harness";
|
|
5
5
|
import { RedisClient } from "@mark1russell7/service/redis";
|
|
6
|
+
import { DRAIN_RULES, O04, O09, O10, O16 } from "@mark1russell7/service/rules";
|
|
6
7
|
//#region src/backends.d.ts
|
|
7
8
|
/** A service rule names the Service whose backends the agent reads: its namespace, its name, and its ClusterIP and port for IPVS. */
|
|
8
9
|
interface ServiceRule {
|
|
@@ -176,6 +177,7 @@ type Step = {
|
|
|
176
177
|
* - `inject` starts the trigger. The stamp of its first act is the `fault` reference.
|
|
177
178
|
* - `heal` ends the fault, `hold` after the fault. A trigger that ends by itself has no heal.
|
|
178
179
|
* - `restore` brings the cell back to its steady state after the run.
|
|
180
|
+
* - `flaps` are the faults after the first one. A plan without them has one fault.
|
|
179
181
|
*/
|
|
180
182
|
interface FaultPlan {
|
|
181
183
|
readonly prepare?: readonly Step[] | undefined;
|
|
@@ -183,6 +185,8 @@ interface FaultPlan {
|
|
|
183
185
|
readonly hold: Quantity | null;
|
|
184
186
|
readonly heal: readonly Step[];
|
|
185
187
|
readonly restore: readonly Step[];
|
|
188
|
+
/** These flaps are the faults after the first one (`Trigger.flaps`). Each one does the inject and the heal again. */
|
|
189
|
+
readonly flaps?: readonly Flap[] | undefined;
|
|
186
190
|
}
|
|
187
191
|
/** This name is the name of the AuthorizationPolicy of the trigger `authorization-policy`. */
|
|
188
192
|
export declare const POLICY = "lab-deny";
|
|
@@ -260,8 +264,17 @@ export declare const sysctlCommand: (key: string, value: string) => string[];
|
|
|
260
264
|
* old flow of the peer. A cell of the middlebox opens no new flow in its gap.
|
|
261
265
|
*/
|
|
262
266
|
export declare const middleboxCommands: (peers: readonly string[], idle: Quantity | null, port: number) => string[][];
|
|
263
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* This function gives the fault plan of a cell. A trigger with flaps (`Trigger.flaps`) gives them to
|
|
269
|
+
* its plan: the runner then does the inject and the heal again for each flap. A plan with no hold or
|
|
270
|
+
* no heal cannot flap.
|
|
271
|
+
*/
|
|
264
272
|
export declare const planOf: (cell: KindCell) => FaultPlan;
|
|
273
|
+
/**
|
|
274
|
+
* This function gives the time from the first fault of a trigger to its last heal. It is the hold,
|
|
275
|
+
* then the rest and the hold of each flap. A trigger with no hold gives zero.
|
|
276
|
+
*/
|
|
277
|
+
export declare const faultSpan: (trigger: Pick<KindCell["trigger"], "hold" | "flaps">) => Quantity;
|
|
265
278
|
/** This function tells if a trigger stops a pod of the service with its grace: a deletion, an eviction, a scale-in or a rollout. */
|
|
266
279
|
export declare const deletes: (cell: KindCell) => boolean;
|
|
267
280
|
//#endregion
|
|
@@ -680,24 +693,6 @@ interface LearnWindow {
|
|
|
680
693
|
export declare const learnWindow: (declaration: Declaration, readiness: KubeletProbe, propagation: Propagation, workload: Workload) => LearnWindow;
|
|
681
694
|
//#endregion
|
|
682
695
|
//#region src/rules.d.ts
|
|
683
|
-
/**
|
|
684
|
-
* These are the rules of the ordering law that a drain in Kubernetes meets, as data. The caller of
|
|
685
|
-
* `lint()` gives the rules, thus they are here and not in the service.
|
|
686
|
-
*/
|
|
687
|
-
/**
|
|
688
|
-
* O04 with the hold of the service. The listener of a pod stays open through the preStop sleep and
|
|
689
|
-
* then through the hold of `fail readiness`. Thus the sum of the two must cover the propagation of
|
|
690
|
-
* the endpoints. The rule of the research is the case without a hold.
|
|
691
|
-
*/
|
|
692
|
-
export declare const O04: Rule;
|
|
693
|
-
/** O09 is W8: readiness detection plus propagation is no longer than liveness detection plus the preStop sleep. */
|
|
694
|
-
export declare const O09: Rule;
|
|
695
|
-
/** O10: the preStop sleep plus the drain of the process fits in the grace period. */
|
|
696
|
-
export declare const O10: Rule;
|
|
697
|
-
/** O16: the cooperative window is shorter than the drain, which is shorter than the grace less the preStop sleep. */
|
|
698
|
-
export declare const O16: Rule;
|
|
699
|
-
/** These are the rules of the drain. A kind cell gets the rules that guard the way that its plan stops a pod. */
|
|
700
|
-
export declare const DRAIN_RULES: readonly Rule[];
|
|
701
696
|
/**
|
|
702
697
|
* This function gives the scenario of a cell for `lint()`: the preStop sleep, the grace, the probe
|
|
703
698
|
* period and the propagation. The probe windows are the period times the threshold of each probe.
|
|
@@ -817,5 +812,5 @@ export declare const toolPath: (tool: Tool, key?: string, cache?: string) => str
|
|
|
817
812
|
*/
|
|
818
813
|
export declare const ensureTool: (tool: Tool, key?: string, cache?: string) => Promise<string>;
|
|
819
814
|
//#endregion
|
|
820
|
-
export { type Band, type BandV1, CLIENT, type Cluster, type ClusterHosts, type ClusterManifest, type Credentials, type Declaration, type Deleted, type DeletionWindow, type EdgeProtocol, type EdsSpec, Endpoint, type EnvironmentManifest, FORMAT, FORMAT_V1, type FaultPlan, HBONE_PORT, HEALTH_PORT, type Judged, KIND_NOISE, KUBE_PROXY_MODES, type KindCell, type KindCellRecord, type KindCellRecordV1, type KindCellResult, type KindCellV1, type KindConfig, type KindDecision, type KindLab, type KindRun, type KindScenario, type KindVerdict, type KindVerdictV1, type KubeProxyMode, type KubeletProbe, LAST_SLACK, LOG_LABEL, type LdsSpec, type LeafCertificate, type LearnWindow, Line, type ListenerCounts, type LoadSample, type Mesh, type MeshFlavor, type MeshImages, type MeshMode, NODE_IMAGES, type NodeImage, PORT, type Parts, PodLine, type PodSettings, type Prediction, type PredictionV1, type Propagated, type Propagation, PropagationSource, REDIS, RELATIVE, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, type RunOptions, SERVER, STAGES, type ServiceRule, SliceLine, SocketLine, type Stack, type Stamp, type Step, TCP_STATE, type Target, type Template, type TimeSpread, type Tool, type Trigger, type TriggerKind, type TriggerV1, TunnelLine, type Verdicts, type WindowPrediction, type Workload, ZtunnelPodLine, backendsAt, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cidrOverlap, cidrRange, deletionOf, deletionsOf, dropOf, emptyOf, factsOf, failuresOf, goDuration, intakeOf, isTunnelState, judge, judgeKind, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, medianInterval, medianText, middle, nodeNames, observationAfter, observationEnd, outcomesOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, scenario, scenarioProblems, seconds, secondsOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, ztunnelPodsOf, ztunnelReplaced };
|
|
815
|
+
export { type Band, type BandV1, CLIENT, type Cluster, type ClusterHosts, type ClusterManifest, type Credentials, type Cycle, DRAIN_RULES, type Declaration, type Deleted, type DeletionWindow, type EdgeProtocol, type EdsSpec, Endpoint, type EnvironmentManifest, FORMAT, FORMAT_V1, type FaultPlan, type Flap, HBONE_PORT, HEALTH_PORT, type Judged, KIND_NOISE, KUBE_PROXY_MODES, type KindCell, type KindCellRecord, type KindCellRecordV1, type KindCellResult, type KindCellV1, type KindConfig, type KindDecision, type KindLab, type KindRun, type KindScenario, type KindVerdict, type KindVerdictV1, type KubeProxyMode, type KubeletProbe, LAST_SLACK, LOG_LABEL, type LdsSpec, type LeafCertificate, type LearnWindow, Line, type ListenerCounts, type LoadSample, type Mesh, type MeshFlavor, type MeshImages, type MeshMode, NODE_IMAGES, type NodeImage, O04, O09, O10, O16, PORT, type Parts, PodLine, type PodSettings, type Prediction, type PredictionV1, type Propagated, type Propagation, PropagationSource, REDIS, RELATIVE, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, type RunOptions, SERVER, STAGES, type ServiceRule, SliceLine, SocketLine, type Stack, type Stamp, type Step, TCP_STATE, type Target, type Template, type TimeSpread, type Tool, type Trigger, type TriggerKind, type TriggerV1, TunnelLine, type Verdicts, type WindowPrediction, type Workload, ZtunnelPodLine, backendsAt, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cidrOverlap, cidrRange, cyclesOf, deletionOf, deletionsOf, dropOf, emptyOf, factsOf, failuresOf, goDuration, intakeOf, isTunnelState, judge, judgeKind, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, medianInterval, medianText, middle, nodeNames, observationAfter, observationEnd, outcomesOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, scenario, scenarioProblems, seconds, secondsOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, ztunnelPodsOf, ztunnelReplaced };
|
|
821
816
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as rulesOf, A as RELATIVE, B as dropOf, C as observationEnd, D as reusesReset, E as referenceOf, F as TCP_STATE, G as kernelCounts, H as failuresOf, I as backendsAt, J as podsOf, K as outcomesOf, L as byClients, M as middle, N as quantileOf, O as unitOf, P as HBONE_PORT, Q as restartsAt, R as byNode, S as observationAfter, St as showBand, T as propagationSource, U as intakeOf, V as emptyOf, W as isTunnelState, X as requestsOf, Y as recordsOf, Z as restartOf, _ as checkRun, _t as REDIS, a as calibrationOf, at as sliceReadyOf, b as factsOf, bt as seconds, c as predictionText, ct as stoppingOf, d as FORMAT_V1, dt as ztunnelPodsOf, et as signalOf, f as judge, ft as ztunnelReplaced, g as LAST_SLACK, gt as PORT, h as KIND_NOISE, ht as LOG_LABEL, i as readRecord, it as sliceReadyAt, j as medianInterval, k as updatesOf, l as timeSpread, lt as transitionOf, m as upgradeCell, mt as HEALTH_PORT, n as kindCellRecordSchema, nt as sliceDropOf, o as cellsTable, ot as slicesOf, p as upgrade, pt as CLIENT, q as podsAt, r as kindCellRecordV1Schema, rt as sliceEmptyOf, s as medianText, st as socketsOf, t as STAGES, tt as signalsOf, u as FORMAT, ut as tunnelsOf, v as cyclesOf, vt as SERVER, w as propagationOf, x as judgeKind, xt as secondsOf, y as deletionsOf, yt as bandOf, z as deletionOf } from "./judge-ZoLw3AXV.js";
|
|
2
2
|
import { valueIn } from "@mark1russell7/quantity";
|
|
3
3
|
import { execFile, execFileSync } from "node:child_process";
|
|
4
4
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
@@ -12,6 +12,7 @@ import { createRequire } from "node:module";
|
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
import { harnessImage, imageOf } from "@mark1russell7/harness";
|
|
14
14
|
import { redisClient } from "@mark1russell7/service/redis";
|
|
15
|
+
import { DRAIN_RULES, DRAIN_RULES as DRAIN_RULES$1, O04, O09, O10, O16 } from "@mark1russell7/service/rules";
|
|
15
16
|
//#region src/backends.ts
|
|
16
17
|
const hexIp = (hex) => [
|
|
17
18
|
0,
|
|
@@ -853,8 +854,36 @@ const middleboxCommands = (peers, idle, port) => {
|
|
|
853
854
|
* is a rule in the target replica only, with the client pods as peers.
|
|
854
855
|
*/
|
|
855
856
|
const linkOf = (cell) => cell.trigger.partition === true ? "server" : cell.template === "T15" ? "servers" : "redis";
|
|
856
|
-
/**
|
|
857
|
+
/**
|
|
858
|
+
* This function gives the fault plan of a cell. A trigger with flaps (`Trigger.flaps`) gives them to
|
|
859
|
+
* its plan: the runner then does the inject and the heal again for each flap. A plan with no hold or
|
|
860
|
+
* no heal cannot flap.
|
|
861
|
+
*/
|
|
857
862
|
const planOf = (cell) => {
|
|
863
|
+
const plan = stepsOf(cell);
|
|
864
|
+
const flaps = cell.trigger.flaps;
|
|
865
|
+
if (flaps === void 0 || flaps.length === 0) return plan;
|
|
866
|
+
if (plan.hold === null || plan.heal.length === 0) throw new Error(`the trigger ${cell.trigger.kind} has no hold and heal, thus it cannot flap`);
|
|
867
|
+
for (const flap of flaps) if (valueIn(flap.rest, "ms") <= 0 || valueIn(flap.hold, "ms") <= 0) throw new Error("each flap has a rest and a hold above zero");
|
|
868
|
+
return {
|
|
869
|
+
...plan,
|
|
870
|
+
flaps
|
|
871
|
+
};
|
|
872
|
+
};
|
|
873
|
+
/**
|
|
874
|
+
* This function gives the time from the first fault of a trigger to its last heal. It is the hold,
|
|
875
|
+
* then the rest and the hold of each flap. A trigger with no hold gives zero.
|
|
876
|
+
*/
|
|
877
|
+
const faultSpan = (trigger) => {
|
|
878
|
+
const hold = trigger.hold === void 0 ? 0 : valueIn(trigger.hold, "s");
|
|
879
|
+
const flaps = (trigger.flaps ?? []).reduce((sum, flap) => sum + valueIn(flap.rest, "s") + valueIn(flap.hold, "s"), 0);
|
|
880
|
+
return {
|
|
881
|
+
value: Math.round((hold + flaps) * 1e6) / 1e6,
|
|
882
|
+
unit: "s"
|
|
883
|
+
};
|
|
884
|
+
};
|
|
885
|
+
/** This function gives the steps of the fault plan of a cell, with no flaps. */
|
|
886
|
+
const stepsOf = (cell) => {
|
|
858
887
|
const ns = ["-n", "{namespace}"];
|
|
859
888
|
const trigger = cell.trigger;
|
|
860
889
|
const replicas = cell.pod.replicas;
|
|
@@ -2653,130 +2682,6 @@ const learnWindow = (declaration, readiness, propagation, workload) => {
|
|
|
2653
2682
|
};
|
|
2654
2683
|
//#endregion
|
|
2655
2684
|
//#region src/rules.ts
|
|
2656
|
-
/**
|
|
2657
|
-
* These are the rules of the ordering law that a drain in Kubernetes meets, as data. The caller of
|
|
2658
|
-
* `lint()` gives the rules, thus they are here and not in the service.
|
|
2659
|
-
*/
|
|
2660
|
-
/**
|
|
2661
|
-
* O04 with the hold of the service. The listener of a pod stays open through the preStop sleep and
|
|
2662
|
-
* then through the hold of `fail readiness`. Thus the sum of the two must cover the propagation of
|
|
2663
|
-
* the endpoints. The rule of the research is the case without a hold.
|
|
2664
|
-
*/
|
|
2665
|
-
const O04 = {
|
|
2666
|
-
id: "O04",
|
|
2667
|
-
rule: "the preStop sleep plus the hold of fail readiness is at least the endpoint propagation",
|
|
2668
|
-
window: "new connections reach a pod whose listener is closed",
|
|
2669
|
-
expr: {
|
|
2670
|
-
lhs: { terms: [{
|
|
2671
|
-
knob: "prestop_sleep",
|
|
2672
|
-
coef: 1,
|
|
2673
|
-
at: "pod"
|
|
2674
|
-
}, {
|
|
2675
|
-
knob: "readiness_hold",
|
|
2676
|
-
coef: 1,
|
|
2677
|
-
at: "process"
|
|
2678
|
-
}] },
|
|
2679
|
-
op: ">=",
|
|
2680
|
-
rhs: { terms: [{
|
|
2681
|
-
knob: "propagation_bound",
|
|
2682
|
-
coef: 1,
|
|
2683
|
-
at: "cluster"
|
|
2684
|
-
}] }
|
|
2685
|
-
}
|
|
2686
|
-
};
|
|
2687
|
-
/** O09 is W8: readiness detection plus propagation is no longer than liveness detection plus the preStop sleep. */
|
|
2688
|
-
const O09 = {
|
|
2689
|
-
id: "O09",
|
|
2690
|
-
rule: "readiness detection plus endpoint propagation is no longer than liveness detection plus the preStop sleep",
|
|
2691
|
-
window: "traffic reaches a container that its liveness probe kills",
|
|
2692
|
-
expr: {
|
|
2693
|
-
lhs: { terms: [{
|
|
2694
|
-
knob: "readiness_detection_window",
|
|
2695
|
-
coef: 1,
|
|
2696
|
-
at: "pod"
|
|
2697
|
-
}, {
|
|
2698
|
-
knob: "propagation_bound",
|
|
2699
|
-
coef: 1,
|
|
2700
|
-
at: "cluster"
|
|
2701
|
-
}] },
|
|
2702
|
-
op: "<=",
|
|
2703
|
-
rhs: { terms: [{
|
|
2704
|
-
knob: "liveness_detection_window",
|
|
2705
|
-
coef: 1,
|
|
2706
|
-
at: "pod"
|
|
2707
|
-
}, {
|
|
2708
|
-
knob: "prestop_sleep",
|
|
2709
|
-
coef: 1,
|
|
2710
|
-
at: "pod"
|
|
2711
|
-
}] }
|
|
2712
|
-
}
|
|
2713
|
-
};
|
|
2714
|
-
/** O10: the preStop sleep plus the drain of the process fits in the grace period. */
|
|
2715
|
-
const O10 = {
|
|
2716
|
-
id: "O10",
|
|
2717
|
-
rule: "the preStop sleep plus the shutdown of the process fits in the grace period",
|
|
2718
|
-
window: "work in flight at SIGKILL is cut, and each connection closes at once",
|
|
2719
|
-
expr: {
|
|
2720
|
-
lhs: { terms: [{
|
|
2721
|
-
knob: "prestop_sleep",
|
|
2722
|
-
coef: 1,
|
|
2723
|
-
at: "pod"
|
|
2724
|
-
}, {
|
|
2725
|
-
knob: "process_drain_time",
|
|
2726
|
-
coef: 1,
|
|
2727
|
-
at: "process"
|
|
2728
|
-
}] },
|
|
2729
|
-
op: "<=",
|
|
2730
|
-
rhs: { terms: [{
|
|
2731
|
-
knob: "termination_grace",
|
|
2732
|
-
coef: 1,
|
|
2733
|
-
at: "pod"
|
|
2734
|
-
}] }
|
|
2735
|
-
}
|
|
2736
|
-
};
|
|
2737
|
-
/** O16: the cooperative window is shorter than the drain, which is shorter than the grace less the preStop sleep. */
|
|
2738
|
-
const O16 = {
|
|
2739
|
-
id: "O16",
|
|
2740
|
-
rule: "the cooperative window is shorter than the drain, which is shorter than the grace less the preStop sleep",
|
|
2741
|
-
window: "handlers are cut before they answer, or the drain itself gets SIGKILL",
|
|
2742
|
-
expr: {
|
|
2743
|
-
lhs: { terms: [{
|
|
2744
|
-
knob: "cooperative_window",
|
|
2745
|
-
coef: 1,
|
|
2746
|
-
at: "process"
|
|
2747
|
-
}] },
|
|
2748
|
-
op: "<",
|
|
2749
|
-
rhs: { terms: [{
|
|
2750
|
-
knob: "process_drain_time",
|
|
2751
|
-
coef: 1,
|
|
2752
|
-
at: "process"
|
|
2753
|
-
}] }
|
|
2754
|
-
},
|
|
2755
|
-
expr_more: [{
|
|
2756
|
-
lhs: { terms: [{
|
|
2757
|
-
knob: "process_drain_time",
|
|
2758
|
-
coef: 1,
|
|
2759
|
-
at: "process"
|
|
2760
|
-
}] },
|
|
2761
|
-
op: "<",
|
|
2762
|
-
rhs: { terms: [{
|
|
2763
|
-
knob: "termination_grace",
|
|
2764
|
-
coef: 1,
|
|
2765
|
-
at: "pod"
|
|
2766
|
-
}, {
|
|
2767
|
-
knob: "prestop_sleep",
|
|
2768
|
-
coef: -1,
|
|
2769
|
-
at: "pod"
|
|
2770
|
-
}] }
|
|
2771
|
-
}]
|
|
2772
|
-
};
|
|
2773
|
-
/** These are the rules of the drain. A kind cell gets the rules that guard the way that its plan stops a pod. */
|
|
2774
|
-
const DRAIN_RULES = [
|
|
2775
|
-
O04,
|
|
2776
|
-
O09,
|
|
2777
|
-
O10,
|
|
2778
|
-
O16
|
|
2779
|
-
];
|
|
2780
2685
|
const seconds$1 = (amount) => valueIn(amount, "s");
|
|
2781
2686
|
const s = (value) => ({
|
|
2782
2687
|
value,
|
|
@@ -2835,7 +2740,7 @@ const stopOf = (cell) => {
|
|
|
2835
2740
|
const lintCell = (description, cell, propagation) => {
|
|
2836
2741
|
const way = stopOf(cell);
|
|
2837
2742
|
const scenario = scenarioOf(cell, propagation);
|
|
2838
|
-
return way === null ? lint(description, scenario, DRAIN_RULES) : lintStop(description, scenario, DRAIN_RULES, way);
|
|
2743
|
+
return way === null ? lint(description, scenario, DRAIN_RULES$1) : lintStop(description, scenario, DRAIN_RULES$1, way);
|
|
2839
2744
|
};
|
|
2840
2745
|
/** This function gives the verdict of each drain rule, by its identifier. */
|
|
2841
2746
|
const verdictsOf = (findings) => Object.fromEntries(findings.map((finding) => [finding.rule, finding.verdict]));
|
|
@@ -3500,16 +3405,46 @@ const runOnce = async (ctx, env, index, warmup, ours) => {
|
|
|
3500
3405
|
if (stamp !== null && fault === null) fault = stamp.t0;
|
|
3501
3406
|
}
|
|
3502
3407
|
let heal = null;
|
|
3503
|
-
|
|
3408
|
+
const healAfter = async (from, hold) => {
|
|
3504
3409
|
const now = await lab.now();
|
|
3505
|
-
await sleep(Math.max(0, valueIn(
|
|
3410
|
+
await sleep(Math.max(0, valueIn(hold, "ms") - (now - (from ?? now))));
|
|
3411
|
+
let stamped = null;
|
|
3506
3412
|
for (const step of plan.heal) try {
|
|
3507
3413
|
const stamp = await doStep(ctx, step, replicas, background);
|
|
3508
|
-
if (stamp !== null &&
|
|
3414
|
+
if (stamp !== null && stamped === null) stamped = stamp.t0;
|
|
3509
3415
|
} catch (error) {
|
|
3510
3416
|
notes.push(`the heal ${step.do} failed: ${String(error)}`);
|
|
3511
3417
|
}
|
|
3418
|
+
return stamped;
|
|
3419
|
+
};
|
|
3420
|
+
const cycles = [];
|
|
3421
|
+
if (plan.hold !== null) {
|
|
3422
|
+
heal = await healAfter(fault, plan.hold);
|
|
3423
|
+
if (fault !== null && heal !== null) cycles.push({
|
|
3424
|
+
fault,
|
|
3425
|
+
heal
|
|
3426
|
+
});
|
|
3427
|
+
for (const flap of plan.flaps ?? []) {
|
|
3428
|
+
const now = await lab.now();
|
|
3429
|
+
await sleep(Math.max(0, valueIn(flap.rest, "ms") - (now - (heal ?? now))));
|
|
3430
|
+
let again = null;
|
|
3431
|
+
for (const step of plan.inject) try {
|
|
3432
|
+
const stamp = await doStep(ctx, step, replicas, background);
|
|
3433
|
+
if (stamp !== null && again === null) again = stamp.t0;
|
|
3434
|
+
} catch (error) {
|
|
3435
|
+
notes.push(`the inject ${step.do} of a flap failed: ${String(error)}`);
|
|
3436
|
+
}
|
|
3437
|
+
const healed = await healAfter(again, flap.hold);
|
|
3438
|
+
if (again !== null && healed !== null) cycles.push({
|
|
3439
|
+
fault: again,
|
|
3440
|
+
heal: healed
|
|
3441
|
+
});
|
|
3442
|
+
heal = healed ?? heal;
|
|
3443
|
+
}
|
|
3512
3444
|
}
|
|
3445
|
+
const flapped = (plan.flaps ?? []).length > 0;
|
|
3446
|
+
if (flapped && cycles.length !== (plan.flaps ?? []).length + 1) notes.push(`the run has ${cycles.length} cycles with stamps of the ${(plan.flaps ?? []).length + 1} of the trigger`);
|
|
3447
|
+
const flapping = flapped ? { cycles } : {};
|
|
3513
3448
|
const settled = await Promise.allSettled(background);
|
|
3514
3449
|
for (const each of settled) if (each.status === "fulfilled" && typeof each.value === "object" && each.value !== null && "t1" in each.value) resume = each.value.t1;
|
|
3515
3450
|
const limit = Date.now() + 24e4 + valueIn(cell.pod.grace, "ms") + valueIn(cell.pod.preStop, "ms");
|
|
@@ -3524,7 +3459,8 @@ const runOnce = async (ctx, env, index, warmup, ours) => {
|
|
|
3524
3459
|
acts: {
|
|
3525
3460
|
fault,
|
|
3526
3461
|
heal,
|
|
3527
|
-
resume
|
|
3462
|
+
resume,
|
|
3463
|
+
...flapping
|
|
3528
3464
|
},
|
|
3529
3465
|
target: stoppedOf(cell, replicas, target, lab.lines),
|
|
3530
3466
|
replicas,
|
|
@@ -3573,7 +3509,8 @@ const runOnce = async (ctx, env, index, warmup, ours) => {
|
|
|
3573
3509
|
acts: {
|
|
3574
3510
|
fault,
|
|
3575
3511
|
heal,
|
|
3576
|
-
resume
|
|
3512
|
+
resume,
|
|
3513
|
+
...flapping
|
|
3577
3514
|
},
|
|
3578
3515
|
target: stopped,
|
|
3579
3516
|
paused,
|
|
@@ -3791,7 +3728,7 @@ const runKindCells = async (cells, options) => {
|
|
|
3791
3728
|
};
|
|
3792
3729
|
/** This function gives the estimate of a cell in seconds, for the arithmetic of the shards. */
|
|
3793
3730
|
const estimate = (cell, environments = 2) => {
|
|
3794
|
-
const hold =
|
|
3731
|
+
const hold = valueIn(faultSpan(cell.trigger), "s");
|
|
3795
3732
|
const trigger = {
|
|
3796
3733
|
"liveness-restart": 100,
|
|
3797
3734
|
crash: 30,
|
|
@@ -3840,6 +3777,6 @@ const shardOf = (cells, index, count) => {
|
|
|
3840
3777
|
return out;
|
|
3841
3778
|
};
|
|
3842
3779
|
//#endregion
|
|
3843
|
-
export { ACCESS_LOG_FORMAT, CHANNEL_USE, CLIENT, CLIENT_ACCOUNT, CLOSE_LEAD, CONTROLLER, DOCUMENTED, DRAIN_RULES, EDS_EVERY, FLAG_CHECK, FORMAT, FORMAT_V1, HBONE_PORT, HEALTH_PORT, ISTIOCTL, ISTIO_IMAGES, ISTIO_VERSION, KEPT_KERNEL, KIND, KIND_NOISE, KUBECTL, KUBE_PROXY_MODES, LAST_SLACK, LDS_EVERY, LDS_FILTER, LOG_LABEL, MESH_IMAGES, MESH_WORKLOADS, MIDDLEBOX, NETNS_DEFAULTS, NODE_IMAGES, O04, O09, O10, O16, POLICY, PORT, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, SPREAD_LEAD, STAGES, SYSCTL, TCP_STATE, WATCHDOG, ZTUNNEL_PODS, backendsAt, backendsOf, bandOf, byClients, byNode, cacheFolder, calibrationOf, capOf, cellsTable, certificateArgs, checkRun, cidrOverlap, cidrRange, clientObjects, clusterFilter, compose, createCluster, deletes, deletionOf, deletionWindow, deletionsOf, describeCell, dropOf, emptyOf, ensureTool, estimatedTime, factsOf, failuresOf, followsZtunnel, goDuration, hostsOf, installMesh, intakeAfter, intakeOf, isTunnelState, istioOperator, judge, judgeKind, keptKernel, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, kubeletBand, labImage, labSource, latchBand, leafCertificates, learnWindow, lintCell, listenerCountsOf, localPin, medianInterval, medianText, meshKey, middle, middleboxCommands, namespaceObject, namespaceOf, nodeNames, observationAfter, observationEnd, openKindLab, outboundCluster, outcomesOf, pausedWindow, planOf, platformKey, podsAt, podsOf, policyObject, pollsListeners, predictionText, probeOf, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, redisObjects, referenceOf, removalBand, requestsOf, restartBand, restartOf, restartsAt, reusesReset, rulesOf, runKindCells, scenario, scenarioOf, scenarioProblems, seconds, secondsOf, serverCluster, serverObjects, setZtunnelEnv, sha256, shardOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, slicesOf, socketsOf, stackOf, stageLabImage, stallRemovalBand, stopOf, stoppingOf, sysctlCommand, tarEntry, timeSpread, toolPath, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, verdictsOf, writeResult, ztunnelCertificates, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
|
|
3780
|
+
export { ACCESS_LOG_FORMAT, CHANNEL_USE, CLIENT, CLIENT_ACCOUNT, CLOSE_LEAD, CONTROLLER, DOCUMENTED, DRAIN_RULES, EDS_EVERY, FLAG_CHECK, FORMAT, FORMAT_V1, HBONE_PORT, HEALTH_PORT, ISTIOCTL, ISTIO_IMAGES, ISTIO_VERSION, KEPT_KERNEL, KIND, KIND_NOISE, KUBECTL, KUBE_PROXY_MODES, LAST_SLACK, LDS_EVERY, LDS_FILTER, LOG_LABEL, MESH_IMAGES, MESH_WORKLOADS, MIDDLEBOX, NETNS_DEFAULTS, NODE_IMAGES, O04, O09, O10, O16, POLICY, PORT, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, SPREAD_LEAD, STAGES, SYSCTL, TCP_STATE, WATCHDOG, ZTUNNEL_PODS, backendsAt, backendsOf, bandOf, byClients, byNode, cacheFolder, calibrationOf, capOf, cellsTable, certificateArgs, checkRun, cidrOverlap, cidrRange, clientObjects, clusterFilter, compose, createCluster, cyclesOf, deletes, deletionOf, deletionWindow, deletionsOf, describeCell, dropOf, emptyOf, ensureTool, estimatedTime, factsOf, failuresOf, faultSpan, followsZtunnel, goDuration, hostsOf, installMesh, intakeAfter, intakeOf, isTunnelState, istioOperator, judge, judgeKind, keptKernel, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, kubeletBand, labImage, labSource, latchBand, leafCertificates, learnWindow, lintCell, listenerCountsOf, localPin, medianInterval, medianText, meshKey, middle, middleboxCommands, namespaceObject, namespaceOf, nodeNames, observationAfter, observationEnd, openKindLab, outboundCluster, outcomesOf, pausedWindow, planOf, platformKey, podsAt, podsOf, policyObject, pollsListeners, predictionText, probeOf, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, redisObjects, referenceOf, removalBand, requestsOf, restartBand, restartOf, restartsAt, reusesReset, rulesOf, runKindCells, scenario, scenarioOf, scenarioProblems, seconds, secondsOf, serverCluster, serverObjects, setZtunnelEnv, sha256, shardOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, stackOf, stageLabImage, stallRemovalBand, stopOf, stoppingOf, sysctlCommand, tarEntry, timeSpread, toolPath, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, verdictsOf, writeResult, ztunnelCertificates, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
|
|
3844
3781
|
|
|
3845
3782
|
//# sourceMappingURL=index.js.map
|