Skip to content

Commit

Permalink
Merge pull request #11127 from afbjorklund/image-pull
Browse files Browse the repository at this point in the history
new command "image pull: allow to load remote images directly without cache
  • Loading branch information
medyagh authored Apr 19, 2021
2 parents a7c9617 + 7c7c25d commit d4c1c2a
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 1 deletion.
11 changes: 11 additions & 0 deletions cmd/minikube/cmd/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var imageCmd = &cobra.Command{
}

var (
pull bool
imgDaemon bool
imgRemote bool
)
Expand Down Expand Up @@ -74,6 +75,15 @@ var loadImageCmd = &cobra.Command{
exit.Error(reason.Usage, "loading profile", err)
}

if pull {
// Pull image from remote registry, without doing any caching except in container runtime.
// This is similar to daemon.Image but it is done by the container runtime in the cluster.
if err := machine.PullImages(args, profile); err != nil {
exit.Error(reason.GuestImageLoad, "Failed to pull image", err)
}
return
}

var local bool
if imgRemote || imgDaemon {
local = false
Expand Down Expand Up @@ -166,6 +176,7 @@ $ minikube image list
func init() {
imageCmd.AddCommand(loadImageCmd)
imageCmd.AddCommand(removeImageCmd)
loadImageCmd.Flags().BoolVarP(&pull, "pull", "", false, "Pull the remote image (no caching)")
loadImageCmd.Flags().BoolVar(&imgDaemon, "daemon", false, "Cache image from docker daemon")
loadImageCmd.Flags().BoolVar(&imgRemote, "remote", false, "Cache image from remote registry")
imageCmd.AddCommand(listImageCmd)
Expand Down
5 changes: 5 additions & 0 deletions pkg/minikube/cruntime/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ func (r *Containerd) LoadImage(path string) error {
return nil
}

// PullImage pulls an image into this runtime
func (r *Containerd) PullImage(name string) error {
return pullCRIImage(r.Runner, name)
}

// RemoveImage removes a image
func (r *Containerd) RemoveImage(name string) error {
return removeCRIImage(r.Runner, name)
Expand Down
13 changes: 13 additions & 0 deletions pkg/minikube/cruntime/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@ func killCRIContainers(cr CommandRunner, ids []string) error {
return nil
}

// pullCRIImage pulls image using crictl
func pullCRIImage(cr CommandRunner, name string) error {
klog.Infof("Pulling image: %s", name)

crictl := getCrictlPath(cr)
args := append([]string{crictl, "pull"}, name)
c := exec.Command("sudo", args...)
if _, err := cr.RunCmd(c); err != nil {
return errors.Wrap(err, "crictl")
}
return nil
}

// removeCRIImage remove image using crictl
func removeCRIImage(cr CommandRunner, name string) error {
klog.Infof("Removing image: %s", name)
Expand Down
5 changes: 5 additions & 0 deletions pkg/minikube/cruntime/crio.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ func (r *CRIO) LoadImage(path string) error {
return nil
}

// PullImage pulls an image
func (r *CRIO) PullImage(name string) error {
return pullCRIImage(r.Runner, name)
}

// RemoveImage removes a image
func (r *CRIO) RemoveImage(name string) error {
return removeCRIImage(r.Runner, name)
Expand Down
4 changes: 3 additions & 1 deletion pkg/minikube/cruntime/cruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ type Manager interface {

// Load an image idempotently into the runtime on a host
LoadImage(string) error
// Pull an image to the runtime from the container registry
PullImage(string) error

// ImageExists takes image name and image sha checks if an it exists
ImageExists(string, string) bool
Expand Down Expand Up @@ -150,7 +152,7 @@ type ListContainersOptions struct {
Namespaces []string
}

// ListImageOptions are the options to use for listing images
// ListImagesOptions are the options to use for listing images
type ListImagesOptions struct {
}

Expand Down
13 changes: 13 additions & 0 deletions pkg/minikube/cruntime/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,19 @@ func (r *Docker) LoadImage(path string) error {
return nil
}

// PullImage pulls an image
func (r *Docker) PullImage(name string) error {
klog.Infof("Pulling image: %s", name)
if r.UseCRI {
return pullCRIImage(r.Runner, name)
}
c := exec.Command("docker", "pull", name)
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "pull image docker.")
}
return nil
}

// RemoveImage removes a image
func (r *Docker) RemoveImage(name string) error {
klog.Infof("Removing image: %s", name)
Expand Down
83 changes: 83 additions & 0 deletions pkg/minikube/machine/cache_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,87 @@ func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, src st
return nil
}

// pullImages pulls images to the container run time
func pullImages(cruntime cruntime.Manager, images []string) error {
klog.Infof("PullImages start: %s", images)
start := time.Now()

defer func() {
klog.Infof("PullImages completed in %s", time.Since(start))
}()

var g errgroup.Group

for _, image := range images {
image := image
g.Go(func() error {
return cruntime.PullImage(image)
})
}
if err := g.Wait(); err != nil {
return errors.Wrap(err, "error pulling images")
}
klog.Infoln("Successfully pulled images")
return nil
}

// PullImages pulls images to all nodes in profile
func PullImages(images []string, profile *config.Profile) error {
api, err := NewAPIClient()
if err != nil {
return errors.Wrap(err, "error creating api client")
}
defer api.Close()

succeeded := []string{}
failed := []string{}

pName := profile.Name

c, err := config.Load(pName)
if err != nil {
klog.Errorf("Failed to load profile %q: %v", pName, err)
return errors.Wrapf(err, "error loading config for profile :%v", pName)
}

for _, n := range c.Nodes {
m := config.MachineName(*c, n)

status, err := Status(api, m)
if err != nil {
klog.Warningf("error getting status for %s: %v", m, err)
continue
}

if status == state.Running.String() {
h, err := api.Load(m)
if err != nil {
klog.Warningf("Failed to load machine %q: %v", m, err)
continue
}
runner, err := CommandRunner(h)
if err != nil {
return err
}
cruntime, err := cruntime.New(cruntime.Config{Type: c.KubernetesConfig.ContainerRuntime, Runner: runner})
if err != nil {
return errors.Wrap(err, "error creating container runtime")
}
err = pullImages(cruntime, images)
if err != nil {
failed = append(failed, m)
klog.Warningf("Failed to pull images for profile %s %v", pName, err.Error())
continue
}
succeeded = append(succeeded, m)
}
}

klog.Infof("succeeded pulling to: %s", strings.Join(succeeded, " "))
klog.Infof("failed pulling to: %s", strings.Join(failed, " "))
return nil
}

// removeImages removes images from the container run time
func removeImages(cruntime cruntime.Manager, images []string) error {
klog.Infof("RemovingImages start: %s", images)
Expand All @@ -318,6 +399,7 @@ func removeImages(cruntime cruntime.Manager, images []string) error {
return nil
}

// RemoveImages removes images from all nodes in profile
func RemoveImages(images []string, profile *config.Profile) error {
api, err := NewAPIClient()
if err != nil {
Expand Down Expand Up @@ -374,6 +456,7 @@ func RemoveImages(images []string, profile *config.Profile) error {
return nil
}

// ListImages lists images on all nodes in profile
func ListImages(profile *config.Profile) error {
api, err := NewAPIClient()
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions site/content/en/docs/commands/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ minikube image load image.tar

```
--daemon Cache image from docker daemon
--pull Pull the remote image (no caching)
--remote Cache image from remote registry
```

Expand Down

0 comments on commit d4c1c2a

Please sign in to comment.