Port V1 --format table to V2 podman

* volume ls
* container ps
* updated broken tests when skip removed

Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
Jhon Honce
2020-10-08 13:15:09 -07:00
parent 0afbe2d152
commit e9b667bb5f
4 changed files with 65 additions and 61 deletions

View File

@ -12,7 +12,9 @@ import (
tm "github.com/buger/goterm" tm "github.com/buger/goterm"
"github.com/containers/buildah/pkg/formats" "github.com/containers/buildah/pkg/formats"
"github.com/containers/podman/v2/cmd/podman/parse"
"github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/report"
"github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/cmd/podman/utils"
"github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/cmd/podman/validate"
"github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/domain/entities"
@ -176,47 +178,51 @@ func ps(cmd *cobra.Command, args []string) error {
return err return err
} }
} }
if listOpts.Format == "json" {
switch {
case parse.MatchesJSONFormat(listOpts.Format):
return jsonOut(listContainers) return jsonOut(listContainers)
} case listOpts.Quiet:
if listOpts.Quiet {
return quietOut(listContainers) return quietOut(listContainers)
} }
// Output table Watch > 0 will refresh screen
responses := make([]psReporter, 0, len(listContainers)) responses := make([]psReporter, 0, len(listContainers))
for _, r := range listContainers { for _, r := range listContainers {
responses = append(responses, psReporter{r}) responses = append(responses, psReporter{r})
} }
headers, format := createPsOut() var headers, format string
if cmd.Flag("format").Changed { if cmd.Flags().Changed("format") {
format = strings.TrimPrefix(listOpts.Format, "table ") headers = ""
if !strings.HasPrefix(format, "\n") { format = report.NormalizeFormat(listOpts.Format)
format += "\n" } else {
} headers, format = createPsOut()
}
format = "{{range . }}" + format + "{{end}}"
if !listOpts.Quiet && !cmd.Flag("format").Changed {
format = headers + format
} }
format = headers + "{{range . }}" + format + "{{end}}"
tmpl, err := template.New("listContainers").Parse(format) tmpl, err := template.New("listContainers").Parse(format)
if err != nil { if err != nil {
return err return err
} }
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
if listOpts.Watch > 0 { if listOpts.Watch > 0 {
for { for {
var responses []psReporter var responses []psReporter
tm.Clear() tm.Clear()
tm.MoveCursor(1, 1) tm.MoveCursor(1, 1)
tm.Flush() tm.Flush()
listContainers, err := getResponses()
for _, r := range listContainers { if ctnrs, err := getResponses(); err != nil {
responses = append(responses, psReporter{r})
}
if err != nil {
return err return err
} else {
for _, r := range ctnrs {
responses = append(responses, psReporter{r})
}
} }
if err := tmpl.Execute(w, responses); err != nil { if err := tmpl.Execute(w, responses); err != nil {
return err return err
} }
@ -232,11 +238,11 @@ func ps(cmd *cobra.Command, args []string) error {
if err := tmpl.Execute(w, responses); err != nil { if err := tmpl.Execute(w, responses); err != nil {
return err return err
} }
return w.Flush()
} }
return nil return nil
} }
// cannot use report.Headers() as it doesn't support structures as fields
func createPsOut() (string, string) { func createPsOut() (string, string) {
var row string var row string
if listOpts.Namespace { if listOpts.Namespace {
@ -257,12 +263,9 @@ func createPsOut() (string, string) {
headers += "\tSIZE" headers += "\tSIZE"
row += "\t{{.Size}}" row += "\t{{.Size}}"
} }
if !strings.HasSuffix(headers, "\n") {
headers += "\n" headers = report.NormalizeFormat(headers)
} row = report.NormalizeFormat(row)
if !strings.HasSuffix(row, "\n") {
row += "\n"
}
return headers, row return headers, row
} }

View File

@ -3,13 +3,14 @@ package volumes
import ( import (
"context" "context"
"fmt" "fmt"
"io"
"os" "os"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"text/template" "text/template"
"github.com/containers/podman/v2/cmd/podman/parse"
"github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/report"
"github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/cmd/podman/validate"
"github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/domain/entities"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -55,7 +56,6 @@ func init() {
} }
func list(cmd *cobra.Command, args []string) error { func list(cmd *cobra.Command, args []string) error {
var w io.Writer = os.Stdout
if cliOpts.Quiet && cmd.Flag("format").Changed { if cliOpts.Quiet && cmd.Flag("format").Changed {
return errors.New("quiet and format flags cannot be used together") return errors.New("quiet and format flags cannot be used together")
} }
@ -73,40 +73,40 @@ func list(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return err return err
} }
if cliOpts.Format == "json" {
return outputJSON(responses)
}
if len(responses) < 1 { switch {
case parse.MatchesJSONFormat(cliOpts.Format):
return outputJSON(responses)
case len(responses) < 1:
return nil return nil
} }
// "\t" from the command line is not being recognized as a tab return outputTemplate(cmd, responses)
// replacing the string "\t" to a tab character if the user passes in "\t" }
cliOpts.Format = strings.Replace(cliOpts.Format, `\t`, "\t", -1)
func outputTemplate(cmd *cobra.Command, responses []*entities.VolumeListReport) error {
headers := report.Headers(entities.VolumeListReport{}, map[string]string{
"Name": "VOLUME NAME",
})
row := report.NormalizeFormat(cliOpts.Format)
if cliOpts.Quiet { if cliOpts.Quiet {
cliOpts.Format = "{{.Name}}\n" row = "{{.Name}}\n"
} }
headers := "DRIVER\tVOLUME NAME\n" row = "{{range . }}" + row + "{{end}}"
row := cliOpts.Format
if !strings.HasSuffix(cliOpts.Format, "\n") { tmpl, err := template.New("list volume").Parse(row)
row += "\n"
}
format := "{{range . }}" + row + "{{end}}"
if !cliOpts.Quiet && !cmd.Flag("format").Changed {
w = tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0)
format = headers + format
}
tmpl, err := template.New("listVolume").Parse(format)
if err != nil { if err != nil {
return err return err
} }
if err := tmpl.Execute(w, responses); err != nil { w := tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0)
return err defer w.Flush()
if !cliOpts.Quiet && !cmd.Flag("format").Changed {
if err := tmpl.Execute(w, headers); err != nil {
return errors.Wrapf(err, "failed to write report column headers")
}
} }
if flusher, ok := w.(interface{ Flush() error }); ok { return tmpl.Execute(w, responses)
return flusher.Flush()
}
return nil
} }
func outputJSON(vols []*entities.VolumeListReport) error { func outputJSON(vols []*entities.VolumeListReport) error {

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/go-units" "github.com/docker/go-units"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
) )
var _ = Describe("Podman ps", func() { var _ = Describe("Podman ps", func() {
@ -218,17 +219,16 @@ var _ = Describe("Podman ps", func() {
}) })
It("podman ps namespace flag with go template format", func() { It("podman ps namespace flag with go template format", func() {
Skip("FIXME: table still not supported in podman ps command")
_, ec, _ := podmanTest.RunLsContainer("test1") _, ec, _ := podmanTest.RunLsContainer("test1")
Expect(ec).To(Equal(0)) Expect(ec).To(Equal(0))
result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.ID}} {{.Image}} {{.ImageID}} {{.Labels}}"}) result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.ID}} {{.Image}} {{.ImageID}} {{.Labels}}"})
result.WaitWithDefaultTimeout() result.WaitWithDefaultTimeout()
Expect(strings.Contains(result.OutputToStringArray()[0], "table")).To(BeFalse())
Expect(strings.Contains(result.OutputToStringArray()[0], "ID")).To(BeTrue()) Expect(result.OutputToStringArray()[0]).ToNot(ContainSubstring("table"))
Expect(strings.Contains(result.OutputToStringArray()[0], "ImageID")).To(BeTrue()) Expect(result.OutputToStringArray()[0]).ToNot(ContainSubstring("ImageID"))
Expect(strings.Contains(result.OutputToStringArray()[1], "alpine:latest")).To(BeTrue()) Expect(result.OutputToStringArray()[0]).To(ContainSubstring("alpine:latest"))
Expect(result.ExitCode()).To(Equal(0)) Expect(result).Should(Exit(0))
}) })
It("podman ps ancestor filter flag", func() { It("podman ps ancestor filter flag", func() {

View File

@ -7,6 +7,7 @@ import (
. "github.com/containers/podman/v2/test/utils" . "github.com/containers/podman/v2/test/utils"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
) )
var _ = Describe("Podman volume ls", func() { var _ = Describe("Podman volume ls", func() {
@ -56,15 +57,15 @@ var _ = Describe("Podman volume ls", func() {
}) })
It("podman ls volume with Go template", func() { It("podman ls volume with Go template", func() {
Skip("FIXME: table still not supported in podman volume command")
session := podmanTest.Podman([]string{"volume", "create", "myvol"}) session := podmanTest.Podman([]string{"volume", "create", "myvol"})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0)) Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"volume", "ls", "--format", "table {{.Name}} {{.Driver}} {{.Scope}}"}) session = podmanTest.Podman([]string{"volume", "ls", "--format", "table {{.Name}} {{.Driver}} {{.Scope}}"})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(2)) Expect(session).Should(Exit(0))
Expect(len(session.OutputToStringArray())).To(Equal(1), session.OutputToString())
}) })
It("podman ls volume with --filter flag", func() { It("podman ls volume with --filter flag", func() {