mirror of
https://github.com/containers/podman.git
synced 2026-05-24 16:40:44 -04:00
ps: format labels as comma separated key=value for Docker compatibility
Fixes: https://github.com/containers/podman/issues/21847 Signed-off-by: Jan Rodák <hony.com@seznam.cz>
This commit is contained in:
21
cmd/podman/common/format.go
Normal file
21
cmd/podman/common/format.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FormatLabels converts a map of labels to a sorted, comma-separated list
|
||||
// of key=value pairs, matching Docker CLI output format.
|
||||
func FormatLabels(labels map[string]string) string {
|
||||
keys := make([]string, 0, len(labels))
|
||||
for k := range labels {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
slices.Sort(keys)
|
||||
list := make([]string, 0, len(keys))
|
||||
for _, k := range keys {
|
||||
list = append(list, k+"="+labels[k])
|
||||
}
|
||||
return strings.Join(list, ",")
|
||||
}
|
||||
@@ -342,7 +342,13 @@ func (l psReporter) ImageID() string {
|
||||
return l.ListContainer.ImageID
|
||||
}
|
||||
|
||||
// Label returns a map of the pod's labels
|
||||
// Labels returns the container's labels as a sorted, comma-separated list of
|
||||
// key=value pairs, matching Docker CLI output format.
|
||||
func (l psReporter) Labels() string {
|
||||
return common.FormatLabels(l.ListContainer.Labels)
|
||||
}
|
||||
|
||||
// Label returns the value of a single container label by name.
|
||||
func (l psReporter) Label(name string) string {
|
||||
return l.ListContainer.Labels[name]
|
||||
}
|
||||
|
||||
@@ -194,9 +194,10 @@ func (l ListPodReporter) Created() string {
|
||||
return units.HumanDuration(time.Since(l.ListPodsReport.Created)) + " ago"
|
||||
}
|
||||
|
||||
// Labels returns a map of the pod's labels
|
||||
func (l ListPodReporter) Labels() map[string]string {
|
||||
return l.ListPodsReport.Labels
|
||||
// Labels returns the pod's labels as a sorted, comma-separated list of
|
||||
// key=value pairs, matching Docker CLI output format.
|
||||
func (l ListPodReporter) Labels() string {
|
||||
return common.FormatLabels(l.ListPodsReport.Labels)
|
||||
}
|
||||
|
||||
// Label returns a map of the pod's labels
|
||||
|
||||
@@ -58,7 +58,7 @@ Valid placeholders for the Go template are listed below:
|
||||
| .ID | Container ID |
|
||||
| .InfraID | Pod infra container ID |
|
||||
| .Label *string* | Specified label of the pod |
|
||||
| .Labels ... | All the labels assigned to the pod |
|
||||
| .Labels | All the labels assigned to the pod |
|
||||
| .Name | Name of pod |
|
||||
| .Networks | Show all networks connected to the infra container |
|
||||
| .NumberOfContainers | Show the number of containers attached to pod |
|
||||
|
||||
@@ -61,7 +61,7 @@ Valid placeholders for the Go template are listed below:
|
||||
| .ImageID | Image ID |
|
||||
| .IsInfra | "true" if infra container |
|
||||
| .Label *string* | Specified label of the container |
|
||||
| .Labels ... | All the labels assigned to the container |
|
||||
| .Labels | All the labels assigned to the container |
|
||||
| .Mounts | Volumes mounted in the container |
|
||||
| .Names | Name of container |
|
||||
| .Networks | Show all networks connected to the container |
|
||||
|
||||
@@ -239,6 +239,43 @@ load helpers
|
||||
run_podman pod rm -t 0 -f test
|
||||
}
|
||||
|
||||
@test "podman ps --format json Labels is a string" {
|
||||
rand_value=$(random_string 10)
|
||||
|
||||
run_podman run -d --label mylabel=$rand_value $IMAGE sleep inf
|
||||
cid=$output
|
||||
|
||||
# {{json .Labels}} should produce a JSON string ("key=val,..."), not a JSON object
|
||||
run_podman ps --format '{{json .Labels}}'
|
||||
assert "$output" =~ "\".*mylabel=${rand_value}.*\"" "json .Labels should be a quoted string, not a JSON object"
|
||||
assert "$output" !~ "{" "json .Labels should not contain braces (not a JSON object)"
|
||||
|
||||
# Plain {{.Labels}} should produce key=value format
|
||||
run_podman ps --format '{{.Labels}}'
|
||||
assert "$output" =~ "mylabel=${rand_value}" ".Labels should contain key=value pair"
|
||||
assert "$output" !~ "map\[" ".Labels should not use Go map format"
|
||||
|
||||
run_podman rm -t 0 -f $cid
|
||||
}
|
||||
|
||||
@test "podman pod ps --format json Labels is a string" {
|
||||
rand_value=$(random_string 10)
|
||||
|
||||
run_podman pod create --label mylabel=${rand_value} test
|
||||
|
||||
# {{json .Labels}} should produce a JSON string, not a JSON object
|
||||
run_podman pod ps --format '{{json .Labels}}'
|
||||
assert "$output" =~ "\".*mylabel=${rand_value}.*\"" "json .Labels should be a quoted string, not a JSON object"
|
||||
assert "$output" !~ "{" "json .Labels should not contain braces (not a JSON object)"
|
||||
|
||||
# Plain {{.Labels}} should produce key=value format
|
||||
run_podman pod ps --format '{{.Labels}}'
|
||||
assert "$output" =~ "mylabel=${rand_value}" ".Labels should contain key=value pair"
|
||||
assert "$output" !~ "map\[" ".Labels should not use Go map format"
|
||||
|
||||
run_podman pod rm -t 0 -f test
|
||||
}
|
||||
|
||||
@test "podman ps --format PodName" {
|
||||
rand_value=$(random_string 10)
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ EOF
|
||||
|
||||
# pod ps
|
||||
run_podman pod ps --format '{{.ID}} {{.Name}} {{.Status}} {{.Labels}}'
|
||||
assert "$output" =~ "${pod_id:0:12} $podname Running map\[${labelname}:${labelvalue}]" "pod ps"
|
||||
assert "$output" =~ "${pod_id:0:12} $podname Running ${labelname}=${labelvalue}" "pod ps"
|
||||
|
||||
run_podman pod ps --no-trunc --filter "label=${labelname}=${labelvalue}" --format '{{.ID}}'
|
||||
is "$output" "$pod_id" "pod ps --filter label=..."
|
||||
|
||||
@@ -213,10 +213,10 @@ EOF
|
||||
|
||||
@test "ps -a : shows all containers" {
|
||||
run_podman ps -a \
|
||||
--format '{{.Names}}--{{.Status}}--{{.Ports}}--{{.Labels.mylabel}}' \
|
||||
--format '{{.Names}}--{{.Status}}--{{.Ports}}--{{.Label "mylabel"}}' \
|
||||
--sort=created
|
||||
assert "${lines[0]}" == "mycreatedcontainer--Created----$LABEL_CREATED" "line 0, created"
|
||||
assert "${lines[1]}" =~ "mydonecontainer--Exited \(0\).*----<no value>" "line 1, done"
|
||||
assert "${lines[1]}" =~ "mydonecontainer--Exited \(0\).*----" "line 1, done"
|
||||
assert "${lines[2]}" =~ "myfailedcontainer--Exited \(17\) .*----$LABEL_FAILED" "line 2, fail"
|
||||
|
||||
# Port order is not guaranteed
|
||||
@@ -224,7 +224,7 @@ EOF
|
||||
assert "${lines[3]}" =~ ".*--.*0\.0\.0\.0:$HOST_PORT->80\/tcp.*--.*" "line 3, first port forward"
|
||||
assert "${lines[3]}" =~ ".*--.*127\.0\.0\.1\:9090-9092->8080-8082\/tcp.*--.*" "line 3, second port forward"
|
||||
|
||||
assert "${lines[4]}" =~ ".*-infra--Created----<no value>" "line 4, infra container"
|
||||
assert "${lines[4]}" =~ ".*-infra--Created----" "line 4, infra container"
|
||||
|
||||
# For debugging: dump containers and IDs
|
||||
if [[ -n "$PODMAN_UPGRADE_TEST_DEBUG" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user