Skip to content

Fixing issue with OSV artifact cleanup on date boundaries#43408

Merged
ksykulev merged 1 commit intomainfrom
39900-date-bugfix
Apr 10, 2026
Merged

Fixing issue with OSV artifact cleanup on date boundaries#43408
ksykulev merged 1 commit intomainfrom
39900-date-bugfix

Conversation

@ksykulev
Copy link
Copy Markdown
Contributor

@ksykulev ksykulev commented Apr 10, 2026

Unreleased bug fix for #42063
Related issue: Resolves #39900

https://fleet-cm.sentry.io/issues/7397434783/?alert_rule_id=14022333&alert_timestamp=1775694137225&alert_type=email&notification_uuid=980228f0-4f9c-4ed1-8a88-9646b887b927&project=4504912025550848&referrer=alert_email
missing FleetError in chain: loading OSV artifact: finding OSV artifact for Ubuntu 2404: no OSV artifact found for Ubuntu 2404

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

  • Confirmed that the fix is not expected to adversely impact load test results
  • Alerted the release DRI if additional load testing is needed
    We shouldn't need any additional load testing. This change will not have a large impact on load.

@ksykulev ksykulev requested a review from a team as a code owner April 10, 2026 14:59
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Copilot AI review requested due to automatic review settings April 10, 2026 14:59
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

Walkthrough

The changes refine how the OSV downloader categorizes synchronization results. The SyncResult struct adds a new NotInRelease field to distinguish between two skip scenarios: Skipped now represents local files with matching checksums, while NotInRelease indicates Ubuntu versions without corresponding release assets. The syncOSVWithDownloader initialization and control flow are updated accordingly. Tests are modified to validate this distinction, including a new test for artifact cleanup at date boundaries and updated assertions in fault tolerance testing to expect errors and classify missing assets under NotInRelease.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Code changes address only a specific date boundary bug in artifact cleanup; they do not meaningfully advance the broader OSV migration objectives from #39900. The PR fixes a narrow cleanup bug but does not implement OSV data fetching, parsing, evaluation, or core migration features required by #39900. Clarify if this is an interim bugfix for an existing system, or document how it relates to the OSV transition roadmap.
Description check ⚠️ Warning PR description is minimal and lacks required sections from the template, including changes file, security/validation checks, database/config sections, and testing details. Complete the template by addressing: (1) Add a changes file for user-visible changes, (2) Describe input validation and security measures, (3) Address database migration checks if applicable, (4) Explicitly confirm manual QA was completed by checking the box.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the main change: fixing an OSV artifact cleanup bug occurring at date boundaries.
Out of Scope Changes check ✅ Passed Changes are narrowly focused on OSV artifact cleanup logic and are in scope for the bugfix, with no extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 39900-date-bugfix

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
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes an OSV artifact cleanup edge case at date boundaries by ensuring Ubuntu versions that are missing from the current release aren’t treated as “up to date” (which could trigger deletion of the last-known-good local artifact).

Changes:

  • Introduce SyncResult.NotInRelease to distinguish “missing in GitHub release” from checksum-based “Skipped”.
  • Update sync logic to classify missing assets as NotInRelease instead of Skipped.
  • Update/extend tests around sync fault tolerance and date-boundary cleanup behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
server/vulnerabilities/osv/sync_test.go Adds a new date-boundary test and updates expected sync result fields/error behavior.
server/vulnerabilities/osv/downloader.go Extends SyncResult and changes missing-release-asset handling to populate NotInRelease.

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

Comment on lines +136 to +143
// 2404 is in NotInRelease, not Skipped
// so removeOldOSVArtifacts should not touch it
err := removeOldOSVArtifacts(today, tmpDir, []string{})
require.NoError(t, err)

// Yesterday's artifact must still exist since the version wasn't in the successful set
_, err = os.Stat(filepath.Join(tmpDir, "osv-ubuntu-2404-2026-04-09.json.gz"))
require.NoError(t, err, "old artifact must be preserved when version is not in release")
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

This test doesn’t actually exercise the date-boundary scenario in the sync flow: it calls removeOldOSVArtifacts with an empty successfulVersions slice directly, so it would pass even if SyncOSV still classified missing release assets as “Skipped” (the original bug). Consider constructing a ReleaseInfo that lacks today’s asset, calling syncOSVWithDownloader for version 2404, building upToDateVersions from result.Downloaded+result.Skipped (as Refresh does), and then calling removeOldOSVArtifacts to assert yesterday’s artifact is preserved.

Suggested change
// 2404 is in NotInRelease, not Skipped
// so removeOldOSVArtifacts should not touch it
err := removeOldOSVArtifacts(today, tmpDir, []string{})
require.NoError(t, err)
// Yesterday's artifact must still exist since the version wasn't in the successful set
_, err = os.Stat(filepath.Join(tmpDir, "osv-ubuntu-2404-2026-04-09.json.gz"))
require.NoError(t, err, "old artifact must be preserved when version is not in release")
release := ReleaseInfo{
Assets: []ReleaseAsset{
{
Name: "osv-ubuntu-2204-2026-04-10.json.gz",
BrowserDownloadURL: "https://example.com/osv-ubuntu-2204-2026-04-10.json.gz",
},
},
}
downloader := func(_ context.Context, _, _ string) error {
return errors.New("downloader should not be called for a version missing from the release")
}
result, err := syncOSVWithDownloader(context.Background(), today, tmpDir, release, []string{"2404"}, downloader)
require.NoError(t, err)
require.Empty(t, result.Downloaded, "2404 should not be downloaded when today's asset is missing from the release")
require.Empty(t, result.Skipped, "2404 should not be marked skipped when today's asset is missing from the release")
require.Equal(t, []string{"2404"}, result.NotInRelease, "2404 should be classified as not in release")
upToDateVersions := append([]string{}, result.Downloaded...)
upToDateVersions = append(upToDateVersions, result.Skipped...)
err = removeOldOSVArtifacts(today, tmpDir, upToDateVersions)
require.NoError(t, err)
// Yesterday's artifact must still exist since the version was not treated as up-to-date.
_, err = os.Stat(filepath.Join(tmpDir, "osv-ubuntu-2404-2026-04-09.json.gz"))
require.NoError(t, err, "old artifact must be preserved when today's release asset is missing")

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.88%. Comparing base (ea9a335) to head (5ffa0f1).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #43408   +/-   ##
=======================================
  Coverage   66.88%   66.88%           
=======================================
  Files        2590     2590           
  Lines      207650   207651    +1     
  Branches     9202     9202           
=======================================
+ Hits       138892   138893    +1     
- Misses      56122    56123    +1     
+ Partials    12636    12635    -1     
Flag Coverage Δ
backend 68.67% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

if !ok {
// Artifact not available, skip
result.Skipped = append(result.Skipped, ubuntuVersion)
result.NotInRelease = append(result.NotInRelease, ubuntuVersion)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Making the distinction between File must exist locally AND checksum must match vs No file in the release that matches this criteria. The cleanup job needs to treat these differently.

@mostlikelee mostlikelee self-assigned this Apr 10, 2026
Copy link
Copy Markdown
Contributor

@mostlikelee mostlikelee left a comment

Choose a reason for hiding this comment

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

Nice, i think this also addresses an issue where local artifacts are deleted if there's an outage feeds can't be generated for a day.

@ksykulev ksykulev merged commit c8e9610 into main Apr 10, 2026
52 checks passed
@ksykulev ksykulev deleted the 39900-date-bugfix branch April 10, 2026 16:38
ksykulev added a commit that referenced this pull request Apr 10, 2026
Unreleased bug fix for #42063
**Related issue:** Resolves #39900

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

- [x] Confirmed that the fix is not expected to adversely impact load
test results
- [x] Alerted the release DRI if additional load testing is needed
We shouldn't need any additional load testing. This change will not have
a large impact on load.
ksykulev added a commit that referenced this pull request Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transition Fleet from OVAL to OSV feeds for Ubuntu vulnerabilities

3 participants