Skip to content

Add quit and relaunch logic to macOS FMAs - #37670

Merged
allenhouchins merged 6 commits into
mainfrom
allenhouchins-add-quit-relaunch-logic
Jan 6, 2026
Merged

Add quit and relaunch logic to macOS FMAs#37670
allenhouchins merged 6 commits into
mainfrom
allenhouchins-add-quit-relaunch-logic

Conversation

@allenhouchins

@allenhouchins allenhouchins commented Dec 24, 2025

Copy link
Copy Markdown
Member

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:

  • Added new shell functions quit_and_track_application and relaunch_application to 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]
  • Removed the previous simpler quit_application logic from the install script generation, as the new functions supersede it.

Docker Desktop metadata and script updates:

  • Renamed the Docker Desktop input and updated its slug and unique_identifier to match the new bundle identifier (com.electron.dockerdesktop), reflecting the current packaging.
  • Updated the output app metadata in apps.json to use the new slug and unique identifier for Docker Desktop.
  • Added a new output file for Docker Desktop (docker-desktop/darwin.json) with the updated install and uninstall scripts, including the new quit/relaunch logic and references.

fleet-release
fleet-release previously approved these changes Dec 24, 2025
@codecov

codecov Bot commented Dec 24, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 7.69231% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.88%. Comparing base (9adfe73) to head (68d34ee).
⚠️ Report is 85 commits behind head on main.

Files with missing lines Patch % Lines
ee/maintained-apps/ingesters/homebrew/scripts.go 8.33% 9 Missing and 2 partials ⚠️
...end/pages/SoftwarePage/components/icons/Docker.tsx 0.00% 1 Missing ⚠️
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     
Flag Coverage Δ
backend 67.73% <8.33%> (-0.01%) ⬇️
frontend 54.40% <0.00%> (ø)

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.

fleet-release
fleet-release previously approved these changes Dec 24, 2025
fleet-release
fleet-release previously approved these changes Dec 24, 2025
@allenhouchins
allenhouchins marked this pull request as ready for review December 24, 2025 06:19
@allenhouchins
allenhouchins requested review from a team as code owners December 24, 2025 06:19
@fleet-release
fleet-release requested a review from eashaw December 24, 2025 06:19
@allenhouchins
allenhouchins merged commit 7d527ca into main Jan 6, 2026
52 checks passed
@allenhouchins
allenhouchins deleted the allenhouchins-add-quit-relaunch-logic branch January 6, 2026 04:31
headmin added a commit to headmin/fleet-stuff that referenced this pull request Jan 27, 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 -->
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.

3 participants