Merge pull request #11639 from jwhonce/issues/2221

Support --format tables in ps output
This commit is contained in:
OpenShift Merge Robot 2021-09-20 18:39:36 -04:00 committed by GitHub
commit b925d707fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 26 deletions

View file

@ -221,7 +221,10 @@ func ps(cmd *cobra.Command, _ []string) error {
}
hdrs, format := createPsOut()
noHeading, _ := cmd.Flags().GetBool("noheading")
if cmd.Flags().Changed("format") {
noHeading = noHeading || !report.HasTable(listOpts.Format)
format = report.NormalizeFormat(listOpts.Format)
format = report.EnforceRange(format)
}
@ -240,8 +243,7 @@ func ps(cmd *cobra.Command, _ []string) error {
defer w.Flush()
headers := func() error { return nil }
noHeading, _ := cmd.Flags().GetBool("noheading")
if !(noHeading || listOpts.Quiet || cmd.Flags().Changed("format")) {
if !noHeading {
headers = func() error {
return tmpl.Execute(w, hdrs)
}
@ -298,9 +300,11 @@ func createPsOut() ([]map[string]string, string) {
"IPC": "ipc",
"MNT": "mnt",
"NET": "net",
"Networks": "networks",
"PIDNS": "pidns",
"Pod": "pod id",
"PodName": "podname", // undo camelcase space break
"RunningFor": "running for",
"UTS": "uts",
"User": "userns",
})

View file

@ -6,7 +6,6 @@ import (
"regexp"
"sort"
"strconv"
"strings"
. "github.com/containers/podman/v3/test/utils"
"github.com/containers/storage/pkg/stringid"
@ -187,7 +186,10 @@ var _ = Describe("Podman ps", func() {
result.WaitWithDefaultTimeout()
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(result.OutputToString()).To(ContainSubstring("bravo"))
actual := result.OutputToString()
Expect(actual).To(ContainSubstring("bravo"))
Expect(actual).To(ContainSubstring("NAMES"))
})
It("podman ps --filter network=container:<id>", func() {
@ -206,7 +208,9 @@ var _ = Describe("Podman ps", func() {
result.WaitWithDefaultTimeout()
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(result.OutputToString()).To(ContainSubstring("second"))
actual := result.OutputToString()
Expect(actual).To(ContainSubstring("second"))
Expect(actual).ToNot(ContainSubstring("table"))
})
It("podman ps namespace flag", func() {
@ -228,7 +232,7 @@ var _ = Describe("Podman ps", func() {
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
// it must contains `::` when some ns is null. If it works normally, it should be "$num1:$num2:$num3"
Expect(result.OutputToString()).To(Not(ContainSubstring(`::`)))
Expect(result.OutputToString()).ToNot(ContainSubstring(`::`))
})
It("podman ps with no containers is valid json format", func() {
@ -285,11 +289,14 @@ var _ = Describe("Podman ps", func() {
result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.ID}} {{.Image}} {{.ImageID}} {{.Labels}}"})
result.WaitWithDefaultTimeout()
Expect(result.OutputToStringArray()[0]).ToNot(ContainSubstring("table"))
Expect(result.OutputToStringArray()[0]).ToNot(ContainSubstring("ImageID"))
Expect(result.OutputToStringArray()[0]).To(ContainSubstring("alpine:latest"))
Expect(result).Should(Exit(0))
Expect(result.OutputToString()).ToNot(ContainSubstring("table"))
actual := result.OutputToStringArray()
Expect(actual[0]).To(ContainSubstring("CONTAINER ID"))
Expect(actual[0]).ToNot(ContainSubstring("ImageID"))
Expect(actual[1]).To(ContainSubstring("alpine:latest"))
})
It("podman ps ancestor filter flag", func() {
@ -380,7 +387,9 @@ var _ = Describe("Podman ps", func() {
psFilter.WaitWithDefaultTimeout()
Expect(psFilter).Should(Exit(0))
Expect(strings.Contains(psFilter.OutputToString(), ctrName)).To(BeFalse())
actual := psFilter.OutputToString()
Expect(actual).ToNot(ContainSubstring(ctrName))
Expect(actual).ToNot(ContainSubstring("NAMES"))
})
It("podman ps mutually exclusive flags", func() {
@ -453,14 +462,13 @@ var _ = Describe("Podman ps", func() {
Expect(session).Should(Exit(0))
session = podmanTest.Podman([]string{"ps", "-a", "--sort=command", "--format", "{{.Command}}"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).ToNot(ContainSubstring("COMMAND"))
sortedArr := session.OutputToStringArray()
Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue())
})
It("podman --pod", func() {
@ -474,7 +482,7 @@ var _ = Describe("Podman ps", func() {
session = podmanTest.Podman([]string{"ps", "--no-trunc"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(Not(ContainSubstring(podid)))
Expect(session.OutputToString()).ToNot(ContainSubstring(podid))
session = podmanTest.Podman([]string{"ps", "--pod", "--no-trunc"})
session.WaitWithDefaultTimeout()
@ -510,7 +518,11 @@ var _ = Describe("Podman ps", func() {
session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"})
session.WaitWithDefaultTimeout()
Expect(session.OutputToString()).To(ContainSubstring("0.0.0.0:2000-2006"))
Expect(session).To(Exit(0))
actual := session.OutputToString()
Expect(actual).To(ContainSubstring("0.0.0.0:2000-2006"))
Expect(actual).ToNot(ContainSubstring("PORT"))
})
It("podman ps test with invalid port range", func() {
@ -628,7 +640,10 @@ var _ = Describe("Podman ps", func() {
result := podmanTest.Podman([]string{"ps", "-a", "--format", "{{.RunningFor}}"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(result.OutputToString()).To(ContainSubstring("ago"))
actual := result.OutputToString()
Expect(actual).To(ContainSubstring("ago"))
Expect(actual).ToNot(ContainSubstring("RUNNING FOR"))
})
It("podman ps filter test", func() {
@ -823,8 +838,9 @@ var _ = Describe("Podman ps", func() {
session = podmanTest.Podman([]string{"ps", "--all", "--no-trunc", "--filter", "network=" + net})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring(ctrWithNet))
Expect(session.OutputToString()).To(Not(ContainSubstring(ctrWithoutNet)))
actual := session.OutputToString()
Expect(actual).To(ContainSubstring(ctrWithNet))
Expect(actual).ToNot(ContainSubstring(ctrWithoutNet))
})
It("podman ps --format networks", func() {
@ -835,12 +851,15 @@ var _ = Describe("Podman ps", func() {
session = podmanTest.Podman([]string{"ps", "--all", "--format", "{{ .Networks }}"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
actual := session.OutputToString()
Expect(actual).ToNot(ContainSubstring("NETWORKS"))
if isRootless() {
// rootless container don't have a network by default
Expect(session.OutputToString()).To(Equal(""))
Expect(actual).To(BeEmpty())
} else {
// default network name is podman
Expect(session.OutputToString()).To(Equal("podman"))
Expect(actual).To(Equal("podman"))
}
net1 := stringid.GenerateNonCryptoID()

View file

@ -19,7 +19,7 @@ import (
)
var (
defaultWaitTimeout = 90
DefaultWaitTimeout = 90
OSReleasePath = "/etc/os-release"
ProcessOneCgroupPath = "/proc/1/cgroup"
)
@ -317,15 +317,20 @@ func (s *PodmanSession) IsJSONOutputValid() bool {
return true
}
// WaitWithDefaultTimeout waits for process finished with defaultWaitTimeout
// WaitWithDefaultTimeout waits for process finished with DefaultWaitTimeout
func (s *PodmanSession) WaitWithDefaultTimeout() {
Eventually(s, defaultWaitTimeout).Should(Exit())
s.WaitWithTimeout(DefaultWaitTimeout)
}
// WaitWithTimeout waits for process finished with DefaultWaitTimeout
func (s *PodmanSession) WaitWithTimeout(timeout int) {
Eventually(s, timeout).Should(Exit())
os.Stdout.Sync()
os.Stderr.Sync()
fmt.Println("output:", s.OutputToString())
}
// CreateTempDirinTempDir create a temp dir with prefix podman_test
// CreateTempDirInTempDir create a temp dir with prefix podman_test
func CreateTempDirInTempDir() (string, error) {
return ioutil.TempDir("", "podman_test")
}
@ -337,7 +342,7 @@ func SystemExec(command string, args []string) *PodmanSession {
if err != nil {
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
}
session.Wait(defaultWaitTimeout)
session.Wait(DefaultWaitTimeout)
return &PodmanSession{session}
}