From f7e97f74816281520c0eb2455785efdfffb3150d Mon Sep 17 00:00:00 2001 From: Martin Angers Date: Mon, 20 Jan 2025 08:56:39 -0500 Subject: [PATCH] Unified Queue: implement correct fleet-initiated flag and setup experience priority (#25448) --- ee/server/service/setup_experience.go | 12 ++- ee/server/service/setup_experience_test.go | 2 +- ee/server/service/software_installers.go | 92 +++++++++++-------- ee/server/service/software_installers_test.go | 2 +- server/datastore/mysql/activities.go | 13 +-- server/datastore/mysql/activities_test.go | 17 ++-- server/datastore/mysql/hosts_test.go | 2 +- server/datastore/mysql/policies_test.go | 4 +- server/datastore/mysql/scripts.go | 3 +- server/datastore/mysql/software_installers.go | 23 +++-- .../mysql/software_installers_test.go | 32 +++---- server/datastore/mysql/software_test.go | 4 +- .../datastore/mysql/software_titles_test.go | 2 +- server/datastore/mysql/vpp.go | 23 +++-- server/datastore/mysql/vpp_test.go | 6 +- server/fleet/datastore.go | 4 +- server/fleet/service.go | 4 +- server/fleet/software_installer.go | 8 ++ server/mock/datastore_mock.go | 12 +-- server/service/integration_core_test.go | 2 +- server/service/osquery.go | 11 ++- server/service/software_installers.go | 2 +- 22 files changed, 156 insertions(+), 124 deletions(-) diff --git a/ee/server/service/setup_experience.go b/ee/server/service/setup_experience.go index ab733e5441a5..508597497fa4 100644 --- a/ee/server/service/setup_experience.go +++ b/ee/server/service/setup_experience.go @@ -178,8 +178,10 @@ func (svc *Service) SetupExperienceNextStep(ctx context.Context, hostUUID string case len(installersPending) > 0: // enqueue installers for _, installer := range installersPending { - // TODO(mna): this should be top priority as this is setup exp. - installUUID, err := svc.ds.InsertSoftwareInstallRequest(ctx, host.ID, *installer.SoftwareInstallerID, false, nil) + installUUID, err := svc.ds.InsertSoftwareInstallRequest(ctx, host.ID, *installer.SoftwareInstallerID, fleet.HostSoftwareInstallOptions{ + SelfService: false, + ForSetupExperience: true, + }) if err != nil { return false, ctxerr.Wrap(ctx, err, "queueing setup experience install request") } @@ -208,8 +210,10 @@ func (svc *Service) SetupExperienceNextStep(ctx context.Context, hostUUID string }, } - // TODO(mna): setup experience must be higher-priority - cmdUUID, err := svc.installSoftwareFromVPP(ctx, host, vppApp, true, false) + cmdUUID, err := svc.installSoftwareFromVPP(ctx, host, vppApp, true, fleet.HostSoftwareInstallOptions{ + SelfService: false, + ForSetupExperience: true, + }) if err != nil { return false, ctxerr.Wrap(ctx, err, "queueing vpp app installation") } diff --git a/ee/server/service/setup_experience_test.go b/ee/server/service/setup_experience_test.go index 444851c49e2b..290b52912023 100644 --- a/ee/server/service/setup_experience_test.go +++ b/ee/server/service/setup_experience_test.go @@ -56,7 +56,7 @@ func TestSetupExperienceNextStep(t *testing.T) { return mockListHostsLite, nil } - ds.InsertSoftwareInstallRequestFunc = func(ctx context.Context, hostID, softwareInstallerID uint, selfService bool, policyID *uint) (string, error) { + ds.InsertSoftwareInstallRequestFunc = func(ctx context.Context, hostID, softwareInstallerID uint, opts fleet.HostSoftwareInstallOptions) (string, error) { requestedInstalls[hostID] = append(requestedInstalls[hostID], softwareInstallerID) return "install-uuid", nil } diff --git a/ee/server/service/software_installers.go b/ee/server/service/software_installers.go index 8b60ad84a2bb..57ac69a6d222 100644 --- a/ee/server/service/software_installers.go +++ b/ee/server/service/software_installers.go @@ -16,7 +16,6 @@ import ( "github.com/fleetdm/fleet/v4/pkg/file" "github.com/fleetdm/fleet/v4/pkg/fleethttp" - "github.com/fleetdm/fleet/v4/server/authz" authz_ctx "github.com/fleetdm/fleet/v4/server/contexts/authz" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" hostctx "github.com/fleetdm/fleet/v4/server/contexts/host" @@ -1001,17 +1000,19 @@ func (svc *Service) InstallSoftwareTitle(ctx context.Context, hostID uint, softw return ctxerr.Wrap(ctx, err, "finding VPP app for title") } - _, err = svc.installSoftwareFromVPP(ctx, host, vppApp, mobileAppleDevice || fleet.AppleDevicePlatform(platform) == fleet.MacOSPlatform, false) + _, err = svc.installSoftwareFromVPP(ctx, host, vppApp, mobileAppleDevice || fleet.AppleDevicePlatform(platform) == fleet.MacOSPlatform, fleet.HostSoftwareInstallOptions{ + SelfService: false, + }) return err } -func (svc *Service) installSoftwareFromVPP(ctx context.Context, host *fleet.Host, vppApp *fleet.VPPApp, appleDevice bool, selfService bool) (string, error) { +func (svc *Service) installSoftwareFromVPP(ctx context.Context, host *fleet.Host, vppApp *fleet.VPPApp, appleDevice bool, opts fleet.HostSoftwareInstallOptions) (string, error) { token, err := svc.GetVPPTokenIfCanInstallVPPApps(ctx, appleDevice, host) if err != nil { return "", err } - return svc.InstallVPPAppPostValidation(ctx, host, vppApp, token, selfService, nil) + return svc.InstallVPPAppPostValidation(ctx, host, vppApp, token, opts) } func (svc *Service) GetVPPTokenIfCanInstallVPPApps(ctx context.Context, appleDevice bool, host *fleet.Host) (string, error) { @@ -1057,7 +1058,7 @@ func (svc *Service) GetVPPTokenIfCanInstallVPPApps(ctx context.Context, appleDev return token, nil } -func (svc *Service) InstallVPPAppPostValidation(ctx context.Context, host *fleet.Host, vppApp *fleet.VPPApp, token string, selfService bool, policyID *uint) (string, error) { +func (svc *Service) InstallVPPAppPostValidation(ctx context.Context, host *fleet.Host, vppApp *fleet.VPPApp, token string, opts fleet.HostSoftwareInstallOptions) (string, error) { // at this moment, neither the UI nor the back-end are prepared to // handle [asyncronous errors][1] on assignment, so before assigning a // device to a license, we need to: @@ -1133,7 +1134,7 @@ func (svc *Service) InstallVPPAppPostValidation(ctx context.Context, host *fleet // enqueue the VPP app command to install cmdUUID := uuid.NewString() - err = svc.ds.InsertHostVPPSoftwareInstall(ctx, host.ID, vppApp.VPPAppID, cmdUUID, eventID, selfService, policyID) + err = svc.ds.InsertHostVPPSoftwareInstall(ctx, host.ID, vppApp.VPPAppID, cmdUUID, eventID, opts) if err != nil { return "", ctxerr.Wrapf(ctx, err, "inserting host vpp software install for host with serial %s and app with adamID %s", host.HardwareSerial, vppApp.AdamID) } @@ -1159,7 +1160,9 @@ func (svc *Service) installSoftwareTitleUsingInstaller(ctx context.Context, host } } - _, err := svc.ds.InsertSoftwareInstallRequest(ctx, host.ID, installer.InstallerID, false, nil) + _, err := svc.ds.InsertSoftwareInstallRequest(ctx, host.ID, installer.InstallerID, fleet.HostSoftwareInstallOptions{ + SelfService: false, + }) return ctxerr.Wrap(ctx, err, "inserting software install request") } @@ -1249,40 +1252,45 @@ func (svc *Service) UninstallSoftwareTitle(ctx context.Context, hostID uint, sof } } - // Get the uninstall script and use the standard script infrastructure to run it. - contents, err := svc.ds.GetAnyScriptContents(ctx, installer.UninstallScriptContentID) - if err != nil { - if fleet.IsNotFound(err) { - return ctxerr.Wrap(ctx, - fleet.NewInvalidArgumentError("software_title_id", `No uninstall script exists for the provided "software_title_id".`). - WithStatus(http.StatusNotFound), "getting uninstall script contents") - } - return err - } - - var teamID uint - if host.TeamID != nil { - teamID = *host.TeamID - } - // create the script execution request; the host will be notified of the - // script execution request via the orbit config's Notifications mechanism. - request := fleet.HostScriptRequestPayload{ - HostID: host.ID, - ScriptContents: string(contents), - ScriptContentID: installer.UninstallScriptContentID, - TeamID: teamID, - } - if ctxUser := authz.UserFromContext(ctx); ctxUser != nil { - request.UserID = &ctxUser.ID - } - scriptResult, err := svc.ds.NewInternalScriptExecutionRequest(ctx, &request) - if err != nil { - return ctxerr.Wrap(ctx, err, "create script execution request") - } + // TODO(mna): an uninstall request will first go in the upcoming_activities + // queue, and only when that activity is ready to run will the internal script + // be created in host_script_requests. Keeping it here but commented, for when + // we implement the queue execution. + + // // Get the uninstall script and use the standard script infrastructure to run it. + // contents, err := svc.ds.GetAnyScriptContents(ctx, installer.UninstallScriptContentID) + // if err != nil { + // if fleet.IsNotFound(err) { + // return ctxerr.Wrap(ctx, + // fleet.NewInvalidArgumentError("software_title_id", `No uninstall script exists for the provided "software_title_id".`). + // WithStatus(http.StatusNotFound), "getting uninstall script contents") + // } + // return err + // } + // var teamID uint + // if host.TeamID != nil { + // teamID = *host.TeamID + // } + // // create the script execution request; the host will be notified of the + // // script execution request via the orbit config's Notifications mechanism. + // request := fleet.HostScriptRequestPayload{ + // HostID: host.ID, + // ScriptContents: string(contents), + // ScriptContentID: installer.UninstallScriptContentID, + // TeamID: teamID, + // } + // if ctxUser := authz.UserFromContext(ctx); ctxUser != nil { + // request.UserID = &ctxUser.ID + // } + // scriptResult, err := svc.ds.NewInternalScriptExecutionRequest(ctx, &request) + // if err != nil { + // return ctxerr.Wrap(ctx, err, "create script execution request") + // } // Update the host software installs table with the uninstall request. // Pending uninstalls will automatically show up in the UI Host Details -> Activity -> Upcoming tab. - if err = svc.insertSoftwareUninstallRequest(ctx, scriptResult.ExecutionID, host, installer); err != nil { + execID := uuid.NewString() + if err = svc.insertSoftwareUninstallRequest(ctx, execID, host, installer); err != nil { return err } @@ -1830,7 +1838,9 @@ func (svc *Service) SelfServiceInstallSoftwareTitle(ctx context.Context, host *f } } - _, err = svc.ds.InsertSoftwareInstallRequest(ctx, host.ID, installer.InstallerID, true, nil) + _, err = svc.ds.InsertSoftwareInstallRequest(ctx, host.ID, installer.InstallerID, fleet.HostSoftwareInstallOptions{ + SelfService: true, + }) return ctxerr.Wrap(ctx, err, "inserting self-service software install request") } @@ -1864,7 +1874,9 @@ func (svc *Service) SelfServiceInstallSoftwareTitle(ctx context.Context, host *f platform := host.FleetPlatform() mobileAppleDevice := fleet.AppleDevicePlatform(platform) == fleet.IOSPlatform || fleet.AppleDevicePlatform(platform) == fleet.IPadOSPlatform - _, err = svc.installSoftwareFromVPP(ctx, host, vppApp, mobileAppleDevice || fleet.AppleDevicePlatform(platform) == fleet.MacOSPlatform, true) + _, err = svc.installSoftwareFromVPP(ctx, host, vppApp, mobileAppleDevice || fleet.AppleDevicePlatform(platform) == fleet.MacOSPlatform, fleet.HostSoftwareInstallOptions{ + SelfService: true, + }) return err } diff --git a/ee/server/service/software_installers_test.go b/ee/server/service/software_installers_test.go index 769d91b7aed9..c1c95d830114 100644 --- a/ee/server/service/software_installers_test.go +++ b/ee/server/service/software_installers_test.go @@ -105,7 +105,7 @@ func TestInstallUninstallAuth(t *testing.T) { ds.GetHostLastInstallDataFunc = func(ctx context.Context, hostID uint, installerID uint) (*fleet.HostLastInstallData, error) { return nil, nil } - ds.InsertSoftwareInstallRequestFunc = func(ctx context.Context, hostID uint, softwareInstallerID uint, selfService bool, policyID *uint) (string, + ds.InsertSoftwareInstallRequestFunc = func(ctx context.Context, hostID uint, softwareInstallerID uint, opts fleet.HostSoftwareInstallOptions) (string, error, ) { return "request_id", nil diff --git a/server/datastore/mysql/activities.go b/server/datastore/mysql/activities.go index b5814677f8cb..3c8ecafa98a0 100644 --- a/server/datastore/mysql/activities.go +++ b/server/datastore/mysql/activities.go @@ -266,10 +266,9 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint listStmts := []string{ // list pending scripts - // TODO(mna): should the user name IF use fleet_initiated? `SELECT ua.execution_id as uuid, - IF(sua.policy_id IS NOT NULL, 'Fleet', COALESCE(u.name, JSON_EXTRACT(ua.payload, '$.user.name'))) as name, + IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, JSON_EXTRACT(ua.payload, '$.user.name'))) as name, u.id as user_id, COALESCE(u.gravatar_url, JSON_EXTRACT(ua.payload, '$.user.gravatar_url')) as gravatar_url, COALESCE(u.email, JSON_EXTRACT(ua.payload, '$.user.email')) as user_email, @@ -307,12 +306,9 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint ua.activity_type = 'script' `, // list pending software installs - // TODO(mna): should the user name IF use fleet_initiated? `SELECT ua.execution_id as uuid, - -- policies with automatic installers generate a host_software_installs with (user_id=NULL,self_service=0), - -- so we mark those as "Fleet" - IF(ua.user_id IS NULL AND NOT JSON_EXTRACT(ua.payload, '$.self_service'), 'Fleet', COALESCE(u.name, JSON_EXTRACT(ua.payload, '$.user.name'))) AS name, + IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, JSON_EXTRACT(ua.payload, '$.user.name'))) AS name, ua.user_id as user_id, COALESCE(u.gravatar_url, JSON_EXTRACT(ua.payload, '$.user.gravatar_url')) as gravatar_url, COALESCE(u.email, JSON_EXTRACT(ua.payload, '$.user.email')) as user_email, @@ -352,12 +348,9 @@ func (ds *Datastore) ListHostUpcomingActivities(ctx context.Context, hostID uint ua.activity_type = 'software_install' `, // list pending software uninstalls - // TODO(mna): should the user name IF use fleet_initiated? `SELECT ua.execution_id as uuid, - -- policies with automatic installers generate a host_software_installs with (user_id=NULL,self_service=0), - -- so we mark those as "Fleet" - IF(ua.user_id IS NULL, 'Fleet', COALESCE(u.name, JSON_EXTRACT(ua.payload, '$.user.name'))) AS name, + IF(ua.fleet_initiated, 'Fleet', COALESCE(u.name, JSON_EXTRACT(ua.payload, '$.user.name'))) AS name, ua.user_id as user_id, COALESCE(u.gravatar_url, JSON_EXTRACT(ua.payload, '$.user.gravatar_url')) as gravatar_url, COALESCE(u.email, JSON_EXTRACT(ua.payload, '$.user.email')) as user_email, diff --git a/server/datastore/mysql/activities_test.go b/server/datastore/mysql/activities_test.go index e18df75ea9ac..696a65fcf1fb 100644 --- a/server/datastore/mysql/activities_test.go +++ b/server/datastore/mysql/activities_test.go @@ -457,7 +457,7 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { // install the VPP app on h1 // commander, _ := createMDMAppleCommanderAndStorage(t, ds) - err = ds.InsertHostVPPSoftwareInstall(ctx, h1.ID, vppApp.VPPAppID, vppCommand1, "event-id-1", false, nil) + err = ds.InsertHostVPPSoftwareInstall(ctx, h1.ID, vppApp.VPPAppID, vppCommand1, "event-id-1", fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // err = commander.EnqueueCommand( // ctx, @@ -466,7 +466,7 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { // ) // require.NoError(t, err) // install the VPP app on h2, self-service - err = ds.InsertHostVPPSoftwareInstall(noUserCtx, h2.ID, vppApp.VPPAppID, vppCommand2, "event-id-2", true, nil) + err = ds.InsertHostVPPSoftwareInstall(noUserCtx, h2.ID, vppApp.VPPAppID, vppCommand2, "event-id-2", fleet.HostSoftwareInstallOptions{SelfService: true}) require.NoError(t, err) // err = commander.EnqueueCommand( // ctx, @@ -516,7 +516,7 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { // create some software installs requests for h1, make some complete // h1FooFailed, err := ds.InsertSoftwareInstallRequest(ctx, h1.ID, sw1Meta.InstallerID, false, nil) // require.NoError(t, err) - h1Bar, err := ds.InsertSoftwareInstallRequest(ctx, h1.ID, sw2Meta.InstallerID, false, nil) + h1Bar, err := ds.InsertSoftwareInstallRequest(ctx, h1.ID, sw2Meta.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) t.Log("h1Bar", h1Bar) // err = ds.SetHostSoftwareInstallResult(ctx, &fleet.HostSoftwareInstallResultPayload{ @@ -541,7 +541,7 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { Query: "SELECT 1", }) require.NoError(t, err) - h1Fleet, err := ds.InsertSoftwareInstallRequest(noUserCtx, h1.ID, sw1Meta.InstallerID, false, &policy.ID) + h1Fleet, err := ds.InsertSoftwareInstallRequest(noUserCtx, h1.ID, sw1Meta.InstallerID, fleet.HostSoftwareInstallOptions{PolicyID: &policy.ID}) t.Log("h1Fleet", h1Fleet) require.NoError(t, err) @@ -557,11 +557,11 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { // require.NoError(t, err) // h2F := hsr.ExecutionID // add a pending software install request for h2 - h2Bar, err := ds.InsertSoftwareInstallRequest(ctx, h2.ID, sw2Meta.InstallerID, false, nil) + h2Bar, err := ds.InsertSoftwareInstallRequest(ctx, h2.ID, sw2Meta.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) t.Log("h2Bar", h2Bar) // No user for this one and Self-service, means it was installed by the end user, so the user_id should be null/nil. - h2SelfService, err := ds.InsertSoftwareInstallRequest(noUserCtx, h2.ID, sw1Meta.InstallerID, true, nil) + h2SelfService, err := ds.InsertSoftwareInstallRequest(noUserCtx, h2.ID, sw1Meta.InstallerID, fleet.HostSoftwareInstallOptions{SelfService: true}) require.NoError(t, err) t.Log("h2SelfService", h2SelfService) @@ -576,7 +576,7 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { t.Log("h2SetupExp", h2SetupExp) // create pending install and uninstall requests for h3 that will be deleted - _, err = ds.InsertSoftwareInstallRequest(ctx, h3.ID, sw3Meta.InstallerID, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, h3.ID, sw3Meta.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) err = ds.InsertSoftwareUninstallRequest(ctx, "uninstallRun", h3.ID, sw3Meta.InstallerID) require.NoError(t, err) @@ -764,8 +764,7 @@ func testListHostUpcomingActivities(t *testing.T, ds *Datastore) { require.Equal(t, wantUser.Email, *a.ActorEmail, "result %d", i) } else { require.Nil(t, a.ActorID, "result %d", i) - // TODO(mna): this should probably become consistent across activity types, all based on fleet_initiated - if a.Type == (fleet.ActivityInstalledAppStoreApp{}.ActivityName()) { + if a.FleetInitiated { require.NotNil(t, a.ActorFullName, "result %d", i) require.Equal(t, "Fleet", *a.ActorFullName, "result %d", i) } else { diff --git a/server/datastore/mysql/hosts_test.go b/server/datastore/mysql/hosts_test.go index 7b4319c5b0cc..04c53f12aba0 100644 --- a/server/datastore/mysql/hosts_test.go +++ b/server/datastore/mysql/hosts_test.go @@ -7030,7 +7030,7 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) { ValidatedLabels: &fleet.LabelIdentsWithScope{}, }) require.NoError(t, err) - _, err = ds.InsertSoftwareInstallRequest(context.Background(), host.ID, softwareInstaller, false, nil) + _, err = ds.InsertSoftwareInstallRequest(context.Background(), host.ID, softwareInstaller, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // Add an awaiting configuration entry diff --git a/server/datastore/mysql/policies_test.go b/server/datastore/mysql/policies_test.go index 9421a706b5a1..b8f763a9cd03 100644 --- a/server/datastore/mysql/policies_test.go +++ b/server/datastore/mysql/policies_test.go @@ -308,7 +308,7 @@ func testGlobalPolicyPendingScriptsAndInstalls(t *testing.T, ds *Datastore) { require.Len(t, policies, 1) // create a pending software install request - _, err = ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID, false, &policy2.ID) + _, err = ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID, fleet.HostSoftwareInstallOptions{PolicyID: &policy2.ID}) require.NoError(t, err) pendingInstalls, err := ds.ListPendingSoftwareInstalls(ctx, host2.ID) @@ -900,7 +900,7 @@ func testTeamPolicyPendingScriptsAndInstalls(t *testing.T, ds *Datastore) { }) require.NoError(t, err) // create a pending software install request - _, err = ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID, false, &policy2.ID) + _, err = ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID, fleet.HostSoftwareInstallOptions{PolicyID: &policy2.ID}) require.NoError(t, err) pendingInstalls, err := ds.ListPendingSoftwareInstalls(ctx, host2.ID) diff --git a/server/datastore/mysql/scripts.go b/server/datastore/mysql/scripts.go index 0e685ff83015..d928716e39a1 100644 --- a/server/datastore/mysql/scripts.go +++ b/server/datastore/mysql/scripts.go @@ -48,6 +48,7 @@ func (ds *Datastore) NewHostScriptExecutionRequest(ctx context.Context, request }) } +// TODO(mna): might become unused after unified queue implementation func (ds *Datastore) NewInternalScriptExecutionRequest(ctx context.Context, request *fleet.HostScriptRequestPayload) (*fleet.HostScriptResult, error) { var res *fleet.HostScriptResult var err error @@ -109,7 +110,7 @@ WHERE request.HostID, priority, request.UserID, - isInternal || request.UserID == nil, // TODO(mna): confirm if this makes sense + request.PolicyID != nil, // fleet-initiated if request is via a policy failure execID, request.SyncRequest, isInternal, diff --git a/server/datastore/mysql/software_installers.go b/server/datastore/mysql/software_installers.go index 2a0623a0c1bd..db11afc59cd6 100644 --- a/server/datastore/mysql/software_installers.go +++ b/server/datastore/mysql/software_installers.go @@ -753,7 +753,7 @@ func (ds *Datastore) deletePendingSoftwareInstallsForPolicy(ctx context.Context, return nil } -func (ds *Datastore) InsertSoftwareInstallRequest(ctx context.Context, hostID uint, softwareInstallerID uint, selfService bool, policyID *uint) (string, error) { +func (ds *Datastore) InsertSoftwareInstallRequest(ctx context.Context, hostID uint, softwareInstallerID uint, opts fleet.HostSoftwareInstallOptions) (string, error) { const ( getInstallerStmt = ` SELECT @@ -812,40 +812,45 @@ VALUES return "", ctxerr.Wrap(ctx, err, "getting installer data") } + fleetInitiated := !opts.SelfService && opts.PolicyID != nil + var priority int + if opts.ForSetupExperience { + // a bit naive/simplistic for now, but we'll support user-provided + // priorities in a future story and we can improve on how we manage those. + priority = 100 + } var userID *uint - fleetInitiated := true - if ctxUser := authz.UserFromContext(ctx); ctxUser != nil { + if ctxUser := authz.UserFromContext(ctx); ctxUser != nil && opts.PolicyID == nil { userID = &ctxUser.ID - fleetInitiated = false } execID := uuid.NewString() err = ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { res, err := tx.ExecContext(ctx, insertUAStmt, hostID, - 0, // TODO(mna): detect if this is software install for setup exp, to boost priority + priority, userID, fleetInitiated, execID, - selfService, + opts.SelfService, installerDetails.Filename, installerDetails.Version, installerDetails.TitleName, userID, ) if err != nil { - return err + return ctxerr.Wrap(ctx, err, "insert software install request") } activityID, _ := res.LastInsertId() _, err = tx.ExecContext(ctx, insertSIUAStmt, activityID, softwareInstallerID, - policyID, + opts.PolicyID, installerDetails.TitleID, ) if err != nil { - return err + return ctxerr.Wrap(ctx, err, "insert software install request join table") } return nil }) diff --git a/server/datastore/mysql/software_installers_test.go b/server/datastore/mysql/software_installers_test.go index 10af59f9cbcf..304abcad5f43 100644 --- a/server/datastore/mysql/software_installers_test.go +++ b/server/datastore/mysql/software_installers_test.go @@ -126,19 +126,19 @@ func testListPendingSoftwareInstalls(t *testing.T, ds *Datastore) { }) require.NoError(t, err) - hostInstall1, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID1, false, nil) + hostInstall1, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID1, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) time.Sleep(time.Millisecond) - hostInstall2, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID2, false, nil) + hostInstall2, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID2, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) time.Sleep(time.Millisecond) - hostInstall3, err := ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID1, false, nil) + hostInstall3, err := ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID1, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) time.Sleep(time.Millisecond) - hostInstall4, err := ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID2, false, nil) + hostInstall4, err := ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID2, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) pendingHost1, err := ds.ListPendingSoftwareInstalls(ctx, host1.ID) @@ -291,7 +291,7 @@ func testSoftwareInstallRequests(t *testing.T, ds *Datastore) { require.Equal(t, "foo.pkg", si.Name) // non-existent host - _, err = ds.InsertSoftwareInstallRequest(ctx, 12, si.InstallerID, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, 12, si.InstallerID, fleet.HostSoftwareInstallOptions{}) require.ErrorAs(t, err, &nfe) // Host with software install pending @@ -305,7 +305,7 @@ func testSoftwareInstallRequests(t *testing.T, ds *Datastore) { TeamID: teamID, }) require.NoError(t, err) - _, err = ds.InsertSoftwareInstallRequest(ctx, hostPendingInstall.ID, si.InstallerID, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, hostPendingInstall.ID, si.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // Host with software install failed @@ -319,7 +319,7 @@ func testSoftwareInstallRequests(t *testing.T, ds *Datastore) { TeamID: teamID, }) require.NoError(t, err) - _, err = ds.InsertSoftwareInstallRequest(ctx, hostFailedInstall.ID, si.InstallerID, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, hostFailedInstall.ID, si.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { // _, err = q.ExecContext(ctx, ` @@ -340,7 +340,7 @@ func testSoftwareInstallRequests(t *testing.T, ds *Datastore) { TeamID: teamID, }) require.NoError(t, err) - _, err = ds.InsertSoftwareInstallRequest(ctx, hostInstalled.ID, si.InstallerID, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, hostInstalled.ID, si.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { // _, err = q.ExecContext(ctx, ` @@ -600,7 +600,7 @@ func testGetSoftwareInstallResult(t *testing.T, ds *Datastore) { require.NoError(t, err) beforeInstallRequest := time.Now() - installUUID, err := ds.InsertSoftwareInstallRequest(ctx, host.ID, installerID, false, nil) + installUUID, err := ds.InsertSoftwareInstallRequest(ctx, host.ID, installerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) res, err := ds.GetSoftwareInstallResults(ctx, installUUID) @@ -1298,7 +1298,7 @@ func testDeletePendingSoftwareInstallsForPolicy(t *testing.T, ds *Datastore) { var count int // install for correct policy & correct status - executionID, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID1, false, &policy1.ID) + executionID, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID1, fleet.HostSoftwareInstallOptions{PolicyID: &policy1.ID}) require.NoError(t, err) err = sqlx.GetContext(ctx, ds.reader(ctx), &count, hostSoftwareInstallsCount, fleet.SoftwareInstallPending, executionID) @@ -1313,7 +1313,7 @@ func testDeletePendingSoftwareInstallsForPolicy(t *testing.T, ds *Datastore) { require.Equal(t, 0, count) // install for different policy & correct status - executionID, err = ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID2, false, &policy2.ID) + executionID, err = ds.InsertSoftwareInstallRequest(ctx, host1.ID, installerID2, fleet.HostSoftwareInstallOptions{PolicyID: &policy2.ID}) require.NoError(t, err) err = sqlx.GetContext(ctx, ds.reader(ctx), &count, hostSoftwareInstallsCount, fleet.SoftwareInstallPending, executionID) @@ -1328,7 +1328,7 @@ func testDeletePendingSoftwareInstallsForPolicy(t *testing.T, ds *Datastore) { require.Equal(t, 1, count) // install for correct policy & incorrect status - executionID, err = ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID1, false, &policy1.ID) + executionID, err = ds.InsertSoftwareInstallRequest(ctx, host2.ID, installerID1, fleet.HostSoftwareInstallOptions{PolicyID: &policy1.ID}) require.NoError(t, err) err = ds.SetHostSoftwareInstallResult(ctx, &fleet.HostSoftwareInstallResultPayload{ @@ -1402,7 +1402,7 @@ func testGetHostLastInstallData(t *testing.T, ds *Datastore) { require.Nil(t, host1LastInstall) // Install installer.pkg on host1. - installUUID1, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, softwareInstallerID1, false, nil) + installUUID1, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, softwareInstallerID1, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) require.NotEmpty(t, installUUID1) @@ -1432,7 +1432,7 @@ func testGetHostLastInstallData(t *testing.T, ds *Datastore) { require.Equal(t, fleet.SoftwareInstalled, *host1LastInstall.Status) // Install installer2.pkg on host1. - installUUID2, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, softwareInstallerID2, false, nil) + installUUID2, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, softwareInstallerID2, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) require.NotEmpty(t, installUUID2) @@ -1452,7 +1452,7 @@ func testGetHostLastInstallData(t *testing.T, ds *Datastore) { require.Equal(t, fleet.SoftwareInstallPending, *host1LastInstall.Status) // Perform another installation of installer1.pkg. - installUUID3, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, softwareInstallerID1, false, nil) + installUUID3, err := ds.InsertSoftwareInstallRequest(ctx, host1.ID, softwareInstallerID1, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) require.NotEmpty(t, installUUID3) @@ -1751,7 +1751,7 @@ func testBatchSetSoftwareInstallersScopedViaLabels(t *testing.T, ds *Datastore) globalOrTeamID, payload.Installer.Title, payload.Installer.Source) return err }) - _, err = ds.InsertSoftwareInstallRequest(ctx, host.ID, swID, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, host.ID, swID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) installerIDs[i] = swID } diff --git a/server/datastore/mysql/software_test.go b/server/datastore/mysql/software_test.go index d654a9e0ad4f..b46e7bd82d36 100644 --- a/server/datastore/mysql/software_test.go +++ b/server/datastore/mysql/software_test.go @@ -4630,7 +4630,7 @@ func testListHostSoftwareInstallThenTransferTeam(t *testing.T, ds *Datastore) { require.NoError(t, err) // install it on the host - hostInstall1, err := ds.InsertSoftwareInstallRequest(ctx, host.ID, installerTm1, false, nil) + hostInstall1, err := ds.InsertSoftwareInstallRequest(ctx, host.ID, installerTm1, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) err = ds.SetHostSoftwareInstallResult(ctx, &fleet.HostSoftwareInstallResultPayload{ HostID: host.ID, @@ -4743,7 +4743,7 @@ func testListHostSoftwareInstallThenDeleteInstallers(t *testing.T, ds *Datastore require.NoError(t, err) // fail to install it on the host - hostInstall1, err := ds.InsertSoftwareInstallRequest(ctx, host.ID, installerTm1, false, nil) + hostInstall1, err := ds.InsertSoftwareInstallRequest(ctx, host.ID, installerTm1, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) err = ds.SetHostSoftwareInstallResult(ctx, &fleet.HostSoftwareInstallResultPayload{ HostID: host.ID, diff --git a/server/datastore/mysql/software_titles_test.go b/server/datastore/mysql/software_titles_test.go index 585c695f81ec..58b652ca680a 100644 --- a/server/datastore/mysql/software_titles_test.go +++ b/server/datastore/mysql/software_titles_test.go @@ -325,7 +325,7 @@ func testOrderSoftwareTitles(t *testing.T, ds *Datastore) { ValidatedLabels: &fleet.LabelIdentsWithScope{}, }) require.NoError(t, err) - _, err = ds.InsertSoftwareInstallRequest(ctx, host1.ID, installer2, false, nil) + _, err = ds.InsertSoftwareInstallRequest(ctx, host1.ID, installer2, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) test.CreateInsertGlobalVPPToken(t, ds) diff --git a/server/datastore/mysql/vpp.go b/server/datastore/mysql/vpp.go index 141a629de82a..980de7698785 100644 --- a/server/datastore/mysql/vpp.go +++ b/server/datastore/mysql/vpp.go @@ -566,7 +566,7 @@ WHERE vat.global_or_team_id = ? AND va.title_id = ? } func (ds *Datastore) InsertHostVPPSoftwareInstall(ctx context.Context, hostID uint, appID fleet.VPPAppID, - commandUUID, associatedEventID string, selfService bool, policyID *uint, + commandUUID, associatedEventID string, opts fleet.HostSoftwareInstallOptions, ) error { const ( insertUAStmt = ` @@ -601,26 +601,31 @@ VALUES return ctxerr.Wrap(ctx, err, "checking if host exists") } + fleetInitiated := !opts.SelfService && opts.PolicyID != nil + var priority int + if opts.ForSetupExperience { + // a bit naive/simplistic for now, but we'll support user-provided + // priorities in a future story and we can improve on how we manage those. + priority = 100 + } var userID *uint - fleetInitiated := true - if ctxUser := authz.UserFromContext(ctx); ctxUser != nil && policyID == nil { + if ctxUser := authz.UserFromContext(ctx); ctxUser != nil && opts.PolicyID == nil { userID = &ctxUser.ID - fleetInitiated = false } err = ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { res, err := tx.ExecContext(ctx, insertUAStmt, hostID, - 0, // TODO(mna): detect if this is software install for setup exp, to boost priority + priority, userID, fleetInitiated, commandUUID, - selfService, + opts.SelfService, associatedEventID, userID, ) if err != nil { - return err + return ctxerr.Wrap(ctx, err, "insert vpp install request") } activityID, _ := res.LastInsertId() @@ -628,10 +633,10 @@ VALUES activityID, appID.AdamID, appID.Platform, - policyID, + opts.PolicyID, ) if err != nil { - return err + return ctxerr.Wrap(ctx, err, "insert vpp install request join table") } return nil }) diff --git a/server/datastore/mysql/vpp_test.go b/server/datastore/mysql/vpp_test.go index 9712c1138c7b..973b1a91e87d 100644 --- a/server/datastore/mysql/vpp_test.go +++ b/server/datastore/mysql/vpp_test.go @@ -505,11 +505,11 @@ func testVPPApps(t *testing.T, ds *Datastore) { require.NoError(t, err) ctx = viewer.NewContext(ctx, viewer.Viewer{User: u}) - err = ds.InsertHostVPPSoftwareInstall(ctx, h1.ID, app1.VPPAppID, "a", "b", false, nil) + err = ds.InsertHostVPPSoftwareInstall(ctx, h1.ID, app1.VPPAppID, "a", "b", fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // non-existing host - err = ds.InsertHostVPPSoftwareInstall(ctx, h1.ID+1, app2.VPPAppID, "c", "d", true, nil) + err = ds.InsertHostVPPSoftwareInstall(ctx, h1.ID+1, app2.VPPAppID, "c", "d", fleet.HostSoftwareInstallOptions{SelfService: true}) require.Error(t, err) var nfe fleet.NotFoundError require.ErrorAs(t, err, &nfe) @@ -524,7 +524,7 @@ func testVPPApps(t *testing.T, ds *Datastore) { HardwareSerial: "654321b", }) require.NoError(t, err) - err = ds.InsertHostVPPSoftwareInstall(ctx, h2.ID, app2.VPPAppID, "c", "d", true, nil) + err = ds.InsertHostVPPSoftwareInstall(ctx, h2.ID, app2.VPPAppID, "c", "d", fleet.HostSoftwareInstallOptions{SelfService: true}) require.NoError(t, err) acts, _, err := ds.ListHostUpcomingActivities(ctx, h1.ID, fleet.ListOptions{}) diff --git a/server/fleet/datastore.go b/server/fleet/datastore.go index 03eac549f4c8..0adf6e5fb470 100644 --- a/server/fleet/datastore.go +++ b/server/fleet/datastore.go @@ -548,7 +548,7 @@ type Datastore interface { // InsertSoftwareInstallRequest tracks a new request to install the provided // software installer in the host. It returns the auto-generated installation // uuid. - InsertSoftwareInstallRequest(ctx context.Context, hostID uint, softwareInstallerID uint, selfService bool, policyID *uint) (string, error) + InsertSoftwareInstallRequest(ctx context.Context, hostID uint, softwareInstallerID uint, opts HostSoftwareInstallOptions) (string, error) // InsertSoftwareUninstallRequest tracks a new request to uninstall the provided // software installer on the host. executionID is the script execution ID corresponding to uninstall script InsertSoftwareUninstallRequest(ctx context.Context, executionID string, hostID uint, softwareInstallerID uint) error @@ -1821,7 +1821,7 @@ type Datastore interface { SetTeamVPPApps(ctx context.Context, teamID *uint, appIDs []VPPAppTeam) error InsertVPPAppWithTeam(ctx context.Context, app *VPPApp, teamID *uint) (*VPPApp, error) - InsertHostVPPSoftwareInstall(ctx context.Context, hostID uint, appID VPPAppID, commandUUID, associatedEventID string, selfService bool, policyID *uint) error + InsertHostVPPSoftwareInstall(ctx context.Context, hostID uint, appID VPPAppID, commandUUID, associatedEventID string, opts HostSoftwareInstallOptions) error GetPastActivityDataForVPPAppInstall(ctx context.Context, commandResults *mdm.CommandResults) (*User, *ActivityInstalledAppStoreApp, error) GetVPPTokenByLocation(ctx context.Context, loc string) (*VPPTokenDB, error) diff --git a/server/fleet/service.go b/server/fleet/service.go index 80ebb0b17cd9..18745284a111 100644 --- a/server/fleet/service.go +++ b/server/fleet/service.go @@ -37,7 +37,7 @@ type EnterpriseOverrides struct { MDMAppleEditedAppleOSUpdates func(ctx context.Context, teamID *uint, appleDevice AppleDevice, updates AppleOSUpdateSettings) error SetupExperienceNextStep func(ctx context.Context, hostUUID string) (bool, error) GetVPPTokenIfCanInstallVPPApps func(ctx context.Context, appleDevice bool, host *Host) (string, error) - InstallVPPAppPostValidation func(ctx context.Context, host *Host, vppApp *VPPApp, token string, selfService bool, policyID *uint) (string, error) + InstallVPPAppPostValidation func(ctx context.Context, host *Host, vppApp *VPPApp, token string, opts HostSoftwareInstallOptions) (string, error) } type OsqueryService interface { @@ -654,7 +654,7 @@ type Service interface { GetVPPTokenIfCanInstallVPPApps(ctx context.Context, appleDevice bool, host *Host) (string, error) // InstallVPPAppPostValidation installs a VPP app, assuming that GetVPPTokenIfCanInstallVPPApps has passed and provided a VPP token - InstallVPPAppPostValidation(ctx context.Context, host *Host, vppApp *VPPApp, token string, selfService bool, policyID *uint) (string, error) + InstallVPPAppPostValidation(ctx context.Context, host *Host, vppApp *VPPApp, token string, opts HostSoftwareInstallOptions) (string, error) // UninstallSoftwareTitle uninstalls a software title in the given host. UninstallSoftwareTitle(ctx context.Context, hostID uint, softwareTitleID uint) error diff --git a/server/fleet/software_installer.go b/server/fleet/software_installer.go index 8ca8e9346ad5..e24ba32fb294 100644 --- a/server/fleet/software_installer.go +++ b/server/fleet/software_installer.go @@ -675,3 +675,11 @@ type SoftwareScopeLabel struct { Exclude bool `db:"exclude" json:"-"` // not rendered in JSON, used when processing LabelsIncludeAny and LabelsExcludeAny on parent title (may be the empty value in some cases) TitleID uint `db:"title_id" json:"-"` // not rendered in JSON, used to store the associated title ID (may be the empty value in some cases) } + +// HostSoftwareInstallOptions contains options that apply to a software or VPP +// app install request. +type HostSoftwareInstallOptions struct { + SelfService bool + PolicyID *uint + ForSetupExperience bool +} diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index 8f154100a0a4..f608c03fc91a 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -411,7 +411,7 @@ type ListSoftwareTitlesFunc func(ctx context.Context, opt fleet.SoftwareTitleLis type SoftwareTitleByIDFunc func(ctx context.Context, id uint, teamID *uint, tmFilter fleet.TeamFilter) (*fleet.SoftwareTitle, error) -type InsertSoftwareInstallRequestFunc func(ctx context.Context, hostID uint, softwareInstallerID uint, selfService bool, policyID *uint) (string, error) +type InsertSoftwareInstallRequestFunc func(ctx context.Context, hostID uint, softwareInstallerID uint, opts fleet.HostSoftwareInstallOptions) (string, error) type InsertSoftwareUninstallRequestFunc func(ctx context.Context, executionID string, hostID uint, softwareInstallerID uint) error @@ -1149,7 +1149,7 @@ type SetTeamVPPAppsFunc func(ctx context.Context, teamID *uint, appIDs []fleet.V type InsertVPPAppWithTeamFunc func(ctx context.Context, app *fleet.VPPApp, teamID *uint) (*fleet.VPPApp, error) -type InsertHostVPPSoftwareInstallFunc func(ctx context.Context, hostID uint, appID fleet.VPPAppID, commandUUID string, associatedEventID string, selfService bool, policyID *uint) error +type InsertHostVPPSoftwareInstallFunc func(ctx context.Context, hostID uint, appID fleet.VPPAppID, commandUUID string, associatedEventID string, opts fleet.HostSoftwareInstallOptions) error type GetPastActivityDataForVPPAppInstallFunc func(ctx context.Context, commandResults *mdm.CommandResults) (*fleet.User, *fleet.ActivityInstalledAppStoreApp, error) @@ -4350,11 +4350,11 @@ func (s *DataStore) SoftwareTitleByID(ctx context.Context, id uint, teamID *uint return s.SoftwareTitleByIDFunc(ctx, id, teamID, tmFilter) } -func (s *DataStore) InsertSoftwareInstallRequest(ctx context.Context, hostID uint, softwareInstallerID uint, selfService bool, policyID *uint) (string, error) { +func (s *DataStore) InsertSoftwareInstallRequest(ctx context.Context, hostID uint, softwareInstallerID uint, opts fleet.HostSoftwareInstallOptions) (string, error) { s.mu.Lock() s.InsertSoftwareInstallRequestFuncInvoked = true s.mu.Unlock() - return s.InsertSoftwareInstallRequestFunc(ctx, hostID, softwareInstallerID, selfService, policyID) + return s.InsertSoftwareInstallRequestFunc(ctx, hostID, softwareInstallerID, opts) } func (s *DataStore) InsertSoftwareUninstallRequest(ctx context.Context, executionID string, hostID uint, softwareInstallerID uint) error { @@ -6933,11 +6933,11 @@ func (s *DataStore) InsertVPPAppWithTeam(ctx context.Context, app *fleet.VPPApp, return s.InsertVPPAppWithTeamFunc(ctx, app, teamID) } -func (s *DataStore) InsertHostVPPSoftwareInstall(ctx context.Context, hostID uint, appID fleet.VPPAppID, commandUUID string, associatedEventID string, selfService bool, policyID *uint) error { +func (s *DataStore) InsertHostVPPSoftwareInstall(ctx context.Context, hostID uint, appID fleet.VPPAppID, commandUUID string, associatedEventID string, opts fleet.HostSoftwareInstallOptions) error { s.mu.Lock() s.InsertHostVPPSoftwareInstallFuncInvoked = true s.mu.Unlock() - return s.InsertHostVPPSoftwareInstallFunc(ctx, hostID, appID, commandUUID, associatedEventID, selfService, policyID) + return s.InsertHostVPPSoftwareInstallFunc(ctx, hostID, appID, commandUUID, associatedEventID, opts) } func (s *DataStore) GetPastActivityDataForVPPAppInstall(ctx context.Context, commandResults *mdm.CommandResults) (*fleet.User, *fleet.ActivityInstalledAppStoreApp, error) { diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index 655c393b4235..bbdd630494ba 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -12116,7 +12116,7 @@ func (s *integrationTestSuite) TestListHostUpcomingActivities() { require.NoError(t, err) s1Meta, err := s.ds.GetSoftwareInstallerMetadataByID(ctx, sw1) require.NoError(t, err) - h1Foo, err := s.ds.InsertSoftwareInstallRequest(ctx, host1.ID, s1Meta.InstallerID, false, nil) + h1Foo, err := s.ds.InsertSoftwareInstallRequest(ctx, host1.ID, s1Meta.InstallerID, fleet.HostSoftwareInstallOptions{}) require.NoError(t, err) // force an order to the activities diff --git a/server/service/osquery.go b/server/service/osquery.go index 07e63c999da9..dfcbcc74ea12 100644 --- a/server/service/osquery.go +++ b/server/service/osquery.go @@ -1835,8 +1835,10 @@ func (svc *Service) processSoftwareForNewlyFailingPolicies( installUUID, err := svc.ds.InsertSoftwareInstallRequest( ctx, hostID, installerMetadata.InstallerID, - false, // Set Self-service as false because this is triggered by Fleet. - &policyID, + fleet.HostSoftwareInstallOptions{ + SelfService: false, + PolicyID: &policyID, + }, ) if err != nil { return ctxerr.Wrapf(ctx, err, @@ -1973,7 +1975,10 @@ func (svc *Service) processVPPForNewlyFailingPolicies( continue } - commandUUID, err := svc.EnterpriseOverrides.InstallVPPAppPostValidation(ctx, host, vppMetadata, vppToken, false, &policyID) + commandUUID, err := svc.EnterpriseOverrides.InstallVPPAppPostValidation(ctx, host, vppMetadata, vppToken, fleet.HostSoftwareInstallOptions{ + SelfService: false, + PolicyID: &policyID, + }) if err != nil { level.Error(svc.logger).Log( "msg", "failed to get install VPP app", diff --git a/server/service/software_installers.go b/server/service/software_installers.go index 5d7a1ffe58d5..783fc9c04be3 100644 --- a/server/service/software_installers.go +++ b/server/service/software_installers.go @@ -563,7 +563,7 @@ func (svc *Service) GetVPPTokenIfCanInstallVPPApps(ctx context.Context, appleDev return "", fleet.ErrMissingLicense // called downstream of auth checks so doesn't need skipauth } -func (svc *Service) InstallVPPAppPostValidation(ctx context.Context, host *fleet.Host, vppApp *fleet.VPPApp, token string, selfService bool, policyID *uint) (string, error) { +func (svc *Service) InstallVPPAppPostValidation(ctx context.Context, host *fleet.Host, vppApp *fleet.VPPApp, token string, opts fleet.HostSoftwareInstallOptions) (string, error) { return "", fleet.ErrMissingLicense // called downstream of auth checks so doesn't need skipauth }