mirror of https://github.com/docker/buildx.git
Merge pull request #433 from tonistiigi/buildkit-pull-creds
docker-container: ensure credentials are passed when pulling buildkit
This commit is contained in:
commit
1ccf0bd7d8
|
@ -127,7 +127,7 @@ func allIndexes(l int) []int {
|
||||||
return out
|
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))
|
clients := make([]*client.Client, len(drivers))
|
||||||
|
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
@ -135,7 +135,7 @@ func ensureBooted(ctx context.Context, drivers []DriverInfo, idxs []int, pw prog
|
||||||
for _, i := range idxs {
|
for _, i := range idxs {
|
||||||
func(i int) {
|
func(i int) {
|
||||||
eg.Go(func() error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ func splitToDriverPairs(availablePlatforms map[string]int, opt map[string]Option
|
||||||
return m
|
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{}
|
availablePlatforms := map[string]int{}
|
||||||
for i, d := range drivers {
|
for i, d := range drivers {
|
||||||
|
@ -199,7 +199,7 @@ func resolveDrivers(ctx context.Context, drivers []DriverInfo, opt map[string]Op
|
||||||
for k, opt := range opt {
|
for k, opt := range opt {
|
||||||
m[k] = []driverPair{{driverIndex: 0, platforms: opt.Platforms}}
|
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 {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ func resolveDrivers(ctx context.Context, drivers []DriverInfo, opt map[string]Op
|
||||||
// map based on existing platforms
|
// map based on existing platforms
|
||||||
if !undetectedPlatform {
|
if !undetectedPlatform {
|
||||||
m := splitToDriverPairs(availablePlatforms, opt)
|
m := splitToDriverPairs(availablePlatforms, opt)
|
||||||
clients, err := ensureBooted(ctx, drivers, driverIndexes(m), pw)
|
clients, err := ensureBooted(ctx, drivers, driverIndexes(m), auth, pw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ func resolveDrivers(ctx context.Context, drivers []DriverInfo, opt map[string]Op
|
||||||
}
|
}
|
||||||
|
|
||||||
// boot all drivers in k
|
// 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 {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
if err != nil {
|
||||||
close(pw.Status())
|
close(pw.Status())
|
||||||
<-pw.Done()
|
<-pw.Done()
|
||||||
|
|
|
@ -79,12 +79,14 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
||||||
|
|
||||||
err = loadNodeGroupData(timeoutCtx, dockerCli, ngi)
|
err = loadNodeGroupData(timeoutCtx, dockerCli, ngi)
|
||||||
|
|
||||||
|
var bootNgi *nginfo
|
||||||
if in.bootstrap {
|
if in.bootstrap {
|
||||||
var ok bool
|
var ok bool
|
||||||
ok, err = boot(ctx, ngi)
|
ok, err = boot(ctx, ngi, dockerCli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
bootNgi = ngi
|
||||||
if ok {
|
if ok {
|
||||||
ngi = &nginfo{ng: ng}
|
ngi = &nginfo{ng: ng}
|
||||||
err = loadNodeGroupData(ctx, dockerCli, ngi)
|
err = loadNodeGroupData(ctx, dockerCli, ngi)
|
||||||
|
@ -113,6 +115,8 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
||||||
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
|
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
|
||||||
} else if err := ngi.drivers[i].err; err != nil {
|
} else if err := ngi.drivers[i].err; err != nil {
|
||||||
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
|
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 {
|
} else {
|
||||||
fmt.Fprintf(w, "Status:\t%s\n", ngi.drivers[i].info.Status)
|
fmt.Fprintf(w, "Status:\t%s\n", ngi.drivers[i].info.Status)
|
||||||
if len(n.Flags) > 0 {
|
if len(n.Flags) > 0 {
|
||||||
|
@ -153,7 +157,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||||
return cmd
|
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))
|
toBoot := make([]int, 0, len(ngi.drivers))
|
||||||
for i, d := range ngi.drivers {
|
for i, d := range ngi.drivers {
|
||||||
if d.err != nil || d.di.Err != nil || d.di.Driver == nil || d.info == nil {
|
if d.err != nil || d.di.Err != nil || d.di.Driver == nil || d.info == nil {
|
||||||
|
@ -176,7 +180,7 @@ func boot(ctx context.Context, ngi *nginfo) (bool, error) {
|
||||||
func(idx int) {
|
func(idx int) {
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
pw := mw.WithPrefix(ngi.ng.Nodes[idx].Name, len(toBoot) > 1)
|
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 {
|
if err != nil {
|
||||||
ngi.drivers[idx].err = err
|
ngi.drivers[idx].err = err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/buildx/driver"
|
"github.com/docker/buildx/driver"
|
||||||
"github.com/docker/buildx/driver/bkimage"
|
"github.com/docker/buildx/driver/bkimage"
|
||||||
|
"github.com/docker/buildx/util/imagetools"
|
||||||
"github.com/docker/buildx/util/progress"
|
"github.com/docker/buildx/util/progress"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
dockertypes "github.com/docker/docker/api/types"
|
dockertypes "github.com/docker/docker/api/types"
|
||||||
|
@ -31,12 +32,12 @@ type Driver struct {
|
||||||
env []string
|
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 {
|
return progress.Wrap("[internal] booting buildkit", l, func(sub progress.SubLogger) error {
|
||||||
_, err := d.DockerAPI.ContainerInspect(ctx, d.Name)
|
_, err := d.DockerAPI.ContainerInspect(ctx, d.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if dockerclient.IsErrNotFound(err) {
|
if dockerclient.IsErrNotFound(err) {
|
||||||
return d.create(ctx, sub)
|
return d.create(ctx, auth, sub)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -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
|
imageName := bkimage.DefaultImage
|
||||||
if d.image != "" {
|
if d.image != "" {
|
||||||
imageName = d.image
|
imageName = d.image
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := l.Wrap("pulling image "+imageName, func() error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ type Driver struct {
|
||||||
driver.InitConfig
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/buildx/store"
|
"github.com/docker/buildx/store"
|
||||||
"github.com/docker/buildx/util/progress"
|
"github.com/docker/buildx/util/progress"
|
||||||
|
clitypes "github.com/docker/cli/cli/config/types"
|
||||||
"github.com/moby/buildkit/client"
|
"github.com/moby/buildkit/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -44,9 +45,13 @@ type Info struct {
|
||||||
DynamicNodes []store.Node
|
DynamicNodes []store.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Auth interface {
|
||||||
|
GetAuthConfig(registryHostname string) (clitypes.AuthConfig, error)
|
||||||
|
}
|
||||||
|
|
||||||
type Driver interface {
|
type Driver interface {
|
||||||
Factory() Factory
|
Factory() Factory
|
||||||
Bootstrap(context.Context, progress.Logger) error
|
Bootstrap(context.Context, Auth, progress.Logger) error
|
||||||
Info(context.Context) (*Info, error)
|
Info(context.Context) (*Info, error)
|
||||||
Stop(ctx context.Context, force bool) error
|
Stop(ctx context.Context, force bool) error
|
||||||
Rm(ctx context.Context, force bool) error
|
Rm(ctx context.Context, force bool) error
|
||||||
|
@ -54,7 +59,7 @@ type Driver interface {
|
||||||
Features() map[Feature]bool
|
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
|
try := 0
|
||||||
for {
|
for {
|
||||||
info, err := d.Info(ctx)
|
info, err := d.Info(ctx)
|
||||||
|
@ -66,7 +71,7 @@ func Boot(ctx context.Context, d Driver, pw progress.Writer) (*client.Client, er
|
||||||
if try > 2 {
|
if try > 2 {
|
||||||
return nil, errors.Errorf("failed to bootstrap %T driver in attempts", d)
|
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 {
|
if pw != nil {
|
||||||
pw.Status() <- s
|
pw.Status() <- s
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ type Driver struct {
|
||||||
podChooser podchooser.PodChooser
|
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 {
|
return progress.Wrap("[internal] booting buildkit", l, func(sub progress.SubLogger) error {
|
||||||
_, err := d.deploymentClient.Get(ctx, d.deployment.Name, metav1.GetOptions{})
|
_, err := d.deploymentClient.Get(ctx, d.deployment.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package imagetools
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -107,3 +109,23 @@ func toCredentialsFunc(a Auth) func(string) (string, string, error) {
|
||||||
return ac.Username, ac.Password, nil
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue