From 3372df1506d4288d3f6c5e1b4812eccaa4bdb1b0 Mon Sep 17 00:00:00 2001 From: YaoZengzeng Date: Tue, 25 Sep 2018 13:58:43 +0800 Subject: [PATCH] bugfix: only list container stats which are created by cri Signed-off-by: YaoZengzeng --- cri/v1alpha1/cri.go | 13 ++++++++ cri/v1alpha1/cri_utils.go | 14 ++++++++ cri/v1alpha1/cri_utils_test.go | 61 ++++++++++++++++++++++++++++++++++ cri/v1alpha2/cri.go | 13 ++++++++ cri/v1alpha2/cri_utils.go | 14 ++++++++ cri/v1alpha2/cri_utils_test.go | 61 ++++++++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+) diff --git a/cri/v1alpha1/cri.go b/cri/v1alpha1/cri.go index 5dda38b2b6..51d055cf4d 100644 --- a/cri/v1alpha1/cri.go +++ b/cri/v1alpha1/cri.go @@ -822,6 +822,19 @@ func (c *CriManager) ContainerStats(ctx context.Context, r *runtime.ContainerSta func (c *CriManager) ListContainerStats(ctx context.Context, r *runtime.ListContainerStatsRequest) (*runtime.ListContainerStatsResponse, error) { opts := &mgr.ContainerListOption{All: true} filter := func(c *mgr.Container) bool { + if c.Config.Labels[containerTypeLabelKey] != containerTypeLabelContainer { + return false + } + if r.GetFilter().GetId() != "" && c.ID != r.GetFilter().GetId() { + return false + } + if r.GetFilter().GetPodSandboxId() != "" && c.Config.Labels[sandboxIDLabelKey] != r.GetFilter().GetPodSandboxId() { + return false + } + if r.GetFilter().GetLabelSelector() != nil && + !matchLabelSelector(r.GetFilter().GetLabelSelector(), c.Config.Labels) { + return false + } return true } opts.FilterFunc = filter diff --git a/cri/v1alpha1/cri_utils.go b/cri/v1alpha1/cri_utils.go index 9d4679301c..8374743899 100644 --- a/cri/v1alpha1/cri_utils.go +++ b/cri/v1alpha1/cri_utils.go @@ -787,6 +787,20 @@ func filterCRIContainers(containers []*runtime.Container, filter *runtime.Contai return filtered } +// matchLabelSelector returns true if labels cover selector. +func matchLabelSelector(selector, labels map[string]string) bool { + for k, v := range selector { + if val, ok := labels[k]; ok { + if v != val { + return false + } + } else { + return false + } + } + return true +} + // containerNetns returns the network namespace of the given container. func containerNetns(container *mgr.Container) string { pid := container.State.Pid diff --git a/cri/v1alpha1/cri_utils_test.go b/cri/v1alpha1/cri_utils_test.go index 65e682a7ca..345291f79c 100644 --- a/cri/v1alpha1/cri_utils_test.go +++ b/cri/v1alpha1/cri_utils_test.go @@ -1199,6 +1199,67 @@ func Test_toCriContainer(t *testing.T) { } } +func Test_matchLabelSelector(t *testing.T) { + type args struct { + selector map[string]string + labels map[string]string + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Normal Test", + args: args{ + selector: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + labels: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + }, + want: true, + }, + { + name: "Uncovered Test", + args: args{ + selector: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + labels: map[string]string{ + "a2": "b2", + }, + }, + want: false, + }, + { + name: "Unmatched Test", + args: args{ + selector: map[string]string{ + "a1": "b0", + "a2": "b2", + }, + labels: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := matchLabelSelector(tt.args.selector, tt.args.labels); got != tt.want { + t.Errorf("matchLabelSelector() = %v, want %v", got, tt.want) + } + }) + } +} + func Test_containerNetns(t *testing.T) { type args struct { container *mgr.Container diff --git a/cri/v1alpha2/cri.go b/cri/v1alpha2/cri.go index 9d67f3ce3e..4965d36581 100644 --- a/cri/v1alpha2/cri.go +++ b/cri/v1alpha2/cri.go @@ -918,6 +918,19 @@ func (c *CriManager) ContainerStats(ctx context.Context, r *runtime.ContainerSta func (c *CriManager) ListContainerStats(ctx context.Context, r *runtime.ListContainerStatsRequest) (*runtime.ListContainerStatsResponse, error) { opts := &mgr.ContainerListOption{All: true} filter := func(c *mgr.Container) bool { + if c.Config.Labels[containerTypeLabelKey] != containerTypeLabelContainer { + return false + } + if r.GetFilter().GetId() != "" && c.ID != r.GetFilter().GetId() { + return false + } + if r.GetFilter().GetPodSandboxId() != "" && c.Config.Labels[sandboxIDLabelKey] != r.GetFilter().GetPodSandboxId() { + return false + } + if r.GetFilter().GetLabelSelector() != nil && + !matchLabelSelector(r.GetFilter().GetLabelSelector(), c.Config.Labels) { + return false + } return true } opts.FilterFunc = filter diff --git a/cri/v1alpha2/cri_utils.go b/cri/v1alpha2/cri_utils.go index 8d8cb1ef40..35b69f2cd3 100644 --- a/cri/v1alpha2/cri_utils.go +++ b/cri/v1alpha2/cri_utils.go @@ -814,6 +814,20 @@ func filterCRIContainers(containers []*runtime.Container, filter *runtime.Contai return filtered } +// matchLabelSelector returns true if labels cover selector. +func matchLabelSelector(selector, labels map[string]string) bool { + for k, v := range selector { + if val, ok := labels[k]; ok { + if v != val { + return false + } + } else { + return false + } + } + return true +} + // containerNetns returns the network namespace of the given container. func containerNetns(container *mgr.Container) string { pid := container.State.Pid diff --git a/cri/v1alpha2/cri_utils_test.go b/cri/v1alpha2/cri_utils_test.go index 41726d73c1..ba1e82b7c7 100644 --- a/cri/v1alpha2/cri_utils_test.go +++ b/cri/v1alpha2/cri_utils_test.go @@ -1186,6 +1186,67 @@ func Test_toCriContainer(t *testing.T) { } } +func Test_matchLabelSelector(t *testing.T) { + type args struct { + selector map[string]string + labels map[string]string + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Normal Test", + args: args{ + selector: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + labels: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + }, + want: true, + }, + { + name: "Uncovered Test", + args: args{ + selector: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + labels: map[string]string{ + "a2": "b2", + }, + }, + want: false, + }, + { + name: "Unmatched Test", + args: args{ + selector: map[string]string{ + "a1": "b0", + "a2": "b2", + }, + labels: map[string]string{ + "a1": "b1", + "a2": "b2", + }, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := matchLabelSelector(tt.args.selector, tt.args.labels); got != tt.want { + t.Errorf("matchLabelSelector() = %v, want %v", got, tt.want) + } + }) + } +} + func Test_containerNetns(t *testing.T) { type args struct { container *mgr.Container