Skip to content

Commit 2af6487

Browse files
vigneshrajsbclaude
andcommitted
fix(kubernetes): consolidate namespace label management and rename annotations to lfc/*
- Simplify ensureNamespaceExists labels in nativeBuild/utils.ts - Rename lifecycle.io/* annotations to lfc/* in utils.ts and jobFactory.ts - Update generateTTLLabels and generateTTLPatch to include lfc/uuid, lfc/type, and app.kubernetes.io/managed-by - Consolidate createOrUpdateNamespace PATCH branches in kubernetes.ts - Add UUID fallback derivation from namespace name in ttlCleanup.ts - Update annotation assertions in buildkit.test.ts and utils.test.ts to match lfc/* Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 17c3d10 commit 2af6487

File tree

6 files changed

+42
-43
lines changed

6 files changed

+42
-43
lines changed

src/server/lib/kubernetes.ts

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ async function generateTTLLabels({
8282
ttl: boolean;
8383
buildUUID: string;
8484
}): Promise<{ labels: Record<string, string>; logMessage: string }> {
85-
const baseLabels = { 'lfc/uuid': uuid };
85+
const baseLabels: Record<string, string> = {
86+
'lfc/uuid': uuid,
87+
'lfc/type': staticEnv ? 'static' : 'ephemeral',
88+
'app.kubernetes.io/managed-by': 'lifecycle',
89+
};
8690

8791
// Static or TTL disabled - only set enable flag
8892
if (staticEnv || !ttl) {
@@ -117,16 +121,27 @@ async function generateTTLLabels({
117121
* Generates patch operations for updating TTL labels on existing namespace
118122
*/
119123
async function generateTTLPatch({
124+
uuid,
125+
staticEnv,
120126
ttl,
121127
buildUUID,
122128
}: {
129+
uuid: string;
130+
staticEnv: boolean;
123131
ttl: boolean;
124132
buildUUID: string;
125133
}): Promise<{ patch: any[]; logMessage: string }> {
134+
const basePatch = [
135+
{ op: 'add', path: '/metadata/labels/lfc~1uuid', value: uuid },
136+
{ op: 'add', path: '/metadata/labels/lfc~1type', value: staticEnv ? 'static' : 'ephemeral' },
137+
{ op: 'add', path: '/metadata/labels/app.kubernetes.io~1managed-by', value: 'lifecycle' },
138+
];
139+
126140
// TTL disabled - only update enable flag
127141
if (!ttl) {
128142
return {
129143
patch: [
144+
...basePatch,
130145
{
131146
op: 'add',
132147
path: '/metadata/labels/lfc~1ttl-enable',
@@ -143,6 +158,7 @@ async function generateTTLPatch({
143158

144159
return {
145160
patch: [
161+
...basePatch,
146162
{
147163
op: 'add',
148164
path: '/metadata/labels/lfc~1ttl-enable',
@@ -213,32 +229,18 @@ export async function createOrUpdateNamespace({
213229
};
214230

215231
if (await namespaceExists(client, name)) {
216-
// Only update TTL labels if not static env
217-
if (!staticEnv) {
218-
const { patch, logMessage: patchMessage } = await generateTTLPatch({
219-
ttl,
220-
buildUUID,
221-
});
232+
const { patch, logMessage: patchMessage } = await generateTTLPatch({
233+
uuid,
234+
staticEnv,
235+
ttl: staticEnv ? false : ttl,
236+
buildUUID,
237+
});
222238

223-
await client.patchNamespace(name, patch, undefined, undefined, undefined, undefined, undefined, {
224-
headers: { 'Content-Type': 'application/json-patch+json' },
225-
});
226-
getLogger({ namespace: name }).info(`Deploy: updated namespace ${patchMessage}`);
227-
return;
228-
} else {
229-
await client.patchNamespace(
230-
name,
231-
[{ op: 'add', path: '/metadata/labels/lfc~1ttl-enable', value: 'false' }],
232-
undefined,
233-
undefined,
234-
undefined,
235-
undefined,
236-
undefined,
237-
{ headers: { 'Content-Type': 'application/json-patch+json' } }
238-
);
239-
getLogger({ namespace: name }).info('Deploy: patched namespace TTL disabled (static env)');
240-
return;
241-
}
239+
await client.patchNamespace(name, patch, undefined, undefined, undefined, undefined, undefined, {
240+
headers: { 'Content-Type': 'application/json-patch+json' },
241+
});
242+
getLogger({ namespace: name }).info(`Deploy: updated namespace ${patchMessage}`);
243+
return;
242244
}
243245

244246
try {

src/server/lib/kubernetes/jobFactory.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function createKubernetesJob(config: JobConfig): V1Job {
7070
...labels,
7171
},
7272
annotations: {
73-
'lifecycle.io/triggered-at': new Date().toISOString(),
73+
'lfc/triggered-at': new Date().toISOString(),
7474
...annotations,
7575
},
7676
},
@@ -145,8 +145,8 @@ export function createBuildJob(config: BuildJobConfig): V1Job {
145145
'build-method': 'native',
146146
},
147147
annotations: {
148-
'lifecycle.io/dockerfile': config.dockerfilePath,
149-
'lifecycle.io/ecr-repo': config.ecrRepo,
148+
'lfc/dockerfile': config.dockerfilePath,
149+
'lfc/ecr-repo': config.ecrRepo,
150150
},
151151
podAnnotations: config.podAnnotations,
152152
initContainers: config.initContainers,

src/server/lib/nativeBuild/__tests__/buildkit.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ describe('buildkitBuild', () => {
246246
expect(fullCommand).toContain('build-method: "native"');
247247

248248
// Check annotations
249-
expect(fullCommand).toContain('lifecycle.io/dockerfile: "Dockerfile"');
250-
expect(fullCommand).toContain('lifecycle.io/ecr-repo: "test-repo"');
249+
expect(fullCommand).toContain('lfc/dockerfile: "Dockerfile"');
250+
expect(fullCommand).toContain('lfc/ecr-repo: "test-repo"');
251251
});
252252
});
253253

src/server/lib/nativeBuild/__tests__/utils.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,9 @@ describe('nativeBuild/utils', () => {
7373
expect(manifest.metadata.labels['build-method']).toBe('native');
7474

7575
// Check annotations
76-
expect(manifest.metadata.annotations['lifecycle.io/dockerfile']).toBe('Dockerfile');
77-
expect(manifest.metadata.annotations['lifecycle.io/ecr-repo']).toBe(
78-
'123456789.dkr.ecr.us-east-1.amazonaws.com/test-repo'
79-
);
80-
expect(manifest.metadata.annotations['lifecycle.io/triggered-at']).toBeDefined();
76+
expect(manifest.metadata.annotations['lfc/dockerfile']).toBe('Dockerfile');
77+
expect(manifest.metadata.annotations['lfc/ecr-repo']).toBe('123456789.dkr.ecr.us-east-1.amazonaws.com/test-repo');
78+
expect(manifest.metadata.annotations['lfc/triggered-at']).toBeDefined();
8179

8280
// Check spec
8381
expect(manifest.spec.ttlSecondsAfterFinished).toBeUndefined(); // No TTL by default for non-static builds

src/server/lib/nativeBuild/utils.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export async function ensureNamespaceExists(namespace: string): Promise<void> {
3939
name: namespace,
4040
labels: {
4141
'app.kubernetes.io/managed-by': 'lifecycle',
42-
'lifecycle.io/type': 'ephemeral',
4342
},
4443
},
4544
});
@@ -208,9 +207,9 @@ export function getBuildLabels(
208207

209208
export function getBuildAnnotations(dockerfilePath: string, ecrRepo: string): Record<string, string> {
210209
return {
211-
'lifecycle.io/dockerfile': dockerfilePath,
212-
'lifecycle.io/ecr-repo': ecrRepo,
213-
'lifecycle.io/triggered-at': new Date().toISOString(),
210+
'lfc/dockerfile': dockerfilePath,
211+
'lfc/ecr-repo': ecrRepo,
212+
'lfc/triggered-at': new Date().toISOString(),
214213
};
215214
}
216215

src/server/services/ttlCleanup.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,10 @@ export default class TTLCleanupService extends Service {
187187

188188
const daysExpired = Math.floor((now - expireTime) / (1000 * 60 * 60 * 24));
189189

190-
const buildUUID = labels['lfc/uuid'];
190+
let buildUUID = labels['lfc/uuid'];
191191
if (!buildUUID) {
192-
getLogger().warn(`TTL: namespace missing uuid label namespace=${nsName}`);
193-
continue;
192+
buildUUID = nsName.replace('env-', '');
193+
getLogger().warn(`TTL: namespace missing uuid label, derived from name namespace=${nsName}`);
194194
}
195195

196196
updateLogContext({ buildUuid: buildUUID });

0 commit comments

Comments
 (0)