Skip to content

Commit 33aaf6d

Browse files
authored
Merge pull request #22072 from medyagh/add_retry_localimage
image save: Add retry logic for local image in case of EOF
2 parents fd1ed49 + 7cfc5c5 commit 33aaf6d

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

hack/preload-images/preload_images.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func makePreload(cfg preloadCfg) error {
159159
fmt.Printf("skip upload of %q\n", tf)
160160
return nil
161161
}
162-
if err := uploadTarball(tf, kv); err != nil {
162+
if err := uploadTarballToGCS(tf, kv); err != nil {
163163
return errors.Wrap(err, fmt.Sprintf("uploading tarball for k8s version %s with %s", kv, cr))
164164
}
165165
return nil

pkg/minikube/image/image.go

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,7 @@ func UploadCachedImage(imgName string) error {
212212
return err
213213
}
214214
if err := uploadImage(tag, imagePathInCache(imgName)); err != nil {
215-
// this time try determine image tags from tarball
216-
217-
manifest, err := tarball.LoadManifest(func() (io.ReadCloser, error) {
218-
return os.Open(imagePathInCache(imgName))
219-
})
215+
manifest, err := loadManifestWithRetry(imagePathInCache(imgName))
220216
if err != nil || len(manifest) == 0 || len(manifest[0].RepoTags) == 0 {
221217
return fmt.Errorf("failed to determine the image tag from tarball, err: %v", err)
222218
}
@@ -239,9 +235,9 @@ func uploadImage(tag name.Tag, p string) error {
239235
return fmt.Errorf("neither daemon nor remote")
240236
}
241237

242-
img, err = tarball.ImageFromPath(p, &tag)
238+
img, err = imageFromPathWithRetry(p, tag)
243239
if err != nil {
244-
return errors.Wrap(err, "tarball")
240+
return err
245241
}
246242
ref := name.Reference(tag)
247243

@@ -271,6 +267,52 @@ func uploadRemote(ref name.Reference, img v1.Image, p v1.Platform) error {
271267
return err
272268
}
273269

270+
func imageFromPathWithRetry(path string, tag name.Tag) (v1.Image, error) {
271+
var lastErr error
272+
const maxAttempts = 3
273+
for i := 0; i < maxAttempts; i++ {
274+
if i > 0 {
275+
time.Sleep(200 * time.Millisecond)
276+
}
277+
img, err := tarball.ImageFromPath(path, &tag)
278+
if err == nil {
279+
return img, nil
280+
}
281+
lastErr = errors.Wrap(err, "tarball")
282+
if !isRetryableEOF(err) {
283+
return nil, lastErr
284+
}
285+
klog.Infof("retrying tarball read for %s due to EOF (%d/%d)", path, i+1, maxAttempts)
286+
}
287+
return nil, lastErr
288+
}
289+
290+
func loadManifestWithRetry(path string) (tarball.Manifest, error) {
291+
var lastErr error
292+
const maxAttempts = 3
293+
for i := 0; i < maxAttempts; i++ {
294+
if i > 0 {
295+
time.Sleep(200 * time.Millisecond)
296+
}
297+
manifest, err := tarball.LoadManifest(func() (io.ReadCloser, error) {
298+
return os.Open(path)
299+
})
300+
if err == nil {
301+
return manifest, nil
302+
}
303+
lastErr = err
304+
if !isRetryableEOF(err) {
305+
return nil, lastErr
306+
}
307+
klog.Infof("retrying manifest read for %s due to EOF (%d/%d)", path, i+1, maxAttempts)
308+
}
309+
return nil, lastErr
310+
}
311+
312+
func isRetryableEOF(err error) bool {
313+
return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) || strings.Contains(err.Error(), "unexpected EOF")
314+
}
315+
274316
// See https://github.com/kubernetes/minikube/issues/10402
275317
// check if downloaded image Architecture field matches the requested and fix it otherwise
276318
func fixPlatform(ref name.Reference, img v1.Image, p v1.Platform) (v1.Image, error) {

0 commit comments

Comments
 (0)