Skip to content

Commit d9fb2e0

Browse files
committed
Use preloaded tarball for cri-o container runtime
Pretty much the same as containerd, minus Restart
1 parent cdc456a commit d9fb2e0

File tree

4 files changed

+116
-22
lines changed

4 files changed

+116
-22
lines changed

pkg/minikube/cruntime/containerd.go

+2-14
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ func containerdImagesPreloaded(runner command.Runner, images []string) bool {
370370
if err != nil {
371371
return false
372372
}
373-
type containerdImages struct {
373+
type criImages struct {
374374
Images []struct {
375375
ID string `json:"id"`
376376
RepoTags []string `json:"repoTags"`
@@ -381,7 +381,7 @@ func containerdImagesPreloaded(runner command.Runner, images []string) bool {
381381
} `json:"images"`
382382
}
383383

384-
var jsonImages containerdImages
384+
var jsonImages criImages
385385
err = json.Unmarshal(rr.Stdout.Bytes(), &jsonImages)
386386
if err != nil {
387387
glog.Errorf("failed to unmarshal images, will assume images are not preloaded")
@@ -412,15 +412,3 @@ func containerdImagesPreloaded(runner command.Runner, images []string) bool {
412412
glog.Infof("all images are preloaded for containerd runtime.")
413413
return true
414414
}
415-
416-
// addRepoTagToImageName makes sure the image name has a repo tag in it.
417-
// in crictl images list have the repo tag prepended to them
418-
// for example "kubernetesui/dashboard:v2.0.0 will show up as "docker.io/kubernetesui/dashboard:v2.0.0"
419-
// warning this is only meant for kuberentes images where we know the GCR addreses have .io in them
420-
// not mean to be used for public images
421-
func addRepoTagToImageName(imgName string) string {
422-
if !strings.Contains(imgName, ".io/") {
423-
return "docker.io/" + imgName
424-
} // else it already has repo name dont add anything
425-
return imgName
426-
}

pkg/minikube/cruntime/cri.go

+12
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,15 @@ func criContainerLogCmd(cr CommandRunner, id string, len int, follow bool) strin
259259
cmd.WriteString(id)
260260
return cmd.String()
261261
}
262+
263+
// addRepoTagToImageName makes sure the image name has a repo tag in it.
264+
// in crictl images list have the repo tag prepended to them
265+
// for example "kubernetesui/dashboard:v2.0.0 will show up as "docker.io/kubernetesui/dashboard:v2.0.0"
266+
// warning this is only meant for kuberentes images where we know the GCR addreses have .io in them
267+
// not mean to be used for public images
268+
func addRepoTagToImageName(imgName string) string {
269+
if !strings.Contains(imgName, ".io/") {
270+
return "docker.io/" + imgName
271+
} // else it already has repo name dont add anything
272+
return imgName
273+
}

pkg/minikube/cruntime/crio.go

+102-1
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,20 @@ limitations under the License.
1717
package cruntime
1818

1919
import (
20+
"encoding/json"
2021
"fmt"
2122
"net"
2223
"os/exec"
24+
"path"
2325
"strings"
26+
"time"
2427

2528
"github.com/blang/semver"
2629
"github.com/golang/glog"
2730
"github.com/pkg/errors"
31+
"k8s.io/minikube/pkg/minikube/assets"
2832
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
33+
"k8s.io/minikube/pkg/minikube/command"
2934
"k8s.io/minikube/pkg/minikube/config"
3035
"k8s.io/minikube/pkg/minikube/download"
3136
"k8s.io/minikube/pkg/minikube/out"
@@ -222,7 +227,103 @@ func (r *CRIO) Preload(cfg config.KubernetesConfig) error {
222227
if !download.PreloadExists(cfg.KubernetesVersion, cfg.ContainerRuntime) {
223228
return nil
224229
}
225-
return fmt.Errorf("not yet implemented for %s", r.Name())
230+
231+
k8sVersion := cfg.KubernetesVersion
232+
cRuntime := cfg.ContainerRuntime
233+
234+
// If images already exist, return
235+
images, err := images.Kubeadm(cfg.ImageRepository, k8sVersion)
236+
if err != nil {
237+
return errors.Wrap(err, "getting images")
238+
}
239+
if crioImagesPreloaded(r.Runner, images) {
240+
glog.Info("Images already preloaded, skipping extraction")
241+
return nil
242+
}
243+
244+
tarballPath := download.TarballPath(k8sVersion, cRuntime)
245+
targetDir := "/"
246+
targetName := "preloaded.tar.lz4"
247+
dest := path.Join(targetDir, targetName)
248+
249+
c := exec.Command("which", "lz4")
250+
if _, err := r.Runner.RunCmd(c); err != nil {
251+
return NewErrISOFeature("lz4")
252+
}
253+
254+
// Copy over tarball into host
255+
fa, err := assets.NewFileAsset(tarballPath, targetDir, targetName, "0644")
256+
if err != nil {
257+
return errors.Wrap(err, "getting file asset")
258+
}
259+
t := time.Now()
260+
if err := r.Runner.Copy(fa); err != nil {
261+
return errors.Wrap(err, "copying file")
262+
}
263+
glog.Infof("Took %f seconds to copy over tarball", time.Since(t).Seconds())
264+
265+
t = time.Now()
266+
// extract the tarball to /var in the VM
267+
if rr, err := r.Runner.RunCmd(exec.Command("sudo", "tar", "-I", "lz4", "-C", "/var", "-xvf", dest)); err != nil {
268+
return errors.Wrapf(err, "extracting tarball: %s", rr.Output())
269+
}
270+
glog.Infof("Took %f seconds t extract the tarball", time.Since(t).Seconds())
271+
272+
// remove the tarball in the VM
273+
if err := r.Runner.Remove(fa); err != nil {
274+
glog.Infof("error removing tarball: %v", err)
275+
}
276+
277+
return nil
278+
}
279+
280+
// crioImagesPreloaded returns true if all images have been preloaded
281+
func crioImagesPreloaded(runner command.Runner, images []string) bool {
282+
rr, err := runner.RunCmd(exec.Command("sudo", "crictl", "images", "--output", "json"))
283+
if err != nil {
284+
return false
285+
}
286+
type criImages struct {
287+
Images []struct {
288+
ID string `json:"id"`
289+
RepoTags []string `json:"repoTags"`
290+
RepoDigests []string `json:"repoDigests"`
291+
Size string `json:"size"`
292+
UID interface{} `json:"uid"`
293+
Username string `json:"username"`
294+
} `json:"images"`
295+
}
296+
297+
var jsonImages criImages
298+
err = json.Unmarshal(rr.Stdout.Bytes(), &jsonImages)
299+
if err != nil {
300+
glog.Errorf("failed to unmarshal images, will assume images are not preloaded")
301+
return false
302+
}
303+
304+
// Make sure images == imgs
305+
for _, i := range images {
306+
found := false
307+
for _, ji := range jsonImages.Images {
308+
for _, rt := range ji.RepoTags {
309+
i = addRepoTagToImageName(i)
310+
if i == rt {
311+
found = true
312+
break
313+
}
314+
}
315+
if found {
316+
break
317+
}
318+
319+
}
320+
if !found {
321+
glog.Infof("couldn't find preloaded image for %q. assuming images are not preloaded.", i)
322+
return false
323+
}
324+
}
325+
glog.Infof("all images are preloaded for crio runtime.")
326+
return true
226327
}
227328

228329
// UpdateCRIONet updates CRIO CNI network configuration and restarts it

pkg/minikube/download/preload.go

-7
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,6 @@ func remoteTarballURL(k8sVersion, containerRuntime string) string {
7878
// PreloadExists returns true if there is a preloaded tarball that can be used
7979
func PreloadExists(k8sVersion, containerRuntime string, forcePreload ...bool) bool {
8080

81-
// and https://github.com/kubernetes/minikube/issues/6934
82-
// to track status of adding crio
83-
if containerRuntime == "crio" {
84-
glog.Info("crio is not supported yet, skipping preload")
85-
return false
86-
}
87-
8881
// TODO (#8166): Get rid of the need for this and viper at all
8982
force := false
9083
if len(forcePreload) > 0 {

0 commit comments

Comments
 (0)