mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
fix: handle individual cataloger panics (#1636)
This commit is contained in:
parent
8e1205f7ab
commit
24584a4d27
@ -46,14 +46,11 @@ func generateCatalogPackagesTask(app *config.Application) (Task, error) {
|
||||
|
||||
task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
|
||||
packageCatalog, relationships, theDistro, err := syft.CatalogPackages(src, app.ToCatalogerConfig())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results.PackageCatalog = packageCatalog
|
||||
results.LinuxDistribution = theDistro
|
||||
|
||||
return relationships, nil
|
||||
return relationships, err
|
||||
}
|
||||
|
||||
return task, nil
|
||||
|
||||
@ -70,13 +70,10 @@ func CatalogPackages(src *source.Source, cfg cataloger.Config) (*pkg.Catalog, []
|
||||
}
|
||||
|
||||
catalog, relationships, err := cataloger.Catalog(resolver, release, cfg.Parallelism, catalogers...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
relationships = append(relationships, newSourceRelationshipsFromCatalog(src, catalog)...)
|
||||
|
||||
return catalog, relationships, release, nil
|
||||
return catalog, relationships, release, err
|
||||
}
|
||||
|
||||
func newSourceRelationshipsFromCatalog(src *source.Source, c *pkg.Catalog) []artifact.Relationship {
|
||||
|
||||
@ -3,6 +3,7 @@ package cataloger
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
@ -49,8 +50,15 @@ func newMonitor() (*progress.Manual, *progress.Manual) {
|
||||
return &filesProcessed, &packagesDiscovered
|
||||
}
|
||||
|
||||
func runCataloger(cataloger pkg.Cataloger, resolver source.FileResolver) (*catalogResult, error) {
|
||||
catalogerResult := new(catalogResult)
|
||||
func runCataloger(cataloger pkg.Cataloger, resolver source.FileResolver) (catalogerResult *catalogResult, err error) {
|
||||
// handle individual cataloger panics
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("%v at:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
catalogerResult = new(catalogResult)
|
||||
|
||||
// find packages from the underlying raw data
|
||||
log.WithFields("cataloger", cataloger.Name()).Trace("cataloging started")
|
||||
@ -88,7 +96,7 @@ func runCataloger(cataloger pkg.Cataloger, resolver source.FileResolver) (*catal
|
||||
}
|
||||
catalogerResult.Relationships = append(catalogerResult.Relationships, relationships...)
|
||||
log.WithFields("cataloger", cataloger.Name()).Trace("cataloging complete")
|
||||
return catalogerResult, nil
|
||||
return catalogerResult, err
|
||||
}
|
||||
|
||||
// Catalog a given source (container image or filesystem) with the given catalogers, returning all discovered packages.
|
||||
@ -100,7 +108,11 @@ func runCataloger(cataloger pkg.Cataloger, resolver source.FileResolver) (*catal
|
||||
func Catalog(resolver source.FileResolver, release *linux.Release, parallelism int, catalogers ...pkg.Cataloger) (*pkg.Catalog, []artifact.Relationship, error) {
|
||||
catalog := pkg.NewCatalog()
|
||||
var allRelationships []artifact.Relationship
|
||||
|
||||
filesProcessed, packagesDiscovered := newMonitor()
|
||||
defer filesProcessed.SetCompleted()
|
||||
defer packagesDiscovered.SetCompleted()
|
||||
|
||||
// perform analysis, accumulating errors for each failed analysis
|
||||
var errs error
|
||||
|
||||
@ -158,7 +170,6 @@ func Catalog(resolver source.FileResolver, release *linux.Release, parallelism i
|
||||
for result := range results {
|
||||
if result.Error != nil {
|
||||
errs = multierror.Append(errs, result.Error)
|
||||
continue
|
||||
}
|
||||
for _, p := range result.Packages {
|
||||
catalog.Add(p)
|
||||
@ -168,14 +179,7 @@ func Catalog(resolver source.FileResolver, release *linux.Release, parallelism i
|
||||
|
||||
allRelationships = append(allRelationships, pkg.NewRelationships(catalog)...)
|
||||
|
||||
if errs != nil {
|
||||
return nil, nil, errs
|
||||
}
|
||||
|
||||
filesProcessed.SetCompleted()
|
||||
packagesDiscovered.SetCompleted()
|
||||
|
||||
return catalog, allRelationships, nil
|
||||
return catalog, allRelationships, errs
|
||||
}
|
||||
|
||||
func packageFileOwnershipRelationships(p pkg.Package, resolver source.FilePathResolver) ([]artifact.Relationship, error) {
|
||||
|
||||
67
syft/pkg/cataloger/catalog_test.go
Normal file
67
syft/pkg/cataloger/catalog_test.go
Normal file
@ -0,0 +1,67 @@
|
||||
package cataloger
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/linux"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func Test_CatalogPanicHandling(t *testing.T) {
|
||||
catalog, relationships, err := Catalog(
|
||||
source.NewMockResolverForPaths(),
|
||||
&linux.Release{},
|
||||
1,
|
||||
panickingCataloger{},
|
||||
returningCataloger{},
|
||||
)
|
||||
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "catalog_test.go")
|
||||
require.Len(t, catalog.Sorted(), 2)
|
||||
require.Len(t, relationships, 1)
|
||||
}
|
||||
|
||||
type panickingCataloger struct{}
|
||||
|
||||
func (p panickingCataloger) Name() string {
|
||||
return "panicking-cataloger"
|
||||
}
|
||||
|
||||
func (p panickingCataloger) Catalog(_ source.FileResolver) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
panic("something bad happened")
|
||||
}
|
||||
|
||||
var _ pkg.Cataloger = (*panickingCataloger)(nil)
|
||||
|
||||
type returningCataloger struct{}
|
||||
|
||||
func (p returningCataloger) Name() string {
|
||||
return "returning-cataloger"
|
||||
}
|
||||
|
||||
func (p returningCataloger) Catalog(_ source.FileResolver) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
pkg1 := pkg.Package{
|
||||
Name: "package-1",
|
||||
Version: "1.0",
|
||||
}
|
||||
pkg1.SetID()
|
||||
pkg2 := pkg.Package{
|
||||
Name: "package-2",
|
||||
Version: "2.0",
|
||||
}
|
||||
pkg2.SetID()
|
||||
return []pkg.Package{pkg1, pkg2}, []artifact.Relationship{
|
||||
{
|
||||
From: pkg1,
|
||||
To: pkg2,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
var _ pkg.Cataloger = (*returningCataloger)(nil)
|
||||
Loading…
x
Reference in New Issue
Block a user