mirror of
https://github.com/docker/compose.git
synced 2025-07-06 05:14:25 +02:00
stop using buildkit hack to pull images
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
db30ef76d0
commit
fe085df7b7
@ -20,7 +20,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
@ -87,7 +86,18 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) ensureImagesExists(ctx context.Context, project *types.Project, observedState Containers, quietPull bool) error {
|
func (s *composeService) ensureImagesExists(ctx context.Context, project *types.Project, observedState Containers, quietPull bool) error {
|
||||||
images, err := s.getImageDigests(ctx, project)
|
for _, service := range project.Services {
|
||||||
|
if service.Image == "" && service.Build == nil {
|
||||||
|
return fmt.Errorf("invalid service %q. Must specify either image or build", service.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
images, err := s.getLocalImagesDigests(ctx, project)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.pullRequiredImages(ctx, project, images, quietPull)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -122,9 +132,6 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) getBuildOptions(project *types.Project, images map[string]string) (map[string]build.Options, []string, error) {
|
func (s *composeService) getBuildOptions(project *types.Project, images map[string]string) (map[string]build.Options, []string, error) {
|
||||||
session := []session.Attachable{
|
|
||||||
authprovider.NewDockerAuthProvider(os.Stderr),
|
|
||||||
}
|
|
||||||
opts := map[string]build.Options{}
|
opts := map[string]build.Options{}
|
||||||
imagesToBuild := []string{}
|
imagesToBuild := []string{}
|
||||||
for _, service := range project.Services {
|
for _, service := range project.Services {
|
||||||
@ -146,30 +153,12 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri
|
|||||||
opts[imageName] = opt
|
opts[imageName] = opt
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if service.Image != "" {
|
|
||||||
if localImagePresent {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Buildx has no command to "just pull", see
|
|
||||||
// so we bake a temporary dockerfile that will just pull and export pulled image
|
|
||||||
opts[service.Name] = build.Options{
|
|
||||||
Inputs: build.Inputs{
|
|
||||||
ContextPath: ".",
|
|
||||||
DockerfilePath: "-",
|
|
||||||
InStream: strings.NewReader("FROM " + service.Image),
|
|
||||||
},
|
|
||||||
Tags: []string{service.Image}, // Used to retrieve image to pull in case of windows engine
|
|
||||||
Pull: true,
|
|
||||||
Session: session,
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return opts, imagesToBuild, nil
|
return opts, imagesToBuild, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) getImageDigests(ctx context.Context, project *types.Project) (map[string]string, error) {
|
func (s *composeService) getLocalImagesDigests(ctx context.Context, project *types.Project) (map[string]string, error) {
|
||||||
imageNames := []string{}
|
imageNames := []string{}
|
||||||
for _, s := range project.Services {
|
for _, s := range project.Services {
|
||||||
imgName := getImageName(s, project.Name)
|
imgName := getImageName(s, project.Name)
|
||||||
@ -289,6 +278,9 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
|
|||||||
Exports: []bclient.ExportEntry{{Type: "image", Attrs: map[string]string{}}},
|
Exports: []bclient.ExportEntry{{Type: "image", Attrs: map[string]string{}}},
|
||||||
Platforms: plats,
|
Platforms: plats,
|
||||||
Labels: service.Build.Labels,
|
Labels: service.Build.Labels,
|
||||||
|
Session: []session.Attachable{
|
||||||
|
authprovider.NewDockerAuthProvider(os.Stderr),
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ func (s *composeService) Pull(ctx context.Context, project *types.Project, opts
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
err := s.pullServiceImage(ctx, service, info, s.configFile, w)
|
err := s.pullServiceImage(ctx, service, info, s.configFile, w, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !opts.IgnoreFailures {
|
if !opts.IgnoreFailures {
|
||||||
return err
|
return err
|
||||||
@ -75,7 +75,7 @@ func (s *composeService) Pull(ctx context.Context, project *types.Project, opts
|
|||||||
return eg.Wait()
|
return eg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig, info moby.Info, configFile driver.Auth, w progress.Writer) error {
|
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig, info moby.Info, configFile driver.Auth, w progress.Writer, quietPull bool) error {
|
||||||
w.Event(progress.Event{
|
w.Event(progress.Event{
|
||||||
ID: service.Name,
|
ID: service.Name,
|
||||||
Status: progress.Working,
|
Status: progress.Working,
|
||||||
@ -131,7 +131,9 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
|||||||
if jm.Error != nil {
|
if jm.Error != nil {
|
||||||
return metrics.WrapCategorisedComposeError(errors.New(jm.Error.Message), metrics.PullFailure)
|
return metrics.WrapCategorisedComposeError(errors.New(jm.Error.Message), metrics.PullFailure)
|
||||||
}
|
}
|
||||||
toPullProgressEvent(service.Name, jm, w)
|
if !quietPull {
|
||||||
|
toPullProgressEvent(service.Name, jm, w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
w.Event(progress.Event{
|
w.Event(progress.Event{
|
||||||
ID: service.Name,
|
ID: service.Name,
|
||||||
@ -141,6 +143,47 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]string, quietPull bool) error {
|
||||||
|
info, err := s.apiClient.Info(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.IndexServerAddress == "" {
|
||||||
|
info.IndexServerAddress = registry.IndexServer
|
||||||
|
}
|
||||||
|
|
||||||
|
return progress.Run(ctx, func(ctx context.Context) error {
|
||||||
|
w := progress.ContextWriter(ctx)
|
||||||
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
for _, service := range project.Services {
|
||||||
|
if service.Image == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch service.PullPolicy {
|
||||||
|
case types.PullPolicyMissing, types.PullPolicyIfNotPresent:
|
||||||
|
if _, ok := images[service.Image]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case types.PullPolicyNever, types.PullPolicyBuild:
|
||||||
|
continue
|
||||||
|
case types.PullPolicyAlways:
|
||||||
|
// force pull
|
||||||
|
}
|
||||||
|
service := service
|
||||||
|
eg.Go(func() error {
|
||||||
|
err := s.pullServiceImage(ctx, service, info, s.configFile, w, quietPull)
|
||||||
|
if err != nil && service.Build != nil {
|
||||||
|
// image can be built, so we can ignore pull failure
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return eg.Wait()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func toPullProgressEvent(parent string, jm jsonmessage.JSONMessage, w progress.Writer) {
|
func toPullProgressEvent(parent string, jm jsonmessage.JSONMessage, w progress.Writer) {
|
||||||
if jm.ID == "" || jm.Progress == nil {
|
if jm.ID == "" || jm.Progress == nil {
|
||||||
return
|
return
|
||||||
|
@ -65,14 +65,14 @@ func TestComposeMetrics(t *testing.T) {
|
|||||||
res.Assert(t, icmd.Expected{ExitCode: 16, Err: "unknown flag: --file"})
|
res.Assert(t, icmd.Expected{ExitCode: 16, Err: "unknown flag: --file"})
|
||||||
res = c.RunDockerOrExitError("compose", "donw", "--file", "../compose/fixtures/wrong-composefile/compose.yml")
|
res = c.RunDockerOrExitError("compose", "donw", "--file", "../compose/fixtures/wrong-composefile/compose.yml")
|
||||||
res.Assert(t, icmd.Expected{ExitCode: 16, Err: `unknown docker command: "compose donw"`})
|
res.Assert(t, icmd.Expected{ExitCode: 16, Err: `unknown docker command: "compose donw"`})
|
||||||
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "pull")
|
|
||||||
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
|
|
||||||
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/build-error.yml", "build")
|
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/build-error.yml", "build")
|
||||||
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
|
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
|
||||||
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/build-error.yml", "up")
|
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/build-error.yml", "up")
|
||||||
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
|
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
|
||||||
|
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "pull")
|
||||||
|
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
|
||||||
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "up")
|
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "up")
|
||||||
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `pull access denied, repository does not exist or may require authorization`})
|
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
|
||||||
|
|
||||||
usage := s.GetUsage()
|
usage := s.GetUsage()
|
||||||
assert.DeepEqual(t, []string{
|
assert.DeepEqual(t, []string{
|
||||||
@ -82,10 +82,10 @@ func TestComposeMetrics(t *testing.T) {
|
|||||||
`{"command":"compose up","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
|
`{"command":"compose up","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
|
||||||
`{"command":"compose up","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
|
`{"command":"compose up","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
|
||||||
`{"command":"compose","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
|
`{"command":"compose","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
|
||||||
`{"command":"compose pull","context":"moby","source":"cli","status":"failure-pull"}`,
|
|
||||||
`{"command":"compose build","context":"moby","source":"cli","status":"failure-build"}`,
|
`{"command":"compose build","context":"moby","source":"cli","status":"failure-build"}`,
|
||||||
`{"command":"compose up","context":"moby","source":"cli","status":"failure-build"}`,
|
`{"command":"compose up","context":"moby","source":"cli","status":"failure-build"}`,
|
||||||
`{"command":"compose up","context":"moby","source":"cli","status":"failure-build"}`,
|
`{"command":"compose pull","context":"moby","source":"cli","status":"failure-pull"}`,
|
||||||
|
`{"command":"compose up","context":"moby","source":"cli","status":"failure-pull"}`,
|
||||||
}, usage)
|
}, usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user