Skip to content

Conversation

@lllamnyp
Copy link
Member

@lllamnyp lllamnyp commented Dec 12, 2025

What this PR does

This adds custom indexable fields on core backup resources to enable filtering by backed-up application. This will later be useful for displaying backup resources in the dashboard: it will be possible to filter them with a field selector to display only those backup resources that are relevant to a given application.

Release note

[backups] Enable filtering backup resources by backed up application for
per-app views of backups.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced new Backup, BackupJob, Plan, and RestoreJob API resources for enhanced backup management.
    • Added selectable fields to backup resources, enabling efficient filtering and querying by application reference.
    • Added status subresource with conditions to Plan resources for improved status tracking and observability.
  • Chores

    • Updated repository metadata configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

## What this PR does

This adds custom indexable fields on core backup resources to enable
filtering by backed-up application. This will later be useful for
displaying backup resources in the dashboard: it will be possible to
filter them with a field selector to display only those backup resources
that are relevant to a given application.

### Release note

```release-note
[backups] Enable filtering backup resources by backed up application for
per-app views of backups.
```

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Dec 12, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

This pull request introduces Kubernetes API type definitions for backup management resources (Backup, BackupJob, Plan, RestoreJob) with corresponding scheme registration, deep copy support, and CRD schema definitions including selectable fields and status subresources for enhanced resource querying and lifecycle management.

Changes

Cohort / File(s) Summary
API Type Registration & Initialization
api/backups/v1alpha1/backup_types.go, api/backups/v1alpha1/backupjob_types.go, api/backups/v1alpha1/plan_types.go, api/backups/v1alpha1/restorejob_types.go
Added init functions to register Backup, BackupJob, Plan, and RestoreJob types with SchemeBuilder. Introduced kubebuilder selectable field markers on applicationRef fields (apiGroup, kind, name) across BackupJob and Plan types for per-application resource indexing.
Scheme Builder Initialization
api/backups/v1alpha1/groupversion_info.go
Changed SchemeBuilder construction from addKnownTypes to addGroupVersion for updated type registration path.
Deep Copy Support
api/backups/v1alpha1/zz_generated.deepcopy.go
Added DeepCopyInto and DeepCopy methods for PlanStatus. Updated Plan.DeepCopyInto to deep-copy Status field with proper condition slice handling.
CRD Schema Definitions — Selectable Fields
packages/system/backup-controller/definitions/backups.cozystack.io_backups.yaml, packages/system/backup-controller/definitions/backups.cozystack.io_backupjobs.yaml
Added selectableFields array to CRD schemas with jsonPath entries for applicationRef.apiGroup, applicationRef.kind, and applicationRef.name to enable field-based querying.
CRD Schema Definitions — Status Subresource
packages/system/backup-controller/definitions/backups.cozystack.io_plans.yaml
Added status subresource endpoint, introduced status field with Conditions array (including lastTransitionTime, message, observedGeneration, reason, status, type), and added selectableFields for plan-level resource querying.
Git Configuration
packages/system/backup-controller/definitions/.gitattributes
Updated linguist classification to exclude .gitattributes from generated-file marking.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25–30 minutes

  • Scheme builder migration (groupversion_info.go): Verify correctness of addGroupVersion registration path and completeness of type handling.
  • Status subresource schema (backups.cozystack.io_plans.yaml): Validate condition structure, required fields, and proper subresource declaration for status endpoint functionality.
  • Repetitive init functions across type files: Confirm all types are correctly registered and no duplicate or missing registrations exist across the four type files.
  • Generated deep copy methods: Verify PlanStatus deep copy correctly handles Conditions slice and Plan.DeepCopyInto properly chains Status copy.

Poem

🐰 Five new types hop into the scheme,
With selectableFields to query the dream,
Plans now have status to track every state,
Deep copies ensure data stays true and first-rate,
The backup warren is ready—let's celebrate! 🎉

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[backups] Add indices to core backup resources' clearly and concisely summarizes the main change in this PR, which adds selectable/indexable fields to backup resource CRDs.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/update-backupjob-types

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @lllamnyp, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant improvement to how backup-related custom resources are managed and viewed. By adding indexable fields to Backup, BackupJob, and Plan based on their applicationRef, it lays the groundwork for advanced filtering capabilities. This change is primarily aimed at enhancing the user experience in dashboards, allowing for more intuitive and application-centric management of backup operations.

Highlights

  • Enhanced Filtering for Backup Resources: Custom indexable fields have been added to core backup resources (Backup, BackupJob, Plan) to enable filtering by the backed-up application. This will be crucial for displaying and managing backup resources in a dashboard with per-application views.
  • Kubebuilder Selectable Fields: The Backup, BackupJob, and Plan custom resource definitions (CRDs) now include kubebuilder:selectablefield markers for spec.applicationRef.apiGroup, spec.applicationRef.kind, and spec.applicationRef.name, allowing these fields to be used for filtering.
  • CRD Type Registration Refactoring: The mechanism for registering types with the SchemeBuilder has been refactored. Individual _types.go files now contain init() functions to register their respective types, simplifying groupversion_info.go.
  • Plan Status Subresource: The Plan CRD has been updated to include a status subresource, allowing for better tracking of the plan's current state and conditions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds custom indexable fields to core backup resources, which is a great feature for improving filterability in the dashboard. The refactoring to move type registration into individual type files is a good architectural improvement, making the API definitions more modular.

I've found a couple of areas for potential improvement:

  • The comments for exported variables in groupversion_info.go were removed. It would be good to restore them for better code documentation.
  • For consistency, RestoreJob could also be made filterable by its target application.

Additionally, it seems this PR also fixes a bug where the Plan.Status field was not being correctly deep-copied, which is an excellent correction. Overall, solid changes.

Comment on lines +29 to +31
GroupVersion = schema.GroupVersion{Group: "backups.cozystack.io", Version: "v1alpha1"}
SchemeBuilder = runtime.NewSchemeBuilder(addGroupVersion)
AddToScheme = SchemeBuilder.AddToScheme
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The comments for these exported variables were removed. While the new layout is more compact, the comments were valuable for documenting the purpose of these variables. Consider re-adding them as line comments to maintain documentation without sacrificing the compact format.

Suggested change
GroupVersion = schema.GroupVersion{Group: "backups.cozystack.io", Version: "v1alpha1"}
SchemeBuilder = runtime.NewSchemeBuilder(addGroupVersion)
AddToScheme = SchemeBuilder.AddToScheme
GroupVersion = schema.GroupVersion{Group: "backups.cozystack.io", Version: "v1alpha1"} // group version used to register these objects
SchemeBuilder = runtime.NewSchemeBuilder(addGroupVersion) // used to add go types to the GroupVersionKind scheme
AddToScheme = SchemeBuilder.AddToScheme // adds the types in this group-version to the given scheme

Comment on lines +40 to +42
// +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.apiGroup`
// +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.kind`
// +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.name`
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Adding these selectablefield annotations is a great improvement for filtering. For consistency across all backup-related resources, consider also adding similar annotations to the RestoreJob type. This would allow filtering RestoreJob resources by their target application via the .spec.targetApplicationRef field.

Copy link
Contributor

@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 (2)
api/backups/v1alpha1/backup_types.go (1)

95-100: Consider adding +kubebuilder:subresource:status marker.

The Backup type has a Status field, but there's no +kubebuilder:subresource:status marker. Without this, status updates require full resource writes instead of using the /status subresource endpoint. This is typically desired for types with a status to enable proper RBAC separation and optimistic concurrency on status updates.

 // The field indexing on applicationRef will be needed later to display per-app backup resources.

 // +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
 // +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.apiGroup`
 // +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.kind`
 // +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.name`
api/backups/v1alpha1/backupjob_types.go (1)

85-90: Consider adding +kubebuilder:subresource:status marker for consistency.

Similar to Backup, BackupJob has a Status field but lacks the status subresource marker. Adding it enables proper status update semantics via the /status endpoint.

 // The field indexing on applicationRef will be needed later to display per-app backup resources.

 // +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
 // +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.apiGroup`
 // +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.kind`
 // +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.name`
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10d3574 and 0f7bd3e.

📒 Files selected for processing (10)
  • api/backups/v1alpha1/backup_types.go (2 hunks)
  • api/backups/v1alpha1/backupjob_types.go (2 hunks)
  • api/backups/v1alpha1/groupversion_info.go (1 hunks)
  • api/backups/v1alpha1/plan_types.go (2 hunks)
  • api/backups/v1alpha1/restorejob_types.go (1 hunks)
  • api/backups/v1alpha1/zz_generated.deepcopy.go (2 hunks)
  • packages/system/backup-controller/definitions/.gitattributes (1 hunks)
  • packages/system/backup-controller/definitions/backups.cozystack.io_backupjobs.yaml (1 hunks)
  • packages/system/backup-controller/definitions/backups.cozystack.io_backups.yaml (1 hunks)
  • packages/system/backup-controller/definitions/backups.cozystack.io_plans.yaml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Use Controller-runtime patterns and kubebuilder style for Go code

Files:

  • api/backups/v1alpha1/zz_generated.deepcopy.go
  • api/backups/v1alpha1/plan_types.go
  • api/backups/v1alpha1/backupjob_types.go
  • api/backups/v1alpha1/groupversion_info.go
  • api/backups/v1alpha1/backup_types.go
  • api/backups/v1alpha1/restorejob_types.go
**/zz_generated.*.go

📄 CodeRabbit inference engine (AGENTS.md)

Do not edit auto-generated Go files matching pattern zz_generated.*.go

Files:

  • api/backups/v1alpha1/zz_generated.deepcopy.go
🧬 Code graph analysis (6)
api/backups/v1alpha1/zz_generated.deepcopy.go (1)
api/backups/v1alpha1/plan_types.go (1)
  • PlanStatus (96-98)
api/backups/v1alpha1/plan_types.go (2)
api/backups/v1alpha1/groupversion_info.go (2)
  • SchemeBuilder (30-30)
  • GroupVersion (29-29)
pkg/apiserver/apiserver.go (1)
  • Scheme (53-53)
api/backups/v1alpha1/backupjob_types.go (2)
api/backups/v1alpha1/groupversion_info.go (2)
  • SchemeBuilder (30-30)
  • GroupVersion (29-29)
pkg/apiserver/apiserver.go (1)
  • Scheme (53-53)
api/backups/v1alpha1/groupversion_info.go (1)
pkg/apiserver/apiserver.go (1)
  • Scheme (53-53)
api/backups/v1alpha1/backup_types.go (2)
api/backups/v1alpha1/groupversion_info.go (2)
  • SchemeBuilder (30-30)
  • GroupVersion (29-29)
pkg/apiserver/apiserver.go (1)
  • Scheme (53-53)
api/backups/v1alpha1/restorejob_types.go (2)
api/backups/v1alpha1/groupversion_info.go (2)
  • SchemeBuilder (30-30)
  • GroupVersion (29-29)
pkg/apiserver/apiserver.go (1)
  • Scheme (53-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (13)
packages/system/backup-controller/definitions/.gitattributes (1)

1-2: LGTM!

Good practice to mark generated CRD files as linguist-generated while explicitly excluding .gitattributes itself so it remains visible in PRs and diffs.

api/backups/v1alpha1/restorejob_types.go (1)

14-22: LGTM!

The scheme registration follows the correct controller-runtime pattern, consistently registering both the type and its list variant. The absence of selectableFields markers here is appropriate since RestoreJob references backups rather than applications directly.

api/backups/v1alpha1/backup_types.go (1)

14-22: LGTM!

Correct scheme registration pattern using SchemeBuilder.Register with AddKnownTypes.

api/backups/v1alpha1/groupversion_info.go (1)

28-37: LGTM!

The scheme registration follows the standard kubebuilder pattern:

  1. addGroupVersion registers the group version and standard metav1 types
  2. Individual type files use init() to register their specific types with SchemeBuilder.Register
  3. AddToScheme aggregates all registrations for use by controllers
api/backups/v1alpha1/backupjob_types.go (1)

14-22: LGTM!

Correct scheme registration pattern, consistent with other type files in this PR.

packages/system/backup-controller/definitions/backups.cozystack.io_backups.yaml (1)

233-236: No action needed. The optional apiGroup field in selectableFields is appropriate and aligns with Kubernetes standards. An empty or omitted apiGroup represents the core API group (/api/v1), which is valid Kubernetes semantics, not an edge case requiring special handling in field selector queries.

Likely an incorrect or invalid review comment.

api/backups/v1alpha1/plan_types.go (2)

11-11: LGTM: Runtime import added for scheme registration.

The import is necessary for the scheme registration logic added below.


14-22: LGTM: Scheme registration follows controller-runtime patterns.

The init function correctly registers Plan and PlanList types with the SchemeBuilder using the standard AddKnownTypes pattern.

packages/system/backup-controller/definitions/backups.cozystack.io_backupjobs.yaml (1)

230-233: LGTM: selectableFields correctly configured for BackupJob.

The selectableFields section correctly exposes the applicationRef subfields (apiGroup, kind, name) for field selector filtering, consistent with the PR objective to enable per-app filtering of backup resources.

api/backups/v1alpha1/zz_generated.deepcopy.go (1)

1-501: Auto-generated file - no review needed.

This file is auto-generated by controller-gen (as indicated by the header comment and filename pattern). Per the coding guidelines for **/zz_generated.*.go files, auto-generated files should not be edited or reviewed.

packages/system/backup-controller/definitions/backups.cozystack.io_plans.yaml (3)

133-191: LGTM: Status schema correctly defined with standard Conditions.

The status field schema follows Kubernetes conventions with a properly structured Conditions array, including all required fields and appropriate validation constraints.


193-196: LGTM: selectableFields correctly configured for Plan.

The selectableFields section correctly exposes the applicationRef subfields for field selector filtering, consistent with the BackupJob CRD and the PR objective.


199-200: LGTM: Status subresource properly enabled.

The status subresource configuration follows the standard Kubernetes pattern, allowing separate updates to the status field.

Comment on lines +36 to +42
// The field indexing on applicationRef will be needed later to display per-app backup resources.

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.apiGroup`
// +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.kind`
// +kubebuilder:selectablefield:JSONPath=`.spec.applicationRef.name`
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for field index setup for applicationRef fields in controller code

# Search for FieldIndexer or IndexField patterns
rg -nP -C5 'FieldIndexer|IndexField.*applicationRef' --type=go

# Also search for Plan reconciler setup
rg -nP -C5 'func.*SetupWithManager.*Plan' --type=go

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Find Plan-related controller files
find . -type f -name "*.go" | grep -i plan | head -20

# List the directory structure around the provided file
ls -la api/backups/v1alpha1/ 2>/dev/null || echo "Directory not found"

# Search more broadly for SetupWithManager implementations
rg -n "SetupWithManager" --type=go | head -20

# Search for any field index setup patterns across the codebase
rg -n "IndexField\|SetupIndexes" --type=go | head -20

Repository: cozystack/cozystack

Length of output: 3189


🏁 Script executed:

#!/bin/bash
# Read the PlanReconciler SetupWithManager method
sed -n '99,150p' internal/backupcontroller/plan_controller.go

# Also check the entire plan_controller.go file to look for any index setup
wc -l internal/backupcontroller/plan_controller.go
echo "---"
cat -n internal/backupcontroller/plan_controller.go | grep -i "index\|field"

Repository: cozystack/cozystack

Length of output: 356


🏁 Script executed:

#!/bin/bash
# Read the plan_types.go file to see the full context around lines 36-42
cat -n api/backups/v1alpha1/plan_types.go | head -50

Repository: cozystack/cozystack

Length of output: 1684


Add field indexes to the Plan controller to support efficient filtering by applicationRef subfields.

The kubebuilder selectablefield markers define JSONPath selectors for kubectl queries, but they require corresponding field indexes in the controller for efficient filtering. Add index setup in PlanReconciler.SetupWithManager() using mgr.GetFieldIndexer().IndexField() for .spec.applicationRef.apiGroup, .spec.applicationRef.kind, and .spec.applicationRef.name to support the "per-app backup resources" objective.

🤖 Prompt for AI Agents
In api/backups/v1alpha1/plan_types.go around lines 36-42 the kubebuilder
selectablefield markers were added for .spec.applicationRef.apiGroup,
.spec.applicationRef.kind and .spec.applicationRef.name but the Plan controller
lacks corresponding field indexes; update PlanReconciler.SetupWithManager() to
call mgr.GetFieldIndexer().IndexField(ctx, &Plan{},
"spec.applicationRef.apiGroup", func(obj client.Object) []string { ... }) (and
similarly for the two other paths) to extract and return the respective subfield
values, check and return any indexing errors, and ensure the index keys match
the JSONPath selectors so controller List/Watch filtering by those fields is
efficient.

@lllamnyp lllamnyp mentioned this pull request Dec 12, 2025
19 tasks
@lllamnyp lllamnyp enabled auto-merge December 12, 2025 13:21
@lllamnyp lllamnyp merged commit 1ec14d6 into main Dec 14, 2025
26 checks passed
@lllamnyp lllamnyp deleted the fix/update-backupjob-types branch December 14, 2025 00:04
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Dec 14, 2025
lllamnyp added a commit that referenced this pull request Jan 8, 2026
## What this PR does

This adds custom indexable fields on core backup resources to enable
filtering by backed-up application. This will later be useful for
displaying backup resources in the dashboard: it will be possible to
filter them with a field selector to display only those backup resources
that are relevant to a given application.

### Release note

```release-note
[backups] Enable filtering backup resources by backed up application for
per-app views of backups.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Introduced new Backup, BackupJob, Plan, and RestoreJob API resources
for enhanced backup management.
* Added selectable fields to backup resources, enabling efficient
filtering and querying by application reference.
* Added status subresource with conditions to Plan resources for
improved status tracking and observability.

* **Chores**
  * Updated repository metadata configuration.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

(cherry picked from commit 1ec14d6)
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
kvaps added a commit that referenced this pull request Jan 16, 2026
…d backup system (#1867)

## What this PR does

Update changelog for v1.0.0-alpha.1 to include missing features:
- **Cozystack Operator**: New operator for Package and PackageSource
management (#1740, #1741, #1755, #1756, #1760, #1761)
- **Backup System**: Comprehensive backup functionality with Velero
integration (#1640, #1685, #1687, #1708, #1719, #1720, #1737, #1762)
- Add @androndo to contributors
- Update Full Changelog link to v0.38.0...v1.0.0-alpha.1

### Release note

```release-note
[docs] Update changelog for v1.0.0-alpha.1: add cozystack-operator and backup system
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants