From a5bbb7fe4d8c344a03337cbaa4e4ee08dcc2673f Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Thu, 14 Nov 2024 09:34:28 -0500 Subject: [PATCH] Pass errors up the stack in CalculateWorld and InstallPackages This problem was found in melange https://github.com/chainguard-dev/melange/issues/1645 Any time a download failed, we did not communicate the error up the stack. Signed-off-by: Scott Moser --- pkg/apk/apk/implementation.go | 38 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/pkg/apk/apk/implementation.go b/pkg/apk/apk/implementation.go index 34d52b942..a02fab06d 100644 --- a/pkg/apk/apk/implementation.go +++ b/pkg/apk/apk/implementation.go @@ -524,9 +524,9 @@ func (a *APK) CalculateWorld(ctx context.Context, allpkgs []*RepositoryPackage) resolved := make([]*APKResolved, len(allpkgs)) // A slice of pseudo-promises that get closed when expanded[i] is ready. - done := make([]chan struct{}, len(allpkgs)) + done := make([]chan error, len(allpkgs)) for i := range allpkgs { - done[i] = make(chan struct{}) + done[i] = make(chan error) } // Meanwhile, concurrently fetch and expand all our APKs. @@ -537,18 +537,22 @@ func (a *APK) CalculateWorld(ctx context.Context, allpkgs []*RepositoryPackage) g.Go(func() error { r, err := a.FetchPackage(ctx, pkg) if err != nil { - return fmt.Errorf("fetching %s: %w", pkg.Name, err) + err = fmt.Errorf("fetching %s: %w", pkg.Name, err) + done[i] <- err + return err } + res, err := ResolveApk(ctx, r) if err != nil { - return fmt.Errorf("resolving %s: %w", pkg.Name, err) + err = fmt.Errorf("resolving %s: %w", pkg.Name, err) + done[i] <- err + return err } res.Package = pkg resolved[i] = res - close(done[i]) - + done[i] <- nil return nil }) } @@ -645,9 +649,9 @@ func (a *APK) InstallPackages(ctx context.Context, sourceDateEpoch *time.Time, a infos := make([]*Package, len(allpkgs)) // A slice of pseudo-promises that get closed when expanded[i] is ready. - done := make([]chan struct{}, len(allpkgs)) + done := make([]chan error, len(allpkgs)) for i := range allpkgs { - done[i] = make(chan struct{}) + done[i] = make(chan error) } // Kick off a goroutine that sequentially installs packages as they become ready. @@ -660,7 +664,10 @@ func (a *APK) InstallPackages(ctx context.Context, sourceDateEpoch *time.Time, a select { case <-ctx.Done(): return ctx.Err() - case <-ch: + case err := <-ch: + if err != nil { + return err + } exp := expanded[i] pkg := allpkgs[i] @@ -700,13 +707,13 @@ func (a *APK) InstallPackages(ctx context.Context, sourceDateEpoch *time.Time, a g.Go(func() error { exp, err := a.expandPackage(ctx, pkg) if err != nil { - return fmt.Errorf("expanding %s: %w", pkg, err) + err = fmt.Errorf("expanding %s: %w", pkg, err) + } else { + expanded[i] = exp } - expanded[i] = exp - close(done[i]) - - return nil + done[i] <- err + return err }) } @@ -1151,7 +1158,8 @@ func (a *APK) expandPackage(ctx context.Context, pkg InstallablePackage) (*expan return expandPackage(ctx, a, pkg) } - return globalApkCache.get(ctx, a, pkg) + r, err := globalApkCache.get(ctx, a, pkg) + return r, err } func expandPackage(ctx context.Context, a *APK, pkg InstallablePackage) (*expandapk.APKExpanded, error) {