Skip to content

Commit 6a7d2b9

Browse files
authored
add command skaffold inspect build-env add local (#5944)
1 parent 0b96ef3 commit 6a7d2b9

File tree

5 files changed

+496
-3
lines changed

5 files changed

+496
-3
lines changed

cmd/skaffold/app/cmd/cmd.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,14 @@ func isHouseKeepingMessagesAllowed(cmd *cobra.Command) bool {
284284
if cmd.Annotations == nil {
285285
return false
286286
}
287-
return cmd.Annotations[HouseKeepingMessagesAllowedAnnotation] == "true"
287+
return cmd.Annotations[HouseKeepingMessagesAllowedAnnotation] == fmt.Sprintf("%t", true)
288288
}
289289

290290
func allowHouseKeepingMessages(cmd *cobra.Command) {
291291
if cmd.Annotations == nil {
292292
cmd.Annotations = make(map[string]string)
293293
}
294-
cmd.Annotations[HouseKeepingMessagesAllowedAnnotation] = "true"
294+
cmd.Annotations[HouseKeepingMessagesAllowedAnnotation] = fmt.Sprintf("%t", true)
295295
}
296296

297297
func preReleaseVersion(s string) bool {

cmd/skaffold/app/cmd/inspect_build_env.go

+56-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/spf13/cobra"
2424
"github.com/spf13/pflag"
2525

26+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
2627
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/inspect"
2728
buildEnv "github.com/GoogleContainerTools/skaffold/pkg/skaffold/inspect/buildEnv"
2829
)
@@ -34,6 +35,12 @@ var buildEnvFlags = struct {
3435
timeout string
3536
concurrency int
3637

38+
// Local
39+
push config.BoolOrUndefined
40+
tryImportMissing config.BoolOrUndefined
41+
useDockerCLI config.BoolOrUndefined
42+
useBuildkit config.BoolOrUndefined
43+
3744
// Google Cloud Build
3845
projectID string
3946
diskSizeGb int64
@@ -74,7 +81,7 @@ func cmdBuildEnvAdd() *cobra.Command {
7481
return NewCmd("add").
7582
WithDescription("Add a new build environment to the default pipeline or to a new or existing profile.").
7683
WithPersistentFlagAdder(cmdBuildEnvAddFlags).
77-
WithCommands(cmdBuildEnvAddGcb(), cmdBuildEnvAddCluster())
84+
WithCommands(cmdBuildEnvAddLocal(), cmdBuildEnvAddGcb(), cmdBuildEnvAddCluster())
7885
}
7986

8087
func cmdBuildEnvAddGcb() *cobra.Command {
@@ -89,6 +96,18 @@ Use the '--module' filter to specify the individual module to target. Otherwise,
8996
NoArgs(addGcbBuildEnv)
9097
}
9198

99+
func cmdBuildEnvAddLocal() *cobra.Command {
100+
return NewCmd("local").
101+
WithDescription("Add a new Local build environment definition").
102+
WithLongDescription(`Add a new Local build environment definition.
103+
Without the '--profile' flag the new environment definition is added to the default pipeline. With the '--profile' flag it will create a new profile with this build env definition.
104+
In these respective scenarios, it will fail if the build env definition for the default pipeline or the named profile already exists. To override an existing definition use 'skaffold inspect build-env modify' command instead.
105+
Use the '--module' filter to specify the individual module to target. Otherwise, it'll be applied to all modules defined in the target file. Also, with the '--profile' flag if the target config imports other configs as dependencies, then the new profile will be recursively created in all the imported configs also.`).
106+
WithExample("Add a new profile named 'local' targeting the local build environment with option to push images and using buildkit", "inspect build-env add local --profile local --push true --useBuildkit true -f skaffold.yaml").
107+
WithFlagAdder(cmdBuildEnvLocalFlags).
108+
NoArgs(addLocalBuildEnv)
109+
}
110+
92111
func cmdBuildEnvAddCluster() *cobra.Command {
93112
return NewCmd("cluster").
94113
WithDescription("Add a new Cluster build environment definition").
@@ -105,6 +124,10 @@ func listBuildEnv(ctx context.Context, out io.Writer) error {
105124
return buildEnv.PrintBuildEnvsList(ctx, out, printBuildEnvsListOptions())
106125
}
107126

127+
func addLocalBuildEnv(ctx context.Context, out io.Writer) error {
128+
return buildEnv.AddLocalBuildEnv(ctx, out, localBuildEnvOptions())
129+
}
130+
108131
func addGcbBuildEnv(ctx context.Context, out io.Writer) error {
109132
return buildEnv.AddGcbBuildEnv(ctx, out, addGcbBuildEnvOptions())
110133
}
@@ -117,6 +140,20 @@ func cmdBuildEnvAddFlags(f *pflag.FlagSet) {
117140
f.StringVarP(&buildEnvFlags.profile, "profile", "p", "", `Profile name to add the new build env definition in. If the profile name doesn't exist then the profile will be created in all the target configs. If this flag is not specified then the build env is added to the default pipeline of the target configs.`)
118141
}
119142

143+
func cmdBuildEnvLocalFlags(f *pflag.FlagSet) {
144+
var flags []*pflag.Flag
145+
flags = append(flags, f.VarPF(&buildEnvFlags.push, "push", "", `Set to true to push images to a registry`))
146+
flags = append(flags, f.VarPF(&buildEnvFlags.tryImportMissing, "tryImportMissing", "", `Set to true to to attempt importing artifacts from Docker (either a local or remote registry) if not in the build cache`))
147+
flags = append(flags, f.VarPF(&buildEnvFlags.useDockerCLI, "useDockerCLI", "", `Set to true to use 'docker' command-line interface instead of Docker Engine APIs`))
148+
flags = append(flags, f.VarPF(&buildEnvFlags.useBuildkit, "useBuildkit", "", `Set to true to use BuildKit to build Docker images`))
149+
f.IntVar(&buildEnvFlags.concurrency, "concurrency", -1, `number of artifacts to build concurrently. 0 means "no-limit"`)
150+
151+
// support *bool flags without a value to be interpreted as `true`; like `--push` instead of `--push=true`
152+
for _, f := range flags {
153+
f.NoOptDefVal = "true"
154+
}
155+
}
156+
120157
func cmdBuildEnvAddGcbFlags(f *pflag.FlagSet) {
121158
f.StringVar(&buildEnvFlags.projectID, "projectId", "", `ID of the Cloud Platform Project.`)
122159
f.Int64Var(&buildEnvFlags.diskSizeGb, "diskSizeGb", 0, `Disk size of the VM that runs the build`)
@@ -162,6 +199,23 @@ func printBuildEnvsListOptions() inspect.Options {
162199
},
163200
}
164201
}
202+
203+
func localBuildEnvOptions() inspect.Options {
204+
return inspect.Options{
205+
Filename: inspectFlags.fileName,
206+
OutFormat: inspectFlags.outFormat,
207+
Modules: inspectFlags.modules,
208+
BuildEnvOptions: inspect.BuildEnvOptions{
209+
Profile: buildEnvFlags.profile,
210+
Push: buildEnvFlags.push.Value(),
211+
TryImportMissing: buildEnvFlags.tryImportMissing.Value(),
212+
UseDockerCLI: buildEnvFlags.useDockerCLI.Value(),
213+
UseBuildkit: buildEnvFlags.useBuildkit.Value(),
214+
Concurrency: buildEnvFlags.concurrency,
215+
},
216+
}
217+
}
218+
165219
func addGcbBuildEnvOptions() inspect.Options {
166220
return inspect.Options{
167221
Filename: inspectFlags.fileName,
@@ -177,6 +231,7 @@ func addGcbBuildEnvOptions() inspect.Options {
177231
},
178232
}
179233
}
234+
180235
func addClusterBuildEnvOptions() inspect.Options {
181236
return inspect.Options{
182237
Filename: inspectFlags.fileName,
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
Copyright 2021 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 inspect
18+
19+
import (
20+
"context"
21+
"io"
22+
23+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
24+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/inspect"
25+
latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
26+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
27+
)
28+
29+
func AddLocalBuildEnv(ctx context.Context, out io.Writer, opts inspect.Options) error {
30+
formatter := inspect.OutputFormatter(out, opts.OutFormat)
31+
cfgs, err := inspect.ConfigSetFunc(config.SkaffoldOptions{ConfigurationFile: opts.Filename, ConfigurationFilter: opts.Modules, SkipConfigDefaults: true, MakePathsAbsolute: util.BoolPtr(false)})
32+
if err != nil {
33+
return formatter.WriteErr(err)
34+
}
35+
if opts.Profile == "" {
36+
// empty profile flag implies that the new build env needs to be added to the default pipeline.
37+
// for these cases, don't add the new env definition to any configs imported as dependencies.
38+
cfgs = cfgs.SelectRootConfigs()
39+
for _, cfg := range cfgs {
40+
if cfg.Build.LocalBuild != nil && (*cfg.Build.LocalBuild != latestV1.LocalBuild{}) {
41+
return formatter.WriteErr(inspect.BuildEnvAlreadyExists(inspect.BuildEnvs.Local, cfg.SourceFile, ""))
42+
}
43+
cfg.Build.LocalBuild = constructLocalDefinition(cfg.Build.LocalBuild, opts.BuildEnvOptions)
44+
cfg.Build.GoogleCloudBuild = nil
45+
cfg.Build.Cluster = nil
46+
}
47+
} else {
48+
for _, cfg := range cfgs {
49+
index := -1
50+
for i := range cfg.Profiles {
51+
if cfg.Profiles[i].Name == opts.Profile {
52+
index = i
53+
break
54+
}
55+
}
56+
if index < 0 {
57+
index = len(cfg.Profiles)
58+
cfg.Profiles = append(cfg.Profiles, latestV1.Profile{Name: opts.Profile})
59+
}
60+
if cfg.Profiles[index].Build.LocalBuild != nil && (*cfg.Profiles[index].Build.LocalBuild != latestV1.LocalBuild{}) {
61+
return formatter.WriteErr(inspect.BuildEnvAlreadyExists(inspect.BuildEnvs.Local, cfg.SourceFile, opts.Profile))
62+
}
63+
cfg.Profiles[index].Build.LocalBuild = constructLocalDefinition(cfg.Profiles[index].Build.LocalBuild, opts.BuildEnvOptions)
64+
cfg.Profiles[index].Build.GoogleCloudBuild = nil
65+
cfg.Profiles[index].Build.Cluster = nil
66+
}
67+
}
68+
return inspect.MarshalConfigSet(cfgs)
69+
}
70+
71+
func constructLocalDefinition(existing *latestV1.LocalBuild, opts inspect.BuildEnvOptions) *latestV1.LocalBuild {
72+
var b latestV1.LocalBuild
73+
if existing != nil {
74+
b = *existing
75+
}
76+
if opts.Concurrency >= 0 {
77+
b.Concurrency = util.IntPtr(opts.Concurrency)
78+
}
79+
if opts.Push != nil {
80+
b.Push = opts.Push
81+
}
82+
if opts.TryImportMissing != nil {
83+
b.TryImportMissing = *opts.TryImportMissing
84+
}
85+
if opts.UseDockerCLI != nil {
86+
b.UseDockerCLI = *opts.UseDockerCLI
87+
}
88+
if opts.UseBuildkit != nil {
89+
b.UseBuildkit = *opts.UseBuildkit
90+
}
91+
return &b
92+
}

0 commit comments

Comments
 (0)