Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ListImages function and image list command #11007

Merged
merged 2 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions cmd/minikube/cmd/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,28 @@ $ minikube image unload image busybox
},
}

var listImageCmd = &cobra.Command{
Use: "list",
Short: "List images",
Example: `
$ minikube image list
`,
Aliases: []string{"ls"},
Run: func(cmd *cobra.Command, args []string) {
profile, err := config.LoadProfile(viper.GetString(config.ProfileName))
if err != nil {
exit.Error(reason.Usage, "loading profile", err)
}
if err := machine.ListImages(profile); err != nil {
exit.Error(reason.GuestImageList, "Failed to list images", err)
}
},
}

func init() {
imageCmd.AddCommand(loadImageCmd)
imageCmd.AddCommand(removeImageCmd)
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)
}
2 changes: 1 addition & 1 deletion pkg/drivers/kic/kic.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ func (d *Driver) Stop() error {
// even though we can't stop the cotainers inside, we still wanna stop the minikube container itself
klog.Errorf("unable to get container runtime: %v", err)
} else {
containers, err := runtime.ListContainers(cruntime.ListOptions{Namespaces: constants.DefaultNamespaces})
containers, err := runtime.ListContainers(cruntime.ListContainersOptions{Namespaces: constants.DefaultNamespaces})
if err != nil {
klog.Infof("unable list containers : %v", err)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/drivers/none/none.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (d *Driver) Kill() error {
}

// First try to gracefully stop containers
containers, err := d.runtime.ListContainers(cruntime.ListOptions{})
containers, err := d.runtime.ListContainers(cruntime.ListContainersOptions{})
if err != nil {
return errors.Wrap(err, "containers")
}
Expand All @@ -164,7 +164,7 @@ func (d *Driver) Kill() error {
return errors.Wrap(err, "stop")
}

containers, err = d.runtime.ListContainers(cruntime.ListOptions{})
containers, err = d.runtime.ListContainers(cruntime.ListContainersOptions{})
if err != nil {
return errors.Wrap(err, "containers")
}
Expand Down Expand Up @@ -220,7 +220,7 @@ func (d *Driver) Stop() error {
klog.Warningf("couldn't force stop kubelet. will continue with stop anyways: %v", err)
}
}
containers, err := d.runtime.ListContainers(cruntime.ListOptions{})
containers, err := d.runtime.ListContainers(cruntime.ListContainersOptions{})
if err != nil {
return errors.Wrap(err, "containers")
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/drivers/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func (d *Driver) Stop() error {
klog.Warningf("couldn't force stop kubelet. will continue with stop anyways: %v", err)
}
}
containers, err := d.runtime.ListContainers(cruntime.ListOptions{})
containers, err := d.runtime.ListContainers(cruntime.ListContainersOptions{})
if err != nil {
return errors.Wrap(err, "containers")
}
Expand Down Expand Up @@ -219,7 +219,7 @@ func (d *Driver) Kill() error {
}

// First try to gracefully stop containers
containers, err := d.runtime.ListContainers(cruntime.ListOptions{})
containers, err := d.runtime.ListContainers(cruntime.ListContainersOptions{})
if err != nil {
return errors.Wrap(err, "containers")
}
Expand All @@ -231,7 +231,7 @@ func (d *Driver) Kill() error {
return errors.Wrap(err, "stop")
}

containers, err = d.runtime.ListContainers(cruntime.ListOptions{})
containers, err = d.runtime.ListContainers(cruntime.ListContainersOptions{})
if err != nil {
return errors.Wrap(err, "containers")
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/minikube/bootstrapper/kubeadm/kubeadm.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ func (k *Bootstrapper) unpause(cfg config.ClusterConfig) error {
return err
}

ids, err := cr.ListContainers(cruntime.ListOptions{State: cruntime.Paused, Namespaces: []string{"kube-system"}})
ids, err := cr.ListContainers(cruntime.ListContainersOptions{State: cruntime.Paused, Namespaces: []string{"kube-system"}})
if err != nil {
return errors.Wrap(err, "list paused")
}
Expand Down Expand Up @@ -819,7 +819,7 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error {
klog.Warningf("stop kubelet: %v", err)
}

containers, err := cr.ListContainers(cruntime.ListOptions{Namespaces: []string{"kube-system"}})
containers, err := cr.ListContainers(cruntime.ListContainersOptions{Namespaces: []string{"kube-system"}})
if err != nil {
klog.Warningf("unable to list kube-system containers: %v", err)
}
Expand Down Expand Up @@ -1023,7 +1023,7 @@ func (k *Bootstrapper) stopKubeSystem(cfg config.ClusterConfig) error {
return errors.Wrap(err, "new cruntime")
}

ids, err := cr.ListContainers(cruntime.ListOptions{Namespaces: []string{"kube-system"}})
ids, err := cr.ListContainers(cruntime.ListContainersOptions{Namespaces: []string{"kube-system"}})
if err != nil {
return errors.Wrap(err, "list")
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/minikube/cluster/pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func pause(cr cruntime.Manager, r command.Runner, namespaces []string) ([]string
return ids, errors.Wrap(err, "kubelet stop")
}

ids, err := cr.ListContainers(cruntime.ListOptions{State: cruntime.Running, Namespaces: namespaces})
ids, err := cr.ListContainers(cruntime.ListContainersOptions{State: cruntime.Running, Namespaces: namespaces})
if err != nil {
return ids, errors.Wrap(err, "list running")
}
Expand Down Expand Up @@ -84,7 +84,7 @@ func Unpause(cr cruntime.Manager, r command.Runner, namespaces []string) ([]stri

// unpause unpauses a Kubernetes cluster
func unpause(cr cruntime.Manager, r command.Runner, namespaces []string) ([]string, error) {
ids, err := cr.ListContainers(cruntime.ListOptions{State: cruntime.Paused, Namespaces: namespaces})
ids, err := cr.ListContainers(cruntime.ListContainersOptions{State: cruntime.Paused, Namespaces: namespaces})
if err != nil {
return ids, errors.Wrap(err, "list paused")
}
Expand All @@ -105,7 +105,7 @@ func unpause(cr cruntime.Manager, r command.Runner, namespaces []string) ([]stri
}

func CheckIfPaused(cr cruntime.Manager, namespaces []string) (bool, error) {
ids, err := cr.ListContainers(cruntime.ListOptions{State: cruntime.Paused, Namespaces: namespaces})
ids, err := cr.ListContainers(cruntime.ListContainersOptions{State: cruntime.Paused, Namespaces: namespaces})
if err != nil {
return true, errors.Wrap(err, "list paused")
}
Expand Down
20 changes: 19 additions & 1 deletion pkg/minikube/cruntime/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,24 @@ func (r *Containerd) ImageExists(name string, sha string) bool {
return true
}

// ListImages lists images managed by this container runtime
func (r *Containerd) ListImages(ListImagesOptions) ([]string, error) {
c := exec.Command("sudo", "ctr", "-n=k8s.io", "images", "list", "--quiet")
rr, err := r.Runner.RunCmd(c)
if err != nil {
return nil, errors.Wrapf(err, "ctr images list")
}
all := strings.Split(rr.Stdout.String(), "\n")
imgs := []string{}
for _, img := range all {
if img == "" || strings.Contains(img, "sha256:") {
continue
}
imgs = append(imgs, img)
}
return imgs, nil
}

// LoadImage loads an image into this runtime
func (r *Containerd) LoadImage(path string) error {
klog.Infof("Loading image: %s", path)
Expand Down Expand Up @@ -288,7 +306,7 @@ func (r *Containerd) KubeletOptions() map[string]string {
}

// ListContainers returns a list of managed by this container runtime
func (r *Containerd) ListContainers(o ListOptions) ([]string, error) {
func (r *Containerd) ListContainers(o ListContainersOptions) ([]string, error) {
return listCRIContainers(r.Runner, containerdNamespaceRoot, o)
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/minikube/cruntime/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type container struct {
}

// crictlList returns the output of 'crictl ps' in an efficient manner
func crictlList(cr CommandRunner, root string, o ListOptions) (*command.RunResult, error) {
func crictlList(cr CommandRunner, root string, o ListContainersOptions) (*command.RunResult, error) {
klog.Infof("listing CRI containers in root %s: %+v", root, o)

// Use -a because otherwise paused containers are missed
Expand All @@ -63,7 +63,7 @@ func crictlList(cr CommandRunner, root string, o ListOptions) (*command.RunResul
}

// listCRIContainers returns a list of containers
func listCRIContainers(cr CommandRunner, root string, o ListOptions) ([]string, error) {
func listCRIContainers(cr CommandRunner, root string, o ListContainersOptions) ([]string, error) {
rr, err := crictlList(cr, root, o)
if err != nil {
return nil, errors.Wrap(err, "crictl list")
Expand Down
12 changes: 11 additions & 1 deletion pkg/minikube/cruntime/crio.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ func (r *CRIO) ImageExists(name string, sha string) bool {
return true
}

// ListImages returns a list of images managed by this container runtime
func (r *CRIO) ListImages(ListImagesOptions) ([]string, error) {
c := exec.Command("sudo", "podman", "images", "--format", "{{.Repository}}:{{.Tag}}")
rr, err := r.Runner.RunCmd(c)
if err != nil {
return nil, errors.Wrapf(err, "podman images")
}
return strings.Split(strings.TrimSpace(rr.Stdout.String()), "\n"), nil
}

// LoadImage loads an image into this runtime
func (r *CRIO) LoadImage(path string) error {
klog.Infof("Loading image: %s", path)
Expand Down Expand Up @@ -213,7 +223,7 @@ func (r *CRIO) KubeletOptions() map[string]string {
}

// ListContainers returns a list of managed by this container runtime
func (r *CRIO) ListContainers(o ListOptions) ([]string, error) {
func (r *CRIO) ListContainers(o ListContainersOptions) ([]string, error) {
return listCRIContainers(r.Runner, "", o)
}

Expand Down
14 changes: 10 additions & 4 deletions pkg/minikube/cruntime/cruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,14 @@ type Manager interface {

// ImageExists takes image name and image sha checks if an it exists
ImageExists(string, string) bool
// ListImages returns a list of images managed by this container runtime
ListImages(ListImagesOptions) ([]string, error)

// RemoveImage remove image based on name
RemoveImage(string) error

// ListContainers returns a list of managed by this container runtime
ListContainers(ListOptions) ([]string, error)
// ListContainers returns a list of containers managed by this container runtime
ListContainers(ListContainersOptions) ([]string, error)
// KillContainers removes containers based on ID
KillContainers([]string) error
// StopContainers stops containers based on ID
Expand Down Expand Up @@ -138,8 +140,8 @@ type Config struct {
InsecureRegistry []string
}

// ListOptions are the options to use for listing containers
type ListOptions struct {
// ListContainersOptions are the options to use for listing containers
type ListContainersOptions struct {
// State is the container state to filter by (All, Running, Paused)
State ContainerState
// Name is a name filter
Expand All @@ -148,6 +150,10 @@ type ListOptions struct {
Namespaces []string
}

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

// ErrContainerRuntimeNotRunning is thrown when container runtime is not running
var ErrContainerRuntimeNotRunning = errors.New("container runtime is not running")

Expand Down
8 changes: 4 additions & 4 deletions pkg/minikube/cruntime/cruntime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ func TestContainerFunctions(t *testing.T) {
}

// Get the list of apiservers
got, err := cr.ListContainers(ListOptions{Name: "apiserver"})
got, err := cr.ListContainers(ListContainersOptions{Name: "apiserver"})
if err != nil {
t.Fatalf("ListContainers: %v", err)
}
Expand All @@ -712,7 +712,7 @@ func TestContainerFunctions(t *testing.T) {
if err := cr.StopContainers(got); err != nil {
t.Fatalf("stop failed: %v", err)
}
got, err = cr.ListContainers(ListOptions{Name: "apiserver"})
got, err = cr.ListContainers(ListContainersOptions{Name: "apiserver"})
if err != nil {
t.Fatalf("ListContainers: %v", err)
}
Expand All @@ -722,7 +722,7 @@ func TestContainerFunctions(t *testing.T) {
}

// Get the list of everything else.
got, err = cr.ListContainers(ListOptions{})
got, err = cr.ListContainers(ListContainersOptions{})
if err != nil {
t.Fatalf("ListContainers: %v", err)
}
Expand All @@ -735,7 +735,7 @@ func TestContainerFunctions(t *testing.T) {
if err := cr.KillContainers(got); err != nil {
t.Errorf("KillContainers: %v", err)
}
got, err = cr.ListContainers(ListOptions{})
got, err = cr.ListContainers(ListContainersOptions{})
if err != nil {
t.Fatalf("ListContainers: %v", err)
}
Expand Down
44 changes: 43 additions & 1 deletion pkg/minikube/cruntime/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,25 @@ func (r *Docker) ImageExists(name string, sha string) bool {
return true
}

// ListImages returns a list of images managed by this container runtime
func (r *Docker) ListImages(ListImagesOptions) ([]string, error) {
c := exec.Command("docker", "images", "--format", "{{.Repository}}:{{.Tag}}")
rr, err := r.Runner.RunCmd(c)
if err != nil {
return nil, errors.Wrapf(err, "docker images")
}
short := strings.Split(rr.Stdout.String(), "\n")
imgs := []string{}
for _, img := range short {
if img == "" {
continue
}
img = addDockerIO(img)
imgs = append(imgs, img)
}
return imgs, nil
}

// LoadImage loads an image into this runtime
func (r *Docker) LoadImage(path string) error {
klog.Infof("Loading image: %s", path)
Expand Down Expand Up @@ -212,7 +231,7 @@ func (r *Docker) KubeletOptions() map[string]string {
}

// ListContainers returns a list of containers
func (r *Docker) ListContainers(o ListOptions) ([]string, error) {
func (r *Docker) ListContainers(o ListContainersOptions) ([]string, error) {
if r.UseCRI {
return listCRIContainers(r.Runner, "", o)
}
Expand Down Expand Up @@ -446,6 +465,29 @@ func dockerImagesPreloaded(runner command.Runner, images []string) bool {
return true
}

// Add docker.io prefix
func addDockerIO(name string) string {
var reg, usr, img string
p := strings.SplitN(name, "/", 2)
if len(p) > 1 && strings.Contains(p[0], ".") {
reg = p[0]
img = p[1]
} else {
reg = "docker.io"
img = name
p = strings.SplitN(img, "/", 2)
if len(p) > 1 {
usr = p[0]
img = p[1]
} else {
usr = "library"
img = name
}
return reg + "/" + usr + "/" + img
}
return reg + "/" + img
}

// Remove docker.io prefix since it won't be included in images names
// when we call 'docker images'
func trimDockerIO(name string) string {
Expand Down
2 changes: 1 addition & 1 deletion pkg/minikube/logs/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func OutputOffline(lines int) {
func logCommands(r cruntime.Manager, bs bootstrapper.Bootstrapper, cfg config.ClusterConfig, length int, follow bool) map[string]string {
cmds := bs.LogCommands(cfg, bootstrapper.LogOptions{Lines: length, Follow: follow})
for _, pod := range importantPods {
ids, err := r.ListContainers(cruntime.ListOptions{Name: pod})
ids, err := r.ListContainers(cruntime.ListContainersOptions{Name: pod})
if err != nil {
klog.Errorf("Failed to list containers for %q: %v", pod, err)
continue
Expand Down
Loading