Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: Add support for multiple sources and distros #1218

Closed
wants to merge 10 commits into from
30 changes: 23 additions & 7 deletions cmd/syft/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,23 @@ var (
intotoJSONDsseType = `application/vnd.in-toto+json`
)

//nolint:funlen
func Run(ctx context.Context, app *config.Application, ko sigopts.KeyOpts, args []string) error {
// We cannot generate an attestation for more than one output
if len(app.Outputs) > 1 {
return fmt.Errorf("unable to generate attestation for more than one output")
}

// can only be an image for attestation or OCI DIR
userInput := args[0]
si, err := parseImageSource(userInput, app)
if err != nil {
return err
// TODO support input from config somehow
var userInputs []source.Input
for _, userInput := range args {
// could be an image or a directory, with or without a scheme
// can only be an image for attestation or OCI DIR
si, err := parseImageSource(userInput, app)
if err != nil {
return err
}
userInputs = append(userInputs, *si)
}

output := parseAttestationOutput(app.Outputs)
Expand Down Expand Up @@ -107,7 +113,7 @@ func Run(ctx context.Context, app *config.Application, ko sigopts.KeyOpts, args
subscription := eventBus.Subscribe()

return eventloop.EventLoop(
execWorker(app, *si, format, predicateType, sv),
execWorkers(app, userInputs, format, predicateType, sv),
eventloop.SetupSignals(),
subscription,
stereoscope.Cleanup,
Expand Down Expand Up @@ -151,6 +157,16 @@ func parseImageSource(userInput string, app *config.Application) (s *source.Inpu
return si, nil
}

func execWorkers(app *config.Application, sourceInputs []source.Input, format sbom.Format, predicateType string, sv *sign.SignerVerifier) <-chan error {
errs := make(chan error)
for _, src := range sourceInputs {
for err := range execWorker(app, src, format, predicateType, sv) {
errs <- err
}
}
return errs
}

func execWorker(app *config.Application, sourceInput source.Input, format sbom.Format, predicateType string, sv *sign.SignerVerifier) <-chan error {
errs := make(chan error)
go func() {
Expand All @@ -165,7 +181,7 @@ func execWorker(app *config.Application, sourceInput source.Input, format sbom.F
return
}

s, err := packages.GenerateSBOM(src, errs, app)
s, err := packages.GenerateSBOM([]source.Source{*src}, errs, app)
if err != nil {
errs <- err
return
Expand Down
2 changes: 1 addition & 1 deletion cmd/syft/cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func validateArgs(cmd *cobra.Command, args []string) error {
return fmt.Errorf("an image/directory argument is required")
}

return cobra.MaximumNArgs(1)(cmd, args)
return nil // cobra.MaximumNArgs(1)(cmd, args)
}

func checkForApplicationUpdate() {
Expand Down
85 changes: 46 additions & 39 deletions cmd/syft/cli/eventloop/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import (
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/linux"
"github.com/anchore/syft/syft/sbom"
"github.com/anchore/syft/syft/source"
)

type Task func(*sbom.Artifacts, *source.Source) ([]artifact.Relationship, error)
type Task func(*sbom.SBOM, *source.Source) error

func Tasks(app *config.Application) ([]Task, error) {
var tasks []Task
Expand Down Expand Up @@ -45,16 +46,28 @@ func generateCatalogPackagesTask(app *config.Application) (Task, error) {
return nil, nil
}

task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
task := func(results *sbom.SBOM, src *source.Source) error {
packageCatalog, relationships, theDistro, err := syft.CatalogPackages(src, app.ToCatalogerConfig())
if err != nil {
return nil, err
return err
}

for p := range packageCatalog.Enumerate() {
results.Relationships = append(results.Relationships, artifact.Relationship{
From: p,
To: &src.Metadata,
Type: artifact.SourceRelationship,
})
results.Artifacts.PackageCatalog.Add(p)
}

results.PackageCatalog = packageCatalog
results.LinuxDistribution = theDistro
if theDistro != nil {
results.Artifacts.LinuxDistributions = []linux.Release{*theDistro}
}

results.Relationships = append(results.Relationships, relationships...)

return relationships, nil
return nil
}

return task, nil
Expand All @@ -67,18 +80,18 @@ func generateCatalogFileMetadataTask(app *config.Application) (Task, error) {

metadataCataloger := file.NewMetadataCataloger()

task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
task := func(results *sbom.SBOM, src *source.Source) error {
resolver, err := src.FileResolver(app.FileMetadata.Cataloger.ScopeOpt)
if err != nil {
return nil, err
return err
}

result, err := metadataCataloger.Catalog(resolver)
if err != nil {
return nil, err
return err
}
results.FileMetadata = result
return nil, nil
results.Artifacts.FileMetadata = result
return nil
}

return task, nil
Expand Down Expand Up @@ -113,18 +126,18 @@ func generateCatalogFileDigestsTask(app *config.Application) (Task, error) {
return nil, err
}

task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
task := func(results *sbom.SBOM, src *source.Source) error {
resolver, err := src.FileResolver(app.FileMetadata.Cataloger.ScopeOpt)
if err != nil {
return nil, err
return err
}

result, err := digestsCataloger.Catalog(resolver)
if err != nil {
return nil, err
return err
}
results.FileDigests = result
return nil, nil
results.Artifacts.FileDigests = result
return nil
}

return task, nil
Expand All @@ -145,18 +158,18 @@ func generateCatalogSecretsTask(app *config.Application) (Task, error) {
return nil, err
}

task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
task := func(results *sbom.SBOM, src *source.Source) error {
resolver, err := src.FileResolver(app.Secrets.Cataloger.ScopeOpt)
if err != nil {
return nil, err
return err
}

result, err := secretsCataloger.Catalog(resolver)
if err != nil {
return nil, err
return err
}
results.Secrets = result
return nil, nil
results.Artifacts.Secrets = result
return nil
}

return task, nil
Expand All @@ -173,18 +186,18 @@ func generateCatalogFileClassificationsTask(app *config.Application) (Task, erro
return nil, err
}

task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
task := func(results *sbom.SBOM, src *source.Source) error {
resolver, err := src.FileResolver(app.FileClassification.Cataloger.ScopeOpt)
if err != nil {
return nil, err
return err
}

result, err := classifierCataloger.Catalog(resolver)
if err != nil {
return nil, err
return err
}
results.FileClassifications = result
return nil, nil
results.Artifacts.FileClassifications = result
return nil
}

return task, nil
Expand All @@ -200,33 +213,27 @@ func generateCatalogContentsTask(app *config.Application) (Task, error) {
return nil, err
}

task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) {
task := func(results *sbom.SBOM, src *source.Source) error {
resolver, err := src.FileResolver(app.FileContents.Cataloger.ScopeOpt)
if err != nil {
return nil, err
return err
}

result, err := contentsCataloger.Catalog(resolver)
if err != nil {
return nil, err
return err
}
results.FileContents = result
return nil, nil
results.Artifacts.FileContents = result
return nil
}

return task, nil
}

func RunTask(t Task, a *sbom.Artifacts, src *source.Source, c chan<- artifact.Relationship, errs chan<- error) {
defer close(c)

relationships, err := t(a, src)
func RunTask(t Task, a *sbom.SBOM, src *source.Source, errs chan<- error) {
err := t(a, src)
if err != nil {
errs <- err
return
}

for _, relationship := range relationships {
c <- relationship
}
}
Loading