From 9c37db2a05cb03bd29e045bbd39a8f7bd35e71c4 Mon Sep 17 00:00:00 2001 From: Martin Angers Date: Mon, 5 Feb 2024 10:51:32 -0500 Subject: [PATCH] Remove unnecessary nested transactions in batch-set of MDM profiles (#16449) --- changes/16273-remove-nested-transactions | 1 + server/datastore/mysql/apple_mdm.go | 170 ++++++++++------- server/datastore/mysql/mdm.go | 2 +- server/datastore/mysql/mdm_test.go | 67 +++++++ server/datastore/mysql/microsoft_mdm.go | 187 +++++++++++-------- server/datastore/mysql/microsoft_mdm_test.go | 2 +- 6 files changed, 284 insertions(+), 145 deletions(-) create mode 100644 changes/16273-remove-nested-transactions diff --git a/changes/16273-remove-nested-transactions b/changes/16273-remove-nested-transactions new file mode 100644 index 0000000000..e7fa044306 --- /dev/null +++ b/changes/16273-remove-nested-transactions @@ -0,0 +1 @@ +* Removed unnecessary nested database transactions in batch-setting of MDM profiles. diff --git a/server/datastore/mysql/apple_mdm.go b/server/datastore/mysql/apple_mdm.go index f4ca6d6c31..0ec4e130d3 100644 --- a/server/datastore/mysql/apple_mdm.go +++ b/server/datastore/mysql/apple_mdm.go @@ -1166,11 +1166,23 @@ func (ds *Datastore) GetNanoMDMEnrollment(ctx context.Context, id string) (*flee } func (ds *Datastore) BatchSetMDMAppleProfiles(ctx context.Context, tmID *uint, profiles []*fleet.MDMAppleConfigProfile) error { - return ds.withTx(ctx, func(tx sqlx.ExtContext) error { + return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { return ds.batchSetMDMAppleProfilesDB(ctx, tx, tmID, profiles) }) } +// set this in tests to simulate an error at various stages in the +// batchSetMDMAppleProfilesDB execution: if the string starts with "insert", it +// will be in the insert/upsert stage, "delete" for deletion, "select" to load +// existing ones, "reselect" to reload existing ones after insert, and "labels" +// to simulate an error in batch setting the profile label associations. +// "inselect", "inreselect", "indelete", etc. can also be used to fail the +// sqlx.In before the corresponding statement. +// +// e.g.: testBatchSetMDMAppleProfilesErr = "insert:fail" +var testBatchSetMDMAppleProfilesErr string + +// batchSetMDMAppleProfilesDB must be called from inside a transaction. func (ds *Datastore) batchSetMDMAppleProfilesDB( ctx context.Context, tx sqlx.ExtContext, @@ -1229,90 +1241,112 @@ ON DUPLICATE KEY UPDATE incomingProfs[p.Identifier] = p } - return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { - var existingProfiles []*fleet.MDMAppleConfigProfile + var existingProfiles []*fleet.MDMAppleConfigProfile - if len(incomingIdents) > 0 { - // load existing profiles that match the incoming profiles by identifiers - stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingIdents) - if err != nil { - return ctxerr.Wrap(ctx, err, "build query to load existing profiles") + if len(incomingIdents) > 0 { + // load existing profiles that match the incoming profiles by identifiers + stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingIdents) + if err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "inselect") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) } - if err := sqlx.SelectContext(ctx, tx, &existingProfiles, stmt, args...); err != nil { - return ctxerr.Wrap(ctx, err, "load existing profiles") + return ctxerr.Wrap(ctx, err, "build query to load existing profiles") + } + if err := sqlx.SelectContext(ctx, tx, &existingProfiles, stmt, args...); err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "select") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) } + return ctxerr.Wrap(ctx, err, "load existing profiles") } + } - // figure out if we need to delete any profiles - keepIdents := make([]string, 0, len(incomingIdents)) - for _, p := range existingProfiles { - if newP := incomingProfs[p.Identifier]; newP != nil { - keepIdents = append(keepIdents, p.Identifier) + // figure out if we need to delete any profiles + keepIdents := make([]string, 0, len(incomingIdents)) + for _, p := range existingProfiles { + if newP := incomingProfs[p.Identifier]; newP != nil { + keepIdents = append(keepIdents, p.Identifier) + } + } + + // profiles that are managed and delivered by Fleet + fleetIdents := []string{} + for ident := range mobileconfig.FleetPayloadIdentifiers() { + fleetIdents = append(fleetIdents, ident) + } + + var ( + stmt string + args []interface{} + err error + ) + // delete the obsolete profiles (all those that are not in keepIdents or delivered by Fleet) + stmt, args, err = sqlx.In(deleteProfilesNotInList, profTeamID, append(keepIdents, fleetIdents...)) + if err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "indelete") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) + } + return ctxerr.Wrap(ctx, err, "build statement to delete obsolete profiles") + } + if _, err := tx.ExecContext(ctx, stmt, args...); err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "delete") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) + } + return ctxerr.Wrap(ctx, err, "delete obsolete profiles") + } + + // insert the new profiles and the ones that have changed + for _, p := range incomingProfs { + if _, err := tx.ExecContext(ctx, insertNewOrEditedProfile, profTeamID, p.Identifier, p.Name, p.Mobileconfig); err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "insert") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) } + return ctxerr.Wrapf(ctx, err, "insert new/edited profile with identifier %q", p.Identifier) } + } - // profiles that are managed and delivered by Fleet - fleetIdents := []string{} - for ident := range mobileconfig.FleetPayloadIdentifiers() { - fleetIdents = append(fleetIdents, ident) - } - - var ( - stmt string - args []interface{} - err error - ) - // delete the obsolete profiles (all those that are not in keepIdents or delivered by Fleet) - stmt, args, err = sqlx.In(deleteProfilesNotInList, profTeamID, append(keepIdents, fleetIdents...)) - if err != nil { - return ctxerr.Wrap(ctx, err, "build statement to delete obsolete profiles") - } - if _, err := tx.ExecContext(ctx, stmt, args...); err != nil { - return ctxerr.Wrap(ctx, err, "delete obsolete profiles") - } - - // insert the new profiles and the ones that have changed - for _, p := range incomingProfs { - if _, err := tx.ExecContext(ctx, insertNewOrEditedProfile, profTeamID, p.Identifier, p.Name, p.Mobileconfig); err != nil { - return ctxerr.Wrapf(ctx, err, "insert new/edited profile with identifier %q", p.Identifier) + // build a list of labels so the associations can be batch-set all at once + // TODO: with minor changes this chunk of code could be shared + // between macOS and Windows, but at the time of this + // implementation we're under tight time constraints. + incomingLabels := []fleet.ConfigurationProfileLabel{} + if len(incomingIdents) > 0 { + var newlyInsertedProfs []*fleet.MDMAppleConfigProfile + // load current profiles (again) that match the incoming profiles by name to grab their uuids + stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingIdents) + if err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "inreselect") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) } + return ctxerr.Wrap(ctx, err, "build query to load newly inserted profiles") + } + if err := sqlx.SelectContext(ctx, tx, &newlyInsertedProfs, stmt, args...); err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "reselect") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) + } + return ctxerr.Wrap(ctx, err, "load newly inserted profiles") } - // build a list of labels so the associations can be batch-set all at once - // TODO: with minor changes this chunk of code could be shared - // between macOS and Windows, but at the time of this - // implementation we're under tight time constraints. - incomingLabels := []fleet.ConfigurationProfileLabel{} - if len(incomingIdents) > 0 { - var newlyInsertedProfs []*fleet.MDMAppleConfigProfile - // load current profiles (again) that match the incoming profiles by name to grab their uuids - stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingIdents) - if err != nil { - return ctxerr.Wrap(ctx, err, "build query to load newly inserted profiles") - } - if err := sqlx.SelectContext(ctx, tx, &newlyInsertedProfs, stmt, args...); err != nil { - return ctxerr.Wrap(ctx, err, "load newly inserted profiles") + for _, newlyInsertedProf := range newlyInsertedProfs { + incomingProf, ok := incomingProfs[newlyInsertedProf.Identifier] + if !ok { + return ctxerr.Wrapf(ctx, err, "profile %q is in the database but was not incoming", newlyInsertedProf.Identifier) } - for _, newlyInsertedProf := range newlyInsertedProfs { - incomingProf, ok := incomingProfs[newlyInsertedProf.Identifier] - if !ok { - return ctxerr.Wrapf(ctx, err, "profile %q is in the database but was not incoming", newlyInsertedProf.Identifier) - } - - for _, label := range incomingProf.Labels { - label.ProfileUUID = newlyInsertedProf.ProfileUUID - incomingLabels = append(incomingLabels, label) - } + for _, label := range incomingProf.Labels { + label.ProfileUUID = newlyInsertedProf.ProfileUUID + incomingLabels = append(incomingLabels, label) } } + } - // insert label associations - if err := batchSetProfileLabelAssociationsDB(ctx, tx, incomingLabels, "darwin"); err != nil { - return ctxerr.Wrap(ctx, err, "inserting apple profile label associations") + // insert label associations + if err := batchSetProfileLabelAssociationsDB(ctx, tx, incomingLabels, "darwin"); err != nil || strings.HasPrefix(testBatchSetMDMAppleProfilesErr, "labels") { + if err == nil { + err = errors.New(testBatchSetMDMAppleProfilesErr) } - return nil - }) + return ctxerr.Wrap(ctx, err, "inserting apple profile label associations") + } + return nil } func (ds *Datastore) BulkDeleteMDMAppleHostsConfigProfiles(ctx context.Context, profs []*fleet.MDMAppleProfilePayload) error { diff --git a/server/datastore/mysql/mdm.go b/server/datastore/mysql/mdm.go index 6d672f202d..50288c89e4 100644 --- a/server/datastore/mysql/mdm.go +++ b/server/datastore/mysql/mdm.go @@ -88,7 +88,7 @@ INNER JOIN hosts h ON h.uuid = mwe.host_uuid } func (ds *Datastore) BatchSetMDMProfiles(ctx context.Context, tmID *uint, macProfiles []*fleet.MDMAppleConfigProfile, winProfiles []*fleet.MDMWindowsConfigProfile) error { - return ds.withTx(ctx, func(tx sqlx.ExtContext) error { + return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { if err := ds.batchSetMDMWindowsProfilesDB(ctx, tx, tmID, winProfiles); err != nil { return ctxerr.Wrap(ctx, err, "batch set windows profiles") } diff --git a/server/datastore/mysql/mdm_test.go b/server/datastore/mysql/mdm_test.go index 9a109c9e94..60d114a622 100644 --- a/server/datastore/mysql/mdm_test.go +++ b/server/datastore/mysql/mdm_test.go @@ -33,6 +33,7 @@ func TestMDMShared(t *testing.T) { {"TestBulkSetPendingMDMHostProfilesBatch3", testBulkSetPendingMDMHostProfilesBatch3}, {"TestGetHostMDMAppleProfilesExpectedForVerification", testGetHostMDMAppleProfilesExpectedForVerification}, {"TestBatchSetProfileLabelAssociations", testBatchSetProfileLabelAssociations}, + {"TestBatchSetProfilesTransactionError", testBatchSetMDMProfilesTransactionError}, } for _, c := range cases { @@ -3021,3 +3022,69 @@ func testBatchSetProfileLabelAssociations(t *testing.T, ds *Datastore) { require.Error(t, err) }) } + +func testBatchSetMDMProfilesTransactionError(t *testing.T, ds *Datastore) { + ctx := context.Background() + + lbl, err := ds.NewLabel(ctx, &fleet.Label{Name: "label", Query: "select 1"}) + require.NoError(t, err) + + cases := []struct { + windowsErr string + appleErr string + wantErr string + }{ + {"select:a", "", "batch set windows profiles: load existing profiles: select:a"}, + {"insert:b", "", ": insert:b"}, + {"delete:c", "", "batch set windows profiles: delete obsolete profiles: delete:c"}, + {"reselect:d", "", "batch set windows profiles: load newly inserted profiles: reselect:d"}, + {"labels:e", "", "batch set windows profiles: inserting windows profile label associations: labels:e"}, + {"inselect:k", "", "batch set windows profiles: build query to load existing profiles: inselect:k"}, + {"indelete:l", "", "batch set windows profiles: build statement to delete obsolete profiles: indelete:l"}, + {"inreselect:m", "", "batch set windows profiles: build query to load newly inserted profiles: inreselect:m"}, + {"", "select:f", "batch set apple profiles: load existing profiles: select:f"}, + {"", "insert:g", ": insert:g"}, + {"", "delete:h", "batch set apple profiles: delete obsolete profiles: delete:h"}, + {"", "reselect:i", "batch set apple profiles: load newly inserted profiles: reselect:i"}, + {"", "labels:j", "batch set apple profiles: inserting apple profile label associations: labels:j"}, + {"", "inselect:n", "batch set apple profiles: build query to load existing profiles: inselect:n"}, + {"", "indelete:o", "batch set apple profiles: build statement to delete obsolete profiles: indelete:o"}, + {"", "inreselect:p", "batch set apple profiles: build query to load newly inserted profiles: inreselect:p"}, + } + for _, c := range cases { + t.Run(c.windowsErr+" "+c.appleErr, func(t *testing.T) { + t.Cleanup(func() { + testBatchSetMDMAppleProfilesErr = "" + testBatchSetMDMWindowsProfilesErr = "" + }) + + appleProfs := []*fleet.MDMAppleConfigProfile{ + configProfileForTest(t, "N1", "I1", "a"), + configProfileForTest(t, "N2", "I2", "b"), + } + winProfs := []*fleet.MDMWindowsConfigProfile{ + windowsConfigProfileForTest(t, "W1", "l1"), + windowsConfigProfileForTest(t, "W2", "l2"), + } + // set the initial profiles without error + err := ds.BatchSetMDMProfiles(ctx, nil, appleProfs, winProfs) + require.NoError(t, err) + + // now ensure all steps are required (add a profile, delete a profile, set labels) + appleProfs = []*fleet.MDMAppleConfigProfile{ + configProfileForTest(t, "N1", "I1", "aa"), + configProfileForTest(t, "N3", "I3", "c", lbl), + } + winProfs = []*fleet.MDMWindowsConfigProfile{ + windowsConfigProfileForTest(t, "W1", "l11"), + windowsConfigProfileForTest(t, "W3", "l3", lbl), + } + // setup the expected errors + testBatchSetMDMAppleProfilesErr = c.appleErr + testBatchSetMDMWindowsProfilesErr = c.windowsErr + + err = ds.BatchSetMDMProfiles(ctx, nil, appleProfs, winProfs) + require.ErrorContains(t, err, c.wantErr) + }) + } +} diff --git a/server/datastore/mysql/microsoft_mdm.go b/server/datastore/mysql/microsoft_mdm.go index db962c030c..4ff692c37c 100644 --- a/server/datastore/mysql/microsoft_mdm.go +++ b/server/datastore/mysql/microsoft_mdm.go @@ -1561,6 +1561,18 @@ ON DUPLICATE KEY UPDATE return nil } +// set this in tests to simulate an error at various stages in the +// batchSetMDMWindowsProfilesDB execution: if the string starts with "insert", +// it will be in the insert/upsert stage, "delete" for deletion, "select" to +// load existing ones, "reselect" to reload existing ones after insert, and +// "labels" to simulate an error in batch setting the profile label +// associations. "inselect", "inreselect", "indelete", etc. can also be used to +// fail the sqlx.In before the corresponding statement. +// +// e.g.: testBatchSetMDMWindowsProfilesErr = "insert:fail" +var testBatchSetMDMWindowsProfilesErr string + +// batchSetMDMWindowsProfilesDB must be called from inside a transaction. func (ds *Datastore) batchSetMDMWindowsProfilesDB( ctx context.Context, tx sqlx.ExtContext, @@ -1625,91 +1637,116 @@ ON DUPLICATE KEY UPDATE incomingProfs[p.Name] = p } - return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { - var existingProfiles []*fleet.MDMWindowsConfigProfile + var existingProfiles []*fleet.MDMWindowsConfigProfile - if len(incomingNames) > 0 { - // load existing profiles that match the incoming profiles by name - stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingNames) - if err != nil { - return ctxerr.Wrap(ctx, err, "build query to load existing profiles") + if len(incomingNames) > 0 { + // load existing profiles that match the incoming profiles by name + stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingNames) + if err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "inselect") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) } - if err := sqlx.SelectContext(ctx, tx, &existingProfiles, stmt, args...); err != nil { - return ctxerr.Wrap(ctx, err, "load existing profiles") + return ctxerr.Wrap(ctx, err, "build query to load existing profiles") + } + if err := sqlx.SelectContext(ctx, tx, &existingProfiles, stmt, args...); err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "select") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) } + return ctxerr.Wrap(ctx, err, "load existing profiles") + } + } + + // figure out if we need to delete any profiles + keepNames := make([]string, 0, len(incomingNames)) + for _, p := range existingProfiles { + if newP := incomingProfs[p.Name]; newP != nil { + keepNames = append(keepNames, p.Name) + } + } + + var ( + stmt string + args []interface{} + err error + ) + // delete the obsolete profiles (all those that are not in keepNames) + if len(keepNames) > 0 { + stmt, args, err = sqlx.In(deleteProfilesNotInList, profTeamID, keepNames) + if err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "indelete") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) + } + return ctxerr.Wrap(ctx, err, "build statement to delete obsolete profiles") + } + if _, err := tx.ExecContext(ctx, stmt, args...); err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "delete") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) + } + return ctxerr.Wrap(ctx, err, "delete obsolete profiles") + } + } else { + if _, err := tx.ExecContext(ctx, deleteAllProfilesForTeam, profTeamID); err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "delete") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) + } + return ctxerr.Wrap(ctx, err, "delete all profiles for team") + } + } + + // insert the new profiles and the ones that have changed + for _, p := range incomingProfs { + if _, err := tx.ExecContext(ctx, insertNewOrEditedProfile, profTeamID, p.Name, p.SyncML); err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "insert") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) + } + return ctxerr.Wrapf(ctx, err, "insert new/edited profile with name %q", p.Name) + } + } + + // build a list of labels so the associations can be batch-set all at once + // TODO: with minor changes this chunk of code could be shared + // between macOS and Windows, but at the time of this + // implementation we're under tight time constraints. + incomingLabels := []fleet.ConfigurationProfileLabel{} + if len(incomingNames) > 0 { + var newlyInsertedProfs []*fleet.MDMWindowsConfigProfile + // load current profiles (again) that match the incoming profiles by name to grab their uuids + stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingNames) + if err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "inreselect") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) + } + return ctxerr.Wrap(ctx, err, "build query to load newly inserted profiles") + } + if err := sqlx.SelectContext(ctx, tx, &newlyInsertedProfs, stmt, args...); err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "reselect") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) + } + return ctxerr.Wrap(ctx, err, "load newly inserted profiles") } - // figure out if we need to delete any profiles - keepNames := make([]string, 0, len(incomingNames)) - for _, p := range existingProfiles { - if newP := incomingProfs[p.Name]; newP != nil { - keepNames = append(keepNames, p.Name) + for _, newlyInsertedProf := range newlyInsertedProfs { + incomingProf, ok := incomingProfs[newlyInsertedProf.Name] + if !ok { + return ctxerr.Wrapf(ctx, err, "profile %q is in the database but was not incoming", newlyInsertedProf.Name) + } + + for _, label := range incomingProf.Labels { + label.ProfileUUID = newlyInsertedProf.ProfileUUID + incomingLabels = append(incomingLabels, label) } } + } - var ( - stmt string - args []interface{} - err error - ) - // delete the obsolete profiles (all those that are not in keepNames) - if len(keepNames) > 0 { - stmt, args, err = sqlx.In(deleteProfilesNotInList, profTeamID, keepNames) - if err != nil { - return ctxerr.Wrap(ctx, err, "build statement to delete obsolete profiles") - } - if _, err := tx.ExecContext(ctx, stmt, args...); err != nil { - return ctxerr.Wrap(ctx, err, "delete obsolete profiles") - } - } else { - if _, err := tx.ExecContext(ctx, deleteAllProfilesForTeam, profTeamID); err != nil { - return ctxerr.Wrap(ctx, err, "delete all profiles for team") - } + // insert/delete the label associations + if err := batchSetProfileLabelAssociationsDB(ctx, tx, incomingLabels, "windows"); err != nil || strings.HasPrefix(testBatchSetMDMWindowsProfilesErr, "labels") { + if err == nil { + err = errors.New(testBatchSetMDMWindowsProfilesErr) } + return ctxerr.Wrap(ctx, err, "inserting windows profile label associations") + } - // insert the new profiles and the ones that have changed - for _, p := range incomingProfs { - if _, err := tx.ExecContext(ctx, insertNewOrEditedProfile, profTeamID, p.Name, p.SyncML); err != nil { - return ctxerr.Wrapf(ctx, err, "insert new/edited profile with name %q", p.Name) - } - } - - // build a list of labels so the associations can be batch-set all at once - // TODO: with minor changes this chunk of code could be shared - // between macOS and Windows, but at the time of this - // implementation we're under tight time constraints. - incomingLabels := []fleet.ConfigurationProfileLabel{} - if len(incomingNames) > 0 { - var newlyInsertedProfs []*fleet.MDMWindowsConfigProfile - // load current profiles (again) that match the incoming profiles by name to grab their uuids - stmt, args, err := sqlx.In(loadExistingProfiles, profTeamID, incomingNames) - if err != nil { - return ctxerr.Wrap(ctx, err, "build query to load newly inserted profiles") - } - if err := sqlx.SelectContext(ctx, tx, &newlyInsertedProfs, stmt, args...); err != nil { - return ctxerr.Wrap(ctx, err, "load newly inserted profiles") - } - - for _, newlyInsertedProf := range newlyInsertedProfs { - incomingProf, ok := incomingProfs[newlyInsertedProf.Name] - if !ok { - return ctxerr.Wrapf(ctx, err, "profile %q is in the database but was not incoming", newlyInsertedProf.Name) - } - - for _, label := range incomingProf.Labels { - label.ProfileUUID = newlyInsertedProf.ProfileUUID - incomingLabels = append(incomingLabels, label) - } - } - } - - // insert/delete the label associations - if err := batchSetProfileLabelAssociationsDB(ctx, tx, incomingLabels, "windows"); err != nil { - return ctxerr.Wrap(ctx, err, "inserting windows profile label associations") - } - - return nil - }) + return nil } func (ds *Datastore) bulkSetPendingMDMWindowsHostProfilesDB( diff --git a/server/datastore/mysql/microsoft_mdm_test.go b/server/datastore/mysql/microsoft_mdm_test.go index a039f10ec7..21083bca84 100644 --- a/server/datastore/mysql/microsoft_mdm_test.go +++ b/server/datastore/mysql/microsoft_mdm_test.go @@ -2007,7 +2007,7 @@ func testBatchSetMDMWindowsProfiles(t *testing.T, ds *Datastore) { ctx := context.Background() applyAndExpect := func(newSet []*fleet.MDMWindowsConfigProfile, tmID *uint, want []*fleet.MDMWindowsConfigProfile) map[string]string { - err := ds.withTx(ctx, func(tx sqlx.ExtContext) error { + err := ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { return ds.batchSetMDMWindowsProfilesDB(ctx, tx, tmID, newSet) }) require.NoError(t, err)