Repository navigation
Write a query and its labels in a single transaction - #51845
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. WalkthroughQuery creation and editing now persist query fields and labels in the same retryable transaction. New queries initialize packs after the transaction succeeds. Tests verify rollback when label writes fail, delivery only to matching hosts, and preservation of existing query data and labels after failed edits. Merge Risk: ⚪ Minimal · up to This localized change makes query and label updates atomic, preventing temporarily unscoped queries; no actionable merge-blocking risk remains beyond normal checks and review. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #51845 +/- ##
==========================================
- Coverage 69.81% 69.79% -0.02%
==========================================
Files 4071 4071
Lines 265492 265493 +1
Branches 14067 14067
==========================================
- Hits 185341 185294 -47
- Misses 63962 63995 +33
- Partials 16189 16204 +15
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A scheduled query with no query_labels rows targets every host, so committing the queries row before its labels briefly exposed a label-scoped query to all hosts polling /api/osquery/config. Their results were then stored in the query report without a scope check. NewQuery and SaveQuery now write the query row and its labels inside one withRetryTxx. deleteQueryStats and deleteQueryResults stay outside the transaction as before. Adds a datastore test that fails on the old code: a failed label write must roll back the query row instead of leaving an unscoped query behind. Fixes fleetdm#49502
88fed84 to
43075b7
Compare
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
This pull request fixes a race where label-scoped scheduled queries could be briefly visible to all hosts because the queries row and its query_labels rows were previously written in separate transactions. It makes query creation and updates atomic so out-of-scope hosts don’t ever observe an unscoped “global” scheduled query during host config polling.
Changes:
- Wrap
NewQueryinsert + label writes in a singlewithRetryTxxtransaction. - Wrap
SaveQueryupdate + label writes in a singlewithRetryTxxtransaction. - Add a datastore regression test ensuring failed label writes roll back both
NewQueryandSaveQuerychanges.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| server/datastore/mysql/queries.go | Makes NewQuery and SaveQuery write the query row and query_labels atomically via a single transaction. |
| server/datastore/mysql/queries_test.go | Adds QueryLabelsAtomic regression test covering rollback behavior and host scoping. |
| changes/49502-atomic-query-labels | Release note entry (content excluded from review by policy). |
Files excluded by content exclusion policy (1)
- changes/49502-atomic-query-labels
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // is visible before its labels are written) leaks a label-scoped query to | ||
| // out-of-scope hosts (#49502). | ||
| func testQueryLabelsAtomic(t *testing.T, ds *Datastore) { | ||
| ctx := context.Background() |
- Adds related issue (if any), and if any of the manual QA checkboxes were selected. - Adds a -v verbose mode that also outputs who is assigned to the PR, a full link, and tags from the related issue Examples: ``` jonathan@jonathans-macbook-pro:~/repos/fleet-2$ ./tools/oncall/oncall.sh prs 51893 2026-08-25T17:29:40Z tested prateek-0490 Batch scheduled query name lookups when processing result logs 51881 2026-08-25T16:25:40Z nonpunctual Include script for printer configuration from CSV 51845 2026-08-25T04:20:44Z 49502 tested rajendrachavan Write a query and its labels in a single transaction 51731 2026-08-21T19:49:52Z tested prateek-0490 Validate software list order keys against an allowlist 51583 2026-08-19T19:34:15Z tested prateek-0490 Require a team selection when validating report run targets 51338 2026-08-17T05:23:53Z 50846 Dhvanit41 Hide the toast details panel when the payload is empty 51265 2026-08-14T17:54:28Z tested prateek-0490 Expand host script variables via the environment 51241 2026-08-14T14:32:34Z 50336 tested andymFleet 50336 apple business stale fleet names 51178 2026-08-13T20:18:48Z moojomoore Add macOS unlock user account action 51119 2026-08-13T05:28:14Z 50882 Dhvanit41 Return an error when refetching an Android host 51020 2026-08-12T00:46:05Z 40092 sjawhar Support credentialProviderPolicy in Android app configuration 50943 2026-08-11T12:31:48Z 46773 tested surajtripathy07 Add software custom targets warning to delete label modal 50898 2026-08-10T19:26:08Z 45100 tianrking Recover vulnerability counts after interrupted table swaps 50836 2026-08-08T19:23:13Z 50300 tested kitarp29 Adding the logic to make controls even when it's empty 50822 2026-08-08T01:35:19Z tested viewer12 Add Nexus Shell as a macOS Fleet-maintained app 50774 2026-08-07T15:14:11Z 50357 tested Dhvanit41 Clear stale failure detail when an Android profile becomes verified 49816 2026-07-23T13:19:19Z tested sleepy-slothh Fix Ubuntu OSV binary package matching 43774 2026-04-20T15:46:23Z BCTBB Helm - Gateway API support ``` ``` jonathan@jonathans-macbook-pro:~/repos/fleet-2$ ./tools/oncall/oncall.sh prs -v 51893 2026-08-25T17:29:40Z tested prateek-0490 #51893 Batch scheduled query name lookups when processing result logs 51881 2026-08-25T16:25:40Z nonpunctual #51881 Include script for printer configuration from CSV 51845 2026-08-25T04:20:44Z 49502 tested rajendrachavan lucasmrod #51845 Write a query and its labels in a single transaction bug, ~backend, ~released bug, #g-orchestration 51731 2026-08-21T19:49:52Z tested prateek-0490 juan-fdz-hawa #51731 Validate software list order keys against an allowlist 51583 2026-08-19T19:34:15Z tested prateek-0490 juan-fdz-hawa #51583 Require a team selection when validating report run targets 51338 2026-08-17T05:23:53Z 50846 Dhvanit41 #51338 Hide the toast details panel when the payload is empty bug, ~frontend, ~released bug, #g-auto-patching 51265 2026-08-14T17:54:28Z tested prateek-0490 georgekarrv #51265 Expand host script variables via the environment 51241 2026-08-14T14:32:34Z 50336 tested andymFleet JordanMontgomery #51241 50336 apple business stale fleet names bug, ~released bug, #g-apple-at-work 51178 2026-08-13T20:18:48Z moojomoore #51178 Add macOS unlock user account action 51119 2026-08-13T05:28:14Z 50882 Dhvanit41 #51119 Return an error when refetching an Android host bug, ~released bug, #g-byod 51020 2026-08-12T00:46:05Z 40092 sjawhar #51020 Support credentialProviderPolicy in Android app configuration ~feature fest, customer-pingali, #g-byod 50943 2026-08-11T12:31:48Z 46773 tested surajtripathy07 lucasmrod #50943 Add software custom targets warning to delete label modal bug, ~released bug, #g-orchestration, customer-susanoo 50898 2026-08-10T19:26:08Z 45100 tianrking juan-fdz-hawa #50898 Recover vulnerability counts after interrupted table swaps bug, ~released bug, ~community, #g-supply-chain, ~aging bug 50836 2026-08-08T19:23:13Z 50300 tested kitarp29 lucasmrod #50836 Adding the logic to make controls even when it's empty bug, ~gitops, #g-orchestration 50822 2026-08-08T01:35:19Z tested viewer12 AdamBaali #50822 Add Nexus Shell as a macOS Fleet-maintained app 50774 2026-08-07T15:14:11Z 50357 tested Dhvanit41 #50774 Clear stale failure detail when an Android profile becomes verified bug, ~released bug, #g-byod 49816 2026-07-23T13:19:19Z tested sleepy-slothh #49816 Fix Ubuntu OSV binary package matching 43774 2026-04-20T15:46:23Z BCTBB #43774 Helm - Gateway API support ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an optional verbose mode for pull request listings, showing assignees, URLs, linked issue labels, and manual QA status. * Improved output formatting with aligned columns. * **Bug Fixes** * Unknown command-line arguments are now rejected with clearer usage guidance. * Improved detection of linked issues in pull request descriptions. * **Documentation** * Updated command usage information to describe the verbose option. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
@rajendrachavan Hi! Thanks for the contribution. It seems this PR doesn't actually solve the linked bug report #49502 (I closed the issue because it was caused by some invalid caching, which is now fixed in This PR actually solve a different issue described in Reed's tests: a very small window of time where reports temporarily a being scheduled on hosts that are not member of the labels. I've created #52263 and updated the PR description. |
lucasmrod
left a comment
There was a problem hiding this comment.
LGTM! Pending a merge conflict to allow merging.
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
@rajendrachavan To save you some time I pushed the conflict resolution. Once CI passes I'll merge. |
|
Thanks @lucasmrod for digging into the original report, filing #52263, sorting the conflict, and merging. Appreciate you saving me the round trip. Happy to pick up more bugs in this area. |
Related issue: Resolves #52263.
Summary
A scheduled query with no
query_labelsrows targets every host.NewQueryandSaveQuerycommitted thequeriesrow first and wrote the labels in a second transaction, so a label-scoped query was briefly visible to every host polling/api/osquery/config, and their results were stored in the query report (diagnosed by @xpkoala in the issue).This change writes the query row and its labels inside one
withRetryTxxin bothNewQueryandSaveQuery. TheupdateQueryLabelswrapper is removed; callers now use the existingupdateQueryLabelsInTxwith the outer transaction.deleteQueryStatsanddeleteQueryResultsintentionally stay outside the transaction, per @lucasmrod'sTODOfrom #14710.Testing
New datastore test
TestQueries/QueryLabelsAtomic(server/datastore/mysql/queries_test.go):NewQuerywith a label that doesn't exist must not leave a query row behind (fails onmainat this assertion: an unscoped query row survives and is served to an out-of-scope host).SaveQuerywith a failed label write rolls back the column updates and keeps the previous labels.Ran locally:
MYSQL_TEST=1 go test ./server/datastore/mysql/ -run TestQueries -count=1(all 17 subtests pass),go vet,golangci-lint(no findings in changed files). HTTP-level integration tests (server/service/integration_*) were not run locally because they hard-code Redis at127.0.0.1:6379and flush keys; relying on CI for those.Manual QA on
fleet serve --dev --dev_license: enrolled two hosts via/api/osquery/enroll, put each in its own manual label, created a query withlabels_include_any= label A, then edited it to label B, then to A+B. After each step/api/osquery/configfor each host returned the query only when that host was in scope:Checklist for submitter
changes/.SELECT *is avoided, SQL injection is prevented (using placeholders for values in statements).withRetryTxxbounds retries).Testing
Summary by CodeRabbit
Bug Fixes