Skip to content

Commit 6c9376c

Browse files
Implement required artifact resolution in jib builder (#4997)
* Implement required artifact resolution in jib builder * Update pkg/skaffold/build/jib/jib.go Co-authored-by: Brian de Alwis <[email protected]> Co-authored-by: Brian de Alwis <[email protected]>
1 parent e252d0d commit 6c9376c

File tree

9 files changed

+154
-42
lines changed

9 files changed

+154
-42
lines changed

pkg/skaffold/build/gcb/jib.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ func (b *Builder) jibBuildSpec(artifact *latest.Artifact, tag string) (cloudbuil
4141
Steps: []*cloudbuild.BuildStep{{
4242
Name: b.MavenImage,
4343
Entrypoint: "sh",
44-
Args: fixHome("mvn", jib.GenerateMavenBuildArgs("build", tag, artifact.JibArtifact, b.skipTests, b.cfg.GetInsecureRegistries())),
44+
Args: fixHome("mvn", jib.GenerateMavenBuildArgs("build", tag, artifact.JibArtifact, b.skipTests, true, artifact.Dependencies, b.artifactStore, b.cfg.GetInsecureRegistries())),
4545
}},
4646
}, nil
4747
case jib.JibGradle:
4848
return cloudbuild.Build{
4949
Steps: []*cloudbuild.BuildStep{{
5050
Name: b.GradleImage,
5151
Entrypoint: "sh",
52-
Args: fixHome("gradle", jib.GenerateGradleBuildArgs("jib", tag, artifact.JibArtifact, b.skipTests, b.cfg.GetInsecureRegistries())),
52+
Args: fixHome("gradle", jib.GenerateGradleBuildArgs("jib", tag, artifact.JibArtifact, b.skipTests, true, artifact.Dependencies, b.artifactStore, b.cfg.GetInsecureRegistries())),
5353
}},
5454
}, nil
5555
default:

pkg/skaffold/build/jib/build.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ func (b *Builder) Build(ctx context.Context, out io.Writer, artifact *latest.Art
3434
switch t {
3535
case JibMaven:
3636
if b.pushImages {
37-
return b.buildJibMavenToRegistry(ctx, out, artifact.Workspace, artifact.JibArtifact, tag)
37+
return b.buildJibMavenToRegistry(ctx, out, artifact.Workspace, artifact.JibArtifact, artifact.Dependencies, tag)
3838
}
39-
return b.buildJibMavenToDocker(ctx, out, artifact.Workspace, artifact.JibArtifact, tag)
39+
return b.buildJibMavenToDocker(ctx, out, artifact.Workspace, artifact.JibArtifact, artifact.Dependencies, tag)
4040

4141
case JibGradle:
4242
if b.pushImages {
43-
return b.buildJibGradleToRegistry(ctx, out, artifact.Workspace, artifact.JibArtifact, tag)
43+
return b.buildJibGradleToRegistry(ctx, out, artifact.Workspace, artifact.JibArtifact, artifact.Dependencies, tag)
4444
}
45-
return b.buildJibGradleToDocker(ctx, out, artifact.Workspace, artifact.JibArtifact, tag)
45+
return b.buildJibGradleToDocker(ctx, out, artifact.Workspace, artifact.JibArtifact, artifact.Dependencies, tag)
4646

4747
default:
4848
return "", fmt.Errorf("unable to determine Jib builder type for %s", artifact.Workspace)

pkg/skaffold/build/jib/gradle.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ const MinimumJibGradleVersionForSync = "2.0.0"
4242
// GradleCommand stores Gradle executable and wrapper name
4343
var GradleCommand = util.CommandWrapper{Executable: "gradle", Wrapper: "gradlew"}
4444

45-
func (b *Builder) buildJibGradleToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, tag string) (string, error) {
46-
args := GenerateGradleBuildArgs("jibDockerBuild", tag, artifact, b.skipTests, b.cfg.GetInsecureRegistries())
45+
func (b *Builder) buildJibGradleToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, deps []*latest.ArtifactDependency, tag string) (string, error) {
46+
args := GenerateGradleBuildArgs("jibDockerBuild", tag, artifact, b.skipTests, b.pushImages, deps, b.artifacts, b.cfg.GetInsecureRegistries())
4747
if err := b.runGradleCommand(ctx, out, workspace, args); err != nil {
4848
return "", err
4949
}
5050

5151
return b.localDocker.ImageID(ctx, tag)
5252
}
5353

54-
func (b *Builder) buildJibGradleToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, tag string) (string, error) {
55-
args := GenerateGradleBuildArgs("jib", tag, artifact, b.skipTests, b.cfg.GetInsecureRegistries())
54+
func (b *Builder) buildJibGradleToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, deps []*latest.ArtifactDependency, tag string) (string, error) {
55+
args := GenerateGradleBuildArgs("jib", tag, artifact, b.skipTests, b.pushImages, deps, b.artifacts, b.cfg.GetInsecureRegistries())
5656
if err := b.runGradleCommand(ctx, out, workspace, args); err != nil {
5757
return "", err
5858
}
@@ -97,14 +97,14 @@ func getSyncMapCommandGradle(ctx context.Context, workspace string, a *latest.Ji
9797
}
9898

9999
// GenerateGradleBuildArgs generates the arguments to Gradle for building the project as an image.
100-
func GenerateGradleBuildArgs(task string, imageName string, a *latest.JibArtifact, skipTests bool, insecureRegistries map[string]bool) []string {
100+
func GenerateGradleBuildArgs(task string, imageName string, a *latest.JibArtifact, skipTests, pushImages bool, deps []*latest.ArtifactDependency, r ArtifactResolver, insecureRegistries map[string]bool) []string {
101101
args := gradleBuildArgsFunc(task, a, skipTests, true, MinimumJibGradleVersion)
102102
if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err == nil && insecure {
103103
// jib doesn't support marking specific registries as insecure
104104
args = append(args, "-Djib.allowInsecureRegistries=true")
105105
}
106-
if a.BaseImage != "" {
107-
args = append(args, fmt.Sprintf("-Djib.from.image=%s", a.BaseImage))
106+
if baseImg, found := baseImageArg(a, r, deps, pushImages); found {
107+
args = append(args, baseImg)
108108
}
109109
args = append(args, "--image="+imageName)
110110
return args

pkg/skaffold/build/jib/gradle_test.go

+55-10
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func TestBuildJibGradleToDocker(t *testing.T) {
8282
api := (&testutil.FakeAPIClient{}).Add("img:tag", "imageID")
8383
localDocker := fakeLocalDaemon(api)
8484

85-
builder := NewArtifactBuilder(localDocker, &mockConfig{}, false, false)
85+
builder := NewArtifactBuilder(localDocker, &mockConfig{}, false, false, nil)
8686
result, err := builder.Build(context.Background(), ioutil.Discard, &latest.Artifact{
8787
ArtifactType: latest.ArtifactType{
8888
JibArtifact: test.artifact,
@@ -153,7 +153,7 @@ func TestBuildJibGradleToRegistry(t *testing.T) {
153153
})
154154
localDocker := fakeLocalDaemon(&testutil.FakeAPIClient{})
155155

156-
builder := NewArtifactBuilder(localDocker, &mockConfig{}, true, false)
156+
builder := NewArtifactBuilder(localDocker, &mockConfig{}, true, false, nil)
157157
result, err := builder.Build(context.Background(), ioutil.Discard, &latest.Artifact{
158158
ArtifactType: latest.ArtifactType{
159159
JibArtifact: test.artifact,
@@ -341,23 +341,59 @@ func TestGenerateGradleBuildArgs(t *testing.T) {
341341
tests := []struct {
342342
description string
343343
in latest.JibArtifact
344+
deps []*latest.ArtifactDependency
344345
image string
345346
skipTests bool
347+
pushImages bool
348+
r ArtifactResolver
346349
insecureRegistries map[string]bool
347350
out []string
348351
}{
349-
{"single module", latest.JibArtifact{}, "image", false, nil, []string{"fake-gradleBuildArgs-for-testTask", "--image=image"}},
350-
{"single module without tests", latest.JibArtifact{}, "image", true, nil, []string{"fake-gradleBuildArgs-for-testTask-skipTests", "--image=image"}},
351-
{"multi module", latest.JibArtifact{Project: "project"}, "image", false, nil, []string{"fake-gradleBuildArgs-for-project-for-testTask", "--image=image"}},
352-
{"multi module without tests", latest.JibArtifact{Project: "project"}, "image", true, nil, []string{"fake-gradleBuildArgs-for-project-for-testTask-skipTests", "--image=image"}},
353-
{"multi module without tests with insecure registries", latest.JibArtifact{Project: "project"}, "registry.tld/image", true, map[string]bool{"registry.tld": true}, []string{"fake-gradleBuildArgs-for-project-for-testTask-skipTests", "-Djib.allowInsecureRegistries=true", "--image=registry.tld/image"}},
354-
{"single module with custom base image", latest.JibArtifact{BaseImage: "docker://busybox"}, "image", false, nil, []string{"fake-gradleBuildArgs-for-testTask", "-Djib.from.image=docker://busybox", "--image=image"}},
355-
{"multi module with custom base image", latest.JibArtifact{Project: "project", BaseImage: "docker://busybox"}, "image", false, nil, []string{"fake-gradleBuildArgs-for-project-for-testTask", "-Djib.from.image=docker://busybox", "--image=image"}},
352+
{description: "single module", image: "image", out: []string{"fake-gradleBuildArgs-for-testTask", "--image=image"}},
353+
{description: "single module without tests", image: "image", skipTests: true, out: []string{"fake-gradleBuildArgs-for-testTask-skipTests", "--image=image"}},
354+
{description: "multi module", in: latest.JibArtifact{Project: "project"}, image: "image", out: []string{"fake-gradleBuildArgs-for-project-for-testTask", "--image=image"}},
355+
{description: "multi module without tests", in: latest.JibArtifact{Project: "project"}, image: "image", skipTests: true, out: []string{"fake-gradleBuildArgs-for-project-for-testTask-skipTests", "--image=image"}},
356+
{description: "multi module without tests with insecure registries", in: latest.JibArtifact{Project: "project"}, image: "registry.tld/image", skipTests: true, insecureRegistries: map[string]bool{"registry.tld": true}, out: []string{"fake-gradleBuildArgs-for-project-for-testTask-skipTests", "-Djib.allowInsecureRegistries=true", "--image=registry.tld/image"}},
357+
{description: "single module with custom base image", in: latest.JibArtifact{BaseImage: "docker://busybox"}, image: "image", out: []string{"fake-gradleBuildArgs-for-testTask", "-Djib.from.image=docker://busybox", "--image=image"}},
358+
{description: "multi module with custom base image", in: latest.JibArtifact{Project: "project", BaseImage: "docker://busybox"}, image: "image", out: []string{"fake-gradleBuildArgs-for-project-for-testTask", "-Djib.from.image=docker://busybox", "--image=image"}},
359+
{
360+
description: "single module with local base image from required artifacts",
361+
in: latest.JibArtifact{BaseImage: "alias"},
362+
image: "image",
363+
deps: []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
364+
r: mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
365+
out: []string{"fake-gradleBuildArgs-for-testTask", "-Djib.from.image=docker://img:tag", "--image=image"},
366+
},
367+
{
368+
description: "multi module with local base image from required artifacts",
369+
in: latest.JibArtifact{Project: "project", BaseImage: "alias"},
370+
image: "image",
371+
deps: []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
372+
r: mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
373+
out: []string{"fake-gradleBuildArgs-for-project-for-testTask", "-Djib.from.image=docker://img:tag", "--image=image"},
374+
}, {
375+
description: "single module with remote base image from required artifacts",
376+
in: latest.JibArtifact{BaseImage: "alias"},
377+
image: "image",
378+
pushImages: true,
379+
deps: []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
380+
r: mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
381+
out: []string{"fake-gradleBuildArgs-for-testTask", "-Djib.from.image=img:tag", "--image=image"},
382+
},
383+
{
384+
description: "multi module with remote base image from required artifacts",
385+
in: latest.JibArtifact{Project: "project", BaseImage: "alias"},
386+
image: "image",
387+
pushImages: true,
388+
deps: []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
389+
r: mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
390+
out: []string{"fake-gradleBuildArgs-for-project-for-testTask", "-Djib.from.image=img:tag", "--image=image"},
391+
},
356392
}
357393
for _, test := range tests {
358394
testutil.Run(t, test.description, func(t *testutil.T) {
359395
t.Override(&gradleBuildArgsFunc, getGradleBuildArgsFuncFake(t, MinimumJibGradleVersion))
360-
command := GenerateGradleBuildArgs("testTask", test.image, &test.in, test.skipTests, test.insecureRegistries)
396+
command := GenerateGradleBuildArgs("testTask", test.image, &test.in, test.skipTests, test.pushImages, test.deps, test.r, test.insecureRegistries)
361397
t.CheckDeepEqual(test.out, command)
362398
})
363399
}
@@ -485,3 +521,12 @@ type mockConfig struct {
485521
}
486522

487523
func (c *mockConfig) GetInsecureRegistries() map[string]bool { return nil }
524+
525+
type mockArtifactResolver struct {
526+
m map[string]string
527+
}
528+
529+
func (r mockArtifactResolver) GetImageTag(imageName string) (string, bool) {
530+
val, found := r.m[imageName]
531+
return val, found
532+
}

pkg/skaffold/build/jib/jib.go

+23
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,26 @@ func isOnInsecureRegistry(image string, insecureRegistries map[string]bool) (boo
326326

327327
return docker.IsInsecure(ref, insecureRegistries), nil
328328
}
329+
330+
// baseImageArg formats the base image as a build argument. It also replaces the provided base image with an image from the required artifacts if specified.
331+
func baseImageArg(a *latest.JibArtifact, r ArtifactResolver, deps []*latest.ArtifactDependency, pushImages bool) (string, bool) {
332+
if a.BaseImage == "" {
333+
return "", false
334+
}
335+
for _, d := range deps {
336+
if a.BaseImage != d.Alias {
337+
continue
338+
}
339+
img, found := r.GetImageTag(d.ImageName)
340+
if !found {
341+
logrus.Fatalf("failed to resolve build result for required artifact %q", d.ImageName)
342+
}
343+
if pushImages {
344+
// pull image from the registry (prefix `registry://` is optional)
345+
return fmt.Sprintf("-Djib.from.image=%s", img), true
346+
}
347+
// must use `docker://` prefix to retrieve image from the local docker daemon
348+
return fmt.Sprintf("-Djib.from.image=docker://%s", img), true
349+
}
350+
return fmt.Sprintf("-Djib.from.image=%s", a.BaseImage), true
351+
}

pkg/skaffold/build/jib/maven.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ const MinimumJibMavenVersionForSync = "2.0.0"
4242
// MavenCommand stores Maven executable and wrapper name
4343
var MavenCommand = util.CommandWrapper{Executable: "mvn", Wrapper: "mvnw"}
4444

45-
func (b *Builder) buildJibMavenToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, tag string) (string, error) {
46-
args := GenerateMavenBuildArgs("dockerBuild", tag, artifact, b.skipTests, b.cfg.GetInsecureRegistries())
45+
func (b *Builder) buildJibMavenToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, deps []*latest.ArtifactDependency, tag string) (string, error) {
46+
args := GenerateMavenBuildArgs("dockerBuild", tag, artifact, b.skipTests, b.pushImages, deps, b.artifacts, b.cfg.GetInsecureRegistries())
4747
if err := b.runMavenCommand(ctx, out, workspace, args); err != nil {
4848
return "", err
4949
}
5050

5151
return b.localDocker.ImageID(ctx, tag)
5252
}
5353

54-
func (b *Builder) buildJibMavenToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, tag string) (string, error) {
55-
args := GenerateMavenBuildArgs("build", tag, artifact, b.skipTests, b.cfg.GetInsecureRegistries())
54+
func (b *Builder) buildJibMavenToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, deps []*latest.ArtifactDependency, tag string) (string, error) {
55+
args := GenerateMavenBuildArgs("build", tag, artifact, b.skipTests, b.pushImages, deps, b.artifacts, b.cfg.GetInsecureRegistries())
5656
if err := b.runMavenCommand(ctx, out, workspace, args); err != nil {
5757
return "", err
5858
}
@@ -98,14 +98,14 @@ func getSyncMapCommandMaven(ctx context.Context, workspace string, a *latest.Jib
9898
}
9999

100100
// GenerateMavenBuildArgs generates the arguments to Maven for building the project as an image.
101-
func GenerateMavenBuildArgs(goal string, imageName string, a *latest.JibArtifact, skipTests bool, insecureRegistries map[string]bool) []string {
101+
func GenerateMavenBuildArgs(goal string, imageName string, a *latest.JibArtifact, skipTests, pushImages bool, deps []*latest.ArtifactDependency, r ArtifactResolver, insecureRegistries map[string]bool) []string {
102102
args := mavenBuildArgsFunc(goal, a, skipTests, true, MinimumJibMavenVersion)
103103
if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err == nil && insecure {
104104
// jib doesn't support marking specific registries as insecure
105105
args = append(args, "-Djib.allowInsecureRegistries=true")
106106
}
107-
if a.BaseImage != "" {
108-
args = append(args, fmt.Sprintf("-Djib.from.image=%s", a.BaseImage))
107+
if baseImg, found := baseImageArg(a, r, deps, pushImages); found {
108+
args = append(args, baseImg)
109109
}
110110
args = append(args, "-Dimage="+imageName)
111111

0 commit comments

Comments
 (0)