Skip to content

Commit

Permalink
Merge pull request #433 from tonistiigi/buildkit-pull-creds
Browse files Browse the repository at this point in the history
docker-container: ensure credentials are passed when pulling buildkit
  • Loading branch information
tonistiigi committed Nov 16, 2020
2 parents ddbfddc + ea19cf9 commit 1ccf0bd
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 19 deletions.
14 changes: 7 additions & 7 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ func allIndexes(l int) []int {
return out
}

func ensureBooted(ctx context.Context, drivers []DriverInfo, idxs []int, pw progress.Writer) ([]*client.Client, error) {
func ensureBooted(ctx context.Context, drivers []DriverInfo, idxs []int, auth Auth, pw progress.Writer) ([]*client.Client, error) {
clients := make([]*client.Client, len(drivers))

eg, ctx := errgroup.WithContext(ctx)

for _, i := range idxs {
func(i int) {
eg.Go(func() error {
c, err := driver.Boot(ctx, drivers[i].Driver, pw)
c, err := driver.Boot(ctx, drivers[i].Driver, auth, pw)
if err != nil {
return err
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func splitToDriverPairs(availablePlatforms map[string]int, opt map[string]Option
return m
}

func resolveDrivers(ctx context.Context, drivers []DriverInfo, opt map[string]Options, pw progress.Writer) (map[string][]driverPair, []*client.Client, error) {
func resolveDrivers(ctx context.Context, drivers []DriverInfo, auth Auth, opt map[string]Options, pw progress.Writer) (map[string][]driverPair, []*client.Client, error) {

availablePlatforms := map[string]int{}
for i, d := range drivers {
Expand All @@ -199,7 +199,7 @@ func resolveDrivers(ctx context.Context, drivers []DriverInfo, opt map[string]Op
for k, opt := range opt {
m[k] = []driverPair{{driverIndex: 0, platforms: opt.Platforms}}
}
clients, err := ensureBooted(ctx, drivers, driverIndexes(m), pw)
clients, err := ensureBooted(ctx, drivers, driverIndexes(m), auth, pw)
if err != nil {
return nil, nil, err
}
Expand All @@ -209,15 +209,15 @@ func resolveDrivers(ctx context.Context, drivers []DriverInfo, opt map[string]Op
// map based on existing platforms
if !undetectedPlatform {
m := splitToDriverPairs(availablePlatforms, opt)
clients, err := ensureBooted(ctx, drivers, driverIndexes(m), pw)
clients, err := ensureBooted(ctx, drivers, driverIndexes(m), auth, pw)
if err != nil {
return nil, nil, err
}
return m, clients, nil
}

// boot all drivers in k
clients, err := ensureBooted(ctx, drivers, allIndexes(len(drivers)), pw)
clients, err := ensureBooted(ctx, drivers, allIndexes(len(drivers)), auth, pw)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -506,7 +506,7 @@ func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, do
}
}

m, clients, err := resolveDrivers(ctx, drivers, opt, pw)
m, clients, err := resolveDrivers(ctx, drivers, auth, opt, pw)
if err != nil {
close(pw.Status())
<-pw.Done()
Expand Down
10 changes: 7 additions & 3 deletions commands/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {

err = loadNodeGroupData(timeoutCtx, dockerCli, ngi)

var bootNgi *nginfo
if in.bootstrap {
var ok bool
ok, err = boot(ctx, ngi)
ok, err = boot(ctx, ngi, dockerCli)
if err != nil {
return err
}
bootNgi = ngi
if ok {
ngi = &nginfo{ng: ng}
err = loadNodeGroupData(ctx, dockerCli, ngi)
Expand Down Expand Up @@ -113,6 +115,8 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
} else if err := ngi.drivers[i].err; err != nil {
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
} else if bootNgi != nil && len(bootNgi.drivers) > i && bootNgi.drivers[i].err != nil {
fmt.Fprintf(w, "Error:\t%s\n", bootNgi.drivers[i].err.Error())
} else {
fmt.Fprintf(w, "Status:\t%s\n", ngi.drivers[i].info.Status)
if len(n.Flags) > 0 {
Expand Down Expand Up @@ -153,7 +157,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
return cmd
}

func boot(ctx context.Context, ngi *nginfo) (bool, error) {
func boot(ctx context.Context, ngi *nginfo, dockerCli command.Cli) (bool, error) {
toBoot := make([]int, 0, len(ngi.drivers))
for i, d := range ngi.drivers {
if d.err != nil || d.di.Err != nil || d.di.Driver == nil || d.info == nil {
Expand All @@ -176,7 +180,7 @@ func boot(ctx context.Context, ngi *nginfo) (bool, error) {
func(idx int) {
eg.Go(func() error {
pw := mw.WithPrefix(ngi.ng.Nodes[idx].Name, len(toBoot) > 1)
_, err := driver.Boot(ctx, ngi.drivers[idx].di.Driver, pw)
_, err := driver.Boot(ctx, ngi.drivers[idx].di.Driver, dockerCli.ConfigFile(), pw)
if err != nil {
ngi.drivers[idx].err = err
}
Expand Down
15 changes: 11 additions & 4 deletions driver/docker-container/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/docker/buildx/driver"
"github.com/docker/buildx/driver/bkimage"
"github.com/docker/buildx/util/imagetools"
"github.com/docker/buildx/util/progress"
"github.com/docker/docker/api/types"
dockertypes "github.com/docker/docker/api/types"
Expand All @@ -31,12 +32,12 @@ type Driver struct {
env []string
}

func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
func (d *Driver) Bootstrap(ctx context.Context, auth driver.Auth, l progress.Logger) error {
return progress.Wrap("[internal] booting buildkit", l, func(sub progress.SubLogger) error {
_, err := d.DockerAPI.ContainerInspect(ctx, d.Name)
if err != nil {
if dockerclient.IsErrNotFound(err) {
return d.create(ctx, sub)
return d.create(ctx, auth, sub)
}
return err
}
Expand All @@ -52,14 +53,20 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
})
}

func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
func (d *Driver) create(ctx context.Context, auth driver.Auth, l progress.SubLogger) error {
imageName := bkimage.DefaultImage
if d.image != "" {
imageName = d.image
}

if err := l.Wrap("pulling image "+imageName, func() error {
rc, err := d.DockerAPI.ImageCreate(ctx, imageName, types.ImageCreateOptions{})
ra, err := imagetools.RegistryAuthForRef(imageName, auth)
if err != nil {
return err
}
rc, err := d.DockerAPI.ImageCreate(ctx, imageName, types.ImageCreateOptions{
RegistryAuth: ra,
})
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion driver/docker/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Driver struct {
driver.InitConfig
}

func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
func (d *Driver) Bootstrap(ctx context.Context, _ driver.Auth, l progress.Logger) error {
return nil
}

Expand Down
11 changes: 8 additions & 3 deletions driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/docker/buildx/store"
"github.com/docker/buildx/util/progress"
clitypes "github.com/docker/cli/cli/config/types"
"github.com/moby/buildkit/client"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -44,17 +45,21 @@ type Info struct {
DynamicNodes []store.Node
}

type Auth interface {
GetAuthConfig(registryHostname string) (clitypes.AuthConfig, error)
}

type Driver interface {
Factory() Factory
Bootstrap(context.Context, progress.Logger) error
Bootstrap(context.Context, Auth, progress.Logger) error
Info(context.Context) (*Info, error)
Stop(ctx context.Context, force bool) error
Rm(ctx context.Context, force bool) error
Client(ctx context.Context) (*client.Client, error)
Features() map[Feature]bool
}

func Boot(ctx context.Context, d Driver, pw progress.Writer) (*client.Client, error) {
func Boot(ctx context.Context, d Driver, auth Auth, pw progress.Writer) (*client.Client, error) {
try := 0
for {
info, err := d.Info(ctx)
Expand All @@ -66,7 +71,7 @@ func Boot(ctx context.Context, d Driver, pw progress.Writer) (*client.Client, er
if try > 2 {
return nil, errors.Errorf("failed to bootstrap %T driver in attempts", d)
}
if err := d.Bootstrap(ctx, func(s *client.SolveStatus) {
if err := d.Bootstrap(ctx, auth, func(s *client.SolveStatus) {
if pw != nil {
pw.Status() <- s
}
Expand Down
2 changes: 1 addition & 1 deletion driver/kubernetes/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type Driver struct {
podChooser podchooser.PodChooser
}

func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
func (d *Driver) Bootstrap(ctx context.Context, auth driver.Auth, l progress.Logger) error {
return progress.Wrap("[internal] booting buildkit", l, func(sub progress.SubLogger) error {
_, err := d.deploymentClient.Get(ctx, d.deployment.Name, metav1.GetOptions{})
if err != nil {
Expand Down
22 changes: 22 additions & 0 deletions util/imagetools/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package imagetools
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"io"
"net/http"

Expand Down Expand Up @@ -107,3 +109,23 @@ func toCredentialsFunc(a Auth) func(string) (string, string, error) {
return ac.Username, ac.Password, nil
}
}

func RegistryAuthForRef(ref string, a Auth) (string, error) {
r, err := parseRef(ref)
if err != nil {
return "", err
}
host := reference.Domain(r)
if host == "docker.io" {
host = "https://index.docker.io/v1/"
}
ac, err := a.GetAuthConfig(host)
if err != nil {
return "", err
}
buf, err := json.Marshal(ac)
if err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(buf), nil
}

0 comments on commit 1ccf0bd

Please sign in to comment.