From 0d907e015b784a4edeb17c0580bf1e408c966de7 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Wed, 10 Jul 2019 14:00:20 -0700 Subject: [PATCH 1/8] Add ImageFSInfo, ContainerStats, and ListContainerStats impl for linux to dockershim --- pkg/kubelet/dockershim/docker_image_linux.go | 50 +++++++++++- pkg/kubelet/dockershim/docker_stats_linux.go | 84 +++++++++++++++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/pkg/kubelet/dockershim/docker_image_linux.go b/pkg/kubelet/dockershim/docker_image_linux.go index e68d83b19ab..0762d26334c 100644 --- a/pkg/kubelet/dockershim/docker_image_linux.go +++ b/pkg/kubelet/dockershim/docker_image_linux.go @@ -20,12 +20,58 @@ package dockershim import ( "context" - "fmt" + "path/filepath" + "os" + "time" + + "k8s.io/klog" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" ) // ImageFsInfo returns information of the filesystem that is used to store images. func (ds *dockerService) ImageFsInfo(_ context.Context, r *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { - return nil, fmt.Errorf("not implemented") + info, err := ds.client.Info() + if err != nil { + klog.Errorf("Failed to get docker info: %v", err) + return nil, err + } + + bytes, inodes, err := dirSize(filepath.Join(info.DockerRootDir, "image")) + if err != nil { + return nil, err + } + + return &runtimeapi.ImageFsInfoResponse{ + ImageFilesystems: []*runtimeapi.FilesystemUsage{ + &runtimeapi.FilesystemUsage{ + Timestamp: time.Now().Unix(), + FsId: &runtimeapi.FilesystemIdentifier{ + Mountpoint: info.DockerRootDir, + }, + UsedBytes: &runtimeapi.UInt64Value{ + Value: uint64(bytes), + }, + InodesUsed: &runtimeapi.UInt64Value{ + Value: uint64(inodes), + }, + }, + }, + }, nil +} + +func dirSize(path string) (int64, int64, error) { + bytes := int64(0) + inodes := int64(0) + err := filepath.Walk(path, func(dir string, info os.FileInfo, err error) error { + if err != nil { + return err + } + inodes += 1 + if !info.IsDir() { + bytes += info.Size() + } + return nil + }) + return bytes, inodes, err } diff --git a/pkg/kubelet/dockershim/docker_stats_linux.go b/pkg/kubelet/dockershim/docker_stats_linux.go index b78ff9c3c95..d0f3cd463c0 100644 --- a/pkg/kubelet/dockershim/docker_stats_linux.go +++ b/pkg/kubelet/dockershim/docker_stats_linux.go @@ -20,17 +20,93 @@ package dockershim import ( "context" - "fmt" + "time" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" ) // ContainerStats returns stats for a container stats request based on container id. func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { - return nil, fmt.Errorf("not implemented") + stats, err := ds.getContainerStats(r.ContainerId) + if err != nil { + return nil, err + } + return &runtimeapi.ContainerStatsResponse{Stats: stats}, nil } // ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(_ context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { - return nil, fmt.Errorf("not implemented") +func (ds *dockerService) ListContainerStats(ctx context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { + containerStatsFilter := r.GetFilter() + filter := &runtimeapi.ContainerFilter{} + + if containerStatsFilter != nil { + filter.Id = containerStatsFilter.Id + filter.PodSandboxId = containerStatsFilter.PodSandboxId + filter.LabelSelector = containerStatsFilter.LabelSelector + } + + listResp, err := ds.ListContainers(ctx, &runtimeapi.ListContainersRequest{Filter: filter}) + if err != nil { + return nil, err + } + + var stats []*runtimeapi.ContainerStats + for _, container := range listResp.Containers { + containerStats, err := ds.getContainerStats(container.Id) + if err != nil { + return nil, err + } + + stats = append(stats, containerStats) + } + + return &runtimeapi.ListContainerStatsResponse{Stats: stats}, nil +} + +func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.ContainerStats, error) { + info, err := ds.client.Info() + if err != nil { + return nil, err + } + + statsJSON, err := ds.client.GetContainerStats(containerID) + if err != nil { + return nil, err + } + + containerJSON, err := ds.client.InspectContainerWithSize(containerID) + if err != nil { + return nil, err + } + + statusResp, err := ds.ContainerStatus(context.Background(), &runtimeapi.ContainerStatusRequest{ContainerId: containerID}) + if err != nil { + return nil, err + } + status := statusResp.GetStatus() + + dockerStats := statsJSON.Stats + timestamp := time.Now().UnixNano() + containerStats := &runtimeapi.ContainerStats{ + Attributes: &runtimeapi.ContainerAttributes{ + Id: containerID, + Metadata: status.Metadata, + Labels: status.Labels, + Annotations: status.Annotations, + }, + Cpu: &runtimeapi.CpuUsage{ + Timestamp: timestamp, + UsageCoreNanoSeconds: &runtimeapi.UInt64Value{Value: dockerStats.CPUStats.CPUUsage.TotalUsage}, + }, + Memory: &runtimeapi.MemoryUsage{ + Timestamp: timestamp, + WorkingSetBytes: &runtimeapi.UInt64Value{Value: dockerStats.MemoryStats.PrivateWorkingSet}, + }, + WritableLayer: &runtimeapi.FilesystemUsage{ + Timestamp: timestamp, + FsId: &runtimeapi.FilesystemIdentifier{Mountpoint: info.DockerRootDir}, + UsedBytes: &runtimeapi.UInt64Value{Value: uint64(*containerJSON.SizeRw)}, + }, + } + return containerStats, nil } From db8e47a965818c9d666efb9967846ad0785f4558 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 08:24:51 -0700 Subject: [PATCH 2/8] Run gofmt --- pkg/kubelet/dockershim/docker_image_linux.go | 4 ++-- pkg/kubelet/dockershim/docker_stats_linux.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/kubelet/dockershim/docker_image_linux.go b/pkg/kubelet/dockershim/docker_image_linux.go index 0762d26334c..ffaad085f99 100644 --- a/pkg/kubelet/dockershim/docker_image_linux.go +++ b/pkg/kubelet/dockershim/docker_image_linux.go @@ -20,8 +20,8 @@ package dockershim import ( "context" - "path/filepath" "os" + "path/filepath" "time" "k8s.io/klog" @@ -44,7 +44,7 @@ func (ds *dockerService) ImageFsInfo(_ context.Context, r *runtimeapi.ImageFsInf return &runtimeapi.ImageFsInfoResponse{ ImageFilesystems: []*runtimeapi.FilesystemUsage{ - &runtimeapi.FilesystemUsage{ + { Timestamp: time.Now().Unix(), FsId: &runtimeapi.FilesystemIdentifier{ Mountpoint: info.DockerRootDir, diff --git a/pkg/kubelet/dockershim/docker_stats_linux.go b/pkg/kubelet/dockershim/docker_stats_linux.go index d0f3cd463c0..bb53c13e3ad 100644 --- a/pkg/kubelet/dockershim/docker_stats_linux.go +++ b/pkg/kubelet/dockershim/docker_stats_linux.go @@ -95,7 +95,7 @@ func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.Cont Annotations: status.Annotations, }, Cpu: &runtimeapi.CpuUsage{ - Timestamp: timestamp, + Timestamp: timestamp, UsageCoreNanoSeconds: &runtimeapi.UInt64Value{Value: dockerStats.CPUStats.CPUUsage.TotalUsage}, }, Memory: &runtimeapi.MemoryUsage{ From 5a26fe5696d06f524ab482a27cd5f46c49e41655 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 08:26:42 -0700 Subject: [PATCH 3/8] Rename unused variable --- pkg/kubelet/dockershim/docker_image_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kubelet/dockershim/docker_image_linux.go b/pkg/kubelet/dockershim/docker_image_linux.go index ffaad085f99..25e3d7a074e 100644 --- a/pkg/kubelet/dockershim/docker_image_linux.go +++ b/pkg/kubelet/dockershim/docker_image_linux.go @@ -30,7 +30,7 @@ import ( ) // ImageFsInfo returns information of the filesystem that is used to store images. -func (ds *dockerService) ImageFsInfo(_ context.Context, r *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { +func (ds *dockerService) ImageFsInfo(_ context.Context, _ *runtimeapi.ImageFsInfoRequest) (*runtimeapi.ImageFsInfoResponse, error) { info, err := ds.client.Info() if err != nil { klog.Errorf("Failed to get docker info: %v", err) From 9ed8340306fe7875ada0d594ba11057413295549 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 08:41:06 -0700 Subject: [PATCH 4/8] Removed duplicate code --- pkg/kubelet/dockershim/BUILD | 1 + pkg/kubelet/dockershim/docker_stats.go | 61 +++++++++++++++++++ pkg/kubelet/dockershim/docker_stats_linux.go | 38 ------------ .../dockershim/docker_stats_windows.go | 38 ------------ 4 files changed, 62 insertions(+), 76 deletions(-) create mode 100644 pkg/kubelet/dockershim/docker_stats.go diff --git a/pkg/kubelet/dockershim/BUILD b/pkg/kubelet/dockershim/BUILD index d73a27b007e..e5edb510c4b 100644 --- a/pkg/kubelet/dockershim/BUILD +++ b/pkg/kubelet/dockershim/BUILD @@ -17,6 +17,7 @@ go_library( "docker_logs.go", "docker_sandbox.go", "docker_service.go", + "docker_stats.go", "docker_stats_linux.go", "docker_stats_unsupported.go", "docker_stats_windows.go", diff --git a/pkg/kubelet/dockershim/docker_stats.go b/pkg/kubelet/dockershim/docker_stats.go new file mode 100644 index 00000000000..ede30c4efbb --- /dev/null +++ b/pkg/kubelet/dockershim/docker_stats.go @@ -0,0 +1,61 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dockershim + +import ( + "context" + + runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" +) + +// ContainerStats returns stats for a container stats request based on container id. +func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { + stats, err := ds.getContainerStats(r.ContainerId) + if err != nil { + return nil, err + } + return &runtimeapi.ContainerStatsResponse{Stats: stats}, nil +} + +// ListContainerStats returns stats for a list container stats request based on a filter. +func (ds *dockerService) ListContainerStats(ctx context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { + containerStatsFilter := r.GetFilter() + filter := &runtimeapi.ContainerFilter{} + + if containerStatsFilter != nil { + filter.Id = containerStatsFilter.Id + filter.PodSandboxId = containerStatsFilter.PodSandboxId + filter.LabelSelector = containerStatsFilter.LabelSelector + } + + listResp, err := ds.ListContainers(ctx, &runtimeapi.ListContainersRequest{Filter: filter}) + if err != nil { + return nil, err + } + + var stats []*runtimeapi.ContainerStats + for _, container := range listResp.Containers { + containerStats, err := ds.getContainerStats(container.Id) + if err != nil { + return nil, err + } + + stats = append(stats, containerStats) + } + + return &runtimeapi.ListContainerStatsResponse{Stats: stats}, nil +} diff --git a/pkg/kubelet/dockershim/docker_stats_linux.go b/pkg/kubelet/dockershim/docker_stats_linux.go index bb53c13e3ad..11d6add29c4 100644 --- a/pkg/kubelet/dockershim/docker_stats_linux.go +++ b/pkg/kubelet/dockershim/docker_stats_linux.go @@ -25,44 +25,6 @@ import ( runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" ) -// ContainerStats returns stats for a container stats request based on container id. -func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { - stats, err := ds.getContainerStats(r.ContainerId) - if err != nil { - return nil, err - } - return &runtimeapi.ContainerStatsResponse{Stats: stats}, nil -} - -// ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(ctx context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { - containerStatsFilter := r.GetFilter() - filter := &runtimeapi.ContainerFilter{} - - if containerStatsFilter != nil { - filter.Id = containerStatsFilter.Id - filter.PodSandboxId = containerStatsFilter.PodSandboxId - filter.LabelSelector = containerStatsFilter.LabelSelector - } - - listResp, err := ds.ListContainers(ctx, &runtimeapi.ListContainersRequest{Filter: filter}) - if err != nil { - return nil, err - } - - var stats []*runtimeapi.ContainerStats - for _, container := range listResp.Containers { - containerStats, err := ds.getContainerStats(container.Id) - if err != nil { - return nil, err - } - - stats = append(stats, containerStats) - } - - return &runtimeapi.ListContainerStatsResponse{Stats: stats}, nil -} - func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.ContainerStats, error) { info, err := ds.client.Info() if err != nil { diff --git a/pkg/kubelet/dockershim/docker_stats_windows.go b/pkg/kubelet/dockershim/docker_stats_windows.go index 460730257f7..053c11d93ad 100644 --- a/pkg/kubelet/dockershim/docker_stats_windows.go +++ b/pkg/kubelet/dockershim/docker_stats_windows.go @@ -25,44 +25,6 @@ import ( runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" ) -// ContainerStats returns stats for a container stats request based on container id. -func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { - stats, err := ds.getContainerStats(r.ContainerId) - if err != nil { - return nil, err - } - return &runtimeapi.ContainerStatsResponse{Stats: stats}, nil -} - -// ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(ctx context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { - containerStatsFilter := r.GetFilter() - filter := &runtimeapi.ContainerFilter{} - - if containerStatsFilter != nil { - filter.Id = containerStatsFilter.Id - filter.PodSandboxId = containerStatsFilter.PodSandboxId - filter.LabelSelector = containerStatsFilter.LabelSelector - } - - listResp, err := ds.ListContainers(ctx, &runtimeapi.ListContainersRequest{Filter: filter}) - if err != nil { - return nil, err - } - - var stats []*runtimeapi.ContainerStats - for _, container := range listResp.Containers { - containerStats, err := ds.getContainerStats(container.Id) - if err != nil { - return nil, err - } - - stats = append(stats, containerStats) - } - - return &runtimeapi.ListContainerStatsResponse{Stats: stats}, nil -} - func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.ContainerStats, error) { info, err := ds.client.Info() if err != nil { From 2cfc85c8b300c5a727f7caebc8530a8db4e96c43 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 09:04:22 -0700 Subject: [PATCH 5/8] Fix compile on non windows linux systems --- pkg/kubelet/dockershim/docker_stats_unsupported.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/pkg/kubelet/dockershim/docker_stats_unsupported.go b/pkg/kubelet/dockershim/docker_stats_unsupported.go index 751624cfb1f..736215a9d64 100644 --- a/pkg/kubelet/dockershim/docker_stats_unsupported.go +++ b/pkg/kubelet/dockershim/docker_stats_unsupported.go @@ -19,18 +19,11 @@ limitations under the License. package dockershim import ( - "context" "fmt" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" ) -// ContainerStats returns stats for a container stats request based on container id. -func (ds *dockerService) ContainerStats(_ context.Context, r *runtimeapi.ContainerStatsRequest) (*runtimeapi.ContainerStatsResponse, error) { - return nil, fmt.Errorf("not implemented") -} - -// ListContainerStats returns stats for a list container stats request based on a filter. -func (ds *dockerService) ListContainerStats(_ context.Context, r *runtimeapi.ListContainerStatsRequest) (*runtimeapi.ListContainerStatsResponse, error) { +func (ds *dockerService) getContainerStats(containerID string) (*runtimeapi.ContainerStats, error) { return nil, fmt.Errorf("not implemented") } From cd8d8f2dce35a1d4c03a85cb6910454492806e30 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 09:56:55 -0700 Subject: [PATCH 6/8] Add tracing to GetContainerStats --- pkg/kubelet/dockershim/libdocker/fake_client.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pkg/kubelet/dockershim/libdocker/fake_client.go b/pkg/kubelet/dockershim/libdocker/fake_client.go index 7e95cf36516..cc063cc8c3d 100644 --- a/pkg/kubelet/dockershim/libdocker/fake_client.go +++ b/pkg/kubelet/dockershim/libdocker/fake_client.go @@ -77,6 +77,7 @@ type FakeDockerClient struct { execCmd []string EnableSleep bool ImageHistoryMap map[string][]dockerimagetypes.HistoryResponseItem + ContainerStatsMap map[string]*dockertypes.StatsJSON } const ( @@ -913,9 +914,19 @@ func (f *FakeDockerPuller) GetImageRef(image string) (string, error) { return image, err } +func (f *FakeDockerClient) InjectContainerStats(data map[string]*dockertypes.StatsJSON) { + f.Lock() + defer f.Unlock() + f.ContainerStatsMap = data +} + func (f *FakeDockerClient) GetContainerStats(id string) (*dockertypes.StatsJSON, error) { f.Lock() defer f.Unlock() - f.appendCalled(CalledDetail{name: "getContainerStats"}) - return nil, fmt.Errorf("not implemented") + f.appendCalled(CalledDetail{name: "get_container_stats"}) + stats, ok := f.ContainerStatsMap[id] + if !ok { + return nil, fmt.Errorf("container %q not found", id) + } + return stats, nil } From 82b6b191737eac15b62692270953bebdfd968de3 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 09:57:21 -0700 Subject: [PATCH 7/8] Add test for ContainerStats --- pkg/kubelet/dockershim/BUILD | 1 + pkg/kubelet/dockershim/docker_stats_test.go | 66 +++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 pkg/kubelet/dockershim/docker_stats_test.go diff --git a/pkg/kubelet/dockershim/BUILD b/pkg/kubelet/dockershim/BUILD index e5edb510c4b..3d82bfedd4d 100644 --- a/pkg/kubelet/dockershim/BUILD +++ b/pkg/kubelet/dockershim/BUILD @@ -94,6 +94,7 @@ go_test( "docker_image_test.go", "docker_sandbox_test.go", "docker_service_test.go", + "docker_stats_test.go", "helpers_linux_test.go", "helpers_test.go", "naming_test.go", diff --git a/pkg/kubelet/dockershim/docker_stats_test.go b/pkg/kubelet/dockershim/docker_stats_test.go new file mode 100644 index 00000000000..b4ce51ae6be --- /dev/null +++ b/pkg/kubelet/dockershim/docker_stats_test.go @@ -0,0 +1,66 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dockershim + +import ( + "testing" + + dockertypes "github.com/docker/docker/api/types" + "github.com/stretchr/testify/assert" + runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" + "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker" +) + +func TestContainerStats(t *testing.T) { + tests := map[string]struct { + containerID string + container *libdocker.FakeContainer + containerStats *dockertypes.StatsJSON + calledDetails []libdocker.CalledDetail + }{ + "container exists": { + "fake_container", + &libdocker.FakeContainer{ID: "fake_container"}, + &dockertypes.StatsJSON{}, + []libdocker.CalledDetail{ + libdocker.NewCalledDetail("get_container_stats", nil), + libdocker.NewCalledDetail("inspect_container_withsize", nil), + libdocker.NewCalledDetail("inspect_container", nil), + libdocker.NewCalledDetail("inspect_image", nil), + }, + }, + "container doesn't exists": { + "nonexistant_fake_container", + &libdocker.FakeContainer{ID: "fake_container"}, + &dockertypes.StatsJSON{}, + []libdocker.CalledDetail{ + libdocker.NewCalledDetail("get_container_stats", nil), + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + ds, fakeDocker, _ := newTestDockerService() + fakeDocker.SetFakeContainers([]*libdocker.FakeContainer{test.container}) + fakeDocker.InjectContainerStats(map[string]*dockertypes.StatsJSON{test.container.ID: test.containerStats}) + ds.ContainerStats(getTestCTX(), &runtimeapi.ContainerStatsRequest{ContainerId: test.containerID}) + err := fakeDocker.AssertCallDetails(test.calledDetails...) + assert.NoError(t, err) + }) + } +} From 0c1d6d330f76dfc970fa23ff71bae2fd3e067579 Mon Sep 17 00:00:00 2001 From: Arnav Sankaran Date: Mon, 15 Jul 2019 09:58:09 -0700 Subject: [PATCH 8/8] Run gofmt --- pkg/kubelet/dockershim/libdocker/fake_client.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/kubelet/dockershim/libdocker/fake_client.go b/pkg/kubelet/dockershim/libdocker/fake_client.go index cc063cc8c3d..57cdad82a48 100644 --- a/pkg/kubelet/dockershim/libdocker/fake_client.go +++ b/pkg/kubelet/dockershim/libdocker/fake_client.go @@ -71,12 +71,12 @@ type FakeDockerClient struct { // Images pulled by ref (name or ID). ImagesPulled []string - VersionInfo dockertypes.Version - Information dockertypes.Info - ExecInspect *dockertypes.ContainerExecInspect - execCmd []string - EnableSleep bool - ImageHistoryMap map[string][]dockerimagetypes.HistoryResponseItem + VersionInfo dockertypes.Version + Information dockertypes.Info + ExecInspect *dockertypes.ContainerExecInspect + execCmd []string + EnableSleep bool + ImageHistoryMap map[string][]dockerimagetypes.HistoryResponseItem ContainerStatsMap map[string]*dockertypes.StatsJSON }