Skip to content

fix: clean up expired/deleted containerprofile time series database entries#338

Open
matthyx wants to merge 1 commit into
mainfrom
fix/expired-ts-profiles-zombies
Open

fix: clean up expired/deleted containerprofile time series database entries#338
matthyx wants to merge 1 commit into
mainfrom
fix/expired-ts-profiles-zombies

Conversation

@matthyx

@matthyx matthyx commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

This PR fixes a gap in the consolidation pipeline where expired time series profiles were not deleted from SQLite, leaving zombie records. It also purges time series records when container profiles are deleted via the REST API or cleanup walked paths.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed container profile expiration handling to ensure accurate completion status tracking.
    • Improved error handling during cleanup operations for container profile metadata deletion.
  • Improvements

    • Enhanced storage operations for consistent container profile identifier normalization across deletion workflows.
  • Tests

    • Added unit tests for expired container profile status update scenarios.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@matthyx, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 50 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 05371047-ffd7-4830-9bd3-cf25089343ec

📥 Commits

Reviewing files that changed from the base of the PR and between 242c325 and da6dde6.

📒 Files selected for processing (8)
  • pkg/registry/file/cleanup.go
  • pkg/registry/file/containerprofile_processor.go
  • pkg/registry/file/containerprofile_processor_test.go
  • pkg/registry/file/containerprofile_storage.go
  • pkg/registry/file/containerprofile_user_managed_test.go
  • pkg/registry/file/sqlite.go
  • pkg/registry/file/storage.go
  • pkg/registry/file/utils.go
📝 Walkthrough

Walkthrough

Adds ContainerProfileKindPlural, IsContainerProfileKind, and NormalizeContainerProfileKind helpers, then wires time-series cleanup into StorageImpl.delete, deleteMetadata, and cleanupNamespace for all containerprofile deletion paths. Refactors updateProfileStatus to branch explicitly on expired, producing Completed/Full or Completed/Partial outcomes with corresponding time-series data handling. Extends processor and user-managed tests accordingly.

Changes

ContainerProfile Time-Series Cleanup and Expired-Status Refactor

Layer / File(s) Summary
ContainerProfile kind constants and normalization helpers
pkg/registry/file/containerprofile_storage.go
Adds ContainerProfileKindPlural constant and exports IsContainerProfileKind and NormalizeContainerProfileKind used across all deletion and query paths.
Time-series cleanup wired into all deletion paths
pkg/registry/file/sqlite.go, pkg/registry/file/storage.go, pkg/registry/file/utils.go, pkg/registry/file/cleanup.go
NormalizeContainerProfileKind is applied inside DeleteTimeSeriesContainerEntries before the DELETE query. StorageImpl.delete detects containerprofile kinds and calls DeleteTimeSeriesContainerEntries. deleteMetadata now returns and propagates errors and also invokes DeleteTimeSeriesContainerEntries for containerprofile kinds. cleanupNamespace checks the error from deleteMetadata before dispatching watch events.
updateProfileStatus expired-branch refactor
pkg/registry/file/containerprofile_processor.go
Adds an explicit early branch for expired=true that sets Completed/Full with time-series deletion when the single-continuous-completed criterion is met, or Completed/Partial with data cleared otherwise. Removes the expired fallback from the switch default case so it unconditionally sets Learning. The helpers.Completed case now returns skipFurtherProcessing=false when the profile is already Completed/Full.
Tests
pkg/registry/file/containerprofile_processor_test.go, pkg/registry/file/containerprofile_user_managed_test.go
TestConsolidateData defers DB connection cleanup. Adds TestUpdateProfileStatusExpired and TestUpdateProfileStatusExpiredFull with a mockContainerProfileStorage asserting Completed/Partial and Completed/Full annotation outcomes plus DeleteTimeSeriesContainerEntries invocation. Adds writeTSEntryDirect helper and uses it in TestConsolidateUserManagedIdempotent to force second and third tick consolidation runs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hop, hop! The expired shelf
Gets sorted out all by itself—
Full or Partial, clear the row,
Time-series rows? Away they go!
No stale data left to keep,
The bunny's store is clean and neat. 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and clearly summarizes the main purpose: cleaning up expired/deleted containerprofile time series database entries, which aligns with the primary objective of removing orphaned records from SQLite during consolidation and deletion scenarios.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/expired-ts-profiles-zombies

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.

@matthyx matthyx force-pushed the fix/expired-ts-profiles-zombies branch from 9e6cf82 to ab45bcf Compare June 16, 2026 13:41

@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

🧹 Nitpick comments (1)
pkg/registry/file/sqlite.go (1)

289-291: ⚡ Quick win

Centralize container-profile kind normalization/matching in one helper.

The alias logic is now split across pkg/registry/file/sqlite.go, pkg/registry/file/storage.go, and pkg/registry/file/utils.go. Please extract shared helpers (for example, NormalizeContainerProfileKind + IsContainerProfileKind) and reuse them to avoid drift.

🤖 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/registry/file/sqlite.go` around lines 289 - 291, The container-profile
kind normalization logic (checking for "containerprofiles" and
"containerprofile-merged" aliases) is duplicated across multiple files:
sqlite.go, storage.go, and utils.go, creating maintenance risk and potential
drift. Extract shared helper functions such as NormalizeContainerProfileKind and
IsContainerProfileKind in a common location (likely utils.go), then replace all
instances of the kind alias logic throughout these files with calls to these
centralized helpers. This ensures consistent behavior and a single source of
truth for kind normalization.
🤖 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/registry/file/containerprofile_processor.go`:
- Around line 719-727: The early return with skipFurtherProcessing=true in the
ContainerProfileProcessor.updateProfileStatus function at the expired full-path
check prevents remaining series from being processed and added to the processed
set, which causes deleteProcessedTimeSeries to miss cleaning up TS profile
objects. Instead of returning true to skip further processing, return false to
allow the remaining series in the loop to complete their processing, ensuring
all series are properly tracked in the processed set so they can be fully
deleted later.

In `@pkg/registry/file/dynamicpathdetector/analyzer.go`:
- Around line 124-129: The fast-reject logic in the analyzer function does not
properly handle the root-protected prefix "/". When "/" is a protected prefix,
paths like "/etc" have topDir("/etc") = "/etc", which fails the pinAncestors
lookup and returns false prematurely, bypassing the descendant check that should
succeed. Ensure that when "/" is included as a protected prefix, it is properly
represented in the ua.pinAncestors map so that the fast-reject check does not
incorrectly exclude valid paths that should be protected as descendants of the
root. This may involve ensuring "/" is added to pinAncestors during
initialization, or handling the root case specially in the pinAncestors lookup
logic.

In `@pkg/registry/file/storage.go`:
- Around line 376-382: The StorageImpl.delete method currently logs the error
from DeleteTimeSeriesContainerEntries but continues execution and returns
success, leaving orphaned data in the database. When the error check for
DeleteTimeSeriesContainerEntries fails in the containerprofile cleanup block,
return the error immediately instead of just logging it. This ensures callers
are aware the operation failed and can implement retry logic, preventing the API
from reporting a successful deletion when time-series cleanup is incomplete.

In `@pkg/registry/file/utils.go`:
- Around line 59-64: The error from DeleteTimeSeriesContainerEntries in the
containerprofile cleanup logic is being only logged without being propagated to
the caller, which prevents structured error handling and retry mechanisms.
Instead of just logging the error, return it from the deleteMetadata method so
that the caller can appropriately handle the failure, implement retries, or
signal that the cleanup operation did not fully succeed. This ensures orphaned
time-series rows are not silently left behind without a path to recovery.

---

Nitpick comments:
In `@pkg/registry/file/sqlite.go`:
- Around line 289-291: The container-profile kind normalization logic (checking
for "containerprofiles" and "containerprofile-merged" aliases) is duplicated
across multiple files: sqlite.go, storage.go, and utils.go, creating maintenance
risk and potential drift. Extract shared helper functions such as
NormalizeContainerProfileKind and IsContainerProfileKind in a common location
(likely utils.go), then replace all instances of the kind alias logic throughout
these files with calls to these centralized helpers. This ensures consistent
behavior and a single source of truth for kind normalization.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ed35a624-9a09-46c1-80d9-b99033190c2e

📥 Commits

Reviewing files that changed from the base of the PR and between 54669a0 and 9e6cf82.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (16)
  • go.mod
  • main.go
  • pkg/apiserver/apiserver.go
  • pkg/cmd/server/start.go
  • pkg/config/config.go
  • pkg/registry/file/containerprofile_processor.go
  • pkg/registry/file/containerprofile_processor_test.go
  • pkg/registry/file/dynamicpathdetector/analyzer.go
  • pkg/registry/file/dynamicpathdetector/protection.go
  • pkg/registry/file/dynamicpathdetector/protection_test.go
  • pkg/registry/file/dynamicpathdetector/types.go
  • pkg/registry/file/openprotection.go
  • pkg/registry/file/openprotection_test.go
  • pkg/registry/file/sqlite.go
  • pkg/registry/file/storage.go
  • pkg/registry/file/utils.go

Comment thread pkg/registry/file/containerprofile_processor.go
Comment thread pkg/registry/file/dynamicpathdetector/analyzer.go Outdated
Comment thread pkg/registry/file/storage.go
Comment thread pkg/registry/file/utils.go
@matthyx matthyx force-pushed the fix/expired-ts-profiles-zombies branch from ab45bcf to 1cec3df Compare June 16, 2026 13:48
@matthyx matthyx requested a review from Copilot June 16, 2026 13:53

Copilot AI 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.

Pull request overview

This PR aims to prevent “zombie” SQLite time_series rows by cascading deletions when container profiles are removed (REST delete / cleanup walks) and by tightening consolidation behavior for expired time-series profiles.

Changes:

  • Cascade-delete time_series rows when container profile metadata/payload is deleted in storage and cleanup flows.
  • Normalize kind handling in DeleteTimeSeriesContainerEntries to match how time_series.kind is stored.
  • Update expired time-series consolidation to finalize status and clear consolidated series; add a unit test for the expired partial path.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/registry/file/utils.go Cleanup-walk metadata deletion now also deletes related time_series rows for container profiles.
pkg/registry/file/storage.go REST delete path now also deletes related time_series rows for container profiles.
pkg/registry/file/sqlite.go Adjusts DeleteTimeSeriesContainerEntries kind normalization before deleting time_series rows.
pkg/registry/file/containerprofile_storage.go Introduces a plural kind constant for container profiles.
pkg/registry/file/containerprofile_processor.go Refactors expired time-series status handling and adds deletion behavior in the completed/full path.
pkg/registry/file/containerprofile_processor_test.go Fixes connection handling in an existing test and adds a test for expired status finalization (partial).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/registry/file/storage.go Outdated
Comment thread pkg/registry/file/utils.go Outdated
Comment thread pkg/registry/file/sqlite.go Outdated
Comment thread pkg/registry/file/containerprofile_processor.go
@matthyx matthyx force-pushed the fix/expired-ts-profiles-zombies branch from 1cec3df to 5969768 Compare June 16, 2026 14:08
@matthyx matthyx requested a review from Copilot June 16, 2026 14:12

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread pkg/registry/file/storage.go
Comment thread pkg/registry/file/containerprofile_processor.go Outdated
Comment thread pkg/registry/file/containerprofile_processor.go
@matthyx matthyx force-pushed the fix/expired-ts-profiles-zombies branch from 5969768 to 242c325 Compare June 16, 2026 14:51
@matthyx matthyx requested a review from Copilot June 16, 2026 14:54

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment thread pkg/registry/file/containerprofile_processor.go
Comment thread pkg/registry/file/cleanup.go
@github-actions

Copy link
Copy Markdown

Summary:

  • License scan: failure
  • Credentials scan: failure
  • Vulnerabilities scan: failure
  • Unit test: success
  • Go linting: failure

…ntries

Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
@matthyx matthyx force-pushed the fix/expired-ts-profiles-zombies branch from 242c325 to da6dde6 Compare June 16, 2026 15:13
@github-actions

Copy link
Copy Markdown

Summary:

  • License scan: failure
  • Credentials scan: failure
  • Vulnerabilities scan: failure
  • Unit test: success
  • Go linting: failure

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants