WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@jahzielv
Copy link
Member

@jahzielv jahzielv commented Dec 24, 2025

Related issue: Resolves #37265

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Input data is properly validated, SELECT * is avoided, SQL injection is prevented (using placeholders for values in statements)

Testing

@jahzielv
Copy link
Member Author

Note: integration testing will come after implementing the next backend subtask for this story.

if ok {
for _, f := range handlers {
if err := f(ctx, result); err != nil {
// TODO: should we run as many as we can? if so we have to collect into a multierror
Copy link
Member Author

Choose a reason for hiding this comment

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

I can address this in a subsequent PR, since this is the existing behavior

Copy link
Member

Choose a reason for hiding this comment

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

Guessing we'll need this for automatic VPP updates anyway? /cc @lucasmrod

Copy link
Member

Choose a reason for hiding this comment

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

Gonna merge on top of this and @lucasmrod can stack on top.

Copy link
Member

Choose a reason for hiding this comment

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

Guessing we'll need this for automatic VPP updates anyway?

Do we? Will there be any commands that will be processed by more than one handler?

Copy link
Member

Choose a reason for hiding this comment

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

Depends on where you're hooking in on MDM-driven software inventory, I suppose.

Guessing you already built that out though so maybe we're good to go?

Copy link
Member

Choose a reason for hiding this comment

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

Depends on where you're hooking in on MDM-driven software inventory, I suppose.

Guessing you already built that out though so maybe we're good to go?

Copy link
Member

Choose a reason for hiding this comment

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

Depends on where you're hooking in on MDM-driven software inventory, I suppose.

Guessing you already built that out though so maybe we're good to go?

Copy link
Member

Choose a reason for hiding this comment

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

Depends on where you're hooking in on MDM-driven software inventory, I suppose.

Guessing you already built that out though so maybe we're good to go?

Copy link
Member Author

@jahzielv jahzielv Dec 24, 2025

Choose a reason for hiding this comment

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

Do we? Will there be any commands that will be processed by more than one handler?

I think yes, eventually. The goal with the handlers was to make a pattern for handling MDM command results for independent operations. That way we don't end up with 1 mega-function per MDM command result type that tries to contain all possible Fleet logic for that type.

ctx := context.Background()
iOSHost := newTestHostWithPlatform(t, ds, "iphone_"+t.Name(), string(fleet.IOSPlatform), nil)

err := ds.InsertHostLocationData(ctx, iOSHost.ID, 42.42, -42.42)
Copy link
Member

Choose a reason for hiding this comment

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

Thoughts on rolling this up into the HostLocation struct, including adding host ID in? At which point you can just check equality on the round trip (which for this low of precision should work despite dealing with a float to decimal conversion).

Also, since we aren't doing math, maybe specifying the struct fields for lat/long as strings is a better idea here, so we don't lose anything going from string-formatted in the plist to floats and then back to fixed-point in the database.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thoughts on rolling this up into the HostLocation struct, including adding host ID in? At which point you can just check equality on the round trip (which for this low of precision should work despite dealing with a float to decimal conversion).

sgtm 👍

Also, since we aren't doing math, maybe specifying the struct fields for lat/long as strings is a better idea here, so we don't lose anything going from string-formatted in the plist to floats and then back to fixed-point in the database.

I have a slight preference for leaving it as floats, but not huge. Seems like floats might be something we need in future.

Copy link
Member

Choose a reason for hiding this comment

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

Gonna continue pushing on the floats thing because we can maintain precision from the Apple result of we don't do that.

If we need to do math on these later, it'll probably be in the database anyway, which is (correctly) defined as fixed-point.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hrm, seems like I can't unmarshal the plist fields into a string.

I get

err="build device location command result: device location command result: xml unmarshal: plist: cannot unmarshal $VERY_LONG_DECIMAL_HERE into Go value of type string"

Does it make sense to unmarshal into float64, then turn those into strings?

Copy link
Member

Choose a reason for hiding this comment

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

Nope, doesn't make sense after we hit floating point. Can leave this as is then.

Copy link
Member

Choose a reason for hiding this comment

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

Nope, doesn't make sense after we hit floating point. Can leave this as is then.

if ok {
for _, f := range handlers {
if err := f(ctx, result); err != nil {
// TODO: should we run as many as we can? if so we have to collect into a multierror
Copy link
Member

Choose a reason for hiding this comment

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

Guessing we'll need this for automatic VPP updates anyway? /cc @lucasmrod

@codecov
Copy link

codecov bot commented Dec 24, 2025

Codecov Report

❌ Patch coverage is 67.46032% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.91%. Comparing base (9adfe73) to head (7dcb38d).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
server/service/apple_mdm.go 51.11% 15 Missing and 7 partials ⚠️
server/service/apple_mdm_cmd_results.go 40.90% 12 Missing and 1 partial ⚠️
...ns/tables/20251222174712_AddHostLocationSupport.go 76.47% 3 Missing and 1 partial ⚠️
cmd/fleet/serve.go 0.00% 1 Missing ⚠️
server/datastore/mysql/apple_mdm.go 96.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #37668      +/-   ##
==========================================
+ Coverage   65.88%   65.91%   +0.02%     
==========================================
  Files        2360     2362       +2     
  Lines      187285   187295      +10     
  Branches     8006     7989      -17     
==========================================
+ Hits       123402   123456      +54     
+ Misses      52605    52550      -55     
- Partials    11278    11289      +11     
Flag Coverage Δ
backend 67.73% <67.46%> (-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.

@jahzielv jahzielv changed the title 37265 be database and devicelocation mdm command DeviceLocation command handling and DB support Dec 24, 2025
@jahzielv
Copy link
Member Author

Looks like the failing test is unrelated FYI

@jahzielv jahzielv marked this pull request as ready for review December 24, 2025 05:10
@jahzielv jahzielv requested a review from a team as a code owner December 24, 2025 05:10
Copy link
Member

@iansltx iansltx left a comment

Choose a reason for hiding this comment

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

Sorry, found a few more things. Setting this to draft in the mean time.

Comment on lines 3728 to 3735
host, err := svc.ds.HostByIdentifier(r.Context, cmdResult.Identifier())
if err != nil {
return nil, ctxerr.Wrap(r.Context, err, "DisableLostMode: get host by identifier")
}

if err := svc.ds.DeleteHostLocationData(r.Context, host.ID); err != nil {
return nil, ctxerr.Wrap(r.Context, err, "DisableLostMode: delete host location data")
}
Copy link
Member

Choose a reason for hiding this comment

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

Thinking we want to put this, plus the device location command on lost mode entry, inside the status gate rather than before it? Otherwise we could be clearing location on a pending lost mode request right?

}

case fleet.DeviceLocationCmdName:

Copy link
Member

Choose a reason for hiding this comment

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

Do we need to check for command status here?

Copy link
Member Author

Choose a reason for hiding this comment

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

@iansltx I added a check for command success status (Acknowledged). Any error handling is a product decision (e.g. should we retry?) and can be added in followup PRs relatively easily.

Copy link
Member

Choose a reason for hiding this comment

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

@jahzielv In case of an error, we have this state in the Location modal:
Screenshot 2025-12-29 at 11 36 47

We will soon surface MDM commands in the activity, allowing users to track if a location command has failed.

Comment on lines 52 to 56
if err != nil {
return ctxerr.Wrap(ctx, err, "device location command result: insert host location data")
}

return nil
Copy link
Member

Choose a reason for hiding this comment

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

We can just return the wrap here, right?

@iansltx iansltx marked this pull request as draft December 24, 2025 12:31
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.

BE: Database and DeviceLocation MDM command

5 participants