Skip to content

Updated Windows setup experience to not cancel for BYOD.#45994

Merged
getvictor merged 1 commit into
mainfrom
victor/45946-windows-setup
May 21, 2026
Merged

Updated Windows setup experience to not cancel for BYOD.#45994
getvictor merged 1 commit into
mainfrom
victor/45946-windows-setup

Conversation

@getvictor

@getvictor getvictor commented May 21, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #45946

Unreleased bug.

Checklist for submitter

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

  • Confirmed that the fix is not expected to adversely impact load test results

Summary by CodeRabbit

Bug Fixes

  • Enhanced Windows setup experience cancellation to accurately validate device enrollment status before processing cancellations
  • Improved device identification reliability during concurrent operations through robust fallback mechanisms that reference recent enrollment records when initial lookups fail

Review Change Stack

@getvictor getvictor requested a review from Copilot May 21, 2026 18:08
@getvictor

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@getvictor

Copy link
Copy Markdown
Member Author

/agentic_review

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented May 21, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0)

Grey Divider


Action required

1. Replica-lag bypasses cancel gate 🐞 Bug ☼ Reliability
Description
maybeCancelPendingSetupExperienceSteps gates cancellation on
mdm_windows_enrollments.awaiting_configuration but queries it via
GetMDMWindowsAwaitingConfigurationByHostUUID without forcing primary routing, so replica lag can
return NotFound/None and incorrectly skip cancellation and canceled_setup_experience activity. This
can leave pending setup steps and upcoming activities uncanceled for a Windows host actively in ESP.
Code

server/service/setup_experience.go[R304-320]

Evidence
The service code calls a reader-backed method to decide whether to cancel; the datastore method
explicitly warns that callers needing primary semantics must wrap the context with
ctxdb.RequirePrimary. Similar ESP-critical code paths already force primary routing to avoid
replica-lag races, and the prior enrollment lookup used writer routing for this reason.

server/service/setup_experience.go[286-320]
server/datastore/mysql/microsoft_mdm.go[198-214]
server/datastore/mysql/microsoft_mdm.go[102-133]
server/service/microsoft_mdm.go[2124-2141]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`maybeCancelPendingSetupExperienceSteps` uses `GetMDMWindowsAwaitingConfigurationByHostUUID` (and the device-name fallback) to decide whether to run the cancellation cascade. Those lookups are currently performed with the default routing (`ds.reader(ctx)`), which can be stale in replica-backed deployments, causing the gate to incorrectly skip cancellation/activity.

### Issue Context
`GetMDMWindowsAwaitingConfigurationByHostUUID` is explicitly documented as **reader-backed** and instructs callers needing primary semantics to wrap the context with `ctxdb.RequirePrimary`. The ESP codebase already uses primary routing in other ESP-critical paths specifically to avoid replica-lag races.

### Fix
In `maybeCancelPendingSetupExperienceSteps`, create a primary-routed context (e.g., `ctxPrimary := ctxdb.RequirePrimary(ctx, true)`) and use it for:
- `ds.GetMDMWindowsAwaitingConfigurationByHostUUID`
- `ds.MDMWindowsGetUnlinkedEnrolledDeviceWithDeviceName`

(Optionally, consider using the same primary-routed context for subsequent reads in the cancel cascade if you want the entire cancellation decision+execution to be strongly consistent.)

### Fix Focus Areas
- server/service/setup_experience.go[286-321]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Windows “cancel setup experience if software fails” behavior so that cancellation (and the associated canceled_setup_experience activity) only occurs when the host is actually in a Fleet-tracked Windows ESP flow, preventing BYOD/manual enrollment paths from incorrectly triggering cancellation.

Changes:

  • Gates the Windows cancel cascade on mdm_windows_enrollments.awaiting_configuration being Pending or Active, with a device-name fallback for the host-UUID linking race window.
  • Reworks/expands unit tests into a Windows cancel-gate matrix to cover ESP vs non-ESP enrollment paths and the fallback lookup behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
server/service/setup_experience.go Changes Windows cancellation gating logic to rely on awaiting_configuration (Pending/Active) and adds a device-name fallback when host_uuid isn’t linked yet.
server/service/setup_experience_test.go Updates Windows setup experience tests to validate the new gate behavior across multiple enrollment scenarios (including the race-window fallback).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/service/setup_experience.go
Comment thread server/service/setup_experience.go
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR changes how Windows setup-experience cancellation is gated when software installation fails. Instead of checking whether a host is a BYOD device via the "MDMNotInOOBE" enrollment status, the code now gates on mdm_windows_enrollments.awaiting_configuration being in Pending or Active state. The implementation includes a fallback path: when the primary lookup by host_uuid does not find an enrollment (e.g., due to ingestion race), it falls back to the most-recent unlinked enrollment matched by host.ComputerName. The test suite is expanded with a comprehensive matrix test covering all awaiting_configuration states and race scenarios.

Possibly related issues

  • #45946: The PR directly addresses this issue, which reports that canceled_setup_experience activity appears for manually enrolled hosts when software installation fails—the new gate ensures cancellation only occurs when the host is in an active ESP (awaiting_configuration Pending/Active).

Possibly related PRs

  • fleetdm/fleet#45331: Both PRs modify the Windows cancellation flow in maybeCancelPendingSetupExperienceSteps by changing how mdm_windows_enrollments lookup is performed (host UUID first, then device-name fallback) and how the cancellation gate is determined.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is incomplete. It covers only testing and load test confirmation but omits critical sections like changes files, input validation, timeouts/retries, endpoint compatibility, multi-host isolation testing, database migrations, and fleetd/orbit compatibility. Complete the checklist by addressing all applicable sections: document changes files, confirm input validation/SQL injection prevention, verify database migration considerations, and validate fleetd/orbit compatibility for Windows setup experience changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: updating Windows setup experience to prevent cancellation for BYOD (bring-your-own-device) hosts, which directly addresses the linked issue.
Linked Issues check ✅ Passed The code changes address the core requirement: preventing setup experience cancellation and failed activity for manually enrolled (BYOD) Windows hosts by gating on MDM enrollment status instead of OOBE state.
Out of Scope Changes check ✅ Passed All changes are focused on the setup experience cancellation logic and its tests, directly addressing the scope defined in issue #45946 without introducing unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch victor/45946-windows-setup

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/service/setup_experience.go`:
- Around line 308-315: The fallback using
MDMWindowsGetUnlinkedEnrolledDeviceWithDeviceName(ctx, host.ComputerName) is too
broad because ComputerName is not unique; restrict the match before trusting
device.AwaitingConfiguration to avoid flipping cancellation for the wrong
machine. Change the lookup to include an additional discriminator (e.g.,
hardware UUID or serial) or add/replace with a datastore method like
MDMWindowsGetUnlinkedEnrolledDeviceWithDeviceNameAndHardwareID and then, after
calling the lookup, verify the returned device's hardware identifier (e.g.,
device.HardwareUUID or device.SerialNumber) equals the host's (host.HardwareUUID
or host.HardwareSerial) before assigning awaiting = device.AwaitingConfiguration
and emitting cancellation.
🪄 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: 37da39e7-47e7-45be-be3e-a40e37edc8d1

📥 Commits

Reviewing files that changed from the base of the PR and between e3713da and ce0b719.

📒 Files selected for processing (2)
  • server/service/setup_experience.go
  • server/service/setup_experience_test.go

Comment thread server/service/setup_experience.go
@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.81%. Comparing base (e3713da) to head (ce0b719).
⚠️ Report is 12 commits behind head on main.

Files with missing lines Patch % Lines
server/service/setup_experience.go 77.77% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #45994   +/-   ##
=======================================
  Coverage   66.81%   66.81%           
=======================================
  Files        2754     2754           
  Lines      220112   220115    +3     
  Branches    10981    10981           
=======================================
+ Hits       147071   147074    +3     
  Misses      59757    59757           
  Partials    13284    13284           
Flag Coverage Δ
backend 68.61% <77.77%> (+<0.01%) ⬆️

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.

@getvictor getvictor marked this pull request as ready for review May 21, 2026 20:12

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@getvictor getvictor requested a review from a team as a code owner May 21, 2026 20:12
@getvictor getvictor merged commit f9c9ad0 into main May 21, 2026
47 checks passed
@getvictor getvictor deleted the victor/45946-windows-setup branch May 21, 2026 21:54
getvictor added a commit that referenced this pull request May 21, 2026
…6028)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45946

Unreleased bug.

# Checklist for submitter

## 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

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

**Bug Fixes**
- Enhanced Windows setup experience cancellation to accurately validate
device enrollment status before processing cancellations
- Improved device identification reliability during concurrent
operations through robust fallback mechanisms that reference recent
enrollment records when initial lookups fail

<!-- review_stack_entry_start -->

[![Review Change

Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45994?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

(cherry picked from commit f9c9ad0)
@coderabbitai coderabbitai Bot mentioned this pull request Jun 1, 2026
12 tasks
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.

Failed setup experience activity shows up for manually enrolled hosts when software installation fails

3 participants