mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 07:10:41 -08:00
feat: respect custom exit code from plugin (#6584)
Signed-off-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
@@ -9,12 +10,17 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/commands"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/plugin"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
|
||||
_ "modernc.org/sqlite" // sqlite driver for RPM DB and Java DB
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
var exitError *types.ExitError
|
||||
if errors.As(err, &exitError) {
|
||||
os.Exit(exitError.Code)
|
||||
}
|
||||
log.Fatal("Fatal error", log.Err(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/commands/operation"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
var allSupportedServicesFunc = awsScanner.AllSupportedServices
|
||||
@@ -170,6 +171,5 @@ func Run(ctx context.Context, opt flag.Options) error {
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
operation.Exit(opt, r.Failed())
|
||||
return nil
|
||||
return operation.Exit(opt, r.Failed(), types.Metadata{})
|
||||
}
|
||||
|
||||
@@ -130,6 +130,8 @@ func loadPluginCommands() []*cobra.Command {
|
||||
return nil
|
||||
},
|
||||
DisableFlagParsing: true,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
}
|
||||
commands = append(commands, cmd)
|
||||
}
|
||||
|
||||
@@ -452,10 +452,7 @@ func Run(ctx context.Context, opts flag.Options, targetKind TargetKind) (err err
|
||||
return xerrors.Errorf("report error: %w", err)
|
||||
}
|
||||
|
||||
operation.ExitOnEOL(opts, report.Metadata)
|
||||
operation.Exit(opts, report.Results.Failed())
|
||||
|
||||
return nil
|
||||
return operation.Exit(opts, report.Results.Failed(), report.Metadata)
|
||||
}
|
||||
|
||||
func disabledAnalyzers(opts flag.Options) []analyzer.Type {
|
||||
|
||||
@@ -44,8 +44,5 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
operation.ExitOnEOL(opts, r.Metadata)
|
||||
operation.Exit(opts, r.Results.Failed())
|
||||
|
||||
return nil
|
||||
return operation.Exit(opts, r.Results.Failed(), r.Metadata)
|
||||
}
|
||||
|
||||
@@ -204,16 +204,15 @@ func GetTLSConfig(caCertPath, certPath, keyPath string) (*x509.CertPool, tls.Cer
|
||||
return caCertPool, cert, nil
|
||||
}
|
||||
|
||||
func Exit(opts flag.Options, failedResults bool) {
|
||||
if opts.ExitCode != 0 && failedResults {
|
||||
os.Exit(opts.ExitCode)
|
||||
}
|
||||
}
|
||||
|
||||
func ExitOnEOL(opts flag.Options, m types.Metadata) {
|
||||
func Exit(opts flag.Options, failedResults bool, m types.Metadata) error {
|
||||
if opts.ExitOnEOL != 0 && m.OS != nil && m.OS.Eosl {
|
||||
log.Error("Detected EOL OS", log.String("family", string(m.OS.Family)),
|
||||
log.String("version", m.OS.Name))
|
||||
os.Exit(opts.ExitOnEOL)
|
||||
return &types.ExitError{Code: opts.ExitOnEOL}
|
||||
}
|
||||
|
||||
if opts.ExitCode != 0 && failedResults {
|
||||
return &types.ExitError{Code: opts.ExitCode}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -122,9 +122,7 @@ func (r *runner) run(ctx context.Context, artifacts []*k8sArtifacts.Artifact) er
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
operation.Exit(r.flagOpts, rpt.Failed())
|
||||
|
||||
return nil
|
||||
return operation.Exit(r.flagOpts, rpt.Failed(), types.Metadata{})
|
||||
}
|
||||
|
||||
// Full-cluster scanning with '--format table' without explicit '--report all' is not allowed so that it won't mess up user's terminal.
|
||||
|
||||
@@ -2,6 +2,7 @@ package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/downloader"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
|
||||
)
|
||||
|
||||
@@ -111,8 +113,11 @@ func (p Plugin) Run(ctx context.Context, opts RunOptions) error {
|
||||
// out if the error was from not being able to execute the plugin or
|
||||
// an error set by the plugin itself.
|
||||
if err = cmd.Run(); err != nil {
|
||||
if _, ok := err.(*exec.ExitError); !ok {
|
||||
return xerrors.Errorf("exit: %w", err)
|
||||
var execError *exec.ExitError
|
||||
if errors.As(err, &execError) {
|
||||
return &types.ExitError{
|
||||
Code: execError.ExitCode(),
|
||||
}
|
||||
}
|
||||
return xerrors.Errorf("plugin exec: %w", err)
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ func TestPlugin_Run(t *testing.T) {
|
||||
GOOS: "linux",
|
||||
GOARCH: "amd64",
|
||||
},
|
||||
wantErr: "plugin exec: exit status 1",
|
||||
wantErr: "exit status 1",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
||||
13
pkg/types/error.go
Normal file
13
pkg/types/error.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ExitError struct {
|
||||
Code int
|
||||
}
|
||||
|
||||
func (e *ExitError) Error() string {
|
||||
return fmt.Sprintf("exit status %d", e.Code)
|
||||
}
|
||||
Reference in New Issue
Block a user