github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/tag/tagger_mux.go (about)

     1  /*
     2  Copyright 2020 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 tag
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
    24  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext"
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    26  )
    27  
    28  type TaggerMux struct {
    29  	taggers     []Tagger
    30  	byImageName map[string]Tagger
    31  }
    32  
    33  func (t *TaggerMux) GenerateTag(ctx context.Context, image latest.Artifact) (string, error) {
    34  	tagger, found := t.byImageName[image.ImageName]
    35  	if !found {
    36  		return "", fmt.Errorf("no valid tagger found for artifact: %q", image.ImageName)
    37  	}
    38  	return tagger.GenerateTag(ctx, image)
    39  }
    40  
    41  func NewTaggerMux(runCtx *runcontext.RunContext) (Tagger, error) {
    42  	pipelines := runCtx.GetPipelines()
    43  	m := make(map[string]Tagger)
    44  	sl := make([]Tagger, len(pipelines))
    45  	for _, p := range pipelines {
    46  		t, err := getTagger(runCtx, &p.Build.TagPolicy)
    47  		if err != nil {
    48  			return nil, fmt.Errorf("creating tagger: %w", err)
    49  		}
    50  		sl = append(sl, t)
    51  		for _, a := range p.Build.Artifacts {
    52  			m[a.ImageName] = t
    53  		}
    54  	}
    55  	return &TaggerMux{taggers: sl, byImageName: m}, nil
    56  }
    57  
    58  func getTagger(runCtx *runcontext.RunContext, t *latest.TagPolicy) (Tagger, error) {
    59  	switch {
    60  	case runCtx.CustomTag() != "":
    61  		return &CustomTag{
    62  			Tag: runCtx.CustomTag(),
    63  		}, nil
    64  
    65  	case t.EnvTemplateTagger != nil:
    66  		return NewEnvTemplateTagger(t.EnvTemplateTagger.Template)
    67  
    68  	case t.ShaTagger != nil:
    69  		return &ChecksumTagger{}, nil
    70  
    71  	case t.GitTagger != nil:
    72  		return NewGitCommit(t.GitTagger.Prefix, t.GitTagger.Variant, t.GitTagger.IgnoreChanges)
    73  
    74  	case t.DateTimeTagger != nil:
    75  		return NewDateTimeTagger(t.DateTimeTagger.Format, t.DateTimeTagger.TimeZone), nil
    76  
    77  	case t.InputDigest != nil:
    78  		graph := graph.ToArtifactGraph(runCtx.Artifacts())
    79  		return NewInputDigestTagger(runCtx, graph)
    80  
    81  	case t.CustomTemplateTagger != nil:
    82  		components, err := CreateComponents(runCtx, t.CustomTemplateTagger)
    83  
    84  		if err != nil {
    85  			return nil, fmt.Errorf("creating components: %w", err)
    86  		}
    87  
    88  		return NewCustomTemplateTagger(t.CustomTemplateTagger.Template, components)
    89  
    90  	default:
    91  		return nil, fmt.Errorf("unknown tagger for strategy %+v", t)
    92  	}
    93  }
    94  
    95  // CreateComponents creates a map of taggers for CustomTemplateTagger
    96  func CreateComponents(runCtx *runcontext.RunContext, t *latest.CustomTemplateTagger) (map[string]Tagger, error) {
    97  	components := map[string]Tagger{}
    98  
    99  	for _, taggerComponent := range t.Components {
   100  		name, c := taggerComponent.Name, taggerComponent.Component
   101  
   102  		if _, ok := components[name]; ok {
   103  			return nil, fmt.Errorf("multiple components with name %s", name)
   104  		}
   105  
   106  		switch {
   107  		case c.EnvTemplateTagger != nil:
   108  			components[name], _ = NewEnvTemplateTagger(c.EnvTemplateTagger.Template)
   109  
   110  		case c.ShaTagger != nil:
   111  			components[name] = &ChecksumTagger{}
   112  
   113  		case c.GitTagger != nil:
   114  			components[name], _ = NewGitCommit(c.GitTagger.Prefix, c.GitTagger.Variant, c.GitTagger.IgnoreChanges)
   115  
   116  		case c.DateTimeTagger != nil:
   117  			components[name] = NewDateTimeTagger(c.DateTimeTagger.Format, c.DateTimeTagger.TimeZone)
   118  
   119  		case c.InputDigest != nil:
   120  			graph := graph.ToArtifactGraph(runCtx.Artifacts())
   121  			inputDigest, _ := NewInputDigestTagger(runCtx, graph)
   122  			components[name] = inputDigest
   123  
   124  		case c.CustomTemplateTagger != nil:
   125  			return nil, fmt.Errorf("nested customTemplate components are not supported in skaffold (%s)", name)
   126  
   127  		default:
   128  			return nil, fmt.Errorf("unknown component for custom template: %s %+v", name, c)
   129  		}
   130  	}
   131  
   132  	return components, nil
   133  }