mirror of
https://github.com/containers/podman.git
synced 2025-05-21 09:05:56 +08:00
Merge pull request #11639 from jwhonce/issues/2221
Support --format tables in ps output
This commit is contained in:
@ -221,7 +221,10 @@ func ps(cmd *cobra.Command, _ []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdrs, format := createPsOut()
|
hdrs, format := createPsOut()
|
||||||
|
|
||||||
|
noHeading, _ := cmd.Flags().GetBool("noheading")
|
||||||
if cmd.Flags().Changed("format") {
|
if cmd.Flags().Changed("format") {
|
||||||
|
noHeading = noHeading || !report.HasTable(listOpts.Format)
|
||||||
format = report.NormalizeFormat(listOpts.Format)
|
format = report.NormalizeFormat(listOpts.Format)
|
||||||
format = report.EnforceRange(format)
|
format = report.EnforceRange(format)
|
||||||
}
|
}
|
||||||
@ -240,8 +243,7 @@ func ps(cmd *cobra.Command, _ []string) error {
|
|||||||
defer w.Flush()
|
defer w.Flush()
|
||||||
|
|
||||||
headers := func() error { return nil }
|
headers := func() error { return nil }
|
||||||
noHeading, _ := cmd.Flags().GetBool("noheading")
|
if !noHeading {
|
||||||
if !(noHeading || listOpts.Quiet || cmd.Flags().Changed("format")) {
|
|
||||||
headers = func() error {
|
headers = func() error {
|
||||||
return tmpl.Execute(w, hdrs)
|
return tmpl.Execute(w, hdrs)
|
||||||
}
|
}
|
||||||
@ -298,9 +300,11 @@ func createPsOut() ([]map[string]string, string) {
|
|||||||
"IPC": "ipc",
|
"IPC": "ipc",
|
||||||
"MNT": "mnt",
|
"MNT": "mnt",
|
||||||
"NET": "net",
|
"NET": "net",
|
||||||
|
"Networks": "networks",
|
||||||
"PIDNS": "pidns",
|
"PIDNS": "pidns",
|
||||||
"Pod": "pod id",
|
"Pod": "pod id",
|
||||||
"PodName": "podname", // undo camelcase space break
|
"PodName": "podname", // undo camelcase space break
|
||||||
|
"RunningFor": "running for",
|
||||||
"UTS": "uts",
|
"UTS": "uts",
|
||||||
"User": "userns",
|
"User": "userns",
|
||||||
})
|
})
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
. "github.com/containers/podman/v3/test/utils"
|
. "github.com/containers/podman/v3/test/utils"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
@ -187,7 +186,10 @@ var _ = Describe("Podman ps", func() {
|
|||||||
result.WaitWithDefaultTimeout()
|
result.WaitWithDefaultTimeout()
|
||||||
result.WaitWithDefaultTimeout()
|
result.WaitWithDefaultTimeout()
|
||||||
Expect(result).Should(Exit(0))
|
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() {
|
It("podman ps --filter network=container:<id>", func() {
|
||||||
@ -206,7 +208,9 @@ var _ = Describe("Podman ps", func() {
|
|||||||
result.WaitWithDefaultTimeout()
|
result.WaitWithDefaultTimeout()
|
||||||
result.WaitWithDefaultTimeout()
|
result.WaitWithDefaultTimeout()
|
||||||
Expect(result).Should(Exit(0))
|
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() {
|
It("podman ps namespace flag", func() {
|
||||||
@ -228,7 +232,7 @@ var _ = Describe("Podman ps", func() {
|
|||||||
result.WaitWithDefaultTimeout()
|
result.WaitWithDefaultTimeout()
|
||||||
Expect(result).Should(Exit(0))
|
Expect(result).Should(Exit(0))
|
||||||
// it must contains `::` when some ns is null. If it works normally, it should be "$num1:$num2:$num3"
|
// 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() {
|
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 := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.ID}} {{.Image}} {{.ImageID}} {{.Labels}}"})
|
||||||
result.WaitWithDefaultTimeout()
|
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).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() {
|
It("podman ps ancestor filter flag", func() {
|
||||||
@ -380,7 +387,9 @@ var _ = Describe("Podman ps", func() {
|
|||||||
psFilter.WaitWithDefaultTimeout()
|
psFilter.WaitWithDefaultTimeout()
|
||||||
Expect(psFilter).Should(Exit(0))
|
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() {
|
It("podman ps mutually exclusive flags", func() {
|
||||||
@ -453,14 +462,13 @@ var _ = Describe("Podman ps", func() {
|
|||||||
Expect(session).Should(Exit(0))
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
session = podmanTest.Podman([]string{"ps", "-a", "--sort=command", "--format", "{{.Command}}"})
|
session = podmanTest.Podman([]string{"ps", "-a", "--sort=command", "--format", "{{.Command}}"})
|
||||||
|
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(Exit(0))
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
Expect(session.OutputToString()).ToNot(ContainSubstring("COMMAND"))
|
||||||
|
|
||||||
sortedArr := session.OutputToStringArray()
|
sortedArr := session.OutputToStringArray()
|
||||||
|
|
||||||
Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue())
|
Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue())
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman --pod", func() {
|
It("podman --pod", func() {
|
||||||
@ -474,7 +482,7 @@ var _ = Describe("Podman ps", func() {
|
|||||||
session = podmanTest.Podman([]string{"ps", "--no-trunc"})
|
session = podmanTest.Podman([]string{"ps", "--no-trunc"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(Exit(0))
|
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 = podmanTest.Podman([]string{"ps", "--pod", "--no-trunc"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
@ -510,7 +518,11 @@ var _ = Describe("Podman ps", func() {
|
|||||||
|
|
||||||
session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"})
|
session = podmanTest.Podman([]string{"ps", "--format", "{{.Ports}}"})
|
||||||
session.WaitWithDefaultTimeout()
|
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() {
|
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 := podmanTest.Podman([]string{"ps", "-a", "--format", "{{.RunningFor}}"})
|
||||||
result.WaitWithDefaultTimeout()
|
result.WaitWithDefaultTimeout()
|
||||||
Expect(result).Should(Exit(0))
|
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() {
|
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 = podmanTest.Podman([]string{"ps", "--all", "--no-trunc", "--filter", "network=" + net})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(Exit(0))
|
Expect(session).Should(Exit(0))
|
||||||
Expect(session.OutputToString()).To(ContainSubstring(ctrWithNet))
|
actual := session.OutputToString()
|
||||||
Expect(session.OutputToString()).To(Not(ContainSubstring(ctrWithoutNet)))
|
Expect(actual).To(ContainSubstring(ctrWithNet))
|
||||||
|
Expect(actual).ToNot(ContainSubstring(ctrWithoutNet))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman ps --format networks", func() {
|
It("podman ps --format networks", func() {
|
||||||
@ -835,12 +851,15 @@ var _ = Describe("Podman ps", func() {
|
|||||||
session = podmanTest.Podman([]string{"ps", "--all", "--format", "{{ .Networks }}"})
|
session = podmanTest.Podman([]string{"ps", "--all", "--format", "{{ .Networks }}"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(Exit(0))
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
actual := session.OutputToString()
|
||||||
|
Expect(actual).ToNot(ContainSubstring("NETWORKS"))
|
||||||
if isRootless() {
|
if isRootless() {
|
||||||
// rootless container don't have a network by default
|
// rootless container don't have a network by default
|
||||||
Expect(session.OutputToString()).To(Equal(""))
|
Expect(actual).To(BeEmpty())
|
||||||
} else {
|
} else {
|
||||||
// default network name is podman
|
// default network name is podman
|
||||||
Expect(session.OutputToString()).To(Equal("podman"))
|
Expect(actual).To(Equal("podman"))
|
||||||
}
|
}
|
||||||
|
|
||||||
net1 := stringid.GenerateNonCryptoID()
|
net1 := stringid.GenerateNonCryptoID()
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultWaitTimeout = 90
|
DefaultWaitTimeout = 90
|
||||||
OSReleasePath = "/etc/os-release"
|
OSReleasePath = "/etc/os-release"
|
||||||
ProcessOneCgroupPath = "/proc/1/cgroup"
|
ProcessOneCgroupPath = "/proc/1/cgroup"
|
||||||
)
|
)
|
||||||
@ -317,15 +317,20 @@ func (s *PodmanSession) IsJSONOutputValid() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitWithDefaultTimeout waits for process finished with defaultWaitTimeout
|
// WaitWithDefaultTimeout waits for process finished with DefaultWaitTimeout
|
||||||
func (s *PodmanSession) WaitWithDefaultTimeout() {
|
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.Stdout.Sync()
|
||||||
os.Stderr.Sync()
|
os.Stderr.Sync()
|
||||||
fmt.Println("output:", s.OutputToString())
|
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) {
|
func CreateTempDirInTempDir() (string, error) {
|
||||||
return ioutil.TempDir("", "podman_test")
|
return ioutil.TempDir("", "podman_test")
|
||||||
}
|
}
|
||||||
@ -337,7 +342,7 @@ func SystemExec(command string, args []string) *PodmanSession {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
|
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
|
||||||
}
|
}
|
||||||
session.Wait(defaultWaitTimeout)
|
session.Wait(DefaultWaitTimeout)
|
||||||
return &PodmanSession{session}
|
return &PodmanSession{session}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user