Fixed bad software ingestion debug message and added filter for invalid software with missing names. (#33682)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #33681

# Checklist for submitter
- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

## Testing

- [x] QA'd all new/changed functionality manually
This commit is contained in:
Victor Lyuboslavsky
2025-10-01 12:17:23 -05:00
committed by GitHub
parent 956ba0a8b1
commit ecb8ee19e2
2 changed files with 24 additions and 3 deletions
+1
View File
@@ -0,0 +1 @@
Fixed bad software ingestion debug message and added filter for invalid software with missing names.
+23 -3
View File
@@ -363,6 +363,19 @@ WHERE
return softwares, nil
}
// filterSoftwareWithEmptyNames removes software entries with empty names in-place.
// This is a well-known Go idiom: https://go.dev/wiki/SliceTricks#filter-in-place
func filterSoftwareWithEmptyNames(software []fleet.Software) []fleet.Software {
n := 0
for _, sw := range software {
if sw.Name != "" {
software[n] = sw
n++
}
}
return software[:n]
}
// applyChangesForNewSoftwareDB returns the current host software and the applied mutations: what
// was inserted and what was deleted
func (ds *Datastore) applyChangesForNewSoftwareDB(
@@ -372,6 +385,9 @@ func (ds *Datastore) applyChangesForNewSoftwareDB(
) (*fleet.UpdateHostSoftwareDBResult, error) {
r := &fleet.UpdateHostSoftwareDBResult{}
// We want to make sure we have valid data before proceeding. We've seen Windows programs with empty names.
software = filterSoftwareWithEmptyNames(software)
// This code executes once an hour for each host, so we should optimize for MySQL master (writer) DB performance.
// We use a slave (reader) DB to avoid accessing the master. If nothing has changed, we avoid all access to the master.
// It is possible that the software list is out of sync between the slave and the master. This is unlikely because
@@ -710,11 +726,15 @@ func (ds *Datastore) getIncomingSoftwareChecksumsToExistingTitles(
existingChecksums := uniqueTitleStrToChecksums[titleStr]
if len(existingChecksums) > 0 {
// Log when multiple checksums map to the same title.
existingChecksumsHex := make([]string, len(existingChecksums))
for i, cs := range existingChecksums {
existingChecksumsHex[i] = fmt.Sprintf("%x", cs)
}
level.Debug(ds.logger).Log(
"msg", "multiple checksums mapping to same title",
"title_str", titleStr,
"new_checksum", checksum,
"existing_checksums", fmt.Sprintf("%v", existingChecksums),
"new_checksum", fmt.Sprintf("%x", checksum),
"existing_checksums", fmt.Sprintf("%v", existingChecksumsHex),
"software_name", sw.Name,
"software_version", sw.Version,
)
@@ -1162,7 +1182,7 @@ func (ds *Datastore) linkSoftwareToHost(
// Log missing software but continue
level.Warn(ds.logger).Log(
"msg", "software not found after pre-insertion",
"checksum", checksum,
"checksum", fmt.Sprintf("%x", checksum),
"name", sw.Name,
"version", sw.Version,
)