Skip to content

MCO-1814: Setup metrics for builds - #6316

Open
eric200428 wants to merge 2 commits into
openshift:mainfrom
eric200428:OCL_Metrics
Open

MCO-1814: Setup metrics for builds#6316
eric200428 wants to merge 2 commits into
openshift:mainfrom
eric200428:OCL_Metrics

Conversation

@eric200428

@eric200428 eric200428 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

- What I did

  • Added a new OCLMetrics module that registers Prometheus metrics for build telemetry
  • Wired the metrics into the buildReconciler to track the full OCL build lifecycle: build state, duration, job state, image push operations, config change counts, rollout progress, and active build counts
  • Metrics are emitted per pool and build name, making it easy to scope dashboards and alerts to specific pools

- How to verify it

go test ./pkg/controller/build/

Or on a live cluster:

  1. Trigger a build by creating / updating a MOSC
  2. Port forward the MOSB metrics endpoint:
    oc port-forward -n openshift-machine-config-operator deploy/machine-os-builder 8797:8797
  3. Scrape the metric:
    curl -s http://localhost:8797/metrics | grep ocl_

- Description for the changelog

Add Prometheus metrics for OCL build telemetry

Summary by CodeRabbit

  • New Features
    • Added Prometheus metrics for On-Cluster Layering build and image-push lifecycle, including queue timing, retries, active builds, layered nodes, and rollout adoption.
    • Enabled configurable metrics endpoint settings (address and TLS parameters) at startup.
    • Added Prometheus alerts for OCL build failure/degraded states and image-push failures (with runbook links).
  • Bug Fixes
    • Improved accuracy of lifecycle transitions, timestamps, and metrics for succeeded/failed/interrupted flows and retries.
    • Cleaned up alert description formatting.
  • Tests
    • Added unit tests covering metric transitions, counters, duration observations, and active-build gauge behavior.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 16, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@eric200428: This pull request references MCO-1814 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

- What I did

  • Added a new OCLMetrics module that registers Prometheus metrics for build telemetry
  • Wired the metrics into the buildReconciler to track the full OCL build lifecycle: build state, duration, job state, image push operations, config change counts, rollout progress, and active build counts
  • Metrics are emitted per pool and build name, making it easy to scope dashboards and alerts to specific pools

- How to verify it

go test ./pkg/controller/build/

Or on a live cluster:

  1. Trigger a build by creating / updating a MOSC
  2. Port forward the MOSB metrics endpoint:
oc port-forward -n openshift-machine-config-operator deploy/machine-os-builder 8797:8797
  1. Scrape the metric:
curl -s http://localhost:8797/metrics | grep ocl_

- Description for the changelog

Add Prometheus metrics for OCL build telemetry

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 openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR adds OCL Prometheus metrics, records build and image-push lifecycle transitions during reconciliation, exposes metrics through a TLS-configurable listener, tests metric behavior, and adds Prometheus alerts for OCL failures.

Changes

OCL observability

Layer / File(s) Summary
Define and validate OCL metrics
pkg/controller/build/ocl_metrics.go, pkg/controller/build/ocl_metrics_test.go
Defines and registers OCL build, job, image-push, rollout, queue, and pool metrics, with tests for lifecycle states, counters, gauges, and duration observations.
Instrument build reconciliation
pkg/controller/build/reconciler.go
Resolves owning pools and records job, build, image-push, retry, configuration-change, rollout, and queue metrics during reconciliation.
Expose metrics and configure alerts
cmd/machine-os-builder/start.go, install/0000_90_machine-config_01_prometheus-rules.yaml
Adds metrics listener and TLS flags, starts the OCL metrics listener, and adds alerts for OCL build and image-push failures.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BuildJob
  participant BuildReconciler
  participant OCLMetrics
  participant MetricsListener
  participant Prometheus
  BuildJob->>BuildReconciler: add or update build job
  BuildReconciler->>OCLMetrics: record lifecycle and queue metrics
  MachineOSBuilder->>MetricsListener: start TLS-configured listener
  Prometheus->>MetricsListener: scrape OCL metrics
  Prometheus->>Prometheus: evaluate OCL alert rules
Loading

Suggested reviewers: dkhater-redhat, harshwardhanpatil07


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error start.go logs the full startOpts struct and StartMetricsListener logs the bind addr, which can reveal internal hostnames at startup. Log only non-sensitive fields (or redact kubeconfig/bind address) before Infof, and avoid emitting the listener address at info level.
Docstring Coverage ⚠️ Warning Docstring coverage is 55.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding build metrics instrumentation for OCL builds.
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.
Stable And Deterministic Test Names ✅ Passed The new tests use only static Test... names in ocl_metrics_test.go; no dynamic Ginkgo-style titles were added.
Test Structure And Quality ✅ Passed PASS: The new tests are plain Go unit tests, not Ginkgo, and they only exercise in-memory Prometheus metrics; the Ginkgo-specific checklist doesn’t apply.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the new test file uses plain Go testing and has no MicroShift-sensitive OpenShift APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; the new tests are plain Go unit tests in pkg/controller/build using testing.T.
Topology-Aware Scheduling Compatibility ✅ Passed Touched code adds OCL metrics/alerts only; no nodeSelector, affinity, topology spread, replica logic, or topology labels were introduced.
Ote Binary Stdout Contract ✅ Passed Touched main/init/startup code only uses klog with logtostderr enabled; no new fmt.Print/stdout writes were added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the new tests are plain Go unit tests and show no IPv4-only or external-network assumptions.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret comparisons were added; TLS defaults to VersionTLS12/intermediate ciphers.
Container-Privileges ✅ Passed The PR only changes a PrometheusRule YAML and Go code; no changed manifest contains privileged/hostPID/hostNetwork/hostIPC/SYS_ADMIN/allowPrivilegeEscalation/root settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@openshift-ci

openshift-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: eric200428
Once this PR has been reviewed and has the lgtm label, please assign sergiordlr 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 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: 4

🤖 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 `@pkg/controller/build/ocl_metrics.go`:
- Around line 17-132: Remove the unbounded build_name and job_name labels from
lifecycle gauges including oclBuildState, oclBuildStartTime, oclBuildJobState,
and oclImagePushState, retaining only pool and state labels where needed. Use
aggregate metrics such as oclBuildTotal and the existing pool-level gauges for
historical and active tracking, and update all metric observations accordingly.
- Around line 236-246: Delete the corresponding pushStartTimes entry using the
pool/buildName key when a build reaches any terminal state. Add this cleanup to
RecordBuildInterrupted and also to RecordBuildFailed and RecordBuildCompleted,
while preserving their existing metric updates and the cleanup performed by
image-push completion/failure handlers.
- Around line 248-263: Update RecordBuildJobState so every recorded state label
combination sets oclBuildJobState to 1.0, removing the state-dependent 2.0 and
3.0 assignments while preserving the existing label cleanup and registration
flow. Also remove outdated enum-value mappings from the Help strings for
oclBuildState, oclBuildJobState, and oclImagePushState if they describe numeric
gauge values.

In `@pkg/controller/build/reconciler.go`:
- Around line 222-232: Stop suppressing lookup errors in AddJob and UpdateJob:
explicitly check errors from getMachineOSBuildForJob and
GetMachineOSConfigForMachineOSBuild, log warnings, and only continue recording
metrics when lookups succeed. In getMachineOSBuildForJob, return nil, nil for
jobs without the MachineOSBuild label while preserving genuine lookup errors;
apply these changes at pkg/controller/build/reconciler.go lines 222-232,
244-265, and 556-565.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 771cf087-ce25-40ad-a683-9b345be95df4

📥 Commits

Reviewing files that changed from the base of the PR and between 98771b6 and 94060a9.

📒 Files selected for processing (5)
  • cmd/machine-os-builder/start.go
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics.go
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go

Comment thread pkg/controller/build/ocl_metrics.go
Comment thread pkg/controller/build/ocl_metrics.go
Comment thread pkg/controller/build/ocl_metrics.go
Comment on lines +222 to +232
mosb, err := b.getMachineOSBuildForJob(job)
if err == nil && mosb != nil {
mosc, err := utils.GetMachineOSConfigForMachineOSBuild(mosb, b.utilListers())
if err == nil {
poolName := mosc.Spec.MachineConfigPool.Name
RecordBuildJobState(poolName, mosb.Name, job.Name, "active")
RecordImagePushStarted(poolName, mosb.Name)
RecordBuildQueueDuration(poolName, mosb.CreationTimestamp.Time)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not ignore error returns.

The current implementation ignores all errors returned from getMachineOSBuildForJob and GetMachineOSConfigForMachineOSBuild because the helper function intentionally returns an error for jobs missing the MachineOSBuild label. This pattern suppresses legitimate Lister lookup errors. As per path instructions, **/*.go: Go security (prodsec-skills): Never ignore error returns.

Refactor the helper to return nil, nil for unlabelled jobs, allowing the callers to explicitly check and log genuine errors.

  • pkg/controller/build/reconciler.go#L222-L232: Update AddJob to explicitly check err != nil and log warnings instead of silently skipping with if err == nil.
  • pkg/controller/build/reconciler.go#L244-L265: Update UpdateJob to explicitly check and log err != nil.
  • pkg/controller/build/reconciler.go#L556-L565: Modify getMachineOSBuildForJob to return nil, nil when the label is absent, rather than returning an error.
📍 Affects 1 file
  • pkg/controller/build/reconciler.go#L222-L232 (this comment)
  • pkg/controller/build/reconciler.go#L244-L265
  • pkg/controller/build/reconciler.go#L556-L565
🤖 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 `@pkg/controller/build/reconciler.go` around lines 222 - 232, Stop suppressing
lookup errors in AddJob and UpdateJob: explicitly check errors from
getMachineOSBuildForJob and GetMachineOSConfigForMachineOSBuild, log warnings,
and only continue recording metrics when lookups succeed. In
getMachineOSBuildForJob, return nil, nil for jobs without the MachineOSBuild
label while preserving genuine lookup errors; apply these changes at
pkg/controller/build/reconciler.go lines 222-232, 244-265, and 556-565.

Source: Path instructions

@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: 1

🤖 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 `@pkg/controller/build/ocl_metrics.go`:
- Around line 40-45: Remove the build_name label from oclBuildEndTime and
oclBuildRetries, then remove the corresponding buildName argument from all
listed WithLabelValues calls in pkg/controller/build/ocl_metrics.go at lines
40-45, 68-73, 215, 232, 246, and 264. Keep buildName function parameters if
needed to preserve existing reconciler.go callers.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3b1f10a1-c768-458e-aa17-22737d35567b

📥 Commits

Reviewing files that changed from the base of the PR and between 94060a9 and 2a84b00.

📒 Files selected for processing (5)
  • cmd/machine-os-builder/start.go
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics.go
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • cmd/machine-os-builder/start.go
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go

Comment thread pkg/controller/build/ocl_metrics.go Outdated

@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.

🧹 Nitpick comments (1)
pkg/controller/build/ocl_metrics.go (1)

182-249: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Prevent metric drift by using .Set() instead of .Inc() / .Dec().

Reconcilers may execute idempotent updates or re-process the same logical state (e.g., due to cache syncs or retries). If RecordBuildStarted is called multiple times without reaching a completion, or if a terminal state is recorded repeatedly, using .Inc() and .Dec() will cause the ocl_active_builds gauge to drift and potentially become unbounded or negative.

Since previous states are cleared per pool (implying a maximum of one tracked active build per pool), it is safer and more robust to use .Set(1) and .Set(0). This ensures the gauge immediately self-corrects even if events are missed or re-delivered.

🛠️ Proposed fix

Update the oclActiveBuilds logic across the lifecycle functions:

 func RecordBuildStarted(pool string) {
...
 	oclBuildStartTime.WithLabelValues(pool).Set(now)
-	oclActiveBuilds.WithLabelValues(pool).Inc()
+	oclActiveBuilds.WithLabelValues(pool).Set(1)
 }

... (update all terminal states)
 func RecordBuildCompleted(pool string, startTime time.Time) {
...
 	oclBuildTotal.WithLabelValues(pool, StateSucceeded).Inc()
-	oclActiveBuilds.WithLabelValues(pool).Dec()
+	oclActiveBuilds.WithLabelValues(pool).Set(0)
 }
 
 func RecordBuildFailed(pool string, startTime time.Time) {
...
 	oclBuildTotal.WithLabelValues(pool, StateFailed).Inc()
-	oclActiveBuilds.WithLabelValues(pool).Dec()
+	oclActiveBuilds.WithLabelValues(pool).Set(0)
 }
 
 func RecordBuildInterrupted(pool string) {
...
 	oclBuildTotal.WithLabelValues(pool, StateInterrupted).Inc()
-	oclActiveBuilds.WithLabelValues(pool).Dec()
+	oclActiveBuilds.WithLabelValues(pool).Set(0)
 }
🤖 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 `@pkg/controller/build/ocl_metrics.go` around lines 182 - 249, Update
oclActiveBuilds usage in RecordBuildStarted, RecordBuildCompleted,
RecordBuildFailed, and RecordBuildInterrupted to use Set(1) when a pool enters
an active build and Set(0) when it reaches any terminal state, replacing Inc and
Dec. Preserve the existing per-pool state cleanup and lifecycle transitions so
repeated or retried events remain idempotent.
🤖 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.

Nitpick comments:
In `@pkg/controller/build/ocl_metrics.go`:
- Around line 182-249: Update oclActiveBuilds usage in RecordBuildStarted,
RecordBuildCompleted, RecordBuildFailed, and RecordBuildInterrupted to use
Set(1) when a pool enters an active build and Set(0) when it reaches any
terminal state, replacing Inc and Dec. Preserve the existing per-pool state
cleanup and lifecycle transitions so repeated or retried events remain
idempotent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d818b986-0b4e-4d31-a4d0-6a8b24562116

📥 Commits

Reviewing files that changed from the base of the PR and between 2a84b00 and f67564d.

📒 Files selected for processing (5)
  • cmd/machine-os-builder/start.go
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics.go
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go

@eric200428

Copy link
Copy Markdown
Contributor Author

/pipeline required

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-upgrade
/test e2e-gcp-op-ocl-part1
/test e2e-gcp-op-ocl-part2
/test e2e-gcp-op-part1
/test e2e-gcp-op-part2
/test e2e-gcp-op-single-node
/test e2e-hypershift

@umohnani8

Copy link
Copy Markdown
Contributor

/pipeline required

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-upgrade
/test e2e-gcp-op-ocl-part1
/test e2e-gcp-op-ocl-part2
/test e2e-gcp-op-part1
/test e2e-gcp-op-part2
/test e2e-gcp-op-single-node
/test e2e-hypershift

@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: 1

🧹 Nitpick comments (2)
pkg/controller/build/ocl_metrics.go (2)

174-183: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer SetToCurrentTime() for timestamp gauges.

Prometheus's Gauge interface provides a built-in SetToCurrentTime() method. It is more idiomatic and abstracts away the float64 and Unix epoch conversion.

(Note: You could also apply this to oclBuildEndTime in the terminal state handlers if desired, though relying on the pre-computed now variable is fine there since it is also used for calculating durations).

♻️ Proposed refactor
 func RecordBuildStarted(pool string) {
-	now := float64(time.Now().Unix())
-
 	// Clear previous states for this pool
 	oclBuildState.DeletePartialMatch(prometheus.Labels{"pool": pool})
 
 	// Set new state
 	oclBuildState.WithLabelValues(pool, StatePending).Set(1)
-	oclBuildStartTime.WithLabelValues(pool).Set(now)
+	oclBuildStartTime.WithLabelValues(pool).SetToCurrentTime()
 	oclActiveBuilds.WithLabelValues(pool).Inc()
🤖 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 `@pkg/controller/build/ocl_metrics.go` around lines 174 - 183, Update
RecordBuildStarted to use
oclBuildStartTime.WithLabelValues(pool).SetToCurrentTime() instead of manually
computing and setting a Unix timestamp; leave the surrounding state reset and
active-build updates unchanged.

12-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the stale map key comment.

The map key was updated to just pool in a recent commit to prevent cardinality leaks, but the comment still references pool/buildName.

♻️ Proposed refactor
-// pushStartTimes stores the time each image push began, keyed by "pool/buildName".
+// pushStartTimes stores the time each image push began, keyed by pool name.
 // Used to compute push duration across separate AddJob and UpdateJob reconciler events.
🤖 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 `@pkg/controller/build/ocl_metrics.go` around lines 12 - 13, Update the comment
for pushStartTimes to state that entries are keyed only by pool, removing the
stale pool/buildName description while retaining its purpose for tracking push
duration across reconciler events.
🤖 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 `@pkg/controller/build/ocl_metrics.go`:
- Around line 200-202: Clear stale pool-specific end-time metrics before
recording terminal build states: update RecordBuildCompleted at
pkg/controller/build/ocl_metrics.go#L200-L202, RecordBuildFailed at
pkg/controller/build/ocl_metrics.go#L217-L219, and RecordBuildInterrupted at
pkg/controller/build/ocl_metrics.go#L231-L233 to delete oclBuildEndTime partial
matches for the pool, preserving only the newest state’s end time.

---

Nitpick comments:
In `@pkg/controller/build/ocl_metrics.go`:
- Around line 174-183: Update RecordBuildStarted to use
oclBuildStartTime.WithLabelValues(pool).SetToCurrentTime() instead of manually
computing and setting a Unix timestamp; leave the surrounding state reset and
active-build updates unchanged.
- Around line 12-13: Update the comment for pushStartTimes to state that entries
are keyed only by pool, removing the stale pool/buildName description while
retaining its purpose for tracking push duration across reconciler events.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 193410f4-f5fa-4237-8bbf-c5e97de830e7

📥 Commits

Reviewing files that changed from the base of the PR and between f67564d and c2a7b48.

📒 Files selected for processing (5)
  • cmd/machine-os-builder/start.go
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics.go
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • cmd/machine-os-builder/start.go
  • install/0000_90_machine-config_01_prometheus-rules.yaml
  • pkg/controller/build/ocl_metrics_test.go
  • pkg/controller/build/reconciler.go

Comment on lines +200 to +202
// Clear previous states
oclBuildState.DeletePartialMatch(prometheus.Labels{"pool": pool})
pushStartTimes.Delete(pool)

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

Clear stale states from oclBuildEndTime.

When a build reaches a terminal state, the new end time is recorded with a state label (e.g., state="succeeded"). Because previous end states (like a prior failed build) are not cleared, a single pool will indefinitely accumulate and expose multiple end times for different states concurrently. This can lead to ambiguous or incorrect results in Prometheus queries that check the last completion time. Ensure only the most recent end time is preserved by deleting the partial match for the pool.

  • pkg/controller/build/ocl_metrics.go#L200-L202: Add oclBuildEndTime.DeletePartialMatch(prometheus.Labels{"pool": pool}) to RecordBuildCompleted.
  • pkg/controller/build/ocl_metrics.go#L217-L219: Add the same clearance to RecordBuildFailed.
  • pkg/controller/build/ocl_metrics.go#L231-L233: Add the same clearance to RecordBuildInterrupted.
📍 Affects 1 file
  • pkg/controller/build/ocl_metrics.go#L200-L202 (this comment)
  • pkg/controller/build/ocl_metrics.go#L217-L219
  • pkg/controller/build/ocl_metrics.go#L231-L233
🤖 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 `@pkg/controller/build/ocl_metrics.go` around lines 200 - 202, Clear stale
pool-specific end-time metrics before recording terminal build states: update
RecordBuildCompleted at pkg/controller/build/ocl_metrics.go#L200-L202,
RecordBuildFailed at pkg/controller/build/ocl_metrics.go#L217-L219, and
RecordBuildInterrupted at pkg/controller/build/ocl_metrics.go#L231-L233 to
delete oclBuildEndTime partial matches for the pool, preserving only the newest
state’s end time.

@eric200428

Copy link
Copy Markdown
Contributor Author

/retest

@eric200428

Copy link
Copy Markdown
Contributor Author

/pipeline required

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-upgrade
/test e2e-gcp-op-ocl-part1
/test e2e-gcp-op-ocl-part2
/test e2e-gcp-op-part1
/test e2e-gcp-op-part2
/test e2e-gcp-op-single-node
/test e2e-hypershift

@isabella-janssen

Copy link
Copy Markdown
Member

/hold

Holding to allow the Kube rebase to land in #6321. Please ensure this will not cause merge conflicts for the Kube rebase before unholding this PR.

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 28, 2026
Comment thread pkg/controller/build/reconciler.go Outdated
}
}

UpdateOCLRolloutCounts(curMCP.Name, curMCP.Status.UpdatedMachineCount, curMCP.Status.MachineCount)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks like this will happen for every MCP update, we should limit it to only pools that have opted into layering

}

// RecordImagePushStarted records when a build job becomes active (image push begins).
func RecordImagePushStarted(pool string) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't see this being called anywhere in the code except of in tests.

severity: warning
annotations:
summary: "On-Cluster Layering build is degraded for pool {{ $labels.pool }}"
description: "OCL build {{ $labels.build_name }} for MachineConfigPool {{ $labels.pool }} is in a persistent failed state. Check the MachineOSBuild {{ $labels.build_name }} status conditions and machine-os-builder pod logs."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@eric200428

Copy link
Copy Markdown
Contributor Author

/retest

@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@eric200428: 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

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants