From d5e4f5deb71b1b691b7bd9851cdd0fc83b190c85 Mon Sep 17 00:00:00 2001 From: Tiago Queiroz Date: Thu, 23 May 2024 15:53:45 -0400 Subject: [PATCH] Add flag to ignore Systemd version and improve tests This commit adds a flag to ignore the Systemd version check for the Journald input. The mage targets are updated so the Journald input unit tests always run. The tests disable the Systemd version check so we can run the tests in our current hosts. --- filebeat/cmd/root.go | 1 + filebeat/input/journald/input.go | 24 ++++++++++++++++++++++-- filebeat/input/journald/input_test.go | 8 ++++++++ filebeat/magefile.go | 19 +++++++++++++------ libbeat/docs/command-reference.asciidoc | 7 +++++++ 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/filebeat/cmd/root.go b/filebeat/cmd/root.go index 4a5a2607b186..81d87807fcf1 100644 --- a/filebeat/cmd/root.go +++ b/filebeat/cmd/root.go @@ -63,6 +63,7 @@ func Filebeat(inputs beater.PluginFactory, settings instance.Settings) *cmd.Beat command.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("M")) command.TestCmd.Flags().AddGoFlag(flag.CommandLine.Lookup("modules")) command.SetupCmd.Flags().AddGoFlag(flag.CommandLine.Lookup("modules")) + command.Flags().AddGoFlag(flag.CommandLine.Lookup("ignore-journald-version")) command.AddCommand(cmd.GenModulesCmd(Name, "", buildModulesManager)) command.AddCommand(genGenerateCmd()) return command diff --git a/filebeat/input/journald/input.go b/filebeat/input/journald/input.go index 736569c00bfc..c633154a976f 100644 --- a/filebeat/input/journald/input.go +++ b/filebeat/input/journald/input.go @@ -21,6 +21,7 @@ package journald import ( "errors" + "flag" "fmt" "strconv" "strings" @@ -42,6 +43,15 @@ import ( "github.com/elastic/elastic-agent-libs/logp" ) +var noVersionCheck bool + +func init() { + flag.BoolVar(&noVersionCheck, + "ignore-journald-version", + false, + "Does not check Journald version when starting the Journald input. This might cause Filebeat to crash!") +} + type journald struct { Backoff time.Duration MaxBackoff time.Duration @@ -92,6 +102,11 @@ func Plugin(log *logp.Logger, store cursor.StateStore) input.Plugin { Manager: m, } + if noVersionCheck { + log.Warn("Journald version check has been DISABLED! Filebeat might crash if Journald version is < 255.") + return p + } + version, err := systemdVersion() if err != nil { configErr := fmt.Errorf("%w: %s", ErrCannotGetSystemdVersion, err) @@ -358,9 +373,14 @@ func parseSystemdVersion(output string) (int, error) { return version, err } -// getSystemdVersionViaDBus foo +// getSystemdVersionViaDBus gets the Systemd version from D-Bus +// +// We get the version by reading the property +// `org.freedesktop.systemd1.Manager.Version`. Even though this property is +// is documented as not being part of the official API and having an unstable +// scheme, on our tests it proved to be stable enough. // -// Version string should not be parsed: +// The Systemd D-Bus documentation states: // // Version encodes the version string of the running systemd // instance. Note that the version string is purely informational, diff --git a/filebeat/input/journald/input_test.go b/filebeat/input/journald/input_test.go index 5c81c52998c0..fc4c0796a820 100644 --- a/filebeat/input/journald/input_test.go +++ b/filebeat/input/journald/input_test.go @@ -21,13 +21,21 @@ package journald import ( "context" + "flag" "fmt" + "os" "path" "testing" "github.com/elastic/elastic-agent-libs/mapstr" ) +func TestMain(m *testing.M) { + flag.Parse() + noVersionCheck = true + os.Exit(m.Run()) +} + func TestInputFieldsTranslation(t *testing.T) { // A few random keys to verify keysToCheck := map[string]string{ diff --git a/filebeat/magefile.go b/filebeat/magefile.go index 771741f02a15..f25e021024fe 100644 --- a/filebeat/magefile.go +++ b/filebeat/magefile.go @@ -28,6 +28,7 @@ import ( devtools "github.com/elastic/beats/v7/dev-tools/mage" "github.com/elastic/beats/v7/dev-tools/mage/target/build" + "github.com/elastic/beats/v7/dev-tools/mage/target/unittest" filebeat "github.com/elastic/beats/v7/filebeat/scripts/mage" //mage:import @@ -45,6 +46,7 @@ import ( func init() { common.RegisterCheckDeps(Update) test.RegisterDeps(IntegTest) + unittest.RegisterGoTestDeps(TestJournaldInput) devtools.BeatDescription = "Filebeat sends log files to Logstash or directly to Elasticsearch." } @@ -215,15 +217,20 @@ func PythonIntegTest(ctx context.Context) error { return devtools.PythonIntegTestFromHost(devtools.DefaultPythonTestIntegrationFromHostArgs()) } -// TestJournald executes the Journald input tests +// TestJournaldInput executes the Journald input unit tests. +// +// It requires Systemd >= 255 and D-Bus to be installed +// on the host. +// // Use TEST_COVERAGE=true to enable code coverage profiling. // Use RACE_DETECTOR=true to enable the race detector. -func TestJournald(ctx context.Context) error { - utArgs := devtools.DefaultGoTestUnitArgs() - utArgs.Packages = []string{"./input/journald"} +func TestJournaldInput(ctx context.Context) error { if devtools.Platform.GOOS == "linux" { - utArgs.ExtraFlags = append(utArgs.ExtraFlags, "-tags=withjournald") + testArgs := devtools.DefaultGoTestUnitArgs() + testArgs.Packages = []string{"./input/journald"} + testArgs.ExtraFlags = append(testArgs.ExtraFlags, "-tags=withjournald") + return devtools.GoTest(ctx, testArgs) } - return devtools.GoTest(ctx, utArgs) + return nil } diff --git a/libbeat/docs/command-reference.asciidoc b/libbeat/docs/command-reference.asciidoc index 91daaf097be6..3574a7144ac9 100644 --- a/libbeat/docs/command-reference.asciidoc +++ b/libbeat/docs/command-reference.asciidoc @@ -744,12 +744,19 @@ the end of the file is reached. By default harvesters are closed after The `--once` option is not currently supported with the {filebeat-ref}/filebeat-input-filestream.html[`filestream`] input type. +*`--ignore-journald-version`*:: +When the `--ignore-journald-version` is used, the Journald input +**will not** validate the minimum Systemd version during the input +initialisation. Running the Journald input with an unsupported version +of Systemd might cause {beatname_uc} to crash. endif::[] +ifeval::["{beatname_lc}"=="metricbeat"] *`--system.hostfs MOUNT_POINT`*:: Specifies the mount point of the host's filesystem for use in monitoring a host. This flag is depricated, and an alternate hostfs should be specified via the `hostfs` module config value. +endif::[] ifeval::["{beatname_lc}"=="packetbeat"]