Skip to content

Phase 1 changes for MCS Firstboot Pivot Failure Reporting#6029

Draft
CourtCourt521 wants to merge 1 commit into
openshift:mainfrom
CourtCourt521:FirstBootPivotErrorReporting
Draft

Phase 1 changes for MCS Firstboot Pivot Failure Reporting#6029
CourtCourt521 wants to merge 1 commit into
openshift:mainfrom
CourtCourt521:FirstBootPivotErrorReporting

Conversation

@CourtCourt521
Copy link
Copy Markdown
Contributor

@CourtCourt521 CourtCourt521 commented May 12, 2026

- What I did

Testing not an actual pull request

- How to verify it

Testing not an actual pull request

- Description for the changelog

Testing not an actual pull request

Testing not an actual pull request

Summary by CodeRabbit

  • New Features

    • Added --mcs-url command-line flag to configure the Machine Config Server base URL for status reporting.
  • Chores

    • Updated bootstrap and cluster server configurations to support MCS URL parameter passing.
    • Updated deployment manifests to include MCS URL configuration in container arguments.
    • Extended node annotations to include configured Machine Config Server URL when provided.

@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 openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 12, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 12, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 12, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: CourtCourt521
Once this PR has been reviewed and has the lgtm label, please assign umohnani8 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
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Walkthrough

The PR adds support for passing a Machine Config Server (MCS) URL through the system to enable status reporting. A new --mcs-url CLI flag is introduced in bootstrap and start commands, the operator computes the URL from infrastructure status, servers store and use it to annotate nodes, and manifests pass the configuration to containers.

Changes

MCS URL Annotation Support and Server Contracts

Layer / File(s) Summary
Annotation key constant and server-side contracts
pkg/daemon/constants/constants.go, pkg/server/server.go, pkg/server/bootstrap_server.go, pkg/server/cluster_server.go
Adds MachineConfigServerURLAnnotationKey constant. Updates WithNodeAnnotations, appendNodeAnnotations, and getNodeAnnotation to accept and conditionally use mcsURL. NewBootstrapServer and NewClusterServer constructors now accept and store mcsURL.
Node annotation generation with MCS URL
pkg/server/server_test.go
TestBootstrapServer and TestClusterServer update getNodeAnnotation calls to include the hardcoded test MCS URL argument, validating the updated annotation generation logic.

Operator Infrastructure-to-URL Computation

Layer / File(s) Summary
Operator render config wiring
pkg/operator/render.go, pkg/operator/sync.go, pkg/operator/bootstrap.go
Adds MCSURL field to renderConfig struct. Updates getRenderConfig signature to accept mcsURL and assign it to the render config. Both syncRenderConfig and buildSpec compute mcsURL from the ignition host derived from infrastructure status and pass it to getRenderConfig.

CLI Flags and Manifest Configuration

Layer / File(s) Summary
Bootstrap and cluster server CLI integration
cmd/machine-config-server/bootstrap.go, cmd/machine-config-server/start.go
Adds mcsURL option field and --mcs-url persistent flag to both bootstrap and start commands. Updated server constructor calls pass bootstrapOpts.mcsURL and startOpts.mcsURL respectively.
Pod and daemonset manifest configuration
manifests/bootstrap-pod-v2.yaml, manifests/machineconfigserver/daemonset.yaml
Adds --mcs-url={{.MCSURL}} container argument to both bootstrap pod and machine-config-server daemonset to pass the configured URL to running services.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Phase 1 changes for MCS Firstboot Pivot Failure Reporting' accurately describes the main objective of the changeset, which introduces the foundational infrastructure for MCS URL-based status reporting in bootstrap and cluster servers.
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 custom check for stable test names applies only to Ginkgo tests. This repository uses Go's standard testing framework, not Ginkgo. No Ginkgo tests found.
Test Structure And Quality ✅ Passed Check not applicable. Custom check requires reviewing Ginkgo test code, but pkg/server/server_test.go uses standard Go testing.T, not Ginkgo. The check's requirements are Ginkgo-specific patterns.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. Only existing Go unit tests in pkg/server/server_test.go are updated. The check does not apply.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR does not add new Ginkgo e2e tests. Only standard Go unit tests in pkg/server/server_test.go were modified. The PR focuses on configuration and server code changes for MCS URL reporting.
Topology-Aware Scheduling Compatibility ✅ Passed No new scheduling constraints introduced. PR adds --mcs-url arguments and operator logic. No affinity, topology spread, replica changes, or nodeSelectors targeting control-plane.
Ote Binary Stdout Contract ✅ Passed No OTE stdout violations detected. PR adds --mcs-url flag without introducing stdout writes in process-level code. All logging properly configured to stderr via klog.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added. The modified test file is a standard Go unit test, not Ginkgo. Check does not apply.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 (3)
cmd/machine-config-server/bootstrap.go (1)

34-34: ⚡ Quick win

Consider validating the --mcs-url flag format.

Similar to the start command, the bootstrap command accepts any string value for --mcs-url without validating it's a well-formed URL. Adding basic URL validation when the flag is non-empty would improve robustness and prevent malformed URLs from being written to node annotations.

✨ Suggested validation approach
 func runBootstrapCmd(_ *cobra.Command, _ []string) {
 	flag.Set("logtostderr", "true")
 	flag.Parse()
 
+	if bootstrapOpts.mcsURL != "" {
+		if _, err := url.Parse(bootstrapOpts.mcsURL); err != nil {
+			klog.Exitf("--mcs-url is not a valid URL: %v", err)
+		}
+	}
+
 	// To help debugging, immediately log version
🤖 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 `@cmd/machine-config-server/bootstrap.go` at line 34, The bootstrap command
currently accepts any string for bootstrapOpts.mcsURL via
bootstrapCmd.PersistentFlags().StringVar; add validation so if
bootstrapOpts.mcsURL is non-empty you parse it (e.g., url.Parse) and ensure it
has a valid scheme (http or https) and a non-empty host, returning an error from
the command (RunE or a PreRun validation) when invalid; update the bootstrap
command to perform this check before proceeding to avoid storing malformed URLs
in node annotations.
pkg/server/server_test.go (1)

188-195: ⚡ Quick win

Consider adding explicit assertions for the mcsURL annotation.

The tests now pass a non-empty mcsURL to getNodeAnnotation, which should add the MachineConfigServerURLAnnotationKey to the generated annotations. While the tests validate the overall ignition structure (which includes the annotations file), they don't explicitly assert that the new annotation is present with the expected value.

Adding explicit assertions would improve test clarity and make it easier to catch regressions in this specific feature.

💡 Example assertion approach

After decoding the annotations JSON, add:

var annotations map[string]string
err = json.Unmarshal([]byte(anno), &annotations)
require.NoError(t, err)

assert.Equal(t, "https://api-int.test.example.com:22623", 
    annotations[daemonconsts.MachineConfigServerURLAnnotationKey],
    "MCS URL annotation should be present")

Also applies to: 383-390

🤖 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/server/server_test.go` around lines 188 - 195, Add explicit assertions
that the annotations returned by getNodeAnnotation include the
MachineConfigServerURLAnnotationKey with the expected mcsURL value; after
obtaining anno (used before appendFileToIgnition and referenced as mcIgnCfg),
unmarshal anno into a map[string]string and assert that
annotations[daemonconsts.MachineConfigServerURLAnnotationKey] equals
"https://api-int.test.example.com:22623". Apply the same check for the other
occurrence around lines 383-390 to ensure both test cases validate the presence
and value of the MCS URL annotation.
cmd/machine-config-server/start.go (1)

34-34: ⚡ Quick win

Consider validating the --mcs-url flag format.

The flag accepts any string value without validating it's a well-formed URL. While the operator typically generates this URL from infrastructure status, manual CLI invocation could provide a malformed URL that would be written to node annotations and cause status reporting failures.

Consider adding basic URL validation when the flag is non-empty to improve robustness.

✨ Suggested validation approach
 func runStartCmd(_ *cobra.Command, _ []string) {
 	flag.Set("logtostderr", "true")
 	flag.Parse()
 
+	if startOpts.mcsURL != "" {
+		if _, err := url.Parse(startOpts.mcsURL); err != nil {
+			klog.Exitf("--mcs-url is not a valid URL: %v", err)
+		}
+	}
+
 	// Initialize controller-runtime logger before any controller-runtime components are used
🤖 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 `@cmd/machine-config-server/start.go` at line 34, Add basic URL validation for
the --mcs-url flag value (startOpts.mcsURL) after it's parsed and before it's
used in status reporting: if startOpts.mcsURL is non-empty, parse it (e.g.,
using net/url's Parse or ParseRequestURI) and ensure it has a valid scheme
(http/https) and non-empty host; if validation fails return an error (or exit)
with a clear message so the process doesn't write a malformed URL to node
annotations. Place this check in the command initialization/run logic that
executes after startCmd.PersistentFlags().StringVar is parsed so it rejects
invalid values early.
🤖 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/operator/bootstrap.go`:
- Around line 150-157: The call to getIgnitionHost can panic because it indexes
APIServerInternalIPs[0] without verifying the slice length; update the
getIgnitionHost function to check that platform-specific APIServerInternalIPs
(or equivalent IP lists) are non-empty before indexing and return a clear error
if empty, and keep the existing error return path in the bootstrap caller (the
call site in bootstrap.go already checks err). Ensure the check covers all
platforms handled inside getIgnitionHost and that the returned error message
identifies the missing internal IP so the bootstrap render path can fail
gracefully instead of panicking.

---

Nitpick comments:
In `@cmd/machine-config-server/bootstrap.go`:
- Line 34: The bootstrap command currently accepts any string for
bootstrapOpts.mcsURL via bootstrapCmd.PersistentFlags().StringVar; add
validation so if bootstrapOpts.mcsURL is non-empty you parse it (e.g.,
url.Parse) and ensure it has a valid scheme (http or https) and a non-empty
host, returning an error from the command (RunE or a PreRun validation) when
invalid; update the bootstrap command to perform this check before proceeding to
avoid storing malformed URLs in node annotations.

In `@cmd/machine-config-server/start.go`:
- Line 34: Add basic URL validation for the --mcs-url flag value
(startOpts.mcsURL) after it's parsed and before it's used in status reporting:
if startOpts.mcsURL is non-empty, parse it (e.g., using net/url's Parse or
ParseRequestURI) and ensure it has a valid scheme (http/https) and non-empty
host; if validation fails return an error (or exit) with a clear message so the
process doesn't write a malformed URL to node annotations. Place this check in
the command initialization/run logic that executes after
startCmd.PersistentFlags().StringVar is parsed so it rejects invalid values
early.

In `@pkg/server/server_test.go`:
- Around line 188-195: Add explicit assertions that the annotations returned by
getNodeAnnotation include the MachineConfigServerURLAnnotationKey with the
expected mcsURL value; after obtaining anno (used before appendFileToIgnition
and referenced as mcIgnCfg), unmarshal anno into a map[string]string and assert
that annotations[daemonconsts.MachineConfigServerURLAnnotationKey] equals
"https://api-int.test.example.com:22623". Apply the same check for the other
occurrence around lines 383-390 to ensure both test cases validate the presence
and value of the MCS URL annotation.
🪄 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: f1f35220-fad5-4aec-94b8-29e7a568fbbc

📥 Commits

Reviewing files that changed from the base of the PR and between 99cb8a4 and 49e978d.

📒 Files selected for processing (12)
  • cmd/machine-config-server/bootstrap.go
  • cmd/machine-config-server/start.go
  • manifests/bootstrap-pod-v2.yaml
  • manifests/machineconfigserver/daemonset.yaml
  • pkg/daemon/constants/constants.go
  • pkg/operator/bootstrap.go
  • pkg/operator/render.go
  • pkg/operator/sync.go
  • pkg/server/bootstrap_server.go
  • pkg/server/cluster_server.go
  • pkg/server/server.go
  • pkg/server/server_test.go

Comment thread pkg/operator/bootstrap.go
Comment on lines +150 to +157
ignitionHost, err := getIgnitionHost(&dependencies.Infrastructure.Status)
if err != nil {
return nil, err
}
mcsURL := fmt.Sprintf("https://%s", ignitionHost)

config := getRenderConfig("", dependencies.KubeAPIServerServingCA, spec,
&imgs.RenderConfigImages, dependencies.Infrastructure, nil, nil, "2")
&imgs.RenderConfigImages, dependencies.Infrastructure, nil, nil, mcsURL, "2")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Guard getIgnitionHost against empty platform IP lists before bootstrap render.

Line 150 introduces a new bootstrap-time call path to getIgnitionHost, but that helper indexes APIServerInternalIPs[0] for some platforms without a length check. Empty lists will panic the render path.

Proposed hardening
--- a/pkg/operator/sync.go
+++ b/pkg/operator/sync.go
@@
 	if infraStatus.PlatformStatus != nil {
 		switch infraStatus.PlatformStatus.Type {
 		case configv1.BareMetalPlatformType:
-			ignitionHost = net.JoinHostPort(infraStatus.PlatformStatus.BareMetal.APIServerInternalIPs[0], securePortStr)
+			if infraStatus.PlatformStatus.BareMetal != nil && len(infraStatus.PlatformStatus.BareMetal.APIServerInternalIPs) > 0 {
+				ignitionHost = net.JoinHostPort(infraStatus.PlatformStatus.BareMetal.APIServerInternalIPs[0], securePortStr)
+			}
 		case configv1.OpenStackPlatformType:
-			ignitionHost = net.JoinHostPort(infraStatus.PlatformStatus.OpenStack.APIServerInternalIPs[0], securePortStr)
+			if infraStatus.PlatformStatus.OpenStack != nil && len(infraStatus.PlatformStatus.OpenStack.APIServerInternalIPs) > 0 {
+				ignitionHost = net.JoinHostPort(infraStatus.PlatformStatus.OpenStack.APIServerInternalIPs[0], securePortStr)
+			}
 		case configv1.OvirtPlatformType:
-			ignitionHost = net.JoinHostPort(infraStatus.PlatformStatus.Ovirt.APIServerInternalIPs[0], securePortStr)
+			if infraStatus.PlatformStatus.Ovirt != nil && len(infraStatus.PlatformStatus.Ovirt.APIServerInternalIPs) > 0 {
+				ignitionHost = net.JoinHostPort(infraStatus.PlatformStatus.Ovirt.APIServerInternalIPs[0], securePortStr)
+			}
🤖 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/operator/bootstrap.go` around lines 150 - 157, The call to
getIgnitionHost can panic because it indexes APIServerInternalIPs[0] without
verifying the slice length; update the getIgnitionHost function to check that
platform-specific APIServerInternalIPs (or equivalent IP lists) are non-empty
before indexing and return a clear error if empty, and keep the existing error
return path in the bootstrap caller (the call site in bootstrap.go already
checks err). Ensure the check covers all platforms handled inside
getIgnitionHost and that the returned error message identifies the missing
internal IP so the bootstrap render path can fail gracefully instead of
panicking.

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

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant