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"]