feat: improve resource reconciliation and observability
This commit is contained in:
+51
-41
@@ -7,6 +7,7 @@ import {
|
||||
type V1Status,
|
||||
} from "@kubernetes/client-node";
|
||||
import { PassThrough } from "node:stream";
|
||||
import { logKubernetesRequest } from "../lib/request-log";
|
||||
import {
|
||||
type ExecDeployment,
|
||||
type ExecPod,
|
||||
@@ -17,18 +18,14 @@ import {
|
||||
type KubernetesExecRequest,
|
||||
} from "./exec-service";
|
||||
|
||||
function selectorString(
|
||||
labels: Readonly<Record<string, string>>,
|
||||
): string {
|
||||
function selectorString(labels: Readonly<Record<string, string>>): string {
|
||||
return Object.entries(labels)
|
||||
.sort(([left], [right]) => left.localeCompare(right))
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join(",");
|
||||
}
|
||||
|
||||
function matchLabels(
|
||||
deployment: V1Deployment,
|
||||
): Record<string, string> {
|
||||
function matchLabels(deployment: V1Deployment): Record<string, string> {
|
||||
const matchExpressions = deployment.spec?.selector?.matchExpressions;
|
||||
if (matchExpressions?.length) return {};
|
||||
return deployment.spec?.selector?.matchLabels ?? {};
|
||||
@@ -37,11 +34,13 @@ function matchLabels(
|
||||
async function ownerDeploymentUid(
|
||||
apps: AppsV1Api,
|
||||
namespace: string,
|
||||
ownerReferences: Array<{
|
||||
kind?: string;
|
||||
name?: string;
|
||||
uid?: string;
|
||||
}> | undefined,
|
||||
ownerReferences:
|
||||
| Array<{
|
||||
kind?: string;
|
||||
name?: string;
|
||||
uid?: string;
|
||||
}>
|
||||
| undefined,
|
||||
): Promise<string> {
|
||||
if (!ownerReferences?.length) return "";
|
||||
for (const ref of ownerReferences) {
|
||||
@@ -153,27 +152,25 @@ export class KubernetesExec implements KubernetesExecBackend {
|
||||
pod.metadata?.ownerReferences,
|
||||
);
|
||||
const containerStatuses = pod.status?.containerStatuses ?? [];
|
||||
const containers: ExecPodContainer[] = (
|
||||
pod.spec?.containers ?? []
|
||||
).map((container) => {
|
||||
const status = containerStatuses.find(
|
||||
(item) => item.name === container.name,
|
||||
);
|
||||
return {
|
||||
name: container.name ?? "",
|
||||
running: status?.state?.running !== undefined,
|
||||
ready: status?.ready,
|
||||
};
|
||||
});
|
||||
const containers: ExecPodContainer[] = (pod.spec?.containers ?? []).map(
|
||||
(container) => {
|
||||
const status = containerStatuses.find(
|
||||
(item) => item.name === container.name,
|
||||
);
|
||||
return {
|
||||
name: container.name ?? "",
|
||||
running: status?.state?.running !== undefined,
|
||||
ready: status?.ready,
|
||||
};
|
||||
},
|
||||
);
|
||||
pods.push({
|
||||
name,
|
||||
uid,
|
||||
deploymentUid,
|
||||
phase: pod.status?.phase,
|
||||
deletionTimestamp: pod.metadata?.deletionTimestamp
|
||||
? new Date(
|
||||
pod.metadata.deletionTimestamp,
|
||||
).toISOString()
|
||||
? new Date(pod.metadata.deletionTimestamp).toISOString()
|
||||
: undefined,
|
||||
containers,
|
||||
});
|
||||
@@ -206,22 +203,35 @@ export class KubernetesExec implements KubernetesExecBackend {
|
||||
signal.addEventListener("abort", abort, { once: true });
|
||||
|
||||
try {
|
||||
const ws = await this.execClient.exec(
|
||||
request.namespace,
|
||||
request.pod,
|
||||
request.container,
|
||||
[...request.command],
|
||||
stdout,
|
||||
stderr,
|
||||
stdin,
|
||||
request.tty,
|
||||
(status) => {
|
||||
completed({
|
||||
exitCode: exitCodeFromStatus(status) ?? 1,
|
||||
reason: status.reason,
|
||||
message: status.message,
|
||||
});
|
||||
const ws = await logKubernetesRequest(
|
||||
{
|
||||
method: "GET",
|
||||
pathname: `/api/v1/namespaces/${request.namespace}/pods/${request.pod}/exec`,
|
||||
body: {
|
||||
container: request.container,
|
||||
command: request.command,
|
||||
tty: request.tty,
|
||||
},
|
||||
attempt: 1,
|
||||
},
|
||||
() =>
|
||||
this.execClient.exec(
|
||||
request.namespace,
|
||||
request.pod,
|
||||
request.container,
|
||||
[...request.command],
|
||||
stdout,
|
||||
stderr,
|
||||
stdin,
|
||||
request.tty,
|
||||
(status) => {
|
||||
completed({
|
||||
exitCode: exitCodeFromStatus(status) ?? 1,
|
||||
reason: status.reason,
|
||||
message: status.message,
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
close = () => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user