Skip to content

Commit 6578f09

Browse files
authored
refact: exec.Command() -> exec.CommandContext() (#3826)
* refact: exec.Command() -> exec.CommandContext() * lint
1 parent d48a570 commit 6578f09

File tree

10 files changed

+50
-43
lines changed

10 files changed

+50
-43
lines changed

.golangci.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,6 @@ linters:
468468
- noctx
469469
text: "net.Listen must not be called"
470470

471-
- linters:
472-
- noctx
473-
text: "exec.Command must not be called"
474-
475471
- linters:
476472
- noctx
477473
text: "net.LookupAddr must not be called"

cmd/crowdsec-cli/cliexplain/explain.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cliexplain
22

33
import (
44
"bufio"
5+
"context"
56
"errors"
67
"fmt"
78
"io"
@@ -18,8 +19,8 @@ import (
1819
"github.com/crowdsecurity/crowdsec/pkg/hubtest"
1920
)
2021

21-
func getLineCountForFile(filepath string) (int, error) {
22-
f, err := os.Open(filepath)
22+
func getLineCountForFile(pth string) (int, error) {
23+
f, err := os.Open(pth)
2324
if err != nil {
2425
return 0, err
2526
}
@@ -83,8 +84,8 @@ tail -n 5 myfile.log | cscli explain --type nginx -f -
8384
`,
8485
Args: args.NoArgs,
8586
DisableAutoGenTag: true,
86-
RunE: func(_ *cobra.Command, _ []string) error {
87-
return cli.run()
87+
RunE: func(cmd *cobra.Command, _ []string) error {
88+
return cli.run(cmd.Context())
8889
},
8990
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
9091
fileInfo, _ := os.Stdin.Stat()
@@ -115,7 +116,7 @@ tail -n 5 myfile.log | cscli explain --type nginx -f -
115116
return cmd
116117
}
117118

118-
func (cli *cliExplain) run() error {
119+
func (cli *cliExplain) run(ctx context.Context) error {
119120
logFile := cli.flags.logFile
120121
logLine := cli.flags.logLine
121122
logType := cli.flags.logType
@@ -227,11 +228,11 @@ func (cli *cliExplain) run() error {
227228
cmdArgs = append(cmdArgs, "-label", labels)
228229
}
229230

230-
crowdsecCmd := exec.Command(crowdsec, cmdArgs...)
231+
crowdsecCmd := exec.CommandContext(ctx, crowdsec, cmdArgs...)
231232

232233
output, err := crowdsecCmd.CombinedOutput()
233234
if err != nil {
234-
fmt.Println(string(output))
235+
fmt.Fprintln(os.Stdout, string(output))
235236

236237
return fmt.Errorf("fail to run crowdsec for test: %w", err)
237238
}

pkg/acquisition/modules/journalctl/journalctl_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ journalctl_filter:
264264
err = tomb.Wait()
265265
require.NoError(t, err)
266266

267-
output, _ := exec.Command("pgrep", "-x", "journalctl").CombinedOutput()
267+
output, _ := exec.CommandContext(ctx, "pgrep", "-x", "journalctl").CombinedOutput()
268268
if len(output) != 0 {
269-
t.Fatalf("Found a journalctl process after killing the tomb !")
269+
t.Fatal("Found a journalctl process after killing the tomb !")
270270
}
271271

272272
if ts.expectedOutput != "" {

pkg/csplugin/broker.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const (
3737
CrowdsecPluginKey string = "CROWDSEC_PLUGIN_KEY"
3838
)
3939

40-
// The broker is responsible for running the plugins and dispatching events
40+
// PluginBroker is responsible for running the plugins and dispatching events
4141
// It receives all the events from the main process and stacks them up
4242
// It is as well notified by the watcher when it needs to deliver events to plugins (based on time or count threshold)
4343
type PluginBroker struct {
@@ -95,7 +95,6 @@ func (pc *PluginConfig) UnmarshalYAML(unmarshal func(any) error) error {
9595

9696
type PluginConfigList []PluginConfig
9797

98-
9998
func (pb *PluginBroker) Init(ctx context.Context, pluginCfg *csconfig.PluginCfg, profileConfigs []*csconfig.ProfileCfg, configPaths *csconfig.ConfigurationPaths) error {
10099
pb.PluginChannel = make(chan models.ProfileAlert)
101100
pb.notificationConfigsByPluginType = make(map[string][][]byte)
@@ -300,7 +299,7 @@ func (pb *PluginBroker) loadPlugins(ctx context.Context, path string) error {
300299
continue
301300
}
302301

303-
pluginClient, err := pb.loadNotificationPlugin(pSubtype, binaryPath)
302+
pluginClient, err := pb.loadNotificationPlugin(ctx, pSubtype, binaryPath)
304303
if err != nil {
305304
return err
306305
}
@@ -331,15 +330,15 @@ func (pb *PluginBroker) loadPlugins(ctx context.Context, path string) error {
331330
return pb.verifyPluginBinaryWithProfile()
332331
}
333332

334-
func (pb *PluginBroker) loadNotificationPlugin(name string, binaryPath string) (protobufs.NotifierServer, error) {
333+
func (pb *PluginBroker) loadNotificationPlugin(ctx context.Context, name string, binaryPath string) (protobufs.NotifierServer, error) {
335334
handshake, err := getHandshake()
336335
if err != nil {
337336
return nil, err
338337
}
339338

340339
log.Debugf("Executing plugin %s", binaryPath)
341340

342-
cmd, err := pb.CreateCmd(binaryPath)
341+
cmd, err := pb.CreateCmd(ctx, binaryPath)
343342
if err != nil {
344343
return nil, err
345344
}

pkg/csplugin/broker_suite_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ func (s *PluginSuite) SetupSuite() {
5151
s.builtBinary += ".exe"
5252
}
5353

54-
cmd := exec.Command("go", "build", "-o", s.builtBinary, "../../cmd/notification-dummy/")
54+
ctx := t.Context()
55+
56+
cmd := exec.CommandContext(ctx, "go", "build", "-o", s.builtBinary, "../../cmd/notification-dummy/")
5557
err = cmd.Run()
5658
require.NoError(t, err, "while building dummy plugin")
5759
}
@@ -120,6 +122,7 @@ func (s *PluginSuite) SetupSubTest() {
120122

121123
err = copyFile(s.builtBinary, s.pluginBinary)
122124
require.NoError(t, err, "while copying built binary")
125+
123126
err = os.Chmod(s.pluginBinary, 0o744)
124127
require.NoError(t, err, "chmod 0744 %s", s.pluginBinary)
125128

pkg/csplugin/utils.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package csplugin
44

55
import (
6+
"context"
67
"errors"
78
"fmt"
89
"io/fs"
@@ -25,9 +26,9 @@ func CheckCredential(uid int, gid int) *syscall.SysProcAttr {
2526
}
2627
}
2728

28-
func (pb *PluginBroker) CreateCmd(binaryPath string) (*exec.Cmd, error) {
29+
func (pb *PluginBroker) CreateCmd(ctx context.Context, binaryPath string) (*exec.Cmd, error) {
2930
var err error
30-
cmd := exec.Command(binaryPath)
31+
cmd := exec.CommandContext(ctx, binaryPath)
3132
if pb.pluginProcConfig.User != "" || pb.pluginProcConfig.Group != "" {
3233
if pb.pluginProcConfig.User == "" || pb.pluginProcConfig.Group == "" {
3334
return nil, errors.New("while getting process attributes: both plugin user and group must be set")

pkg/csplugin/utils_js.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package csplugin
22

3-
import "os/exec"
3+
import (
4+
"context"
5+
"os/exec"
6+
)
47

58
//All functions are empty, just to make the code compile when targeting js/wasm
69

7-
func (pb *PluginBroker) CreateCmd(binaryPath string) (*exec.Cmd, error) {
10+
func (pb *PluginBroker) CreateCmd(ctx context.Context, binaryPath string) (*exec.Cmd, error) {
811
return nil, nil
912
}
1013

pkg/csplugin/utils_windows.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package csplugin
44

55
import (
6+
"context"
67
"errors"
78
"fmt"
89
"os"
@@ -200,9 +201,9 @@ func getProcessAtr() (*syscall.SysProcAttr, error) {
200201
}, nil
201202
}
202203

203-
func (pb *PluginBroker) CreateCmd(binaryPath string) (*exec.Cmd, error) {
204+
func (pb *PluginBroker) CreateCmd(ctx context.Context, binaryPath string) (*exec.Cmd, error) {
204205
var err error
205-
cmd := exec.Command(binaryPath)
206+
cmd := exec.CommandContext(ctx, binaryPath)
206207
cmd.SysProcAttr, err = getProcessAtr()
207208
if err != nil {
208209
return nil, fmt.Errorf("while getting process attributes: %w", err)

pkg/hubtest/hubtest_item.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ func NewTest(name string, hubTest *HubTest, dataDir string) (*HubTestItem, error
123123
}
124124

125125
parserAssertFilePath := filepath.Join(testPath, ParserAssertFileName)
126-
ParserAssert := NewParserAssert(parserAssertFilePath)
126+
parserAssert := NewParserAssert(parserAssertFilePath)
127127

128128
scenarioAssertFilePath := filepath.Join(testPath, ScenarioAssertFileName)
129-
ScenarioAssert := NewScenarioAssert(scenarioAssertFilePath)
129+
scenarioAssert := NewScenarioAssert(scenarioAssertFilePath)
130130

131131
// force own_data_dir for backard compatibility
132132
if name == "magento-ccs-by-as" || name == "magento-ccs-by-country" || name == "geoip-enrich" {
@@ -170,8 +170,8 @@ func NewTest(name string, hubTest *HubTest, dataDir string) (*HubTestItem, error
170170
TemplateAcquisPath: hubTest.TemplateAcquisPath,
171171
TemplateAppsecProfilePath: hubTest.TemplateAppsecProfilePath,
172172
HubIndex: hubTest.HubIndex,
173-
ScenarioAssert: ScenarioAssert,
174-
ParserAssert: ParserAssert,
173+
ScenarioAssert: scenarioAssert,
174+
ParserAssert: parserAssert,
175175
CustomItemsLocation: []string{hubTest.HubPath, testPath},
176176
NucleiTargetHost: hubTest.NucleiTargetHost,
177177
AppSecHost: hubTest.AppSecHost,
@@ -318,7 +318,7 @@ func (t *HubTestItem) ImprovedLogDisplay(crowdsecLogFile string) error {
318318
return nil
319319
}
320320

321-
func (t *HubTestItem) RunWithNucleiTemplate() error {
321+
func (t *HubTestItem) RunWithNucleiTemplate(ctx context.Context) error {
322322
testPath := filepath.Join(t.HubTestPath, t.Name)
323323
if _, err := os.Stat(testPath); os.IsNotExist(err) {
324324
return fmt.Errorf("test '%s' doesn't exist in '%s', exiting", t.Name, t.HubTestPath)
@@ -328,7 +328,7 @@ func (t *HubTestItem) RunWithNucleiTemplate() error {
328328

329329
// machine add
330330
cmdArgs := []string{"-c", t.RuntimeConfigFilePath, "machines", "add", "testMachine", "--force", "--auto"}
331-
cscliRegisterCmd := exec.Command(t.CscliPath, cmdArgs...)
331+
cscliRegisterCmd := exec.CommandContext(ctx, t.CscliPath, cmdArgs...)
332332
cscliRegisterCmd.Dir = testPath
333333
cscliRegisterCmd.Env = []string{"TESTDIR=" + testPath, "DATADIR=" + t.RuntimeHubConfig.InstallDataDir, "TZ=UTC"}
334334

@@ -342,7 +342,7 @@ func (t *HubTestItem) RunWithNucleiTemplate() error {
342342

343343
// hardcode bouncer key
344344
cmdArgs = []string{"-c", t.RuntimeConfigFilePath, "bouncers", "add", "appsectests", "-k", TestBouncerApiKey}
345-
cscliBouncerCmd := exec.Command(t.CscliPath, cmdArgs...)
345+
cscliBouncerCmd := exec.CommandContext(ctx, t.CscliPath, cmdArgs...)
346346
cscliBouncerCmd.Dir = testPath
347347
cscliBouncerCmd.Env = []string{"TESTDIR=" + testPath, "DATADIR=" + t.RuntimeHubConfig.InstallDataDir, "TZ=UTC"}
348348

@@ -356,7 +356,7 @@ func (t *HubTestItem) RunWithNucleiTemplate() error {
356356

357357
// start crowdsec service
358358
cmdArgs = []string{"-c", t.RuntimeConfigFilePath}
359-
crowdsecDaemon := exec.Command(t.CrowdSecPath, cmdArgs...)
359+
crowdsecDaemon := exec.CommandContext(ctx, t.CrowdSecPath, cmdArgs...)
360360
crowdsecDaemon.Dir = testPath
361361
crowdsecDaemon.Env = []string{"TESTDIR=" + testPath, "DATADIR=" + t.RuntimeHubConfig.InstallDataDir, "TZ=UTC"}
362362

@@ -400,7 +400,7 @@ func (t *HubTestItem) RunWithNucleiTemplate() error {
400400
// the value in config is relative
401401
nucleiTemplate := filepath.Join(t.Path, t.Config.NucleiTemplate)
402402

403-
err = nucleiConfig.RunNucleiTemplate(t.Name, nucleiTemplate, t.NucleiTargetHost)
403+
err = nucleiConfig.RunNucleiTemplate(ctx, t.Name, nucleiTemplate, t.NucleiTargetHost)
404404
if t.Config.ExpectedNucleiFailure {
405405
if err != nil && errors.Is(err, ErrNucleiTemplateFail) {
406406
log.Infof("Appsec test %s failed as expected", t.Name)
@@ -441,7 +441,7 @@ func createDirs(dirs []string) error {
441441
return nil
442442
}
443443

444-
func (t *HubTestItem) RunWithLogFile() error {
444+
func (t *HubTestItem) RunWithLogFile(ctx context.Context) error {
445445
testPath := filepath.Join(t.HubTestPath, t.Name)
446446
if _, err := os.Stat(testPath); os.IsNotExist(err) {
447447
return fmt.Errorf("test '%s' doesn't exist in '%s', exiting", t.Name, t.HubTestPath)
@@ -461,7 +461,7 @@ func (t *HubTestItem) RunWithLogFile() error {
461461
}
462462

463463
cmdArgs := []string{"-c", t.RuntimeConfigFilePath, "machines", "add", "testMachine", "--force", "--auto"}
464-
cscliRegisterCmd := exec.Command(t.CscliPath, cmdArgs...)
464+
cscliRegisterCmd := exec.CommandContext(ctx, t.CscliPath, cmdArgs...)
465465
cscliRegisterCmd.Dir = testPath
466466
cscliRegisterCmd.Env = []string{"TESTDIR=" + testPath, "DATADIR=" + t.RuntimeHubConfig.InstallDataDir, "TZ=UTC"}
467467

@@ -482,7 +482,7 @@ func (t *HubTestItem) RunWithLogFile() error {
482482
cmdArgs = append(cmdArgs, "-label", arg)
483483
}
484484

485-
crowdsecCmd := exec.Command(t.CrowdSecPath, cmdArgs...)
485+
crowdsecCmd := exec.CommandContext(ctx, t.CrowdSecPath, cmdArgs...)
486486
crowdsecCmd.Dir = testPath
487487
crowdsecCmd.Env = []string{"TESTDIR=" + testPath, "DATADIR=" + t.RuntimeHubConfig.InstallDataDir, "TZ=UTC"}
488488

@@ -649,11 +649,11 @@ func (t *HubTestItem) Run(ctx context.Context, patternDir string) error {
649649
}
650650

651651
if t.Config.LogFile != "" {
652-
return t.RunWithLogFile()
652+
return t.RunWithLogFile(ctx)
653653
}
654654

655655
if t.Config.NucleiTemplate != "" {
656-
return t.RunWithNucleiTemplate()
656+
return t.RunWithNucleiTemplate(ctx)
657657
}
658658

659659
return fmt.Errorf("log file or nuclei template must be set in '%s'", t.Name)

pkg/hubtest/nucleirunner.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package hubtest
22

33
import (
44
"bytes"
5+
"context"
56
"errors"
67
"fmt"
78
"os"
@@ -19,7 +20,7 @@ type NucleiConfig struct {
1920

2021
var ErrNucleiTemplateFail = errors.New("nuclei template failed")
2122

22-
func (nc *NucleiConfig) RunNucleiTemplate(testName string, templatePath string, target string) error {
23+
func (nc *NucleiConfig) RunNucleiTemplate(ctx context.Context, testName string, templatePath string, target string) error {
2324
tstamp := time.Now().Unix()
2425

2526
outputPrefix := fmt.Sprintf("%s/%s-%d", nc.OutputDir, testName, tstamp)
@@ -30,7 +31,7 @@ func (nc *NucleiConfig) RunNucleiTemplate(testName string, templatePath string,
3031
"-o", outputPrefix + ".json",
3132
}
3233
args = append(args, nc.CmdLineOptions...)
33-
cmd := exec.Command(nc.Path, args...)
34+
cmd := exec.CommandContext(ctx, nc.Path, args...)
3435

3536
log.Debugf("Running Nuclei command: '%s'", cmd.String())
3637

@@ -41,7 +42,6 @@ func (nc *NucleiConfig) RunNucleiTemplate(testName string, templatePath string,
4142
cmd.Stderr = &outErr
4243

4344
err := cmd.Run()
44-
4545
if err := os.WriteFile(outputPrefix+"_stdout.txt", out.Bytes(), 0o644); err != nil {
4646
log.Warningf("Error writing stdout: %s", err)
4747
}
@@ -55,13 +55,16 @@ func (nc *NucleiConfig) RunNucleiTemplate(testName string, templatePath string,
5555
log.Warningf("Stdout saved to %s", outputPrefix+"_stdout.txt")
5656
log.Warningf("Stderr saved to %s", outputPrefix+"_stderr.txt")
5757
log.Warningf("Nuclei generated output saved to %s", outputPrefix+".json")
58+
5859
return err
5960
} else if out.String() == "" {
6061
log.Warningf("Stdout saved to %s", outputPrefix+"_stdout.txt")
6162
log.Warningf("Stderr saved to %s", outputPrefix+"_stderr.txt")
6263
log.Warningf("Nuclei generated output saved to %s", outputPrefix+".json")
63-
//No stdout means no finding, it means our test failed
64+
65+
// No stdout means no finding, it means our test failed
6466
return ErrNucleiTemplateFail
6567
}
68+
6669
return nil
6770
}

0 commit comments

Comments
 (0)