mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	Merge pull request #25245 from pmorie/kubelet/cadvisor
Automatic merge from submit-queue Reduce kubelet LOC: extract cadvisor Step 2 of #25028 @yujuhong @kubernetes/sig-node
This commit is contained in:
		@@ -34,7 +34,6 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/golang/glog"
 | 
			
		||||
	cadvisorapi "github.com/google/cadvisor/info/v1"
 | 
			
		||||
	cadvisorapiv2 "github.com/google/cadvisor/info/v2"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	apierrors "k8s.io/kubernetes/pkg/api/errors"
 | 
			
		||||
	utilpod "k8s.io/kubernetes/pkg/api/pod"
 | 
			
		||||
@@ -3582,71 +3581,6 @@ func (kl *Kubelet) ResyncInterval() time.Duration {
 | 
			
		||||
	return kl.resyncInterval
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetContainerInfo returns stats (from Cadvisor) for a container.
 | 
			
		||||
func (kl *Kubelet) GetContainerInfo(podFullName string, podUID types.UID, containerName string, req *cadvisorapi.ContainerInfoRequest) (*cadvisorapi.ContainerInfo, error) {
 | 
			
		||||
 | 
			
		||||
	podUID = kl.podManager.TranslatePodUID(podUID)
 | 
			
		||||
 | 
			
		||||
	pods, err := kl.runtimeCache.GetPods()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	pod := kubecontainer.Pods(pods).FindPod(podFullName, podUID)
 | 
			
		||||
	container := pod.FindContainerByName(containerName)
 | 
			
		||||
	if container == nil {
 | 
			
		||||
		return nil, kubecontainer.ErrContainerNotFound
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ci, err := kl.cadvisor.DockerContainer(container.ID.ID, req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &ci, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetContainerInfoV2 returns stats (from Cadvisor) for containers.
 | 
			
		||||
func (kl *Kubelet) GetContainerInfoV2(name string, options cadvisorapiv2.RequestOptions) (map[string]cadvisorapiv2.ContainerInfo, error) {
 | 
			
		||||
	return kl.cadvisor.ContainerInfoV2(name, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DockerImagesFsInfo returns information about docker image fs usage from
 | 
			
		||||
// cadvisor.
 | 
			
		||||
func (kl *Kubelet) DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) {
 | 
			
		||||
	return kl.cadvisor.DockerImagesFsInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RootFsInfo returns info about the root fs from cadvisor.
 | 
			
		||||
func (kl *Kubelet) RootFsInfo() (cadvisorapiv2.FsInfo, error) {
 | 
			
		||||
	return kl.cadvisor.RootFsInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns stats (from Cadvisor) for a non-Kubernetes container.
 | 
			
		||||
func (kl *Kubelet) GetRawContainerInfo(containerName string, req *cadvisorapi.ContainerInfoRequest, subcontainers bool) (map[string]*cadvisorapi.ContainerInfo, error) {
 | 
			
		||||
	if subcontainers {
 | 
			
		||||
		return kl.cadvisor.SubcontainerInfo(containerName, req)
 | 
			
		||||
	} else {
 | 
			
		||||
		containerInfo, err := kl.cadvisor.ContainerInfo(containerName, req)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return map[string]*cadvisorapi.ContainerInfo{
 | 
			
		||||
			containerInfo.Name: containerInfo,
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCachedMachineInfo assumes that the machine info can't change without a reboot
 | 
			
		||||
func (kl *Kubelet) GetCachedMachineInfo() (*cadvisorapi.MachineInfo, error) {
 | 
			
		||||
	if kl.machineInfo == nil {
 | 
			
		||||
		info, err := kl.cadvisor.MachineInfo()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		kl.machineInfo = info
 | 
			
		||||
	}
 | 
			
		||||
	return kl.machineInfo, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenAndServe runs the kubelet HTTP server.
 | 
			
		||||
func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers bool) {
 | 
			
		||||
	server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableDebuggingHandlers, kl.containerRuntime)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								pkg/kubelet/kubelet_cadvisor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								pkg/kubelet/kubelet_cadvisor.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2015 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
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 kubelet
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	cadvisorapi "github.com/google/cadvisor/info/v1"
 | 
			
		||||
	cadvisorapiv2 "github.com/google/cadvisor/info/v2"
 | 
			
		||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetContainerInfo returns stats (from Cadvisor) for a container.
 | 
			
		||||
func (kl *Kubelet) GetContainerInfo(podFullName string, podUID types.UID, containerName string, req *cadvisorapi.ContainerInfoRequest) (*cadvisorapi.ContainerInfo, error) {
 | 
			
		||||
 | 
			
		||||
	podUID = kl.podManager.TranslatePodUID(podUID)
 | 
			
		||||
 | 
			
		||||
	pods, err := kl.runtimeCache.GetPods()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	pod := kubecontainer.Pods(pods).FindPod(podFullName, podUID)
 | 
			
		||||
	container := pod.FindContainerByName(containerName)
 | 
			
		||||
	if container == nil {
 | 
			
		||||
		return nil, kubecontainer.ErrContainerNotFound
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ci, err := kl.cadvisor.DockerContainer(container.ID.ID, req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &ci, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetContainerInfoV2 returns stats (from Cadvisor) for containers.
 | 
			
		||||
func (kl *Kubelet) GetContainerInfoV2(name string, options cadvisorapiv2.RequestOptions) (map[string]cadvisorapiv2.ContainerInfo, error) {
 | 
			
		||||
	return kl.cadvisor.ContainerInfoV2(name, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DockerImagesFsInfo returns information about docker image fs usage from
 | 
			
		||||
// cadvisor.
 | 
			
		||||
func (kl *Kubelet) DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) {
 | 
			
		||||
	return kl.cadvisor.DockerImagesFsInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RootFsInfo returns info about the root fs from cadvisor.
 | 
			
		||||
func (kl *Kubelet) RootFsInfo() (cadvisorapiv2.FsInfo, error) {
 | 
			
		||||
	return kl.cadvisor.RootFsInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns stats (from Cadvisor) for a non-Kubernetes container.
 | 
			
		||||
func (kl *Kubelet) GetRawContainerInfo(containerName string, req *cadvisorapi.ContainerInfoRequest, subcontainers bool) (map[string]*cadvisorapi.ContainerInfo, error) {
 | 
			
		||||
	if subcontainers {
 | 
			
		||||
		return kl.cadvisor.SubcontainerInfo(containerName, req)
 | 
			
		||||
	} else {
 | 
			
		||||
		containerInfo, err := kl.cadvisor.ContainerInfo(containerName, req)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return map[string]*cadvisorapi.ContainerInfo{
 | 
			
		||||
			containerInfo.Name: containerInfo,
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCachedMachineInfo assumes that the machine info can't change without a reboot
 | 
			
		||||
func (kl *Kubelet) GetCachedMachineInfo() (*cadvisorapi.MachineInfo, error) {
 | 
			
		||||
	if kl.machineInfo == nil {
 | 
			
		||||
		info, err := kl.cadvisor.MachineInfo()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		kl.machineInfo = info
 | 
			
		||||
	}
 | 
			
		||||
	return kl.machineInfo, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										232
									
								
								pkg/kubelet/kubelet_cadvisor_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								pkg/kubelet/kubelet_cadvisor_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,232 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
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 kubelet
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	cadvisorapi "github.com/google/cadvisor/info/v1"
 | 
			
		||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfo(t *testing.T) {
 | 
			
		||||
	containerID := "ab2cdf"
 | 
			
		||||
	containerPath := fmt.Sprintf("/docker/%v", containerID)
 | 
			
		||||
	containerInfo := cadvisorapi.ContainerInfo{
 | 
			
		||||
		ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
			Name: containerPath,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	mockCadvisor.On("DockerContainer", containerID, cadvisorReq).Return(containerInfo, nil)
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{
 | 
			
		||||
		{
 | 
			
		||||
			ID:        "12345678",
 | 
			
		||||
			Name:      "qux",
 | 
			
		||||
			Namespace: "ns",
 | 
			
		||||
			Containers: []*kubecontainer.Container{
 | 
			
		||||
				{
 | 
			
		||||
					Name: "foo",
 | 
			
		||||
					ID:   kubecontainer.ContainerID{Type: "test", ID: containerID},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", cadvisorReq)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if stats == nil {
 | 
			
		||||
		t.Fatalf("stats should not be nil")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetRawContainerInfoRoot(t *testing.T) {
 | 
			
		||||
	containerPath := "/"
 | 
			
		||||
	containerInfo := &cadvisorapi.ContainerInfo{
 | 
			
		||||
		ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
			Name: containerPath,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor.On("ContainerInfo", containerPath, cadvisorReq).Return(containerInfo, nil)
 | 
			
		||||
 | 
			
		||||
	_, err := kubelet.GetRawContainerInfo(containerPath, cadvisorReq, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetRawContainerInfoSubcontainers(t *testing.T) {
 | 
			
		||||
	containerPath := "/kubelet"
 | 
			
		||||
	containerInfo := map[string]*cadvisorapi.ContainerInfo{
 | 
			
		||||
		containerPath: {
 | 
			
		||||
			ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
				Name: containerPath,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		"/kubelet/sub": {
 | 
			
		||||
			ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
				Name: "/kubelet/sub",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor.On("SubcontainerInfo", containerPath, cadvisorReq).Return(containerInfo, nil)
 | 
			
		||||
 | 
			
		||||
	result, err := kubelet.GetRawContainerInfo(containerPath, cadvisorReq, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if len(result) != 2 {
 | 
			
		||||
		t.Errorf("Expected 2 elements, received: %+v", result)
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWhenCadvisorFailed(t *testing.T) {
 | 
			
		||||
	containerID := "ab2cdf"
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	cadvisorApiFailure := fmt.Errorf("cAdvisor failure")
 | 
			
		||||
	containerInfo := cadvisorapi.ContainerInfo{}
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor.On("DockerContainer", containerID, cadvisorReq).Return(containerInfo, cadvisorApiFailure)
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{
 | 
			
		||||
		{
 | 
			
		||||
			ID:        "uuid",
 | 
			
		||||
			Name:      "qux",
 | 
			
		||||
			Namespace: "ns",
 | 
			
		||||
			Containers: []*kubecontainer.Container{
 | 
			
		||||
				{Name: "foo",
 | 
			
		||||
					ID: kubecontainer.ContainerID{Type: "test", ID: containerID},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "uuid", "foo", cadvisorReq)
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats on error")
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("expect error but received nil error")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err.Error() != cadvisorApiFailure.Error() {
 | 
			
		||||
		t.Errorf("wrong error message. expect %v, got %v", cadvisorApiFailure, err)
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoOnNonExistContainer(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{}
 | 
			
		||||
 | 
			
		||||
	stats, _ := kubelet.GetContainerInfo("qux", "", "foo", nil)
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats on non exist container")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWhenContainerRuntimeFailed(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	expectedErr := fmt.Errorf("List containers error")
 | 
			
		||||
	fakeRuntime.Err = expectedErr
 | 
			
		||||
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux", "", "foo", nil)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("expected error from dockertools, got none")
 | 
			
		||||
	}
 | 
			
		||||
	if err.Error() != expectedErr.Error() {
 | 
			
		||||
		t.Errorf("expected error %v got %v", expectedErr.Error(), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats when dockertools failed")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWithNoContainers(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("expected error from cadvisor client, got none")
 | 
			
		||||
	}
 | 
			
		||||
	if err != kubecontainer.ErrContainerNotFound {
 | 
			
		||||
		t.Errorf("expected error %v, got %v", kubecontainer.ErrContainerNotFound.Error(), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats when dockertools returned no containers")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWithNoMatchingContainers(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{
 | 
			
		||||
		{
 | 
			
		||||
			ID:        "12345678",
 | 
			
		||||
			Name:      "qux",
 | 
			
		||||
			Namespace: "ns",
 | 
			
		||||
			Containers: []*kubecontainer.Container{
 | 
			
		||||
				{Name: "bar",
 | 
			
		||||
					ID: kubecontainer.ContainerID{Type: "test", ID: "fakeID"},
 | 
			
		||||
				},
 | 
			
		||||
			}},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("Expected error from cadvisor client, got none")
 | 
			
		||||
	}
 | 
			
		||||
	if err != kubecontainer.ErrContainerNotFound {
 | 
			
		||||
		t.Errorf("Expected error %v, got %v", kubecontainer.ErrContainerNotFound.Error(), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats when dockertools returned no containers")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
@@ -665,183 +665,6 @@ func TestMakeVolumeMounts(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfo(t *testing.T) {
 | 
			
		||||
	containerID := "ab2cdf"
 | 
			
		||||
	containerPath := fmt.Sprintf("/docker/%v", containerID)
 | 
			
		||||
	containerInfo := cadvisorapi.ContainerInfo{
 | 
			
		||||
		ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
			Name: containerPath,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	mockCadvisor.On("DockerContainer", containerID, cadvisorReq).Return(containerInfo, nil)
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{
 | 
			
		||||
		{
 | 
			
		||||
			ID:        "12345678",
 | 
			
		||||
			Name:      "qux",
 | 
			
		||||
			Namespace: "ns",
 | 
			
		||||
			Containers: []*kubecontainer.Container{
 | 
			
		||||
				{
 | 
			
		||||
					Name: "foo",
 | 
			
		||||
					ID:   kubecontainer.ContainerID{Type: "test", ID: containerID},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", cadvisorReq)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if stats == nil {
 | 
			
		||||
		t.Fatalf("stats should not be nil")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetRawContainerInfoRoot(t *testing.T) {
 | 
			
		||||
	containerPath := "/"
 | 
			
		||||
	containerInfo := &cadvisorapi.ContainerInfo{
 | 
			
		||||
		ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
			Name: containerPath,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor.On("ContainerInfo", containerPath, cadvisorReq).Return(containerInfo, nil)
 | 
			
		||||
 | 
			
		||||
	_, err := kubelet.GetRawContainerInfo(containerPath, cadvisorReq, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetRawContainerInfoSubcontainers(t *testing.T) {
 | 
			
		||||
	containerPath := "/kubelet"
 | 
			
		||||
	containerInfo := map[string]*cadvisorapi.ContainerInfo{
 | 
			
		||||
		containerPath: {
 | 
			
		||||
			ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
				Name: containerPath,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		"/kubelet/sub": {
 | 
			
		||||
			ContainerReference: cadvisorapi.ContainerReference{
 | 
			
		||||
				Name: "/kubelet/sub",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor.On("SubcontainerInfo", containerPath, cadvisorReq).Return(containerInfo, nil)
 | 
			
		||||
 | 
			
		||||
	result, err := kubelet.GetRawContainerInfo(containerPath, cadvisorReq, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if len(result) != 2 {
 | 
			
		||||
		t.Errorf("Expected 2 elements, received: %+v", result)
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWhenCadvisorFailed(t *testing.T) {
 | 
			
		||||
	containerID := "ab2cdf"
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	cadvisorApiFailure := fmt.Errorf("cAdvisor failure")
 | 
			
		||||
	containerInfo := cadvisorapi.ContainerInfo{}
 | 
			
		||||
	cadvisorReq := &cadvisorapi.ContainerInfoRequest{}
 | 
			
		||||
	mockCadvisor.On("DockerContainer", containerID, cadvisorReq).Return(containerInfo, cadvisorApiFailure)
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{
 | 
			
		||||
		{
 | 
			
		||||
			ID:        "uuid",
 | 
			
		||||
			Name:      "qux",
 | 
			
		||||
			Namespace: "ns",
 | 
			
		||||
			Containers: []*kubecontainer.Container{
 | 
			
		||||
				{Name: "foo",
 | 
			
		||||
					ID: kubecontainer.ContainerID{Type: "test", ID: containerID},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "uuid", "foo", cadvisorReq)
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats on error")
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("expect error but received nil error")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err.Error() != cadvisorApiFailure.Error() {
 | 
			
		||||
		t.Errorf("wrong error message. expect %v, got %v", cadvisorApiFailure, err)
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoOnNonExistContainer(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{}
 | 
			
		||||
 | 
			
		||||
	stats, _ := kubelet.GetContainerInfo("qux", "", "foo", nil)
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats on non exist container")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWhenContainerRuntimeFailed(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	expectedErr := fmt.Errorf("List containers error")
 | 
			
		||||
	fakeRuntime.Err = expectedErr
 | 
			
		||||
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux", "", "foo", nil)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("expected error from dockertools, got none")
 | 
			
		||||
	}
 | 
			
		||||
	if err.Error() != expectedErr.Error() {
 | 
			
		||||
		t.Errorf("expected error %v got %v", expectedErr.Error(), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats when dockertools failed")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWithNoContainers(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("expected error from cadvisor client, got none")
 | 
			
		||||
	}
 | 
			
		||||
	if err != kubecontainer.ErrContainerNotFound {
 | 
			
		||||
		t.Errorf("expected error %v, got %v", kubecontainer.ErrContainerNotFound.Error(), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats when dockertools returned no containers")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNodeIPParam(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
@@ -882,36 +705,6 @@ func TestNodeIPParam(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetContainerInfoWithNoMatchingContainers(t *testing.T) {
 | 
			
		||||
	testKubelet := newTestKubelet(t)
 | 
			
		||||
	fakeRuntime := testKubelet.fakeRuntime
 | 
			
		||||
	kubelet := testKubelet.kubelet
 | 
			
		||||
	mockCadvisor := testKubelet.fakeCadvisor
 | 
			
		||||
	fakeRuntime.PodList = []*kubecontainer.Pod{
 | 
			
		||||
		{
 | 
			
		||||
			ID:        "12345678",
 | 
			
		||||
			Name:      "qux",
 | 
			
		||||
			Namespace: "ns",
 | 
			
		||||
			Containers: []*kubecontainer.Container{
 | 
			
		||||
				{Name: "bar",
 | 
			
		||||
					ID: kubecontainer.ContainerID{Type: "test", ID: "fakeID"},
 | 
			
		||||
				},
 | 
			
		||||
			}},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("Expected error from cadvisor client, got none")
 | 
			
		||||
	}
 | 
			
		||||
	if err != kubecontainer.ErrContainerNotFound {
 | 
			
		||||
		t.Errorf("Expected error %v, got %v", kubecontainer.ErrContainerNotFound.Error(), err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	if stats != nil {
 | 
			
		||||
		t.Errorf("non-nil stats when dockertools returned no containers")
 | 
			
		||||
	}
 | 
			
		||||
	mockCadvisor.AssertExpectations(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fakeContainerCommandRunner struct {
 | 
			
		||||
	Cmd    []string
 | 
			
		||||
	ID     kubecontainer.ContainerID
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user