diff --git a/src/cmd/completion.go b/src/cmd/completion.go index b9113e72b..e5c4eea7e 100644 --- a/src/cmd/completion.go +++ b/src/cmd/completion.go @@ -20,7 +20,9 @@ import ( "os" "strings" + "github.com/containers/toolbox/pkg/podman" "github.com/containers/toolbox/pkg/utils" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -129,8 +131,13 @@ func completionImageNames(cmd *cobra.Command, _ []string, _ string) ([]string, c return nil, cobra.ShellCompDirectiveNoFileComp } + logrus.Debug("Getting all images") + var imageNames []string - if images, err := getImages(true); err == nil { + + if images, err := podman.GetImages(true); err != nil { + logrus.Debugf("Getting all images failed: %s", err) + } else { for _, image := range images { if len(image.Names) != 1 { panic("cannot complete unflattened Image") @@ -144,8 +151,13 @@ func completionImageNames(cmd *cobra.Command, _ []string, _ string) ([]string, c } func completionImageNamesFiltered(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) { + logrus.Debug("Getting all images") + var imageNames []string - if images, err := getImages(true); err == nil { + + if images, err := podman.GetImages(true); err != nil { + logrus.Debugf("Getting all images failed: %s", err) + } else { for _, image := range images { skip := false diff --git a/src/cmd/list.go b/src/cmd/list.go index ae2bf3987..eb1e96d9e 100644 --- a/src/cmd/list.go +++ b/src/cmd/list.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "os" - "sort" "text/tabwriter" "github.com/containers/toolbox/pkg/podman" @@ -35,12 +34,6 @@ var ( onlyContainers bool onlyImages bool } - - // toolboxLabels holds labels used by containers/images that mark them as compatible with Toolbx - toolboxLabels = map[string]string{ - "com.github.debarshiray.toolbox": "true", - "com.github.containers.toolbox": "true", - } ) var listCmd = &cobra.Command{ @@ -93,9 +86,12 @@ func list(cmd *cobra.Command, args []string) error { var err error if lsImages { - images, err = getImages(false) + logrus.Debug("Getting all images") + + images, err = podman.GetImages(false) if err != nil { - return err + logrus.Debugf("Getting all images failed: %s", err) + return errors.New("failed to get images") } } @@ -151,44 +147,6 @@ func listHelp(cmd *cobra.Command, args []string) { } } -func getImages(fillNameWithID bool) ([]podman.Image, error) { - logrus.Debug("Fetching all images") - var args []string - images, err := podman.GetImages(args...) - if err != nil { - logrus.Debugf("Fetching all images failed: %s", err) - return nil, errors.New("failed to get images") - } - - processed := make(map[string]struct{}) - var toolboxImages []podman.Image - - for _, image := range images { - if _, ok := processed[image.ID]; ok { - continue - } - - processed[image.ID] = struct{}{} - var isToolboxImage bool - - for label := range toolboxLabels { - if _, ok := image.Labels[label]; ok { - isToolboxImage = true - break - } - } - - if isToolboxImage { - flattenedImages := image.FlattenNames(fillNameWithID) - toolboxImages = append(toolboxImages, flattenedImages...) - } - - } - - sort.Sort(podman.ImageSlice(toolboxImages)) - return toolboxImages, nil -} - func listOutput(images []podman.Image, containers []podman.Container) { if len(images) != 0 { writer := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) diff --git a/src/cmd/rmi.go b/src/cmd/rmi.go index 581bd3f23..4f84aa839 100644 --- a/src/cmd/rmi.go +++ b/src/cmd/rmi.go @@ -24,6 +24,7 @@ import ( "github.com/containers/toolbox/pkg/podman" "github.com/containers/toolbox/pkg/utils" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -67,9 +68,12 @@ func rmi(cmd *cobra.Command, args []string) error { } if rmiFlags.deleteAll { - toolboxImages, err := getImages(false) + logrus.Debug("Getting all images") + + toolboxImages, err := podman.GetImages(false) if err != nil { - return err + logrus.Debugf("Getting all images failed: %s", err) + return errors.New("failed to get images") } for _, image := range toolboxImages { diff --git a/src/pkg/podman/container.go b/src/pkg/podman/container.go index 4e7182763..bbc41a4e4 100644 --- a/src/pkg/podman/container.go +++ b/src/pkg/podman/container.go @@ -297,11 +297,3 @@ func (containers *Containers) Next() bool { func (containers *Containers) Reset() { containers.i = 0 } - -func isToolbx(labels map[string]string) bool { - if labels["com.github.containers.toolbox"] == "true" || labels["com.github.debarshiray.toolbox"] == "true" { - return true - } - - return false -} diff --git a/src/pkg/podman/podman.go b/src/pkg/podman/podman.go index 08828c1df..26ff02781 100644 --- a/src/pkg/podman/podman.go +++ b/src/pkg/podman/podman.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "io" + "sort" "strconv" "time" @@ -39,7 +40,7 @@ type Image struct { Names []string } -type ImageSlice []Image +type imageSlice []Image var ( podmanVersion string @@ -53,7 +54,7 @@ var ( LogLevel = logrus.ErrorLevel ) -func (image *Image) FlattenNames(fillNameWithID bool) []Image { +func (image *Image) flattenNames(fillNameWithID bool) []Image { var ret []Image if len(image.Names) == 0 { @@ -109,23 +110,23 @@ func (image *Image) UnmarshalJSON(data []byte) error { return nil } -func (images ImageSlice) Len() int { +func (images imageSlice) Len() int { return len(images) } -func (images ImageSlice) Less(i, j int) bool { +func (images imageSlice) Less(i, j int) bool { if len(images[i].Names) != 1 { - panic("cannot sort unflattened ImageSlice") + panic("cannot sort unflattened imageSlice") } if len(images[j].Names) != 1 { - panic("cannot sort unflattened ImageSlice") + panic("cannot sort unflattened imageSlice") } return images[i].Names[0] < images[j].Names[0] } -func (images ImageSlice) Swap(i, j int) { +func (images imageSlice) Swap(i, j int) { images[i], images[j] = images[j], images[i] } @@ -188,18 +189,19 @@ func GetContainers(args ...string) (*Containers, error) { return &Containers{containers, 0}, nil } -// GetImages is a wrapper function around `podman images --format json` command. +// GetImages is a wrapper function around `podman images --format json` command that returns all Toolbx images // -// Parameter args accepts an array of strings to be passed to the wrapped command (eg. ["-a", "--filter", "123"]). +// Parameter fillNameWithID is a boolean that indicates if the image names should be filled with the ID, when there +// are no names. // // Returned value is a slice of Images. // // If a problem happens during execution, first argument is nil and second argument holds the error message. -func GetImages(args ...string) ([]Image, error) { +func GetImages(fillNameWithID bool) ([]Image, error) { var stdout bytes.Buffer logLevelString := LogLevel.String() - args = append([]string{"--log-level", logLevelString, "images", "--format", "json"}, args...) + args := []string{"--log-level", logLevelString, "images", "--format", "json"} if err := shell.Run("podman", nil, &stdout, nil, args...); err != nil { return nil, err } @@ -210,7 +212,23 @@ func GetImages(args ...string) ([]Image, error) { return nil, err } - return images, nil + processedIDs := make(map[string]struct{}) + var toolbxImages []Image + + for _, image := range images { + if _, ok := processedIDs[image.ID]; ok { + continue + } + + processedIDs[image.ID] = struct{}{} + if isToolbx(image.Labels) { + flattenedImages := image.flattenNames(fillNameWithID) + toolbxImages = append(toolbxImages, flattenedImages...) + } + } + + sort.Sort(imageSlice(toolbxImages)) + return toolbxImages, nil } // GetVersion returns version of Podman in a string @@ -363,6 +381,14 @@ func IsToolboxImage(image string) (bool, error) { return true, nil } +func isToolbx(labels map[string]string) bool { + if labels["com.github.containers.toolbox"] == "true" || labels["com.github.debarshiray.toolbox"] == "true" { + return true + } + + return false +} + func Logs(container string, since time.Time, stderr io.Writer) error { ctx := context.Background() err := LogsContext(ctx, container, false, since, stderr)