From bbd2d42dbb1cdebf4716c8e17bbfb8d8bde3d517 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Thu, 27 Jul 2023 11:32:02 -0400 Subject: [PATCH] Fix panic condition on docker pull failure (#1968) * [wip] add image pull error handlers Signed-off-by: Alex Goodman * fix panic and ui hang on docker pull failure Signed-off-by: Alex Goodman * linter fix Signed-off-by: Alex Goodman --------- Signed-off-by: Alex Goodman --- cmd/syft/cli/packages/packages.go | 12 +++++++++--- cmd/syft/internal/ui/ui.go | 7 +++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cmd/syft/cli/packages/packages.go b/cmd/syft/cli/packages/packages.go index a7c1d5521..0f87720fb 100644 --- a/cmd/syft/cli/packages/packages.go +++ b/cmd/syft/cli/packages/packages.go @@ -15,6 +15,7 @@ import ( "github.com/anchore/syft/internal/bus" "github.com/anchore/syft/internal/config" "github.com/anchore/syft/internal/file" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/version" "github.com/anchore/syft/syft" "github.com/anchore/syft/syft/artifact" @@ -101,14 +102,19 @@ func execWorker(app *config.Application, userInput string, writer sbom.Writer) < }, ) - if src != nil { - defer src.Close() - } if err != nil { errs <- fmt.Errorf("failed to construct source from user input %q: %w", userInput, err) return } + defer func() { + if src != nil { + if err := src.Close(); err != nil { + log.Tracef("unable to close source: %+v", err) + } + } + }() + s, err := GenerateSBOM(src, errs, app) if err != nil { errs <- err diff --git a/cmd/syft/internal/ui/ui.go b/cmd/syft/internal/ui/ui.go index f8f0fd0ae..441470b7c 100644 --- a/cmd/syft/internal/ui/ui.go +++ b/cmd/syft/internal/ui/ui.go @@ -82,12 +82,15 @@ func (m *UI) Teardown(force bool) error { if !force { m.handler.Running.Wait() m.program.Quit() + // typically in all cases we would want to wait for the UI to finish. However there are still error cases + // that are not accounted for, resulting in hangs. For now, we'll just wait for the UI to finish in the + // happy path only. There will always be an indication of the problem to the user via reporting the error + // string from the worker (outside of the UI after teardown). + m.running.Wait() } else { m.program.Kill() } - m.running.Wait() - // TODO: allow for writing out the full log output to the screen (only a partial log is shown currently) // this needs coordination to know what the last frame event is to change the state accordingly (which isn't possible now)