mirror of
https://github.com/fleetdm/fleet
synced 2026-05-14 12:38:41 +00:00
> Related issue: #19886 # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality - For Orbit and Fleet Desktop changes: - [x] Manual QA must be performed in the three main OSs, macOS, Windows and Linux. - [x] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
// based on github.com/kolide/launcher/pkg/osquery/tables
|
|
package tablehelpers
|
|
|
|
// based on https://github.com/fleetdm/launcher/blob/main/pkg/osquery/tables/tablehelpers
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
// Exec is a wrapper over exec.CommandContext. It does a couple of
|
|
// additional things to help with table usage:
|
|
// 1. It enforces a timeout.
|
|
// 2. Second, it accepts an array of possible binaries locations, and if something is not
|
|
// found, it will go down the list.
|
|
// 3. It moves the stderr into the return error, if needed.
|
|
//
|
|
// This is not suitable for high performance work -- it allocates new buffers each time.
|
|
func Exec(ctx context.Context, log zerolog.Logger, timeoutSeconds int, possibleBins []string, args []string, includeStderr bool) ([]byte, error) {
|
|
ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second)
|
|
defer cancel()
|
|
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
for _, bin := range possibleBins {
|
|
stdout.Reset()
|
|
stderr.Reset()
|
|
|
|
cmd := exec.CommandContext(ctx, bin, args...)
|
|
cmd.Stdout = &stdout
|
|
if includeStderr {
|
|
cmd.Stderr = &stdout
|
|
} else {
|
|
cmd.Stderr = &stderr
|
|
}
|
|
|
|
log.Debug().Str("cmd", cmd.String()).Msg("execing")
|
|
|
|
switch err := cmd.Run(); {
|
|
case err == nil:
|
|
return stdout.Bytes(), nil
|
|
case os.IsNotExist(err):
|
|
// try the next binary
|
|
continue
|
|
default:
|
|
// an actual error
|
|
return nil, fmt.Errorf("exec '%s'. Got: '%s': %w", cmd.String(), string(stderr.Bytes()), err)
|
|
}
|
|
|
|
}
|
|
// Getting here means no binary was found
|
|
return nil, fmt.Errorf("No binary found in specified paths: %v: %w", possibleBins, os.ErrNotExist)
|
|
}
|