diff --git a/go.mod b/go.mod index 955c41f6ed..39ca21b95d 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/blang/semver v3.5.0+incompatible github.com/c4milo/gotoolkit v0.0.0-20170318115440-bcc06269efa9 // indirect github.com/cenkalti/backoff v2.2.1+incompatible + github.com/cheggaaa/pb v1.0.27 github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 // indirect github.com/docker/docker v1.13.1 // indirect @@ -34,8 +35,8 @@ require ( github.com/johanneswuerbach/nfsexports v0.0.0-20181204082207-1aa528dcb345 github.com/libvirt/libvirt-go v3.4.0+incompatible github.com/machine-drivers/docker-machine-driver-vmware v0.1.1 - github.com/mattn/go-colorable v0.1.1 // indirect - github.com/mattn/go-isatty v0.0.5 + github.com/mattn/go-colorable v0.1.2 // indirect + github.com/mattn/go-isatty v0.0.8 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 github.com/moby/hyperkit v0.0.0-20171020124204-a12cd7250bcd github.com/olekukonko/tablewriter v0.0.0-20160923125401-bdcc175572fd @@ -47,6 +48,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 github.com/samalba/dockerclient v0.0.0-20160414174713-91d7393ff859 // indirect github.com/shirou/gopsutil v2.18.12+incompatible + github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect github.com/sirupsen/logrus v1.4.1 // indirect github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.3 @@ -58,7 +60,7 @@ require ( golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a golang.org/x/sync v0.0.0-20190423024810-112230192c58 - golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f + golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb golang.org/x/text v0.3.2 gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect diff --git a/go.sum b/go.sum index 670d0201fd..d984677ef8 100644 --- a/go.sum +++ b/go.sum @@ -57,6 +57,7 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/client9/misspell v0.0.0-20170928000206-9ce5d979ffda/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -194,6 +195,7 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -295,11 +297,11 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -398,6 +400,8 @@ github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e/go.mod h github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -538,8 +542,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/pkg/util/downloader.go b/pkg/util/downloader.go index 03b130a56d..6a6059110e 100644 --- a/pkg/util/downloader.go +++ b/pkg/util/downloader.go @@ -17,13 +17,12 @@ limitations under the License. package util import ( - "crypto" "net/url" "os" "path/filepath" "github.com/golang/glog" - download "github.com/jimmidyson/go-download" + "github.com/hashicorp/go-getter" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/out" @@ -55,32 +54,30 @@ func (f DefaultDownloader) GetISOFileURI(isoURL string) string { } // CacheMinikubeISOFromURL downloads the ISO, if it doesn't exist in cache -func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error { - if !f.ShouldCacheMinikubeISO(isoURL) { - glog.Infof("Not caching ISO, using %s", isoURL) +func (f DefaultDownloader) CacheMinikubeISOFromURL(url string) error { + if !f.ShouldCacheMinikubeISO(url) { + glog.Infof("Not caching ISO, using %s", url) return nil } - options := download.FileOptions{ - Mkdirs: download.MkdirAll, - Options: download.Options{ - ProgressBars: &download.ProgressBarOptions{ - MaxWidth: 80, - }, - }, + urlWithChecksum := url + if url == constants.DefaultISOURL { + urlWithChecksum = url + "?checksum=file:" + constants.DefaultISOSHAURL } - // Validate the ISO if it was the default URL, before writing it to disk. - if isoURL == constants.DefaultISOURL { - options.Checksum = constants.DefaultISOSHAURL - options.ChecksumHash = crypto.SHA256 + opts := []getter.ClientOption{getter.WithProgress(defaultProgressBar)} + client := &getter.Client{ + Src: urlWithChecksum, + Dst: f.GetISOCacheFilepath(url), + Mode: getter.ClientModeFile, + Options: opts, } - out.T(out.ISODownload, "Downloading Minikube ISO ...") - if err := download.ToFile(isoURL, f.GetISOCacheFilepath(isoURL), options); err != nil { - return errors.Wrap(err, isoURL) + glog.Infof("full url: %s", urlWithChecksum) + out.T(out.ISODownload, "Downloading VM boot image ...") + if err := client.Get(); err != nil { + return errors.Wrap(err, url) } - return nil } diff --git a/pkg/util/progressbar.go b/pkg/util/progressbar.go new file mode 100644 index 0000000000..e1bb6ebb70 --- /dev/null +++ b/pkg/util/progressbar.go @@ -0,0 +1,90 @@ +/* +Copyright 2019 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// This file implements a go-getter wrapper for cheggaaa progress bar + +// based on: +// https://github.com/hashicorp/go-getter/blob/master/cmd/go-getter/progress_tracking.go +package util + +import ( + "fmt" + "io" + "path/filepath" + "sync" + + "github.com/cheggaaa/pb" + "github.com/golang/glog" + "github.com/hashicorp/go-getter" +) + +var defaultProgressBar getter.ProgressTracker = &progressBar{} + +type progressBar struct { + lock sync.Mutex + pool *pb.Pool + pbs int +} + +// TrackProgress instantiates a new progress bar that will +// display the progress of stream until closed. +// total can be 0. +func (cpb *progressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser { + cpb.lock.Lock() + defer cpb.lock.Unlock() + + if cpb.pool == nil { + cpb.pool = pb.NewPool() + if err := cpb.pool.Start(); err != nil { + glog.Errorf("pool start: %v", err) + } + } + + p := pb.New64(totalSize) + p.Set64(currentSize) + p.SetUnits(pb.U_BYTES) + p.Prefix(fmt.Sprintf(" %s:", filepath.Base(src))) + // Just a hair less than 80 (standard terminal width) for aesthetics & pasting into docs + p.SetWidth(78) + cpb.pool.Add(p) + reader := p.NewProxyReader(stream) + + cpb.pbs++ + return &readCloser{ + Reader: reader, + close: func() error { + cpb.lock.Lock() + defer cpb.lock.Unlock() + + p.Finish() + cpb.pbs-- + if cpb.pbs <= 0 { + if err := cpb.pool.Stop(); err != nil { + glog.Errorf("pool stop: %v", err) + } + cpb.pool = nil + } + return nil + }, + } +} + +type readCloser struct { + io.Reader + close func() error +} + +func (c *readCloser) Close() error { return c.close() }