Skip to content

Commit

Permalink
image: Fix multi-stage build caching
Browse files Browse the repository at this point in the history
* Sets tar options to remove uid, gid from files.
* Uses session-based auth with injected registry auth.

Prior to this commit, verbose logs would report errors importing cache manifests
from images built with arg `BUILDKIT_INLINE_CACHE=1`:

```
[builder 1/6] FROM docker.io/library/node:alpine@sha256:4a3a2ccfa801ce6960e7fc29fc5e5a1ed896b633e4731cdb87b4e1a1e9ad246e

digest: sha256:13a7ee18c229d7dd37fc02dee457f4e525951359df4cad0db5eeb56079cc806b
importing cache manifest from 616138583583.dkr.ecr.us-west-2.amazonaws.com/docker-provider-test-11ec639:latest
error: unexpected status code [manifests latest]: 401 Unauthorized
```
  • Loading branch information
AaronFriel committed Mar 13, 2023
1 parent 0829eef commit f396f03
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions provider/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"net"
"path/filepath"

"github.com/docker/distribution/reference"
"github.com/docker/docker/pkg/idtools"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/auth/authprovider"
"github.com/moby/moby/registry"
"net"
"path/filepath"

"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"
clitypes "github.com/docker/cli/cli/config/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
Expand Down Expand Up @@ -98,6 +102,10 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
// make the build context and ensure to exclude dockerignore file patterns
dockerIgnorePath := filepath.Join(build.Context, ".dockerignore")
initialIgnorePatterns, err := getIgnore(dockerIgnorePath)
if err != nil {
return "", nil, fmt.Errorf("error reading ignore file: %w", err)
}

// un-ignore build files so the docker daemon can use them
ignorePatterns := buildCmd.TrimBuildFilesFromExcludes(
initialIgnorePatterns,
Expand All @@ -120,8 +128,9 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
return "", nil, err
}

tar, err := archive.TarWithOptions(img.Build.Context, &archive.TarOptions{
tar, err := archive.TarWithOptions(contextDir, &archive.TarOptions{
ExcludePatterns: ignorePatterns,
ChownOpts: &idtools.Identity{UID: 0, GID: 0},
})
if err != nil {
return "", nil, err
Expand Down Expand Up @@ -157,14 +166,14 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
return "", nil, err
}
}
authConfigs[auth.ServerAddress] = auth // for image cache
regAuth = auth // for image push
authConfigs[auth.ServerAddress] = auth // for image cache
cfg.AuthConfigs[auth.ServerAddress] = clitypes.AuthConfig(auth) // for buildkit cache using session auth
regAuth = auth // for image push
}
// make the build options
opts := types.ImageBuildOptions{
Dockerfile: img.Build.Dockerfile,
Tags: []string{img.Name}, //this should build the image locally, sans registry info
Remove: true,
CacheFrom: img.Build.CachedImages,
BuildArgs: build.Args,
Version: build.BuilderVersion,
Expand All @@ -177,6 +186,10 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
// Start a session for BuildKit
if build.BuilderVersion == defaultBuilder {
sess, _ := session.NewSession(ctx, "pulumi-docker", "")

dockerAuthProvider := authprovider.NewDockerAuthProvider(cfg)
sess.Allow(dockerAuthProvider)

dialSession := func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) {
return docker.DialHijack(ctx, "/session", proto, meta)
}
Expand Down

0 comments on commit f396f03

Please sign in to comment.