@mark1russell7/kind 0.11.9 → 0.11.11
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/build/index.d.ts +76 -2
- package/build/index.js +214 -16
- package/build/index.js.map +1 -1
- package/build/{judge-BBHSeu4i.d.ts → judge-0ku_4dsJ.d.ts} +39 -11
- package/build/{judge-ZoLw3AXV.js → judge-CLBiWALR.js} +36 -12
- package/build/judge-CLBiWALR.js.map +1 -0
- package/build/judge.d.ts +2 -2
- package/build/judge.js +1 -1
- package/image/agent.mjs +58 -1
- package/package.json +1 -1
- package/build/judge-ZoLw3AXV.js.map +0 -1
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as unitOf, $t as secondsOf, A as TriggerV1, An as
|
|
1
|
+
import { $ as unitOf, $t as secondsOf, A as TriggerV1, An as NodeImage, At as restartsAt, B as RunCheck, Bn as scenario, Bt as stoppingOf, C as KindCellResult, Cn as WindowPrediction, Ct as kernelCounts, D as PredictionV1, Dn as KindScenario, Dt as recordsOf, E as LoadSample, En as KindConfig, Et as podsOf, F as KIND_NOISE, Fn as cidrRange, Ft as sliceEmptyOf, G as factsOf, Gt as CLIENT, H as checkRun, Hn as zoneOf, Ht as tunnelsOf, I as KindDecision, In as goDuration, It as sliceReadyAt, J as observationEnd, Jt as PORT, K as judgeKind, Kt as HEALTH_PORT, L as KindVerdict, Ln as kindConfig, Lt as sliceReadyOf, M as upgrade, Mn as ZONE_LABEL, Mt as signalOf, N as upgradeCell, Nn as ZONE_LOST, Nt as signalsOf, O as RunCheckV1, On as KubeProxyMode, Ot as requestsOf, P as Deleted, Pn as cidrOverlap, Pt as sliceDropOf, Q as reusesReset, Qt as seconds, R as LAST_SLACK, Rn as kubeProxyPatch, Rt as slicesOf, S as KindCellRecordV1, Sn as TriggerKind, St as isTunnelState, T as KindVerdictV1, Tn as KUBE_PROXY_MODES, Tt as podsAt, U as cyclesOf, Ut as ztunnelPodsOf, V as RunFacts, Vn as scenarioProblems, 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 Replica, _t as deletionOf, a as STAGES, an as Flap, at as PropagationSource, b as FORMAT_V1, bn as Template, 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 NonePrediction, ft as TunnelLine, g as BandV1, gn as Reference, gt as byNode, h as timeSpread, hn as RedisDeclaration, ht as byClients, i as quantileOf, in as EdgeProtocol, it as PodLine, j as judge, jn as ZONE_KEPT, jt as rulesOf, k as RunFactsV1, kn as NODE_IMAGES, kt as restartOf, l as Judged, ln as Mesh, lt as SliceLine, m as predictionText, mn as Prediction, 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 PodSettings, 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 ResetReuse, vt as dropOf, w as KindCellV1, wn as Workload, wt as outcomesOf, x as KindCellRecord, xn as Trigger, xt as intakeOf, y as FORMAT, yn as Stack, yt as emptyOf, z as Propagated, zn as nodeNames, zt as socketsOf } from "./judge-0ku_4dsJ.js";
|
|
2
2
|
import { Quantity } from "@mark1russell7/quantity";
|
|
3
3
|
import { CheckFn, Finding, HealthServer, Poll, Scenario, ServiceBuilder, ServiceDescription, Stage, StopWay, Timing, TransportImpl, Verdict } from "@mark1russell7/service";
|
|
4
4
|
import { BuildImage } from "@mark1russell7/harness";
|
|
@@ -169,6 +169,13 @@ type Step = {
|
|
|
169
169
|
readonly port: number;
|
|
170
170
|
} | {
|
|
171
171
|
readonly do: "certificates";
|
|
172
|
+
} | {
|
|
173
|
+
readonly do: "zone";
|
|
174
|
+
readonly lost: boolean;
|
|
175
|
+
} | {
|
|
176
|
+
readonly do: "netem";
|
|
177
|
+
readonly target: Target;
|
|
178
|
+
readonly delay: Quantity | null;
|
|
172
179
|
};
|
|
173
180
|
/**
|
|
174
181
|
* A fault plan is the steps of a run:
|
|
@@ -275,6 +282,14 @@ export declare const planOf: (cell: KindCell) => FaultPlan;
|
|
|
275
282
|
* then the rest and the hold of each flap. A trigger with no hold gives zero.
|
|
276
283
|
*/
|
|
277
284
|
export declare const faultSpan: (trigger: Pick<KindCell["trigger"], "hold" | "flaps">) => Quantity;
|
|
285
|
+
/** This device is the link of a pod: the end of its veth pair in its network namespace. */
|
|
286
|
+
export declare const POD_LINK = "eth0";
|
|
287
|
+
/**
|
|
288
|
+
* This time is how long the heal of a delay waits from the delay of zero to the removal of the
|
|
289
|
+
* qdisc. Each packet in the queue leaves in it, because each one waits the delay at the most. A delay
|
|
290
|
+
* of a cell must be shorter than it.
|
|
291
|
+
*/
|
|
292
|
+
export declare const NETEM_DRAIN: Quantity;
|
|
278
293
|
/** 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. */
|
|
279
294
|
export declare const deletes: (cell: KindCell) => boolean;
|
|
280
295
|
//#endregion
|
|
@@ -627,6 +642,64 @@ export declare const restartBand: (latch: Band, liveness: KubeletProbe, preStop:
|
|
|
627
642
|
* replica from the rules. Each probe in the stall fails at its timeout, because the loop does not answer it.
|
|
628
643
|
*/
|
|
629
644
|
export declare const stallRemovalBand: (readiness: KubeletProbe, propagation: Propagation) => Band;
|
|
645
|
+
/**
|
|
646
|
+
* A node lifecycle is the set of timers that removes the pods of a lost node. The same timers give
|
|
647
|
+
* them back after the heal of the node. The lab sets none of them, thus each one is a default of Kubernetes
|
|
648
|
+
* v1.37.0 (file and line in that tag).
|
|
649
|
+
*/
|
|
650
|
+
interface NodeLifecycle {
|
|
651
|
+
/**
|
|
652
|
+
* This time is `NodeMonitorGracePeriod`. The node lifecycle controller marks a node Unknown when
|
|
653
|
+
* it saw no renewal of its lease for this time. Then it marks each pod of the node not ready.
|
|
654
|
+
*/
|
|
655
|
+
readonly grace: Quantity;
|
|
656
|
+
/** This time is `NodeMonitorPeriod`: the controller checks each node once in it. */
|
|
657
|
+
readonly monitor: Quantity;
|
|
658
|
+
/** This time is the renewal interval of the lease of the kubelet. */
|
|
659
|
+
readonly renew: Quantity;
|
|
660
|
+
/** This share is the jitter of each renewal interval: a renewal comes `renew` to `renew × (1 + jitter)` after the one before it. */
|
|
661
|
+
readonly jitter: number;
|
|
662
|
+
/** This time is the margin of the writes of the controller: the status of the node, then each pod of the node. */
|
|
663
|
+
readonly writes: Quantity;
|
|
664
|
+
/** This time is the PING timeout of the HTTP/2 health check of client-go. A kubelet that gets no PING ACK in it connects again. */
|
|
665
|
+
readonly pingTimeout: Quantity;
|
|
666
|
+
/** This time is the longest first backoff of a reflector of client-go before it watches again. */
|
|
667
|
+
readonly rewatch: Quantity;
|
|
668
|
+
/** This time is the sync period of the status manager of the kubelet: it puts back a pod status that the controller changed. */
|
|
669
|
+
readonly statusSync: Quantity;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* These are the defaults of Kubernetes v1.37.0 for a lost node:
|
|
673
|
+
* - `grace` 50 s and `monitor` 5 s: pkg/controller/nodelifecycle/config/v1alpha1/defaults.go, lines
|
|
674
|
+
* 46 and 52. The controller checks the nodes on a sliding period (node_lifecycle_controller.go,
|
|
675
|
+
* lines 506–510). It sets the probe time when it sees a new lease (lines 952–960), and it marks the
|
|
676
|
+
* node Unknown after `grace` (line 962). Then it marks each pod of the node not ready (lines 768–773).
|
|
677
|
+
* - `renew` 10 s: `NodeLeaseDurationSeconds` 40 (pkg/kubelet/apis/config/v1beta1/defaults.go, line 150)
|
|
678
|
+
* times the fraction 0.25 (pkg/kubelet/kubelet.go, lines 237 and 1156).
|
|
679
|
+
* - `jitter` 0.04: the lease controller renews on a sliding jitter of 0.04
|
|
680
|
+
* (staging/src/k8s.io/component-helpers/apimachinery/lease/controller.go, line 153).
|
|
681
|
+
* - `pingTimeout` 15 s: the PING timeout of the HTTP/2 health check, after a read idle timeout of 30 s
|
|
682
|
+
* (staging/src/k8s.io/apimachinery/pkg/util/net/http.go, lines 131–192).
|
|
683
|
+
* - `rewatch` 1.6 s: a first backoff of 800 ms with a jitter of 1.0
|
|
684
|
+
* (staging/src/k8s.io/client-go/tools/cache/reflector.go, lines 62–67).
|
|
685
|
+
* - `statusSync` 10 s: the sync period of the status manager (pkg/kubelet/status/status_manager.go, line 215).
|
|
686
|
+
* - `writes` 0.25 s is a margin of the lab, not a default.
|
|
687
|
+
*/
|
|
688
|
+
export declare const NODE_LIFECYCLE: NodeLifecycle;
|
|
689
|
+
/**
|
|
690
|
+
* This function gives the time from the loss of a node to the drop of its pods from the rules of
|
|
691
|
+
* the other nodes. The last renewal of the lease comes up to `renew × (1 + jitter)` before the loss.
|
|
692
|
+
* The controller sees it up to one `monitor` later, and marks the node `grace` after that. Then the
|
|
693
|
+
* writes and the propagation follow. The band does not add the low bound of the propagation.
|
|
694
|
+
*/
|
|
695
|
+
export declare const nodeLossBand: (lifecycle: NodeLifecycle, propagation: Propagation) => Band;
|
|
696
|
+
/**
|
|
697
|
+
* This function gives the time from the heal of a lost node until its pods are ready again in the
|
|
698
|
+
* EndpointSlice. The kubelet connects again in one PING timeout at the most: its old connection
|
|
699
|
+
* waits behind the backoff of TCP. Its reflectors watch again after their first backoff. Then its
|
|
700
|
+
* status manager puts back the pod status in one sync period at the most.
|
|
701
|
+
*/
|
|
702
|
+
export declare const nodeReturnBand: (lifecycle: NodeLifecycle) => Band;
|
|
630
703
|
/** This function gives the cap of a stage in a declaration, or zero when the declaration does not name the stage. */
|
|
631
704
|
export declare const capOf: (declaration: Declaration, stage: Stage) => Quantity;
|
|
632
705
|
/**
|
|
@@ -706,6 +779,7 @@ type Verdicts = Readonly<Record<string, Verdict>>;
|
|
|
706
779
|
* - In T07 a pause of kube-proxy comes before a deletion. In T18 the pause is on Redis.
|
|
707
780
|
* - The crash of the lab is SIGKILL from the node. Like a crash, it has no preStop hook and no drain.
|
|
708
781
|
* - The other faults are on a link, on Redis or on the process. The kubelet can restart a pod after them.
|
|
782
|
+
* A zone loss freezes the pods of its node and deletes none of them in its hold.
|
|
709
783
|
*/
|
|
710
784
|
export declare const stopOf: (cell: KindCell) => StopWay | null;
|
|
711
785
|
/**
|
|
@@ -812,5 +886,5 @@ export declare const toolPath: (tool: Tool, key?: string, cache?: string) => str
|
|
|
812
886
|
*/
|
|
813
887
|
export declare const ensureTool: (tool: Tool, key?: string, cache?: string) => Promise<string>;
|
|
814
888
|
//#endregion
|
|
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 };
|
|
889
|
+
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, type NodeLifecycle, type NonePrediction, 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, ZONE_KEPT, ZONE_LABEL, ZONE_LOST, 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, zoneOf, ztunnelPodsOf, ztunnelReplaced };
|
|
816
890
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-
|
|
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-CLBiWALR.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";
|
|
@@ -92,8 +92,16 @@ const NODE_IMAGES = {
|
|
|
92
92
|
image: "kindest/node:v1.36.4@sha256:099e049362a1526b2db71494e1947aae99bd16290d7c895f2b7ea312e3cbfaed"
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
|
+
/** This label gives the zone of a node, as Kubernetes names it. */
|
|
96
|
+
const ZONE_LABEL = "topology.kubernetes.io/zone";
|
|
97
|
+
/** This zone holds the control plane and each worker but the last. A zone loss keeps it. */
|
|
98
|
+
const ZONE_KEPT = "zone-a";
|
|
99
|
+
/** This zone holds only the last worker. A zone loss loses it. */
|
|
100
|
+
const ZONE_LOST = "zone-b";
|
|
101
|
+
/** This function gives the zone of the node at the position `at` of `nodeNames`, in a cluster of `count` nodes. */
|
|
102
|
+
const zoneOf = (at, count) => at === count - 1 && at > 0 ? ZONE_LOST : ZONE_KEPT;
|
|
95
103
|
/** This function gives a scenario with the defaults of Kubernetes for kube-proxy, as explicit values. */
|
|
96
|
-
const scenario = (name, mode, workers, kubernetes = "1.37") => ({
|
|
104
|
+
const scenario = (name, mode, workers, kubernetes = "1.37", zoned = false) => ({
|
|
97
105
|
name,
|
|
98
106
|
kubernetes,
|
|
99
107
|
workers,
|
|
@@ -110,7 +118,8 @@ const scenario = (name, mode, workers, kubernetes = "1.37") => ({
|
|
|
110
118
|
},
|
|
111
119
|
cni: "kindnet",
|
|
112
120
|
podSubnet: "10.244.0.0/16",
|
|
113
|
-
serviceSubnet: "10.96.0.0/16"
|
|
121
|
+
serviceSubnet: "10.96.0.0/16",
|
|
122
|
+
...zoned ? { zoned } : {}
|
|
114
123
|
});
|
|
115
124
|
const NAME = /^[a-z0-9]([a-z0-9-]{0,30}[a-z0-9])?$/;
|
|
116
125
|
/** This function gives the problems of a scenario: a name that kind refuses, no image for the version, or a count out of range. */
|
|
@@ -155,10 +164,13 @@ const kindConfig = (s) => {
|
|
|
155
164
|
podSubnet: s.podSubnet,
|
|
156
165
|
serviceSubnet: s.serviceSubnet
|
|
157
166
|
},
|
|
158
|
-
nodes: nodeNames(s).map((node, at) => ({
|
|
167
|
+
nodes: nodeNames(s).map((node, at, all) => ({
|
|
159
168
|
role: at === 0 ? "control-plane" : "worker",
|
|
160
169
|
image,
|
|
161
|
-
labels: {
|
|
170
|
+
labels: {
|
|
171
|
+
"lab.systems/node": node.slice(s.name.length + 1),
|
|
172
|
+
...s.zoned === true ? { [ZONE_LABEL]: zoneOf(at, all.length) } : {}
|
|
173
|
+
}
|
|
162
174
|
})),
|
|
163
175
|
kubeadmConfigPatches: [kubeProxyPatch(s)]
|
|
164
176
|
};
|
|
@@ -882,6 +894,17 @@ const faultSpan = (trigger) => {
|
|
|
882
894
|
unit: "s"
|
|
883
895
|
};
|
|
884
896
|
};
|
|
897
|
+
/** This device is the link of a pod: the end of its veth pair in its network namespace. */
|
|
898
|
+
const POD_LINK = "eth0";
|
|
899
|
+
/**
|
|
900
|
+
* This time is how long the heal of a delay waits from the delay of zero to the removal of the
|
|
901
|
+
* qdisc. Each packet in the queue leaves in it, because each one waits the delay at the most. A delay
|
|
902
|
+
* of a cell must be shorter than it.
|
|
903
|
+
*/
|
|
904
|
+
const NETEM_DRAIN = {
|
|
905
|
+
value: 1,
|
|
906
|
+
unit: "s"
|
|
907
|
+
};
|
|
885
908
|
/** This function gives the steps of the fault plan of a cell, with no flaps. */
|
|
886
909
|
const stepsOf = (cell) => {
|
|
887
910
|
const ns = ["-n", "{namespace}"];
|
|
@@ -1334,6 +1357,62 @@ const stepsOf = (cell) => {
|
|
|
1334
1357
|
on: false
|
|
1335
1358
|
}]
|
|
1336
1359
|
};
|
|
1360
|
+
case "zone-loss": return {
|
|
1361
|
+
prepare: [{
|
|
1362
|
+
do: "signal",
|
|
1363
|
+
target: "clients",
|
|
1364
|
+
signal: "SIGHUP"
|
|
1365
|
+
}, {
|
|
1366
|
+
do: "wait",
|
|
1367
|
+
time: SPREAD_LEAD
|
|
1368
|
+
}],
|
|
1369
|
+
inject: [{
|
|
1370
|
+
do: "zone",
|
|
1371
|
+
lost: true
|
|
1372
|
+
}],
|
|
1373
|
+
hold: needs(trigger.hold, "a hold, the time that the zone is lost"),
|
|
1374
|
+
heal: [{
|
|
1375
|
+
do: "zone",
|
|
1376
|
+
lost: false
|
|
1377
|
+
}],
|
|
1378
|
+
restore: [{
|
|
1379
|
+
do: "zone",
|
|
1380
|
+
lost: false
|
|
1381
|
+
}]
|
|
1382
|
+
};
|
|
1383
|
+
case "latency": {
|
|
1384
|
+
const delay = needs(trigger.delay, "a delay, the time that each packet of Redis waits");
|
|
1385
|
+
if (valueIn(delay, "ms") <= 0 || valueIn(delay, "ms") >= valueIn(NETEM_DRAIN, "ms")) throw new Error(`the delay of latency is above zero and below ${valueIn(NETEM_DRAIN, "s")} s`);
|
|
1386
|
+
const back = [
|
|
1387
|
+
{
|
|
1388
|
+
do: "netem",
|
|
1389
|
+
target: "redis",
|
|
1390
|
+
delay: {
|
|
1391
|
+
value: 0,
|
|
1392
|
+
unit: "s"
|
|
1393
|
+
}
|
|
1394
|
+
},
|
|
1395
|
+
{
|
|
1396
|
+
do: "wait",
|
|
1397
|
+
time: NETEM_DRAIN
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
do: "netem",
|
|
1401
|
+
target: "redis",
|
|
1402
|
+
delay: null
|
|
1403
|
+
}
|
|
1404
|
+
];
|
|
1405
|
+
return {
|
|
1406
|
+
inject: [{
|
|
1407
|
+
do: "netem",
|
|
1408
|
+
target: "redis",
|
|
1409
|
+
delay
|
|
1410
|
+
}],
|
|
1411
|
+
hold: needs(trigger.hold, "a hold, the time that Redis is slow"),
|
|
1412
|
+
heal: back,
|
|
1413
|
+
restore: back
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1337
1416
|
}
|
|
1338
1417
|
};
|
|
1339
1418
|
/** 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. */
|
|
@@ -2450,7 +2529,12 @@ const serverObjects = (cell, namespace, image, version = 1) => {
|
|
|
2450
2529
|
topologyKey: "kubernetes.io/hostname",
|
|
2451
2530
|
whenUnsatisfiable: "ScheduleAnyway",
|
|
2452
2531
|
labelSelector: { matchLabels: { app: "lab" } }
|
|
2453
|
-
}
|
|
2532
|
+
}, ...cell.trigger.kind === "zone-loss" ? [{
|
|
2533
|
+
maxSkew: 1,
|
|
2534
|
+
topologyKey: ZONE_LABEL,
|
|
2535
|
+
whenUnsatisfiable: "DoNotSchedule",
|
|
2536
|
+
labelSelector: { matchLabels: { app: "lab" } }
|
|
2537
|
+
}] : []],
|
|
2454
2538
|
containers: [{
|
|
2455
2539
|
name: "app",
|
|
2456
2540
|
image,
|
|
@@ -2492,6 +2576,11 @@ const clientObjects = (cell, namespace, image, target) => [{
|
|
|
2492
2576
|
operator: "Exists",
|
|
2493
2577
|
effect: "NoSchedule"
|
|
2494
2578
|
}],
|
|
2579
|
+
...cell.trigger.kind === "zone-loss" ? { affinity: { nodeAffinity: { requiredDuringSchedulingIgnoredDuringExecution: { nodeSelectorTerms: [{ matchExpressions: [{
|
|
2580
|
+
key: ZONE_LABEL,
|
|
2581
|
+
operator: "NotIn",
|
|
2582
|
+
values: [ZONE_LOST]
|
|
2583
|
+
}] }] } } } } : {},
|
|
2495
2584
|
containers: [{
|
|
2496
2585
|
name: CLIENT,
|
|
2497
2586
|
image,
|
|
@@ -2604,6 +2693,50 @@ const stallRemovalBand = (readiness, propagation) => {
|
|
|
2604
2693
|
const spread = secondsOf(propagation);
|
|
2605
2694
|
return band(kubelet.lo + spread.lo, kubelet.hi + spread.hi);
|
|
2606
2695
|
};
|
|
2696
|
+
/**
|
|
2697
|
+
* These are the defaults of Kubernetes v1.37.0 for a lost node:
|
|
2698
|
+
* - `grace` 50 s and `monitor` 5 s: pkg/controller/nodelifecycle/config/v1alpha1/defaults.go, lines
|
|
2699
|
+
* 46 and 52. The controller checks the nodes on a sliding period (node_lifecycle_controller.go,
|
|
2700
|
+
* lines 506–510). It sets the probe time when it sees a new lease (lines 952–960), and it marks the
|
|
2701
|
+
* node Unknown after `grace` (line 962). Then it marks each pod of the node not ready (lines 768–773).
|
|
2702
|
+
* - `renew` 10 s: `NodeLeaseDurationSeconds` 40 (pkg/kubelet/apis/config/v1beta1/defaults.go, line 150)
|
|
2703
|
+
* times the fraction 0.25 (pkg/kubelet/kubelet.go, lines 237 and 1156).
|
|
2704
|
+
* - `jitter` 0.04: the lease controller renews on a sliding jitter of 0.04
|
|
2705
|
+
* (staging/src/k8s.io/component-helpers/apimachinery/lease/controller.go, line 153).
|
|
2706
|
+
* - `pingTimeout` 15 s: the PING timeout of the HTTP/2 health check, after a read idle timeout of 30 s
|
|
2707
|
+
* (staging/src/k8s.io/apimachinery/pkg/util/net/http.go, lines 131–192).
|
|
2708
|
+
* - `rewatch` 1.6 s: a first backoff of 800 ms with a jitter of 1.0
|
|
2709
|
+
* (staging/src/k8s.io/client-go/tools/cache/reflector.go, lines 62–67).
|
|
2710
|
+
* - `statusSync` 10 s: the sync period of the status manager (pkg/kubelet/status/status_manager.go, line 215).
|
|
2711
|
+
* - `writes` 0.25 s is a margin of the lab, not a default.
|
|
2712
|
+
*/
|
|
2713
|
+
const NODE_LIFECYCLE = {
|
|
2714
|
+
grace: seconds(50),
|
|
2715
|
+
monitor: seconds(5),
|
|
2716
|
+
renew: seconds(10),
|
|
2717
|
+
jitter: .04,
|
|
2718
|
+
writes: seconds(.25),
|
|
2719
|
+
pingTimeout: seconds(15),
|
|
2720
|
+
rewatch: seconds(1.6),
|
|
2721
|
+
statusSync: seconds(10)
|
|
2722
|
+
};
|
|
2723
|
+
/**
|
|
2724
|
+
* This function gives the time from the loss of a node to the drop of its pods from the rules of
|
|
2725
|
+
* the other nodes. The last renewal of the lease comes up to `renew × (1 + jitter)` before the loss.
|
|
2726
|
+
* The controller sees it up to one `monitor` later, and marks the node `grace` after that. Then the
|
|
2727
|
+
* writes and the propagation follow. The band does not add the low bound of the propagation.
|
|
2728
|
+
*/
|
|
2729
|
+
const nodeLossBand = (lifecycle, propagation) => {
|
|
2730
|
+
const last = s$1(lifecycle.renew) * (1 + lifecycle.jitter);
|
|
2731
|
+
return band(s$1(lifecycle.grace) - last, s$1(lifecycle.grace) + s$1(lifecycle.monitor) + s$1(lifecycle.writes) + s$1(propagation.hi));
|
|
2732
|
+
};
|
|
2733
|
+
/**
|
|
2734
|
+
* This function gives the time from the heal of a lost node until its pods are ready again in the
|
|
2735
|
+
* EndpointSlice. The kubelet connects again in one PING timeout at the most: its old connection
|
|
2736
|
+
* waits behind the backoff of TCP. Its reflectors watch again after their first backoff. Then its
|
|
2737
|
+
* status manager puts back the pod status in one sync period at the most.
|
|
2738
|
+
*/
|
|
2739
|
+
const nodeReturnBand = (lifecycle) => band(0, s$1(lifecycle.pingTimeout) + s$1(lifecycle.rewatch) + s$1(lifecycle.statusSync) + s$1(lifecycle.writes));
|
|
2607
2740
|
/** This function gives the cap of a stage in a declaration, or zero when the declaration does not name the stage. */
|
|
2608
2741
|
const capOf = (declaration, stage) => {
|
|
2609
2742
|
const found = declaration.phases.find(([name]) => name === stage);
|
|
@@ -2709,6 +2842,7 @@ const scenarioOf = (cell, propagation) => ({
|
|
|
2709
2842
|
* - In T07 a pause of kube-proxy comes before a deletion. In T18 the pause is on Redis.
|
|
2710
2843
|
* - The crash of the lab is SIGKILL from the node. Like a crash, it has no preStop hook and no drain.
|
|
2711
2844
|
* - The other faults are on a link, on Redis or on the process. The kubelet can restart a pod after them.
|
|
2845
|
+
* A zone loss freezes the pods of its node and deletes none of them in its hold.
|
|
2712
2846
|
*/
|
|
2713
2847
|
const stopOf = (cell) => {
|
|
2714
2848
|
switch (cell.trigger.kind) {
|
|
@@ -2729,7 +2863,9 @@ const stopOf = (cell) => {
|
|
|
2729
2863
|
case "idle":
|
|
2730
2864
|
case "ztunnel-restart":
|
|
2731
2865
|
case "certificate-expiry":
|
|
2732
|
-
case "cannot-serve":
|
|
2866
|
+
case "cannot-serve":
|
|
2867
|
+
case "zone-loss":
|
|
2868
|
+
case "latency": return null;
|
|
2733
2869
|
}
|
|
2734
2870
|
};
|
|
2735
2871
|
/**
|
|
@@ -2768,8 +2904,13 @@ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
2768
2904
|
const slug = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
2769
2905
|
/** This function tells if a cell has Redis: only a declaration of the service can have it. */
|
|
2770
2906
|
const hasRedis = (cell) => cell.declaration !== null && cell.declaration.redis !== null;
|
|
2771
|
-
/**
|
|
2772
|
-
|
|
2907
|
+
/**
|
|
2908
|
+
* This function gives the key of the cluster of a cell: its kube-proxy mode, its node count, and the
|
|
2909
|
+
* flavor of its mesh. A zone loss has clusters of its own, with a zone on each node.
|
|
2910
|
+
*/
|
|
2911
|
+
const clusterKey = (cell) => cell.mesh !== void 0 ? `${cell.mode}-${cell.workers}-${cell.mesh.flavor}` : zoned(cell) ? `${cell.mode}-${cell.workers}-zones` : `${cell.mode}-${cell.workers}`;
|
|
2912
|
+
/** This function tells if a cell needs a cluster with zones: a zone loss. */
|
|
2913
|
+
const zoned = (cell) => cell.trigger.kind === "zone-loss";
|
|
2773
2914
|
/**
|
|
2774
2915
|
* This tracker keeps the latest state of the cell from the lines: each pod, each slice and each
|
|
2775
2916
|
* client. It also has, for each node, the backends of its rules and the hosts of its client sidecar.
|
|
@@ -2832,7 +2973,8 @@ const unsteady = (ctx) => {
|
|
|
2832
2973
|
for (const node of ctx.cluster.nodes) if ((tracker.hosts.get(node) ?? []).join() !== expected) return `the client sidecar of ${node} has ${(tracker.hosts.get(node) ?? []).join(" ") || "no host"}`;
|
|
2833
2974
|
}
|
|
2834
2975
|
const nodes = new Set([...tracker.clients.values()].map((client) => client.node));
|
|
2835
|
-
|
|
2976
|
+
const clientNodes = ctx.cluster.nodes.length - (cell.trigger.kind === "zone-loss" ? 1 : 0);
|
|
2977
|
+
if (nodes.size !== clientNodes) return `clients answer on ${nodes.size} nodes, not ${clientNodes}`;
|
|
2836
2978
|
for (const [pod, client] of tracker.clients) {
|
|
2837
2979
|
if (tracker.last - client.ok > 1e3) return `client ${pod} has no answer in the last second`;
|
|
2838
2980
|
if (tracker.last - client.failed < 2e3) return `client ${pod} failed in the last 2 s`;
|
|
@@ -2849,6 +2991,37 @@ const steady = async (ctx, within) => {
|
|
|
2849
2991
|
}
|
|
2850
2992
|
return why;
|
|
2851
2993
|
};
|
|
2994
|
+
/** These taints of the node lifecycle controller mark a node that it does not see as ready. */
|
|
2995
|
+
const NODE_LOSS_TAINTS = ["node.kubernetes.io/unreachable", "node.kubernetes.io/not-ready"];
|
|
2996
|
+
/**
|
|
2997
|
+
* This function tells why a node is not at rest for the node lifecycle controller, or gives null. A
|
|
2998
|
+
* ready pod is not sufficient after a zone loss. The controller can still see the node as lost, and
|
|
2999
|
+
* then it does not mark the pods again at the next loss. The controller removes its taints only after
|
|
3000
|
+
* it sees the node ready.
|
|
3001
|
+
*/
|
|
3002
|
+
const nodeUnsteady = async (cluster, name) => {
|
|
3003
|
+
const node = JSON.parse(await cluster.kubectl([
|
|
3004
|
+
"get",
|
|
3005
|
+
"node",
|
|
3006
|
+
name,
|
|
3007
|
+
"-o",
|
|
3008
|
+
"json"
|
|
3009
|
+
]));
|
|
3010
|
+
const ready = node.status?.conditions?.find((condition) => condition.type === "Ready")?.status;
|
|
3011
|
+
if (ready !== "True") return `the node ${name} has the Ready condition ${ready ?? "none"}`;
|
|
3012
|
+
const taints = (node.spec?.taints ?? []).map((taint) => taint.key).filter((key) => NODE_LOSS_TAINTS.includes(key));
|
|
3013
|
+
return taints.length === 0 ? null : `the node ${name} has the taints ${taints.join(", ")}`;
|
|
3014
|
+
};
|
|
3015
|
+
/** This function waits until a node is at rest for the node lifecycle controller. It gives null, or the reason when the node is not at rest in time. */
|
|
3016
|
+
const nodeSteady = async (cluster, name, within) => {
|
|
3017
|
+
const end = Date.now() + within;
|
|
3018
|
+
let why = await nodeUnsteady(cluster, name);
|
|
3019
|
+
while (why !== null && Date.now() < end) {
|
|
3020
|
+
await sleep(1e3);
|
|
3021
|
+
why = await nodeUnsteady(cluster, name);
|
|
3022
|
+
}
|
|
3023
|
+
return why;
|
|
3024
|
+
};
|
|
2852
3025
|
/** This function samples the load of the VM for 4 s, and names the lab containers that are not of this run. */
|
|
2853
3026
|
const sample = async (ctx, ours) => {
|
|
2854
3027
|
const second = (await ctx.loader.exec([
|
|
@@ -3316,8 +3489,27 @@ const doStep = async (ctx, step, replicas, background) => {
|
|
|
3316
3489
|
case "middlebox":
|
|
3317
3490
|
if (step.target !== "servers") throw new Error(`a middlebox takes the target servers, not ${step.target}`);
|
|
3318
3491
|
return middleboxServers(ctx, step.idle, step.port, replicas);
|
|
3492
|
+
case "zone": return lab.act(lostNodeOf(cluster), {
|
|
3493
|
+
op: "zone",
|
|
3494
|
+
lost: step.lost
|
|
3495
|
+
});
|
|
3496
|
+
case "netem": {
|
|
3497
|
+
if (step.target !== "redis") throw new Error(`a netem takes the target redis, not ${step.target}`);
|
|
3498
|
+
const at = await where(step.target);
|
|
3499
|
+
const spec = step.delay === null ? ["clear-netem", POD_LINK] : [
|
|
3500
|
+
"netem",
|
|
3501
|
+
POD_LINK,
|
|
3502
|
+
"delay",
|
|
3503
|
+
`${Math.round(valueIn(step.delay, "ms"))}ms`
|
|
3504
|
+
];
|
|
3505
|
+
return lab.inject(at.node, at.pid, spec);
|
|
3506
|
+
}
|
|
3319
3507
|
}
|
|
3320
3508
|
};
|
|
3509
|
+
/** This function gives the node of the lost zone: the last worker (`zoneOf`). */
|
|
3510
|
+
const lostNodeOf = (cluster) => cluster.nodes.at(-1);
|
|
3511
|
+
/** This function puts the replicas of a node first, and keeps the sequence of the others. */
|
|
3512
|
+
const lostFirst = (replicas, node) => [...replicas.filter((replica) => replica.node === node), ...replicas.filter((replica) => replica.node !== node)];
|
|
3321
3513
|
/** This function tells if a run is over: the trigger is done, and the cell is at rest again. */
|
|
3322
3514
|
const over = (ctx, run, lines) => {
|
|
3323
3515
|
if (unsteady(ctx) !== null) return false;
|
|
@@ -3370,17 +3562,22 @@ const runOnce = async (ctx, env, index, warmup, ours) => {
|
|
|
3370
3562
|
await probeThePods(ctx);
|
|
3371
3563
|
await pollListeners(ctx);
|
|
3372
3564
|
await quiet(ctx, ours);
|
|
3565
|
+
const zoneLoss = cell.trigger.kind === "zone-loss";
|
|
3566
|
+
const lost = zoneLoss ? await nodeSteady(cluster, lostNodeOf(cluster), 3e5) : null;
|
|
3567
|
+
if (lost !== null) return empty(`the node of the lost zone was not at rest: ${lost}`, await lab.now());
|
|
3373
3568
|
if (await steady(ctx, 3e5) !== null) return empty("the cell was not at rest after the wait for a quiet VM", await lab.now());
|
|
3374
|
-
const replicas = replicasOf(ctx);
|
|
3569
|
+
const replicas = zoneLoss ? lostFirst(replicasOf(ctx), lostNodeOf(cluster)) : replicasOf(ctx);
|
|
3570
|
+
if (zoneLoss && replicas[0]?.node !== lostNodeOf(cluster)) return empty(`no replica is on the node of the lost zone, ${lostNodeOf(cluster)}`, await lab.now());
|
|
3375
3571
|
const restarts = new Map(ctx.tracker.servers().map((pod) => [pod.name, pod.cs.reduce((sum, status) => sum + status.rc, 0)]));
|
|
3376
3572
|
const target = hasRedis(cell) && [
|
|
3377
3573
|
"rst",
|
|
3378
3574
|
"blackhole",
|
|
3379
3575
|
"freeze-process",
|
|
3380
3576
|
"peer-gone-without-close",
|
|
3381
|
-
"rollout"
|
|
3577
|
+
"rollout",
|
|
3578
|
+
"latency"
|
|
3382
3579
|
].includes(cell.trigger.kind) ? null : replicas[0];
|
|
3383
|
-
const paused = cell.template === "T07" && cell.trigger.kind === "freeze-process" ? cluster.nodes[1] ?? cluster.nodes[0] : null;
|
|
3580
|
+
const paused = cell.template === "T07" && cell.trigger.kind === "freeze-process" ? cluster.nodes[1] ?? cluster.nodes[0] : zoneLoss ? lostNodeOf(cluster) : null;
|
|
3384
3581
|
const cleared = await lab.forgetHandshakes(ctx.clusterIp, 80);
|
|
3385
3582
|
lab.take();
|
|
3386
3583
|
for (const key of Object.keys(lab.dropped)) delete lab.dropped[key];
|
|
@@ -3595,7 +3792,7 @@ const runKindCells = async (cells, options) => {
|
|
|
3595
3792
|
for (const [key, group] of groups) {
|
|
3596
3793
|
const partial = /* @__PURE__ */ new Map();
|
|
3597
3794
|
for (let env = 0; env < environments; env += 1) {
|
|
3598
|
-
const s = scenario(`lab-${key}-${env}`, group[0].mode, group[0].workers);
|
|
3795
|
+
const s = scenario(`lab-${key}-${env}`, group[0].mode, group[0].workers, void 0, zoned(group[0]));
|
|
3599
3796
|
const dir = join(options.work ?? join(tmpdir(), "systems-kind-work"), s.name);
|
|
3600
3797
|
const mesh = group[0].mesh;
|
|
3601
3798
|
options.log(`cluster ${s.name}: ${s.kubeProxy.mode}, ${s.workers} workers${mesh === void 0 ? "" : `, Istio ${mesh.flavor}`}`);
|
|
@@ -3739,7 +3936,8 @@ const estimate = (cell, environments = 2) => {
|
|
|
3739
3936
|
idle: hold + 5,
|
|
3740
3937
|
"ztunnel-restart": 40,
|
|
3741
3938
|
"certificate-expiry": hold + 20,
|
|
3742
|
-
"cannot-serve": hold + 20
|
|
3939
|
+
"cannot-serve": hold + 20,
|
|
3940
|
+
"zone-loss": hold + 45
|
|
3743
3941
|
};
|
|
3744
3942
|
const after = observationAfter(cell);
|
|
3745
3943
|
const observed = after === null ? 0 : hold + valueIn(after, "s");
|
|
@@ -3777,6 +3975,6 @@ const shardOf = (cells, index, count) => {
|
|
|
3777
3975
|
return out;
|
|
3778
3976
|
};
|
|
3779
3977
|
//#endregion
|
|
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 };
|
|
3978
|
+
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, NETEM_DRAIN, NETNS_DEFAULTS, NODE_IMAGES, NODE_LIFECYCLE, O04, O09, O10, O16, POD_LINK, POLICY, PORT, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, SPREAD_LEAD, STAGES, SYSCTL, TCP_STATE, WATCHDOG, ZONE_KEPT, ZONE_LABEL, ZONE_LOST, 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, nodeLossBand, nodeNames, nodeReturnBand, 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, zoneOf, ztunnelCertificates, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
|
|
3781
3979
|
|
|
3782
3980
|
//# sourceMappingURL=index.js.map
|