@mark1russell7/kind 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -105,6 +105,12 @@ Each pod of a cluster shares the kernel of the Docker VM. Thus each stamp of the
105
105
 
106
106
  Before each run, the lab deletes the conntrack entries in SYN_SENT to the ClusterIP on each node (`forgetHandshakes`). A note of the run gives each count. Such an entry is a SYN with no answer, and it keeps its NAT for 120 s. A new SYN from the same port goes where the first one went, and it gets no answer either. The clients send requests between the runs too. Thus the restore of one run left such entries, and a client that took the port again in the next run timed out (T07, 2026-10-17).
107
107
 
108
+ Before each run, the lab waits for a quiet VM (`quiet.ts`). It waits for no lab container of another agent, and for an idle share. The clients of the cell run at that time, and the agent of each node reads the conntrack table each second. Thus the idle share has the load of the cell in it, and a flat share voided a heavy cell with no other load (SYS-95). The gate reads the cell against itself:
109
+
110
+ - **The baseline.** Before the first run of an environment, the lab waits until the cell is 120 s old, and it takes 3 samples. A baseline sample has no field `needed`. The baseline is the median of those samples, and the highest median of the environments holds, because a foreign load only lowers it.
111
+ - **The share.** A run needs the baseline less the margin, between the floor and the flat share of 60%. Thus a cell at rest at 60% or more keeps its gate. A warm-up with no baseline needs only the floor. Each sample of the gate keeps its share in the field `needed`.
112
+ - **The test of the gate.** A cell with `plannedLoad` starts a process in the loader after the baseline, and the process keeps that count of CPUs busy. The gate must refuse that run, and thus the run is void.
113
+
108
114
  ## The stacks
109
115
 
110
116
  From 0.2.0, a cell names its stack (`stack`): its server and its clients. A cell without a stack has the service.
package/build/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as factsOf, $n as DATAPLANES, $t as transitionOf, A as KindCellResult, An as KubeletProbe, At as failuresOf, B as upgradeCell, Bn as ReconnectsPrediction, Bt as restartOf, C as BandV1, Cn as Band, Ct as ZtunnelPodLine, D as FORMAT_V1, Dn as Flap, Dt as deletionOf, E as FORMAT, En as EdgeProtocol, Et as byNode, F as RunCheckV1, Fn as NonePrediction, Ft as periodOf, G as LAST_SLACK, Gn as Stack, Gt as signalsOf, H as KIND_NOISE, Hn as Reference, Ht as rulesOf, I as RunFactsV1, In as PermittedWindow, It as podsAt, J as RunCheck, Jn as TriggerKind, Jt as sliceReadyAt, K as Propagated, Kn as Template, Kt as sliceDropOf, L as TriggerV1, Ln as PodSettings, Lt as podsOf, M as KindVerdictV1, Mn as Mesh, Mt as isTunnelState, N as LoadSample, Nn as MeshFlavor, Nt as kernelCounts, O as KindCellRecord, On as KindCell, Ot as dropOf, P as PredictionV1, Pn as MeshMode, Pt as outcomesOf, Q as deletionsOf, Qn as Workload, Qt as stoppingOf, R as judge, Rn as Prediction, Rt as recordsOf, S as timeSpread, Sn as Backoff, St as TunnelLine, T as EnvironmentManifest, Tn as Declaration, Tt as byClients, U as KindDecision, Un as Replica, Ut as sessionsAt, V as Deleted, Vn as RedisDeclaration, Vt as restartsAt, W as KindVerdict, Wn as ResetReuse, Wt as signalOf, X as checkRun, Xn as VipSettings, Xt as slicesOf, Y as RunFacts, Yn as VipAnnouncerName, Yt as sliceReadyOf, Z as cyclesOf, Zn as WindowPrediction, Zt as socketsOf, _ as TimeSpread, _n as requestBand, _r as scenario, _t as RulesLine, a as judgeReconnects, an as LB_CLASS, ar as NODE_IMAGES, at as referenceOf, b as medianText, bn as showBand, bt as SocketLine, c as RELATIVE, cn as PORT, cr as ZONE_LABEL, ct as updatesOf, d as quantileOf, dn as VIP_ANNOTATION, dr as cidrRange, dt as Line, en as tunnelsOf, er as Dataplane, et as judgeKind, f as STAGES, fn as CountBand, fr as goDuration, ft as Period, g as Judged, gn as overshootBand, gr as nodeNames, gt as Request, h as readRecord, hn as drainBand, hr as kubeProxyPatch, ht as RecordLine, i as Try, in as HEALTH_PORT, ir as KubeProxyMode, it as propagationSource, j as KindCellV1, jn as MemberlistSettings, jt as intakeOf, k as KindCellRecordV1, kn as KindRun, kt as emptyOf, l as medianInterval, ln as REDIS, lr as ZONE_LOST, lt as Endpoint, m as kindCellRecordV1Schema, mn as bandOf, mr as kindConfig, mt as PropagationSource, n as Return, nn as ztunnelReplaced, nr as KindConfig, nt as observationEnd, o as latestReturn, on as LOG_LABEL, or as NodeImage, ot as reusesReset, p as kindCellRecordSchema, pn as backlogEnd, pr as isKubeProxyMode, pt as PodLine, q as ReconnectsFacts, qn as Trigger, qt as sliceEmptyOf, r as Schedule, rn as CLIENT, rr as KindScenario, rt as propagationOf, s as triesOf, sn as OUTSIDE, sr as ZONE_KEPT, st as unitOf, t as Reconnects, tn as ztunnelPodsOf, tr as KUBE_PROXY_MODES, tt as observationAfter, u as middle, un as SERVER, ur as cidrOverlap, ut as HBONE_PORT, v as calibrationOf, vn as seconds, vr as scenarioProblems, vt as Sessions, w as ClusterManifest, wn as Cycle, wt as backendsAt, x as predictionText, xn as BacklogTerm, xt as TCP_STATE, y as cellsTable, yn as secondsOf, yr as zoneOf, yt as SliceLine, z as upgrade, zn as PulsarSettings, zt as requestsOf } from "./judge-Cp3MzMk1.js";
1
+ import { $ as factsOf, $n as DATAPLANES, $t as transitionOf, A as KindCellResult, An as KubeletProbe, At as failuresOf, B as upgradeCell, Bn as ReconnectsPrediction, Bt as restartOf, C as BandV1, Cn as Band, Ct as ZtunnelPodLine, D as FORMAT_V1, Dn as Flap, Dt as deletionOf, E as FORMAT, En as EdgeProtocol, Et as byNode, F as RunCheckV1, Fn as NonePrediction, Ft as periodOf, G as LAST_SLACK, Gn as Stack, Gt as signalsOf, H as KIND_NOISE, Hn as Reference, Ht as rulesOf, I as RunFactsV1, In as PermittedWindow, It as podsAt, J as RunCheck, Jn as TriggerKind, Jt as sliceReadyAt, K as Propagated, Kn as Template, Kt as sliceDropOf, L as TriggerV1, Ln as PodSettings, Lt as podsOf, M as KindVerdictV1, Mn as Mesh, Mt as isTunnelState, N as LoadSample, Nn as MeshFlavor, Nt as kernelCounts, O as KindCellRecord, On as KindCell, Ot as dropOf, P as PredictionV1, Pn as MeshMode, Pt as outcomesOf, Q as deletionsOf, Qn as Workload, Qt as stoppingOf, R as judge, Rn as Prediction, Rt as recordsOf, S as timeSpread, Sn as Backoff, St as TunnelLine, T as EnvironmentManifest, Tn as Declaration, Tt as byClients, U as KindDecision, Un as Replica, Ut as sessionsAt, V as Deleted, Vn as RedisDeclaration, Vt as restartsAt, W as KindVerdict, Wn as ResetReuse, Wt as signalOf, X as checkRun, Xn as VipSettings, Xt as slicesOf, Y as RunFacts, Yn as VipAnnouncerName, Yt as sliceReadyOf, Z as cyclesOf, Zn as WindowPrediction, Zt as socketsOf, _ as TimeSpread, _n as requestBand, _r as scenario, _t as RulesLine, a as judgeReconnects, an as LB_CLASS, ar as NODE_IMAGES, at as referenceOf, b as medianText, bn as showBand, bt as SocketLine, c as RELATIVE, cn as PORT, cr as ZONE_LABEL, ct as updatesOf, d as quantileOf, dn as VIP_ANNOTATION, dr as cidrRange, dt as Line, en as tunnelsOf, er as Dataplane, et as judgeKind, f as STAGES, fn as CountBand, fr as goDuration, ft as Period, g as Judged, gn as overshootBand, gr as nodeNames, gt as Request, h as readRecord, hn as drainBand, hr as kubeProxyPatch, ht as RecordLine, i as Try, in as HEALTH_PORT, ir as KubeProxyMode, it as propagationSource, j as KindCellV1, jn as MemberlistSettings, jt as intakeOf, k as KindCellRecordV1, kn as KindRun, kt as emptyOf, l as medianInterval, ln as REDIS, lr as ZONE_LOST, lt as Endpoint, m as kindCellRecordV1Schema, mn as bandOf, mr as kindConfig, mt as PropagationSource, n as Return, nn as ztunnelReplaced, nr as KindConfig, nt as observationEnd, o as latestReturn, on as LOG_LABEL, or as NodeImage, ot as reusesReset, p as kindCellRecordSchema, pn as backlogEnd, pr as isKubeProxyMode, pt as PodLine, q as ReconnectsFacts, qn as Trigger, qt as sliceEmptyOf, r as Schedule, rn as CLIENT, rr as KindScenario, rt as propagationOf, s as triesOf, sn as OUTSIDE, sr as ZONE_KEPT, st as unitOf, t as Reconnects, tn as ztunnelPodsOf, tr as KUBE_PROXY_MODES, tt as observationAfter, u as middle, un as SERVER, ur as cidrOverlap, ut as HBONE_PORT, v as calibrationOf, vn as seconds, vr as scenarioProblems, vt as Sessions, w as ClusterManifest, wn as Cycle, wt as backendsAt, x as predictionText, xn as BacklogTerm, xt as TCP_STATE, y as cellsTable, yn as secondsOf, yr as zoneOf, yt as SliceLine, z as upgrade, zn as PulsarSettings, zt as requestsOf } from "./judge-DLn2PLxb.js";
2
2
  import { Quantity } from "@mark1russell7/quantity";
3
3
  import { CheckFn, Coupling, Finding, HealthServer, Poll, Scenario, ServiceBuilder, ServiceDescription, Stage, StopWay, Timing, TransportImpl, Verdict } from "@mark1russell7/service";
4
4
  import { BuildImage } from "@mark1russell7/harness";
@@ -88,8 +88,12 @@ interface PinnedChart {
88
88
  readonly url: string;
89
89
  readonly sha256: string;
90
90
  }
91
- /** This function gives the path of a chart in the cache, after a download when the cache does not have it. It refuses a file whose sha256 is not the pinned value. */
92
- export declare const ensurePinnedChart: (chart: PinnedChart, cache?: string) => Promise<string>;
91
+ /**
92
+ * This function gives the path of a chart in the cache, after a download when the cache does not have it.
93
+ * It refuses a download whose sha256 is not the pinned value. A file in the cache with a different
94
+ * sha256 (a torn write) is downloaded again, and each write replaces the file in one step.
95
+ */
96
+ export declare const ensurePinnedChart: (chart: PinnedChart, cache?: string, get?: (url: string) => Promise<Uint8Array>) => Promise<string>;
93
97
  /**
94
98
  * This function installs a pinned chart in a cluster with the values `values`. It writes the values
95
99
  * to a file in the folder of the cluster. Helm waits for each workload of the chart, for up to 10 min.
@@ -381,7 +385,8 @@ export declare const DNS_PORT = 53;
381
385
  export declare const dnsCommands: (on: boolean) => string[][];
382
386
  /**
383
387
  * This function gives the commands of the injector that put a stateful middlebox in its network
384
- * namespace, with each peer, on the local port `port`. With `idle` null, they remove it.
388
+ * namespace, with each peer, on the local port `port`. With `idle` null, they remove the parts of these
389
+ * peers. A run removes what the table of the namespace holds (`middleboxRemoval`).
385
390
  *
386
391
  * The middlebox forgets a flow of the port after `idle` with no segment. Then it drops each later
387
392
  * segment of it: the silent-drop form of the router of the harness. Conntrack stays as it is. The
@@ -404,6 +409,16 @@ export declare const dnsCommands: (on: boolean) => string[][];
404
409
  * old flow of the peer. A cell of the middlebox opens no new flow in its gap.
405
410
  */
406
411
  export declare const middleboxCommands: (peers: readonly string[], idle: Quantity | null, port: number) => string[][];
412
+ /**
413
+ * This function gives the commands that remove a middlebox from a network namespace, from the filter
414
+ * table that `iptables-save -c` gives for it. An empty list means that the namespace has no part of it.
415
+ *
416
+ * The commands remove each part that the table holds, and only those. The lab stops at the first
417
+ * command that fails. Thus a removal from a list of the peers stops at a jump that is not there, and
418
+ * its chains stay. For example, a set that failed half way added no jumps, or a client pod has a new
419
+ * address. Then the next set of the namespace fails at its `-N`.
420
+ */
421
+ export declare const middleboxRemoval: (saved: string) => string[][];
407
422
  /**
408
423
  * This function gives the placement of the sessions of the clients: the backend of each slot of each
409
424
  * client, by client. The clients come in the sequence of their names. The sessions on the target go
@@ -1031,7 +1046,11 @@ export declare const metallbRecord: (cluster: Pick<Cluster, "kubectl">, namespac
1031
1046
  */
1032
1047
  /** This version is the release of Pulsar of the lab. */
1033
1048
  export declare const PULSAR_VERSION = "5.0.0";
1034
- /** This chart is the Helm chart 4.8.0 of Pulsar. The sha256 is of the file of the release. */
1049
+ /**
1050
+ * This chart is the Helm chart 4.8.0 of Pulsar. The sha256 is of the file of the release. The URL is
1051
+ * on the archive of Apache, which keeps each release. The mirror downloads.apache.org keeps only the
1052
+ * latest releases.
1053
+ */
1035
1054
  export declare const PULSAR_CHART: PinnedChart;
1036
1055
  /**
1037
1056
  * This image is Pulsar 5.0.0 for linux/amd64, pinned by the digest of the manifest of the platform.
@@ -1371,6 +1390,60 @@ interface LearnWindow {
1371
1390
  */
1372
1391
  export declare const learnWindow: (declaration: Declaration, readiness: KubeletProbe, propagation: Propagation, workload: Workload) => LearnWindow;
1373
1392
  //#endregion
1393
+ //#region src/quiet.d.ts
1394
+ /**
1395
+ * The quiet gate asks for an idle share of the VM before a run. The clients of the cell run at that
1396
+ * time, and the agent of each node reads the whole conntrack table each second. Thus the idle share
1397
+ * has the load of the cell in it. A flat share can void a heavy cell with no other load (SYS-95).
1398
+ * The gate reads the cell against itself. The baseline is the idle share of the settled cell, and
1399
+ * a foreign load shows as a fall from the baseline.
1400
+ */
1401
+ /** These numbers are the terms of the gate. Each share is a share of all the CPUs of the VM. */
1402
+ interface QuietGate {
1403
+ /** This share is enough for each cell, as it was before SYS-95. */
1404
+ readonly flat: number;
1405
+ /** This share is the most fall from the baseline that the gate lets through. */
1406
+ readonly margin: number;
1407
+ /** This share is the least that the gate lets through, with any baseline. */
1408
+ readonly floor: number;
1409
+ /** This time in milliseconds is the age of a cell at its first baseline sample. */
1410
+ readonly settle: number;
1411
+ /** This count is the samples of a baseline. */
1412
+ readonly samples: number;
1413
+ }
1414
+ /**
1415
+ * These are the terms of the lab. The flat share is the share of SYS-42. The other terms come from the
1416
+ * calibration of SYS-95, over the 9 records of SYS-57, with no foreign container in them:
1417
+ *
1418
+ * - The margin is the 99th percentile of the fall from the settled median of an environment: 4.88
1419
+ * points of 93 samples, rounded up.
1420
+ * - The floor is the lowest settled median of an environment, 48 %, minus the margin.
1421
+ * - The time to settle holds the slowest environment. Its conntrack table was at its plateau at 105 s.
1422
+ */
1423
+ export declare const QUIET_GATE: QuietGate;
1424
+ /**
1425
+ * This function gives the idle share that a run needs. With no baseline, it is the floor: a warm-up
1426
+ * counts for nothing, and its table is not full yet. A cell that is at rest at the flat share or more
1427
+ * keeps the flat share.
1428
+ */
1429
+ export declare const neededIdle: (gate: QuietGate, baseline: number | null) => number;
1430
+ /** This function gives the reason of a sample that the gate refuses. The site reads it back with `NOT_QUIET`. */
1431
+ export declare const quietWhy: (idle: number, needed: number, foreign: readonly string[]) => string;
1432
+ /**
1433
+ * This form reads the void of a run that the gate refuses. Its groups are the wait in seconds, the idle share, the share
1434
+ * of the gate and the other lab containers. A record from before SYS-95 has no share of the gate.
1435
+ */
1436
+ export declare const NOT_QUIET: RegExp;
1437
+ /**
1438
+ * This function gives the next baseline of a cell from the samples of one environment. Samples with
1439
+ * a foreign container do not count. The highest median holds, because a foreign load only lowers
1440
+ * the idle share. Thus a load in one environment does not move the gate of the other one.
1441
+ */
1442
+ export declare const baselineOf: (previous: number | null, samples: ReadonlyArray<{
1443
+ readonly idle: number;
1444
+ readonly foreign: readonly string[];
1445
+ }>) => number | null;
1446
+ //#endregion
1374
1447
  //#region src/rules.d.ts
1375
1448
  /**
1376
1449
  * This function gives the scenario of a cell for `lint()`: the preStop sleep, the grace, the probe
@@ -1500,5 +1573,5 @@ export declare const toolPath: (tool: Tool, key?: string, cache?: string) => str
1500
1573
  */
1501
1574
  export declare const ensureTool: (tool: Tool, key?: string, cache?: string) => Promise<string>;
1502
1575
  //#endregion
1503
- export { type Announcement, type BacklogTerm, type Backoff, type Band, type BandV1, type Broker, CLIENT, type CiliumImages, type Cluster, type ClusterHosts, type ClusterManifest, type CountBand, type Credentials, type Cycle, DATAPLANES, DRAIN_RULES, type Dataplane, 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 KubeVipPod, type KubeletProbe, LAST_SLACK, LB_CLASS, LOG_LABEL, type LdsSpec, type LeafCertificate, type LearnWindow, Line, type ListenerCounts, type LoadSample, type MemberlistSettings, type Mesh, type MeshFlavor, type MeshImages, type MeshMode, type MetallbImages, NODE_IMAGES, type NodeImage, type NodeLifecycle, type NonePrediction, O04, O09, O10, O16, OUTSIDE, type OutsideSpec, PORT, type Parts, Period, type PermittedWindow, type PinnedChart, PodLine, type PodSettings, type Prediction, type PredictionV1, type ProducerState, type Propagated, type Propagation, PropagationSource, type PulsarSettings, REDIS, RELATIVE, type Reconnects, type ReconnectsFacts, type ReconnectsPrediction, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, type Return, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, type RunOptions, SERVER, STAGES, type Schedule, type ServiceRule, Sessions, SliceLine, SocketLine, type Stack, type Stamp, type Step, TCP_STATE, type Target, type Template, type TimeSpread, type Tool, type Trigger, type TriggerKind, type TriggerV1, type Try, TunnelLine, VIP_ANNOTATION, type Verdicts, type VipAnnouncer, type VipAnnouncerName, type VipLease, type VipNetwork, type VipService, type VipSettings, type WindowPrediction, type Workload, ZONE_KEPT, ZONE_LABEL, ZONE_LOST, ZtunnelPodLine, backendsAt, backlogEnd, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cidrOverlap, cidrRange, cyclesOf, deletionOf, deletionsOf, drainBand, dropOf, emptyOf, factsOf, failuresOf, goDuration, intakeOf, isKubeProxyMode, isTunnelState, judge, judgeKind, judgeReconnects, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, latestReturn, medianInterval, medianText, middle, nodeNames, observationAfter, observationEnd, outcomesOf, overshootBand, periodOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestBand, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, scenario, scenarioProblems, seconds, secondsOf, sessionsAt, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, triesOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, zoneOf, ztunnelPodsOf, ztunnelReplaced };
1576
+ export { type Announcement, type BacklogTerm, type Backoff, type Band, type BandV1, type Broker, CLIENT, type CiliumImages, type Cluster, type ClusterHosts, type ClusterManifest, type CountBand, type Credentials, type Cycle, DATAPLANES, DRAIN_RULES, type Dataplane, 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 KubeVipPod, type KubeletProbe, LAST_SLACK, LB_CLASS, LOG_LABEL, type LdsSpec, type LeafCertificate, type LearnWindow, Line, type ListenerCounts, type LoadSample, type MemberlistSettings, type Mesh, type MeshFlavor, type MeshImages, type MeshMode, type MetallbImages, NODE_IMAGES, type NodeImage, type NodeLifecycle, type NonePrediction, O04, O09, O10, O16, OUTSIDE, type OutsideSpec, PORT, type Parts, Period, type PermittedWindow, type PinnedChart, PodLine, type PodSettings, type Prediction, type PredictionV1, type ProducerState, type Propagated, type Propagation, PropagationSource, type PulsarSettings, type QuietGate, REDIS, RELATIVE, type Reconnects, type ReconnectsFacts, type ReconnectsPrediction, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, type Return, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, type RunOptions, SERVER, STAGES, type Schedule, type ServiceRule, Sessions, SliceLine, SocketLine, type Stack, type Stamp, type Step, TCP_STATE, type Target, type Template, type TimeSpread, type Tool, type Trigger, type TriggerKind, type TriggerV1, type Try, TunnelLine, VIP_ANNOTATION, type Verdicts, type VipAnnouncer, type VipAnnouncerName, type VipLease, type VipNetwork, type VipService, type VipSettings, type WindowPrediction, type Workload, ZONE_KEPT, ZONE_LABEL, ZONE_LOST, ZtunnelPodLine, backendsAt, backlogEnd, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cidrOverlap, cidrRange, cyclesOf, deletionOf, deletionsOf, drainBand, dropOf, emptyOf, factsOf, failuresOf, goDuration, intakeOf, isKubeProxyMode, isTunnelState, judge, judgeKind, judgeReconnects, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, latestReturn, medianInterval, medianText, middle, nodeNames, observationAfter, observationEnd, outcomesOf, overshootBand, periodOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestBand, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, scenario, scenarioProblems, seconds, secondsOf, sessionsAt, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, triesOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, zoneOf, ztunnelPodsOf, ztunnelReplaced };
1504
1577
  //# sourceMappingURL=index.d.ts.map
package/build/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { $ as rulesOf, A as judgeReconnects, At as overshootBand, B as emptyOf, C as observationEnd, Ct as PORT, D as reusesReset, Dt as backlogEnd, E as referenceOf, Et as VIP_ANNOTATION, F as backendsAt, G as outcomesOf, H as intakeOf, I as byClients, J as podsOf, K as periodOf, L as byNode, M as triesOf, Mt as seconds, N as HBONE_PORT, Nt as secondsOf, O as unitOf, Ot as bandOf, P as TCP_STATE, Pt as showBand, Q as restartsAt, R as deletionOf, S as observationAfter, St as OUTSIDE, T as propagationSource, Tt as SERVER, U as isTunnelState, V as failuresOf, W as kernelCounts, X as requestsOf, Y as recordsOf, Z as restartOf, _ as checkRun, _t as quantileOf, a as calibrationOf, at as sliceReadyAt, b as factsOf, bt as LB_CLASS, c as predictionText, ct as socketsOf, d as FORMAT_V1, dt as tunnelsOf, et as sessionsAt, f as judge, ft as ztunnelPodsOf, g as LAST_SLACK, gt as middle, h as KIND_NOISE, ht as medianInterval, i as readRecord, it as sliceEmptyOf, j as latestReturn, jt as requestBand, k as updatesOf, kt as drainBand, l as timeSpread, lt as stoppingOf, m as upgradeCell, mt as RELATIVE, n as kindCellRecordSchema, nt as signalsOf, o as cellsTable, ot as sliceReadyOf, p as upgrade, pt as ztunnelReplaced, q as podsAt, r as kindCellRecordV1Schema, rt as sliceDropOf, s as medianText, st as slicesOf, t as STAGES, tt as signalOf, u as FORMAT, ut as transitionOf, v as cyclesOf, vt as CLIENT, w as propagationOf, wt as REDIS, x as judgeKind, xt as LOG_LABEL, y as deletionsOf, yt as HEALTH_PORT, z as dropOf } from "./judge-C6XgY2Pk.js";
1
+ import { $ as rulesOf, A as judgeReconnects, At as overshootBand, B as emptyOf, C as observationEnd, Ct as PORT, D as reusesReset, Dt as backlogEnd, E as referenceOf, Et as VIP_ANNOTATION, F as backendsAt, G as outcomesOf, H as intakeOf, I as byClients, J as podsOf, K as periodOf, L as byNode, M as triesOf, Mt as seconds, N as HBONE_PORT, Nt as secondsOf, O as unitOf, Ot as bandOf, P as TCP_STATE, Pt as showBand, Q as restartsAt, R as deletionOf, S as observationAfter, St as OUTSIDE, T as propagationSource, Tt as SERVER, U as isTunnelState, V as failuresOf, W as kernelCounts, X as requestsOf, Y as recordsOf, Z as restartOf, _ as checkRun, _t as quantileOf, a as calibrationOf, at as sliceReadyAt, b as factsOf, bt as LB_CLASS, c as predictionText, ct as socketsOf, d as FORMAT_V1, dt as tunnelsOf, et as sessionsAt, f as judge, ft as ztunnelPodsOf, g as LAST_SLACK, gt as middle, h as KIND_NOISE, ht as medianInterval, i as readRecord, it as sliceEmptyOf, j as latestReturn, jt as requestBand, k as updatesOf, kt as drainBand, l as timeSpread, lt as stoppingOf, m as upgradeCell, mt as RELATIVE, n as kindCellRecordSchema, nt as signalsOf, o as cellsTable, ot as sliceReadyOf, p as upgrade, pt as ztunnelReplaced, q as podsAt, r as kindCellRecordV1Schema, rt as sliceDropOf, s as medianText, st as slicesOf, t as STAGES, tt as signalOf, u as FORMAT, ut as transitionOf, v as cyclesOf, vt as CLIENT, w as propagationOf, wt as REDIS, x as judgeKind, xt as LOG_LABEL, y as deletionsOf, yt as HEALTH_PORT, z as dropOf } from "./judge-DjtNaAVO.js";
2
2
  import { valueIn } from "@mark1russell7/quantity";
3
+ import { median } from "@mark1russell7/rigor-statistics";
3
4
  import { chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
5
  import { dirname, join } from "node:path";
5
6
  import { execFile, execFileSync } from "node:child_process";
@@ -643,16 +644,18 @@ const createCluster = async (scenario, dir) => {
643
644
  };
644
645
  //#endregion
645
646
  //#region src/helm.ts
646
- /** This function gives the path of a chart in the cache, after a download when the cache does not have it. It refuses a file whose sha256 is not the pinned value. */
647
- const ensurePinnedChart = async (chart, cache = cacheFolder()) => {
647
+ /**
648
+ * This function gives the path of a chart in the cache, after a download when the cache does not have it.
649
+ * It refuses a download whose sha256 is not the pinned value. A file in the cache with a different
650
+ * sha256 (a torn write) is downloaded again, and each write replaces the file in one step.
651
+ */
652
+ const ensurePinnedChart = async (chart, cache = cacheFolder(), get = download) => {
648
653
  const path = join(cache, "charts", `${chart.name}-${chart.version}.tgz`);
649
- const bytes = existsSync(path) ? readFileSync(path) : await download(chart.url);
654
+ if (existsSync(path) && sha256(readFileSync(path)) === chart.sha256) return path;
655
+ const bytes = await get(chart.url);
650
656
  const found = sha256(bytes);
651
657
  if (found !== chart.sha256) throw new Error(`the chart ${chart.name} ${chart.version} has the sha256 ${found}, not the pinned ${chart.sha256}`);
652
- if (!existsSync(path)) {
653
- mkdirSync(join(cache, "charts"), { recursive: true });
654
- writeFileSync(path, bytes);
655
- }
658
+ writeWhole(path, bytes, false);
656
659
  return path;
657
660
  };
658
661
  /**
@@ -1069,7 +1072,8 @@ const dnsCommands = (on) => {
1069
1072
  };
1070
1073
  /**
1071
1074
  * This function gives the commands of the injector that put a stateful middlebox in its network
1072
- * namespace, with each peer, on the local port `port`. With `idle` null, they remove it.
1075
+ * namespace, with each peer, on the local port `port`. With `idle` null, they remove the parts of these
1076
+ * peers. A run removes what the table of the namespace holds (`middleboxRemoval`).
1073
1077
  *
1074
1078
  * The middlebox forgets a flow of the port after `idle` with no segment. Then it drops each later
1075
1079
  * segment of it: the silent-drop form of the router of the harness. Conntrack stays as it is. The
@@ -1201,6 +1205,38 @@ const middleboxCommands = (peers, idle, port) => {
1201
1205
  ];
1202
1206
  };
1203
1207
  /**
1208
+ * This function gives the commands that remove a middlebox from a network namespace, from the filter
1209
+ * table that `iptables-save -c` gives for it. An empty list means that the namespace has no part of it.
1210
+ *
1211
+ * The commands remove each part that the table holds, and only those. The lab stops at the first
1212
+ * command that fails. Thus a removal from a list of the peers stops at a jump that is not there, and
1213
+ * its chains stay. For example, a set that failed half way added no jumps, or a client pod has a new
1214
+ * address. Then the next set of the namespace fails at its `-N`.
1215
+ */
1216
+ const middleboxRemoval = (saved) => {
1217
+ const chains = [MIDDLEBOX.input, MIDDLEBOX.output];
1218
+ const lines = saved.split("\n").map((line) => line.trim().replace(/^\[\d+:\d+\]\s+/, ""));
1219
+ const present = chains.filter((chain) => lines.some((line) => line.startsWith(`:${chain} `)));
1220
+ const jumps = lines.map((line) => line.split(/\s+/)).filter((words) => words[0] === "-A" && (words[1] === "INPUT" || words[1] === "OUTPUT") && chains.some((chain) => words.at(-1) === chain && words.at(-2) === "-j")).map((words) => [
1221
+ "iptables",
1222
+ "-D",
1223
+ ...words.slice(1)
1224
+ ]);
1225
+ return [
1226
+ ...present.map((chain) => [
1227
+ "iptables",
1228
+ "-F",
1229
+ chain
1230
+ ]),
1231
+ ...jumps,
1232
+ ...present.map((chain) => [
1233
+ "iptables",
1234
+ "-X",
1235
+ chain
1236
+ ])
1237
+ ];
1238
+ };
1239
+ /**
1204
1240
  * This function gives the target of a reset or a black hole of a cell. In T07 and T18 it is Redis,
1205
1241
  * with the replicas as peers. In T15 the fault is on the mesh leg between the client pods and the
1206
1242
  * replicas. It is a rule in each replica, with the client pods as peers. A partition (`partition`)
@@ -3184,11 +3220,15 @@ const macsAt = (found, mac, count) => {
3184
3220
  */
3185
3221
  /** This version is the release of Pulsar of the lab. */
3186
3222
  const PULSAR_VERSION = "5.0.0";
3187
- /** This chart is the Helm chart 4.8.0 of Pulsar. The sha256 is of the file of the release. */
3223
+ /**
3224
+ * This chart is the Helm chart 4.8.0 of Pulsar. The sha256 is of the file of the release. The URL is
3225
+ * on the archive of Apache, which keeps each release. The mirror downloads.apache.org keeps only the
3226
+ * latest releases.
3227
+ */
3188
3228
  const PULSAR_CHART = {
3189
3229
  name: "pulsar",
3190
3230
  version: "4.8.0",
3191
- url: "https://downloads.apache.org/pulsar/helm-chart/4.8.0/pulsar-4.8.0.tgz",
3231
+ url: "https://archive.apache.org/dist/pulsar/helm-chart/4.8.0/pulsar-4.8.0.tgz",
3192
3232
  sha256: "464f4a268463d187c9bc83b365b31de0b4a460533d948a04f846ba9b026068f5"
3193
3233
  };
3194
3234
  /**
@@ -4655,6 +4695,48 @@ const learnWindow = (declaration, readiness, propagation, workload) => {
4655
4695
  };
4656
4696
  };
4657
4697
  //#endregion
4698
+ //#region src/quiet.ts
4699
+ /**
4700
+ * These are the terms of the lab. The flat share is the share of SYS-42. The other terms come from the
4701
+ * calibration of SYS-95, over the 9 records of SYS-57, with no foreign container in them:
4702
+ *
4703
+ * - The margin is the 99th percentile of the fall from the settled median of an environment: 4.88
4704
+ * points of 93 samples, rounded up.
4705
+ * - The floor is the lowest settled median of an environment, 48 %, minus the margin.
4706
+ * - The time to settle holds the slowest environment. Its conntrack table was at its plateau at 105 s.
4707
+ */
4708
+ const QUIET_GATE = {
4709
+ flat: .6,
4710
+ margin: .05,
4711
+ floor: .43,
4712
+ settle: 12e4,
4713
+ samples: 3
4714
+ };
4715
+ /**
4716
+ * This function gives the idle share that a run needs. With no baseline, it is the floor: a warm-up
4717
+ * counts for nothing, and its table is not full yet. A cell that is at rest at the flat share or more
4718
+ * keeps the flat share.
4719
+ */
4720
+ const neededIdle = (gate, baseline) => baseline === null ? gate.floor : Math.min(gate.flat, Math.max(gate.floor, baseline - gate.margin));
4721
+ /** This function gives the reason of a sample that the gate refuses. The site reads it back with `NOT_QUIET`. */
4722
+ const quietWhy = (idle, needed, foreign) => `${Math.round(idle * 100)}% idle, the gate needs ${Math.round(needed * 100)}%, other lab containers: ${foreign.join("; ") || "none"}`;
4723
+ /**
4724
+ * This form reads the void of a run that the gate refuses. Its groups are the wait in seconds, the idle share, the share
4725
+ * of the gate and the other lab containers. A record from before SYS-95 has no share of the gate.
4726
+ */
4727
+ const NOT_QUIET = /^the VM was not quiet in (\d+) s: (\d+)% idle(?:, the gate needs (\d+)%)?, other lab containers: (.*)$/;
4728
+ /**
4729
+ * This function gives the next baseline of a cell from the samples of one environment. Samples with
4730
+ * a foreign container do not count. The highest median holds, because a foreign load only lowers
4731
+ * the idle share. Thus a load in one environment does not move the gate of the other one.
4732
+ */
4733
+ const baselineOf = (previous, samples) => {
4734
+ const clean = samples.filter((sample) => sample.foreign.length === 0).map((sample) => sample.idle);
4735
+ if (clean.length === 0) return previous;
4736
+ const middle = median(clean);
4737
+ return previous === null ? middle : Math.max(previous, middle);
4738
+ };
4739
+ //#endregion
4658
4740
  //#region src/rules.ts
4659
4741
  const seconds$1 = (amount) => valueIn(amount, "s");
4660
4742
  const s = (value) => ({
@@ -4923,21 +5005,57 @@ const sample = async (ctx, ours) => {
4923
5005
  * This is below the share of 60%. That wait had no bound, and it took approximately 30 min.
4924
5006
  */
4925
5007
  const QUIET_WITHIN = 3e5;
5008
+ /** This function gives the names of this lab at a sample: the prober and the watcher start again with new names. */
5009
+ const oursAt = (ctx, ours) => /* @__PURE__ */ new Set([
5010
+ ...ours,
5011
+ ...ctx.lab.own(),
5012
+ ctx.loader.getName().replace(/^\//, "")
5013
+ ]);
5014
+ /**
5015
+ * This function takes the baseline of the cell in this environment, once. The first run after the
5016
+ * warm-up calls it. It waits until the cell has its age. The conntrack table fills for the life of
5017
+ * its entries, and the read of the table costs more until then.
5018
+ */
5019
+ const takeBaseline = async (ctx, ours) => {
5020
+ if (ctx.settled) return;
5021
+ await sleep(Math.max(0, ctx.deployed + ctx.gate.settle - Date.now()));
5022
+ const samples = [];
5023
+ for (let index = 0; index < ctx.gate.samples; index += 1) samples.push(await sample(ctx, oursAt(ctx, ours)));
5024
+ ctx.loads.push(...samples);
5025
+ const baseline = baselineOf(ctx.baselines.get(ctx.cell.name) ?? null, samples);
5026
+ if (baseline !== null) ctx.baselines.set(ctx.cell.name, baseline);
5027
+ ctx.settled = true;
5028
+ ctx.log(` baseline: ${samples.map((each) => `${Math.round(each.idle * 100)}%`).join(", ")} idle, the gate needs ${Math.round(neededIdle(ctx.gate, baseline) * 100)}%`);
5029
+ };
5030
+ /** This function starts the planned load of a cell for the longest wait of the gate. The load runs in the loader, out of the cluster. */
5031
+ const startPlannedLoad = async (ctx) => {
5032
+ const cores = ctx.cell.plannedLoad;
5033
+ if (cores === void 0) return;
5034
+ const spec = JSON.stringify({
5035
+ cores,
5036
+ ms: 32e4
5037
+ });
5038
+ await ctx.loader.exec([
5039
+ "sh",
5040
+ "-c",
5041
+ `nohup node agent.mjs burn '${spec}' >/dev/null 2>&1 &`
5042
+ ]);
5043
+ };
4926
5044
  /**
4927
5045
  * This function waits until the VM is quiet: no lab container of another agent, and an idle share of
4928
- * the CPUs. It gives null, or the reason when the VM is not quiet in `within` ms.
5046
+ * the CPUs (`neededIdle`). It gives null, or the reason when the VM is not quiet in `within` ms.
4929
5047
  */
4930
5048
  const quiet = async (ctx, ours, within = QUIET_WITHIN) => {
4931
5049
  const end = Date.now() + within;
5050
+ const needed = neededIdle(ctx.gate, ctx.baselines.get(ctx.cell.name) ?? null);
4932
5051
  for (;;) {
4933
- const load = await sample(ctx, /* @__PURE__ */ new Set([
4934
- ...ours,
4935
- ...ctx.lab.own(),
4936
- ctx.loader.getName().replace(/^\//, "")
4937
- ]));
4938
- ctx.loads.push(load);
4939
- if (load.foreign.length === 0 && load.idle >= ctx.idle) return null;
4940
- const why = `${Math.round(load.idle * 100)}% idle, other lab containers: ${load.foreign.join("; ") || "none"}`;
5052
+ const load = await sample(ctx, oursAt(ctx, ours));
5053
+ ctx.loads.push({
5054
+ ...load,
5055
+ needed
5056
+ });
5057
+ if (load.foreign.length === 0 && load.idle >= needed) return null;
5058
+ const why = quietWhy(load.idle, needed, load.foreign);
4941
5059
  if (Date.now() >= end) return `the VM was not quiet in ${within / 1e3} s: ${why}`;
4942
5060
  ctx.log(` waiting: ${why}`);
4943
5061
  await sleep(3e4);
@@ -5245,13 +5363,19 @@ const namespacesOf = async (ctx, target, replicas) => {
5245
5363
  */
5246
5364
  const middleboxServers = async (ctx, idle, port, replicas) => {
5247
5365
  const peers = [...ctx.tracker.pods.values()].filter((pod) => pod.labels["app"] === "client" && !pod.del && pod.ip !== null).map((pod) => pod.ip).sort();
5248
- const commands = middleboxCommands(peers, idle, port);
5366
+ const commands = idle === null ? null : middleboxCommands(peers, idle, port);
5249
5367
  const t0 = await ctx.lab.now();
5250
5368
  const each = await namespacesOf(ctx, "servers", replicas);
5251
5369
  await Promise.all(each.map(async ({ node, pid }) => {
5252
- if (idle === null) await ctx.lab.tables(node, pid, "filter");
5253
- await ctx.lab.netns(node, pid, commands);
5254
- if (idle !== null) await ctx.lab.tables(node, pid, "filter");
5370
+ if (commands !== null) {
5371
+ await ctx.lab.netns(node, pid, commands);
5372
+ await ctx.lab.tables(node, pid, "filter");
5373
+ return;
5374
+ }
5375
+ const removal = middleboxRemoval(await ctx.lab.tables(node, pid, "filter"));
5376
+ if (removal.length > 0) await ctx.lab.netns(node, pid, removal);
5377
+ const left = middleboxRemoval(await ctx.lab.tables(node, pid, "filter"));
5378
+ if (left.length > 0) throw new Error(`the middlebox on ${node} (PID ${pid}) has ${left.length} parts after its removal`);
5255
5379
  }));
5256
5380
  return {
5257
5381
  t0,
@@ -5574,6 +5698,10 @@ const runOnce = async (ctx, env, index, warmup, ours) => {
5574
5698
  if (atRest !== null) return empty(`the cell was not at rest: ${atRest}`, await lab.now());
5575
5699
  await probeThePods(ctx);
5576
5700
  await pollListeners(ctx);
5701
+ if (!warmup) {
5702
+ await takeBaseline(ctx, ours);
5703
+ await startPlannedLoad(ctx);
5704
+ }
5577
5705
  const loud = await quiet(ctx, ours);
5578
5706
  if (loud !== null) {
5579
5707
  ctx.log(` ${loud}`);
@@ -5857,6 +5985,7 @@ const runKindCells = async (cells, options) => {
5857
5985
  const groups = /* @__PURE__ */ new Map();
5858
5986
  for (const cell of cells) groups.set(clusterKey(cell), [...groups.get(clusterKey(cell)) ?? [], cell]);
5859
5987
  const results = [];
5988
+ const baselines = /* @__PURE__ */ new Map();
5860
5989
  for (const group of groups.values()) {
5861
5990
  const partial = /* @__PURE__ */ new Map();
5862
5991
  for (let env = 0; env < environments; env += 1) {
@@ -5943,7 +6072,13 @@ const runKindCells = async (cells, options) => {
5943
6072
  vip: cell.vip === void 0 ? null : vip,
5944
6073
  loads,
5945
6074
  loader,
5946
- idle: options.idle ?? .6,
6075
+ gate: {
6076
+ ...QUIET_GATE,
6077
+ flat: options.idle ?? QUIET_GATE.flat
6078
+ },
6079
+ baselines,
6080
+ deployed: Date.now(),
6081
+ settled: false,
5947
6082
  log: options.log,
5948
6083
  version: 1,
5949
6084
  probed: "",
@@ -6082,6 +6217,6 @@ const shardOf = (cells, index, count) => {
6082
6217
  return out;
6083
6218
  };
6084
6219
  //#endregion
6085
- export { ACCESS_LOG_FORMAT, ANNOUNCE_ANNOTATION, CHANNEL_USE, CILIUM_CHART, CILIUM_CONFIG_KEYS, CILIUM_IMAGES, CILIUM_VERSION, CILIUM_WORKLOADS, CLIENT, CLIENT_ACCOUNT, CLOSE_LEAD, CONTROLLER, DATAPLANES, DNS_PORT, DOCUMENTED, DRAIN_RULES, EDS_EVERY, FLAG_CHECK, FORMAT, FORMAT_V1, HBONE_PORT, HEALTH_PORT, HELM, ISTIOCTL, ISTIO_IMAGES, ISTIO_VERSION, KEPT_KERNEL, KIND, KIND_NOISE, KUBECTL, KUBE_PROXY_MODES, KUBE_VIP, KUBE_VIP_ANNOUNCER, KUBE_VIP_ARP_RATE, KUBE_VIP_ELECTION, KUBE_VIP_IMAGE, KUBE_VIP_LEASE, KUBE_VIP_VERSION, LAST_SLACK, LB_CLASS, LDS_EVERY, LDS_FILTER, LOG_LABEL, MEMBERLIST, MEMBERLIST_FILE, MESH_IMAGES, MESH_WORKLOADS, METALLB_ANNOTATION, METALLB_ANNOUNCER, METALLB_CHART, METALLB_IMAGES, METALLB_NAMESPACE, METALLB_POOL, METALLB_SPAM, METALLB_VERSION, MIDDLEBOX, NETEM_DRAIN, NETNS_DEFAULTS, NODE_IMAGES, NODE_LIFECYCLE, O04, O09, O10, O16, OUTSIDE, PING, POD_LINK, POLICY, PORT, PRODUCER, PRODUCER_BACKOFF, PRODUCER_SCRIPT, PULSAR_CHART, PULSAR_IMAGE, PULSAR_LOOKUP, PULSAR_NAMESPACE, PULSAR_SERVICE, PULSAR_TOPIC, PULSAR_VERSION, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, SESSION, SPREAD_LEAD, STAGES, SYSCTL, TCP_STATE, TICK, VIP_ANNOTATION, VIP_LABEL, WATCHDOG, ZONE_KEPT, ZONE_LABEL, ZONE_LOST, ZTUNNEL_PODS, announcementsOf, announcerOf, arpMacOf, backendsAt, backendsOf, backlogEnd, bandOf, brokerOfHost, brokersOf, byClients, byNode, cacheFolder, calibrationOf, capOf, cellsTable, certificateArgs, checkRun, cidrOverlap, cidrRange, ciliumBackendsOf, ciliumMode, ciliumValues, clientObjects, clusterFilter, clusterNameOf, compose, createCluster, cyclesOf, deletes, deletionOf, deletionWindow, deletionsOf, describeCell, dnsCommands, drainBand, dropOf, emptyOf, ensureChart, ensurePinnedChart, ensureTool, estimatedTime, factsOf, failuresOf, faultSpan, followsZtunnel, goDuration, helmInstall, holdMetallb, holdPulsar, holdVip, hostsOf, installCilium, installKubeVip, installMesh, installMetallb, installPulsar, intakeAfter, intakeOf, isKubeProxyMode, isTunnelState, istioOperator, judge, judgeKind, judgeReconnects, keptKernel, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, kubeVipObjects, kubeVipPods, kubeVipReady, kubeletBand, labImage, labSource, latchBand, latestReturn, leafCertificates, learnWindow, lintCell, listenerCountsOf, localPin, macsAt, medianInterval, medianText, memberlistFileOf, memberlistTermsOf, meshKey, metallbObjects, metallbRecord, metallbValues, metallbVipOf, middle, middleboxCommands, namesService, namespaceObject, namespaceOf, nodeLossBand, nodeNames, nodeReturnBand, observationAfter, observationEnd, openKindLab, outboundCluster, outcomesOf, overshootBand, ownerAtRest, ownerOrder, pausedWindow, periodOf, placementOf, planOf, platformKey, podsAt, podsOf, policyObject, pollsListeners, predictionText, probeOf, propagationOf, propagationSource, pulsarObjects, pulsarRecord, pulsarValues, quantileOf, readRecord, recordsOf, redisObjects, referenceOf, removalBand, requestBand, requestsOf, restartBand, restartOf, restartsAt, reusesReset, rulesOf, runKindCells, scenario, scenarioOf, scenarioProblems, seconds, secondsOf, serverCluster, serverObjects, sessionsAt, setZtunnelEnv, sha256, shardOf, sharedGate, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, speakersReady, stackOf, stageLabImage, stallRemovalBand, stopOf, stoppingOf, suspicionOf, sysctlCommand, tarEntry, timeSpread, toolPath, transitionOf, triesOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, verdictsOf, vipLeaseOf, vipNetworkOf, vipOf, vipServed, vipService, writeResult, zoneOf, ztunnelCertificates, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
6220
+ export { ACCESS_LOG_FORMAT, ANNOUNCE_ANNOTATION, CHANNEL_USE, CILIUM_CHART, CILIUM_CONFIG_KEYS, CILIUM_IMAGES, CILIUM_VERSION, CILIUM_WORKLOADS, CLIENT, CLIENT_ACCOUNT, CLOSE_LEAD, CONTROLLER, DATAPLANES, DNS_PORT, DOCUMENTED, DRAIN_RULES, EDS_EVERY, FLAG_CHECK, FORMAT, FORMAT_V1, HBONE_PORT, HEALTH_PORT, HELM, ISTIOCTL, ISTIO_IMAGES, ISTIO_VERSION, KEPT_KERNEL, KIND, KIND_NOISE, KUBECTL, KUBE_PROXY_MODES, KUBE_VIP, KUBE_VIP_ANNOUNCER, KUBE_VIP_ARP_RATE, KUBE_VIP_ELECTION, KUBE_VIP_IMAGE, KUBE_VIP_LEASE, KUBE_VIP_VERSION, LAST_SLACK, LB_CLASS, LDS_EVERY, LDS_FILTER, LOG_LABEL, MEMBERLIST, MEMBERLIST_FILE, MESH_IMAGES, MESH_WORKLOADS, METALLB_ANNOTATION, METALLB_ANNOUNCER, METALLB_CHART, METALLB_IMAGES, METALLB_NAMESPACE, METALLB_POOL, METALLB_SPAM, METALLB_VERSION, MIDDLEBOX, NETEM_DRAIN, NETNS_DEFAULTS, NODE_IMAGES, NODE_LIFECYCLE, NOT_QUIET, O04, O09, O10, O16, OUTSIDE, PING, POD_LINK, POLICY, PORT, PRODUCER, PRODUCER_BACKOFF, PRODUCER_SCRIPT, PULSAR_CHART, PULSAR_IMAGE, PULSAR_LOOKUP, PULSAR_NAMESPACE, PULSAR_SERVICE, PULSAR_TOPIC, PULSAR_VERSION, QUIET_GATE, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, SESSION, SPREAD_LEAD, STAGES, SYSCTL, TCP_STATE, TICK, VIP_ANNOTATION, VIP_LABEL, WATCHDOG, ZONE_KEPT, ZONE_LABEL, ZONE_LOST, ZTUNNEL_PODS, announcementsOf, announcerOf, arpMacOf, backendsAt, backendsOf, backlogEnd, bandOf, baselineOf, brokerOfHost, brokersOf, byClients, byNode, cacheFolder, calibrationOf, capOf, cellsTable, certificateArgs, checkRun, cidrOverlap, cidrRange, ciliumBackendsOf, ciliumMode, ciliumValues, clientObjects, clusterFilter, clusterNameOf, compose, createCluster, cyclesOf, deletes, deletionOf, deletionWindow, deletionsOf, describeCell, dnsCommands, drainBand, dropOf, emptyOf, ensureChart, ensurePinnedChart, ensureTool, estimatedTime, factsOf, failuresOf, faultSpan, followsZtunnel, goDuration, helmInstall, holdMetallb, holdPulsar, holdVip, hostsOf, installCilium, installKubeVip, installMesh, installMetallb, installPulsar, intakeAfter, intakeOf, isKubeProxyMode, isTunnelState, istioOperator, judge, judgeKind, judgeReconnects, keptKernel, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, kubeVipObjects, kubeVipPods, kubeVipReady, kubeletBand, labImage, labSource, latchBand, latestReturn, leafCertificates, learnWindow, lintCell, listenerCountsOf, localPin, macsAt, medianInterval, medianText, memberlistFileOf, memberlistTermsOf, meshKey, metallbObjects, metallbRecord, metallbValues, metallbVipOf, middle, middleboxCommands, middleboxRemoval, namesService, namespaceObject, namespaceOf, neededIdle, nodeLossBand, nodeNames, nodeReturnBand, observationAfter, observationEnd, openKindLab, outboundCluster, outcomesOf, overshootBand, ownerAtRest, ownerOrder, pausedWindow, periodOf, placementOf, planOf, platformKey, podsAt, podsOf, policyObject, pollsListeners, predictionText, probeOf, propagationOf, propagationSource, pulsarObjects, pulsarRecord, pulsarValues, quantileOf, quietWhy, readRecord, recordsOf, redisObjects, referenceOf, removalBand, requestBand, requestsOf, restartBand, restartOf, restartsAt, reusesReset, rulesOf, runKindCells, scenario, scenarioOf, scenarioProblems, seconds, secondsOf, serverCluster, serverObjects, sessionsAt, setZtunnelEnv, sha256, shardOf, sharedGate, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, speakersReady, stackOf, stageLabImage, stallRemovalBand, stopOf, stoppingOf, suspicionOf, sysctlCommand, tarEntry, timeSpread, toolPath, transitionOf, triesOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, verdictsOf, vipLeaseOf, vipNetworkOf, vipOf, vipServed, vipService, writeResult, zoneOf, ztunnelCertificates, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
6086
6221
 
6087
6222
  //# sourceMappingURL=index.js.map