fix: P0 correctness fixes from FAR-104/FAR-105 analysis

1. Inherit envFrom and env.valueFrom from self pod — secrets wired via
   valueFrom.secretKeyRef or envFrom.secretRef are now forwarded to Job
   pods, fixing credentials silently dropped for K8s-idiomatic secret
   patterns (e.g. ANTHROPIC_API_KEY via Secret).

2. Distinguish 404 vs transient errors in keepalive — only mark the
   keepalive as terminal on 404 (Job deleted). Transient 5xx/connection
   errors are logged and retried on the next tick, preventing premature
   reaper kills during API instability.

3. Fail closed on concurrency-guard read failure — a failing
   listNamespacedJob now returns k8s_concurrency_guard_unreachable
   instead of silently proceeding, protecting against zombie Jobs on
   shared PVCs.

4. Bound the waitForJobCompletion re-check — pass a 60s timeout instead
   of polling forever, preventing indefinite hangs when the K8s API is
   degraded.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Test User
2026-04-20 18:57:16 +00:00
parent c35253ddd4
commit d74b6d34b3
4 changed files with 111 additions and 14 deletions
+18 -3
View File
@@ -20,8 +20,12 @@ export interface SelfPodInfo {
dnsConfig: k8s.V1PodDNSConfig | undefined;
pvcClaimName: string | null;
secretVolumes: SelfPodSecretVolume[];
/** Env vars inherited from the Deployment container. */
/** Env vars inherited from the Deployment container (literal name/value pairs). */
inheritedEnv: Record<string, string>;
/** Env vars with valueFrom (secretKeyRef, configMapKeyRef, etc.) from the Deployment container. */
inheritedEnvValueFrom: k8s.V1EnvVar[];
/** envFrom sources (secretRef, configMapRef) from the Deployment container. */
inheritedEnvFrom: k8s.V1EnvFromSource[];
}
let cachedSelfPod: SelfPodInfo | null = null;
@@ -134,12 +138,21 @@ export async function getSelfPodInfo(kubeconfigPath?: string): Promise<SelfPodIn
// Collect env vars from the pod spec's container definition.
// Agent config env (set in buildEnvVars) will override these.
const inheritedEnv: Record<string, string> = {};
const inheritedEnvValueFrom: k8s.V1EnvVar[] = [];
for (const envItem of mainContainer.env ?? []) {
if (!envItem.name) continue;
const value = envItem.value ?? "";
if (value) inheritedEnv[envItem.name] = value;
if (envItem.valueFrom) {
// Preserve valueFrom entries (secretKeyRef, configMapKeyRef, fieldRef, etc.)
inheritedEnvValueFrom.push({ name: envItem.name, valueFrom: envItem.valueFrom });
} else {
const value = envItem.value ?? "";
if (value) inheritedEnv[envItem.name] = value;
}
}
// Capture envFrom sources (secretRef, configMapRef) from the container spec
const inheritedEnvFrom: k8s.V1EnvFromSource[] = mainContainer.envFrom ?? [];
cachedSelfPod = {
namespace,
image: mainContainer.image,
@@ -150,6 +163,8 @@ export async function getSelfPodInfo(kubeconfigPath?: string): Promise<SelfPodIn
pvcClaimName,
secretVolumes,
inheritedEnv,
inheritedEnvValueFrom,
inheritedEnvFrom,
};
return cachedSelfPod;