mirror of
https://github.com/anchore/syft.git
synced 2026-11-03 07:56:36 +01:00
add analysis coordination (with dummy analyzer)
This commit is contained in:
@@ -2,13 +2,13 @@ package analyzer
|
||||
|
||||
import (
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/imgbom/imgbom/scope"
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/stereoscope/pkg/tree"
|
||||
)
|
||||
|
||||
type Analyzer interface {
|
||||
SelectFiles(scope.Scope) []file.Reference
|
||||
SelectFiles([]*tree.FileTree) []file.Reference
|
||||
// NOTE: one of the errors which is returned is "IterationNeeded", which indicates to the driver to
|
||||
// continue with another Select/Analyze pass
|
||||
Analyze(pkg.CatalogWriter, map[file.Reference]string) error
|
||||
Analyze(map[file.Reference]string) ([]pkg.Package, error)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
"github.com/anchore/imgbom/imgbom/analyzer/dummy"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/imgbom/imgbom/scope"
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
var controllerInstance controller
|
||||
|
||||
func init() {
|
||||
controllerInstance = controller{
|
||||
analyzers: make([]Analyzer, 0),
|
||||
}
|
||||
controllerInstance.add(dummy.NewAnalyzer())
|
||||
}
|
||||
|
||||
func Analyze(s scope.Scope) (pkg.Catalog, error) {
|
||||
return controllerInstance.analyze(s)
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
@@ -16,6 +29,37 @@ func (c *controller) add(a Analyzer) {
|
||||
c.analyzers = append(c.analyzers, a)
|
||||
}
|
||||
|
||||
func Add(a Analyzer) {
|
||||
controllerInstance.add(a)
|
||||
}
|
||||
func (c *controller) analyze(s scope.Scope) (pkg.Catalog, error) {
|
||||
catalog := pkg.NewCatalog()
|
||||
fileSelection := make([]file.Reference, 0)
|
||||
|
||||
// ask analyzers for files to extract from the image tar
|
||||
for _, a := range c.analyzers {
|
||||
fileSelection = append(fileSelection, a.SelectFiles(s.Trees)...)
|
||||
}
|
||||
|
||||
// fetch contents for requested selection by analyzers
|
||||
contents, err := s.Image.MultipleFileContentsByRef(fileSelection...)
|
||||
if err != nil {
|
||||
return pkg.Catalog{}, err
|
||||
}
|
||||
|
||||
// perform analysis, accumulating errors for each failed analysis
|
||||
var errs error
|
||||
for _, a := range c.analyzers {
|
||||
packages, err := a.Analyze(contents)
|
||||
// TODO: check for multiple rounds of analyses by Iterate error
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
for _, p := range packages {
|
||||
catalog.Add(p)
|
||||
}
|
||||
}
|
||||
|
||||
if errs != nil {
|
||||
return pkg.Catalog{}, errs
|
||||
}
|
||||
|
||||
return catalog, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package dummy
|
||||
|
||||
import (
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/stereoscope/pkg/tree"
|
||||
)
|
||||
|
||||
// TODO: delete me
|
||||
|
||||
type Analyzer struct{}
|
||||
|
||||
func NewAnalyzer() *Analyzer {
|
||||
return &Analyzer{}
|
||||
}
|
||||
|
||||
func (a *Analyzer) SelectFiles(trees []*tree.FileTree) []file.Reference {
|
||||
return []file.Reference{*trees[0].File("/etc/centos-release")}
|
||||
}
|
||||
|
||||
func (a *Analyzer) Analyze(contents map[file.Reference]string) ([]pkg.Package, error) {
|
||||
return []pkg.Package{
|
||||
{
|
||||
Name: "dummy",
|
||||
Version: "1.0.0",
|
||||
Type: pkg.DebPkg,
|
||||
Metadata: pkg.DummyPackage{Extra: "some extra metadata"},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package imgbom
|
||||
|
||||
import (
|
||||
"github.com/anchore/imgbom/imgbom/analyzer"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/imgbom/imgbom/scope"
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
)
|
||||
|
||||
// TODO: add os detection results as return value
|
||||
func CatalogImage(img *image.Image, o scope.Option) (pkg.Catalog, error) {
|
||||
s, err := scope.NewScope(img, o)
|
||||
if err != nil {
|
||||
return pkg.Catalog{}, err
|
||||
}
|
||||
|
||||
// TODO: add OS detection here...
|
||||
|
||||
return analyzer.Analyze(s)
|
||||
}
|
||||
+11
-7
@@ -1,18 +1,22 @@
|
||||
package pkg
|
||||
|
||||
// TODO: add reader methods (by type, id, fuzzy search, etc)
|
||||
|
||||
type Catalog struct {
|
||||
// TODO: catalog by package ID for potential indexing
|
||||
catalog map[Type][]Package
|
||||
Packages map[Type][]Package
|
||||
}
|
||||
|
||||
type CatalogWriter interface {
|
||||
Add(Package) error
|
||||
func NewCatalog() Catalog {
|
||||
return Catalog{
|
||||
Packages: make(map[Type][]Package),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Catalog) Add(p Package) {
|
||||
_, ok := c.catalog[p.Type]
|
||||
_, ok := c.Packages[p.Type]
|
||||
if !ok {
|
||||
c.catalog[p.Type] = make([]Package, 0)
|
||||
c.Packages[p.Type] = make([]Package, 0)
|
||||
}
|
||||
c.catalog[p.Type] = append(c.catalog[p.Type], p)
|
||||
}
|
||||
c.Packages[p.Type] = append(c.Packages[p.Type], p)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package pkg
|
||||
|
||||
// TODO: delete me
|
||||
type DummyPackage struct {
|
||||
Extra string
|
||||
}
|
||||
@@ -13,4 +13,4 @@ type Package struct {
|
||||
Metadata interface{}
|
||||
}
|
||||
|
||||
// TODO: stringer...
|
||||
// TODO: stringer...
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package pkg
|
||||
|
||||
const (
|
||||
UnknownPkg uint = iota
|
||||
UnknownPkg Type = iota
|
||||
ApkPkg
|
||||
DebPkg
|
||||
JavaPkg
|
||||
@@ -14,4 +14,4 @@ const (
|
||||
|
||||
type Type uint
|
||||
|
||||
// TODO: stringer...
|
||||
// TODO: stringer...
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package scope
|
||||
|
||||
import "strings"
|
||||
|
||||
const (
|
||||
UnknownScope Option = iota
|
||||
SquashedScope
|
||||
@@ -14,6 +16,21 @@ var optionStr = []string{
|
||||
"AllLayers",
|
||||
}
|
||||
|
||||
var Options = []Option{
|
||||
SquashedScope,
|
||||
AllLayersScope,
|
||||
}
|
||||
|
||||
func ParseOption(userStr string) Option {
|
||||
switch strings.ToLower(userStr) {
|
||||
case strings.ToLower(SquashedScope.String()):
|
||||
return SquashedScope
|
||||
case strings.ToLower(AllLayersScope.String()):
|
||||
return AllLayersScope
|
||||
}
|
||||
return UnknownScope
|
||||
}
|
||||
|
||||
func (o Option) String() string {
|
||||
if int(o) >= len(optionStr) || int(o) < 0 {
|
||||
return optionStr[0]
|
||||
|
||||
Reference in New Issue
Block a user