mirror of https://github.com/docker/compose.git
				
				
				
			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…
	
		Reference in New Issue