mirror of
https://github.com/docker/compose.git
synced 2025-07-26 07:04:32 +02:00
top: expose container labels
Signed-off-by: Dominik Menke <dom@digineo.de>
This commit is contained in:
parent
a766e1669a
commit
375a279785
@ -73,14 +73,23 @@ func runTop(ctx context.Context, dockerCli command.Cli, backend api.Service, opt
|
|||||||
func collectTop(containers []api.ContainerProcSummary) (topHeader, []topEntries) {
|
func collectTop(containers []api.ContainerProcSummary) (topHeader, []topEntries) {
|
||||||
// map column name to its header (should keep working if backend.Top returns
|
// map column name to its header (should keep working if backend.Top returns
|
||||||
// varying columns for different containers)
|
// varying columns for different containers)
|
||||||
header := topHeader{"SERVICE": 0}
|
header := topHeader{"SERVICE": 0, "#": 1}
|
||||||
|
|
||||||
// assume one process per container and grow if needed
|
// assume one process per container and grow if needed
|
||||||
entries := make([]topEntries, 0, len(containers))
|
entries := make([]topEntries, 0, len(containers))
|
||||||
|
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
for _, proc := range container.Processes {
|
for _, proc := range container.Processes {
|
||||||
entry := topEntries{"SERVICE": container.Name}
|
svc := container.Name
|
||||||
|
if tmp, ok := container.Labels[api.ServiceLabel]; ok {
|
||||||
|
svc = tmp
|
||||||
|
}
|
||||||
|
replica := "-"
|
||||||
|
if tmp, ok := container.Labels[api.ContainerNumberLabel]; ok {
|
||||||
|
replica = tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := topEntries{"SERVICE": svc, "#": replica}
|
||||||
|
|
||||||
for i, title := range container.Titles {
|
for i, title := range container.Titles {
|
||||||
if _, exists := header[title]; !exists {
|
if _, exists := header[title]; !exists {
|
||||||
|
@ -39,7 +39,7 @@ var topTestCases = []struct {
|
|||||||
name: "noprocs",
|
name: "noprocs",
|
||||||
titles: []string{"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"},
|
titles: []string{"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"},
|
||||||
procs: [][]string{},
|
procs: [][]string{},
|
||||||
header: topHeader{"SERVICE": 0},
|
header: topHeader{"SERVICE": 0, "#": 1},
|
||||||
entries: []topEntries{},
|
entries: []topEntries{},
|
||||||
output: "",
|
output: "",
|
||||||
},
|
},
|
||||||
@ -49,18 +49,20 @@ var topTestCases = []struct {
|
|||||||
procs: [][]string{{"root", "1", "1", "0", "12:00", "?", "00:00:01", "/entrypoint"}},
|
procs: [][]string{{"root", "1", "1", "0", "12:00", "?", "00:00:01", "/entrypoint"}},
|
||||||
header: topHeader{
|
header: topHeader{
|
||||||
"SERVICE": 0,
|
"SERVICE": 0,
|
||||||
"UID": 1,
|
"#": 1,
|
||||||
"PID": 2,
|
"UID": 2,
|
||||||
"PPID": 3,
|
"PID": 3,
|
||||||
"C": 4,
|
"PPID": 4,
|
||||||
"STIME": 5,
|
"C": 5,
|
||||||
"TTY": 6,
|
"STIME": 6,
|
||||||
"TIME": 7,
|
"TTY": 7,
|
||||||
"CMD": 8,
|
"TIME": 8,
|
||||||
|
"CMD": 9,
|
||||||
},
|
},
|
||||||
entries: []topEntries{
|
entries: []topEntries{
|
||||||
{
|
{
|
||||||
"SERVICE": "simple",
|
"SERVICE": "simple",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
"PPID": "1",
|
"PPID": "1",
|
||||||
@ -72,8 +74,8 @@ var topTestCases = []struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: trim(`
|
output: trim(`
|
||||||
SERVICE UID PID PPID C STIME TTY TIME CMD
|
SERVICE # UID PID PPID C STIME TTY TIME CMD
|
||||||
simple root 1 1 0 12:00 ? 00:00:01 /entrypoint
|
simple 1 root 1 1 0 12:00 ? 00:00:01 /entrypoint
|
||||||
`),
|
`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -82,17 +84,19 @@ var topTestCases = []struct {
|
|||||||
procs: [][]string{{"root", "1", "0", "12:00", "?", "00:00:02", "/entrypoint"}},
|
procs: [][]string{{"root", "1", "0", "12:00", "?", "00:00:02", "/entrypoint"}},
|
||||||
header: topHeader{
|
header: topHeader{
|
||||||
"SERVICE": 0,
|
"SERVICE": 0,
|
||||||
"UID": 1,
|
"#": 1,
|
||||||
"PID": 2,
|
"UID": 2,
|
||||||
"C": 3,
|
"PID": 3,
|
||||||
"STIME": 4,
|
"C": 4,
|
||||||
"TTY": 5,
|
"STIME": 5,
|
||||||
"TIME": 6,
|
"TTY": 6,
|
||||||
"CMD": 7,
|
"TIME": 7,
|
||||||
|
"CMD": 8,
|
||||||
},
|
},
|
||||||
entries: []topEntries{
|
entries: []topEntries{
|
||||||
{
|
{
|
||||||
"SERVICE": "noppid",
|
"SERVICE": "noppid",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
"C": "0",
|
"C": "0",
|
||||||
@ -103,8 +107,8 @@ var topTestCases = []struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: trim(`
|
output: trim(`
|
||||||
SERVICE UID PID C STIME TTY TIME CMD
|
SERVICE # UID PID C STIME TTY TIME CMD
|
||||||
noppid root 1 0 12:00 ? 00:00:02 /entrypoint
|
noppid 1 root 1 0 12:00 ? 00:00:02 /entrypoint
|
||||||
`),
|
`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -113,19 +117,21 @@ var topTestCases = []struct {
|
|||||||
procs: [][]string{{"root", "1", "1", "1", "0", "12:00", "?", "00:00:03", "/entrypoint"}},
|
procs: [][]string{{"root", "1", "1", "1", "0", "12:00", "?", "00:00:03", "/entrypoint"}},
|
||||||
header: topHeader{
|
header: topHeader{
|
||||||
"SERVICE": 0,
|
"SERVICE": 0,
|
||||||
"UID": 1,
|
"#": 1,
|
||||||
"GID": 2,
|
"UID": 2,
|
||||||
"PID": 3,
|
"GID": 3,
|
||||||
"PPID": 4,
|
"PID": 4,
|
||||||
"C": 5,
|
"PPID": 5,
|
||||||
"STIME": 6,
|
"C": 6,
|
||||||
"TTY": 7,
|
"STIME": 7,
|
||||||
"TIME": 8,
|
"TTY": 8,
|
||||||
"CMD": 9,
|
"TIME": 9,
|
||||||
|
"CMD": 10,
|
||||||
},
|
},
|
||||||
entries: []topEntries{
|
entries: []topEntries{
|
||||||
{
|
{
|
||||||
"SERVICE": "extra-hdr",
|
"SERVICE": "extra-hdr",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"GID": "1",
|
"GID": "1",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
@ -138,8 +144,8 @@ var topTestCases = []struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: trim(`
|
output: trim(`
|
||||||
SERVICE UID GID PID PPID C STIME TTY TIME CMD
|
SERVICE # UID GID PID PPID C STIME TTY TIME CMD
|
||||||
extra-hdr root 1 1 1 0 12:00 ? 00:00:03 /entrypoint
|
extra-hdr 1 root 1 1 1 0 12:00 ? 00:00:03 /entrypoint
|
||||||
`),
|
`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -151,18 +157,20 @@ var topTestCases = []struct {
|
|||||||
},
|
},
|
||||||
header: topHeader{
|
header: topHeader{
|
||||||
"SERVICE": 0,
|
"SERVICE": 0,
|
||||||
"UID": 1,
|
"#": 1,
|
||||||
"PID": 2,
|
"UID": 2,
|
||||||
"PPID": 3,
|
"PID": 3,
|
||||||
"C": 4,
|
"PPID": 4,
|
||||||
"STIME": 5,
|
"C": 5,
|
||||||
"TTY": 6,
|
"STIME": 6,
|
||||||
"TIME": 7,
|
"TTY": 7,
|
||||||
"CMD": 8,
|
"TIME": 8,
|
||||||
|
"CMD": 9,
|
||||||
},
|
},
|
||||||
entries: []topEntries{
|
entries: []topEntries{
|
||||||
{
|
{
|
||||||
"SERVICE": "multiple",
|
"SERVICE": "multiple",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
"PPID": "1",
|
"PPID": "1",
|
||||||
@ -174,6 +182,7 @@ var topTestCases = []struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"SERVICE": "multiple",
|
"SERVICE": "multiple",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "123",
|
"PID": "123",
|
||||||
"PPID": "1",
|
"PPID": "1",
|
||||||
@ -185,9 +194,9 @@ var topTestCases = []struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: trim(`
|
output: trim(`
|
||||||
SERVICE UID PID PPID C STIME TTY TIME CMD
|
SERVICE # UID PID PPID C STIME TTY TIME CMD
|
||||||
multiple root 1 1 0 12:00 ? 00:00:04 /entrypoint
|
multiple 1 root 1 1 0 12:00 ? 00:00:04 /entrypoint
|
||||||
multiple root 123 1 0 12:00 ? 00:00:42 sleep infinity
|
multiple 1 root 123 1 0 12:00 ? 00:00:42 sleep infinity
|
||||||
`),
|
`),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -201,9 +210,13 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range topTestCases {
|
for _, tc := range topTestCases {
|
||||||
summary := api.ContainerProcSummary{
|
summary := api.ContainerProcSummary{
|
||||||
Name: tc.name,
|
Name: "not used",
|
||||||
Titles: tc.titles,
|
Titles: tc.titles,
|
||||||
Processes: tc.procs,
|
Processes: tc.procs,
|
||||||
|
Labels: map[string]string{
|
||||||
|
api.ServiceLabel: tc.name,
|
||||||
|
api.ContainerNumberLabel: "1",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
all = append(all, summary)
|
all = append(all, summary)
|
||||||
|
|
||||||
@ -224,19 +237,21 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
header, entries := collectTop(all)
|
header, entries := collectTop(all)
|
||||||
assert.EqualValues(t, topHeader{
|
assert.EqualValues(t, topHeader{
|
||||||
"SERVICE": 0,
|
"SERVICE": 0,
|
||||||
"UID": 1,
|
"#": 1,
|
||||||
"PID": 2,
|
"UID": 2,
|
||||||
"PPID": 3,
|
"PID": 3,
|
||||||
"C": 4,
|
"PPID": 4,
|
||||||
"STIME": 5,
|
"C": 5,
|
||||||
"TTY": 6,
|
"STIME": 6,
|
||||||
"TIME": 7,
|
"TTY": 7,
|
||||||
"CMD": 8,
|
"TIME": 8,
|
||||||
"GID": 9,
|
"CMD": 9,
|
||||||
|
"GID": 10,
|
||||||
}, header)
|
}, header)
|
||||||
assert.EqualValues(t, []topEntries{
|
assert.EqualValues(t, []topEntries{
|
||||||
{
|
{
|
||||||
"SERVICE": "simple",
|
"SERVICE": "simple",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
"PPID": "1",
|
"PPID": "1",
|
||||||
@ -247,6 +262,7 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
"CMD": "/entrypoint",
|
"CMD": "/entrypoint",
|
||||||
}, {
|
}, {
|
||||||
"SERVICE": "noppid",
|
"SERVICE": "noppid",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
"C": "0",
|
"C": "0",
|
||||||
@ -256,6 +272,7 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
"CMD": "/entrypoint",
|
"CMD": "/entrypoint",
|
||||||
}, {
|
}, {
|
||||||
"SERVICE": "extra-hdr",
|
"SERVICE": "extra-hdr",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"GID": "1",
|
"GID": "1",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
@ -267,6 +284,7 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
"CMD": "/entrypoint",
|
"CMD": "/entrypoint",
|
||||||
}, {
|
}, {
|
||||||
"SERVICE": "multiple",
|
"SERVICE": "multiple",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "1",
|
"PID": "1",
|
||||||
"PPID": "1",
|
"PPID": "1",
|
||||||
@ -277,6 +295,7 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
"CMD": "/entrypoint",
|
"CMD": "/entrypoint",
|
||||||
}, {
|
}, {
|
||||||
"SERVICE": "multiple",
|
"SERVICE": "multiple",
|
||||||
|
"#": "1",
|
||||||
"UID": "root",
|
"UID": "root",
|
||||||
"PID": "123",
|
"PID": "123",
|
||||||
"PPID": "1",
|
"PPID": "1",
|
||||||
@ -292,12 +311,12 @@ func TestRunTopCore(t *testing.T) {
|
|||||||
err := topPrint(&buf, header, entries)
|
err := topPrint(&buf, header, entries)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, trim(`
|
assert.Equal(t, trim(`
|
||||||
SERVICE UID PID PPID C STIME TTY TIME CMD GID
|
SERVICE # UID PID PPID C STIME TTY TIME CMD GID
|
||||||
simple root 1 1 0 12:00 ? 00:00:01 /entrypoint -
|
simple 1 root 1 1 0 12:00 ? 00:00:01 /entrypoint -
|
||||||
noppid root 1 - 0 12:00 ? 00:00:02 /entrypoint -
|
noppid 1 root 1 - 0 12:00 ? 00:00:02 /entrypoint -
|
||||||
extra-hdr root 1 1 0 12:00 ? 00:00:03 /entrypoint 1
|
extra-hdr 1 root 1 1 0 12:00 ? 00:00:03 /entrypoint 1
|
||||||
multiple root 1 1 0 12:00 ? 00:00:04 /entrypoint -
|
multiple 1 root 1 1 0 12:00 ? 00:00:04 /entrypoint -
|
||||||
multiple root 123 1 0 12:00 ? 00:00:42 sleep infinity -
|
multiple 1 root 123 1 0 12:00 ? 00:00:42 sleep infinity -
|
||||||
`), buf.String())
|
`), buf.String())
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -523,6 +523,7 @@ type ContainerProcSummary struct {
|
|||||||
Name string
|
Name string
|
||||||
Processes [][]string
|
Processes [][]string
|
||||||
Titles []string
|
Titles []string
|
||||||
|
Labels map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageSummary holds container image description
|
// ImageSummary holds container image description
|
||||||
|
@ -47,6 +47,7 @@ func (s *composeService) Top(ctx context.Context, projectName string, services [
|
|||||||
Name: getCanonicalContainerName(ctr),
|
Name: getCanonicalContainerName(ctr),
|
||||||
Processes: topContent.Processes,
|
Processes: topContent.Processes,
|
||||||
Titles: topContent.Titles,
|
Titles: topContent.Titles,
|
||||||
|
Labels: container.Labels,
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user