From c443598c787ed72abad72ad96dcb6ca709d78a98 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Sun, 5 Jan 2025 17:03:00 -0600 Subject: [PATCH] Fix detection of uninstall scripts when recording script results after a host has had MDM actions taken For #25144. --- changes/25144-uninstall-after-mdm-action | 1 + server/datastore/mysql/scripts.go | 12 ++++++------ server/service/integration_enterprise_test.go | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 changes/25144-uninstall-after-mdm-action diff --git a/changes/25144-uninstall-after-mdm-action b/changes/25144-uninstall-after-mdm-action new file mode 100644 index 000000000000..136a2ff7776e --- /dev/null +++ b/changes/25144-uninstall-after-mdm-action @@ -0,0 +1 @@ +* Fixed reporting of software uninstall results after a host has been locked/unlocked diff --git a/server/datastore/mysql/scripts.go b/server/datastore/mysql/scripts.go index 8def2509ddd4..53d162d524cf 100644 --- a/server/datastore/mysql/scripts.go +++ b/server/datastore/mysql/scripts.go @@ -129,6 +129,12 @@ func (ds *Datastore) SetHostScriptExecutionResult(ctx context.Context, result *f execution_id = ?` const hostMDMActionsStmt = ` + SELECT 'uninstall' AS action + FROM + host_software_installs + WHERE + execution_id = :execution_id AND host_id = :host_id + UNION -- host_mdm_actions query (and thus row in union) must be last to avoid #25144 SELECT CASE WHEN lock_ref = :execution_id THEN 'lock_ref' @@ -140,12 +146,6 @@ func (ds *Datastore) SetHostScriptExecutionResult(ctx context.Context, result *f host_mdm_actions WHERE host_id = :host_id - UNION - SELECT 'uninstall' AS action - FROM - host_software_installs - WHERE - execution_id = :execution_id AND host_id = :host_id ` output := truncateScriptResult(result.Output) diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 76acce2cebd2..79437ffb7c00 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -12500,6 +12500,21 @@ func (s *integrationEnterpriseTestSuite) TestSoftwareInstallerHostRequests() { "install_script_output": "ok" }`, *h.OrbitNodeKey, installUUID)), http.StatusNoContent) + // simulate a lock/unlock; this creates the host_mdm_actions table, which reproduces #25144 + s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/lock", h.ID), nil, http.StatusNoContent) + status, err := s.ds.GetHostLockWipeStatus(context.Background(), h) + require.NoError(t, err) + var orbitScriptResp orbitPostScriptResultResponse + s.DoJSON("POST", "/api/fleet/orbit/scripts/result", + json.RawMessage(fmt.Sprintf(`{"orbit_node_key": %q, "execution_id": %q, "exit_code": 0, "output": "ok"}`, *h.OrbitNodeKey, status.LockScript.ExecutionID)), + http.StatusOK, &orbitScriptResp) + s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/unlock", h.ID), nil, http.StatusNoContent) + status, err = s.ds.GetHostLockWipeStatus(context.Background(), h) + require.NoError(t, err) + s.DoJSON("POST", "/api/fleet/orbit/scripts/result", + json.RawMessage(fmt.Sprintf(`{"orbit_node_key": %q, "execution_id": %q, "exit_code": 0, "output": "ok"}`, *h.OrbitNodeKey, status.UnlockScript.ExecutionID)), + http.StatusOK, &orbitScriptResp) + // Do uninstall s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/software/%d/uninstall", h.ID, titleID), nil, http.StatusAccepted, &resp) s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d/software", h.ID), nil, http.StatusOK, &getHostSoftwareResp)