github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/cache/details.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 cache
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"path/filepath"
    23  	"strings"
    24  
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
    27  )
    28  
    29  type cacheDetails interface {
    30  	Hash() string
    31  }
    32  
    33  // Failed: couldn't lookup cache
    34  type failed struct {
    35  	err error
    36  }
    37  
    38  func (d failed) Hash() string {
    39  	return ""
    40  }
    41  
    42  // Not found, needs building
    43  type needsBuilding struct {
    44  	hash string
    45  }
    46  
    47  func (d needsBuilding) Hash() string {
    48  	return d.hash
    49  }
    50  
    51  // Found in cache
    52  type found struct {
    53  	hash string
    54  }
    55  
    56  func (d found) Hash() string {
    57  	return d.hash
    58  }
    59  
    60  type needsTagging interface {
    61  	Tag(context.Context, *cache, platform.Resolver) error
    62  }
    63  
    64  // Found locally with wrong tag. Needs retagging
    65  type needsLocalTagging struct {
    66  	hash    string
    67  	tag     string
    68  	imageID string
    69  }
    70  
    71  func (d needsLocalTagging) Hash() string {
    72  	return d.hash
    73  }
    74  
    75  func (d needsLocalTagging) Tag(ctx context.Context, c *cache, platforms platform.Resolver) error {
    76  	return c.client.Tag(ctx, d.imageID, d.tag)
    77  }
    78  
    79  // Found remotely with wrong tag. Needs retagging
    80  type needsRemoteTagging struct {
    81  	hash   string
    82  	tag    string
    83  	digest string
    84  }
    85  
    86  func (d needsRemoteTagging) Hash() string {
    87  	return d.hash
    88  }
    89  
    90  func (d needsRemoteTagging) Tag(ctx context.Context, c *cache, platforms platform.Resolver) error {
    91  	fqn := d.tag + "@" + d.digest // Tag is not important. We just need the registry and the digest to locate the image.
    92  	matched := platforms.GetPlatforms(strings.Split(filepath.Base(d.tag), ":")[0])
    93  	return docker.AddRemoteTag(fqn, d.tag, c.cfg, matched.Platforms)
    94  }
    95  
    96  // Found locally. Needs pushing
    97  type needsPushing struct {
    98  	hash    string
    99  	tag     string
   100  	imageID string
   101  }
   102  
   103  func (d needsPushing) Hash() string {
   104  	return d.hash
   105  }
   106  
   107  func (d needsPushing) Push(ctx context.Context, out io.Writer, c *cache) error {
   108  	if err := c.client.Tag(ctx, d.imageID, d.tag); err != nil {
   109  		return err
   110  	}
   111  
   112  	digest, err := c.client.Push(ctx, out, d.tag)
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	// Update cache
   118  	c.cacheMutex.Lock()
   119  	e := c.artifactCache[d.hash]
   120  	e.Digest = digest
   121  	c.artifactCache[d.hash] = e
   122  	c.cacheMutex.Unlock()
   123  	return nil
   124  }