Skip to content

Commit

Permalink
Use preloaded tarball for cri-o container runtime
Browse files Browse the repository at this point in the history
Pretty much the same as containerd, minus Restart
  • Loading branch information
afbjorklund committed Jun 28, 2020
1 parent cdc456a commit d9fb2e0
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 22 deletions.
16 changes: 2 additions & 14 deletions pkg/minikube/cruntime/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func containerdImagesPreloaded(runner command.Runner, images []string) bool {
if err != nil {
return false
}
type containerdImages struct {
type criImages struct {
Images []struct {
ID string `json:"id"`
RepoTags []string `json:"repoTags"`
Expand All @@ -381,7 +381,7 @@ func containerdImagesPreloaded(runner command.Runner, images []string) bool {
} `json:"images"`
}

var jsonImages containerdImages
var jsonImages criImages
err = json.Unmarshal(rr.Stdout.Bytes(), &jsonImages)
if err != nil {
glog.Errorf("failed to unmarshal images, will assume images are not preloaded")
Expand Down Expand Up @@ -412,15 +412,3 @@ func containerdImagesPreloaded(runner command.Runner, images []string) bool {
glog.Infof("all images are preloaded for containerd runtime.")
return true
}

// addRepoTagToImageName makes sure the image name has a repo tag in it.
// in crictl images list have the repo tag prepended to them
// for example "kubernetesui/dashboard:v2.0.0 will show up as "docker.io/kubernetesui/dashboard:v2.0.0"
// warning this is only meant for kuberentes images where we know the GCR addreses have .io in them
// not mean to be used for public images
func addRepoTagToImageName(imgName string) string {
if !strings.Contains(imgName, ".io/") {
return "docker.io/" + imgName
} // else it already has repo name dont add anything
return imgName
}
12 changes: 12 additions & 0 deletions pkg/minikube/cruntime/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,15 @@ func criContainerLogCmd(cr CommandRunner, id string, len int, follow bool) strin
cmd.WriteString(id)
return cmd.String()
}

// addRepoTagToImageName makes sure the image name has a repo tag in it.
// in crictl images list have the repo tag prepended to them
// for example "kubernetesui/dashboard:v2.0.0 will show up as "docker.io/kubernetesui/dashboard:v2.0.0"
// warning this is only meant for kuberentes images where we know the GCR addreses have .io in them
// not mean to be used for public images
func addRepoTagToImageName(imgName string) string {
if !strings.Contains(imgName, ".io/") {
return "docker.io/" + imgName
} // else it already has repo name dont add anything
return imgName
}
103 changes: 102 additions & 1 deletion pkg/minikube/cruntime/crio.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ limitations under the License.
package cruntime

import (
"encoding/json"
"fmt"
"net"
"os/exec"
"path"
"strings"
"time"

"github.com/blang/semver"
"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/download"
"k8s.io/minikube/pkg/minikube/out"
Expand Down Expand Up @@ -222,7 +227,103 @@ func (r *CRIO) Preload(cfg config.KubernetesConfig) error {
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) {
return nil
}
return fmt.Errorf("not yet implemented for %s", r.Name())

k8sVersion := cfg.KubernetesVersion
cRuntime := cfg.ContainerRuntime

// If images already exist, return
images, err := images.Kubeadm(cfg.ImageRepository, k8sVersion)
if err != nil {
return errors.Wrap(err, "getting images")
}
if crioImagesPreloaded(r.Runner, images) {
glog.Info("Images already preloaded, skipping extraction")
return nil
}

tarballPath := download.TarballPath(k8sVersion, cRuntime)
targetDir := "/"
targetName := "preloaded.tar.lz4"
dest := path.Join(targetDir, targetName)

c := exec.Command("which", "lz4")
if _, err := r.Runner.RunCmd(c); err != nil {
return NewErrISOFeature("lz4")
}

// Copy over tarball into host
fa, err := assets.NewFileAsset(tarballPath, targetDir, targetName, "0644")
if err != nil {
return errors.Wrap(err, "getting file asset")
}
t := time.Now()
if err := r.Runner.Copy(fa); err != nil {
return errors.Wrap(err, "copying file")
}
glog.Infof("Took %f seconds to copy over tarball", time.Since(t).Seconds())

t = time.Now()
// extract the tarball to /var in the VM
if rr, err := r.Runner.RunCmd(exec.Command("sudo", "tar", "-I", "lz4", "-C", "/var", "-xvf", dest)); err != nil {
return errors.Wrapf(err, "extracting tarball: %s", rr.Output())
}
glog.Infof("Took %f seconds t extract the tarball", time.Since(t).Seconds())

// remove the tarball in the VM
if err := r.Runner.Remove(fa); err != nil {
glog.Infof("error removing tarball: %v", err)
}

return nil
}

// crioImagesPreloaded returns true if all images have been preloaded
func crioImagesPreloaded(runner command.Runner, images []string) bool {
rr, err := runner.RunCmd(exec.Command("sudo", "crictl", "images", "--output", "json"))
if err != nil {
return false
}
type criImages struct {
Images []struct {
ID string `json:"id"`
RepoTags []string `json:"repoTags"`
RepoDigests []string `json:"repoDigests"`
Size string `json:"size"`
UID interface{} `json:"uid"`
Username string `json:"username"`
} `json:"images"`
}

var jsonImages criImages
err = json.Unmarshal(rr.Stdout.Bytes(), &jsonImages)
if err != nil {
glog.Errorf("failed to unmarshal images, will assume images are not preloaded")
return false
}

// Make sure images == imgs
for _, i := range images {
found := false
for _, ji := range jsonImages.Images {
for _, rt := range ji.RepoTags {
i = addRepoTagToImageName(i)
if i == rt {
found = true
break
}
}
if found {
break
}

}
if !found {
glog.Infof("couldn't find preloaded image for %q. assuming images are not preloaded.", i)
return false
}
}
glog.Infof("all images are preloaded for crio runtime.")
return true
}

// UpdateCRIONet updates CRIO CNI network configuration and restarts it
Expand Down
7 changes: 0 additions & 7 deletions pkg/minikube/download/preload.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ func remoteTarballURL(k8sVersion, containerRuntime string) string {
// PreloadExists returns true if there is a preloaded tarball that can be used
func PreloadExists(k8sVersion, containerRuntime string, forcePreload ...bool) bool {

// and https://github.com/kubernetes/minikube/issues/6934
// to track status of adding crio
if containerRuntime == "crio" {
glog.Info("crio is not supported yet, skipping preload")
return false
}

// TODO (#8166): Get rid of the need for this and viper at all
force := false
if len(forcePreload) > 0 {
Expand Down

0 comments on commit d9fb2e0

Please sign in to comment.