Skip to content

Allow FMAs to be added when default categories don't exist#38303

Merged
jahzielv merged 8 commits intomainfrom
38254-fmas-with-categories-not-available-in-older-versions-of-fleet-fail-to-add
Mar 3, 2026
Merged

Allow FMAs to be added when default categories don't exist#38303
jahzielv merged 8 commits intomainfrom
38254-fmas-with-categories-not-available-in-older-versions-of-fleet-fail-to-add

Conversation

@allenhouchins
Copy link
Copy Markdown
Member

@allenhouchins allenhouchins commented Jan 14, 2026

FYI @allenhouchins: We will want to remove any of the changes made to the ee folder in this PR before merging since these files were added for testing


Related issue: Resolves #38254

This pull request updates how Fleet-maintained apps handle default categories, improving compatibility with older Fleet builds that may not recognize newer categories. It introduces a more flexible approach for category assignment, ensuring apps can still be added even if some categories do not exist in the current database.

Category compatibility improvements:

  • The service now maps only existing categories to IDs when adding Fleet-maintained apps, allowing apps to be added even if some default categories (like "Security" or "Utilities") are not present in older Fleet builds. This prevents errors and improves backward compatibility. [1] [2]
  • Introduced a new GetSoftwareCategoryNameToIDMap method in the datastore to return a mapping of known category names to their IDs, only including those that exist. This is used in both production and test code. [1] [2] [3] [4] [5]

App category updates:

  • Changed the default category for appcleaner from "Productivity" to "Utilities" in both input and output JSON files. [1] [2]
  • Changed the default category for nordvpn from "Productivity" to "Security" in both input and output JSON files. [1] [2]

Test and codebase adjustments:

  • Updated mocks and tests to use the new GetSoftwareCategoryNameToIDMap method instead of the previous category ID list approach. [1] [2]
  • Removed an unused import (fmt) from maintained_apps.go for cleanup.

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/ or ee/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)

  • If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes

Testing

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

Database migrations

  • Checked schema for all modified table for columns that will auto-update timestamps during migration.
  • Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects.
  • Ensured the correct collation is explicitly set for character columns (COLLATE utf8mb4_unicode_ci).

New Fleet configuration settings

  • Setting(s) is/are explicitly excluded from GitOps

If you didn't check the box above, follow this checklist for GitOps-enabled settings:

  • Verified that the setting is exported via fleetctl generate-gitops
  • Verified the setting is documented in a separate PR to the GitOps documentation
  • Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional)
  • Verified that any relevant UI is disabled when GitOps mode is enabled

fleetd/orbit/Fleet Desktop

  • Verified compatibility with the latest released version of Fleet (see Must rule)
  • If the change applies to only one platform, confirmed that runtime.GOOS is used as needed to isolate changes
  • Verified that fleetd runs on macOS, Linux and Windows
  • Verified auto-update works from the released version of component to the new version (see tools/tuf/test)

Introduces a new method GetSoftwareCategoryNameToIDMap to retrieve a mapping of software category names to their IDs, allowing for partial category matches when adding maintained apps. Updates service, tests, and mocks to use the new method, improving compatibility with older Fleet versions where some categories may not exist.
Changed AppCleaner category from 'Productivity' to 'Utilities' and NordVPN from 'Productivity' to 'Security' in both input and output JSON files.
@allenhouchins
Copy link
Copy Markdown
Member Author

allenhouchins commented Jan 14, 2026

For testing, set FLEET_DEV_MAINTAINED_APPS_BASE_URL to https://raw.githubusercontent.com/fleetdm/fleet/refs/heads/38254-fmas-with-categories-not-available-in-older-versions-of-fleet-fail-to-add/ee/maintained-apps/outputs. AppCleaner is using the Utilities category and NordVPN is using the Security category. Check to see if they add successfully on any version of Fleet prior to 4.79. The app should add but will not have a default category assigned.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 14, 2026

Codecov Report

❌ Patch coverage is 82.75862% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.28%. Comparing base (8fccdf5) to head (a8185e6).
⚠️ Report is 902 commits behind head on main.

Files with missing lines Patch % Lines
server/datastore/mysql/software.go 78.94% 2 Missing and 2 partials ⚠️
ee/server/service/maintained_apps.go 90.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #38303      +/-   ##
==========================================
+ Coverage   66.19%   66.28%   +0.08%     
==========================================
  Files        2424     2448      +24     
  Lines      194202   196859    +2657     
  Branches     8457     8439      -18     
==========================================
+ Hits       128549   130482    +1933     
- Misses      53967    54514     +547     
- Partials    11686    11863     +177     
Flag Coverage Δ
backend 68.10% <82.75%> (+0.14%) ⬆️

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.

@allenhouchins
Copy link
Copy Markdown
Member Author

Here is what I tested:

  • Running 4.78.3: AppCleaner and NordVPN added without issue using the default FMA library with the categories set to Productivity
  • Running 4.78.3: I updated the FMA library to use https://raw.githubusercontent.com/fleetdm/fleet/refs/heads/38254-fmas-with-categories-not-available-in-older-versions-of-fleet-fail-to-add/ee/maintained-apps/outputs and confirmed AppCleaner and NordVPN failed to add with the message Couldn't add. some or all of the categories provided don't exist. Other apps added without issue.
  • Running fleetdm/fleet:3a2c3db: AppCleaner and NordVPN both added without issue and had their updated categories though I'm not sure this is a valid test since this build would have contained the database updates for the new categories.

These changes should help going forward if categories change but will not help any customer not running a latest version of Fleet. Another way to prevent this going forward would be an FE to set the Category before the user clicks Add, but that would also only help from that merge forward. I don't think we can do a backwards compatible fix, only a fix that will prevent this from being an issue going forward.

@allenhouchins allenhouchins changed the title Allow FMAs to be added in older builds even if they have a default category that only exists in newer builds Allow FMAs to be added when default categories don't exist Jan 14, 2026
@allenhouchins
Copy link
Copy Markdown
Member Author

We will want to remove any of the changes made to the ee folder in this PR before merging since these files were added for testing and if we merge, customer will run into the issue this PR is looking to address if they add AppCleaner or NordVPN.

Removed unused imports from maintained_apps.go
@allenhouchins allenhouchins marked this pull request as ready for review February 3, 2026 03:46
@allenhouchins allenhouchins requested a review from a team as a code owner February 3, 2026 03:46
@allenhouchins allenhouchins marked this pull request as draft February 8, 2026 05:24
Copy link
Copy Markdown
Member

@mna mna left a comment

Choose a reason for hiding this comment

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

PR looks good to me, looks like you already removed the stuff you mentioned here #38303 (comment) ?

Just a minor thing to clean up, doesn't change the logic at all.

Comment thread server/datastore/mysql/software.go Outdated

var categories []fleet.SoftwareCategory
if err := sqlx.SelectContext(ctx, ds.reader(ctx), &categories, stmt, args...); err != nil {
if !errors.Is(err, sql.ErrNoRows) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit, but SelectContext never returns sql.ErrNoRows, only sqlx.GetContext does, so you can remove the if condition and always return the error here.

@jahzielv jahzielv marked this pull request as ready for review March 3, 2026 17:31
@jahzielv jahzielv merged commit f23fd95 into main Mar 3, 2026
51 checks passed
@jahzielv jahzielv deleted the 38254-fmas-with-categories-not-available-in-older-versions-of-fleet-fail-to-add branch March 3, 2026 19:29
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.

FMAs with categories not available in older versions of Fleet fail to add

3 participants