Add quit and relaunch logic to macOS FMAs - #37670
Merged
Merged
Conversation
fleet-release
previously approved these changes
Dec 24, 2025
allenhouchins
temporarily deployed
to
Docker Hub
December 24, 2025 04:26 — with
GitHub Actions
Inactive
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #37670 +/- ##
==========================================
- Coverage 65.88% 65.88% -0.01%
==========================================
Files 2360 2360
Lines 187285 187290 +5
Branches 8006 8005 -1
==========================================
- Hits 123402 123390 -12
- Misses 52605 52618 +13
- Partials 11278 11282 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
fleet-release
previously approved these changes
Dec 24, 2025
allenhouchins
had a problem deploying
to
Docker Hub
December 24, 2025 04:43 — with
GitHub Actions
Error
fleet-release
previously approved these changes
Dec 24, 2025
allenhouchins
had a problem deploying
to
Docker Hub
December 24, 2025 04:45 — with
GitHub Actions
Error
fleet-release
approved these changes
Dec 24, 2025
allenhouchins
temporarily deployed
to
Docker Hub
December 24, 2025 04:48 — with
GitHub Actions
Inactive
fleet-release
approved these changes
Dec 24, 2025
fleet-release
approved these changes
Dec 24, 2025
cdcme
approved these changes
Jan 5, 2026
headmin
added a commit
to headmin/fleet-stuff
that referenced
this pull request
Jan 27, 2026
This version is latest release - fleetdm/fleet@7d527ca fleetdm/fleet#37670
This was referenced Aug 10, 2026
allenhouchins
added a commit
that referenced
this pull request
Aug 10, 2026
**Related issue:** Resolves #50875 Docker Desktop on macOS never reported an installed version or "Installed" status, and offered "Install" on hosts that already had it. ## Root cause The FMA's `unique_identifier` was `com.electron.dockerdesktop`, which belongs to the embedded Electron bundle. The installed app reports a different identifier: | Path | CFBundleIdentifier | |---|---| | `/Applications/Docker.app` | `com.docker.docker` | | `/Applications/Docker.app/Contents/MacOS/Docker Desktop.app` | `com.electron.dockerdesktop` | The identifier was changed from `com.docker.docker` → `com.electron.dockerdesktop` in #37670 (Jan 5) as "the new bundle identifier … reflecting the current packaging". The top-level bundle never changed. That was latent until #47831 (#44199, Jul 9) added an embedded-bundle filter to the macOS software inventory query in `server/service/osquery_utils/queries.go`: ```sql FROM apps WHERE path NOT LIKE '%.app/Contents/%' ``` `/Applications/Docker.app/Contents/MacOS/Docker Desktop.app` matches that pattern, so the only row carrying the embedded identifier is filtered out and inventory keeps just `/Applications/Docker.app` → `com.docker.docker`. Since FMA↔inventory matching is by bundle identifier (`addSoftwareTitleToMatchingSoftware`), the title the FMA owns had zero installed versions. **Patch policies kept passing**, because they run the FMA's `exists`/`patched` SQL directly against the host's *unfiltered* `apps` table. That's also why #50041 needed a `.back` path exclusion, and why patch status and the software UI have disagreed since July. ## What changed **Catalog** — `unique_identifier` is now `com.docker.docker`, with `docker-desktop/darwin.json` regenerated. `outputs/apps.json` needed a hand-edit because `updateAppsListFile` (`cmd/maintained-apps/main.go`) only appends new apps and never updates an existing entry's identifier — filed separately. The remaining `com.electron.dockerdesktop` references are intentional and untouched: the install script's quit/relaunch targets (the Electron bundle is what responds to AppleScript) and the cask's zap paths. The `.back` exclusion in the patched query also stays — `/Applications/Docker.app.back` is a *top-level* bundle reporting `com.docker.docker` at a path the nested-bundle filter does not match, so a stale `.back` would otherwise show a false "Update available". **Migration** (`20260810152924_FixDockerDesktopBundleIdentifier`) — `fleet_maintained_apps` self-heals on catalog sync (`UpsertMaintainedApp` updates `unique_identifier` on duplicate slug) and `ReconcileMaintainedAppSoftwareNames` renames the existing "Docker" title, but an already-added installer's `software_installers.title_id` binding does not: - **No `com.docker.docker` title yet** → relabel the stale title in place, so everything already pointing at it stays correct. - **Title already exists** (the normal case — any host with Docker creates it) → merge the stale title into it: installer, install history, queued installs, patch policy, `software.title_id`, and per-team settings (icons, display names, pins, update schedules), then drop the stale title. ## Notes for reviewers - **Teams that already have an installer on the target title are skipped** rather than ending up with two installers on one title. `dedup_token` is the *version* for FMAs and the *storage_id* otherwise, so `idx_software_installers_dedup` would not have caught that collision. Those teams keep the pre-migration state instead of having data silently reshaped. - **The stale title is only deleted once nothing depends on it.** `fk_software_installers_title` is `ON DELETE SET NULL`, so deleting it while an installer still pointed at it would orphan that installer. Note also that `fk_patch_software_title_id` is `ON DELETE CASCADE` — re-pointing the patch policy is what keeps it from being deleted outright. - **Dangling-reference check:** the only title-referencing columns without an FK to `software_titles` are `software.title_id` (re-pointed), `software_titles_host_counts` (deleted; the cron recomputes), and `kernel_host_counts` / `in_house_app_install_tokens`, neither of which can hold a macOS app title. - **Naming lags briefly.** The existing title is named "Docker" (from osquery); `ReconcileMaintainedAppSoftwareNames` renames it to "Docker Desktop" on the next catalog sync, so there is a window after upgrade where the name is still "Docker". I left that to the sync rather than duplicating the rename logic in the migration. - **This fixes one app, not the class.** Any other macOS FMA keyed on a nested bundle fails the same silent way, and a green patch policy will not reveal it. An audit is filed separately. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements). Table/column names in the migration's generated SQL come from hardcoded struct literals, never from data; all values are placeholders. ## Testing - [x] Added/updated automated tests Five migration tests cover: relabel-in-place, merge-into-inventory-title, duplicate per-team settings dropped, teams with an existing installer skipped (and the stale title consequently retained), and no-op when the FMA was never added. The merge test also asserts `updated_at` is not restamped. Updated the homebrew ingester test expectations for the new identifier. Verified: full `server/datastore/mysql/migrations/tables` suite passes (201s), `ee/maintained-apps/...`, `cmd/maintained-apps/...`, and the FMA datastore tests pass, `make lint-go-incremental` clean. Root cause was confirmed against real bundles rather than inferred — `PlistBuddy` on both Docker bundles for the identifiers above, and `lsregister -dump` to confirm LaunchServices registers the nested bundles (which is why the raw `apps` table sees them and patch policies pass). - [ ] QA'd all new/changed functionality manually Needs QA on a real instance: add the Docker Desktop FMA, confirm the installed version and "Installed" status appear on a host that already has it, and confirm an upgrade over an instance that already had the FMA added re-points the existing installer. For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results The migration touches only rows tied to a single software title, and is a no-op on instances that never added the Docker Desktop FMA. ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [x] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. Five of the written tables have `updated_at` as `ON UPDATE CURRENT_TIMESTAMP`: `software_installers`, `host_software_installs`, `software_install_upcoming_activities`, `policies`, and `software_title_team_pins`. Since this re-points a foreign key rather than modifying the records, each statement assigns `updated_at = updated_at` so MySQL leaves them alone, with a test asserting it. (Bumping them would have been cosmetic — none of these columns drives ordering, scheduling, or invalidation; policy membership uses `policy_membership.updated_at` and `hosts.policy_updated_at`, and the activity feed orders by the activities table — but preserving them is more faithful to what the migration actually does.) - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). No columns added or altered; this is a data-only migration. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved macOS Docker Desktop detection so installed versions and “Installed” status are reported accurately. * Ensured existing Docker Desktop installations and upgrade history remain correctly associated after detection updates. * Improved handling of stale application bundles during patch evaluation. * **Maintenance** * Updated detection data and migration coverage to support the corrected Docker Desktop identification. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request enhances the macOS app installation process by improving how running applications are handled during install and update, and also updates the metadata and scripts for Docker Desktop. The main improvements are the introduction of quit/relaunch logic for pkg-based FMAs, and the renaming and updating of Docker Desktop’s identifiers and scripts.
App install/relaunch improvements:
quit_and_track_applicationandrelaunch_applicationto the generated install scripts. These functions ensure that if an app (or pkg) is running before installation, it is quit and then automatically relaunched after installation, preserving user state. The logic tracks whether the app was running via an environment variable. [1] [2] [3] [4]quit_applicationlogic from the install script generation, as the new functions supersede it.Docker Desktop metadata and script updates:
slugandunique_identifierto match the new bundle identifier (com.electron.dockerdesktop), reflecting the current packaging.apps.jsonto use the new slug and unique identifier for Docker Desktop.docker-desktop/darwin.json) with the updated install and uninstall scripts, including the new quit/relaunch logic and references.