diff --git a/doc/toolbox-list.1.md b/doc/toolbox-list.1.md index a7ee2fed7..3acae17a3 100644 --- a/doc/toolbox-list.1.md +++ b/doc/toolbox-list.1.md @@ -23,6 +23,10 @@ List only toolbox containers, not images. List only toolbox images, not containers. +**--details, -d** + +Display more details about existing toolbox containers and images. + ## EXAMPLES ### List all existing toolbox containers and images @@ -31,6 +35,12 @@ List only toolbox images, not containers. $ toolbox list ``` +### List all existing toolbox containers and images with detailed information + +``` +$ toolbox list --details +``` + ### List existing toolbox containers only ``` @@ -43,6 +53,13 @@ $ toolbox list --containers $ toolbox list --images ``` +### List existing toolbox images or containers only, with detailed information + +``` +$ toolbox list --images --details +$ toolbox list --containers --details +``` + ## SEE ALSO `toolbox(1)`, `podman(1)`, `podman-ps(1)`, `podman-images(1)` diff --git a/src/cmd/list.go b/src/cmd/list.go index 0f7127b2b..31857d9c8 100644 --- a/src/cmd/list.go +++ b/src/cmd/list.go @@ -50,6 +50,7 @@ var ( listFlags struct { onlyContainers bool onlyImages bool + detailed bool } // toolboxLabels holds labels used by containers/images that mark them as compatible with Toolbox @@ -81,6 +82,12 @@ func init() { false, "List only toolbox images, not containers") + flags.BoolVarP(&listFlags.detailed, + "details", + "d", + false, + "Display more details about existing toolbox containers and images") + listCmd.SetHelpFunc(listHelp) rootCmd.AddCommand(listCmd) } @@ -125,7 +132,11 @@ func list(cmd *cobra.Command, args []string) error { } } - listOutput(images, containers) + if listFlags.detailed { + listOutputDetailed(images, containers) + } else { + listOutput(images, containers) + } return nil } @@ -235,32 +246,90 @@ func getImages() ([]toolboxImage, error) { } func listOutput(images []toolboxImage, containers []toolboxContainer) { + if len(containers) != 0 { + const boldGreenColor = "\033[1;32m" + const defaultColor = "\033[0;00m" // identical to resetColor, but same length as boldGreenColor + const boldDefaultColor = "\033[1m" + const resetColor = "\033[0m" + + stdoutFd := os.Stdout.Fd() + writer := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) + + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", defaultColor) + } + + fmt.Fprintf(writer, "%s", boldDefaultColor) + fmt.Fprintf(writer, "Toolboxes\n") + + for _, container := range containers { + isRunning := false + if podman.CheckVersion("2.0.0") { + isRunning = container.Status == "running" + } + + if isatty.IsTerminal(stdoutFd) { + var color string + if isRunning { + color = boldGreenColor + } else { + color = defaultColor + } + + fmt.Fprintf(writer, "%s", color) + } + fmt.Fprintf(writer, "\t%s", container.Names[0]) + + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", resetColor) + } + + fmt.Fprintf(writer, "\n") + } + + writer.Flush() + } + if len(images) != 0 { + const boldDefaultColor = "\033[1m" + const resetColor = "\033[0m" + + stdoutFd := os.Stdout.Fd() writer := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) - fmt.Fprintf(writer, "%s\t%s\t%s\n", "IMAGE ID", "IMAGE NAME", "CREATED") + + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", resetColor) + } + + fmt.Fprintf(writer, "%s", boldDefaultColor) + fmt.Fprintf(writer, "Images\n") for _, image := range images { + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", resetColor) + } + imageName := "" if len(image.Names) != 0 { imageName = image.Names[0] } - fmt.Fprintf(writer, "%s\t%s\t%s\n", - utils.ShortID(image.ID), - imageName, - image.Created) + fmt.Fprintf(writer, "\t%s\n", imageName) } writer.Flush() } - if len(images) != 0 && len(containers) != 0 { + if len(images) == 0 && len(containers) == 0 { fmt.Println() } +} +func listOutputDetailed(images []toolboxImage, containers []toolboxContainer) { if len(containers) != 0 { const boldGreenColor = "\033[1;32m" const defaultColor = "\033[0;00m" // identical to resetColor, but same length as boldGreenColor + const boldDefaultColor = "\033[1m" const resetColor = "\033[0m" stdoutFd := os.Stdout.Fd() @@ -270,13 +339,20 @@ func listOutput(images []toolboxImage, containers []toolboxContainer) { fmt.Fprintf(writer, "%s", defaultColor) } + fmt.Fprintf(writer, "%s", boldDefaultColor) + fmt.Fprintf(writer, "Toolboxes\n") + + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", defaultColor) + } + fmt.Fprintf(writer, - "%s\t%s\t%s\t%s\t%s", - "CONTAINER ID", - "CONTAINER NAME", - "CREATED", - "STATUS", - "IMAGE NAME") + "\t%s\t%s\t%s\t%s\t%s", + "Name", + "Container ID", + "Created", + "Status", + "Image") if isatty.IsTerminal(stdoutFd) { fmt.Fprintf(writer, "%s", resetColor) @@ -301,9 +377,9 @@ func listOutput(images []toolboxImage, containers []toolboxContainer) { fmt.Fprintf(writer, "%s", color) } - fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%s", - utils.ShortID(container.ID), + fmt.Fprintf(writer, "\t%s\t%s\t%s\t%s\t%s", container.Names[0], + utils.ShortID(container.ID), container.Created, container.Status, container.Image) @@ -314,9 +390,49 @@ func listOutput(images []toolboxImage, containers []toolboxContainer) { fmt.Fprintf(writer, "\n") } + fmt.Fprintf(writer, "\n") + writer.Flush() + } + + if len(images) != 0 { + const boldDefaultColor = "\033[1m" + const resetColor = "\033[0m" + + stdoutFd := os.Stdout.Fd() + writer := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) + + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", resetColor) + } + + fmt.Fprintf(writer, "%s", boldDefaultColor) + fmt.Fprintf(writer, "Images\n") + + fmt.Fprintf(writer, "%s", resetColor) + fmt.Fprintf(writer, "\t%s\t%s\t%s\n", "Name", "Image ID", "Created") + + for _, image := range images { + if isatty.IsTerminal(stdoutFd) { + fmt.Fprintf(writer, "%s", resetColor) + } + + imageName := "" + if len(image.Names) != 0 { + imageName = image.Names[0] + } + + fmt.Fprintf(writer, "\t%s\t%s\t%s\n", + imageName, + utils.ShortID(image.ID), + image.Created) + } writer.Flush() } + + if len(images) == 0 && len(containers) == 0 { + fmt.Println() + } } func (i *toolboxImage) UnmarshalJSON(data []byte) error {