From 3b5498bc4865c74fa4140e3532e376475ef52649 Mon Sep 17 00:00:00 2001 From: Jimmi Dyson Date: Fri, 14 Oct 2016 09:43:10 +0100 Subject: [PATCH] Use temp file for cached downloads & rename to handle interrupted downloads gracefully --- pkg/minikube/cluster/localkube_caching.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/minikube/cluster/localkube_caching.go b/pkg/minikube/cluster/localkube_caching.go index e072d1c47a..99d1ca7570 100644 --- a/pkg/minikube/cluster/localkube_caching.go +++ b/pkg/minikube/cluster/localkube_caching.go @@ -63,17 +63,26 @@ func (l *localkubeCacher) isLocalkubeCached() bool { return true } +// cacheLocalKube downloads the stream to a temporary file & then atomically +// renames the file to the destination file name. This is to gracefully handle +// any errors in downloading the file. func (l *localkubeCacher) cacheLocalkube(body io.ReadCloser) error { // store localkube inside the .minikube dir - out, err := os.Create(l.getLocalkubeCacheFilepath()) + dir := filepath.Dir(l.getLocalkubeCacheFilepath()) + filename := filepath.Base(l.getLocalkubeCacheFilepath()) + out, err := ioutil.TempFile(dir, ".tmp-"+filename) if err != nil { - return errors.Wrap(err, "Error creating localkube local file") + os.Remove(out.Name()) + return errors.Wrap(err, "Error creating temporary localkube local file") } - defer out.Close() - defer body.Close() if _, err = io.Copy(out, body); err != nil { + os.Remove(out.Name()) return errors.Wrap(err, "Error writing localkube to file") } + if err := os.Rename(out.Name(), l.getLocalkubeCacheFilepath()); err != nil { + os.Remove(out.Name()) + return errors.Wrap(err, "Error renaming temporary localkube to destination") + } return nil } @@ -98,6 +107,7 @@ func (l *localkubeCacher) downloadAndCacheLocalkube() error { if err = util.Retry(5, downloader); err != nil { return errors.Wrap(err, "Max error attempts retrying localkube downloader") } + defer resp.Body.Close() if err = l.cacheLocalkube(resp.Body); err != nil { return errors.Wrap(err, "Error caching localkube to local directory") }