Skip to content

Commit 42d0537

Browse files
authored
Merge pull request #3810 from skoeva/sidecars
frontend: k8s: Handle new k8s feature native sidecars
2 parents 085bc1c + 5392040 commit 42d0537

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

frontend/src/lib/k8s/cluster.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,21 @@ export interface KubeContainer {
403403
};
404404
};
405405

406+
/**
407+
* RestartPolicy defines the restart behavior of individual containers in a pod. This field may only be
408+
* set for init containers, and the only allowed value is "Always". For non-init containers or when this
409+
* field is not specified, the restart behavior is defined by the Pod's restart policy and the container
410+
* type. Setting the RestartPolicy as "Always" for the init container will have the following effect: this
411+
* init container will be continually restarted on exit until all regular containers have terminated.
412+
* Once all regular containers have completed, all init containers with restartPolicy "Always" will be
413+
* shut down. This lifecycle differs from normal init containers and is often referred to as a "sidecar"
414+
* container. Although this init container still starts in the init container sequence, it does not wait for
415+
* the container to complete before proceeding to the next init container. Instead, the next init
416+
* container starts immediately after this init container is started, or after any startupProbe has
417+
* successfully completed.
418+
*/
419+
restartPolicy?: string;
420+
406421
// @todo:
407422
// securityContext SecurityContext SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
408423
// startupProbe Probe StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

frontend/src/lib/k8s/pod.ts

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,19 @@ class Pod extends KubeObject<KubePod> {
303303
return lastRestartDate;
304304
}
305305

306+
private isRestartableInitContainer(spec?: KubeContainer): boolean {
307+
return !!spec && (spec as any).restartPolicy === 'Always';
308+
}
309+
310+
private isPodInitializedConditionTrue(status?: KubePod['status']): boolean {
311+
for (const c of status?.conditions ?? []) {
312+
if (c.type === 'Initialized' && c.status === 'True') {
313+
return true;
314+
}
315+
}
316+
return false;
317+
}
318+
306319
private hasPodReadyCondition(conditions: any): boolean {
307320
for (const condition of conditions) {
308321
if (condition.type === 'Ready' && condition.Status === 'True') {
@@ -312,7 +325,7 @@ class Pod extends KubeObject<KubePod> {
312325
return false;
313326
}
314327

315-
// Implementation based on: https://github.com/kubernetes/kubernetes/blob/7b6293b6b6a5662fc37f440e839cf5da8b96e935/pkg/printers/internalversion/printers.go#L759
328+
// Implementation based on: https://github.com/kubernetes/kubernetes/blob/67216cfdd980cdd0234866d66a9ffe2ba3d8fcc4/pkg/printers/internalversion/printers.go#L891
316329
getDetailedStatus(): PodDetailedStatus {
317330
// We cache this data to avoid going through all this logic when nothing has changed
318331
if (
@@ -331,22 +344,58 @@ class Pod extends KubeObject<KubePod> {
331344
}
332345

333346
let restarts = 0;
334-
const totalContainers = (this.spec.containers ?? []).length;
347+
let restartableInitContainerRestarts = 0;
335348
let readyContainers = 0;
336349
let message = '';
337350
let lastRestartDate = new Date(0);
351+
let lastRestartableInitContainerRestartDate = new Date(0);
338352

339353
let reason = this.status.reason || this.status.phase;
340354

355+
const initContainers: Record<string, KubeContainer> = {};
356+
let totalContainers = (this.spec.containers ?? []).length;
357+
for (const ic of this.spec.initContainers ?? []) {
358+
initContainers[ic.name] = ic;
359+
if (this.isRestartableInitContainer(ic)) {
360+
totalContainers++;
361+
}
362+
}
363+
341364
let initializing = false;
342365
for (const i in this.status.initContainerStatuses ?? []) {
343366
const container = this.status.initContainerStatuses![i];
344367
restarts += container.restartCount;
345368
lastRestartDate = this.getLastRestartDate(container, lastRestartDate);
346369

370+
if (container.lastState.terminated !== null) {
371+
const terminatedDate = container.lastState.terminated?.finishedAt
372+
? new Date(container.lastState.terminated?.finishedAt)
373+
: undefined;
374+
if (!!terminatedDate && lastRestartDate < terminatedDate) {
375+
lastRestartDate = terminatedDate;
376+
}
377+
}
378+
379+
if (this.isRestartableInitContainer(initContainers[container.name])) {
380+
restartableInitContainerRestarts += container.restartCount;
381+
if (container.lastState.terminated !== null) {
382+
const terminatedDate = container.lastState.terminated?.finishedAt
383+
? new Date(container.lastState.terminated?.finishedAt)
384+
: undefined;
385+
if (!!terminatedDate && lastRestartableInitContainerRestartDate < terminatedDate) {
386+
lastRestartableInitContainerRestartDate = terminatedDate;
387+
}
388+
}
389+
}
390+
347391
switch (true) {
348392
case container.state.terminated?.exitCode === 0:
349393
continue;
394+
case !!container.started && this.isRestartableInitContainer(initContainers[container.name]):
395+
if (container.ready) {
396+
readyContainers++;
397+
}
398+
continue;
350399
case !!container.state.terminated:
351400
if (!container.state.terminated!.reason) {
352401
if (container.state.terminated!.signal !== 0) {
@@ -373,8 +422,9 @@ class Pod extends KubeObject<KubePod> {
373422
break;
374423
}
375424

376-
if (!initializing) {
377-
restarts = 0;
425+
if (!initializing || this.isPodInitializedConditionTrue(this.status)) {
426+
restarts = restartableInitContainerRestarts;
427+
lastRestartDate = lastRestartableInitContainerRestartDate;
378428
let hasRunning = false;
379429
for (let i = (this.status?.containerStatuses?.length || 0) - 1; i >= 0; i--) {
380430
const container = this.status?.containerStatuses[i];

0 commit comments

Comments
 (0)