Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/docker/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ type Client interface {

type dockerClient struct {
apiClient func() client.APIClient
cli command.Cli
}

func NewClient(cli command.Cli) Client {
return &dockerClient{
cli: cli,
apiClient: sync.OnceValue(func() client.APIClient {
_ = cli.Apply(func(cli *command.DockerCli) error {
if mobyClient, ok := cli.Client().(*client.Client); ok {
Expand Down
23 changes: 23 additions & 0 deletions pkg/docker/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package docker

import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -51,6 +53,25 @@ func (c *dockerClient) InspectImage(ctx context.Context, name string) (image.Ins
return c.apiClient().ImageInspect(ctx, name)
}

// getCredStoreAuth resolves registry credentials from the Docker CLI credential store.
func (c *dockerClient) getCredStoreAuth(hostname string) string {
if c.cli == nil {
return ""
}
authConfig, err := c.cli.ConfigFile().GetAuthConfig(hostname)
if err != nil || authConfig.Username == "" {
return ""
}
buf, err := json.Marshal(map[string]string{
"username": authConfig.Username,
"password": authConfig.Password,
})
if err != nil {
return ""
}
return base64.StdEncoding.EncodeToString(buf)
}

func (c *dockerClient) pullImage(ctx context.Context, imageName string, registryAuthFn func() string) error {
inspect, err := c.apiClient().ImageInspect(ctx, imageName)
if err != nil && !cerrdefs.IsNotFound(err) {
Expand Down Expand Up @@ -78,6 +99,8 @@ func (c *dockerClient) pullImage(ctx context.Context, imageName string, registry
var pullOptions image.PullOptions
if strings.HasPrefix(ref.Name(), "docker.io/") {
pullOptions.RegistryAuth = registryAuthFn()
} else {
pullOptions.RegistryAuth = c.getCredStoreAuth(reference.Domain(ref))
}

response, err := c.apiClient().ImagePull(ctx, imageName, pullOptions)
Expand Down
Loading