Fix FMA pinning not changing patch policy - #49519
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #49519 +/- ##
==========================================
- Coverage 68.08% 67.82% -0.27%
==========================================
Files 3882 3888 +6
Lines 246398 247553 +1155
Branches 13169 13169
==========================================
+ Hits 167753 167891 +138
- Misses 63504 64505 +1001
- Partials 15141 15157 +16
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:
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughFleet-maintained app activation now updates matching patch policy queries from the active installer’s version-specific Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.44.1)server/service/integration_enterprise_test.goast-grep timed out on this file 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@server/datastore/mysql/software_installers.go`:
- Around line 705-714: Update the patch policy UPDATE in the active installer
flow to use MySQL’s null-safe equality operator (<=>) for p.team_id and pass
payload.TeamID directly instead of tmID, so both global NULL team IDs and scoped
team IDs match precisely. Keep the existing title and installer filters
unchanged.
In `@server/service/integration_enterprise_test.go`:
- Around line 28180-28191: Update the POST route in the patch policy setup to
use the team-scoped “teams” segment instead of “fleets”, matching the GET route
used by patchPolicyQuery and preserving the existing team.ID and policies
endpoint.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e12427b1-b2df-4e20-9194-d7cdcbc6a8e1
📒 Files selected for processing (4)
changes/49474-fix-patch-policy-query-not-updatingserver/datastore/mysql/software_installers.goserver/datastore/mysql/software_installers_test.goserver/service/integration_enterprise_test.go
| // Edit the patch policy if it exists to use the pinned installer's query | ||
| if _, err := tx.ExecContext(ctx, ` | ||
| UPDATE policies p | ||
| JOIN software_installers si ON si.id = ? | ||
| SET p.query = si.patch_query | ||
| WHERE p.team_id = ? AND p.patch_software_title_id = ? | ||
| `, activeInstallerID, tmID, payload.TitleID); err != nil { | ||
| return ctxerr.Wrap(ctx, err, "updating patch policy query for active fleet-maintained app installer") | ||
| } | ||
|
|
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win
Fix global policy matching to gracefully handle NULL.
For global policies, payload.TeamID is nil and tmID resolves to 0. However, global policies have team_id = NULL in the database. The WHERE p.team_id = ? clause with 0 will evaluate to NULL = 0 (which is false in MySQL), causing the update to silently fail and leave the global patch policy query unchanged.
As per path instructions, ensure that appropriate filtering criteria are applied to prevent non-deterministic or incorrect results due to a lack of precise scoping. Update the condition to use the null-safe equality operator <=> and pass the pointer directly. The database driver will correctly translate a nil Go pointer to a SQL NULL.
🐛 Proposed fix
// Edit the patch policy if it exists to use the pinned installer's query
if _, err := tx.ExecContext(ctx, `
UPDATE policies p
JOIN software_installers si ON si.id = ?
SET p.query = si.patch_query
- WHERE p.team_id = ? AND p.patch_software_title_id = ?
- `, activeInstallerID, tmID, payload.TitleID); err != nil {
+ WHERE p.team_id <=> ? AND p.patch_software_title_id = ?
+ `, activeInstallerID, payload.TeamID, payload.TitleID); err != nil {
return ctxerr.Wrap(ctx, err, "updating patch policy query for active fleet-maintained app installer")
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Edit the patch policy if it exists to use the pinned installer's query | |
| if _, err := tx.ExecContext(ctx, ` | |
| UPDATE policies p | |
| JOIN software_installers si ON si.id = ? | |
| SET p.query = si.patch_query | |
| WHERE p.team_id = ? AND p.patch_software_title_id = ? | |
| `, activeInstallerID, tmID, payload.TitleID); err != nil { | |
| return ctxerr.Wrap(ctx, err, "updating patch policy query for active fleet-maintained app installer") | |
| } | |
| // Edit the patch policy if it exists to use the pinned installer's query | |
| if _, err := tx.ExecContext(ctx, ` | |
| UPDATE policies p | |
| JOIN software_installers si ON si.id = ? | |
| SET p.query = si.patch_query | |
| WHERE p.team_id <=> ? AND p.patch_software_title_id = ? | |
| `, activeInstallerID, payload.TeamID, payload.TitleID); err != nil { | |
| return ctxerr.Wrap(ctx, err, "updating patch policy query for active fleet-maintained app installer") | |
| } |
🤖 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 `@server/datastore/mysql/software_installers.go` around lines 705 - 714, Update
the patch policy UPDATE in the active installer flow to use MySQL’s null-safe
equality operator (<=>) for p.team_id and pass payload.TeamID directly instead
of tmID, so both global NULL team IDs and scoped team IDs match precisely. Keep
the existing title and installer filters unchanged.
Source: Path instructions
There was a problem hiding this comment.
Patch policies cannot be created globally
cdcme
left a comment
There was a problem hiding this comment.
Few questions, but looks clean!
…n RC branch The FMA patch-policy test cherry-picked in with #49519 calls RecordPolicyQueryExecutions expecting ([]uint, error) (its signature on main), but on this RC branch it returns just error. The non-compiling test package failed both the mysql test suite and the Go linters' typecheck pass. Drop the unused first return value to match the RC signature.
…TeamTitleAndInstallerID (#49760) **Related issue:** N/A — RC branch build/CI fix ## What & why The Docker publish for **4.89.2** on `rc-patch-fleet-v4.89.2` was failing to compile, and the `mysql` test suite + Go linters were red — all from the same root cause: a **broken cherry-pick**. **1. Missing datastore method (broke Docker publish + all binary builds):** ``` server/datastore/mysql/software_installers.go:748:30: ds.GetSoftwareInstallerMetadataByTeamTitleAndInstallerID undefined ``` The FMA patch-policy fix (#49519, commit `9603e84cc4`) was cherry-picked in, bringing a *caller* of `GetSoftwareInstallerMetadataByTeamTitleAndInstallerID`, but the method itself was introduced on `main` by the large "Multiple packages API changes" feature PR (#48607), which is not part of this release. **2. Stale test assertion (broke `mysql` test suite + `lint`/`lint-incremental` typecheck):** ``` server/datastore/mysql/software_installers_test.go:6362:11: assignment mismatch: 2 variables but ds.RecordPolicyQueryExecutions returns 1 value ``` The same cherry-pick brought a test that calls `RecordPolicyQueryExecutions` expecting `([]uint, error)` (its signature on `main`), but on this RC branch it returns just `error`. A non-compiling test package fails both the mysql suite and the linter's typecheck pass. ## Fix - Added `GetSoftwareInstallerMetadataByTeamTitleAndInstallerID` as a self-contained, minimal addition (interface + datastore impl + regenerated mock), refactoring `GetSoftwareInstallerMetadataByTeamAndTitleID` to share a private helper that takes an optional installer ID. The `nil` path preserves existing behavior exactly; a non-nil ID selects that specific package by `si.id`. - Fixed the stale test call to match the RC branch's single-return signature (the discarded first return value is simply dropped). No production behavior change for existing callers. # Checklist for submitter - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## 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 --------- Co-authored-by: test <test@test.com>
Related issue: Resolves #49474
Checklist for submitter
If some of the following don't apply, delete the relevant line.
Changes file added for user-visible changes in
changes/,orbit/changes/oree/fleetd-chrome/changes.See Changes files for more information.
Input data is properly validated,
SELECT *is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.Timeouts are implemented and retries are limited to avoid infinite loops
If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes
Testing
Added/updated automated tests
Where appropriate, automated tests simulate multiple hosts and test for host isolation (updates to one hosts's records do not affect another)
QA'd all new/changed functionality manually
Relied on integration test for testing changes made by the
maintained_apps_auto_updatejobSummary by CodeRabbit