Skip to content

Commit a670a21

Browse files
authored
Merge pull request #15528 from spowelljr/fixDoubleKicDownload
Don't redownload kicbase when already loaded
2 parents 7dc78fb + ba56f3c commit a670a21

File tree

3 files changed

+26
-148
lines changed

3 files changed

+26
-148
lines changed

pkg/minikube/download/download_test.go

-26
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ func TestDownload(t *testing.T) {
3232
t.Run("BinaryDownloadPreventsMultipleDownload", testBinaryDownloadPreventsMultipleDownload)
3333
t.Run("PreloadDownloadPreventsMultipleDownload", testPreloadDownloadPreventsMultipleDownload)
3434
t.Run("ImageToCache", testImageToCache)
35-
t.Run("ImageToDaemon", testImageToDaemon)
3635
t.Run("PreloadNotExists", testPreloadNotExists)
3736
t.Run("PreloadChecksumMismatch", testPreloadChecksumMismatch)
3837
t.Run("PreloadExistsCaching", testPreloadExistsCaching)
@@ -184,31 +183,6 @@ func testImageToCache(t *testing.T) {
184183
}
185184
}
186185

187-
func testImageToDaemon(t *testing.T) {
188-
downloadNum := 0
189-
DownloadMock = mockSleepDownload(&downloadNum)
190-
191-
checkImageExistsInCache = func(img string) bool { return downloadNum > 0 }
192-
193-
var group sync.WaitGroup
194-
group.Add(2)
195-
dlCall := func() {
196-
if err := ImageToCache("testimg"); err != nil {
197-
t.Errorf("Failed to download preload: %+v", err)
198-
}
199-
group.Done()
200-
}
201-
202-
go dlCall()
203-
go dlCall()
204-
205-
group.Wait()
206-
207-
if downloadNum != 1 {
208-
t.Errorf("Expected only 1 download attempt but got %v!", downloadNum)
209-
}
210-
}
211-
212186
// Validates that preload existence checks correctly caches values retrieved by remote checks.
213187
func testPreloadExistsCaching(t *testing.T) {
214188
checkCache = func(file string) (fs.FileInfo, error) {

pkg/minikube/download/image.go

+16-97
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ func ImageExistsInDaemon(img string) bool {
8585
return false
8686
}
8787

88-
var checkImageExistsInDaemon = ImageExistsInDaemon
89-
9088
// ImageToCache downloads img (if not present in cache) and writes it to the local cache directory
9189
func ImageToCache(img string) error {
9290
f := imagePathInCache(img)
@@ -122,7 +120,7 @@ func ImageToCache(img string) error {
122120
if err != nil {
123121
return errors.Wrap(err, "parsing reference")
124122
}
125-
tag, err := name.NewTag(strings.Split(img, "@")[0])
123+
tag, err := name.NewTag(image.Tag(img))
126124
if err != nil {
127125
return errors.Wrap(err, "parsing tag")
128126
}
@@ -142,7 +140,7 @@ func ImageToCache(img string) error {
142140
klog.V(3).Infof("Writing image %v", tag)
143141
errchan := make(chan error)
144142
p := pb.Full.Start64(0)
145-
fn := strings.Split(ref.Name(), "@")[0]
143+
fn := image.Tag(ref.Name())
146144
// abbreviate filename for progress
147145
maxwidth := 30 - len("...")
148146
if len(fn) > maxwidth {
@@ -177,7 +175,7 @@ func ImageToCache(img string) error {
177175
func parseImage(img string) (*name.Tag, name.Reference, error) {
178176

179177
var ref name.Reference
180-
tag, err := name.NewTag(strings.Split(img, "@")[0])
178+
tag, err := name.NewTag(image.Tag(img))
181179
if err != nil {
182180
return nil, nil, errors.Wrap(err, "failed to parse image reference")
183181
}
@@ -197,118 +195,39 @@ func parseImage(img string) (*name.Tag, name.Reference, error) {
197195
}
198196

199197
// CacheToDaemon loads image from tarball in the local cache directory to the local docker daemon
200-
func CacheToDaemon(img string) error {
198+
// It returns the img that was loaded into the daemon
199+
// If online it will be: image:tag@sha256
200+
// If offline it will be: image:tag
201+
func CacheToDaemon(img string) (string, error) {
201202
p := imagePathInCache(img)
202203

203204
tag, ref, err := parseImage(img)
204205
if err != nil {
205-
return err
206+
return "", err
206207
}
207208
// do not use cache if image is set in format <name>:latest
208209
if _, ok := ref.(name.Tag); ok {
209210
if tag.Name() == "latest" {
210-
return fmt.Errorf("can't cache 'latest' tag")
211+
return "", fmt.Errorf("can't cache 'latest' tag")
211212
}
212213
}
213214

214215
i, err := tarball.ImageFromPath(p, tag)
215216
if err != nil {
216-
return errors.Wrap(err, "tarball")
217+
return "", errors.Wrap(err, "tarball")
217218
}
218219

219220
resp, err := daemon.Write(*tag, i)
220221
klog.V(2).Infof("response: %s", resp)
221-
return err
222-
}
223-
224-
// ImageToDaemon downloads img (if not present in daemon) and writes it to the local docker daemon
225-
func ImageToDaemon(img string) error {
226-
fileLock := filepath.Join(detect.KICCacheDir(), path.Base(img)+".d.lock")
227-
fileLock = localpath.SanitizeCacheDir(fileLock)
228-
229-
releaser, err := lockDownload(fileLock)
230-
if releaser != nil {
231-
defer releaser.Release()
232-
}
233222
if err != nil {
234-
return err
235-
}
236-
237-
if checkImageExistsInDaemon(img) {
238-
klog.Infof("%s exists in daemon, skipping pull", img)
239-
return nil
240-
}
241-
// buffered channel
242-
c := make(chan v1.Update, 200)
243-
244-
klog.Infof("Writing %s to local daemon", img)
245-
ref, err := name.ParseReference(img)
246-
if err != nil {
247-
return errors.Wrap(err, "parsing reference")
248-
}
249-
tag, err := name.NewTag(strings.Split(img, "@")[0])
250-
if err != nil {
251-
return errors.Wrap(err, "parsing tag")
252-
}
253-
254-
if DownloadMock != nil {
255-
klog.Infof("Mock download: %s -> daemon", img)
256-
return DownloadMock(img, "daemon")
257-
}
258-
259-
klog.V(3).Infof("Getting image %v", ref)
260-
i, err := remote.Image(ref, remote.WithPlatform(defaultPlatform))
261-
if err != nil {
262-
if strings.Contains(err.Error(), "GitHub Docker Registry needs login") {
263-
ErrGithubNeedsLogin := errors.New(err.Error())
264-
return ErrGithubNeedsLogin
265-
} else if strings.Contains(err.Error(), "UNAUTHORIZED") {
266-
ErrNeedsLogin := errors.New(err.Error())
267-
return ErrNeedsLogin
268-
}
269-
270-
return errors.Wrap(err, "getting remote image")
271-
}
272-
273-
klog.V(3).Infof("Writing image %v", tag)
274-
errchan := make(chan error)
275-
p := pb.Full.Start64(0)
276-
fn := strings.Split(ref.Name(), "@")[0]
277-
// abbreviate filename for progress
278-
maxwidth := 30 - len("...")
279-
if len(fn) > maxwidth {
280-
fn = fn[0:maxwidth] + "..."
223+
return "", err
281224
}
282-
p.Set("prefix", " > "+fn+": ")
283-
p.Set(pb.Bytes, true)
284225

285-
// Just a hair less than 80 (standard terminal width) for aesthetics & pasting into docs
286-
p.SetWidth(79)
287-
288-
go func() {
289-
_, err = daemon.Write(tag, i)
290-
errchan <- err
291-
}()
292-
var update v1.Update
293-
loop:
294-
for {
295-
select {
296-
case update = <-c:
297-
p.SetCurrent(update.Complete)
298-
p.SetTotal(update.Total)
299-
case err = <-errchan:
300-
p.Finish()
301-
if err != nil {
302-
return errors.Wrap(err, "writing daemon image")
303-
}
304-
break loop
305-
}
306-
}
307-
klog.V(3).Infof("Pulling image %v", ref)
308-
// Pull digest
309226
cmd := exec.Command("docker", "pull", "--quiet", img)
310-
if _, err := cmd.Output(); err != nil {
311-
return errors.Wrap(err, "pulling remote image")
227+
if output, err := cmd.CombinedOutput(); err != nil {
228+
klog.Warningf("failed to pull image digest (expected if offline): %s: %v", output, err)
229+
img = image.Tag(img)
312230
}
313-
return nil
231+
232+
return img, nil
314233
}

pkg/minikube/node/cache.go

+10-25
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,15 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down
129129
var finalImg string
130130
// If we end up using a fallback image, notify the user
131131
defer func() {
132-
if finalImg != "" && finalImg != baseImg {
133-
out.WarningT(fmt.Sprintf("minikube was unable to download %s, but successfully downloaded %s as a fallback image", image.Tag(baseImg), image.Tag(finalImg)))
132+
if finalImg != "" {
134133
cc.KicBaseImage = finalImg
134+
if image.Tag(finalImg) != image.Tag(baseImg) {
135+
out.WarningT(fmt.Sprintf("minikube was unable to download %s, but successfully downloaded %s as a fallback image", image.Tag(baseImg), image.Tag(finalImg)))
136+
}
135137
}
136138
}()
137139
for _, img := range append([]string{baseImg}, kic.FallbackImages...) {
138140
var err error
139-
var isFromCache bool
140141

141142
if driver.IsDocker(cc.Driver) && download.ImageExistsInDaemon(img) && !downloadOnly {
142143
klog.Infof("%s exists in daemon, skipping load", img)
@@ -148,34 +149,18 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down
148149
err = download.ImageToCache(img)
149150
if err == nil {
150151
klog.Infof("successfully saved %s as a tarball", img)
151-
finalImg = img
152152
}
153-
if downloadOnly {
154-
return err
153+
if downloadOnly && err == nil {
154+
return nil
155155
}
156156

157157
if cc.Driver == driver.Podman {
158158
return fmt.Errorf("not yet implemented, see issue #8426")
159159
}
160-
if driver.IsDocker(cc.Driver) {
160+
if driver.IsDocker(cc.Driver) && err == nil {
161161
klog.Infof("Loading %s from local cache", img)
162-
err = download.CacheToDaemon(img)
163-
if err == nil {
164-
klog.Infof("successfully loaded %s from cached tarball", img)
165-
isFromCache = true
166-
}
167-
}
168-
169-
if driver.IsDocker(cc.Driver) {
170-
klog.Infof("Downloading %s to local daemon", img)
171-
err = download.ImageToDaemon(img)
172-
if err == nil {
173-
klog.Infof("successfully downloaded %s", img)
174-
finalImg = img
175-
return nil
176-
} else if isFromCache {
177-
klog.Infof("use image loaded from cache %s", strings.Split(img, "@")[0])
178-
finalImg = strings.Split(img, "@")[0]
162+
if finalImg, err = download.CacheToDaemon(img); err == nil {
163+
klog.Infof("successfully loaded and using %s from cached tarball", img)
179164
return nil
180165
}
181166
}
@@ -191,7 +176,7 @@ func waitDownloadKicBaseImage(g *errgroup.Group) {
191176
if err != nil {
192177
if errors.Is(err, image.ErrGithubNeedsLogin) {
193178
klog.Warningf("Error downloading kic artifacts: %v", err)
194-
out.ErrT(style.Connectivity, "Unfortunately, could not download the base image {{.image_name}} ", out.V{"image_name": strings.Split(kic.BaseImage, "@")[0]})
179+
out.ErrT(style.Connectivity, "Unfortunately, could not download the base image {{.image_name}} ", out.V{"image_name": image.Tag(kic.BaseImage)})
195180
out.WarningT("In order to use the fall back image, you need to log in to the github packages registry")
196181
out.Styled(style.Documentation, `Please visit the following link for documentation around this:
197182
https://help.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-docker-for-use-with-github-packages#authenticating-to-github-packages

0 commit comments

Comments
 (0)