Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

docker: support for registry auth in deploy #2245

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
12 changes: 10 additions & 2 deletions builtin/docker/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func (p *Platform) resourceContainerCreate(
netState *Resource_Network,
) error {
// Pull the image
err := p.pullImage(cli, log, ui, img, p.config.ForcePull)
err := p.pullImage(cli, ctx, log, ui, img, p.config.ForcePull)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could make ctx the first argument? That's our convention.

if err != nil {
return status.Errorf(codes.FailedPrecondition,
"unable to pull image from Docker registry: %s", err)
Expand Down Expand Up @@ -687,7 +687,7 @@ func (p *Platform) getDockerClient(ctx context.Context) (*client.Client, error)
return cli, nil
}

func (p *Platform) pullImage(cli *client.Client, log hclog.Logger, ui terminal.UI, img *Image, force bool) error {
func (p *Platform) pullImage(cli *client.Client, ctx context.Context, log hclog.Logger, ui terminal.UI, img *Image, force bool) error {
in := fmt.Sprintf("%s:%s", img.Image, img.Tag)
args := filters.NewArgs()
args.Add("reference", in)
Expand Down Expand Up @@ -733,6 +733,14 @@ func (p *Platform) pullImage(cli *client.Client, log hclog.Logger, ui terminal.U

in = named.Name()

dockerReg := &Registry{}
creds, err := dockerReg.findAuth(named, cli, ctx, log)
if err != nil {
return status.Errorf(codes.Internal, "failed to get docker auth: %s", err)
}

ipo.RegistryAuth = creds

log.Debug("pulling image", "image", in)

out, err := cli.ImagePull(context.Background(), in, ipo)
Expand Down
72 changes: 43 additions & 29 deletions builtin/docker/registry_docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,45 @@ func (r *Registry) pushWithDocker(
return status.Errorf(codes.Internal, "unable to parse image name: %s", err)
}

encodedAuth, err := r.findAuth(ref, cli, ctx, log)
if err != nil {
return status.Errorf(codes.Internal, "unable to extract registry credentials: %s", err)
}


step = sg.Add("Pushing Docker image...")

options := types.ImagePushOptions{
RegistryAuth: encodedAuth,
}

responseBody, err := cli.ImagePush(ctx, reference.FamiliarString(ref), options)
if err != nil {
return status.Errorf(codes.Internal, "unable to push image to registry: %s", err)
}

defer responseBody.Close()

var termFd uintptr
if f, ok := stdout.(*os.File); ok {
termFd = f.Fd()
}

err = jsonmessage.DisplayJSONMessagesStream(responseBody, step.TermOutput(), termFd, true, nil)
if err != nil {
return status.Errorf(codes.Internal, "unable to stream Docker logs to terminal: %s", err)
}

step.Done()
return nil
}

func (r *Registry) findAuth(
ref reference.Named,
cli *client.Client,
ctx context.Context,
log hclog.Logger,
) (string, error) {
encodedAuth := r.config.EncodedAuth

// If there was no explicit encoded auth but there is a password, make the username+password
Expand All @@ -73,7 +112,7 @@ func (r *Registry) pushWithDocker(

buf, err := json.Marshal(authConfig)
if err != nil {
return status.Errorf(codes.Internal, "unable to generate authentication info for registry: %s", err)
return "", status.Errorf(codes.Internal, "unable to generate authentication info for registry: %s", err)
}
encodedAuth = base64.URLEncoding.EncodeToString(buf)
}
Expand All @@ -83,7 +122,7 @@ func (r *Registry) pushWithDocker(
// Resolve the Repository name from fqn to RepositoryInfo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is the only part of the findAuth function that's currently being used in pullImage, because you're not setting r.config.EncodedAuth or r.config.Password.

repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil {
return status.Errorf(codes.Internal, "unable to parse repository info from image name: %s", err)
return "", status.Errorf(codes.Internal, "unable to parse repository info from image name: %s", err)
}

var server string
Expand All @@ -109,34 +148,9 @@ func (r *Registry) pushWithDocker(
authConfig, _ := cf.GetAuthConfig(server)
buf, err := json.Marshal(authConfig)
if err != nil {
return status.Errorf(codes.Internal, "unable to generate authentication info for registry: %s", err)
return "", status.Errorf(codes.Internal, "unable to generate authentication info for registry: %s", err)
}
encodedAuth = base64.URLEncoding.EncodeToString(buf)
}

step = sg.Add("Pushing Docker image...")

options := types.ImagePushOptions{
RegistryAuth: encodedAuth,
}

responseBody, err := cli.ImagePush(ctx, reference.FamiliarString(ref), options)
if err != nil {
return status.Errorf(codes.Internal, "unable to push image to registry: %s", err)
}

defer responseBody.Close()

var termFd uintptr
if f, ok := stdout.(*os.File); ok {
termFd = f.Fd()
}

err = jsonmessage.DisplayJSONMessagesStream(responseBody, step.TermOutput(), termFd, true, nil)
if err != nil {
return status.Errorf(codes.Internal, "unable to stream Docker logs to terminal: %s", err)
}

step.Done()
return nil
return encodedAuth, nil
}