diff --git a/pkg/build/cache.go b/pkg/build/cache.go index 9a93dc5a24..0ad54dbe9c 100644 --- a/pkg/build/cache.go +++ b/pkg/build/cache.go @@ -26,6 +26,7 @@ import ( "strings" "sync" + "github.com/google/go-containerregistry/pkg/logs" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/partial" ) @@ -53,12 +54,14 @@ func (c *layerCache) get(ctx context.Context, file string, miss layerFactory) (v desc: *desc, buildLayer: miss, }, nil + } else { + logs.Debug.Printf("getMeta(%q): %v", file, err) } // Cache miss. layer, err := miss() if err != nil { - return nil, err + return nil, fmt.Errorf("miss(%q): %w", file, err) } if err := c.put(ctx, file, layer); err != nil { log.Printf("failed to cache metadata %s: %v", file, err) @@ -73,7 +76,7 @@ func (c *layerCache) getMeta(ctx context.Context, file string) (*v1.Hash, *v1.De } if buildid == "" { - return nil, nil, fmt.Errorf("no buildid for %s", file) + return nil, nil, fmt.Errorf("no buildid for %q", file) } // TODO: Implement better per-file locking. @@ -137,13 +140,13 @@ func (c *layerCache) put(ctx context.Context, file string, layer v1.Layer) error btodf, err := os.OpenFile(filepath.Join(filepath.Dir(file), "buildid-to-diffid"), os.O_RDWR|os.O_CREATE, 0755) if err != nil { - return err + return fmt.Errorf("opening buildid-to-diffid: %w", err) } defer btodf.Close() dtodf, err := os.OpenFile(filepath.Join(filepath.Dir(file), "diffid-to-descriptor"), os.O_RDWR|os.O_CREATE, 0755) if err != nil { - return err + return fmt.Errorf("opening diffid-to-descriptor: %w", err) } defer dtodf.Close() @@ -169,7 +172,7 @@ func (c *layerCache) readDiffToDesc(file string) (diffIDToDescriptor, error) { dtodf, err := os.Open(filepath.Join(filepath.Dir(file), "diffid-to-descriptor")) if err != nil { - return nil, err + return nil, fmt.Errorf("opening diffid-to-descriptor: %w", err) } defer dtodf.Close() @@ -188,7 +191,7 @@ func (c *layerCache) readBuildToDiff(file string) (buildIDToDiffID, error) { btodf, err := os.Open(filepath.Join(filepath.Dir(file), "buildid-to-diffid")) if err != nil { - return nil, err + return nil, fmt.Errorf("opening buildid-to-diffid: %w", err) } defer btodf.Close() @@ -210,7 +213,7 @@ func getBuildID(ctx context.Context, file string) (string, error) { if err := cmd.Run(); err != nil { log.Printf("Unexpected error running \"go tool buildid %s\": %v\n%v", err, file, output.String()) - return "", err + return "", fmt.Errorf("go tool buildid %s: %w", file, err) } return strings.TrimSpace(output.String()), nil } diff --git a/pkg/build/gobuild.go b/pkg/build/gobuild.go index 54a138e68d..13abd30d16 100644 --- a/pkg/build/gobuild.go +++ b/pkg/build/gobuild.go @@ -269,14 +269,14 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con return "", fmt.Errorf("could not create env for %s: %w", ip, err) } - tmpDir, err := ioutil.TempDir("", "ko") - if err != nil { - return "", err - } + tmpDir := "" if dir := os.Getenv("KOCACHE"); dir != "" { dirInfo, err := os.Stat(dir) - if os.IsNotExist(err) { + if err != nil { + if !os.IsNotExist(err) { + return "", fmt.Errorf("could not stat KOCACHE: %w", err) + } if err := os.MkdirAll(dir, os.ModePerm); err != nil && !os.IsExist(err) { return "", fmt.Errorf("could not create KOCACHE dir %s: %w", dir, err) } @@ -287,6 +287,11 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con // TODO(#264): if KOCACHE is unset, default to filepath.Join(os.TempDir(), "ko"). tmpDir = filepath.Join(dir, "bin", ip, platform.String()) if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil { + return "", fmt.Errorf("creating KOCACHE bin dir: %w", err) + } + } else { + tmpDir, err = ioutil.TempDir("", "ko") + if err != nil { return "", err } } @@ -311,7 +316,7 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con os.RemoveAll(tmpDir) } log.Printf("Unexpected error running \"go build\": %v\n%v", err, output.String()) - return "", err + return "", fmt.Errorf("go build: %w", err) } return file, nil } @@ -326,7 +331,7 @@ func goversionm(ctx context.Context, file string, appPath string, appFileName st cmd.Stdout = sbom cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - return nil, "", err + return nil, "", fmt.Errorf("go version -m %s: %w", file, err) } // In order to get deterministics SBOMs replace our randomized @@ -334,7 +339,7 @@ func goversionm(ctx context.Context, file string, appPath string, appFileName st s := []byte(strings.Replace(sbom.String(), file, appPath, 1)) if err := writeSBOM(s, appFileName, dir, "go.version-m"); err != nil { - return nil, "", err + return nil, "", fmt.Errorf("writing sbom: %w", err) } return s, "application/vnd.go.version-m", nil @@ -513,13 +518,13 @@ func tarBinary(name, binary string, platform *v1.Platform) (*bytes.Buffer, error // 0444, or 0666, none of which are executable. Mode: 0555, }); err != nil { - return nil, fmt.Errorf("writing dir %q: %w", dir, err) + return nil, fmt.Errorf("writing dir %q to tar: %w", dir, err) } } file, err := os.Open(binary) if err != nil { - return nil, err + return nil, fmt.Errorf("opening binary: %w", err) } defer file.Close() stat, err := file.Stat() @@ -544,11 +549,11 @@ func tarBinary(name, binary string, platform *v1.Platform) (*bytes.Buffer, error } // write the header to the tarball archive if err := tw.WriteHeader(header); err != nil { - return nil, err + return nil, fmt.Errorf("writing tar header: %w", err) } // copy the file data to the tarball if _, err := io.Copy(tw, file); err != nil { - return nil, err + return nil, fmt.Errorf("copying file to tar: %w", err) } return buf, nil @@ -828,7 +833,7 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl // Do the build into a temporary file. file, err := g.build(ctx, ref.Path(), g.dir, *platform, g.configForImportPath(ref.Path())) if err != nil { - return nil, err + return nil, fmt.Errorf("build: %w", err) } if os.Getenv("KOCACHE") == "" { defer os.RemoveAll(filepath.Dir(file)) @@ -839,7 +844,7 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl // Create a layer from the kodata directory under this import path. dataLayerBuf, err := g.tarKoData(ref, platform) if err != nil { - return nil, err + return nil, fmt.Errorf("tarring kodata: %w", err) } dataLayerBytes := dataLayerBuf.Bytes() dataLayer, err := tarball.LayerFromOpener(func() (io.ReadCloser, error) { @@ -868,7 +873,7 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl binaryLayer, err := g.cache.get(ctx, file, miss) if err != nil { - return nil, err + return nil, fmt.Errorf("cache.get(%q): %w", file, err) } layers = append(layers, mutate.Addendum{ @@ -948,7 +953,7 @@ func buildLayer(appPath, file string, platform *v1.Platform, layerMediaType type // Construct a tarball with the binary and produce a layer. binaryLayerBuf, err := tarBinary(appPath, file, platform) if err != nil { - return nil, err + return nil, fmt.Errorf("tarring binary: %w", err) } binaryLayerBytes := binaryLayerBuf.Bytes() return tarball.LayerFromOpener(func() (io.ReadCloser, error) { @@ -987,7 +992,7 @@ func (g *gobuild) Build(ctx context.Context, s string) (Result, error) { // early, and we lazily use the ctx within ggcr's remote package. baseRef, base, err := g.getBase(g.ctx, s) if err != nil { - return nil, err + return nil, fmt.Errorf("fetching base image: %w", err) } // Determine what kind of base we have and if we should publish an image or an index. @@ -1069,7 +1074,7 @@ func (g *gobuild) buildAll(ctx context.Context, ref string, baseRef name.Referen // Build an image for each matching platform from the base and append // it to a new index to produce the result. We use the indices to // preserve the base image ordering here. - errg, ctx := errgroup.WithContext(ctx) + errg, gctx := errgroup.WithContext(ctx) adds := make([]ocimutate.IndexAddendum, len(matches)) for i, desc := range matches { i, desc := i, desc @@ -1101,7 +1106,7 @@ func (g *gobuild) buildAll(ctx context.Context, ref string, baseRef name.Referen specsv1.AnnotationBaseImageName: baseRef.Name(), }).(v1.Image) - img, err := g.buildOne(ctx, ref, baseImage, desc.Platform) + img, err := g.buildOne(gctx, ref, baseImage, desc.Platform) if err != nil { return err }