diff --git a/libbeat/cmd/platformcheck/platformcheck.go b/libbeat/cmd/platformcheck/platformcheck.go new file mode 100644 index 00000000000..e3ccc50ad06 --- /dev/null +++ b/libbeat/cmd/platformcheck/platformcheck.go @@ -0,0 +1,48 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// +build linux windows + +package platformcheck + +import ( + "fmt" + "math/bits" + "strings" + + "github.com/shirou/gopsutil/host" +) + +func CheckNativePlatformCompat() error { + const compiledArchBits = bits.UintSize // 32 if the binary was compiled for 32 bit architecture. + + if compiledArchBits > 32 { + // We assume that 64bit binaries can only be run on 64bit systems + return nil + } + + arch, err := host.KernelArch() + if err != nil { + return err + } + + if strings.Contains(arch, "64") { + return fmt.Errorf("trying to run %vBit binary on 64Bit system", compiledArchBits) + } + + return nil +} diff --git a/libbeat/cmd/platformcheck/platformcheck_other.go b/libbeat/cmd/platformcheck/platformcheck_other.go new file mode 100644 index 00000000000..5ef8d3e8090 --- /dev/null +++ b/libbeat/cmd/platformcheck/platformcheck_other.go @@ -0,0 +1,24 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// +build !linux,!windows + +package platformcheck + +func CheckNativePlatformCompat() error { + return nil +} diff --git a/libbeat/cmd/platformcheck/platformcheck_test.go b/libbeat/cmd/platformcheck/platformcheck_test.go new file mode 100644 index 00000000000..9e8d71b4f96 --- /dev/null +++ b/libbeat/cmd/platformcheck/platformcheck_test.go @@ -0,0 +1,65 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package platformcheck + +import ( + "os" + "os/exec" + "path/filepath" + "runtime" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCheckPlatformCompat(t *testing.T) { + if !(runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || + runtime.GOOS == "windows")) { + t.Skip("Test not support on current platform") + } + + // compile test helper + tmp := t.TempDir() + helper := filepath.Join(tmp, "helper") + + cmd := exec.Command("go", "test", "-c", "-o", helper) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Env = append(os.Environ(), "GOARCH=386") + require.NoError(t, cmd.Run(), "failed to compile test helper") + + // run test helper + cmd = exec.Command(helper, "-test.v", "-test.run", "TestHelper") + cmd.Env = []string{"GO_USE_HELPER=1"} + output, err := cmd.Output() + if err != nil { + t.Logf("32bit binary tester failed.\n Output: %s", output) + } +} + +func TestHelper(t *testing.T) { + if os.Getenv("GO_USE_HELPER") != "1" { + t.Log("ignore helper") + return + } + + err := CheckNativePlatformCompat() + if err.Error() != "trying to run 32Bit binary on 64Bit system" { + t.Error("expected the native platform check to fail") + } +} diff --git a/libbeat/cmd/root.go b/libbeat/cmd/root.go index 879da55004e..b35c71dde8d 100644 --- a/libbeat/cmd/root.go +++ b/libbeat/cmd/root.go @@ -28,6 +28,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/cfgfile" "github.com/elastic/beats/v7/libbeat/cmd/instance" + "github.com/elastic/beats/v7/libbeat/cmd/platformcheck" ) func init() { @@ -56,6 +57,11 @@ type BeatsRootCmd struct { // run command, which will be called if no args are given (for backwards compatibility), // and beat settings func GenRootCmdWithSettings(beatCreator beat.Creator, settings instance.Settings) *BeatsRootCmd { + if err := platformcheck.CheckNativePlatformCompat(); err != nil { + fmt.Fprintf(os.Stderr, "Failed to initialize: %v\n", err) + os.Exit(1) + } + if settings.IndexPrefix == "" { settings.IndexPrefix = settings.Name } diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 73028e9fac4..20cad963a5c 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -9,6 +9,7 @@ - Docker container is not run as root by default. {pull}21213[21213] - Read Fleet connection information from `fleet.*` instead of `fleet.kibana.*`. {pull}24713[24713] +- Beats build for 32Bit Windows or Linux system will refuse to run on a 64bit system. {pull}25186[25186] ==== Bugfixes - Fix rename *ConfigChange to *PolicyChange to align on changes in the UI. {pull}20779[20779] diff --git a/x-pack/elastic-agent/main.go b/x-pack/elastic-agent/main.go index f9bf84484ac..170a77811f0 100644 --- a/x-pack/elastic-agent/main.go +++ b/x-pack/elastic-agent/main.go @@ -10,11 +10,17 @@ import ( "os" "time" + "github.com/elastic/beats/v7/libbeat/cmd/platformcheck" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/cmd" ) // Setups and Runs agent. func main() { + if err := platformcheck.CheckNativePlatformCompat(); err != nil { + fmt.Fprintf(os.Stderr, "Failed to initialize: %v\n", err) + os.Exit(1) + } + rand.Seed(time.Now().UnixNano()) command := cmd.NewCommand() if err := command.Execute(); err != nil {