Skip to content

OLS-3566 Add TTL lifecycle CRD fields and reconciler enforcement - #412

Open
sriroopar wants to merge 1 commit into
openshift:mainfrom
sriroopar:ols-3566-ttl-lifecycle
Open

OLS-3566 Add TTL lifecycle CRD fields and reconciler enforcement#412
sriroopar wants to merge 1 commit into
openshift:mainfrom
sriroopar:ols-3566-ttl-lifecycle

Conversation

@sriroopar

Copy link
Copy Markdown

Summary

  • Add automatic garbage collection of terminal AgenticRun resources following the Kubernetes Jobs ttlSecondsAfterFinished pattern
  • Introduces AgenticOLSConfig.spec.lifecycle.terminalTTL as a cluster-wide default TTL and AgenticRun.spec.ttlAfterTerminal as a per-run mutable override
  • Operator stamps status.terminalTime and spec.ttlAfterTerminal when a run reaches terminal state, then deletes expired runs or requeues with RequeueAfter for the remaining duration

CRD Changes

Field Type Description
AgenticOLSConfig.spec.lifecycle.terminalTTL *int32 (optional) Cluster-wide default TTL in seconds for terminal runs
AgenticRun.spec.ttlAfterTerminal *int32 (optional, mutable) Per-run TTL override; 0 disables auto-deletion
AgenticRun.status.terminalTime *metav1.Time (optional) Timestamp when the run first reached terminal state (set once)

Reconciler Changes

  • New handleTerminalTTL() method integrated into all terminal phase branches (Completed, Failed, Denied, Escalated, EmergencyStopped, NoActionRequired)
  • Stamps terminalTime and ttlAfterTerminal on first terminal reconcile
  • Pre-set ttlAfterTerminal (by adapter/admin) is never overwritten
  • ttlAfterTerminal=0 explicitly disables auto-deletion for that run
  • No AgenticOLSConfig CR → no auto-deletion (backwards-compatible)
  • fanOutToActiveRuns updated to enqueue terminal runs needing TTL stamping on config changes

Files Changed

File Change
api/v1alpha1/agenticolsconfig_types.go Added LifecycleConfig struct and Lifecycle field
api/v1alpha1/agenticrun_types.go Added TTLAfterTerminal to spec, TerminalTime to status
controller/agenticrun/reconciler.go Added handleTerminalTTL(), integrated into all terminal branches
controller/agenticrun/helpers.go Added getTerminalTTL() helper
controller/agenticrun/ttl_test.go 9 new unit tests covering all acceptance criteria
config/crd/bases/*.yaml Regenerated via make manifests

Test plan

  • make manifests regenerates CRD YAMLs without error
  • make test passes (all existing + 9 new TTL tests)
  • make api-lint passes
  • Verify terminal runs get terminalTime and ttlAfterTerminal stamped
  • Verify expired runs are deleted after TTL elapses
  • Verify ttlAfterTerminal=0 prevents auto-deletion
  • Verify pre-set ttlAfterTerminal is not overwritten by cluster default
  • Verify no AgenticOLSConfig CR means no auto-deletion

Spec Reference: lightspeed-agentic-operator/.ai/spec/what/agentic-lifecycle.md — rules 1-10

🤖 Generated with Claude Code

Add automatic garbage collection of terminal AgenticRun resources
following the Kubernetes Jobs ttlSecondsAfterFinished pattern.

CRD changes:
- AgenticOLSConfig.spec.lifecycle.terminalTTL (cluster-wide default)
- AgenticRun.spec.ttlAfterTerminal (per-run override, mutable)
- AgenticRun.status.terminalTime (stamped once at terminal state)

Reconciler changes:
- Stamp terminalTime and ttlAfterTerminal on terminal state
- Delete expired runs; RequeueAfter for non-expired
- ttlAfterTerminal=0 disables auto-deletion
- Pre-set ttlAfterTerminal preserved (not overwritten)
- No AgenticOLSConfig CR = no auto-deletion (backwards-compatible)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@openshift-ci
openshift-ci Bot requested review from joshuawilson and xrajesh August 4, 2026 03:48
@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign onmete for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added configurable automatic cleanup for completed, failed, or otherwise terminal runs.
    • Added per-run retention settings and timestamps showing when a run became terminal.
    • Runs are retained when cleanup is disabled or no retention period is configured.
    • Expired terminal runs are deleted automatically; active runs are unaffected.
  • Tests

    • Added coverage for configuration, retention behavior, expiration, requeueing, and terminal run outcomes.

Walkthrough

Changes

AgenticRun now supports per-run and cluster-wide terminal TTL configuration. The controller records terminal timestamps, persists configured TTLs, requeues active terminal runs, and deletes expired runs. Tests cover all terminal phases and configuration states.

AgenticRun terminal cleanup

Layer / File(s) Summary
TTL API contracts
api/v1alpha1/agenticolsconfig_types.go, api/v1alpha1/agenticrun_types.go
Added cluster lifecycle configuration, per-run TTLAfterTerminal, and status TerminalTime.
Terminal TTL reconciliation
controller/agenticrun/helpers.go, controller/agenticrun/reconciler.go
Loads TTL configuration, stamps terminal runs, preserves preset TTLs, requeues unexpired runs, and deletes expired runs across terminal phases.
TTL lifecycle validation
controller/agenticrun/ttl_test.go
Tests configuration lookup, timestamp and TTL persistence, zero and absent TTL behavior, requeue timing, deletion, denied runs, and failed runs.

Sequence Diagram(s)

sequenceDiagram
  participant AgenticRunReconciler
  participant AgenticOLSConfig
  participant KubernetesAPI
  AgenticRunReconciler->>AgenticOLSConfig: Read lifecycle terminal TTL
  AgenticRunReconciler->>KubernetesAPI: Persist TerminalTime and TTLAfterTerminal
  AgenticRunReconciler->>AgenticRunReconciler: Calculate expiration
  AgenticRunReconciler->>KubernetesAPI: Requeue until expiration
  AgenticRunReconciler->>KubernetesAPI: Delete expired AgenticRun
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: TTL lifecycle CRD fields and reconciler enforcement.
Description check ✅ Passed The description directly explains the TTL lifecycle changes, reconciler behavior, CRD updates, and tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controller/agenticrun/reconciler.go`:
- Around line 278-281: Update the enqueue condition in the reconciler around
DerivePhase and isTerminal so terminal runs are enqueued whenever either
TerminalTime or TTLAfterTerminal is missing. Preserve enqueueing for all
non-terminal runs and the existing handling for terminal runs with incomplete
TTL metadata.

In `@controller/agenticrun/ttl_test.go`:
- Line 98: Check every getAgenticRun call in controller/agenticrun/ttl_test.go
at lines 98, 141, 280, 314, and 350: capture its returned error and call
t.Fatalf before dereferencing got, preserving the existing status/spec
assertions after successful retrieval.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 364a3193-6b60-4ee6-8602-6f3929d5792c

📥 Commits

Reviewing files that changed from the base of the PR and between 5d52adf and 6550c99.

⛔ Files ignored due to path filters (2)
  • config/crd/bases/agentic.openshift.io_agenticolsconfigs.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/agentic.openshift.io_agenticruns.yaml is excluded by !config/crd/bases/**
📒 Files selected for processing (5)
  • api/v1alpha1/agenticolsconfig_types.go
  • api/v1alpha1/agenticrun_types.go
  • controller/agenticrun/helpers.go
  • controller/agenticrun/reconciler.go
  • controller/agenticrun/ttl_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift/lightspeed-agentic-sandbox (manual)

Comment on lines +278 to +281
phase := agenticv1alpha1.DerivePhase(p.Status.Conditions)
// Enqueue non-terminal runs (normal workflow) and terminal runs
// that may need TTL stamping (terminalTime set but no ttlAfterTerminal yet).
if !isTerminal(phase) || (p.Status.TerminalTime != nil && p.Spec.TTLAfterTerminal == nil) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enqueue terminal runs with incomplete TTL metadata.

Line 281 skips a terminal run when TerminalTime is nil, even if TTLAfterTerminal is also nil. Terminal runs created before this change have both fields unset. A later AgenticOLSConfig update will not reconcile them, so the default TTL is never applied.

Enqueue terminal runs when either TTL metadata field is missing.

Proposed fix
- if !isTerminal(phase) || (p.Status.TerminalTime != nil && p.Spec.TTLAfterTerminal == nil) {
+ if !isTerminal(phase) || p.Status.TerminalTime == nil || p.Spec.TTLAfterTerminal == nil {
    reqs = append(reqs, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(&p)})
  }

Based on PR objectives, configuration changes must enqueue terminal runs that require TTL metadata.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
phase := agenticv1alpha1.DerivePhase(p.Status.Conditions)
// Enqueue non-terminal runs (normal workflow) and terminal runs
// that may need TTL stamping (terminalTime set but no ttlAfterTerminal yet).
if !isTerminal(phase) || (p.Status.TerminalTime != nil && p.Spec.TTLAfterTerminal == nil) {
phase := agenticv1alpha1.DerivePhase(p.Status.Conditions)
// Enqueue non-terminal runs (normal workflow) and terminal runs
// that may need TTL stamping (terminalTime set but no ttlAfterTerminal yet).
if !isTerminal(phase) || p.Status.TerminalTime == nil || p.Spec.TTLAfterTerminal == nil {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controller/agenticrun/reconciler.go` around lines 278 - 281, Update the
enqueue condition in the reconciler around DerivePhase and isTerminal so
terminal runs are enqueued whenever either TerminalTime or TTLAfterTerminal is
missing. Preserve enqueueing for all non-terminal runs and the existing handling
for terminal runs with incomplete TTL metadata.

t.Fatalf("reconcile: %v", err)
}

got, _ := getAgenticRun(r, "fix-crash")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Check every getAgenticRun error before dereferencing its result. Ignoring these errors can hide the failed client operation or cause a nil dereference.

  • controller/agenticrun/ttl_test.go#L98-L98: capture the error and call t.Fatalf before reading got.Status.
  • controller/agenticrun/ttl_test.go#L141-L141: capture the error and call t.Fatalf before reading got.Spec.
  • controller/agenticrun/ttl_test.go#L280-L280: capture the error and call t.Fatalf before reading got.Status.
  • controller/agenticrun/ttl_test.go#L314-L314: capture the error and call t.Fatalf before reading got.Status.
  • controller/agenticrun/ttl_test.go#L350-L350: capture the error and call t.Fatalf before reading got.Status.

As per path instructions, “Never ignore error returns”.

📍 Affects 1 file
  • controller/agenticrun/ttl_test.go#L98-L98 (this comment)
  • controller/agenticrun/ttl_test.go#L141-L141
  • controller/agenticrun/ttl_test.go#L280-L280
  • controller/agenticrun/ttl_test.go#L314-L314
  • controller/agenticrun/ttl_test.go#L350-L350
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controller/agenticrun/ttl_test.go` at line 98, Check every getAgenticRun call
in controller/agenticrun/ttl_test.go at lines 98, 141, 280, 314, and 350:
capture its returned error and call t.Fatalf before dereferencing got,
preserving the existing status/spec assertions after successful retrieval.

Source: Path instructions

@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown

@sriroopar: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant