github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/jib/gradle.go (about) 1 /* 2 Copyright 2019 The Skaffold Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package jib 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 "os/exec" 24 25 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" 26 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output" 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log" 28 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform" 29 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" 30 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" 31 ) 32 33 // For testing 34 var ( 35 gradleArgsFunc = gradleArgs 36 gradleBuildArgsFunc = gradleBuildArgs 37 ) 38 39 // Skaffold-Jib depends on functionality introduced with Jib-Gradle 1.4.0 40 const MinimumJibGradleVersion = "1.4.0" 41 const MinimumJibGradleVersionForSync = "2.0.0" 42 const MinimumJibGradleVersionForCrossPlatform = "3.2.0" 43 44 // GradleCommand stores Gradle executable and wrapper name 45 var GradleCommand = util.CommandWrapper{Executable: "gradle", Wrapper: "gradlew"} 46 47 func (b *Builder) buildJibGradleToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, deps []*latest.ArtifactDependency, tag string, platforms platform.Matcher) (string, error) { 48 args := GenerateGradleBuildArgs("jibDockerBuild", tag, artifact, platforms, b.skipTests, b.pushImages, deps, b.artifacts, b.cfg.GetInsecureRegistries(), output.IsColorable(out)) 49 if err := b.runGradleCommand(ctx, out, workspace, args); err != nil { 50 return "", jibToolErr(err) 51 } 52 53 return b.localDocker.ImageID(ctx, tag) 54 } 55 56 func (b *Builder) buildJibGradleToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibArtifact, deps []*latest.ArtifactDependency, tag string, platforms platform.Matcher) (string, error) { 57 args := GenerateGradleBuildArgs("jib", tag, artifact, platforms, b.skipTests, b.pushImages, deps, b.artifacts, b.cfg.GetInsecureRegistries(), output.IsColorable(out)) 58 if err := b.runGradleCommand(ctx, out, workspace, args); err != nil { 59 return "", jibToolErr(err) 60 } 61 62 return docker.RemoteDigest(tag, b.cfg, nil) 63 } 64 65 func (b *Builder) runGradleCommand(ctx context.Context, out io.Writer, workspace string, args []string) error { 66 cmd := GradleCommand.CreateCommand(ctx, workspace, args) 67 cmd.Env = append(util.OSEnviron(), b.localDocker.ExtraEnv()...) 68 cmd.Stdout = out 69 cmd.Stderr = out 70 71 log.Entry(ctx).Infof("Building %s: %s, %v", workspace, cmd.Path, cmd.Args) 72 if err := util.RunCmd(ctx, &cmd); err != nil { 73 return fmt.Errorf("gradle build failed: %w", err) 74 } 75 76 return nil 77 } 78 79 // getDependenciesGradle finds the source dependencies for the given jib-gradle artifact. 80 // All paths are absolute. 81 func getDependenciesGradle(ctx context.Context, workspace string, a *latest.JibArtifact) ([]string, error) { 82 cmd := getCommandGradle(ctx, workspace, a) 83 deps, err := getDependencies(ctx, workspace, cmd, a) 84 if err != nil { 85 return nil, dependencyErr(JibGradle, workspace, err) 86 } 87 log.Entry(ctx).Debugf("Found dependencies for jib-gradle artifact: %v", deps) 88 return deps, nil 89 } 90 91 func getCommandGradle(ctx context.Context, workspace string, a *latest.JibArtifact) exec.Cmd { 92 args := append(gradleArgsFunc(a, "_jibSkaffoldFilesV2", MinimumJibGradleVersion), "-q", "--console=plain") 93 return GradleCommand.CreateCommand(ctx, workspace, args) 94 } 95 96 func getSyncMapCommandGradle(ctx context.Context, workspace string, a *latest.JibArtifact) *exec.Cmd { 97 cmd := GradleCommand.CreateCommand(ctx, workspace, gradleBuildArgsFunc("_jibSkaffoldSyncMap", a, true, false, MinimumJibMavenVersionForSync)) 98 return &cmd 99 } 100 101 // GenerateGradleBuildArgs generates the arguments to Gradle for building the project as an image. 102 func GenerateGradleBuildArgs(task, imageName string, a *latest.JibArtifact, platforms platform.Matcher, skipTests, pushImages bool, deps []*latest.ArtifactDependency, r ArtifactResolver, insecureRegistries map[string]bool, showColors bool) []string { 103 minVersion := MinimumJibGradleVersion 104 if platforms.IsCrossPlatform() { 105 minVersion = MinimumJibGradleVersionForCrossPlatform 106 } 107 args := gradleBuildArgsFunc(task, a, skipTests, showColors, minVersion) 108 if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err == nil && insecure { 109 // jib doesn't support marking specific registries as insecure 110 args = append(args, "-Djib.allowInsecureRegistries=true") 111 } 112 if baseImg, found := baseImageArg(a, r, deps, pushImages); found { 113 args = append(args, baseImg) 114 } 115 if platforms.IsNotEmpty() { 116 args = append(args, fmt.Sprintf("-Djib.from.platforms=%s", platforms.String())) 117 } 118 args = append(args, "--image="+imageName) 119 return args 120 } 121 122 // Do not use directly, use gradleBuildArgsFunc 123 func gradleBuildArgs(task string, a *latest.JibArtifact, skipTests, showColors bool, minimumVersion string) []string { 124 // Disable jib's rich progress footer on builds. Show colors on normal builds for clearer information, 125 // but use --console=plain for internal goals to avoid formatting issues 126 var args []string 127 if showColors { 128 args = []string{"-Djib.console=plain"} 129 } else { 130 args = []string{"--console=plain"} 131 } 132 args = append(args, gradleArgsFunc(a, task, minimumVersion)...) 133 134 if skipTests { 135 args = append(args, "-x", "test") 136 } 137 args = append(args, a.Flags...) 138 return args 139 } 140 141 // Do not use directly, use gradleArgsFunc 142 func gradleArgs(a *latest.JibArtifact, task string, minimumVersion string) []string { 143 args := []string{"_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + minimumVersion} 144 if a.Project == "" { 145 return append(args, ":"+task) 146 } 147 148 // multi-module 149 return append(args, fmt.Sprintf(":%s:%s", a.Project, task)) 150 }