Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 8a1a9f0

Browse files
committed
Fix reference for service images we know by tag
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 3912d44 commit 8a1a9f0

File tree

7 files changed

+60
-16
lines changed

7 files changed

+60
-16
lines changed

e2e/build_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ func TestBuild(t *testing.T) {
4343
icmd.RunCmd(cmd).Assert(t, icmd.Success)
4444
}
4545

46+
for _, img := range bndl.Images {
47+
// Check all image not being built locally get a fixed reference
48+
assert.Assert(t, img.Image == "" || strings.Contains(img.Image, "@sha256:"))
49+
}
50+
4651
_, err = os.Stat(iidfile)
4752
assert.NilError(t, err)
4853
bytes, err := ioutil.ReadFile(iidfile)

e2e/commands_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,14 @@ func TestRenderFormatters(t *testing.T) {
7575
cmd := info.configuredCmd
7676

7777
contextPath := filepath.Join("testdata", "simple")
78-
appPath := filepath.Join(contextPath, "simple.dockerapp")
79-
cmd.Command = dockerCli.Command("app", "build", "--tag", "a-simple-tag", contextPath)
78+
cmd.Command = dockerCli.Command("app", "build", "--tag", "a-simple-tag", "--no-resolve-image", contextPath)
8079
icmd.RunCmd(cmd).Assert(t, icmd.Success)
8180

82-
cmd.Command = dockerCli.Command("app", "render", "--formatter", "json", appPath)
81+
cmd.Command = dockerCli.Command("app", "render", "--formatter", "json", "a-simple-tag")
8382
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
8483
golden.Assert(t, result.Stdout(), "expected-json-render.golden")
8584

86-
cmd.Command = dockerCli.Command("app", "render", "--formatter", "yaml", appPath)
85+
cmd.Command = dockerCli.Command("app", "render", "--formatter", "yaml", "a-simple-tag")
8786
result = icmd.RunCmd(cmd).Assert(t, icmd.Success)
8887
golden.Assert(t, result.Stdout(), "expected-yaml-render.golden")
8988
})

e2e/testdata/expected-json-render.golden

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"resources": {},
1818
"placement": {}
1919
},
20-
"image": "python:3.6",
20+
"image": "python:3.6@sha256:52f872eae9755743c9494e0e3cf02a47d34b42032cab1e5ab777b30c3665d5f1",
2121
"networks": {
2222
"back": null,
2323
"front": {
@@ -35,7 +35,7 @@
3535
"resources": {},
3636
"placement": {}
3737
},
38-
"image": "postgres:9.3",
38+
"image": "postgres:9.3@sha256:3cd40afb5803762170a1149ade6962fe24d405b3ccf2fe499ff1428635520a17",
3939
"networks": {
4040
"back": null
4141
}
@@ -47,7 +47,7 @@
4747
"resources": {},
4848
"placement": {}
4949
},
50-
"image": "nginx:latest",
50+
"image": "nginx:latest@sha256:922c815aa4df050d4df476e92daed4231f466acc8ee90e0e774951b0fd7195a4",
5151
"networks": {
5252
"front": null
5353
},

e2e/testdata/expected-yaml-render.golden

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
version: "3.6"
22
services:
33
api:
4-
image: python:3.6
4+
image: python:3.6@sha256:52f872eae9755743c9494e0e3cf02a47d34b42032cab1e5ab777b30c3665d5f1
55
networks:
66
back: null
77
front:
88
aliases:
99
- api.example.com
1010
- example.com
1111
db:
12-
image: postgres:9.3
12+
image: postgres:9.3@sha256:3cd40afb5803762170a1149ade6962fe24d405b3ccf2fe499ff1428635520a17
1313
networks:
1414
back: null
1515
web:
16-
image: nginx:latest
16+
image: nginx:latest@sha256:922c815aa4df050d4df476e92daed4231f466acc8ee90e0e774951b0fd7195a4
1717
networks:
1818
front: null
1919
ports:

internal/commands/build/build.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ import (
1212
"strconv"
1313
"strings"
1414

15+
errors2 "github.com/pkg/errors"
16+
17+
"github.com/docker/app/internal"
18+
"github.com/docker/cnab-to-oci/remotes"
19+
1520
"github.com/deislabs/cnab-go/bundle"
1621
cnab "github.com/deislabs/cnab-go/driver"
1722
"github.com/docker/app/internal/packager"
@@ -130,7 +135,7 @@ func runBuild(dockerCli command.Cli, contextPath string, opt buildOptions) error
130135
}
131136

132137
func buildImageUsingBuildx(app *types.App, contextPath string, opt buildOptions, dockerCli command.Cli) (*bundle.Bundle, error) {
133-
buildopts, err := parseCompose(app, contextPath, opt)
138+
buildopts, pulledServices, err := parseCompose(app, contextPath, opt)
134139
if err != nil {
135140
return nil, err
136141
}
@@ -178,9 +183,42 @@ func buildImageUsingBuildx(app *types.App, contextPath string, opt buildOptions,
178183
if err != nil {
179184
return nil, err
180185
}
186+
187+
if !opt.noResolveImage {
188+
if err = fixServiceImageReferences(ctx, dockerCli, bundle, pulledServices); err != nil {
189+
return nil, err
190+
}
191+
}
192+
181193
return bundle, nil
182194
}
183195

196+
func fixServiceImageReferences(ctx context.Context, dockerCli command.Cli, bundle *bundle.Bundle, pulledServices []ServiceConfig) error {
197+
insecureRegistries, err := internal.InsecureRegistriesFromEngine(dockerCli)
198+
if err != nil {
199+
return errors2.Wrapf(err, "could not retrieve insecure registries")
200+
}
201+
resolver := remotes.CreateResolver(dockerCli.ConfigFile(), insecureRegistries...)
202+
for _, service := range pulledServices {
203+
image := bundle.Images[service.Name]
204+
ref, err := reference.ParseNormalizedNamed(*service.Image)
205+
if err != nil {
206+
return errors2.Wrapf(err, "could not resolve image %s", *service.Image)
207+
}
208+
_, desc, err := resolver.Resolve(ctx, ref.String())
209+
if err != nil {
210+
return errors2.Wrapf(err, "could not resolve image %s", ref.Name())
211+
}
212+
canonical, err := reference.WithDigest(ref, desc.Digest)
213+
if err != nil {
214+
return errors2.Wrapf(err, "could not resolve image %s", ref.Name())
215+
}
216+
image.Image = canonical.String()
217+
bundle.Images[service.Name] = image
218+
}
219+
return nil
220+
}
221+
184222
func getAppFolder(opt buildOptions, contextPath string) (string, error) {
185223
application := opt.folder
186224
if application == "" {

internal/commands/build/compose.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,22 @@ import (
1212

1313
// parseCompose do parse app compose file and extract buildx Options
1414
// We don't rely on bake's ReadTargets + TargetsToBuildOpt here as we have to skip environment variable interpolation
15-
func parseCompose(app *types.App, contextPath string, options buildOptions) (map[string]build.Options, error) {
15+
func parseCompose(app *types.App, contextPath string, options buildOptions) (map[string]build.Options, []ServiceConfig, error) {
1616
parsed, err := loader.ParseYAML(app.Composes()[0])
1717
if err != nil {
18-
return nil, err
18+
return nil, nil, err
1919
}
2020

2121
services, err := load(parsed, options.args)
2222
if err != nil {
23-
return nil, fmt.Errorf("Failed to parse compose file: %s", err)
23+
return nil, nil, fmt.Errorf("Failed to parse compose file: %s", err)
2424
}
2525

26+
pulledServices := []ServiceConfig{}
2627
opts := map[string]build.Options{}
2728
for _, service := range services {
2829
if service.Build == nil {
30+
pulledServices = append(pulledServices, service)
2931
continue
3032
}
3133
var tags []string
@@ -47,7 +49,7 @@ func parseCompose(app *types.App, contextPath string, options buildOptions) (map
4749
Tags: tags,
4850
}
4951
}
50-
return opts, nil
52+
return opts, pulledServices, nil
5153
}
5254

5355
func flatten(in compose.MappingWithEquals) map[string]string {

internal/commands/build/compose_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func Test_parseCompose(t *testing.T) {
5151
t.Run(tt.name, func(t *testing.T) {
5252
app, err := packager.Extract("testdata/" + tt.name)
5353
assert.NilError(t, err)
54-
got, err := parseCompose(app, "testdata", buildOptions{})
54+
got, _, err := parseCompose(app, "testdata", buildOptions{})
5555
assert.NilError(t, err)
5656
_, ok := got["dontwant"]
5757
assert.Assert(t, !ok, "parseCompose() should have excluded 'dontwant' service")

0 commit comments

Comments
 (0)