diff --git a/cmd/remic/main.go b/cmd/remic/main.go index b6c2c96b5b20..f48398705aef 100644 --- a/cmd/remic/main.go +++ b/cmd/remic/main.go @@ -50,6 +50,19 @@ OPTIONS: Name: "output, o", Usage: "output file name", }, + cli.IntFlag{ + Name: "exit-code", + Usage: "Exit code when vulnerabilities were found", + Value: 0, + }, + cli.BoolFlag{ + Name: "skip-update", + Usage: "skip db update", + }, + cli.BoolFlag{ + Name: "ignore-unfixed", + Usage: "display only fixed vulnerabilities", + }, cli.BoolFlag{ Name: "debug, d", Usage: "debug mode", diff --git a/pkg/remic/run.go b/pkg/remic/run.go index ea3eac0576c1..df4fcf442a15 100644 --- a/pkg/remic/run.go +++ b/pkg/remic/run.go @@ -27,7 +27,8 @@ func Run(c *cli.Context) (err error) { args := c.Args() if len(args) == 0 { - return xerrors.New(`remic" requires at least 1 argument.`) + log.Logger.Info(`remic" requires at least 1 argument.`) + cli.ShowAppHelpAndExit(c, 1) } o := c.String("output") @@ -51,8 +52,10 @@ func Run(c *cli.Context) (err error) { return err } - if err = vulnsrc.Update(); err != nil { - return err + if !c.Bool("skip-update") { + if err = vulnsrc.Update(); err != nil { + return xerrors.Errorf("error in vulnerability DB update: %w", err) + } } fileName := args[0] @@ -62,7 +65,8 @@ func Run(c *cli.Context) (err error) { } defer f.Close() - result, err := scanner.ScanFile(f, severities) + ignoreUnfixed := c.Bool("ignore-unfixed") + result, err := scanner.ScanFile(f, severities, ignoreUnfixed) if err != nil { return xerrors.Errorf("failed to scan a file: %w", err) } @@ -81,5 +85,14 @@ func Run(c *cli.Context) (err error) { return xerrors.Errorf("failed to write results: %w", err) } + exitCode := c.Int("exit-code") + if exitCode != 0 { + for _, result := range []report.Result{result} { + if len(result.Vulnerabilities) > 0 { + os.Exit(exitCode) + } + } + } + return nil } diff --git a/pkg/scanner/library/scan.go b/pkg/scanner/library/scan.go index 5f1e8b7d7fcb..94ea565f7ec4 100644 --- a/pkg/scanner/library/scan.go +++ b/pkg/scanner/library/scan.go @@ -72,7 +72,7 @@ func Scan(files extractor.FileMap) (map[string][]types.Vulnerability, error) { } func ScanFile(f *os.File) ([]types.Vulnerability, error) { - scanner := NewScanner(f.Name()) + scanner := NewScanner(filepath.Base(f.Name())) if scanner == nil { return nil, xerrors.New("unknown file type") } diff --git a/pkg/scanner/scan.go b/pkg/scanner/scan.go index 8d186d533717..2191204513f3 100644 --- a/pkg/scanner/scan.go +++ b/pkg/scanner/scan.go @@ -72,7 +72,7 @@ func ScanImage(imageName, filePath string, severities []vulnerability.Severity, osFamily, osVersion, osVulns, err := ospkg.Scan(files) if err != nil { - return nil, xerrors.New("failed to scan image") + return nil, xerrors.Errorf("failed to scan image: %w", err) } @@ -83,7 +83,7 @@ func ScanImage(imageName, filePath string, severities []vulnerability.Severity, libVulns, err := library.Scan(files) if err != nil { - return nil, xerrors.New("failed to scan libraries") + return nil, xerrors.Errorf("failed to scan libraries: %w", err) } for path, vulns := range libVulns { results = append(results, report.Result{ @@ -95,14 +95,14 @@ func ScanImage(imageName, filePath string, severities []vulnerability.Severity, return results, nil } -func ScanFile(f *os.File, severities []vulnerability.Severity) (report.Result, error) { +func ScanFile(f *os.File, severities []vulnerability.Severity, ignoreUnfixed bool) (report.Result, error) { vulns, err := library.ScanFile(f) if err != nil { - return report.Result{}, xerrors.New("failed to scan libraries in file") + return report.Result{}, xerrors.Errorf("failed to scan libraries in file: %w", err) } result := report.Result{ FileName: f.Name(), - Vulnerabilities: processVulnerabilties(vulns, severities, false), + Vulnerabilities: processVulnerabilties(vulns, severities, ignoreUnfixed), } return result, nil }