From 4ebb37d29b42baf7c3df2ae4aa494003c31f3ea0 Mon Sep 17 00:00:00 2001 From: Cesar Araujo <56365373+cesarfda@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:21:45 -0500 Subject: [PATCH] Log osquery version (#1893) --- cmd/launcher/launcher.go | 22 ++-- ee/agent/flags/flag_controller.go | 8 ++ ee/agent/flags/keys/keys.go | 1 + ee/agent/knapsack/knapsack.go | 2 +- ee/agent/types/flags.go | 4 + ee/agent/types/mocks/flags.go | 38 ++++++- ee/agent/types/mocks/knapsack.go | 150 ++++++++++++++++---------- ee/tuf/library_lookup.go | 12 ++- pkg/log/logshipper/logshipper.go | 1 + pkg/log/logshipper/logshipper_test.go | 3 + 10 files changed, 166 insertions(+), 75 deletions(-) diff --git a/cmd/launcher/launcher.go b/cmd/launcher/launcher.go index 902d68b3b..1b950c0ee 100644 --- a/cmd/launcher/launcher.go +++ b/cmd/launcher/launcher.go @@ -30,6 +30,7 @@ import ( "github.com/kolide/launcher/ee/agent/storage" agentbbolt "github.com/kolide/launcher/ee/agent/storage/bbolt" "github.com/kolide/launcher/ee/agent/timemachine" + "github.com/kolide/launcher/ee/agent/types" "github.com/kolide/launcher/ee/control" "github.com/kolide/launcher/ee/control/actionqueue" "github.com/kolide/launcher/ee/control/consumers/acceleratecontrolconsumer" @@ -194,7 +195,7 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl flagController := flags.NewFlagController(slogger, stores[storage.AgentFlagsStore], fcOpts...) k := knapsack.New(stores, flagController, db, multiSlogger, systemMultiSlogger) - go runOsqueryVersionCheck(ctx, slogger, k.LatestOsquerydPath(ctx)) + go runOsqueryVersionCheckAndAddToKnapsack(ctx, slogger, k, k.LatestOsquerydPath(ctx)) go timemachine.AddExclusions(ctx, k) if k.Debug() && runtime.GOOS != "windows" { @@ -593,15 +594,10 @@ func writePidFile(path string) error { return nil } -// runOsqueryVersionCheck execs the osqueryd binary in the background when we're running -// on darwin. Operating on our theory that some startup delay issues for osquery might -// be due to the notarization check taking too long, we execute the binary here ahead -// of time in the hopes of getting the check out of the way. This is expected to be called +// runOsqueryVersionCheckAndAddToKnapsack execs the osqueryd binary in the background when we're running +// on to check the version and save it in the Knapsack. This is expected to be called // from a goroutine, and thus does not return an error. -func runOsqueryVersionCheck(ctx context.Context, slogger *slog.Logger, osquerydPath string) { - if runtime.GOOS != "darwin" { - return - } +func runOsqueryVersionCheckAndAddToKnapsack(ctx context.Context, slogger *slog.Logger, k types.Knapsack, osquerydPath string) { slogger = slogger.With("component", "osquery-version-check") @@ -620,10 +616,7 @@ func runOsqueryVersionCheck(ctx context.Context, slogger *slog.Logger, osquerydP versionCtx, versionCancel := context.WithTimeout(ctx, 30*time.Second) defer versionCancel() - startTime := time.Now().UnixMilli() - osqErr := osq.RunVersion(versionCtx) - executionTimeMs := time.Now().UnixMilli() - startTime outTrimmed := strings.TrimSpace(output.String()) if osqErr != nil { @@ -631,16 +624,17 @@ func runOsqueryVersionCheck(ctx context.Context, slogger *slog.Logger, osquerydP "could not check osqueryd version", "output", outTrimmed, "err", err, - "execution_time_ms", executionTimeMs, "osqueryd_path", osquerydPath, ) return } + // log the version to the knappsack + k.SetCurrentRunningOsqueryVersion(outTrimmed) + slogger.Log(ctx, slog.LevelDebug, "checked osqueryd version", "osqueryd_version", outTrimmed, - "execution_time_ms", executionTimeMs, "osqueryd_path", osquerydPath, ) } diff --git a/ee/agent/flags/flag_controller.go b/ee/agent/flags/flag_controller.go index e968c76f0..6132287b9 100644 --- a/ee/agent/flags/flag_controller.go +++ b/ee/agent/flags/flag_controller.go @@ -420,6 +420,14 @@ func (fc *FlagController) OsqueryTlsDistributedWriteEndpoint() string { return fc.cmdLineOpts.OsqueryTlsDistributedWriteEndpoint } +func (fc *FlagController) CurrentRunningOsqueryVersion() string { + return NewStringFlagValue(WithDefaultString("")).get(fc.getControlServerValue(keys.CurrentRunningOsqueryVersion)) +} + +func (fc *FlagController) SetCurrentRunningOsqueryVersion(osqueryversion string) error { + return fc.setControlServerValue(keys.CurrentRunningOsqueryVersion, []byte(osqueryversion)) +} + func (fc *FlagController) SetAutoupdate(enabled bool) error { return fc.setControlServerValue(keys.Autoupdate, boolToBytes(enabled)) } diff --git a/ee/agent/flags/keys/keys.go b/ee/agent/flags/keys/keys.go index cb2ff63f9..f73fb71f8 100644 --- a/ee/agent/flags/keys/keys.go +++ b/ee/agent/flags/keys/keys.go @@ -57,6 +57,7 @@ const ( LocalDevelopmentPath FlagKey = "localdev_path" LauncherWatchdogEnabled FlagKey = "launcher_watchdog_enabled" // note that this will only impact windows deployments for now SystrayRestartEnabled FlagKey = "systray_restart_enabled" + CurrentRunningOsqueryVersion FlagKey = "osquery_version" ) func (key FlagKey) String() string { diff --git a/ee/agent/knapsack/knapsack.go b/ee/agent/knapsack/knapsack.go index 661b56a5d..32f1313fe 100644 --- a/ee/agent/knapsack/knapsack.go +++ b/ee/agent/knapsack/knapsack.go @@ -161,7 +161,7 @@ func (k *knapsack) LatestOsquerydPath(ctx context.Context) string { if err != nil { return k.OsquerydPath() } - + k.SetCurrentRunningOsqueryVersion(latestBin.Version) return latestBin.Path } diff --git a/ee/agent/types/flags.go b/ee/agent/types/flags.go index 42e1141f6..0790e0db0 100644 --- a/ee/agent/types/flags.go +++ b/ee/agent/types/flags.go @@ -145,6 +145,10 @@ type Flags interface { OsqueryTlsDistributedReadEndpoint() string OsqueryTlsDistributedWriteEndpoint() string + // Osquery Version is the version of osquery that is being used. + SetCurrentRunningOsqueryVersion(version string) error + CurrentRunningOsqueryVersion() string + // Autoupdate enables the autoupdate functionality. SetAutoupdate(enabled bool) error Autoupdate() bool diff --git a/ee/agent/types/mocks/flags.go b/ee/agent/types/mocks/flags.go index 941d18397..c202a37b3 100644 --- a/ee/agent/types/mocks/flags.go +++ b/ee/agent/types/mocks/flags.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.46.0. DO NOT EDIT. +// Code generated by mockery v2.46.3. DO NOT EDIT. package mocks @@ -126,6 +126,24 @@ func (_m *Flags) ControlServerURL() string { return r0 } +// CurrentRunningOsqueryVersion provides a mock function with given fields: +func (_m *Flags) CurrentRunningOsqueryVersion() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CurrentRunningOsqueryVersion") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + // Debug provides a mock function with given fields: func (_m *Flags) Debug() bool { ret := _m.Called() @@ -973,6 +991,24 @@ func (_m *Flags) SetControlServerURL(url string) error { return r0 } +// SetCurrentRunningOsqueryVersion provides a mock function with given fields: version +func (_m *Flags) SetCurrentRunningOsqueryVersion(version string) error { + ret := _m.Called(version) + + if len(ret) == 0 { + panic("no return value specified for SetCurrentRunningOsqueryVersion") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(version) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // SetDebug provides a mock function with given fields: debug func (_m *Flags) SetDebug(debug bool) error { ret := _m.Called(debug) diff --git a/ee/agent/types/mocks/knapsack.go b/ee/agent/types/mocks/knapsack.go index 8386393f2..fb92dfaaf 100644 --- a/ee/agent/types/mocks/knapsack.go +++ b/ee/agent/types/mocks/knapsack.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.46.0. DO NOT EDIT. +// Code generated by mockery v2.46.3. DO NOT EDIT. package mocks @@ -37,19 +37,19 @@ func (_m *Knapsack) AddSlogHandler(handler ...slog.Handler) { } // AgentFlagsStore provides a mock function with given fields: -func (_m *Knapsack) AgentFlagsStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) AgentFlagsStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for AgentFlagsStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -75,19 +75,19 @@ func (_m *Knapsack) Autoupdate() bool { } // AutoupdateErrorsStore provides a mock function with given fields: -func (_m *Knapsack) AutoupdateErrorsStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) AutoupdateErrorsStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for AutoupdateErrorsStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -171,19 +171,19 @@ func (_m *Knapsack) CertPins() [][]byte { } // ConfigStore provides a mock function with given fields: -func (_m *Knapsack) ConfigStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) ConfigStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for ConfigStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -227,19 +227,19 @@ func (_m *Knapsack) ControlServerURL() string { } // ControlStore provides a mock function with given fields: -func (_m *Knapsack) ControlStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) ControlStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for ControlStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -274,6 +274,24 @@ func (_m *Knapsack) CurrentEnrollmentStatus() (types.EnrollmentStatus, error) { return r0, r1 } +// CurrentRunningOsqueryVersion provides a mock function with given fields: +func (_m *Knapsack) CurrentRunningOsqueryVersion() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CurrentRunningOsqueryVersion") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + // Debug provides a mock function with given fields: func (_m *Knapsack) Debug() bool { ret := _m.Called() @@ -563,19 +581,19 @@ func (_m *Knapsack) InModernStandby() bool { } // InitialResultsStore provides a mock function with given fields: -func (_m *Knapsack) InitialResultsStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) InitialResultsStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for InitialResultsStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -637,19 +655,19 @@ func (_m *Knapsack) InsecureTransportTLS() bool { } // KatcConfigStore provides a mock function with given fields: -func (_m *Knapsack) KatcConfigStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) KatcConfigStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for KatcConfigStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -875,19 +893,19 @@ func (_m *Knapsack) OsqueryHealthcheckStartupDelay() time.Duration { } // OsqueryHistoryInstanceStore provides a mock function with given fields: -func (_m *Knapsack) OsqueryHistoryInstanceStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) OsqueryHistoryInstanceStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for OsqueryHistoryInstanceStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -1021,19 +1039,19 @@ func (_m *Knapsack) OsquerydPath() string { } // PersistentHostDataStore provides a mock function with given fields: -func (_m *Knapsack) PersistentHostDataStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) PersistentHostDataStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for PersistentHostDataStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -1117,19 +1135,19 @@ func (_m *Knapsack) RegisterChangeObserver(observer types.FlagsChangeObserver, f } // ResultLogsStore provides a mock function with given fields: -func (_m *Knapsack) ResultLogsStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) ResultLogsStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for ResultLogsStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -1173,19 +1191,19 @@ func (_m *Knapsack) RootPEM() string { } // SentNotificationsStore provides a mock function with given fields: -func (_m *Knapsack) SentNotificationsStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) SentNotificationsStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for SentNotificationsStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -1193,19 +1211,19 @@ func (_m *Knapsack) SentNotificationsStore() types.GetterSetterDeleterIteratorUp } // ServerProvidedDataStore provides a mock function with given fields: -func (_m *Knapsack) ServerProvidedDataStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) ServerProvidedDataStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for ServerProvidedDataStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -1307,6 +1325,24 @@ func (_m *Knapsack) SetControlServerURL(url string) error { return r0 } +// SetCurrentRunningOsqueryVersion provides a mock function with given fields: version +func (_m *Knapsack) SetCurrentRunningOsqueryVersion(version string) error { + ret := _m.Called(version) + + if len(ret) == 0 { + panic("no return value specified for SetCurrentRunningOsqueryVersion") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(version) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // SetDebug provides a mock function with given fields: debug func (_m *Knapsack) SetDebug(debug bool) error { ret := _m.Called(debug) @@ -1955,19 +1991,19 @@ func (_m *Knapsack) Slogger() *slog.Logger { } // StatusLogsStore provides a mock function with given fields: -func (_m *Knapsack) StatusLogsStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) StatusLogsStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for StatusLogsStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } @@ -1975,19 +2011,19 @@ func (_m *Knapsack) StatusLogsStore() types.GetterSetterDeleterIteratorUpdaterCo } // Stores provides a mock function with given fields: -func (_m *Knapsack) Stores() map[storage.Store]types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) Stores() map[storage.Store]types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for Stores") } - var r0 map[storage.Store]types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() map[storage.Store]types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 map[storage.Store]types.KVStore + if rf, ok := ret.Get(0).(func() map[storage.Store]types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(map[storage.Store]types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(map[storage.Store]types.KVStore) } } @@ -2033,19 +2069,19 @@ func (_m *Knapsack) SystrayRestartEnabled() bool { } // TokenStore provides a mock function with given fields: -func (_m *Knapsack) TokenStore() types.GetterSetterDeleterIteratorUpdaterCounterAppender { +func (_m *Knapsack) TokenStore() types.KVStore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for TokenStore") } - var r0 types.GetterSetterDeleterIteratorUpdaterCounterAppender - if rf, ok := ret.Get(0).(func() types.GetterSetterDeleterIteratorUpdaterCounterAppender); ok { + var r0 types.KVStore + if rf, ok := ret.Get(0).(func() types.KVStore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(types.GetterSetterDeleterIteratorUpdaterCounterAppender) + r0 = ret.Get(0).(types.KVStore) } } diff --git a/ee/tuf/library_lookup.go b/ee/tuf/library_lookup.go index 19db1f33f..db0892a68 100644 --- a/ee/tuf/library_lookup.go +++ b/ee/tuf/library_lookup.go @@ -264,7 +264,7 @@ func findExecutable(ctx context.Context, binary autoupdatableBinary, tufReposito return &BinaryUpdateInfo{ Path: targetPath, - Version: targetVersion, + Version: trimVersionString(targetVersion), }, nil } @@ -304,6 +304,14 @@ func mostRecentVersion(ctx context.Context, slogger *slog.Logger, binary autoupd versionDir := filepath.Join(updatesDirectory(binary, baseUpdateDirectory), mostRecentVersionInLibraryRaw) return &BinaryUpdateInfo{ Path: executableLocation(versionDir, binary), - Version: mostRecentVersionInLibraryRaw, + Version: trimVersionString(mostRecentVersionInLibraryRaw), }, nil } + +func trimVersionString(version string) string { + parts := strings.Fields(version) + if len(parts) > 0 { + return parts[len(parts)-1] + } + return version +} diff --git a/pkg/log/logshipper/logshipper.go b/pkg/log/logshipper/logshipper.go index 6223418cc..c5cf32da4 100644 --- a/pkg/log/logshipper/logshipper.go +++ b/pkg/log/logshipper/logshipper.go @@ -193,6 +193,7 @@ func (ls *LogShipper) updateDevideIdentifyingAttributes() error { versionInfo := version.Version() deviceInfo["launcher_version"] = versionInfo.Version deviceInfo["os"] = runtime.GOOS + deviceInfo["osquery_version"] = ls.knapsack.CurrentRunningOsqueryVersion() ls.shippingLogger = log.With(ls.shippingLogger, "launcher_version", versionInfo.Version) diff --git a/pkg/log/logshipper/logshipper_test.go b/pkg/log/logshipper/logshipper_test.go index c90755c16..1ea96f67a 100644 --- a/pkg/log/logshipper/logshipper_test.go +++ b/pkg/log/logshipper/logshipper_test.go @@ -39,6 +39,7 @@ func TestLogShipper(t *testing.T) { knapsack := mocks.NewKnapsack(t) knapsack.On("RegisterChangeObserver", mock.Anything, keys.LogShippingLevel, keys.LogIngestServerURL) knapsack.On("LogShippingLevel").Return("info").Times(5) + knapsack.On("CurrentRunningOsqueryVersion").Return("5.12.3") tokenStore := testKVStore(t, storage.TokenStore.String()) knapsack.On("TokenStore").Return(tokenStore) @@ -132,6 +133,7 @@ func TestStop_Multiple(t *testing.T) { serverDataStore := testKVStore(t, storage.ServerProvidedDataStore.String()) knapsack.On("ServerProvidedDataStore").Return(serverDataStore) + knapsack.On("CurrentRunningOsqueryVersion").Return("5.12.3") endpoint := "https://someurl" knapsack.On("LogIngestServerURL").Return(endpoint).Times(1) @@ -194,6 +196,7 @@ func TestStopWithoutRun(t *testing.T) { knapsack.On("LogShippingLevel").Return("debug") knapsack.On("Slogger").Return(multislogger.NewNopLogger()) knapsack.On("RegisterChangeObserver", mock.Anything, keys.LogShippingLevel, keys.LogIngestServerURL) + knapsack.On("CurrentRunningOsqueryVersion").Return("5.12.3") ls := New(knapsack, log.NewNopLogger())