@@ -35,7 +35,6 @@ import (
35
35
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
36
36
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
37
37
"github.com/google/go-containerregistry/pkg/name"
38
- "github.com/google/go-containerregistry/pkg/v1/remote"
39
38
homedir "github.com/mitchellh/go-homedir"
40
39
"github.com/pkg/errors"
41
40
"github.com/sirupsen/logrus"
@@ -63,13 +62,10 @@ var (
63
62
// For testing
64
63
hashForArtifact = getHashForArtifact
65
64
localCluster = config .GetLocalCluster
65
+ remoteDigest = docker .RemoteDigest
66
66
noCache = & Cache {}
67
67
)
68
68
69
- const (
70
- prefixLength = len ("sha256:" )
71
- )
72
-
73
69
// NewCache returns the current state of the cache
74
70
func NewCache (useCache bool , cacheFile string ) * Cache {
75
71
if ! useCache {
@@ -132,7 +128,7 @@ func (c *Cache) RetrieveCachedArtifacts(ctx context.Context, out io.Writer, arti
132
128
var needToBuild []* latest.Artifact
133
129
var built []Artifact
134
130
for _ , a := range artifacts {
135
- artifact , err := c .retrieveCachedArtifact (ctx , out , a )
131
+ artifact , err := c .resolveCachedArtifact (ctx , out , a )
136
132
if err != nil {
137
133
logrus .Debugf ("error retrieving cached artifact for %s: %v\n " , a .ImageName , err )
138
134
needToBuild = append (needToBuild , a )
@@ -147,40 +143,67 @@ func (c *Cache) RetrieveCachedArtifacts(ctx context.Context, out io.Writer, arti
147
143
return needToBuild , built
148
144
}
149
145
150
- func (c * Cache ) retrieveCachedArtifact (ctx context.Context , out io.Writer , a * latest.Artifact ) (* Artifact , error ) {
146
+ func (c * Cache ) resolveCachedArtifact (ctx context.Context , out io.Writer , a * latest.Artifact ) (* Artifact , error ) {
147
+ details , err := c .retrieveCachedArtifactDetails (ctx , out , a )
148
+ if err != nil {
149
+ return nil , errors .Wrap (err , "getting cached artifact details" )
150
+ }
151
+ if details .needsRebuild {
152
+ return nil , nil
153
+ }
154
+ color .Green .Fprintf (out , "Found %s locally, retagging and pushing if necessary ...\n " , a .ImageName )
155
+ if details .needsRetag {
156
+ if err := c .client .Tag (ctx , details .prebuiltImage , details .hashTag ); err != nil {
157
+ return nil , errors .Wrap (err , "retagging image" )
158
+ }
159
+ }
160
+ if details .needsPush {
161
+ if _ , err := c .client .Push (ctx , out , details .hashTag ); err != nil {
162
+ return nil , errors .Wrap (err , "pushing image" )
163
+ }
164
+ }
165
+ color .Green .Fprintf (out , "Resolved %s, skipping rebuild.\n " , details .hashTag )
166
+ return & Artifact {
167
+ ImageName : a .ImageName ,
168
+ Tag : details .hashTag ,
169
+ }, nil
170
+ }
171
+
172
+ type cachedArtifactDetails struct {
173
+ needsRebuild bool
174
+ needsRetag bool
175
+ needsPush bool
176
+ prebuiltImage string
177
+ hashTag string
178
+ }
179
+
180
+ func (c * Cache ) retrieveCachedArtifactDetails (ctx context.Context , out io.Writer , a * latest.Artifact ) (* cachedArtifactDetails , error ) {
151
181
hash , err := hashForArtifact (ctx , a )
152
182
if err != nil {
153
183
return nil , errors .Wrapf (err , "getting hash for artifact %s" , a .ImageName )
154
184
}
155
185
a .WorkspaceHash = hash
186
+ localCluster , _ := localCluster ()
156
187
imageDetails , cacheHit := c .artifactCache [hash ]
157
188
if ! cacheHit {
158
- return nil , nil
189
+ return & cachedArtifactDetails {
190
+ needsRebuild : true ,
191
+ }, nil
159
192
}
160
193
hashTag := fmt .Sprintf ("%s:%s" , a .ImageName , hash )
161
194
162
195
// Check if we are using a local cluster
163
- local , _ := localCluster ()
164
196
var existsRemotely bool
165
- if ! local {
197
+ if ! localCluster {
166
198
// Check if tagged image exists remotely with the same digest
167
199
existsRemotely = imageExistsRemotely (hashTag , imageDetails .Digest )
168
200
}
169
201
170
202
// See if this image exists in the local daemon
171
203
if c .client .ImageExists (ctx , hashTag ) {
172
- color .Green .Fprintf (out , "Found %s locally...\n " , a .ImageName )
173
- // Push if the image doesn't exist remotely
174
- if ! existsRemotely && ! local {
175
- color .Green .Fprintf (out , "Pushing %s since it doesn't exist remotely...\n " , a .ImageName )
176
- if _ , err := c .client .Push (ctx , out , hashTag ); err != nil {
177
- return nil , errors .Wrapf (err , "pushing %s" , hashTag )
178
- }
179
- }
180
- color .Green .Fprintf (out , "%s ready, skipping rebuild\n " , hashTag )
181
- return & Artifact {
182
- ImageName : a .ImageName ,
183
- Tag : hashTag ,
204
+ return & cachedArtifactDetails {
205
+ needsPush : ! existsRemotely && ! localCluster ,
206
+ hashTag : hashTag ,
184
207
}, nil
185
208
}
186
209
// Check for a local image with the same digest as the image we want to build
@@ -191,20 +214,12 @@ func (c *Cache) retrieveCachedArtifact(ctx context.Context, out io.Writer, a *la
191
214
if prebuiltImage == "" {
192
215
return nil , errors .New ("no tagged prebuilt image" )
193
216
}
194
- color .Green .Fprintf (out , "Found %s locally, retagging and pushing...\n " , a .ImageName )
195
- // Retag the image
196
- if err := c .client .Tag (ctx , prebuiltImage , hashTag ); err != nil {
197
- return nil , errors .Wrap (err , "retagging image" )
198
- }
199
- // Push the retagged image
200
- if _ , err := c .client .Push (ctx , out , hashTag ); err != nil {
201
- return nil , errors .Wrap (err , "pushing image" )
202
- }
203
217
204
- color .Green .Fprintf (out , "Retagged %s, skipping rebuild.\n " , prebuiltImage )
205
- return & Artifact {
206
- ImageName : a .ImageName ,
207
- Tag : hashTag ,
218
+ return & cachedArtifactDetails {
219
+ needsRetag : true ,
220
+ needsPush : ! localCluster ,
221
+ prebuiltImage : prebuiltImage ,
222
+ hashTag : hashTag ,
208
223
}, nil
209
224
}
210
225
@@ -230,21 +245,15 @@ func (c *Cache) retrievePrebuiltImage(ctx context.Context, details ImageDetails)
230
245
231
246
func imageExistsRemotely (image , digest string ) bool {
232
247
if digest == "" {
248
+ logrus .Debugf ("Checking if %s exists remotely, but digest is empty" , image )
233
249
return false
234
250
}
235
- ref , err := name .ParseReference (image , name .WeakValidation )
236
- if err != nil {
237
- return false
238
- }
239
- img , err := remote .Image (ref )
240
- if err != nil {
241
- return false
242
- }
243
- d , err := img .Digest ()
251
+ d , err := remoteDigest (image )
244
252
if err != nil {
253
+ logrus .Debugf ("Checking if %s exists remotely, can't get digest: %v" , image , err )
245
254
return false
246
255
}
247
- return d . Hex == digest [ prefixLength :]
256
+ return d == digest
248
257
}
249
258
250
259
// CacheArtifacts determines the hash for each artifact, stores it in the artifact cache, and saves the cache at the end
0 commit comments