github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/inspect/buildEnv/add_gcb.go (about)

     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  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/parser"
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
    28  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringslice"
    29  )
    30  
    31  func AddGcbBuildEnv(ctx context.Context, out io.Writer, opts inspect.Options) error {
    32  	formatter := inspect.OutputFormatter(out, opts.OutFormat)
    33  	cfgs, err := inspect.GetConfigSet(ctx, config.SkaffoldOptions{
    34  		ConfigurationFile:   opts.Filename,
    35  		RepoCacheDir:        opts.RepoCacheDir,
    36  		ConfigurationFilter: opts.Modules,
    37  		SkipConfigDefaults:  true,
    38  		MakePathsAbsolute:   util.BoolPtr(false)})
    39  	if err != nil {
    40  		formatter.WriteErr(err)
    41  		return err
    42  	}
    43  	if opts.Profile == "" {
    44  		// empty profile flag implies that the new build env needs to be added to the default pipeline.
    45  		// for these cases, don't add the new env definition to any configs imported as dependencies.
    46  		cfgs = cfgs.SelectRootConfigs()
    47  		for _, cfg := range cfgs {
    48  			if cfg.Build.GoogleCloudBuild != nil && (*cfg.Build.GoogleCloudBuild != latest.GoogleCloudBuild{}) {
    49  				formatter.WriteErr(inspect.BuildEnvAlreadyExists(inspect.BuildEnvs.GoogleCloudBuild, cfg.SourceFile, ""))
    50  				return err
    51  			}
    52  			cfg.Build.GoogleCloudBuild = constructGcbDefinition(cfg.Build.GoogleCloudBuild, opts.BuildEnvOptions)
    53  			cfg.Build.LocalBuild = nil
    54  			cfg.Build.Cluster = nil
    55  		}
    56  	} else {
    57  		for _, cfg := range cfgs {
    58  			index := -1
    59  			for i := range cfg.Profiles {
    60  				if cfg.Profiles[i].Name == opts.Profile {
    61  					index = i
    62  					break
    63  				}
    64  			}
    65  			if index < 0 {
    66  				index = len(cfg.Profiles)
    67  				cfg.Profiles = append(cfg.Profiles, latest.Profile{Name: opts.Profile})
    68  			}
    69  			if cfg.Profiles[index].Build.GoogleCloudBuild != nil && (*cfg.Profiles[index].Build.GoogleCloudBuild != latest.GoogleCloudBuild{}) {
    70  				formatter.WriteErr(inspect.BuildEnvAlreadyExists(inspect.BuildEnvs.GoogleCloudBuild, cfg.SourceFile, opts.Profile))
    71  				return err
    72  			}
    73  			cfg.Profiles[index].Build.GoogleCloudBuild = constructGcbDefinition(cfg.Profiles[index].Build.GoogleCloudBuild, opts.BuildEnvOptions)
    74  			cfg.Profiles[index].Build.LocalBuild = nil
    75  			cfg.Profiles[index].Build.Cluster = nil
    76  
    77  			addProfileActivationStanza(cfg, opts.Profile)
    78  		}
    79  	}
    80  	return inspect.MarshalConfigSet(cfgs)
    81  }
    82  
    83  func constructGcbDefinition(existing *latest.GoogleCloudBuild, opts inspect.BuildEnvOptions) *latest.GoogleCloudBuild {
    84  	var b latest.GoogleCloudBuild
    85  	if existing != nil {
    86  		b = *existing
    87  	}
    88  	if opts.Concurrency >= 0 {
    89  		b.Concurrency = opts.Concurrency
    90  	}
    91  	if opts.DiskSizeGb > 0 {
    92  		b.DiskSizeGb = opts.DiskSizeGb
    93  	}
    94  	if opts.MachineType != "" {
    95  		b.MachineType = opts.MachineType
    96  	}
    97  	if opts.ProjectID != "" {
    98  		b.ProjectID = opts.ProjectID
    99  	}
   100  	if opts.Timeout != "" {
   101  		b.Timeout = opts.Timeout
   102  	}
   103  	if opts.Logging != "" {
   104  		b.Logging = opts.Logging
   105  	}
   106  	if opts.LogStreamingOption != "" {
   107  		b.LogStreamingOption = opts.LogStreamingOption
   108  	}
   109  	if opts.WorkerPool != "" {
   110  		b.WorkerPool = opts.WorkerPool
   111  	}
   112  	return &b
   113  }
   114  
   115  func addProfileActivationStanza(cfg *parser.SkaffoldConfigEntry, profileName string) {
   116  	for i := range cfg.Dependencies {
   117  		if cfg.Dependencies[i].GitRepo != nil {
   118  			// setup profile activation stanza only for local config dependencies
   119  			continue
   120  		}
   121  		for j := range cfg.Dependencies[i].ActiveProfiles {
   122  			if cfg.Dependencies[i].ActiveProfiles[j].Name == profileName {
   123  				if !stringslice.Contains(cfg.Dependencies[i].ActiveProfiles[j].ActivatedBy, profileName) {
   124  					cfg.Dependencies[i].ActiveProfiles[j].ActivatedBy = append(cfg.Dependencies[i].ActiveProfiles[j].ActivatedBy, profileName)
   125  				}
   126  				return
   127  			}
   128  		}
   129  		cfg.Dependencies[i].ActiveProfiles = append(cfg.Dependencies[i].ActiveProfiles, latest.ProfileDependency{Name: profileName, ActivatedBy: []string{profileName}})
   130  	}
   131  }