Fix batch set installers not updating some fields (#40631)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #40549 Fix some settings like setup experience, self service, scripts, not being updated in BatchSetSoftwareInstallers ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually - Tested that unlocked version FMA setup experience, self service, or script changes appropriately - Tested with version locked FMA For unreleased bug fixes in a release candidate, one of: - [ ] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed
This commit is contained in:
@@ -2294,6 +2294,19 @@ ON DUPLICATE KEY UPDATE
|
||||
is_active = VALUES(is_active)
|
||||
`
|
||||
|
||||
const updateInstaller = `
|
||||
UPDATE
|
||||
software_installers
|
||||
SET
|
||||
install_during_setup = COALESCE(?, install_during_setup),
|
||||
self_service = ?,
|
||||
install_script_content_id = ?,
|
||||
uninstall_script_content_id = ?,
|
||||
post_install_script_content_id = ?,
|
||||
pre_install_query = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
const loadSoftwareInstallerID = `
|
||||
SELECT
|
||||
id
|
||||
@@ -2715,8 +2728,8 @@ WHERE
|
||||
// for this team+title. This prevents duplicate rows from repeated batch sets
|
||||
// that re-download the same latest version.
|
||||
var skipInsert bool
|
||||
var existingID uint
|
||||
if installer.FleetMaintainedAppID != nil {
|
||||
var existingID uint
|
||||
err := sqlx.GetContext(ctx, tx, &existingID, `
|
||||
SELECT id FROM software_installers
|
||||
WHERE global_or_team_id = ? AND title_id = ? AND fleet_maintained_app_id IS NOT NULL AND version = ?
|
||||
@@ -2729,7 +2742,21 @@ WHERE
|
||||
}
|
||||
}
|
||||
|
||||
if !skipInsert {
|
||||
if skipInsert {
|
||||
// some fields still need to be updated
|
||||
args := []any{
|
||||
installer.InstallDuringSetup,
|
||||
installer.SelfService,
|
||||
installScriptID,
|
||||
uninstallScriptID,
|
||||
postInstallScriptID,
|
||||
installer.PreInstallQuery,
|
||||
existingID,
|
||||
}
|
||||
if _, err := tx.ExecContext(ctx, updateInstaller, args...); err != nil {
|
||||
return ctxerr.Wrapf(ctx, err, "updating existing installer with name %q", installer.Filename)
|
||||
}
|
||||
} else {
|
||||
upsertQuery := insertNewOrEditedInstaller
|
||||
if len(existing) > 0 && existing[0].IsPackageModified { // update uploaded_at for updated installer package
|
||||
upsertQuery = fmt.Sprintf("%s, uploaded_at = NOW()", upsertQuery)
|
||||
|
||||
@@ -57,6 +57,7 @@ func TestSoftwareInstallers(t *testing.T) {
|
||||
{"SoftwareInstallerReplicaLag", testSoftwareInstallerReplicaLag},
|
||||
{"SoftwareTitleDisplayName", testSoftwareTitleDisplayName},
|
||||
{"AddSoftwareTitleToMatchingSoftware", testAddSoftwareTitleToMatchingSoftware},
|
||||
{"FleetMaintainedAppInstallerUpdates", testFleetMaintainedAppInstallerUpdates},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@@ -4275,3 +4276,96 @@ func testAddSoftwareTitleToMatchingSoftware(t *testing.T, ds *Datastore) {
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func testFleetMaintainedAppInstallerUpdates(t *testing.T, ds *Datastore) {
|
||||
ctx := t.Context()
|
||||
user := test.NewUser(t, ds, "Alice", "alice@example.com", true)
|
||||
tfr, err := fleet.NewTempFileReader(strings.NewReader("file contents"), t.TempDir)
|
||||
require.NoError(t, err)
|
||||
|
||||
maintainedApp, err := ds.UpsertMaintainedApp(ctx, &fleet.MaintainedApp{
|
||||
Name: "Maintained1",
|
||||
Slug: "maintained1",
|
||||
Platform: "darwin",
|
||||
UniqueIdentifier: "fleet.maintained1",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
installerID, _, err := ds.MatchOrCreateSoftwareInstaller(ctx, &fleet.UploadSoftwareInstallerPayload{
|
||||
Title: "testpkg",
|
||||
Source: "apps",
|
||||
Platform: "darwin",
|
||||
PreInstallQuery: "SELECT 1",
|
||||
InstallScript: "echo install",
|
||||
PostInstallScript: "echo post install",
|
||||
UninstallScript: "echo uninstall",
|
||||
InstallerFile: tfr,
|
||||
StorageID: "storageid1",
|
||||
Filename: "test.pkg",
|
||||
Version: "1.0",
|
||||
UserID: user.ID,
|
||||
ValidatedLabels: &fleet.LabelIdentsWithScope{},
|
||||
FleetMaintainedAppID: ptr.Uint(maintainedApp.ID),
|
||||
InstallDuringSetup: ptr.Bool(false),
|
||||
SelfService: false,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
tmFilter := fleet.TeamFilter{User: test.UserAdmin}
|
||||
titles, _, _, err := ds.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{TeamID: ptr.Uint(0), Platform: "darwin", AvailableForInstall: true}, tmFilter)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, titles, 1)
|
||||
require.False(t, *titles[0].SoftwarePackage.InstallDuringSetup)
|
||||
require.False(t, *titles[0].SoftwarePackage.SelfService)
|
||||
|
||||
installer, err := ds.GetSoftwareInstallerMetadataByID(ctx, installerID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, installer)
|
||||
|
||||
installScript := installer.InstallScriptContentID
|
||||
postInstallScript := installer.PostInstallScriptContentID
|
||||
uninstallScript := installer.UninstallScriptContentID
|
||||
|
||||
require.NotZero(t, installScript)
|
||||
require.NotZero(t, postInstallScript)
|
||||
require.NotZero(t, uninstallScript)
|
||||
require.Equal(t, "SELECT 1", installer.PreInstallQuery)
|
||||
|
||||
// batch add the installer with different scripts, setup experience, self service
|
||||
err = ds.BatchSetSoftwareInstallers(ctx, nil, []*fleet.UploadSoftwareInstallerPayload{
|
||||
{
|
||||
Title: "testpkg",
|
||||
Source: "apps",
|
||||
PreInstallQuery: "SELECT 1 DIFFERENT",
|
||||
InstallScript: "echo install 2",
|
||||
PostInstallScript: "echo post install 2",
|
||||
UninstallScript: "echo uninstall 2",
|
||||
InstallerFile: tfr,
|
||||
StorageID: "storageid1",
|
||||
Filename: "test.pkg",
|
||||
Version: "1.0",
|
||||
UserID: user.ID,
|
||||
ValidatedLabels: &fleet.LabelIdentsWithScope{},
|
||||
FleetMaintainedAppID: ptr.Uint(maintainedApp.ID),
|
||||
InstallDuringSetup: ptr.Bool(true),
|
||||
SelfService: true,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
titles, _, _, err = ds.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{TeamID: ptr.Uint(0), Platform: "darwin", AvailableForInstall: true}, tmFilter)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, titles, 1)
|
||||
require.True(t, *titles[0].SoftwarePackage.InstallDuringSetup)
|
||||
require.True(t, *titles[0].SoftwarePackage.SelfService)
|
||||
|
||||
installer, err = ds.GetSoftwareInstallerMetadataByID(ctx, installerID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, installer)
|
||||
|
||||
// all fields that should have changed did change
|
||||
require.NotEqual(t, installScript, installer.InstallScriptContentID)
|
||||
require.NotEqual(t, postInstallScript, installer.PostInstallScriptContentID)
|
||||
require.NotEqual(t, uninstallScript, installer.UninstallScriptContentID)
|
||||
require.Equal(t, "SELECT 1 DIFFERENT", installer.PreInstallQuery)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user