From ecc35a7bd6bb251d4db4dc915af111d9a0d96ef0 Mon Sep 17 00:00:00 2001 From: Marco Pfatschbacher Date: Tue, 3 Jan 2023 16:51:44 +0100 Subject: [PATCH] Fix build for windows This needed a bigger refactoring to deal with import cycles: - Move exec_helpers to daemon package - Extract some helper functions into new helper package --- api/graylog.go | 5 +- assignments/assignment.go | 4 +- backends/backend.go | 14 ++--- backends/registry.go | 8 +-- backends/render.go | 3 +- context/context.go | 7 ++- daemon/action_handler.go | 4 +- daemon/daemon.go | 4 +- daemon/exec_helper.go | 44 +++++++++++++ daemon/exec_helper_windows.go | 61 +++++++++++++++++++ daemon/exec_runner.go | 22 ++----- .../exec_helper.go => helpers/argv_helper.go | 3 +- .../argv_helper_windows.go | 3 +- {common => helpers}/helper.go | 10 ++- {common => helpers}/helper_test.go | 2 +- logger/hooks/hooks.go | 2 +- 16 files changed, 149 insertions(+), 47 deletions(-) create mode 100644 daemon/exec_helper.go create mode 100644 daemon/exec_helper_windows.go rename common/exec_helper.go => helpers/argv_helper.go (95%) rename common/exec_helper_windows.go => helpers/argv_helper_windows.go (97%) rename {common => helpers}/helper.go (95%) rename {common => helpers}/helper_test.go (99%) diff --git a/api/graylog.go b/api/graylog.go index 81a05a0d..bb78baa1 100644 --- a/api/graylog.go +++ b/api/graylog.go @@ -19,6 +19,7 @@ import ( "bytes" "crypto/tls" "encoding/json" + "github.com/Graylog2/collector-sidecar/helpers" "io" "net/http" "strconv" @@ -164,7 +165,7 @@ func UpdateRegistration(httpClient *http.Client, checksum string, ctx *context.C registration := graylog.RegistrationRequest{} registration.NodeName = ctx.UserConfig.NodeName - registration.NodeDetails.OperatingSystem = common.GetSystemName() + registration.NodeDetails.OperatingSystem = helpers.GetSystemName() if ctx.UserConfig.SendStatus { metrics := &graylog.MetricsRequest{ @@ -172,7 +173,7 @@ func UpdateRegistration(httpClient *http.Client, checksum string, ctx *context.C CpuIdle: common.GetCpuIdle(), Load1: common.GetLoad1(), } - registration.NodeDetails.IP = common.GetHostIP() + registration.NodeDetails.IP = helpers.GetHostIP() registration.NodeDetails.Status = status registration.NodeDetails.Metrics = metrics if len(ctx.UserConfig.ListLogFiles) > 0 { diff --git a/assignments/assignment.go b/assignments/assignment.go index 5a0b9719..b540e224 100644 --- a/assignments/assignment.go +++ b/assignments/assignment.go @@ -16,7 +16,7 @@ package assignments import ( - "github.com/Graylog2/collector-sidecar/common" + "github.com/Graylog2/collector-sidecar/helpers" "reflect" ) @@ -92,7 +92,7 @@ func (as *assignmentStore) Update(assignments []ConfigurationAssignment) bool { func (as *assignmentStore) cleanup(validBackendIds []string) { for backendId := range as.assignments { - if !common.IsInList(backendId, validBackendIds) { + if !helpers.IsInList(backendId, validBackendIds) { delete(as.assignments, backendId) } } diff --git a/backends/backend.go b/backends/backend.go index 83290808..551413f0 100644 --- a/backends/backend.go +++ b/backends/backend.go @@ -18,6 +18,7 @@ package backends import ( "bytes" "fmt" + "github.com/Graylog2/collector-sidecar/helpers" "os/exec" "path/filepath" "reflect" @@ -27,7 +28,6 @@ import ( "github.com/flynn-archive/go-shlex" "github.com/Graylog2/collector-sidecar/api/graylog" - "github.com/Graylog2/collector-sidecar/common" "github.com/Graylog2/collector-sidecar/context" "github.com/Graylog2/collector-sidecar/system" ) @@ -50,7 +50,7 @@ type Backend struct { func BackendFromResponse(response graylog.ResponseCollectorBackend, configId string, ctx *context.Ctx) *Backend { return &Backend{ - Enabled: common.NewTrue(), + Enabled: helpers.NewTrue(), Id: response.Id + "-" + configId, CollectorId: response.Id, ConfigId: configId, @@ -74,10 +74,10 @@ func (b *Backend) Equals(a *Backend) bool { } func (b *Backend) EqualSettings(a *Backend) bool { - executeParameters, _ := common.Sprintf( + executeParameters, _ := helpers.Sprintf( a.ExecuteParameters, a.ConfigurationPath) - validationParameters, _ := common.Sprintf( + validationParameters, _ := helpers.Sprintf( a.ValidationParameters, a.ConfigurationPath) @@ -104,7 +104,7 @@ func (b *Backend) CheckExecutableAgainstAccesslist(context *context.Ctx) error { if len(context.UserConfig.CollectorBinariesAccesslist) <= 0 { return nil } - isListed, err := common.PathMatch(b.ExecutablePath, context.UserConfig.CollectorBinariesAccesslist) + isListed, err := helpers.PathMatch(b.ExecutablePath, context.UserConfig.CollectorBinariesAccesslist) if err != nil { return fmt.Errorf("Can not validate binary path: %s", err) } @@ -121,7 +121,7 @@ func (b *Backend) CheckExecutableAgainstAccesslist(context *context.Ctx) error { } func (b *Backend) CheckConfigPathAgainstAccesslist(context *context.Ctx) bool { - configuration, err := common.PathMatch(b.ConfigurationPath, context.UserConfig.CollectorBinariesAccesslist) + configuration, err := helpers.PathMatch(b.ConfigurationPath, context.UserConfig.CollectorBinariesAccesslist) if err != nil { log.Errorf("Can not validate configuration path: %s", err) return false @@ -145,7 +145,7 @@ func (b *Backend) ValidateConfigurationFile(context *context.Ctx) (error, string var err error var quotedArgs []string if runtime.GOOS == "windows" { - quotedArgs = common.CommandLineToArgv(b.ValidationParameters) + quotedArgs = helpers.CommandLineToArgv(b.ValidationParameters) } else { quotedArgs, err = shlex.Split(b.ValidationParameters) } diff --git a/backends/registry.go b/backends/registry.go index 6a538313..69482b4e 100644 --- a/backends/registry.go +++ b/backends/registry.go @@ -16,7 +16,7 @@ package backends import ( - "github.com/Graylog2/collector-sidecar/common" + "github.com/Graylog2/collector-sidecar/helpers" "github.com/Graylog2/collector-sidecar/logger" ) @@ -32,13 +32,13 @@ type backendStore struct { func (bs *backendStore) SetBackend(backend Backend) { bs.backends[backend.Id] = &backend - executeParameters, err := common.Sprintf(backend.ExecuteParameters, backend.ConfigurationPath) + executeParameters, err := helpers.Sprintf(backend.ExecuteParameters, backend.ConfigurationPath) if err != nil { log.Errorf("Invalid execute parameters, skip adding backend: %s", backend.Name) return } bs.backends[backend.Id].ExecuteParameters = executeParameters - validationParameters, err := common.Sprintf(backend.ValidationParameters, backend.ConfigurationPath) + validationParameters, err := helpers.Sprintf(backend.ValidationParameters, backend.ConfigurationPath) if err != nil { log.Errorf("Invalid validation parameters, skip adding backend: %s", backend.Name) return @@ -84,7 +84,7 @@ func (bs *backendStore) Update(backends []Backend) { func (bs *backendStore) Cleanup(validBackendIds []string) { for _, backend := range bs.backends { - if !common.IsInList(backend.Id, validBackendIds) { + if !helpers.IsInList(backend.Id, validBackendIds) { log.Debug("Cleaning up backend: " + backend.Name) delete(bs.backends, backend.Id) } diff --git a/backends/render.go b/backends/render.go index 973405e5..51e8f25b 100644 --- a/backends/render.go +++ b/backends/render.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/Graylog2/collector-sidecar/common" "github.com/Graylog2/collector-sidecar/context" + "github.com/Graylog2/collector-sidecar/helpers" "io/ioutil" ) @@ -27,7 +28,7 @@ func (b *Backend) render() []byte { var result bytes.Buffer result.WriteString(b.Template) - return common.ConvertLineBreak(result.Bytes()) + return helpers.ConvertLineBreak(result.Bytes()) } func (b *Backend) renderToFile(context *context.Ctx) error { diff --git a/context/context.go b/context/context.go index c1bb6939..156b8837 100644 --- a/context/context.go +++ b/context/context.go @@ -16,6 +16,8 @@ package context import ( + "github.com/Graylog2/collector-sidecar/common" + "github.com/Graylog2/collector-sidecar/helpers" "github.com/docker/go-units" "net/url" "os" @@ -25,7 +27,6 @@ import ( "time" "github.com/Graylog2/collector-sidecar/cfgfile" - "github.com/Graylog2/collector-sidecar/common" "github.com/Graylog2/collector-sidecar/logger" "github.com/Graylog2/collector-sidecar/system" ) @@ -71,7 +72,7 @@ func (ctx *Ctx) LoadConfig(path *string) error { if ctx.UserConfig.NodeId == "" { log.Fatal("No node ID was configured.") } - ctx.NodeId = common.GetCollectorId(ctx.UserConfig.NodeId) + ctx.NodeId = helpers.GetCollectorId(ctx.UserConfig.NodeId) if ctx.NodeId == "" { log.Fatal("Empty node-id, exiting! Make sure a valid id is configured.") } @@ -79,7 +80,7 @@ func (ctx *Ctx) LoadConfig(path *string) error { // node_name if ctx.UserConfig.NodeName == "" { log.Info("No node name was configured, falling back to hostname") - ctx.UserConfig.NodeName, err = common.GetHostname() + ctx.UserConfig.NodeName, err = helpers.GetHostname() if err != nil { log.Fatal("No node name configured and not able to obtain hostname as alternative.") } diff --git a/daemon/action_handler.go b/daemon/action_handler.go index 22ddc16a..0e2a9c72 100644 --- a/daemon/action_handler.go +++ b/daemon/action_handler.go @@ -18,7 +18,7 @@ package daemon import ( "github.com/Graylog2/collector-sidecar/api/graylog" "github.com/Graylog2/collector-sidecar/backends" - "github.com/Graylog2/collector-sidecar/common" + "github.com/Graylog2/collector-sidecar/helpers" ) func HandleCollectorActions(actions []graylog.ResponseCollectorAction) { @@ -37,7 +37,7 @@ func HandleCollectorActions(actions []graylog.ResponseCollectorAction) { case action.Properties["stop"] == true: stopAction(backend) default: - log.Infof("Got unsupported collector command: %s", common.Inspect(action.Properties)) + log.Infof("Got unsupported collector command: %s", helpers.Inspect(action.Properties)) } } } diff --git a/daemon/daemon.go b/daemon/daemon.go index c998dc52..df84c92c 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -18,8 +18,8 @@ package daemon import ( "github.com/Graylog2/collector-sidecar/assignments" "github.com/Graylog2/collector-sidecar/backends" - "github.com/Graylog2/collector-sidecar/common" "github.com/Graylog2/collector-sidecar/context" + "github.com/Graylog2/collector-sidecar/helpers" "github.com/Graylog2/collector-sidecar/logger" ) @@ -45,7 +45,7 @@ func init() { } func NewConfig() *DaemonConfig { - rootDir, err := common.GetRootPath() + rootDir, err := helpers.GetRootPath() if err != nil { log.Error("Can not access root directory") } diff --git a/daemon/exec_helper.go b/daemon/exec_helper.go new file mode 100644 index 00000000..24b524b9 --- /dev/null +++ b/daemon/exec_helper.go @@ -0,0 +1,44 @@ +// Copyright (C) 2020 Graylog, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the Server Side Public License, version 1, +// as published by MongoDB, Inc. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Server Side Public License for more details. +// +// You should have received a copy of the Server Side Public License +// along with this program. If not, see +// . + +//go:build !windows +// +build !windows + +package daemon + +import ( + "os" + "os/exec" + "syscall" + "time" +) + +func Setpgid(cmd *exec.Cmd) { + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} +} +func KillProcess(r *ExecRunner, proc *os.Process) { + log.Debugf("[%s] PID SIGHUP ignored, sending SIGHUP to process group", r.Name()) + err := syscall.Kill(-proc.Pid, syscall.SIGHUP) + if err != nil { + log.Debugf("[%s] Failed to HUP process group %s", r.Name(), err) + } + time.Sleep(2 * time.Second) + if r.Running() { + err := syscall.Kill(-proc.Pid, syscall.SIGKILL) + if err != nil { + log.Debugf("[%s] Failed to kill process group %s", r.Name(), err) + } + } +} diff --git a/daemon/exec_helper_windows.go b/daemon/exec_helper_windows.go new file mode 100644 index 00000000..c6238639 --- /dev/null +++ b/daemon/exec_helper_windows.go @@ -0,0 +1,61 @@ +// Copyright (C) 2020 Graylog, Inc. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the Server Side Public License, version 1, +// as published by MongoDB, Inc. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Server Side Public License for more details. +// +// You should have received a copy of the Server Side Public License +// along with this program. If not, see +// . + +// Copyright 2009 The Go Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// extracted from github.com/golang/go/blob/master/src/os/exec_windows.go + +package daemon + +import ( + "os" + "os/exec" +) + +func Setpgid(cmd *exec.Cmd) { + panic("not implemented on this platform") +} +func KillProcess(r *ExecRunner, proc *os.Process) { + err := proc.Kill() + if err != nil { + log.Debugf("[%s] Failed to kill process %s", r.Name(), err) + } +} diff --git a/daemon/exec_runner.go b/daemon/exec_runner.go index 920de8d4..b40f7ef9 100644 --- a/daemon/exec_runner.go +++ b/daemon/exec_runner.go @@ -17,6 +17,7 @@ package daemon import ( "errors" + "github.com/Graylog2/collector-sidecar/helpers" "io/ioutil" "os" "os/exec" @@ -198,7 +199,7 @@ func (r *ExecRunner) start() error { var err error var quotedArgs []string if runtime.GOOS == "windows" { - quotedArgs = common.CommandLineToArgv(r.args) + quotedArgs = helpers.CommandLineToArgv(r.args) } else { quotedArgs, err = shlex.Split(r.args) } @@ -208,7 +209,9 @@ func (r *ExecRunner) start() error { r.cmd = exec.Command(r.exec, quotedArgs...) r.cmd.Dir = r.daemon.Dir r.cmd.Env = append(os.Environ(), r.daemon.Env...) - r.cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + if runtime.GOOS != "windows" { + Setpgid(r.cmd) + } // start the actual process and don't block r.startTime = time.Now() @@ -241,20 +244,7 @@ func (r *ExecRunner) stop() error { } // in doubt kill the process - if r.Running() && runtime.GOOS != "windows" { - log.Debugf("[%s] PID SIGHUP ignored, sending SIGHUP to process group", r.Name()) - err := syscall.Kill(-r.cmd.Process.Pid, syscall.SIGHUP) - if err != nil { - log.Debugf("[%s] Failed to HUP process group %s", r.Name(), err) - } - time.Sleep(2 * time.Second) - } - if r.Running() { - err := syscall.Kill(-r.cmd.Process.Pid, syscall.SIGKILL) - if err != nil { - log.Debugf("[%s] Failed to kill process group %s", r.Name(), err) - } - } + KillProcess(r, r.cmd.Process) r.backend.SetStatus(backends.StatusStopped, "Stopped", "") diff --git a/common/exec_helper.go b/helpers/argv_helper.go similarity index 95% rename from common/exec_helper.go rename to helpers/argv_helper.go index e0bc254b..d580c3ed 100644 --- a/common/exec_helper.go +++ b/helpers/argv_helper.go @@ -13,9 +13,10 @@ // along with this program. If not, see // . +//go:build !windows // +build !windows -package common +package helpers // Dummy function. Only used on Windows func CommandLineToArgv(cmd string) []string { diff --git a/common/exec_helper_windows.go b/helpers/argv_helper_windows.go similarity index 97% rename from common/exec_helper_windows.go rename to helpers/argv_helper_windows.go index a5c69a57..75dcd7a7 100644 --- a/common/exec_helper_windows.go +++ b/helpers/argv_helper_windows.go @@ -43,9 +43,8 @@ // extracted from github.com/golang/go/blob/master/src/os/exec_windows.go -package common +package helpers -// appendBSBytes appends n '\\' bytes to b and returns the resulting slice. func appendBSBytes(b []byte, n int) []byte { for ; n > 0; n-- { b = append(b, '\\') diff --git a/common/helper.go b/helpers/helper.go similarity index 95% rename from common/helper.go rename to helpers/helper.go index bda01e71..4c09b591 100644 --- a/common/helper.go +++ b/helpers/helper.go @@ -13,13 +13,15 @@ // along with this program. If not, see // . -package common +package helpers import ( "bytes" "encoding/json" "fmt" "github.com/Graylog2/collector-sidecar/cfgfile" + "github.com/Graylog2/collector-sidecar/common" + "github.com/Graylog2/collector-sidecar/logger" "github.com/pborman/uuid" "io/ioutil" "net" @@ -31,6 +33,8 @@ import ( "unicode" ) +var log = logger.Log() + func GetRootPath() (string, error) { return filepath.Abs("/") } @@ -90,10 +94,10 @@ func GetCollectorId(collectorId string) string { } func idFromFile(filePath string) string { - err := FileExists(filePath) + err := common.FileExists(filePath) if err != nil { log.Info("node-id file doesn't exist, generating a new one") - err = CreatePathToFile(filePath) + err = common.CreatePathToFile(filePath) if err == nil { err = ioutil.WriteFile(filePath, []byte(RandomUuid()), 0644) if err != nil { diff --git a/common/helper_test.go b/helpers/helper_test.go similarity index 99% rename from common/helper_test.go rename to helpers/helper_test.go index 80a9be42..5b8d6f70 100644 --- a/common/helper_test.go +++ b/helpers/helper_test.go @@ -13,7 +13,7 @@ // along with this program. If not, see // . -package common +package helpers import ( "io/ioutil" diff --git a/logger/hooks/hooks.go b/logger/hooks/hooks.go index 52c6f842..55e5ebd0 100644 --- a/logger/hooks/hooks.go +++ b/logger/hooks/hooks.go @@ -16,13 +16,13 @@ package hooks import ( + "github.com/Graylog2/collector-sidecar/common" "github.com/Graylog2/collector-sidecar/logger" "path/filepath" "github.com/Sirupsen/logrus" "github.com/rifflock/lfshook" - "github.com/Graylog2/collector-sidecar/common" "github.com/Graylog2/collector-sidecar/context" )