Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit 1656868

Browse files
authored
Merge pull request #1733 from ndeloof/pull_digested
stop using buildkit hack to pull images
2 parents 9fd0ac9 + fe085df commit 1656868

File tree

3 files changed

+67
-32
lines changed

3 files changed

+67
-32
lines changed

local/compose/build.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"context"
2121
"fmt"
2222
"os"
23-
"strings"
2423

2524
"github.com/compose-spec/compose-go/types"
2625
"github.com/containerd/containerd/platforms"
@@ -93,7 +92,18 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
9392
}
9493

9594
func (s *composeService) ensureImagesExists(ctx context.Context, project *types.Project, observedState Containers, quietPull bool) error {
96-
images, err := s.getImageDigests(ctx, project)
95+
for _, service := range project.Services {
96+
if service.Image == "" && service.Build == nil {
97+
return fmt.Errorf("invalid service %q. Must specify either image or build", service.Name)
98+
}
99+
}
100+
101+
images, err := s.getLocalImagesDigests(ctx, project)
102+
if err != nil {
103+
return err
104+
}
105+
106+
err = s.pullRequiredImages(ctx, project, images, quietPull)
97107
if err != nil {
98108
return err
99109
}
@@ -128,9 +138,6 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
128138
}
129139

130140
func (s *composeService) getBuildOptions(project *types.Project, images map[string]string) (map[string]build.Options, []string, error) {
131-
session := []session.Attachable{
132-
authprovider.NewDockerAuthProvider(os.Stderr),
133-
}
134141
opts := map[string]build.Options{}
135142
imagesToBuild := []string{}
136143
for _, service := range project.Services {
@@ -152,30 +159,12 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri
152159
opts[imageName] = opt
153160
continue
154161
}
155-
if service.Image != "" {
156-
if localImagePresent {
157-
continue
158-
}
159-
}
160-
// Buildx has no command to "just pull", see
161-
// so we bake a temporary dockerfile that will just pull and export pulled image
162-
opts[service.Name] = build.Options{
163-
Inputs: build.Inputs{
164-
ContextPath: ".",
165-
DockerfilePath: "-",
166-
InStream: strings.NewReader("FROM " + service.Image),
167-
},
168-
Tags: []string{service.Image}, // Used to retrieve image to pull in case of windows engine
169-
Pull: true,
170-
Session: session,
171-
}
172-
173162
}
174163
return opts, imagesToBuild, nil
175164

176165
}
177166

178-
func (s *composeService) getImageDigests(ctx context.Context, project *types.Project) (map[string]string, error) {
167+
func (s *composeService) getLocalImagesDigests(ctx context.Context, project *types.Project) (map[string]string, error) {
179168
imageNames := []string{}
180169
for _, s := range project.Services {
181170
imgName := getImageName(s, project.Name)
@@ -295,6 +284,9 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
295284
Exports: []bclient.ExportEntry{{Type: "image", Attrs: map[string]string{}}},
296285
Platforms: plats,
297286
Labels: service.Build.Labels,
287+
Session: []session.Attachable{
288+
authprovider.NewDockerAuthProvider(os.Stderr),
289+
},
298290
}, nil
299291
}
300292

local/compose/pull.go

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
7070
continue
7171
}
7272
eg.Go(func() error {
73-
err := s.pullServiceImage(ctx, service, info, s.configFile, w)
73+
err := s.pullServiceImage(ctx, service, info, s.configFile, w, false)
7474
if err != nil {
7575
if !opts.IgnoreFailures {
7676
return err
@@ -84,7 +84,7 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
8484
return eg.Wait()
8585
}
8686

87-
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig, info moby.Info, configFile driver.Auth, w progress.Writer) error {
87+
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig, info moby.Info, configFile driver.Auth, w progress.Writer, quietPull bool) error {
8888
w.Event(progress.Event{
8989
ID: service.Name,
9090
Status: progress.Working,
@@ -140,7 +140,9 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
140140
if jm.Error != nil {
141141
return metrics.WrapCategorisedComposeError(errors.New(jm.Error.Message), metrics.PullFailure)
142142
}
143-
toPullProgressEvent(service.Name, jm, w)
143+
if !quietPull {
144+
toPullProgressEvent(service.Name, jm, w)
145+
}
144146
}
145147
w.Event(progress.Event{
146148
ID: service.Name,
@@ -150,6 +152,47 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
150152
return nil
151153
}
152154

155+
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]string, quietPull bool) error {
156+
info, err := s.apiClient.Info(ctx)
157+
if err != nil {
158+
return err
159+
}
160+
161+
if info.IndexServerAddress == "" {
162+
info.IndexServerAddress = registry.IndexServer
163+
}
164+
165+
return progress.Run(ctx, func(ctx context.Context) error {
166+
w := progress.ContextWriter(ctx)
167+
eg, ctx := errgroup.WithContext(ctx)
168+
for _, service := range project.Services {
169+
if service.Image == "" {
170+
continue
171+
}
172+
switch service.PullPolicy {
173+
case types.PullPolicyMissing, types.PullPolicyIfNotPresent:
174+
if _, ok := images[service.Image]; ok {
175+
continue
176+
}
177+
case types.PullPolicyNever, types.PullPolicyBuild:
178+
continue
179+
case types.PullPolicyAlways:
180+
// force pull
181+
}
182+
service := service
183+
eg.Go(func() error {
184+
err := s.pullServiceImage(ctx, service, info, s.configFile, w, quietPull)
185+
if err != nil && service.Build != nil {
186+
// image can be built, so we can ignore pull failure
187+
return nil
188+
}
189+
return err
190+
})
191+
}
192+
return eg.Wait()
193+
})
194+
}
195+
153196
func toPullProgressEvent(parent string, jm jsonmessage.JSONMessage, w progress.Writer) {
154197
if jm.ID == "" || jm.Progress == nil {
155198
return

local/e2e/compose/metrics_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ func TestComposeMetrics(t *testing.T) {
6565
res.Assert(t, icmd.Expected{ExitCode: 16, Err: "unknown flag: --file"})
6666
res = c.RunDockerOrExitError("compose", "donw", "--file", "../compose/fixtures/wrong-composefile/compose.yml")
6767
res.Assert(t, icmd.Expected{ExitCode: 16, Err: `unknown docker command: "compose donw"`})
68-
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "pull")
69-
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
7068
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/build-error.yml", "build")
7169
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
7270
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/build-error.yml", "up")
7371
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `line 17: unknown instruction: WRONG`})
72+
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "pull")
73+
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
7474
res = c.RunDockerOrExitError("compose", "--file", "../compose/fixtures/wrong-composefile/unknown-image.yml", "up")
75-
res.Assert(t, icmd.Expected{ExitCode: 17, Err: `pull access denied, repository does not exist or may require authorization`})
75+
res.Assert(t, icmd.Expected{ExitCode: 18, Err: `pull access denied for unknownimage, repository does not exist or may require 'docker login'`})
7676

7777
usage := s.GetUsage()
7878
assert.DeepEqual(t, []string{
@@ -82,10 +82,10 @@ func TestComposeMetrics(t *testing.T) {
8282
`{"command":"compose up","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
8383
`{"command":"compose up","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
8484
`{"command":"compose","context":"moby","source":"cli","status":"failure-cmd-syntax"}`,
85-
`{"command":"compose pull","context":"moby","source":"cli","status":"failure-pull"}`,
8685
`{"command":"compose build","context":"moby","source":"cli","status":"failure-build"}`,
8786
`{"command":"compose up","context":"moby","source":"cli","status":"failure-build"}`,
88-
`{"command":"compose up","context":"moby","source":"cli","status":"failure-build"}`,
87+
`{"command":"compose pull","context":"moby","source":"cli","status":"failure-pull"}`,
88+
`{"command":"compose up","context":"moby","source":"cli","status":"failure-pull"}`,
8989
}, usage)
9090
})
9191
}

0 commit comments

Comments
 (0)