Skip to content

Commit

Permalink
Merge pull request #10918 from afbjorklund/kicbase-cache
Browse files Browse the repository at this point in the history
Add code for downloading kicbase image to cache
  • Loading branch information
medyagh authored Apr 26, 2021
2 parents b31da8d + 9742680 commit d6e011b
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 25 deletions.
1 change: 0 additions & 1 deletion cmd/minikube/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ var dirs = [...]string{
localpath.MakeMiniPath("certs"),
localpath.MakeMiniPath("machines"),
localpath.MakeMiniPath("cache"),
localpath.MakeMiniPath("cache", "iso"),
localpath.MakeMiniPath("config"),
localpath.MakeMiniPath("addons"),
localpath.MakeMiniPath("files"),
Expand Down
7 changes: 6 additions & 1 deletion pkg/minikube/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,12 @@ var (
// KubernetesReleaseBinaries are Kubernetes release binaries required for
// kubeadm (kubelet, kubeadm) and the addon manager (kubectl)
KubernetesReleaseBinaries = []string{"kubelet", "kubeadm", "kubectl"}
// ImageCacheDir is the path to the image cache directory

// ISOCacheDir is the path to the virtual machine image cache directory
ISOCacheDir = localpath.MakeMiniPath("cache", "iso")
// KICCacheDir is the path to the container node image cache directory
KICCacheDir = localpath.MakeMiniPath("cache", "kic")
// ImageCacheDir is the path to the container image cache directory
ImageCacheDir = localpath.MakeMiniPath("cache", "images")

// DefaultNamespaces are Kubernetes namespaces used by minikube, including addons
Expand Down
7 changes: 5 additions & 2 deletions pkg/minikube/download/iso.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"github.com/juju/mutex"
"github.com/pkg/errors"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/util/lock"
Expand Down Expand Up @@ -75,7 +75,7 @@ func localISOPath(u *url.URL) string {
return u.String()
}

return filepath.Join(localpath.MiniPath(), "cache", "iso", path.Base(u.Path))
return filepath.Join(constants.ISOCacheDir, path.Base(u.Path))
}

// ISO downloads and returns the path to the downloaded ISO
Expand Down Expand Up @@ -115,6 +115,9 @@ func downloadISO(isoURL string, skipChecksum bool) error {

// Lock before we check for existence to avoid thundering herd issues
dst := localISOPath(u)
if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
return errors.Wrapf(err, "making cache image directory: %s", dst)
}
spec := lock.PathMutexSpec(dst)
spec.Timeout = 10 * time.Minute
klog.Infof("acquiring lock: %+v", spec)
Expand Down
83 changes: 83 additions & 0 deletions pkg/minikube/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strings"
Expand Down Expand Up @@ -106,6 +107,23 @@ func DigestByGoLib(imgName string) string {
return cf.Hex
}

// ExistsImageInCache if img exist in local cache directory
func ExistsImageInCache(img string) bool {
f := filepath.Join(constants.KICCacheDir, path.Base(img)+".tar")
f = localpath.SanitizeCacheDir(f)

// Check if image exists locally
klog.Infof("Checking for %s in local cache directory", img)
if st, err := os.Stat(f); err == nil {
if st.Size() > 0 {
klog.Infof("Found %s in local cache directory, skipping pull", img)
return true
}
}
// Else, pull it
return false
}

// ExistsImageInDaemon if img exist in local docker daemon
func ExistsImageInDaemon(img string) bool {
// Check if image exists locally
Expand Down Expand Up @@ -159,6 +177,71 @@ func Tag(img string) string {
return img
}

// WriteImageToCache write img to the local cache directory
func WriteImageToCache(img string) error {
f := filepath.Join(constants.KICCacheDir, path.Base(img)+".tar")
f = localpath.SanitizeCacheDir(f)

if err := os.MkdirAll(filepath.Dir(f), 0777); err != nil {
return errors.Wrapf(err, "making cache image directory: %s", f)
}

// buffered channel
c := make(chan v1.Update, 200)

klog.Infof("Writing %s to local cache", img)
ref, err := name.ParseReference(img)
if err != nil {
return errors.Wrap(err, "parsing reference")
}
klog.V(3).Infof("Getting image %v", ref)
i, err := remote.Image(ref)
if err != nil {
if strings.Contains(err.Error(), "GitHub Docker Registry needs login") {
ErrGithubNeedsLogin = errors.New(err.Error())
return ErrGithubNeedsLogin
} else if strings.Contains(err.Error(), "UNAUTHORIZED") {
ErrNeedsLogin = errors.New(err.Error())
return ErrNeedsLogin
}

return errors.Wrap(err, "getting remote image")
}
klog.V(3).Infof("Writing image %v", ref)
errchan := make(chan error)
p := pb.Full.Start64(0)
fn := strings.Split(ref.Name(), "@")[0]
// abbreviate filename for progress
maxwidth := 30 - len("...")
if len(fn) > maxwidth {
fn = fn[0:maxwidth] + "..."
}
p.Set("prefix", " > "+fn+": ")
p.Set(pb.Bytes, true)

// Just a hair less than 80 (standard terminal width) for aesthetics & pasting into docs
p.SetWidth(79)

go func() {
err = tarball.WriteToFile(f, ref, i, tarball.WithProgress(c))
errchan <- err
}()
var update v1.Update
for {
select {
case update = <-c:
p.SetCurrent(update.Complete)
p.SetTotal(update.Total)
case err = <-errchan:
p.Finish()
if err != nil {
return errors.Wrap(err, "writing tarball image")
}
return nil
}
}
}

// WriteImageToDaemon write img to the local docker daemon
func WriteImageToDaemon(img string) error {
// buffered channel
Expand Down
49 changes: 29 additions & 20 deletions pkg/minikube/node/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,6 @@ func doCacheBinaries(k8sVersion string) error {

// beginDownloadKicBaseImage downloads the kic image
func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, downloadOnly bool) {
if cc.Driver != "docker" {
// TODO: driver == "podman"
klog.Info("Driver isn't docker, skipping base image download")
return
}
if image.ExistsImageInDaemon(cc.KicBaseImage) {
klog.Infof("%s exists in daemon, skipping pull", cc.KicBaseImage)
return
}

klog.Infof("Beginning downloading kic base image for %s with %s", cc.Driver, cc.KubernetesConfig.ContainerRuntime)
register.Reg.SetStep(register.PullingBaseImage)
Expand All @@ -135,23 +126,41 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down
}
}()
for _, img := range append([]string{baseImg}, kic.FallbackImages...) {
if err := image.LoadFromTarball(driver.Docker, img); err == nil {
var err error
if image.ExistsImageInCache(img) {
klog.Infof("%s exists in cache, skipping pull", img)
finalImg = img
} else {
klog.Infof("Downloading %s to local cache", img)
err = image.WriteImageToCache(img)
if err == nil {
klog.Infof("successfully saved %s as a tarball", img)
finalImg = img
}
}
if downloadOnly {
return err
}

if err := image.LoadFromTarball(cc.Driver, img); err == nil {
klog.Infof("successfully loaded %s from cached tarball", img)
// strip the digest from the img before saving it in the config
// because loading an image from tarball to daemon doesn't load the digest
finalImg = img
return nil
}
klog.Infof("Downloading %s to local daemon", img)
err := image.WriteImageToDaemon(img)
if err == nil {
klog.Infof("successfully downloaded %s", img)
finalImg = img
return nil
}
if downloadOnly {
if err := image.SaveToDir([]string{img}, constants.ImageCacheDir); err == nil {
klog.Infof("successfully saved %s as a tarball", img)

if driver.IsDocker(cc.Driver) {
if image.ExistsImageInDaemon(img) {
klog.Infof("%s exists in daemon, skipping pull", img)
finalImg = img
return nil
}

klog.Infof("Downloading %s to local daemon", img)
err = image.WriteImageToDaemon(img)
if err == nil {
klog.Infof("successfully downloaded %s", img)
finalImg = img
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/minikube/tests/dir_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func MakeTempDir() string {
if err != nil {
log.Fatal(err)
}
err = os.MkdirAll(filepath.Join(tempDir, "cache", "iso"), 0777)
err = os.MkdirAll(filepath.Join(tempDir, "cache"), 0777)
if err != nil {
log.Fatal(err)
}
Expand Down

0 comments on commit d6e011b

Please sign in to comment.