Skip to content

Conversation

@dobsonj
Copy link
Member

@dobsonj dobsonj commented Jan 24, 2026

User description

https://issues.redhat.com/browse/STOR-2859

This PR introduces an API to disable force detach in kube-controller-manager. The design is based on this slack discussion (internal only). There is already a KubeControllerManager operator type to configure cluster-kube-controller-manager-operator, and this PR introduces a ControllerManager config type to configure kube-controller-manager. This is approach is consistent with other workload components like KubeAPIServer / APIServer and KubeScheduler / Scheduler.

controllerManager.spec.forceDetachOnTimeout will be used to enable or disable force detach in KCM.

/cc @openshift/storage


PR Type

Enhancement


Description

  • Add ControllerManager API for cluster-wide Kubernetes controller manager configuration

  • Introduce ForceDetachOnTimeoutPolicy to control volume force detach behavior

  • Generate deepcopy, swagger documentation, and OpenAPI schema definitions

  • Create CustomResourceDefinition manifest for controllermanagers resource


Diagram Walkthrough

flowchart LR
  A["ControllerManager API Type"] --> B["ForceDetachOnTimeoutPolicy"]
  A --> C["ControllerManagerSpec"]
  A --> D["ControllerManagerStatus"]
  C --> E["forceDetachOnTimeout Field"]
  E --> F["Enabled/Disabled/Omitted"]
  A --> G["Generated Code"]
  G --> H["DeepCopy Functions"]
  G --> I["Swagger Documentation"]
  G --> J["OpenAPI Schemas"]
  A --> K["CRD Manifest"]
Loading

File Walkthrough

Relevant files
Enhancement
types_controllermanager.go
Define ControllerManager API types and policy                       

config/v1/types_controllermanager.go

  • Define new ControllerManager struct with metadata, spec, and status
    fields
  • Create ControllerManagerSpec with ForceDetachOnTimeoutPolicy field
  • Define ForceDetachOnTimeoutPolicy type with Enabled and Disabled
    constants
  • Create ControllerManagerList struct for list operations
+72/-0   
Code generation
zz_generated.deepcopy.go
Generate deepcopy functions for ControllerManager types   

config/v1/zz_generated.deepcopy.go

  • Generate DeepCopyInto, DeepCopy, and DeepCopyObject methods for
    ControllerManager
  • Generate deepcopy methods for ControllerManagerList
  • Generate deepcopy methods for ControllerManagerSpec
  • Generate deepcopy methods for ControllerManagerStatus
+93/-0   
zz_generated.swagger_doc_generated.go
Generate swagger documentation for ControllerManager         

config/v1/zz_generated.swagger_doc_generated.go

  • Add swagger documentation map for ControllerManager type
  • Add swagger documentation map for ControllerManagerList type
  • Add swagger documentation map for ControllerManagerSpec type
  • Document field descriptions and compatibility level
+28/-0   
zz_generated.openapi.go
Generate OpenAPI schema definitions for ControllerManager

openapi/generated_openapi/zz_generated.openapi.go

  • Register OpenAPI schema definitions for ControllerManager,
    ControllerManagerList, ControllerManagerSpec, and
    ControllerManagerStatus
  • Generate schema_openshift_api_config_v1_ControllerManager function
    with properties and dependencies
  • Generate schema_openshift_api_config_v1_ControllerManagerList function
    with items array
  • Generate schema_openshift_api_config_v1_ControllerManagerSpec and
    ControllerManagerStatus schema functions
+135/-0 
Configuration
0000_10_config-operator_01_controllermanagers.crd.yaml
Create ControllerManager CustomResourceDefinition manifest

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_controllermanagers.crd.yaml

  • Create CustomResourceDefinition manifest for
    controllermanagers.config.openshift.io
  • Define spec with forceDetachOnTimeout property supporting Enabled,
    Disabled, and empty string values
  • Configure cluster-scoped resource with status subresource
  • Include bootstrap-required annotation and API approval reference
+73/-0   
zz_generated.featuregated-crd-manifests.yaml
Register ControllerManager in featuregated manifests         

config/v1/zz_generated.featuregated-crd-manifests.yaml

  • Add controllermanagers.config.openshift.io entry to featuregated CRD
    manifests
  • Register metadata including operator name, run level, and scope
    information
  • Mark as bootstrap-required and ungated feature
+22/-0   
AAA_ungated.yaml
Create ungated ControllerManager CRD manifest                       

config/v1/zz_generated.featuregated-crd-manifests/controllermanagers.config.openshift.io/AAA_ungated.yaml

  • Create ungated CustomResourceDefinition manifest for
    controllermanagers resource
  • Define identical schema to main CRD manifest with feature-gate
    annotations
  • Configure cluster scope with status subresource and bootstrap
    requirement
+74/-0   

@openshift-ci-robot
Copy link

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 Jan 24, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 24, 2026

@dobsonj: This pull request references STOR-2859 which is a valid jira issue.

Details

In response to this:

https://issues.redhat.com/browse/STOR-2859

/cc @openshift/storage

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.

@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 Jan 24, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 24, 2026

Hello @dobsonj! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 24, 2026

@dobsonj: GitHub didn't allow me to request PR reviews from the following users: openshift/storage.

Note that only openshift members and repo collaborators can review this PR, and authors cannot review their own PRs.

Details

In response to this:

https://issues.redhat.com/browse/STOR-2859

/cc @openshift/storage

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.

@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

📝 Walkthrough

Walkthrough

Adds a new cluster-scoped ControllerManager API under config/v1, introducing types: ControllerManager, ControllerManagerSpec (with ForceDetachOnTimeoutPolicy and constants ForceDetachOnTimeoutEnabled/ForceDetachOnTimeoutDisabled), ControllerManagerStatus, and ControllerManagerList. Adds autogenerated deepcopy methods, SwaggerDoc mappings, and OpenAPI schema functions for these types. Adds a feature-gated CRD manifest entry for controllermanagers.config.openshift.io and a packaged CRD YAML at payload-manifests/crds/0000_10_config-operator_01_controllermanagers.crd.yaml.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is directly related to the changeset, clearly explaining the purpose (disabling force detach in KCM), the new ControllerManager API type, and implementation approach consistent with similar workload components.
Title check ✅ Passed The title clearly and concisely describes the main change: adding new APIs for the ControllerManager to support disabling force detach functionality, which aligns with all the file changes in the PR.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

@openshift-ci openshift-ci bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jan 24, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 24, 2026

@dobsonj: This pull request references STOR-2859 which is a valid jira issue.

Details

In response to this:

User description

https://issues.redhat.com/browse/STOR-2859

/cc @openshift/storage


PR Type

Enhancement


Description

  • Add ControllerManager API for cluster-wide Kubernetes controller manager configuration

  • Introduce ForceDetachOnTimeoutPolicy to control volume force detach behavior

  • Generate deepcopy, swagger documentation, and OpenAPI schema definitions

  • Create CustomResourceDefinition manifest for controllermanagers resource


Diagram Walkthrough

flowchart LR
 A["ControllerManager API Type"] --> B["ForceDetachOnTimeoutPolicy"]
 A --> C["ControllerManagerSpec"]
 A --> D["ControllerManagerStatus"]
 C --> E["forceDetachOnTimeout Field"]
 E --> F["Enabled/Disabled/Omitted"]
 A --> G["Generated Code"]
 G --> H["DeepCopy Functions"]
 G --> I["Swagger Documentation"]
 G --> J["OpenAPI Schemas"]
 A --> K["CRD Manifest"]
Loading

File Walkthrough

Relevant files
Enhancement
types_controllermanager.go
Define ControllerManager API types and policy                       

config/v1/types_controllermanager.go

  • Define new ControllerManager struct with metadata, spec, and status
    fields
  • Create ControllerManagerSpec with ForceDetachOnTimeoutPolicy field
  • Define ForceDetachOnTimeoutPolicy type with Enabled and Disabled
    constants
  • Create ControllerManagerList struct for list operations
+72/-0   
Code generation
zz_generated.deepcopy.go
Generate deepcopy functions for ControllerManager types   

config/v1/zz_generated.deepcopy.go

  • Generate DeepCopyInto, DeepCopy, and DeepCopyObject methods for
    ControllerManager
  • Generate deepcopy methods for ControllerManagerList
  • Generate deepcopy methods for ControllerManagerSpec
  • Generate deepcopy methods for ControllerManagerStatus
+93/-0   
zz_generated.swagger_doc_generated.go
Generate swagger documentation for ControllerManager         

config/v1/zz_generated.swagger_doc_generated.go

  • Add swagger documentation map for ControllerManager type
  • Add swagger documentation map for ControllerManagerList type
  • Add swagger documentation map for ControllerManagerSpec type
  • Document field descriptions and compatibility level
+28/-0   
zz_generated.openapi.go
Generate OpenAPI schema definitions for ControllerManager

openapi/generated_openapi/zz_generated.openapi.go

  • Register OpenAPI schema definitions for ControllerManager,
    ControllerManagerList, ControllerManagerSpec, and
    ControllerManagerStatus
  • Generate schema_openshift_api_config_v1_ControllerManager function
    with properties and dependencies
  • Generate schema_openshift_api_config_v1_ControllerManagerList function
    with items array
  • Generate schema_openshift_api_config_v1_ControllerManagerSpec and
    ControllerManagerStatus schema functions
+135/-0 
Configuration
0000_10_config-operator_01_controllermanagers.crd.yaml
Create ControllerManager CustomResourceDefinition manifest

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_controllermanagers.crd.yaml

  • Create CustomResourceDefinition manifest for
    controllermanagers.config.openshift.io
  • Define spec with forceDetachOnTimeout property supporting Enabled,
    Disabled, and empty string values
  • Configure cluster-scoped resource with status subresource
  • Include bootstrap-required annotation and API approval reference
+73/-0   
zz_generated.featuregated-crd-manifests.yaml
Register ControllerManager in featuregated manifests         

config/v1/zz_generated.featuregated-crd-manifests.yaml

  • Add controllermanagers.config.openshift.io entry to featuregated CRD
    manifests
  • Register metadata including operator name, run level, and scope
    information
  • Mark as bootstrap-required and ungated feature
+22/-0   
AAA_ungated.yaml
Create ungated ControllerManager CRD manifest                       

config/v1/zz_generated.featuregated-crd-manifests/controllermanagers.config.openshift.io/AAA_ungated.yaml

  • Create ungated CustomResourceDefinition manifest for
    controllermanagers resource
  • Define identical schema to main CRD manifest with feature-gate
    annotations
  • Configure cluster scope with status subresource and bootstrap
    requirement
+74/-0   

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.

1 similar comment
@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 24, 2026

@dobsonj: This pull request references STOR-2859 which is a valid jira issue.

Details

In response to this:

User description

https://issues.redhat.com/browse/STOR-2859

/cc @openshift/storage


PR Type

Enhancement


Description

  • Add ControllerManager API for cluster-wide Kubernetes controller manager configuration

  • Introduce ForceDetachOnTimeoutPolicy to control volume force detach behavior

  • Generate deepcopy, swagger documentation, and OpenAPI schema definitions

  • Create CustomResourceDefinition manifest for controllermanagers resource


Diagram Walkthrough

flowchart LR
 A["ControllerManager API Type"] --> B["ForceDetachOnTimeoutPolicy"]
 A --> C["ControllerManagerSpec"]
 A --> D["ControllerManagerStatus"]
 C --> E["forceDetachOnTimeout Field"]
 E --> F["Enabled/Disabled/Omitted"]
 A --> G["Generated Code"]
 G --> H["DeepCopy Functions"]
 G --> I["Swagger Documentation"]
 G --> J["OpenAPI Schemas"]
 A --> K["CRD Manifest"]
Loading

File Walkthrough

Relevant files
Enhancement
types_controllermanager.go
Define ControllerManager API types and policy                       

config/v1/types_controllermanager.go

  • Define new ControllerManager struct with metadata, spec, and status
    fields
  • Create ControllerManagerSpec with ForceDetachOnTimeoutPolicy field
  • Define ForceDetachOnTimeoutPolicy type with Enabled and Disabled
    constants
  • Create ControllerManagerList struct for list operations
+72/-0   
Code generation
zz_generated.deepcopy.go
Generate deepcopy functions for ControllerManager types   

config/v1/zz_generated.deepcopy.go

  • Generate DeepCopyInto, DeepCopy, and DeepCopyObject methods for
    ControllerManager
  • Generate deepcopy methods for ControllerManagerList
  • Generate deepcopy methods for ControllerManagerSpec
  • Generate deepcopy methods for ControllerManagerStatus
+93/-0   
zz_generated.swagger_doc_generated.go
Generate swagger documentation for ControllerManager         

config/v1/zz_generated.swagger_doc_generated.go

  • Add swagger documentation map for ControllerManager type
  • Add swagger documentation map for ControllerManagerList type
  • Add swagger documentation map for ControllerManagerSpec type
  • Document field descriptions and compatibility level
+28/-0   
zz_generated.openapi.go
Generate OpenAPI schema definitions for ControllerManager

openapi/generated_openapi/zz_generated.openapi.go

  • Register OpenAPI schema definitions for ControllerManager,
    ControllerManagerList, ControllerManagerSpec, and
    ControllerManagerStatus
  • Generate schema_openshift_api_config_v1_ControllerManager function
    with properties and dependencies
  • Generate schema_openshift_api_config_v1_ControllerManagerList function
    with items array
  • Generate schema_openshift_api_config_v1_ControllerManagerSpec and
    ControllerManagerStatus schema functions
+135/-0 
Configuration
0000_10_config-operator_01_controllermanagers.crd.yaml
Create ControllerManager CustomResourceDefinition manifest

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_controllermanagers.crd.yaml

  • Create CustomResourceDefinition manifest for
    controllermanagers.config.openshift.io
  • Define spec with forceDetachOnTimeout property supporting Enabled,
    Disabled, and empty string values
  • Configure cluster-scoped resource with status subresource
  • Include bootstrap-required annotation and API approval reference
+73/-0   
zz_generated.featuregated-crd-manifests.yaml
Register ControllerManager in featuregated manifests         

config/v1/zz_generated.featuregated-crd-manifests.yaml

  • Add controllermanagers.config.openshift.io entry to featuregated CRD
    manifests
  • Register metadata including operator name, run level, and scope
    information
  • Mark as bootstrap-required and ungated feature
+22/-0   
AAA_ungated.yaml
Create ungated ControllerManager CRD manifest                       

config/v1/zz_generated.featuregated-crd-manifests/controllermanagers.config.openshift.io/AAA_ungated.yaml

  • Create ungated CustomResourceDefinition manifest for
    controllermanagers resource
  • Define identical schema to main CRD manifest with feature-gate
    annotations
  • Configure cluster scope with status subresource and bootstrap
    requirement
+74/-0   

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.

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 24, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Optional field not omittable: ForceDetachOnTimeout is documented as optional/omittable but is a non-pointer field
without omitempty, so it will serialize as "" and cannot reliably represent
“omitted/no opinion.”

Referred Code
type ControllerManagerSpec struct {
	// ForceDetachOnTimeout allows the admin to enable or disable
	// force detaching volumes based on a timeout.
	// Valid values are Enabled, Disabled and omitted.
	// Omitted means no opinion and the platform is left to choose
	// a reasonable default, which is subject to change over time.
	// The current default is Enabled.
	// +optional
	ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout"`
}

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 24, 2026

[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 everettraven 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

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 24, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Consider if a new CRD is justified

The suggestion questions the creation of a new ControllerManager CRD for just a
single configuration field. It asks for justification, such as plans for future
additions, to validate introducing a new top-level API.

Examples:

config/v1/types_controllermanager.go [20-43]
type ControllerManager struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is the standard object's metadata.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	metav1.ObjectMeta `json:"metadata,omitempty"`
	// spec holds user settable values for configuration
	// +required
	Spec ControllerManagerSpec `json:"spec"`
	// status holds observed values from the cluster. They may not be overridden.

 ... (clipped 14 lines)

Solution Walkthrough:

Before:

// File: config/v1/types_controllermanager.go

// A new CRD is introduced
type ControllerManager struct {
  metav1.TypeMeta   `json:",inline"`
  metav1.ObjectMeta `json:"metadata,omitempty"`
  Spec ControllerManagerSpec `json:"spec"`
  Status ControllerManagerStatus `json:"status"`
}

// The spec for the new CRD contains only one field
type ControllerManagerSpec struct {
  ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout"`
}

type ControllerManagerStatus struct {}

After:

// The suggestion implies that instead of a new CRD,
// the new field could be added to an existing, related CRD.
// For example (conceptual):

// File: config/v1/types_some_existing_crd.go

type SomeExistingCRDSpec struct {
  // ... existing fields ...

  // The new field is added here, avoiding a new CRD
  ControllerManager ControllerManagerConfig `json:"controllerManager,omitempty"`
}

type ControllerManagerConfig struct {
    ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout,omitempty"`
}
Suggestion importance[1-10]: 8

__

Why: The suggestion raises a critical API design question about the justification for creating an entirely new CRD for a single configuration field, which has long-term implications for the API surface and maintainability.

Medium
General
Add conditions field to status

Add a Conditions field of type []metav1.Condition to the ControllerManagerStatus
struct to align with Kubernetes API best practices for status reporting.

config/v1/types_controllermanager.go [57-58]

 type ControllerManagerStatus struct {
+	// conditions provide details on the status of the controller manager configuration.
+	// +optional
+	Conditions []metav1.Condition `json:"conditions,omitempty"`
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly recommends adding a standard conditions field to the status struct, which is a Kubernetes API best practice that improves extensibility and observability.

Medium
Possible issue
Omit empty JSON field
Suggestion Impact:The commit updated the `ForceDetachOnTimeout` field JSON tag from `json:"forceDetachOnTimeout"` to `json:"forceDetachOnTimeout,omitempty"`, omitting the field when empty.

code diff:

-	// ForceDetachOnTimeout allows the admin to enable or disable
-	// force detaching volumes based on a timeout.
-	// Valid values are Enabled, Disabled and omitted.
-	// Omitted means no opinion and the platform is left to choose
-	// a reasonable default, which is subject to change over time.
-	// The current default is Enabled.
+	// forceDetachOnTimeout expresses whether to allow kube-controller-manager
+	// to force detach volumes when unmount takes longer than the timeout.
+	// Valid values are Enabled and Disabled. If omitted, the default is Enabled.
+	// +default=Enabled
 	// +optional
-	ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout"`
+	ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout,omitempty"`
 }

Add omitempty to the json tag of the forceDetachOnTimeout field.

config/v1/types_controllermanager.go [41-42]

 // +optional
-ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout"`
+ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout,omitempty"`

[Suggestion processed]

Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that an optional field is missing omitempty in its JSON tag, and adding it aligns with Kubernetes API best practices for cleaner resource definitions.

Low
  • Update

Copy link

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

🤖 Fix all issues with AI agents
In `@config/v1/types_controllermanager.go`:
- Around line 12-15: The +openshift:api-approved annotation in the header
comment of types_controllermanager.go still uses the placeholder URL
"https://github.com/openshift/api/pull/XYZ"; update that annotation to the
actual API approval PR URL (the real pull request number) so it passes API
approval checks—locate the comment block containing
"+openshift:api-approved.openshift.io" and replace the placeholder with the real
PR link.

In `@config/v1/zz_generated.featuregated-crd-manifests.yaml`:
- Around line 199-203: Update the placeholder ApprovedPRNumber value for the CRD
entry with CRDName controllermanagers.config.openshift.io: replace
"https://github.com/openshift/api/pull/XYZ" with the real approval PR URL (or
the correct PR number path) so the ApprovedPRNumber field references the actual
merged/approved PR; ensure the URL is valid and points to the final PR in the
openshift/api repo.
🧹 Nitpick comments (1)
config/v1/types_controllermanager.go (1)

34-42: Add omitempty to the optional enum field for consistency.

ForceDetachOnTimeout is marked optional and should use omitempty in its JSON tag, consistent with other optional enum fields throughout the config/v1 API group (e.g., Platform, CgroupMode, WorkerLatencyProfile). This keeps manifests clean by omitting the field when unset.

♻️ Proposed change
-	ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout"`
+	ForceDetachOnTimeout ForceDetachOnTimeoutPolicy `json:"forceDetachOnTimeout,omitempty"`

Copy link

@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

🤖 Fix all issues with AI agents
In
`@payload-manifests/crds/0000_10_config-operator_01_controllermanagers.crd.yaml`:
- Line 5: The api approval annotation api-approved.openshift.io currently
contains a placeholder URL ending with "XYZ"; replace that placeholder with the
actual GitHub PR URL for the OpenShift API approval (the final merged/approved
PR number), e.g. https://github.com/openshift/api/pull/<PR_NUMBER>, ensuring the
annotation value is a valid URL and kept as a single string on the
api-approved.openshift.io line in the CRD manifest so gating will recognize it.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 28, 2026
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 28, 2026
Copy link

@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

🤖 Fix all issues with AI agents
In `@config/v1/types_controllermanager.go`:
- Around line 58-61: The struct ControllerManagerStatus is empty but annotated
with +kubebuilder:validation:MinProperties=1 which makes an empty status
invalid; remove the +kubebuilder:validation:MinProperties=1 annotation from the
ControllerManagerStatus definition in types_controllermanager.go (or
alternatively add actual status fields to ControllerManagerStatus if you intend
to require properties) so that writing an empty {} status is valid.

Copy link

@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

🤖 Fix all issues with AI agents
In `@config/v1/types_controllermanager.go`:
- Around line 35-44: The kubebuilder markers on ControllerManagerSpec are not
being picked up by controller-gen: move/ensure the
`+kubebuilder:validation:MinProperties=1` marker is placed immediately above the
`type ControllerManagerSpec struct {` line (no blank comment gap) and replace
the incorrect `+default="Enabled"` with the kubebuilder form
`+kubebuilder:default=Enabled` (attach it immediately above the
`ForceDetachOnTimeout ForceDetachOnTimeoutPolicy` field or the field definition)
so controller-gen will emit the spec.minProperties and the default for
`ForceDetachOnTimeout`; then re-run the CRD generation to verify the generated
CRD includes `minProperties` and the `default` value.
🧹 Nitpick comments (2)
config/v1/types_controllermanager.go (2)

29-32: Minor: JSON tag inconsistencies.

  • Line 29: Spec is marked +required but uses omitzero, which could omit the spec from serialized output if it's a zero value. Consider using omitempty for consistency with typical Kubernetes API patterns, or verify this is the intended behavior.
  • Line 32: omitempty,omitzero is redundant—omitzero (Go 1.24+) subsumes omitempty for struct types.

49-56: Use const instead of var for policy constants.

These are immutable enum-like values that should not be modifiable at runtime. Declaring them as const is idiomatic Go and provides compile-time immutability guarantees.

♻️ Proposed fix
-var (
+const (
 	// ForceDetachOnTimeoutEnabled will allow kube-controller-manager to
 	// force detach volumes based on maximum unmount time and node status.
-	ForceDetachOnTimeoutEnabled  ForceDetachOnTimeoutPolicy = "Enabled"
+	ForceDetachOnTimeoutEnabled ForceDetachOnTimeoutPolicy = "Enabled"
 	// ForceDetachOnTimeoutDisabled will prevent kube-controller-manager
 	// from force detaching volumes.
 	ForceDetachOnTimeoutDisabled ForceDetachOnTimeoutPolicy = "Disabled"
 )

Copy link

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

🤖 Fix all issues with AI agents
In `@openapi/generated_openapi/zz_generated.openapi.go`:
- Around line 12445-12452: The generated OpenAPI schema for the field
forceDetachOnTimeout is missing the Enum constraint; regenerate the OpenAPI
output so the SchemaProps for forceDetachOnTimeout includes the Enum values
["Enabled","Disabled"] (the source type has
+kubebuilder:validation:Enum=Enabled;Disabled in types_controllermanager.go).
Re-run the project's OpenAPI generation task (the generator that produces
zz_generated.openapi.go), verify the SchemaProps.Enum for forceDetachOnTimeout
is populated with the two enum strings, and commit the updated
zz_generated.openapi.go so the generated schema matches the source annotation.

In
`@payload-manifests/crds/0000_10_config-operator_01_controllermanagers.crd.yaml`:
- Around line 61-65: The CRD's schema for the status subresource currently sets
"minProperties: 1" on the "status" object but no status properties are declared,
which will prune and reject updates; remove the "minProperties: 1" constraint
from the "status" schema (or alternatively declare the intended status fields
under "status" if you want to enforce at least one field) so status updates are
not rejected; locate the "status:" object in the controllermanagers CRD
definition and delete the "minProperties: 1" line (or add explicit status
property definitions) to fix the issue.

Copy link

@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

🤖 Fix all issues with AI agents
In
`@payload-manifests/crds/0000_10_config-operator_01_controllermanagers.crd.yaml`:
- Around line 46-60: Remove the minProperties: 1 constraint from the spec object
so the CRD no longer requires at least one property; specifically edit the spec
block that contains forceDetachOnTimeout (remove the minProperties: 1 line) to
make spec optional and consistent with other config-operator CRDs while leaving
the forceDetachOnTimeout property, its default, enum and description intact.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 28, 2026

@dobsonj: This pull request references STOR-2859 which is a valid jira issue.

Details

In response to this:

User description

https://issues.redhat.com/browse/STOR-2859

This PR introduces an API to disable force detach in kube-controller-manager. The design is based on this slack discussion (internal only). There is already a KubeControllerManager operator type to configure cluster-kube-controller-manager-operator, and this PR introduces a ControllerManager config type to configure kube-controller-manager. This is approach is consistent with other workload components like KubeAPIServer / APIServer and KubeScheduler / Scheduler.

controllerManager.spec.forceDetachOnTimeout will be used to enable or disable force detach in KCM.

/cc @openshift/storage


PR Type

Enhancement


Description

  • Add ControllerManager API for cluster-wide Kubernetes controller manager configuration

  • Introduce ForceDetachOnTimeoutPolicy to control volume force detach behavior

  • Generate deepcopy, swagger documentation, and OpenAPI schema definitions

  • Create CustomResourceDefinition manifest for controllermanagers resource


Diagram Walkthrough

flowchart LR
 A["ControllerManager API Type"] --> B["ForceDetachOnTimeoutPolicy"]
 A --> C["ControllerManagerSpec"]
 A --> D["ControllerManagerStatus"]
 C --> E["forceDetachOnTimeout Field"]
 E --> F["Enabled/Disabled/Omitted"]
 A --> G["Generated Code"]
 G --> H["DeepCopy Functions"]
 G --> I["Swagger Documentation"]
 G --> J["OpenAPI Schemas"]
 A --> K["CRD Manifest"]
Loading

File Walkthrough

Relevant files
Enhancement
types_controllermanager.go
Define ControllerManager API types and policy                       

config/v1/types_controllermanager.go

  • Define new ControllerManager struct with metadata, spec, and status
    fields
  • Create ControllerManagerSpec with ForceDetachOnTimeoutPolicy field
  • Define ForceDetachOnTimeoutPolicy type with Enabled and Disabled
    constants
  • Create ControllerManagerList struct for list operations
+72/-0   
Code generation
zz_generated.deepcopy.go
Generate deepcopy functions for ControllerManager types   

config/v1/zz_generated.deepcopy.go

  • Generate DeepCopyInto, DeepCopy, and DeepCopyObject methods for
    ControllerManager
  • Generate deepcopy methods for ControllerManagerList
  • Generate deepcopy methods for ControllerManagerSpec
  • Generate deepcopy methods for ControllerManagerStatus
+93/-0   
zz_generated.swagger_doc_generated.go
Generate swagger documentation for ControllerManager         

config/v1/zz_generated.swagger_doc_generated.go

  • Add swagger documentation map for ControllerManager type
  • Add swagger documentation map for ControllerManagerList type
  • Add swagger documentation map for ControllerManagerSpec type
  • Document field descriptions and compatibility level
+28/-0   
zz_generated.openapi.go
Generate OpenAPI schema definitions for ControllerManager

openapi/generated_openapi/zz_generated.openapi.go

  • Register OpenAPI schema definitions for ControllerManager,
    ControllerManagerList, ControllerManagerSpec, and
    ControllerManagerStatus
  • Generate schema_openshift_api_config_v1_ControllerManager function
    with properties and dependencies
  • Generate schema_openshift_api_config_v1_ControllerManagerList function
    with items array
  • Generate schema_openshift_api_config_v1_ControllerManagerSpec and
    ControllerManagerStatus schema functions
+135/-0 
Configuration
0000_10_config-operator_01_controllermanagers.crd.yaml
Create ControllerManager CustomResourceDefinition manifest

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_controllermanagers.crd.yaml

  • Create CustomResourceDefinition manifest for
    controllermanagers.config.openshift.io
  • Define spec with forceDetachOnTimeout property supporting Enabled,
    Disabled, and empty string values
  • Configure cluster-scoped resource with status subresource
  • Include bootstrap-required annotation and API approval reference
+73/-0   
zz_generated.featuregated-crd-manifests.yaml
Register ControllerManager in featuregated manifests         

config/v1/zz_generated.featuregated-crd-manifests.yaml

  • Add controllermanagers.config.openshift.io entry to featuregated CRD
    manifests
  • Register metadata including operator name, run level, and scope
    information
  • Mark as bootstrap-required and ungated feature
+22/-0   
AAA_ungated.yaml
Create ungated ControllerManager CRD manifest                       

config/v1/zz_generated.featuregated-crd-manifests/controllermanagers.config.openshift.io/AAA_ungated.yaml

  • Create ungated CustomResourceDefinition manifest for
    controllermanagers resource
  • Define identical schema to main CRD manifest with feature-gate
    annotations
  • Configure cluster scope with status subresource and bootstrap
    requirement
+74/-0   

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.

@dobsonj dobsonj changed the title [WIP] STOR-2859: Add APIs for disabling force detach in KCM operator STOR-2859: Add APIs for disabling force detach in KCM operator Jan 28, 2026
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 28, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 29, 2026

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

@dobsonj
Copy link
Member Author

dobsonj commented Jan 29, 2026

/cc @gnufied @ingvagabund
for reviews

@openshift-ci openshift-ci bot requested review from gnufied and ingvagabund January 29, 2026 00:58
@gnufied
Copy link
Member

gnufied commented Jan 29, 2026

So, this will introduce a new cluster object in the OCP clusters? Have we tested any POC with this change?

cc @JoelSpeed

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

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. Review effort 2/5 size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants