@mark1russell7/kind 0.13.1 → 0.13.3

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.
@@ -538,6 +538,32 @@ interface WindowPrediction<A = Quantity> {
538
538
  * window has no such term, and the judge does not count the failed requests.
539
539
  */
540
540
  readonly backlog?: BacklogTerm<A> | undefined;
541
+ /**
542
+ * This window permits failures, but no failure is necessary in it (`PermittedWindow`). The judge does not
543
+ * count a failure in it, if the failure is outside the window of the prediction and has an outcome
544
+ * of `outcomes`. Without it, each failure outside the window fails the run.
545
+ */
546
+ readonly permits?: PermittedWindow<A> | undefined;
547
+ readonly why: string;
548
+ }
549
+ /**
550
+ * A permitted window is a second window of a prediction (SYS-51). Failures can come in it, but they
551
+ * need not come. It starts `band.lo` after its reference and ends `band.hi` after it, with δ on each side.
552
+ * For example, the old holder of a VIP can send one gratuitous ARP at the heal of a lost zone. It
553
+ * sends it before it sees the loss of its lease. Each client then moves to the old node for up to one
554
+ * ARP interval.
555
+ */
556
+ interface PermittedWindow<A = Quantity> {
557
+ readonly from: Reference;
558
+ readonly band: Band<A>;
559
+ /** These outcomes are the only failures that the window permits. */
560
+ readonly outcomes: readonly string[];
561
+ /**
562
+ * This time is the least observation after the reference (SYS-53). The record runs at least this
563
+ * long after it. Thus a failure that comes later than the band still shows, and fails the run.
564
+ * Without it, the record ends a timeout after the band.
565
+ */
566
+ readonly watch?: A | undefined;
541
567
  readonly why: string;
542
568
  }
543
569
  /**
@@ -653,6 +679,21 @@ interface KindCell<A = Quantity> {
653
679
  /** This flag marks a calibration: its runs measure the propagation of the endpoints, and nothing fails. */
654
680
  readonly calibrates: boolean;
655
681
  readonly runs: number;
682
+ /**
683
+ * This VIP is a Service of type LoadBalancer with an address of kube-vip in ARP mode (SYS-51) or of MetalLB in L2 mode (SYS-53). With
684
+ * it, `clients` more clients run outside the cluster, on the Docker network of the nodes, and send
685
+ * each request to the VIP. Without it, the cell has no VIP.
686
+ */
687
+ readonly vip?: VipSettings | undefined;
688
+ }
689
+ /** This name is an announcer of a VIP: kube-vip in ARP mode (SYS-51), or MetalLB in L2 mode (SYS-53). */
690
+ type VipAnnouncerName = "kube-vip" | "metallb";
691
+ /** These are the settings of the VIP of a cell (`KindCell.vip`). */
692
+ interface VipSettings {
693
+ /** This count is the clients outside the cluster. Each one is a container on the Docker network of the nodes. */
694
+ readonly clients: number;
695
+ /** This name is the announcer of the VIP (`announcer.ts`). Without it, the announcer is kube-vip. */
696
+ readonly announcer?: VipAnnouncerName | undefined;
656
697
  }
657
698
  //#endregion
658
699
  //#region src/bands.d.ts
@@ -717,6 +758,12 @@ declare const LOG_LABEL = "lab.systems/log";
717
758
  declare const SERVER = "lab";
718
759
  declare const CLIENT = "client";
719
760
  declare const REDIS = "redis";
761
+ /** This class of a Service of type LoadBalancer selects kube-vip (pkg/kubevip/constants.go of v1.3.1). */
762
+ declare const LB_CLASS = "kube-vip.io/kube-vip-class";
763
+ /** This annotation of a Service gives kube-vip the address of its VIP (pkg/kubevip/annotations.go of v1.3.1). */
764
+ declare const VIP_ANNOTATION = "kube-vip.io/loadbalancerIPs";
765
+ /** This is the name of the node of each client outside the cluster, in its lines (`KindCell.vip`). */
766
+ declare const OUTSIDE = "outside";
720
767
  //#endregion
721
768
  //#region src/observe.d.ts
722
769
  /**
@@ -1165,7 +1212,8 @@ declare const observationAfter: (cell: Pick<KindCell, "prediction" | "workload">
1165
1212
  * for a stalled connect. It fails only at its timeout (kind run 40128267098). A reference that is not
1166
1213
  * in the lines yet does not count.
1167
1214
  *
1168
- * The band of `ends` also sets an end: its reference, the end of the band and δ.
1215
+ * The band of `ends` also sets an end: its reference, the end of the band and δ. A permitted window
1216
+ * sets an end too: its reference, the end of its band, the timeout of the workload and δ.
1169
1217
  */
1170
1218
  declare const observationEnd: (cell: KindCell, run: Pick<KindRun, "start" | "acts" | "target" | "replicas" | "lines">) => number | null;
1171
1219
  /** This function gives the facts of a run that each table reads: its failures by outcome and node, and the times of its target. */
@@ -1342,5 +1390,5 @@ declare const quantileOf: (sorted: readonly number[], p: number) => number;
1342
1390
  */
1343
1391
  declare const medianInterval: (sorted: readonly number[]) => [number, number];
1344
1392
  //#endregion
1345
- export { unitOf as $, scenario as $n, REDIS as $t, TriggerV1 as A, Template as An, recordsOf as At, RunCheck as B, KubeProxyMode as Bn, sliceReadyAt as Bt, KindCellResult as C, PodSettings as Cn, intakeOf as Ct, PredictionV1 as D, Replica as Dn, periodOf as Dt, LoadSample as E, Reference as En, outcomesOf as Et, KIND_NOISE as F, DATAPLANES as Fn, sessionsAt as Ft, factsOf as G, ZONE_LOST as Gn, transitionOf as Gt, checkRun as H, NodeImage as Hn, slicesOf as Ht, KindDecision as I, Dataplane as In, signalOf as It, observationEnd as J, goDuration as Jn, ztunnelReplaced as Jt, judgeKind as K, cidrOverlap as Kn, tunnelsOf as Kt, KindVerdict as L, KUBE_PROXY_MODES as Ln, signalsOf as Lt, upgrade as M, TriggerKind as Mn, restartOf as Mt, upgradeCell as N, WindowPrediction as Nn, restartsAt as Nt, RunCheckV1 as O, ResetReuse as On, podsAt as Ot, Deleted as P, Workload as Pn, rulesOf as Pt, reusesReset as Q, nodeNames as Qn, PORT as Qt, LAST_SLACK as R, KindConfig as Rn, sliceDropOf as Rt, KindCellRecordV1 as S, NonePrediction as Sn, failuresOf as St, KindVerdictV1 as T, RedisDeclaration as Tn, kernelCounts as Tt, cyclesOf as U, ZONE_KEPT as Un, socketsOf as Ut, RunFacts as V, NODE_IMAGES as Vn, sliceReadyOf as Vt, deletionsOf as W, ZONE_LABEL as Wn, stoppingOf as Wt, propagationSource as X, kindConfig as Xn, HEALTH_PORT as Xt, propagationOf as Y, isKubeProxyMode as Yn, CLIENT as Yt, referenceOf as Z, kubeProxyPatch as Zn, LOG_LABEL as Zt, ClusterManifest as _, KindRun as _n, byClients as _t, STAGES as a, overshootBand as an, PodLine as at, FORMAT_V1 as b, MeshFlavor as bn, dropOf as bt, readRecord as c, secondsOf as cn, Request as ct, calibrationOf as d, Band as dn, SliceLine as dt, SERVER as en, scenarioProblems as er, updatesOf as et, cellsTable as f, Cycle as fn, SocketLine as ft, BandV1 as g, KindCell as gn, backendsAt as gt, timeSpread as h, Flap as hn, ZtunnelPodLine as ht, quantileOf as i, drainBand as in, Period as it, judge as j, Trigger as jn, requestsOf as jt, RunFactsV1 as k, Stack as kn, podsOf as kt, Judged as l, showBand as ln, RulesLine as lt, predictionText as m, EdgeProtocol as mn, TunnelLine as mt, medianInterval as n, backlogEnd as nn, HBONE_PORT as nt, kindCellRecordSchema as o, requestBand as on, PropagationSource as ot, medianText as p, Declaration as pn, TCP_STATE as pt, observationAfter as q, cidrRange as qn, ztunnelPodsOf as qt, middle as r, bandOf as rn, Line as rt, kindCellRecordV1Schema as s, seconds as sn, RecordLine as st, RELATIVE as t, CountBand as tn, zoneOf as tr, Endpoint as tt, TimeSpread as u, BacklogTerm as un, Sessions as ut, EnvironmentManifest as v, KubeletProbe as vn, byNode as vt, KindCellV1 as w, Prediction as wn, isTunnelState as wt, KindCellRecord as x, MeshMode as xn, emptyOf as xt, FORMAT as y, Mesh as yn, deletionOf as yt, Propagated as z, KindScenario as zn, sliceEmptyOf as zt };
1346
- //# sourceMappingURL=judge-CSWVew2-.d.ts.map
1393
+ export { unitOf as $, cidrRange as $n, OUTSIDE as $t, TriggerV1 as A, Reference as An, recordsOf as At, RunCheck as B, Workload as Bn, sliceReadyAt as Bt, KindCellResult as C, MeshFlavor as Cn, intakeOf as Ct, PredictionV1 as D, PodSettings as Dn, periodOf as Dt, LoadSample as E, PermittedWindow as En, outcomesOf as Et, KIND_NOISE as F, Trigger as Fn, sessionsAt as Ft, factsOf as G, KindScenario as Gn, transitionOf as Gt, checkRun as H, Dataplane as Hn, slicesOf as Ht, KindDecision as I, TriggerKind as In, signalOf as It, observationEnd as J, NodeImage as Jn, ztunnelReplaced as Jt, judgeKind as K, KubeProxyMode as Kn, tunnelsOf as Kt, KindVerdict as L, VipAnnouncerName as Ln, signalsOf as Lt, upgrade as M, ResetReuse as Mn, restartOf as Mt, upgradeCell as N, Stack as Nn, restartsAt as Nt, RunCheckV1 as O, Prediction as On, podsAt as Ot, Deleted as P, Template as Pn, rulesOf as Pt, reusesReset as Q, cidrOverlap as Qn, LOG_LABEL as Qt, LAST_SLACK as R, VipSettings as Rn, sliceDropOf as Rt, KindCellRecordV1 as S, Mesh as Sn, failuresOf as St, KindVerdictV1 as T, NonePrediction as Tn, kernelCounts as Tt, cyclesOf as U, KUBE_PROXY_MODES as Un, socketsOf as Ut, RunFacts as V, DATAPLANES as Vn, sliceReadyOf as Vt, deletionsOf as W, KindConfig as Wn, stoppingOf as Wt, propagationSource as X, ZONE_LABEL as Xn, HEALTH_PORT as Xt, propagationOf as Y, ZONE_KEPT as Yn, CLIENT as Yt, referenceOf as Z, ZONE_LOST as Zn, LB_CLASS as Zt, ClusterManifest as _, EdgeProtocol as _n, byClients as _t, STAGES as a, backlogEnd as an, scenario as ar, PodLine as at, FORMAT_V1 as b, KindRun as bn, dropOf as bt, readRecord as c, overshootBand as cn, Request as ct, calibrationOf as d, secondsOf as dn, SliceLine as dt, PORT as en, goDuration as er, updatesOf as et, cellsTable as f, showBand as fn, SocketLine as ft, BandV1 as g, Declaration as gn, backendsAt as gt, timeSpread as h, Cycle as hn, ZtunnelPodLine as ht, quantileOf as i, CountBand as in, nodeNames as ir, Period as it, judge as j, Replica as jn, requestsOf as jt, RunFactsV1 as k, RedisDeclaration as kn, podsOf as kt, Judged as l, requestBand as ln, RulesLine as lt, predictionText as m, Band as mn, TunnelLine as mt, medianInterval as n, SERVER as nn, kindConfig as nr, HBONE_PORT as nt, kindCellRecordSchema as o, bandOf as on, scenarioProblems as or, PropagationSource as ot, medianText as p, BacklogTerm as pn, TCP_STATE as pt, observationAfter as q, NODE_IMAGES as qn, ztunnelPodsOf as qt, middle as r, VIP_ANNOTATION as rn, kubeProxyPatch as rr, Line as rt, kindCellRecordV1Schema as s, drainBand as sn, zoneOf as sr, RecordLine as st, RELATIVE as t, REDIS as tn, isKubeProxyMode as tr, Endpoint as tt, TimeSpread as u, seconds as un, Sessions as ut, EnvironmentManifest as v, Flap as vn, byNode as vt, KindCellV1 as w, MeshMode as wn, isTunnelState as wt, KindCellRecord as x, KubeletProbe as xn, emptyOf as xt, FORMAT as y, KindCell as yn, deletionOf as yt, Propagated as z, WindowPrediction as zn, sliceEmptyOf as zt };
1394
+ //# sourceMappingURL=judge-DhLShDUj.d.ts.map
package/build/judge.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as unitOf, $t as REDIS, A as TriggerV1, An as Template, At as recordsOf, B as RunCheck, Bn as KubeProxyMode, Bt as sliceReadyAt, C as KindCellResult, Cn as PodSettings, Ct as intakeOf, D as PredictionV1, Dn as Replica, Dt as periodOf, E as LoadSample, En as Reference, Et as outcomesOf, F as KIND_NOISE, Ft as sessionsAt, G as factsOf, Gt as transitionOf, H as checkRun, Ht as slicesOf, I as KindDecision, In as Dataplane, It as signalOf, J as observationEnd, Jt as ztunnelReplaced, K as judgeKind, Kt as tunnelsOf, L as KindVerdict, Lt as signalsOf, M as upgrade, Mn as TriggerKind, Mt as restartOf, N as upgradeCell, Nn as WindowPrediction, Nt as restartsAt, O as RunCheckV1, On as ResetReuse, Ot as podsAt, P as Deleted, Pn as Workload, Pt as rulesOf, Q as reusesReset, Qt as PORT, R as LAST_SLACK, Rt as sliceDropOf, S as KindCellRecordV1, Sn as NonePrediction, St as failuresOf, T as KindVerdictV1, Tn as RedisDeclaration, Tt as kernelCounts, U as cyclesOf, Ut as socketsOf, V as RunFacts, Vt as sliceReadyOf, W as deletionsOf, Wt as stoppingOf, X as propagationSource, Xt as HEALTH_PORT, Y as propagationOf, Yt as CLIENT, Z as referenceOf, Zt as LOG_LABEL, _ as ClusterManifest, _n as KindRun, _t as byClients, a as STAGES, an as overshootBand, at as PodLine, b as FORMAT_V1, bn as MeshFlavor, bt as dropOf, c as readRecord, cn as secondsOf, ct as Request, d as calibrationOf, dn as Band, dt as SliceLine, en as SERVER, et as updatesOf, f as cellsTable, fn as Cycle, ft as SocketLine, g as BandV1, gn as KindCell, gt as backendsAt, h as timeSpread, hn as Flap, ht as ZtunnelPodLine, i as quantileOf, in as drainBand, it as Period, j as judge, jn as Trigger, jt as requestsOf, k as RunFactsV1, kn as Stack, kt as podsOf, l as Judged, ln as showBand, lt as RulesLine, m as predictionText, mn as EdgeProtocol, mt as TunnelLine, n as medianInterval, nn as backlogEnd, nt as HBONE_PORT, o as kindCellRecordSchema, on as requestBand, ot as PropagationSource, p as medianText, pn as Declaration, pt as TCP_STATE, q as observationAfter, qt as ztunnelPodsOf, r as middle, rn as bandOf, rt as Line, s as kindCellRecordV1Schema, sn as seconds, st as RecordLine, t as RELATIVE, tn as CountBand, tt as Endpoint, u as TimeSpread, un as BacklogTerm, ut as Sessions, v as EnvironmentManifest, vn as KubeletProbe, vt as byNode, w as KindCellV1, wn as Prediction, wt as isTunnelState, x as KindCellRecord, xn as MeshMode, xt as emptyOf, y as FORMAT, yn as Mesh, yt as deletionOf, z as Propagated, zt as sliceEmptyOf } from "./judge-CSWVew2-.js";
2
- export { type BacklogTerm, type Band, type BandV1, CLIENT, type ClusterManifest, type CountBand, type Cycle, type Dataplane, type Declaration, type Deleted, type EdgeProtocol, Endpoint, type EnvironmentManifest, FORMAT, FORMAT_V1, type Flap, HBONE_PORT, HEALTH_PORT, type Judged, KIND_NOISE, type KindCell, type KindCellRecord, type KindCellRecordV1, type KindCellResult, type KindCellV1, type KindDecision, type KindRun, type KindVerdict, type KindVerdictV1, type KubeProxyMode, type KubeletProbe, LAST_SLACK, LOG_LABEL, Line, type LoadSample, type Mesh, type MeshFlavor, type MeshMode, type NonePrediction, PORT, Period, PodLine, type PodSettings, type Prediction, type PredictionV1, type Propagated, PropagationSource, REDIS, RELATIVE, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, SERVER, STAGES, Sessions, SliceLine, SocketLine, type Stack, TCP_STATE, type Template, type TimeSpread, type Trigger, type TriggerKind, type TriggerV1, TunnelLine, type WindowPrediction, type Workload, ZtunnelPodLine, backendsAt, backlogEnd, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cyclesOf, deletionOf, deletionsOf, drainBand, dropOf, emptyOf, factsOf, failuresOf, intakeOf, isTunnelState, judge, judgeKind, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, medianInterval, medianText, middle, observationAfter, observationEnd, outcomesOf, overshootBand, periodOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestBand, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, seconds, secondsOf, sessionsAt, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, ztunnelPodsOf, ztunnelReplaced };
1
+ import { $ as unitOf, $t as OUTSIDE, A as TriggerV1, An as Reference, At as recordsOf, B as RunCheck, Bn as Workload, Bt as sliceReadyAt, C as KindCellResult, Cn as MeshFlavor, Ct as intakeOf, D as PredictionV1, Dn as PodSettings, Dt as periodOf, E as LoadSample, En as PermittedWindow, Et as outcomesOf, F as KIND_NOISE, Fn as Trigger, Ft as sessionsAt, G as factsOf, Gt as transitionOf, H as checkRun, Hn as Dataplane, Ht as slicesOf, I as KindDecision, In as TriggerKind, It as signalOf, J as observationEnd, Jt as ztunnelReplaced, K as judgeKind, Kn as KubeProxyMode, Kt as tunnelsOf, L as KindVerdict, Ln as VipAnnouncerName, Lt as signalsOf, M as upgrade, Mn as ResetReuse, Mt as restartOf, N as upgradeCell, Nn as Stack, Nt as restartsAt, O as RunCheckV1, On as Prediction, Ot as podsAt, P as Deleted, Pn as Template, Pt as rulesOf, Q as reusesReset, Qt as LOG_LABEL, R as LAST_SLACK, Rn as VipSettings, Rt as sliceDropOf, S as KindCellRecordV1, Sn as Mesh, St as failuresOf, T as KindVerdictV1, Tn as NonePrediction, Tt as kernelCounts, U as cyclesOf, Ut as socketsOf, V as RunFacts, Vt as sliceReadyOf, W as deletionsOf, Wt as stoppingOf, X as propagationSource, Xt as HEALTH_PORT, Y as propagationOf, Yt as CLIENT, Z as referenceOf, Zt as LB_CLASS, _ as ClusterManifest, _n as EdgeProtocol, _t as byClients, a as STAGES, an as backlogEnd, at as PodLine, b as FORMAT_V1, bn as KindRun, bt as dropOf, c as readRecord, cn as overshootBand, ct as Request, d as calibrationOf, dn as secondsOf, dt as SliceLine, en as PORT, et as updatesOf, f as cellsTable, fn as showBand, ft as SocketLine, g as BandV1, gn as Declaration, gt as backendsAt, h as timeSpread, hn as Cycle, ht as ZtunnelPodLine, i as quantileOf, in as CountBand, it as Period, j as judge, jn as Replica, jt as requestsOf, k as RunFactsV1, kn as RedisDeclaration, kt as podsOf, l as Judged, ln as requestBand, lt as RulesLine, m as predictionText, mn as Band, mt as TunnelLine, n as medianInterval, nn as SERVER, nt as HBONE_PORT, o as kindCellRecordSchema, on as bandOf, ot as PropagationSource, p as medianText, pn as BacklogTerm, pt as TCP_STATE, q as observationAfter, qt as ztunnelPodsOf, r as middle, rn as VIP_ANNOTATION, rt as Line, s as kindCellRecordV1Schema, sn as drainBand, st as RecordLine, t as RELATIVE, tn as REDIS, tt as Endpoint, u as TimeSpread, un as seconds, ut as Sessions, v as EnvironmentManifest, vn as Flap, vt as byNode, w as KindCellV1, wn as MeshMode, wt as isTunnelState, x as KindCellRecord, xn as KubeletProbe, xt as emptyOf, y as FORMAT, yn as KindCell, yt as deletionOf, z as Propagated, zn as WindowPrediction, zt as sliceEmptyOf } from "./judge-DhLShDUj.js";
2
+ export { type BacklogTerm, type Band, type BandV1, CLIENT, type ClusterManifest, type CountBand, type Cycle, type Dataplane, type Declaration, type Deleted, type EdgeProtocol, Endpoint, type EnvironmentManifest, FORMAT, FORMAT_V1, type Flap, HBONE_PORT, HEALTH_PORT, type Judged, KIND_NOISE, type KindCell, type KindCellRecord, type KindCellRecordV1, type KindCellResult, type KindCellV1, type KindDecision, type KindRun, type KindVerdict, type KindVerdictV1, type KubeProxyMode, type KubeletProbe, LAST_SLACK, LB_CLASS, LOG_LABEL, Line, type LoadSample, type Mesh, type MeshFlavor, type MeshMode, type NonePrediction, OUTSIDE, PORT, Period, type PermittedWindow, PodLine, type PodSettings, type Prediction, type PredictionV1, type Propagated, PropagationSource, REDIS, RELATIVE, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, SERVER, STAGES, Sessions, SliceLine, SocketLine, type Stack, TCP_STATE, type Template, type TimeSpread, type Trigger, type TriggerKind, type TriggerV1, TunnelLine, VIP_ANNOTATION, type VipAnnouncerName, type VipSettings, type WindowPrediction, type Workload, ZtunnelPodLine, backendsAt, backlogEnd, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cyclesOf, deletionOf, deletionsOf, drainBand, dropOf, emptyOf, factsOf, failuresOf, intakeOf, isTunnelState, judge, judgeKind, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, medianInterval, medianText, middle, observationAfter, observationEnd, outcomesOf, overshootBand, periodOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestBand, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, seconds, secondsOf, sessionsAt, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, sliceReadyAt, sliceReadyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, ztunnelPodsOf, ztunnelReplaced };
package/build/judge.js CHANGED
@@ -1 +1 @@
1
- export { ht as CLIENT, u as FORMAT, d as FORMAT_V1, A as HBONE_PORT, gt as HEALTH_PORT, h as KIND_NOISE, g as LAST_SLACK, _t as LOG_LABEL, vt as PORT, yt as REDIS, dt as RELATIVE, bt as SERVER, t as STAGES, j as TCP_STATE, M as backendsAt, xt as backlogEnd, St as bandOf, N as byClients, P as byNode, a as calibrationOf, o as cellsTable, _ as checkRun, v as cyclesOf, F as deletionOf, y as deletionsOf, Ct as drainBand, I as dropOf, L as emptyOf, b as factsOf, R as failuresOf, z as intakeOf, B as isTunnelState, f as judge, x as judgeKind, V as kernelCounts, n as kindCellRecordSchema, r as kindCellRecordV1Schema, ft as medianInterval, s as medianText, pt as middle, S as observationAfter, C as observationEnd, H as outcomesOf, wt as overshootBand, U as periodOf, W as podsAt, G as podsOf, c as predictionText, w as propagationOf, T as propagationSource, mt as quantileOf, i as readRecord, K as recordsOf, E as referenceOf, Tt as requestBand, q as requestsOf, J as restartOf, Y as restartsAt, D as reusesReset, X as rulesOf, Et as seconds, Dt as secondsOf, Z as sessionsAt, Ot as showBand, Q as signalOf, $ as signalsOf, et as sliceDropOf, tt as sliceEmptyOf, nt as sliceReadyAt, rt as sliceReadyOf, it as slicesOf, at as socketsOf, ot as stoppingOf, l as timeSpread, st as transitionOf, ct as tunnelsOf, O as unitOf, k as updatesOf, p as upgrade, m as upgradeCell, lt as ztunnelPodsOf, ut as ztunnelReplaced } from "./judge-DA754h1o.js";
1
+ export { ht as CLIENT, u as FORMAT, d as FORMAT_V1, A as HBONE_PORT, gt as HEALTH_PORT, h as KIND_NOISE, g as LAST_SLACK, _t as LB_CLASS, vt as LOG_LABEL, yt as OUTSIDE, bt as PORT, xt as REDIS, dt as RELATIVE, St as SERVER, t as STAGES, j as TCP_STATE, Ct as VIP_ANNOTATION, M as backendsAt, wt as backlogEnd, Tt as bandOf, N as byClients, P as byNode, a as calibrationOf, o as cellsTable, _ as checkRun, v as cyclesOf, F as deletionOf, y as deletionsOf, Et as drainBand, I as dropOf, L as emptyOf, b as factsOf, R as failuresOf, z as intakeOf, B as isTunnelState, f as judge, x as judgeKind, V as kernelCounts, n as kindCellRecordSchema, r as kindCellRecordV1Schema, ft as medianInterval, s as medianText, pt as middle, S as observationAfter, C as observationEnd, H as outcomesOf, Dt as overshootBand, U as periodOf, W as podsAt, G as podsOf, c as predictionText, w as propagationOf, T as propagationSource, mt as quantileOf, i as readRecord, K as recordsOf, E as referenceOf, Ot as requestBand, q as requestsOf, J as restartOf, Y as restartsAt, D as reusesReset, X as rulesOf, kt as seconds, At as secondsOf, Z as sessionsAt, jt as showBand, Q as signalOf, $ as signalsOf, et as sliceDropOf, tt as sliceEmptyOf, nt as sliceReadyAt, rt as sliceReadyOf, it as slicesOf, at as socketsOf, ot as stoppingOf, l as timeSpread, st as transitionOf, ct as tunnelsOf, O as unitOf, k as updatesOf, p as upgrade, m as upgradeCell, lt as ztunnelPodsOf, ut as ztunnelReplaced } from "./judge-DKrgfhAt.js";
package/image/client.mjs CHANGED
@@ -170,6 +170,31 @@ const flush = () => {
170
170
  setInterval(flush, 100);
171
171
  const say = (line) => pending.push(`${JSON.stringify({ ...line, p: pod, n: node })}\n`);
172
172
 
173
+ // With ARP_WATCH, the client reads the MAC address of that IPv4 address in the neighbour table each
174
+ // 10 ms, and it writes a line `arp` at each change (SYS-51). A gratuitous ARP of a new holder of a VIP
175
+ // changes the MAC, thus the line gives the time of the move. An entry with the flags 0x0 has no MAC yet
176
+ const watched = process.env.ARP_WATCH ?? "";
177
+ if (watched !== "") {
178
+ let seen;
179
+ setInterval(() => {
180
+ let mac = null;
181
+ try {
182
+ for (const row of readFileSync("/proc/net/arp", "utf8").split("\n").slice(1)) {
183
+ const [ip, , flags, hw] = row.trim().split(/\s+/);
184
+ if (ip === watched) {
185
+ mac = flags === "0x0" ? null : hw.toLowerCase();
186
+ break;
187
+ }
188
+ }
189
+ } catch {
190
+ return;
191
+ }
192
+ if (mac === seen) return;
193
+ seen = mac;
194
+ say({ ev: "arp", t: now(), ip: watched, mac });
195
+ }, 10);
196
+ }
197
+
173
198
  const outcomeOf = (error) => {
174
199
  const code = error?.code ?? "";
175
200
  if (code === "ECONNREFUSED") return "refused";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@mark1russell7/kind",
4
- "version": "0.13.1",
4
+ "version": "0.13.3",
5
5
  "description": "Kubernetes in Docker as a lab for connection timers: a kind cluster from a scenario, faults in the namespaces of its pods, observations on the one monotonic clock of the VM, and predictions from the ordering law. Its judge entry reads and judges a raw record without Docker.",
6
6
  "keywords": [
7
7
  "kubernetes",
@@ -69,14 +69,14 @@
69
69
  "@mark1russell7/harness": "^0.14.0",
70
70
  "@mark1russell7/quantity": "^0.3.0",
71
71
  "@mark1russell7/rigor-statistics": "^0.1.3",
72
- "@mark1russell7/service": "^0.6.4",
72
+ "@mark1russell7/service": "^0.6.5",
73
73
  "testcontainers": "12.2.0"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "zod": "^4.1.0"
77
77
  },
78
78
  "devDependencies": {
79
- "@mark1russell7/cue": "github:mark1russell7/cue",
79
+ "@mark1russell7/cue": "github:mark1russell7/cue#da04dd56699a2ae806ab64da5b1d677476afe69e",
80
80
  "@types/node": "^26.6.4",
81
81
  "tsdown": "^0.23.1",
82
82
  "typescript": "^7.0.2",