mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Kubelet: add podManager for managing internal pod storage
This change moves pod array and mirrorPods into podManager, along with all methods accessing these internal pod storages. This is the first step of the refactoring, and no function change is involved.
This commit is contained in:
parent
737af02fc8
commit
f440989017
@ -229,6 +229,8 @@ func NewMainKubelet(
|
|||||||
imageManager: imageManager,
|
imageManager: imageManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
klet.podManager = newBasicPodManager(klet.kubeClient)
|
||||||
|
|
||||||
dockerCache, err := dockertools.NewDockerCache(dockerClient)
|
dockerCache, err := dockertools.NewDockerCache(dockerClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -253,8 +255,6 @@ func NewMainKubelet(
|
|||||||
|
|
||||||
klet.podStatuses = make(map[string]api.PodStatus)
|
klet.podStatuses = make(map[string]api.PodStatus)
|
||||||
|
|
||||||
klet.mirrorManager = newBasicMirrorManager(klet.kubeClient)
|
|
||||||
|
|
||||||
return klet, nil
|
return klet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,20 +285,10 @@ type Kubelet struct {
|
|||||||
podStatusUpdateFrequency time.Duration
|
podStatusUpdateFrequency time.Duration
|
||||||
sourcesReady SourcesReadyFn
|
sourcesReady SourcesReadyFn
|
||||||
|
|
||||||
// Protects the pods array
|
podManager podManager
|
||||||
// We make complete array copies out of this while locked, which is OK because once added to this array,
|
|
||||||
// pods are immutable
|
|
||||||
podLock sync.RWMutex
|
|
||||||
pods []api.Pod
|
|
||||||
// Record the set of mirror pods (see mirror_manager.go for more details);
|
|
||||||
// similar to pods, this is not immutable and is protected by the same podLock.
|
|
||||||
// Note that Kubelet.pods do not contain mirror pods as they are filtered
|
|
||||||
// out beforehand.
|
|
||||||
mirrorPods mirrorPods
|
|
||||||
|
|
||||||
// A pod status cache stores statuses for pods (both rejected and synced).
|
// A pod status cache stores statuses for pods (both rejected and synced).
|
||||||
// Note that currently no thread attempts to acquire podStatusesLock while
|
// Note that currently no thread attempts to acquire podStatusesLock while
|
||||||
// holding podLock, and vice versa. If you intend to change this usage
|
// accessing podManager, and vice versa. If you intend to change this usage
|
||||||
// pattern, please explicitly impose an acquiring order to avoid deadlocks
|
// pattern, please explicitly impose an acquiring order to avoid deadlocks
|
||||||
// and document such an order in the comment.
|
// and document such an order in the comment.
|
||||||
podStatusesLock sync.RWMutex
|
podStatusesLock sync.RWMutex
|
||||||
@ -353,9 +343,6 @@ type Kubelet struct {
|
|||||||
// the EventRecorder to use
|
// the EventRecorder to use
|
||||||
recorder record.EventRecorder
|
recorder record.EventRecorder
|
||||||
|
|
||||||
// A mirror pod manager which provides helper functions.
|
|
||||||
mirrorManager mirrorManager
|
|
||||||
|
|
||||||
// Policy for handling garbage collection of dead containers.
|
// Policy for handling garbage collection of dead containers.
|
||||||
containerGC containerGC
|
containerGC containerGC
|
||||||
|
|
||||||
@ -1445,7 +1432,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, hasMirrorPod bool, containersInPod dock
|
|||||||
|
|
||||||
if !hasMirrorPod && isStaticPod(pod) {
|
if !hasMirrorPod && isStaticPod(pod) {
|
||||||
glog.V(4).Infof("Creating a mirror pod %q", podFullName)
|
glog.V(4).Infof("Creating a mirror pod %q", podFullName)
|
||||||
if err := kl.mirrorManager.CreateMirrorPod(*pod, kl.hostname); err != nil {
|
if err := kl.podManager.CreateMirrorPod(*pod, kl.hostname); err != nil {
|
||||||
glog.Errorf("Failed creating a mirror pod %q: %#v", podFullName, err)
|
glog.Errorf("Failed creating a mirror pod %q: %#v", podFullName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1572,7 +1559,7 @@ func (kl *Kubelet) SyncPods(allPods []api.Pod, podSyncTypes map[types.UID]metric
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the sync in an async manifest worker.
|
// Run the sync in an async manifest worker.
|
||||||
kl.podWorkers.UpdatePod(pod, kl.mirrorPods.HasMirrorPod(uid), func() {
|
kl.podWorkers.UpdatePod(pod, mirrorPods.HasMirrorPod(uid), func() {
|
||||||
metrics.SyncPodLatency.WithLabelValues(podSyncTypes[pod.UID].String()).Observe(metrics.SinceInMicroseconds(start))
|
metrics.SyncPodLatency.WithLabelValues(podSyncTypes[pod.UID].String()).Observe(metrics.SinceInMicroseconds(start))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1641,33 +1628,11 @@ func (kl *Kubelet) SyncPods(allPods []api.Pod, podSyncTypes map[types.UID]metric
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove any orphaned mirror pods.
|
// Remove any orphaned mirror pods.
|
||||||
deleteOrphanedMirrorPods(mirrorPods, kl.mirrorManager)
|
kl.podManager.DeleteOrphanedMirrorPods(&mirrorPods)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatePods(changed []api.Pod, current []api.Pod) []api.Pod {
|
|
||||||
updated := []api.Pod{}
|
|
||||||
m := map[types.UID]*api.Pod{}
|
|
||||||
for i := range changed {
|
|
||||||
pod := &changed[i]
|
|
||||||
m[pod.UID] = pod
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range current {
|
|
||||||
pod := ¤t[i]
|
|
||||||
if m[pod.UID] != nil {
|
|
||||||
updated = append(updated, *m[pod.UID])
|
|
||||||
glog.V(4).Infof("pod with UID: %q has a new spec %+v", pod.UID, *m[pod.UID])
|
|
||||||
} else {
|
|
||||||
updated = append(updated, *pod)
|
|
||||||
glog.V(4).Infof("pod with UID: %q stay with the same spec %+v", pod.UID, *pod)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return updated
|
|
||||||
}
|
|
||||||
|
|
||||||
type podsByCreationTime []api.Pod
|
type podsByCreationTime []api.Pod
|
||||||
|
|
||||||
func (s podsByCreationTime) Len() int {
|
func (s podsByCreationTime) Len() int {
|
||||||
@ -1771,7 +1736,7 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) {
|
|||||||
podSyncTypes := make(map[types.UID]metrics.SyncPodType)
|
podSyncTypes := make(map[types.UID]metrics.SyncPodType)
|
||||||
select {
|
select {
|
||||||
case u := <-updates:
|
case u := <-updates:
|
||||||
kl.updatePods(u, podSyncTypes)
|
kl.podManager.UpdatePods(u, podSyncTypes)
|
||||||
unsyncedPod = true
|
unsyncedPod = true
|
||||||
case <-time.After(kl.resyncInterval):
|
case <-time.After(kl.resyncInterval):
|
||||||
glog.V(4).Infof("Periodic sync")
|
glog.V(4).Infof("Periodic sync")
|
||||||
@ -1782,7 +1747,7 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) {
|
|||||||
for unsyncedPod {
|
for unsyncedPod {
|
||||||
select {
|
select {
|
||||||
case u := <-updates:
|
case u := <-updates:
|
||||||
kl.updatePods(u, podSyncTypes)
|
kl.podManager.UpdatePods(u, podSyncTypes)
|
||||||
case <-time.After(5 * time.Millisecond):
|
case <-time.After(5 * time.Millisecond):
|
||||||
// Break the for loop.
|
// Break the for loop.
|
||||||
unsyncedPod = false
|
unsyncedPod = false
|
||||||
@ -1830,52 +1795,6 @@ func (kl *Kubelet) syncStatus(deadline time.Duration) {
|
|||||||
t.Stop()
|
t.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the Kubelet's internal pods with those provided by the update.
|
|
||||||
// Records new and updated pods in newPods and updatedPods.
|
|
||||||
func (kl *Kubelet) updatePods(u PodUpdate, podSyncTypes map[types.UID]metrics.SyncPodType) {
|
|
||||||
kl.podLock.Lock()
|
|
||||||
defer kl.podLock.Unlock()
|
|
||||||
switch u.Op {
|
|
||||||
case SET:
|
|
||||||
glog.V(3).Infof("SET: Containers changed")
|
|
||||||
newPods, newMirrorPods := filterAndCategorizePods(u.Pods)
|
|
||||||
|
|
||||||
// Store the new pods. Don't worry about filtering host ports since those
|
|
||||||
// pods will never be looked up.
|
|
||||||
existingPods := make(map[types.UID]struct{})
|
|
||||||
for i := range kl.pods {
|
|
||||||
existingPods[kl.pods[i].UID] = struct{}{}
|
|
||||||
}
|
|
||||||
for _, pod := range newPods {
|
|
||||||
if _, ok := existingPods[pod.UID]; !ok {
|
|
||||||
podSyncTypes[pod.UID] = metrics.SyncPodCreate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Actually update the pods.
|
|
||||||
kl.pods = newPods
|
|
||||||
kl.mirrorPods = newMirrorPods
|
|
||||||
case UPDATE:
|
|
||||||
glog.V(3).Infof("Update: Containers changed")
|
|
||||||
|
|
||||||
// Store the updated pods. Don't worry about filtering host ports since those
|
|
||||||
// pods will never be looked up.
|
|
||||||
for i := range u.Pods {
|
|
||||||
podSyncTypes[u.Pods[i].UID] = metrics.SyncPodUpdate
|
|
||||||
}
|
|
||||||
allPods := updatePods(u.Pods, kl.pods)
|
|
||||||
kl.pods, kl.mirrorPods = filterAndCategorizePods(allPods)
|
|
||||||
default:
|
|
||||||
panic("syncLoop does not support incremental changes")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark all remaining pods as sync.
|
|
||||||
for i := range kl.pods {
|
|
||||||
if _, ok := podSyncTypes[kl.pods[i].UID]; !ok {
|
|
||||||
podSyncTypes[u.Pods[i].UID] = metrics.SyncPodSync
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns Docker version for this Kubelet.
|
// Returns Docker version for this Kubelet.
|
||||||
func (kl *Kubelet) GetDockerVersion() ([]uint, error) {
|
func (kl *Kubelet) GetDockerVersion() ([]uint, error) {
|
||||||
if kl.dockerClient == nil {
|
if kl.dockerClient == nil {
|
||||||
@ -1937,31 +1856,17 @@ func (kl *Kubelet) GetHostname() string {
|
|||||||
// GetPods returns all pods bound to the kubelet and their spec, and the mirror
|
// GetPods returns all pods bound to the kubelet and their spec, and the mirror
|
||||||
// pod map.
|
// pod map.
|
||||||
func (kl *Kubelet) GetPods() ([]api.Pod, mirrorPods) {
|
func (kl *Kubelet) GetPods() ([]api.Pod, mirrorPods) {
|
||||||
kl.podLock.RLock()
|
return kl.podManager.GetPods()
|
||||||
defer kl.podLock.RUnlock()
|
|
||||||
return append([]api.Pod{}, kl.pods...), kl.mirrorPods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kl *Kubelet) GetPodByFullName(podFullName string) (*api.Pod, bool) {
|
func (kl *Kubelet) GetPodByFullName(podFullName string) (*api.Pod, bool) {
|
||||||
name, namespace, err := ParsePodFullName(podFullName)
|
return kl.podManager.GetPodByFullName(podFullName)
|
||||||
if err != nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return kl.GetPodByName(namespace, name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPodByName provides the first pod that matches namespace and name, as well
|
// GetPodByName provides the first pod that matches namespace and name, as well
|
||||||
// as whether the pod was found.
|
// as whether the pod was found.
|
||||||
func (kl *Kubelet) GetPodByName(namespace, name string) (*api.Pod, bool) {
|
func (kl *Kubelet) GetPodByName(namespace, name string) (*api.Pod, bool) {
|
||||||
kl.podLock.RLock()
|
return kl.podManager.GetPodByName(namespace, name)
|
||||||
defer kl.podLock.RUnlock()
|
|
||||||
for i := range kl.pods {
|
|
||||||
pod := kl.pods[i]
|
|
||||||
if pod.Namespace == namespace && pod.Name == name {
|
|
||||||
return &pod, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateNodeStatus updates node status to master with retries.
|
// updateNodeStatus updates node status to master with retries.
|
||||||
@ -2108,7 +2013,7 @@ func getPodReadyCondition(spec *api.PodSpec, info api.PodInfo) []api.PodConditio
|
|||||||
|
|
||||||
// GetPodStatus returns information from Docker about the containers in a pod
|
// GetPodStatus returns information from Docker about the containers in a pod
|
||||||
func (kl *Kubelet) GetPodStatus(podFullName string, uid types.UID) (api.PodStatus, error) {
|
func (kl *Kubelet) GetPodStatus(podFullName string, uid types.UID) (api.PodStatus, error) {
|
||||||
uid = kl.translatePodUID(uid)
|
uid = kl.podManager.TranslatePodUID(uid)
|
||||||
|
|
||||||
// Check to see if we have a cached version of the status.
|
// Check to see if we have a cached version of the status.
|
||||||
cachedPodStatus, found := kl.getPodStatusFromCache(podFullName)
|
cachedPodStatus, found := kl.getPodStatusFromCache(podFullName)
|
||||||
@ -2172,7 +2077,7 @@ func (kl *Kubelet) ServeLogs(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
// Run a command in a container, returns the combined stdout, stderr as an array of bytes
|
// Run a command in a container, returns the combined stdout, stderr as an array of bytes
|
||||||
func (kl *Kubelet) RunInContainer(podFullName string, uid types.UID, container string, cmd []string) ([]byte, error) {
|
func (kl *Kubelet) RunInContainer(podFullName string, uid types.UID, container string, cmd []string) ([]byte, error) {
|
||||||
uid = kl.translatePodUID(uid)
|
uid = kl.podManager.TranslatePodUID(uid)
|
||||||
|
|
||||||
if kl.runner == nil {
|
if kl.runner == nil {
|
||||||
return nil, fmt.Errorf("no runner specified.")
|
return nil, fmt.Errorf("no runner specified.")
|
||||||
@ -2191,7 +2096,7 @@ func (kl *Kubelet) RunInContainer(podFullName string, uid types.UID, container s
|
|||||||
// ExecInContainer executes a command in a container, connecting the supplied
|
// ExecInContainer executes a command in a container, connecting the supplied
|
||||||
// stdin/stdout/stderr to the command's IO streams.
|
// stdin/stdout/stderr to the command's IO streams.
|
||||||
func (kl *Kubelet) ExecInContainer(podFullName string, uid types.UID, container string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
func (kl *Kubelet) ExecInContainer(podFullName string, uid types.UID, container string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
||||||
uid = kl.translatePodUID(uid)
|
uid = kl.podManager.TranslatePodUID(uid)
|
||||||
|
|
||||||
if kl.runner == nil {
|
if kl.runner == nil {
|
||||||
return fmt.Errorf("no runner specified.")
|
return fmt.Errorf("no runner specified.")
|
||||||
@ -2210,7 +2115,7 @@ func (kl *Kubelet) ExecInContainer(podFullName string, uid types.UID, container
|
|||||||
// PortForward connects to the pod's port and copies data between the port
|
// PortForward connects to the pod's port and copies data between the port
|
||||||
// and the stream.
|
// and the stream.
|
||||||
func (kl *Kubelet) PortForward(podFullName string, uid types.UID, port uint16, stream io.ReadWriteCloser) error {
|
func (kl *Kubelet) PortForward(podFullName string, uid types.UID, port uint16, stream io.ReadWriteCloser) error {
|
||||||
uid = kl.translatePodUID(uid)
|
uid = kl.podManager.TranslatePodUID(uid)
|
||||||
|
|
||||||
if kl.runner == nil {
|
if kl.runner == nil {
|
||||||
return fmt.Errorf("no runner specified.")
|
return fmt.Errorf("no runner specified.")
|
||||||
@ -2244,29 +2149,10 @@ func (kl *Kubelet) StreamingConnectionIdleTimeout() time.Duration {
|
|||||||
return kl.streamingConnectionIdleTimeout
|
return kl.streamingConnectionIdleTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the UID belongs to a mirror pod, maps it to the UID of its static pod.
|
|
||||||
// Otherwise, return the original UID. All public-facing functions should
|
|
||||||
// perform this translation for UIDs because user may provide a mirror pod UID,
|
|
||||||
// which is not recognized by internal Kubelet functions.
|
|
||||||
func (kl *Kubelet) translatePodUID(uid types.UID) types.UID {
|
|
||||||
if uid == "" {
|
|
||||||
return uid
|
|
||||||
}
|
|
||||||
|
|
||||||
kl.podLock.RLock()
|
|
||||||
defer kl.podLock.RUnlock()
|
|
||||||
staticUID, ok := kl.mirrorPods.GetStaticUID(uid)
|
|
||||||
if ok {
|
|
||||||
return staticUID
|
|
||||||
} else {
|
|
||||||
return uid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetContainerInfo returns stats (from Cadvisor) for a container.
|
// GetContainerInfo returns stats (from Cadvisor) for a container.
|
||||||
func (kl *Kubelet) GetContainerInfo(podFullName string, uid types.UID, containerName string, req *cadvisorApi.ContainerInfoRequest) (*cadvisorApi.ContainerInfo, error) {
|
func (kl *Kubelet) GetContainerInfo(podFullName string, uid types.UID, containerName string, req *cadvisorApi.ContainerInfoRequest) (*cadvisorApi.ContainerInfo, error) {
|
||||||
|
|
||||||
uid = kl.translatePodUID(uid)
|
uid = kl.podManager.TranslatePodUID(uid)
|
||||||
|
|
||||||
dockerContainers, err := dockertools.GetKubeletDockerContainers(kl.dockerClient, false)
|
dockerContainers, err := dockertools.GetKubeletDockerContainers(kl.dockerClient, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -105,9 +105,9 @@ func newTestKubelet(t *testing.T) *TestKubelet {
|
|||||||
}
|
}
|
||||||
mockCadvisor := &cadvisor.Mock{}
|
mockCadvisor := &cadvisor.Mock{}
|
||||||
kubelet.cadvisor = mockCadvisor
|
kubelet.cadvisor = mockCadvisor
|
||||||
mirrorManager := newFakeMirrorMananger()
|
podManager, fakeMirrorManager := newFakePodManager()
|
||||||
kubelet.mirrorManager = mirrorManager
|
kubelet.podManager = podManager
|
||||||
return &TestKubelet{kubelet, fakeDocker, mockCadvisor, fakeKubeClient, waitGroup, mirrorManager}
|
return &TestKubelet{kubelet, fakeDocker, mockCadvisor, fakeKubeClient, waitGroup, fakeMirrorManager}
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyCalls(t *testing.T, fakeDocker *dockertools.FakeDockerClient, calls []string) {
|
func verifyCalls(t *testing.T, fakeDocker *dockertools.FakeDockerClient, calls []string) {
|
||||||
@ -434,7 +434,7 @@ func TestSyncPodsDoesNothing(t *testing.T) {
|
|||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -448,8 +448,9 @@ func TestSyncPodsDoesNothing(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -468,7 +469,7 @@ func TestSyncPodsWithTerminationLog(t *testing.T) {
|
|||||||
TerminationMessagePath: "/dev/somepath",
|
TerminationMessagePath: "/dev/somepath",
|
||||||
}
|
}
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{}
|
fakeDocker.ContainerList = []docker.APIContainers{}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -482,8 +483,9 @@ func TestSyncPodsWithTerminationLog(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -518,7 +520,7 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
|
|||||||
waitGroup := testKubelet.waitGroup
|
waitGroup := testKubelet.waitGroup
|
||||||
kubelet.podInfraContainerImage = "custom_image_name"
|
kubelet.podInfraContainerImage = "custom_image_name"
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{}
|
fakeDocker.ContainerList = []docker.APIContainers{}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -532,8 +534,9 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -572,7 +575,7 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
|
|||||||
puller.HasImages = []string{}
|
puller.HasImages = []string{}
|
||||||
kubelet.podInfraContainerImage = "custom_image_name"
|
kubelet.podInfraContainerImage = "custom_image_name"
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{}
|
fakeDocker.ContainerList = []docker.APIContainers{}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -587,7 +590,8 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
kubelet.podManager.SetPods(pods)
|
||||||
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -623,7 +627,7 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
|||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -638,7 +642,8 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
kubelet.podManager.SetPods(pods)
|
||||||
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -670,7 +675,7 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
|||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -696,7 +701,8 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
waitGroup.Add(1)
|
waitGroup.Add(1)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
kubelet.podManager.SetPods(pods)
|
||||||
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -739,7 +745,7 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
|||||||
ID: "8765",
|
ID: "8765",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = []api.Pod{
|
pods := []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
@ -766,7 +772,8 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
waitGroup.Add(2)
|
waitGroup.Add(2)
|
||||||
err := kubelet.SyncPods(kubelet.pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
kubelet.podManager.SetPods(pods)
|
||||||
|
err := kubelet.SyncPods(pods, emptyPodUIDs, *newMirrorPods(), time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -907,7 +914,8 @@ func TestSyncPodDeletesDuplicate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = append(kubelet.pods, bound)
|
pods := []api.Pod{bound}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
err := kubelet.syncPod(&bound, false, dockerContainers)
|
err := kubelet.syncPod(&bound, false, dockerContainers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
@ -948,7 +956,8 @@ func TestSyncPodBadHash(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = append(kubelet.pods, bound)
|
pods := []api.Pod{bound}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
err := kubelet.syncPod(&bound, false, dockerContainers)
|
err := kubelet.syncPod(&bound, false, dockerContainers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
@ -1002,7 +1011,8 @@ func TestSyncPodUnhealthy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = append(kubelet.pods, bound)
|
pods := []api.Pod{bound}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
err := kubelet.syncPod(&bound, false, dockerContainers)
|
err := kubelet.syncPod(&bound, false, dockerContainers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
@ -1692,7 +1702,8 @@ func TestSyncPodEventHandlerFails(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubelet.pods = append(kubelet.pods, bound)
|
pods := []api.Pod{bound}
|
||||||
|
kubelet.podManager.SetPods(pods)
|
||||||
err := kubelet.syncPod(&bound, false, dockerContainers)
|
err := kubelet.syncPod(&bound, false, dockerContainers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
@ -2868,7 +2879,7 @@ func TestHandlePortConflicts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can retrieve the pod status from GetPodStatus().
|
// Check if we can retrieve the pod status from GetPodStatus().
|
||||||
kl.pods = pods
|
kl.podManager.SetPods(pods)
|
||||||
status, err := kl.GetPodStatus(conflictedPodName, "")
|
status, err := kl.GetPodStatus(conflictedPodName, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to retrieve pod status for pod %q: #v.", conflictedPodName, err)
|
t.Fatalf("unable to retrieve pod status for pod %q: #v.", conflictedPodName, err)
|
||||||
@ -2921,7 +2932,7 @@ func TestHandleNodeSelector(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can retrieve the pod status from GetPodStatus().
|
// Check if we can retrieve the pod status from GetPodStatus().
|
||||||
kl.pods = pods
|
kl.podManager.SetPods(pods)
|
||||||
status, err := kl.GetPodStatus(notfittingPodName, "")
|
status, err := kl.GetPodStatus(notfittingPodName, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to retrieve pod status for pod %q: #v.", notfittingPodName, err)
|
t.Fatalf("unable to retrieve pod status for pod %q: #v.", notfittingPodName, err)
|
||||||
@ -2980,7 +2991,7 @@ func TestHandleMemExceeded(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can retrieve the pod status from GetPodStatus().
|
// Check if we can retrieve the pod status from GetPodStatus().
|
||||||
kl.pods = pods
|
kl.podManager.SetPods(pods)
|
||||||
status, err := kl.GetPodStatus(notfittingPodName, "")
|
status, err := kl.GetPodStatus(notfittingPodName, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to retrieve pod status for pod %q: #v.", notfittingPodName, err)
|
t.Fatalf("unable to retrieve pod status for pod %q: #v.", notfittingPodName, err)
|
||||||
@ -3232,7 +3243,8 @@ func TestCreateMirrorPod(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kl.pods = append(kl.pods, pod)
|
pods := []api.Pod{pod}
|
||||||
|
kl.podManager.SetPods(pods)
|
||||||
hasMirrorPod := false
|
hasMirrorPod := false
|
||||||
err := kl.syncPod(&pod, hasMirrorPod, dockertools.DockerContainers{})
|
err := kl.syncPod(&pod, hasMirrorPod, dockertools.DockerContainers{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -3357,7 +3369,7 @@ func TestGetContainerInfoForMirrorPods(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
kubelet.pods, kubelet.mirrorPods = filterAndCategorizePods(pods)
|
kubelet.podManager.SetPods(pods)
|
||||||
// Use the mirror pod UID to retrieve the stats.
|
// Use the mirror pod UID to retrieve the stats.
|
||||||
stats, err := kubelet.GetContainerInfo("qux_ns", "5678", "foo", cadvisorReq)
|
stats, err := kubelet.GetContainerInfo("qux_ns", "5678", "foo", cadvisorReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -85,14 +85,6 @@ func (self *basicMirrorManager) DeleteMirrorPod(podFullName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all orphaned mirror pods.
|
|
||||||
func deleteOrphanedMirrorPods(mirrorPods mirrorPods, manager mirrorManager) {
|
|
||||||
podFullNames := mirrorPods.GetOrphanedMirrorPodNames()
|
|
||||||
for _, podFullName := range podFullNames {
|
|
||||||
manager.DeleteMirrorPod(podFullName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions.
|
// Helper functions.
|
||||||
func getPodSource(pod *api.Pod) (string, error) {
|
func getPodSource(pod *api.Pod) (string, error) {
|
||||||
if pod.Annotations != nil {
|
if pod.Annotations != nil {
|
||||||
|
199
pkg/kubelet/pod_manager.go
Normal file
199
pkg/kubelet/pod_manager.go
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 Google Inc. 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 (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/metrics"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
|
||||||
|
"github.com/golang/glog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type podManager interface {
|
||||||
|
UpdatePods(u PodUpdate, podSyncTypes map[types.UID]metrics.SyncPodType)
|
||||||
|
GetPods() ([]api.Pod, mirrorPods)
|
||||||
|
GetPodByName(namespace, name string) (*api.Pod, bool)
|
||||||
|
GetPodByFullName(podFullName string) (*api.Pod, bool)
|
||||||
|
TranslatePodUID(uid types.UID) types.UID
|
||||||
|
DeleteOrphanedMirrorPods(mirrorPods *mirrorPods)
|
||||||
|
SetPods(pods []api.Pod)
|
||||||
|
mirrorManager
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicPodManager struct {
|
||||||
|
// Protects all internal pod storage/mappings.
|
||||||
|
lock sync.RWMutex
|
||||||
|
pods []api.Pod
|
||||||
|
// Record the set of mirror pods (see mirror_manager.go for more details);
|
||||||
|
// similar to pods, this is not immutable and is protected by the same podLock.
|
||||||
|
// Note that basicPodManager.pods do not contain mirror pods as they are
|
||||||
|
// filtered out beforehand.
|
||||||
|
mirrorPods mirrorPods
|
||||||
|
|
||||||
|
// A mirror pod manager which provides helper functions.
|
||||||
|
mirrorManager mirrorManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBasicPodManager(apiserverClient client.Interface) *basicPodManager {
|
||||||
|
podManager := &basicPodManager{}
|
||||||
|
podManager.mirrorManager = newBasicMirrorManager(apiserverClient)
|
||||||
|
podManager.mirrorPods = *newMirrorPods()
|
||||||
|
podManager.pods = []api.Pod{}
|
||||||
|
return podManager
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is used only for testing to quickly set the internal pods.
|
||||||
|
func (self *basicPodManager) SetPods(pods []api.Pod) {
|
||||||
|
self.pods, self.mirrorPods = filterAndCategorizePods(pods)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the internal pods with those provided by the update.
|
||||||
|
// Records new and updated pods in newPods and updatedPods.
|
||||||
|
func (self *basicPodManager) UpdatePods(u PodUpdate, podSyncTypes map[types.UID]metrics.SyncPodType) {
|
||||||
|
self.lock.Lock()
|
||||||
|
defer self.lock.Unlock()
|
||||||
|
switch u.Op {
|
||||||
|
case SET:
|
||||||
|
glog.V(3).Infof("SET: Containers changed")
|
||||||
|
newPods, newMirrorPods := filterAndCategorizePods(u.Pods)
|
||||||
|
|
||||||
|
// Store the new pods. Don't worry about filtering host ports since those
|
||||||
|
// pods will never be looked up.
|
||||||
|
existingPods := make(map[types.UID]struct{})
|
||||||
|
for i := range self.pods {
|
||||||
|
existingPods[self.pods[i].UID] = struct{}{}
|
||||||
|
}
|
||||||
|
for _, pod := range newPods {
|
||||||
|
if _, ok := existingPods[pod.UID]; !ok {
|
||||||
|
podSyncTypes[pod.UID] = metrics.SyncPodCreate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Actually update the pods.
|
||||||
|
self.pods = newPods
|
||||||
|
self.mirrorPods = newMirrorPods
|
||||||
|
case UPDATE:
|
||||||
|
glog.V(3).Infof("Update: Containers changed")
|
||||||
|
|
||||||
|
// Store the updated pods. Don't worry about filtering host ports since those
|
||||||
|
// pods will never be looked up.
|
||||||
|
for i := range u.Pods {
|
||||||
|
podSyncTypes[u.Pods[i].UID] = metrics.SyncPodUpdate
|
||||||
|
}
|
||||||
|
allPods := updatePods(u.Pods, self.pods)
|
||||||
|
self.pods, self.mirrorPods = filterAndCategorizePods(allPods)
|
||||||
|
default:
|
||||||
|
panic("syncLoop does not support incremental changes")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark all remaining pods as sync.
|
||||||
|
for i := range self.pods {
|
||||||
|
if _, ok := podSyncTypes[self.pods[i].UID]; !ok {
|
||||||
|
podSyncTypes[u.Pods[i].UID] = metrics.SyncPodSync
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatePods(changed []api.Pod, current []api.Pod) []api.Pod {
|
||||||
|
updated := []api.Pod{}
|
||||||
|
m := map[types.UID]*api.Pod{}
|
||||||
|
for i := range changed {
|
||||||
|
pod := &changed[i]
|
||||||
|
m[pod.UID] = pod
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range current {
|
||||||
|
pod := ¤t[i]
|
||||||
|
if m[pod.UID] != nil {
|
||||||
|
updated = append(updated, *m[pod.UID])
|
||||||
|
glog.V(4).Infof("pod with UID: %q has a new spec %+v", pod.UID, *m[pod.UID])
|
||||||
|
} else {
|
||||||
|
updated = append(updated, *pod)
|
||||||
|
glog.V(4).Infof("pod with UID: %q stay with the same spec %+v", pod.UID, *pod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPods returns all pods bound to the kubelet and their spec, and the mirror
|
||||||
|
// pod map.
|
||||||
|
func (self *basicPodManager) GetPods() ([]api.Pod, mirrorPods) {
|
||||||
|
self.lock.RLock()
|
||||||
|
defer self.lock.RUnlock()
|
||||||
|
return append([]api.Pod{}, self.pods...), self.mirrorPods
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPodByName provides the first pod that matches namespace and name, as well
|
||||||
|
// as whether the pod was found.
|
||||||
|
func (self *basicPodManager) GetPodByName(namespace, name string) (*api.Pod, bool) {
|
||||||
|
self.lock.RLock()
|
||||||
|
defer self.lock.RUnlock()
|
||||||
|
for i := range self.pods {
|
||||||
|
pod := self.pods[i]
|
||||||
|
if pod.Namespace == namespace && pod.Name == name {
|
||||||
|
return &pod, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *basicPodManager) GetPodByFullName(podFullName string) (*api.Pod, bool) {
|
||||||
|
name, namespace, err := ParsePodFullName(podFullName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return self.GetPodByName(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the UID belongs to a mirror pod, maps it to the UID of its static pod.
|
||||||
|
// Otherwise, return the original UID. All public-facing functions should
|
||||||
|
// perform this translation for UIDs because user may provide a mirror pod UID,
|
||||||
|
// which is not recognized by internal Kubelet functions.
|
||||||
|
func (self *basicPodManager) TranslatePodUID(uid types.UID) types.UID {
|
||||||
|
if uid == "" {
|
||||||
|
return uid
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lock.RLock()
|
||||||
|
defer self.lock.RUnlock()
|
||||||
|
staticUID, ok := self.mirrorPods.GetStaticUID(uid)
|
||||||
|
if ok {
|
||||||
|
return staticUID
|
||||||
|
} else {
|
||||||
|
return uid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all orphaned mirror pods. This method doesn't acquire the lock
|
||||||
|
// because it assumes the a copy of the mirrorPod is passed as an argument.
|
||||||
|
func (self *basicPodManager) DeleteOrphanedMirrorPods(mirrorPods *mirrorPods) {
|
||||||
|
podFullNames := mirrorPods.GetOrphanedMirrorPodNames()
|
||||||
|
for _, podFullName := range podFullNames {
|
||||||
|
self.mirrorManager.DeleteMirrorPod(podFullName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *basicPodManager) CreateMirrorPod(pod api.Pod, hostname string) error {
|
||||||
|
return self.mirrorManager.CreateMirrorPod(pod, hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *basicPodManager) DeleteMirrorPod(podFullName string) error {
|
||||||
|
return self.mirrorManager.DeleteMirrorPod(podFullName)
|
||||||
|
}
|
25
pkg/kubelet/pod_manager_test.go
Normal file
25
pkg/kubelet/pod_manager_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 Google Inc. 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
|
||||||
|
|
||||||
|
// Stub out mirror manager for testing purpose.
|
||||||
|
func newFakePodManager() (*basicPodManager, *fakeMirrorManager) {
|
||||||
|
podManager := newBasicPodManager(nil)
|
||||||
|
fakeMirrorManager := newFakeMirrorMananger()
|
||||||
|
podManager.mirrorManager = fakeMirrorManager
|
||||||
|
return podManager, fakeMirrorManager
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user