Skip to content

Commit 21308f8

Browse files
authored
Merge pull request #1755 from priyawadhwa/improve-caching
Improve caching
2 parents 464728c + d044daf commit 21308f8

File tree

6 files changed

+75
-29
lines changed

6 files changed

+75
-29
lines changed

pkg/skaffold/build/cache.go

+25-9
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ func NewCache(ctx context.Context, builder Builder, opts *skafconfig.SkaffoldOpt
9797
}
9898
client, err := newDockerCilent()
9999
if err != nil {
100-
logrus.Warnf("Error retrieving local daemon client, not using skaffold cache: %v", err)
101-
return noCache
100+
logrus.Warnf("Error retrieving local daemon client; local daemon will not be used as a cache: %v", err)
102101
}
103102
imageList, err := client.ImageList(ctx, types.ImageListOptions{})
104103
if err != nil {
@@ -230,7 +229,7 @@ func (c *Cache) retrieveCachedArtifactDetails(ctx context.Context, a *latest.Art
230229
needsRebuild: true,
231230
}, nil
232231
}
233-
hashTag := fmt.Sprintf("%s:%s", a.ImageName, hash)
232+
hashTag := HashTag(a)
234233

235234
// Check if we are using a local cluster
236235
var existsRemotely bool
@@ -239,8 +238,14 @@ func (c *Cache) retrieveCachedArtifactDetails(ctx context.Context, a *latest.Art
239238
existsRemotely = imageExistsRemotely(hashTag, imageDetails.Digest)
240239
}
241240

241+
if existsRemotely {
242+
return &cachedArtifactDetails{
243+
hashTag: hashTag,
244+
}, nil
245+
}
246+
242247
// See if this image exists in the local daemon
243-
if c.client.ImageExists(ctx, hashTag) {
248+
if c.client != nil && c.client.ImageExists(ctx, hashTag) {
244249
return &cachedArtifactDetails{
245250
needsPush: (!existsRemotely && !localCluster) || (localCluster && c.needsPush),
246251
hashTag: hashTag,
@@ -325,9 +330,12 @@ func (c *Cache) CacheArtifacts(ctx context.Context, artifacts []*latest.Artifact
325330
if digest == "" {
326331
logrus.Debugf("couldn't get image digest for %s, will try to cache just image id (expected with a local cluster)", tags[a.ImageName])
327332
}
328-
id, err := c.client.ImageID(ctx, tags[a.ImageName])
329-
if err != nil {
330-
logrus.Debugf("couldn't get image id for %s", tags[a.ImageName])
333+
var id string
334+
if c.client != nil {
335+
id, err = c.client.ImageID(ctx, tags[a.ImageName])
336+
if err != nil {
337+
logrus.Debugf("couldn't get image id for %s", tags[a.ImageName])
338+
}
331339
}
332340
if id == "" && digest == "" {
333341
logrus.Debugf("both image id and digest are empty for %s, skipping caching", tags[a.ImageName])
@@ -343,7 +351,7 @@ func (c *Cache) CacheArtifacts(ctx context.Context, artifacts []*latest.Artifact
343351

344352
// Retag retags newly built images in the format [imageName:workspaceHash] and pushes them if using a remote cluster
345353
func (c *Cache) Retag(ctx context.Context, out io.Writer, artifactsToBuild []*latest.Artifact, buildArtifacts []Artifact) {
346-
if !c.useCache || len(artifactsToBuild) == 0 {
354+
if !c.useCache || len(artifactsToBuild) == 0 || c.client == nil {
347355
return
348356
}
349357
tags := map[string]string{}
@@ -369,8 +377,12 @@ func (c *Cache) Retag(ctx context.Context, out io.Writer, artifactsToBuild []*la
369377
}
370378
}
371379

372-
// Check local daemon for img digest
380+
// Check local daemon for img digest, check remote digest if that doesn't work
373381
func (c *Cache) retrieveImageDigest(ctx context.Context, img string) (string, error) {
382+
if c.client == nil {
383+
// Check for remote digest
384+
return docker.RemoteDigest(img)
385+
}
374386
repoDigest, err := c.client.RepoDigest(ctx, img)
375387
if err != nil {
376388
return docker.RemoteDigest(img)
@@ -430,3 +442,7 @@ func cacheHasher(p string) (string, error) {
430442
}
431443
return hex.EncodeToString(h.Sum(nil)), nil
432444
}
445+
446+
func HashTag(a *latest.Artifact) string {
447+
return fmt.Sprintf("%s:%s", a.ImageName, a.WorkspaceHash)
448+
}

pkg/skaffold/build/cache_test.go

+21-8
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ func TestRetrieveCachedArtifactDetails(t *testing.T) {
272272
artifact *latest.Artifact
273273
hashes map[string]string
274274
digest string
275-
api testutil.FakeAPIClient
275+
api *testutil.FakeAPIClient
276276
cache *Cache
277277
expected *cachedArtifactDetails
278278
}{
@@ -299,7 +299,7 @@ func TestRetrieveCachedArtifactDetails(t *testing.T) {
299299
name: "image in cache and exists remotely, remote cluster",
300300
artifact: &latest.Artifact{ImageName: "image"},
301301
hashes: map[string]string{"image": "hash"},
302-
api: testutil.FakeAPIClient{
302+
api: &testutil.FakeAPIClient{
303303
TagToImageID: map[string]string{"image:hash": "image:tag"},
304304
ImageSummaries: []types.ImageSummary{
305305
{
@@ -322,7 +322,7 @@ func TestRetrieveCachedArtifactDetails(t *testing.T) {
322322
artifact: &latest.Artifact{ImageName: "image"},
323323
hashes: map[string]string{"image": "hash"},
324324
localCluster: true,
325-
api: testutil.FakeAPIClient{
325+
api: &testutil.FakeAPIClient{
326326
TagToImageID: map[string]string{"image:hash": "image:tag"},
327327
ImageSummaries: []types.ImageSummary{
328328
{
@@ -356,10 +356,7 @@ func TestRetrieveCachedArtifactDetails(t *testing.T) {
356356
},
357357
digest: digest,
358358
expected: &cachedArtifactDetails{
359-
needsRetag: true,
360-
needsPush: true,
361-
prebuiltImage: "anotherimage:hash",
362-
hashTag: "image:hash",
359+
hashTag: "image:hash",
363360
},
364361
},
365362
{
@@ -408,6 +405,20 @@ func TestRetrieveCachedArtifactDetails(t *testing.T) {
408405
hashTag: "image:hash",
409406
},
410407
},
408+
{
409+
name: "no local daemon, image exists remotely",
410+
artifact: &latest.Artifact{ImageName: "image"},
411+
hashes: map[string]string{"image": "hash"},
412+
cache: &Cache{
413+
useCache: true,
414+
needsPush: true,
415+
artifactCache: ArtifactCache{"hash": ImageDetails{Digest: digest}},
416+
},
417+
digest: digest,
418+
expected: &cachedArtifactDetails{
419+
hashTag: "image:hash",
420+
},
421+
},
411422
}
412423

413424
for _, test := range tests {
@@ -434,7 +445,9 @@ func TestRetrieveCachedArtifactDetails(t *testing.T) {
434445
remoteDigest = originalRemoteDigest
435446
}()
436447

437-
test.cache.client = docker.NewLocalDaemon(&test.api, nil)
448+
if test.api != nil {
449+
test.cache.client = docker.NewLocalDaemon(test.api, nil)
450+
}
438451
actual, err := test.cache.retrieveCachedArtifactDetails(context.Background(), test.artifact)
439452
if err != nil {
440453
t.Fatalf("error retrieving artifact details: %v", err)

pkg/skaffold/build/kaniko/run.go

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"io"
2323

24+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build"
2425
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/kaniko/sources"
2526
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
2627
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes"
@@ -57,6 +58,11 @@ func (b *Builder) run(ctx context.Context, out io.Writer, artifact *latest.Artif
5758
args = append(args, b.AdditionalFlags...)
5859
args = append(args, docker.GetBuildArgs(artifact.DockerArtifact)...)
5960

61+
if artifact.WorkspaceHash != "" {
62+
hashTag := build.HashTag(artifact)
63+
args = append(args, []string{"--destination", hashTag}...)
64+
}
65+
6066
if b.Cache != nil {
6167
args = append(args, "--cache=true")
6268
if b.Cache.Repo != "" {

pkg/skaffold/plugin/environments/gcb/desc.go

+16-9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package gcb
1919
import (
2020
"fmt"
2121

22+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build"
2223
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
2324
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/defaults"
2425
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
@@ -28,7 +29,12 @@ import (
2829
)
2930

3031
func (b *Builder) buildDescription(artifact *latest.Artifact, tag, bucket, object string) (*cloudbuild.Build, error) {
31-
steps, err := b.buildSteps(artifact, tag)
32+
tags := []string{tag}
33+
if artifact.WorkspaceHash != "" {
34+
tags = append(tags, build.HashTag(artifact))
35+
}
36+
37+
steps, err := b.buildSteps(artifact, tags)
3238
if err != nil {
3339
return nil, err
3440
}
@@ -42,7 +48,7 @@ func (b *Builder) buildDescription(artifact *latest.Artifact, tag, bucket, objec
4248
},
4349
},
4450
Steps: steps,
45-
Images: []string{tag},
51+
Images: tags,
4652
Options: &cloudbuild.BuildOptions{
4753
DiskSizeGb: b.DiskSizeGb,
4854
MachineType: b.MachineType,
@@ -51,28 +57,29 @@ func (b *Builder) buildDescription(artifact *latest.Artifact, tag, bucket, objec
5157
}, nil
5258
}
5359

54-
func (b *Builder) buildSteps(artifact *latest.Artifact, tag string) ([]*cloudbuild.BuildStep, error) {
60+
func (b *Builder) buildSteps(artifact *latest.Artifact, tags []string) ([]*cloudbuild.BuildStep, error) {
5561
switch {
5662
case artifact.BuilderPlugin != nil:
57-
return b.pluginBuildSteps(artifact, tag)
63+
return b.pluginBuildSteps(artifact, tags)
5864
case artifact.DockerArtifact != nil:
59-
return b.dockerBuildSteps(artifact.DockerArtifact, tag), nil
65+
return b.dockerBuildSteps(artifact.DockerArtifact, tags), nil
6066

6167
case artifact.BazelArtifact != nil:
6268
return nil, errors.New("skaffold can't build a bazel artifact with Google Cloud Build")
6369

70+
// TODO: build multiple tagged images with jib in GCB (priyawadhwa@)
6471
case artifact.JibMavenArtifact != nil:
65-
return b.jibMavenBuildSteps(artifact.JibMavenArtifact, tag), nil
72+
return b.jibMavenBuildSteps(artifact.JibMavenArtifact, tags[0]), nil
6673

6774
case artifact.JibGradleArtifact != nil:
68-
return b.jibGradleBuildSteps(artifact.JibGradleArtifact, tag), nil
75+
return b.jibGradleBuildSteps(artifact.JibGradleArtifact, tags[0]), nil
6976

7077
default:
7178
return nil, fmt.Errorf("undefined artifact type: %+v", artifact.ArtifactType)
7279
}
7380
}
7481

75-
func (b *Builder) pluginBuildSteps(artifact *latest.Artifact, tag string) ([]*cloudbuild.BuildStep, error) {
82+
func (b *Builder) pluginBuildSteps(artifact *latest.Artifact, tags []string) ([]*cloudbuild.BuildStep, error) {
7683
switch artifact.BuilderPlugin.Name {
7784
case constants.DockerBuilderPluginName:
7885
var da *latest.DockerArtifact
@@ -83,7 +90,7 @@ func (b *Builder) pluginBuildSteps(artifact *latest.Artifact, tag string) ([]*cl
8390
da = &latest.DockerArtifact{}
8491
}
8592
defaults.SetDefaultDockerArtifact(da)
86-
return b.dockerBuildSteps(da, tag), nil
93+
return b.dockerBuildSteps(da, tags), nil
8794
default:
8895
return nil, errors.Errorf("the '%s' builder is not supported", artifact.BuilderPlugin.Name)
8996
}

pkg/skaffold/plugin/environments/gcb/docker.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
cloudbuild "google.golang.org/api/cloudbuild/v1"
2525
)
2626

27-
func (b *Builder) dockerBuildSteps(artifact *latest.DockerArtifact, tag string) []*cloudbuild.BuildStep {
27+
func (b *Builder) dockerBuildSteps(artifact *latest.DockerArtifact, tags []string) []*cloudbuild.BuildStep {
2828
var steps []*cloudbuild.BuildStep
2929

3030
for _, cacheFrom := range artifact.CacheFrom {
@@ -35,7 +35,11 @@ func (b *Builder) dockerBuildSteps(artifact *latest.DockerArtifact, tag string)
3535
})
3636
}
3737

38-
args := append([]string{"build", "--tag", tag, "-f", artifact.DockerfilePath})
38+
args := []string{"build"}
39+
for _, t := range tags {
40+
args = append(args, []string{"--tag", t}...)
41+
}
42+
args = append(args, []string{"-f", artifact.DockerfilePath}...)
3943
args = append(args, docker.GetBuildArgs(artifact)...)
4044
args = append(args, ".")
4145

pkg/skaffold/plugin/environments/gcb/docker_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func TestPullCacheFrom(t *testing.T) {
8282
DockerImage: "docker/docker",
8383
},
8484
}
85-
steps := builder.dockerBuildSteps(artifact, "nginx2")
85+
steps := builder.dockerBuildSteps(artifact, []string{"nginx2"})
8686

8787
expected := []*cloudbuild.BuildStep{{
8888
Name: "docker/docker",

0 commit comments

Comments
 (0)