github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/custom/script.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 custom 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 "os/exec" 24 "path/filepath" 25 "runtime" 26 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/misc" 28 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" 29 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" 30 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log" 31 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform" 32 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" 33 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" 34 ) 35 36 var ( 37 // For testing 38 buildContext = retrieveBuildContext 39 ) 40 41 func (b *Builder) runBuildScript(ctx context.Context, out io.Writer, a *latest.Artifact, tag string, platforms platform.Matcher) error { 42 cmd, err := b.retrieveCmd(ctx, out, a, tag, platforms) 43 if err != nil { 44 return fmt.Errorf("retrieving cmd: %w", err) 45 } 46 47 log.Entry(ctx).Debugf("Running command: %s", cmd.Args) 48 if err := cmd.Start(); err != nil { 49 return fmt.Errorf("starting cmd: %w", err) 50 } 51 52 return misc.HandleGracefulTermination(ctx, cmd) 53 } 54 55 func (b *Builder) retrieveCmd(ctx context.Context, out io.Writer, a *latest.Artifact, tag string, platforms platform.Matcher) (*exec.Cmd, error) { 56 artifact := a.CustomArtifact 57 58 // Expand command 59 command, err := util.ExpandEnvTemplate(artifact.BuildCommand, nil) 60 if err != nil { 61 return nil, fmt.Errorf("unable to parse build command %q: %w", artifact.BuildCommand, err) 62 } 63 64 var cmd *exec.Cmd 65 // We evaluate the command with a shell so that it can contain 66 // env variables. 67 if runtime.GOOS == "windows" { 68 cmd = exec.CommandContext(ctx, "cmd.exe", "/C", command) 69 } else { 70 cmd = exec.CommandContext(ctx, "sh", "-c", command) 71 } 72 cmd.Stdout = out 73 cmd.Stderr = out 74 75 env, err := b.retrieveEnv(a, tag, platforms) 76 if err != nil { 77 return nil, fmt.Errorf("retrieving env variables for %q: %w", a.ImageName, err) 78 } 79 cmd.Env = env 80 81 dir, err := buildContext(a.Workspace) 82 if err != nil { 83 return nil, fmt.Errorf("getting context for artifact: %w", err) 84 } 85 cmd.Dir = dir 86 87 return cmd, nil 88 } 89 90 func (b *Builder) retrieveEnv(a *latest.Artifact, tag string, platforms platform.Matcher) ([]string, error) { 91 buildContext, err := buildContext(a.Workspace) 92 if err != nil { 93 return nil, fmt.Errorf("getting absolute path for artifact build context: %w", err) 94 } 95 96 envs := []string{ 97 fmt.Sprintf("%s=%s", constants.Image, tag), 98 fmt.Sprintf("%s=%t", constants.PushImage, b.pushImages), 99 fmt.Sprintf("%s=%s", constants.BuildContext, buildContext), 100 fmt.Sprintf("%s=%s", constants.Platforms, platforms.String()), 101 fmt.Sprintf("%s=%t", constants.SkipTest, b.skipTest), 102 } 103 104 ref, err := docker.ParseReference(tag) 105 if err != nil { 106 return nil, fmt.Errorf("parsing image %v: %w", tag, err) 107 } 108 109 // Standardize access to Image reference fields in templates 110 envs = append(envs, fmt.Sprintf("%s=%s", constants.ImageRef.Repo, ref.BaseName)) 111 envs = append(envs, fmt.Sprintf("%s=%s", constants.ImageRef.Tag, ref.Tag)) 112 113 envs = append(envs, b.additionalEnv...) 114 envs = append(envs, util.OSEnviron()...) 115 return envs, nil 116 } 117 118 func retrieveBuildContext(workspace string) (string, error) { 119 return filepath.Abs(workspace) 120 }