mirror of https://github.com/k3s-io/k3s
Merge pull request #5103 from yujuhong/naming
kubelet: revamp the pod/container naming schemepull/6/head
commit
9439c0f3bd
|
@ -410,7 +410,7 @@ func createAndInitKubelet(kc *KubeletConfig, pc *config.PodConfig) (*kubelet.Kub
|
||||||
kc.RegistryBurst,
|
kc.RegistryBurst,
|
||||||
kc.MinimumGCAge,
|
kc.MinimumGCAge,
|
||||||
kc.MaxContainerCount,
|
kc.MaxContainerCount,
|
||||||
pc.IsSourceSeen,
|
pc.SeenAllSources,
|
||||||
kc.ClusterDomain,
|
kc.ClusterDomain,
|
||||||
net.IP(kc.ClusterDNS),
|
net.IP(kc.ClusterDNS),
|
||||||
kc.MasterServiceNamespace,
|
kc.MasterServiceNamespace,
|
||||||
|
|
|
@ -18,6 +18,7 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -55,6 +56,10 @@ type PodConfig struct {
|
||||||
|
|
||||||
// the channel of denormalized changes passed to listeners
|
// the channel of denormalized changes passed to listeners
|
||||||
updates chan kubelet.PodUpdate
|
updates chan kubelet.PodUpdate
|
||||||
|
|
||||||
|
// contains the list of all configured sources
|
||||||
|
sourcesLock sync.Mutex
|
||||||
|
sources util.StringSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPodConfig creates an object that can merge many configuration sources into a stream
|
// NewPodConfig creates an object that can merge many configuration sources into a stream
|
||||||
|
@ -66,6 +71,7 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder)
|
||||||
pods: storage,
|
pods: storage,
|
||||||
mux: config.NewMux(storage),
|
mux: config.NewMux(storage),
|
||||||
updates: updates,
|
updates: updates,
|
||||||
|
sources: util.StringSet{},
|
||||||
}
|
}
|
||||||
return podConfig
|
return podConfig
|
||||||
}
|
}
|
||||||
|
@ -73,17 +79,20 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder)
|
||||||
// Channel creates or returns a config source channel. The channel
|
// Channel creates or returns a config source channel. The channel
|
||||||
// only accepts PodUpdates
|
// only accepts PodUpdates
|
||||||
func (c *PodConfig) Channel(source string) chan<- interface{} {
|
func (c *PodConfig) Channel(source string) chan<- interface{} {
|
||||||
|
c.sourcesLock.Lock()
|
||||||
|
defer c.sourcesLock.Unlock()
|
||||||
|
c.sources.Insert(source)
|
||||||
return c.mux.Channel(source)
|
return c.mux.Channel(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSourceSeen returns true if the specified source string has previously
|
// SeenAllSources returns true if this config has received a SET
|
||||||
// been marked as seen.
|
// message from all configured sources, false otherwise.
|
||||||
func (c *PodConfig) IsSourceSeen(source string) bool {
|
func (c *PodConfig) SeenAllSources() bool {
|
||||||
if c.pods == nil {
|
if c.pods == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
glog.V(6).Infof("Looking for %v, have seen %v", source, c.pods.sourcesSeen)
|
glog.V(6).Infof("Looking for %v, have seen %v", c.sources.List(), c.pods.sourcesSeen)
|
||||||
return c.pods.seenSources(source)
|
return c.pods.seenSources(c.sources.List()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates returns a channel of updates to the configuration, properly denormalized.
|
// Updates returns a channel of updates to the configuration, properly denormalized.
|
||||||
|
@ -198,7 +207,7 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de
|
||||||
|
|
||||||
filtered := filterInvalidPods(update.Pods, source, s.recorder)
|
filtered := filterInvalidPods(update.Pods, source, s.recorder)
|
||||||
for _, ref := range filtered {
|
for _, ref := range filtered {
|
||||||
name := podUniqueName(ref)
|
name := kubelet.GetPodFullName(ref)
|
||||||
if existing, found := pods[name]; found {
|
if existing, found := pods[name]; found {
|
||||||
if !reflect.DeepEqual(existing.Spec, ref.Spec) {
|
if !reflect.DeepEqual(existing.Spec, ref.Spec) {
|
||||||
// this is an update
|
// this is an update
|
||||||
|
@ -221,7 +230,7 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de
|
||||||
case kubelet.REMOVE:
|
case kubelet.REMOVE:
|
||||||
glog.V(4).Infof("Removing a pod %v", update)
|
glog.V(4).Infof("Removing a pod %v", update)
|
||||||
for _, value := range update.Pods {
|
for _, value := range update.Pods {
|
||||||
name := podUniqueName(&value)
|
name := kubelet.GetPodFullName(&value)
|
||||||
if existing, found := pods[name]; found {
|
if existing, found := pods[name]; found {
|
||||||
// this is a delete
|
// this is a delete
|
||||||
delete(pods, name)
|
delete(pods, name)
|
||||||
|
@ -240,7 +249,7 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de
|
||||||
|
|
||||||
filtered := filterInvalidPods(update.Pods, source, s.recorder)
|
filtered := filterInvalidPods(update.Pods, source, s.recorder)
|
||||||
for _, ref := range filtered {
|
for _, ref := range filtered {
|
||||||
name := podUniqueName(ref)
|
name := kubelet.GetPodFullName(ref)
|
||||||
if existing, found := oldPods[name]; found {
|
if existing, found := oldPods[name]; found {
|
||||||
pods[name] = existing
|
pods[name] = existing
|
||||||
if !reflect.DeepEqual(existing.Spec, ref.Spec) {
|
if !reflect.DeepEqual(existing.Spec, ref.Spec) {
|
||||||
|
@ -298,7 +307,7 @@ func filterInvalidPods(pods []api.BoundPod, source string, recorder record.Event
|
||||||
// If validation fails, don't trust it any further -
|
// If validation fails, don't trust it any further -
|
||||||
// even Name could be bad.
|
// even Name could be bad.
|
||||||
} else {
|
} else {
|
||||||
name := podUniqueName(pod)
|
name := kubelet.GetPodFullName(pod)
|
||||||
if names.Has(name) {
|
if names.Has(name) {
|
||||||
errlist = append(errlist, apierrs.NewFieldDuplicate("name", pod.Name))
|
errlist = append(errlist, apierrs.NewFieldDuplicate("name", pod.Name))
|
||||||
} else {
|
} else {
|
||||||
|
@ -341,12 +350,6 @@ func (s *podStorage) MergedState() interface{} {
|
||||||
return pods
|
return pods
|
||||||
}
|
}
|
||||||
|
|
||||||
// podUniqueName returns a value for a given pod that is unique across a source,
|
|
||||||
// which is the combination of namespace and name.
|
|
||||||
func podUniqueName(pod *api.BoundPod) string {
|
|
||||||
return fmt.Sprintf("%s.%s", pod.Name, pod.Namespace)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bestPodIdentString(pod *api.BoundPod) string {
|
func bestPodIdentString(pod *api.BoundPod) string {
|
||||||
namespace := pod.Namespace
|
namespace := pod.Namespace
|
||||||
if namespace == "" {
|
if namespace == "" {
|
||||||
|
@ -358,3 +361,11 @@ func bestPodIdentString(pod *api.BoundPod) string {
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s.%s", name, namespace)
|
return fmt.Sprintf("%s.%s", name, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GeneratePodName(name string) (string, error) {
|
||||||
|
hostname, err := os.Hostname() //TODO: kubelet name would be better
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s-%s", name, hostname), nil
|
||||||
|
}
|
||||||
|
|
|
@ -108,11 +108,8 @@ func eventToPods(ev watch.Event) ([]api.BoundPod, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pod := range boundPods.Items {
|
for _, pod := range boundPods.Items {
|
||||||
// Backwards compatibility with old api servers
|
// Always overrides the namespace provided by the etcd event.
|
||||||
// TODO: Remove this after 1.0 release.
|
pod.Namespace = kubelet.NamespaceDefault
|
||||||
if len(pod.Namespace) == 0 {
|
|
||||||
pod.Namespace = api.NamespaceDefault
|
|
||||||
}
|
|
||||||
pods = append(pods, pod)
|
pods = append(pods, pod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,14 @@ func TestEventToPods(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pods: []api.BoundPod{
|
pods: []api.BoundPod{
|
||||||
{ObjectMeta: api.ObjectMeta{UID: "111", Name: "foo", Namespace: "foo"}, Spec: api.PodSpec{}},
|
{
|
||||||
{ObjectMeta: api.ObjectMeta{UID: "222", Name: "bar", Namespace: "bar"}, Spec: api.PodSpec{}},
|
ObjectMeta: api.ObjectMeta{UID: "111", Name: "foo", Namespace: kubelet.NamespaceDefault},
|
||||||
|
Spec: api.PodSpec{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{UID: "222", Name: "bar", Namespace: kubelet.NamespaceDefault},
|
||||||
|
Spec: api.PodSpec{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fail: false,
|
fail: false,
|
||||||
},
|
},
|
||||||
|
@ -116,7 +122,9 @@ func TestEventToPods(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pods: []api.BoundPod{
|
pods: []api.BoundPod{
|
||||||
{ObjectMeta: api.ObjectMeta{UID: "111", Name: "foo", Namespace: "default"}, Spec: api.PodSpec{}},
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{UID: "111", Name: "foo", Namespace: kubelet.NamespaceDefault},
|
||||||
|
Spec: api.PodSpec{}},
|
||||||
},
|
},
|
||||||
fail: false,
|
fail: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/adler32"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -186,17 +185,16 @@ func extractFromFile(filename string) (api.BoundPod, error) {
|
||||||
// completely deprecate ContainerManifest.
|
// completely deprecate ContainerManifest.
|
||||||
if len(pod.Name) == 0 {
|
if len(pod.Name) == 0 {
|
||||||
pod.Name = string(pod.UID)
|
pod.Name = string(pod.UID)
|
||||||
|
}
|
||||||
|
if pod.Name, err = GeneratePodName(pod.Name); err != nil {
|
||||||
|
return pod, err
|
||||||
|
}
|
||||||
glog.V(5).Infof("Generated Name %q for UID %q from file %s", pod.Name, pod.UID, filename)
|
glog.V(5).Infof("Generated Name %q for UID %q from file %s", pod.Name, pod.UID, filename)
|
||||||
}
|
|
||||||
if len(pod.Namespace) == 0 {
|
// Always overrides the namespace provided by the file.
|
||||||
hasher := adler32.New()
|
pod.Namespace = kubelet.NamespaceDefault
|
||||||
fmt.Fprint(hasher, filename)
|
glog.V(5).Infof("Using namespace %q for pod %q from file %s", pod.Namespace, pod.Name, filename)
|
||||||
// TODO: file-<sum>.hostname would be better, if DNS subdomains
|
|
||||||
// are allowed for namespace (some places only allow DNS
|
|
||||||
// labels).
|
|
||||||
pod.Namespace = fmt.Sprintf("file-%08x-%s", hasher.Sum32(), hostname)
|
|
||||||
glog.V(5).Infof("Generated namespace %q for pod %q from file %s", pod.Namespace, pod.Name, filename)
|
|
||||||
}
|
|
||||||
// TODO(dchen1107): BoundPod is not type of runtime.Object. Once we allow kubelet talks
|
// TODO(dchen1107): BoundPod is not type of runtime.Object. Once we allow kubelet talks
|
||||||
// about Pod directly, we can use SelfLinker defined in package: latest
|
// about Pod directly, we can use SelfLinker defined in package: latest
|
||||||
// Currently just simply follow the same format in resthandler.go
|
// Currently just simply follow the same format in resthandler.go
|
||||||
|
|
|
@ -56,6 +56,7 @@ func ExampleManifestAndPod(id string) (v1beta1.ContainerManifest, api.BoundPod)
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: id,
|
Name: id,
|
||||||
UID: types.UID(id),
|
UID: types.UID(id),
|
||||||
|
Namespace: kubelet.NamespaceDefault,
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -131,27 +132,30 @@ func TestReadFromFile(t *testing.T) {
|
||||||
update := got.(kubelet.PodUpdate)
|
update := got.(kubelet.PodUpdate)
|
||||||
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, api.BoundPod{
|
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "test",
|
Name: "",
|
||||||
UID: "12345",
|
UID: "12345",
|
||||||
Namespace: "",
|
Namespace: kubelet.NamespaceDefault,
|
||||||
SelfLink: "",
|
SelfLink: "",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if !strings.HasPrefix(update.Pods[0].Name, "test-") {
|
||||||
|
t.Errorf("Unexpected name: %s", update.Pods[0].Name)
|
||||||
|
}
|
||||||
// There's no way to provide namespace in ContainerManifest, so
|
// There's no way to provide namespace in ContainerManifest, so
|
||||||
// it will be defaulted.
|
// it will be defaulted.
|
||||||
if !strings.HasPrefix(update.Pods[0].ObjectMeta.Namespace, "file-") {
|
if update.Pods[0].Namespace != kubelet.NamespaceDefault {
|
||||||
t.Errorf("Unexpected namespace: %s", update.Pods[0].ObjectMeta.Namespace)
|
t.Errorf("Unexpected namespace: %s", update.Pods[0].Namespace)
|
||||||
}
|
}
|
||||||
update.Pods[0].ObjectMeta.Namespace = ""
|
|
||||||
|
|
||||||
// SelfLink depends on namespace.
|
// SelfLink depends on namespace.
|
||||||
if !strings.HasPrefix(update.Pods[0].ObjectMeta.SelfLink, "/api/") {
|
if !strings.HasPrefix(update.Pods[0].SelfLink, "/api/") {
|
||||||
t.Errorf("Unexpected selflink: %s", update.Pods[0].ObjectMeta.SelfLink)
|
t.Errorf("Unexpected selflink: %s", update.Pods[0].SelfLink)
|
||||||
}
|
}
|
||||||
update.Pods[0].ObjectMeta.SelfLink = ""
|
|
||||||
|
|
||||||
|
// Reset the fileds that we don't want to compare.
|
||||||
|
update.Pods[0].Name = ""
|
||||||
|
update.Pods[0].SelfLink = ""
|
||||||
if !api.Semantic.DeepDerivative(expected, update) {
|
if !api.Semantic.DeepDerivative(expected, update) {
|
||||||
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +183,7 @@ func TestReadFromFileWithoutID(t *testing.T) {
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "",
|
Name: "",
|
||||||
UID: "12345",
|
UID: "12345",
|
||||||
Namespace: "",
|
Namespace: kubelet.NamespaceDefault,
|
||||||
SelfLink: "",
|
SelfLink: "",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
||||||
|
@ -188,10 +192,9 @@ func TestReadFromFileWithoutID(t *testing.T) {
|
||||||
if len(update.Pods[0].ObjectMeta.Name) == 0 {
|
if len(update.Pods[0].ObjectMeta.Name) == 0 {
|
||||||
t.Errorf("Name did not get defaulted")
|
t.Errorf("Name did not get defaulted")
|
||||||
}
|
}
|
||||||
update.Pods[0].ObjectMeta.Name = ""
|
// Reset the fileds that we don't want to compare.
|
||||||
update.Pods[0].ObjectMeta.Namespace = ""
|
update.Pods[0].Name = ""
|
||||||
update.Pods[0].ObjectMeta.SelfLink = ""
|
update.Pods[0].SelfLink = ""
|
||||||
|
|
||||||
if !api.Semantic.DeepDerivative(expected, update) {
|
if !api.Semantic.DeepDerivative(expected, update) {
|
||||||
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
||||||
}
|
}
|
||||||
|
@ -218,17 +221,17 @@ func TestReadV1Beta2FromFile(t *testing.T) {
|
||||||
update := got.(kubelet.PodUpdate)
|
update := got.(kubelet.PodUpdate)
|
||||||
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, api.BoundPod{
|
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "test",
|
Name: "",
|
||||||
UID: "12345",
|
UID: "12345",
|
||||||
Namespace: "",
|
Namespace: kubelet.NamespaceDefault,
|
||||||
SelfLink: "",
|
SelfLink: "",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
||||||
})
|
})
|
||||||
|
|
||||||
update.Pods[0].ObjectMeta.Namespace = ""
|
// Reset the fileds that we don't want to compare.
|
||||||
update.Pods[0].ObjectMeta.SelfLink = ""
|
update.Pods[0].Name = ""
|
||||||
|
update.Pods[0].SelfLink = ""
|
||||||
if !api.Semantic.DeepDerivative(expected, update) {
|
if !api.Semantic.DeepDerivative(expected, update) {
|
||||||
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
||||||
}
|
}
|
||||||
|
@ -252,8 +255,8 @@ func TestReadFromFileWithDefaults(t *testing.T) {
|
||||||
select {
|
select {
|
||||||
case got := <-ch:
|
case got := <-ch:
|
||||||
update := got.(kubelet.PodUpdate)
|
update := got.(kubelet.PodUpdate)
|
||||||
if update.Pods[0].ObjectMeta.UID == "" {
|
if update.Pods[0].UID == "" {
|
||||||
t.Errorf("Unexpected UID: %s", update.Pods[0].ObjectMeta.UID)
|
t.Errorf("Unexpected UID: %s", update.Pods[0].UID)
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-time.After(time.Second):
|
case <-time.After(time.Second):
|
||||||
|
@ -337,12 +340,16 @@ func TestExtractFromDir(t *testing.T) {
|
||||||
|
|
||||||
update := (<-ch).(kubelet.PodUpdate)
|
update := (<-ch).(kubelet.PodUpdate)
|
||||||
for i := range update.Pods {
|
for i := range update.Pods {
|
||||||
update.Pods[i].Namespace = "foobar"
|
// Pod name is generated with hash and is unique. Skip the comparision
|
||||||
|
// here by setting it to a simple value.
|
||||||
|
update.Pods[i].Name = manifests[i].ID
|
||||||
update.Pods[i].SelfLink = ""
|
update.Pods[i].SelfLink = ""
|
||||||
}
|
}
|
||||||
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, pods...)
|
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, pods...)
|
||||||
for i := range expected.Pods {
|
for i := range expected.Pods {
|
||||||
expected.Pods[i].Namespace = "foobar"
|
// Pod name is generated with hash and is unique. Skip the comparision
|
||||||
|
// here by setting it to a simple value.
|
||||||
|
expected.Pods[i].Name = manifests[i].ID
|
||||||
}
|
}
|
||||||
sort.Sort(sortedPods(update.Pods))
|
sort.Sort(sortedPods(update.Pods))
|
||||||
sort.Sort(sortedPods(expected.Pods))
|
sort.Sort(sortedPods(expected.Pods))
|
||||||
|
@ -351,7 +358,7 @@ func TestExtractFromDir(t *testing.T) {
|
||||||
}
|
}
|
||||||
for i := range update.Pods {
|
for i := range update.Pods {
|
||||||
if errs := validation.ValidateBoundPod(&update.Pods[i]); len(errs) != 0 {
|
if errs := validation.ValidateBoundPod(&update.Pods[i]); len(errs) != 0 {
|
||||||
t.Errorf("Expected no validation errors on %#v, Got %#v", update.Pods[i], errs)
|
t.Errorf("Expected no validation errors on %#v, Got %q", update.Pods[i], errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/adler32"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -92,7 +91,9 @@ func (s *sourceURL) extractFromURL() error {
|
||||||
return singleErr
|
return singleErr
|
||||||
}
|
}
|
||||||
// It parsed!
|
// It parsed!
|
||||||
applyDefaults(&pod, s.url)
|
if err = applyDefaults(&pod, s.url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
s.updates <- kubelet.PodUpdate{[]api.BoundPod{pod}, kubelet.SET, kubelet.HTTPSource}
|
s.updates <- kubelet.PodUpdate{[]api.BoundPod{pod}, kubelet.SET, kubelet.HTTPSource}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -114,7 +115,9 @@ func (s *sourceURL) extractFromURL() error {
|
||||||
// Assume it parsed.
|
// Assume it parsed.
|
||||||
for i := range pods.Items {
|
for i := range pods.Items {
|
||||||
pod := &pods.Items[i]
|
pod := &pods.Items[i]
|
||||||
applyDefaults(pod, s.url)
|
if err = applyDefaults(pod, s.url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s.updates <- kubelet.PodUpdate{pods.Items, kubelet.SET, kubelet.HTTPSource}
|
s.updates <- kubelet.PodUpdate{pods.Items, kubelet.SET, kubelet.HTTPSource}
|
||||||
return nil
|
return nil
|
||||||
|
@ -180,7 +183,7 @@ func tryDecodeList(data []byte) (parsed bool, manifests []v1beta1.ContainerManif
|
||||||
return true, manifests, pods, nil
|
return true, manifests, pods, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyDefaults(pod *api.BoundPod, url string) {
|
func applyDefaults(pod *api.BoundPod, url string) error {
|
||||||
if len(pod.UID) == 0 {
|
if len(pod.UID) == 0 {
|
||||||
hasher := md5.New()
|
hasher := md5.New()
|
||||||
fmt.Fprintf(hasher, "url:%s", url)
|
fmt.Fprintf(hasher, "url:%s", url)
|
||||||
|
@ -190,14 +193,18 @@ func applyDefaults(pod *api.BoundPod, url string) {
|
||||||
}
|
}
|
||||||
// This is required for backward compatibility, and should be removed once we
|
// This is required for backward compatibility, and should be removed once we
|
||||||
// completely deprecate ContainerManifest.
|
// completely deprecate ContainerManifest.
|
||||||
|
var err error
|
||||||
if len(pod.Name) == 0 {
|
if len(pod.Name) == 0 {
|
||||||
pod.Name = string(pod.UID)
|
pod.Name = string(pod.UID)
|
||||||
glog.V(5).Infof("Generate Name %q from UID %q from URL %s", pod.Name, pod.UID, url)
|
|
||||||
}
|
}
|
||||||
if len(pod.Namespace) == 0 {
|
pod.Name, err = GeneratePodName(pod.Name)
|
||||||
hasher := adler32.New()
|
if err != nil {
|
||||||
fmt.Fprint(hasher, url)
|
return err
|
||||||
pod.Namespace = fmt.Sprintf("url-%08x", hasher.Sum32())
|
|
||||||
glog.V(5).Infof("Generated namespace %q for pod %q from URL %s", pod.Namespace, pod.Name, url)
|
|
||||||
}
|
}
|
||||||
|
glog.V(5).Infof("Generated Name %q for UID %q from URL %s", pod.Name, pod.UID, url)
|
||||||
|
|
||||||
|
// Always overrides the namespace.
|
||||||
|
pod.Namespace = kubelet.NamespaceDefault
|
||||||
|
glog.V(5).Infof("Using namespace %q for pod %q from URL %s", pod.Namespace, pod.Name, url)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ package config
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -117,6 +117,8 @@ func TestExtractInvalidManifest(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractFromHTTP(t *testing.T) {
|
func TestExtractFromHTTP(t *testing.T) {
|
||||||
|
hostname, _ := os.Hostname()
|
||||||
|
|
||||||
var testCases = []struct {
|
var testCases = []struct {
|
||||||
desc string
|
desc string
|
||||||
manifests interface{}
|
manifests interface{}
|
||||||
|
@ -131,7 +133,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
api.BoundPod{
|
api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "111",
|
UID: "111",
|
||||||
Name: "foo",
|
Name: "foo" + "-" + hostname,
|
||||||
Namespace: "foobar",
|
Namespace: "foobar",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
|
@ -153,7 +155,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
api.BoundPod{
|
api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "111",
|
UID: "111",
|
||||||
Name: "111",
|
Name: "111" + "-" + hostname,
|
||||||
Namespace: "foobar",
|
Namespace: "foobar",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
|
@ -171,7 +173,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
api.BoundPod{
|
api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "111",
|
UID: "111",
|
||||||
Name: "foo",
|
Name: "foo" + "-" + hostname,
|
||||||
Namespace: "foobar",
|
Namespace: "foobar",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
|
@ -198,7 +200,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
api.BoundPod{
|
api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "111",
|
UID: "111",
|
||||||
Name: "foo",
|
Name: "foo" + "-" + hostname,
|
||||||
Namespace: "foobar",
|
Namespace: "foobar",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
|
@ -214,7 +216,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
api.BoundPod{
|
api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: "222",
|
UID: "222",
|
||||||
Name: "bar",
|
Name: "bar" + "-" + hostname,
|
||||||
Namespace: "foobar",
|
Namespace: "foobar",
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
|
@ -234,6 +236,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
expected: CreatePodUpdate(kubelet.SET, kubelet.HTTPSource),
|
expected: CreatePodUpdate(kubelet.SET, kubelet.HTTPSource),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
data, err := json.Marshal(testCase.manifests)
|
data, err := json.Marshal(testCase.manifests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -256,8 +259,8 @@ func TestExtractFromHTTP(t *testing.T) {
|
||||||
for i := range update.Pods {
|
for i := range update.Pods {
|
||||||
// There's no way to provide namespace in ContainerManifest, so
|
// There's no way to provide namespace in ContainerManifest, so
|
||||||
// it will be defaulted.
|
// it will be defaulted.
|
||||||
if !strings.HasPrefix(update.Pods[i].ObjectMeta.Namespace, "url-") {
|
if update.Pods[i].Namespace != kubelet.NamespaceDefault {
|
||||||
t.Errorf("Unexpected namespace: %s", update.Pods[0].ObjectMeta.Namespace)
|
t.Errorf("Unexpected namespace: %s", update.Pods[0].Namespace)
|
||||||
}
|
}
|
||||||
update.Pods[i].ObjectMeta.Namespace = "foobar"
|
update.Pods[i].ObjectMeta.Namespace = "foobar"
|
||||||
}
|
}
|
||||||
|
|
|
@ -719,11 +719,11 @@ func ParseDockerName(name string) (podFullName string, podUID types.UID, contain
|
||||||
if len(parts) == 0 || parts[0] != containerNamePrefix {
|
if len(parts) == 0 || parts[0] != containerNamePrefix {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(parts) < 5 {
|
if len(parts) < 6 {
|
||||||
// We have at least 5 fields. We may have more in the future.
|
// We have at least 5 fields. We may have more in the future.
|
||||||
// Anything with less fields than this is not something we can
|
// Anything with less fields than this is not something we can
|
||||||
// manage.
|
// manage.
|
||||||
glog.Warningf("found a container with the %q prefix, but too few fields (%d): ", containerNamePrefix, len(parts), name)
|
glog.Warningf("found a container with the %q prefix, but too few fields (%d): %q", containerNamePrefix, len(parts), name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,11 +739,10 @@ func ParseDockerName(name string) (podFullName string, podUID types.UID, contain
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pod fullname.
|
// Pod fullname.
|
||||||
podFullName = parts[2]
|
podFullName = parts[2] + "_" + parts[3]
|
||||||
|
|
||||||
// Pod UID.
|
// Pod UID.
|
||||||
podUID = types.UID(parts[3])
|
podUID = types.UID(parts[4])
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,11 @@ func TestGetContainerID(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_bar_qux_2565_42"},
|
Names: []string{"/k8s_bar_qux_ns_2565_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fakeDocker.Container = &docker.Container{
|
fakeDocker.Container = &docker.Container{
|
||||||
|
@ -73,7 +73,7 @@ func TestGetContainerID(t *testing.T) {
|
||||||
t.Errorf("Expected %#v, Got %#v", fakeDocker.ContainerList, dockerContainers)
|
t.Errorf("Expected %#v, Got %#v", fakeDocker.ContainerList, dockerContainers)
|
||||||
}
|
}
|
||||||
verifyCalls(t, fakeDocker, []string{"list"})
|
verifyCalls(t, fakeDocker, []string{"list"})
|
||||||
dockerContainer, found, _ := dockerContainers.FindPodContainer("qux", "", "foo")
|
dockerContainer, found, _ := dockerContainers.FindPodContainer("qux_ns", "", "foo")
|
||||||
if dockerContainer == nil || !found {
|
if dockerContainer == nil || !found {
|
||||||
t.Errorf("Failed to find container %#v", dockerContainer)
|
t.Errorf("Failed to find container %#v", dockerContainer)
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ func verifyPackUnpack(t *testing.T, podNamespace, podUID, podName, containerName
|
||||||
hasher := adler32.New()
|
hasher := adler32.New()
|
||||||
util.DeepHashObject(hasher, *container)
|
util.DeepHashObject(hasher, *container)
|
||||||
computedHash := uint64(hasher.Sum32())
|
computedHash := uint64(hasher.Sum32())
|
||||||
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
||||||
name := BuildDockerName(types.UID(podUID), podFullName, container)
|
name := BuildDockerName(types.UID(podUID), podFullName, container)
|
||||||
returnedPodFullName, returnedUID, returnedContainerName, hash := ParseDockerName(name)
|
returnedPodFullName, returnedUID, returnedContainerName, hash := ParseDockerName(name)
|
||||||
if podFullName != returnedPodFullName || podUID != string(returnedUID) || containerName != returnedContainerName || computedHash != hash {
|
if podFullName != returnedPodFullName || podUID != string(returnedUID) || containerName != returnedContainerName || computedHash != hash {
|
||||||
|
@ -111,8 +111,8 @@ func TestContainerManifestNaming(t *testing.T) {
|
||||||
container := &api.Container{Name: "container"}
|
container := &api.Container{Name: "container"}
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
podNamespace := "test"
|
podNamespace := "test"
|
||||||
name := fmt.Sprintf("k8s_%s_%s.%s_%s_42", container.Name, podName, podNamespace, podUID)
|
name := fmt.Sprintf("k8s_%s_%s_%s_%s_42", container.Name, podName, podNamespace, podUID)
|
||||||
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
||||||
|
|
||||||
returnedPodFullName, returnedPodUID, returnedContainerName, hash := ParseDockerName(name)
|
returnedPodFullName, returnedPodUID, returnedContainerName, hash := ParseDockerName(name)
|
||||||
if returnedPodFullName != podFullName || string(returnedPodUID) != podUID || returnedContainerName != container.Name || hash != 0 {
|
if returnedPodFullName != podFullName || string(returnedPodUID) != podUID || returnedContainerName != container.Name || hash != 0 {
|
||||||
|
@ -463,15 +463,15 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
types.UID("1234"),
|
types.UID("1234"),
|
||||||
|
@ -479,15 +479,15 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -495,15 +495,15 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_foo_qux_2343_42"},
|
Names: []string{"/k8s_foo_qux_ns_2343_42"},
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
types.UID("1234"),
|
types.UID("1234"),
|
||||||
|
@ -511,11 +511,11 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -523,15 +523,15 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_foo_qux_2343_42"},
|
Names: []string{"/k8s_foo_qux_ns_2343_42"},
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
types.UID("5678"),
|
types.UID("5678"),
|
||||||
|
@ -542,7 +542,7 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
|
@ -550,7 +550,7 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_5678_42"},
|
Names: []string{"/k8s_foo_qux_ns_5678_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
types.UID("5678"),
|
types.UID("5678"),
|
||||||
|
@ -558,7 +558,7 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_5678_42"},
|
Names: []string{"/k8s_foo_qux_ns_5678_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -566,23 +566,23 @@ func TestFindContainersByPod(t *testing.T) {
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"foobar": &docker.APIContainers{
|
"foobar": &docker.APIContainers{
|
||||||
ID: "foobar",
|
ID: "foobar",
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_foo_abc_5678_42"},
|
Names: []string{"/k8s_foo_abc_ns_5678_42"},
|
||||||
},
|
},
|
||||||
"baz": &docker.APIContainers{
|
"baz": &docker.APIContainers{
|
||||||
ID: "baz",
|
ID: "baz",
|
||||||
Names: []string{"/k8s_foo_qux_5678_42"},
|
Names: []string{"/k8s_foo_qux_ns_5678_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"",
|
"",
|
||||||
"abc",
|
"abc_ns",
|
||||||
DockerContainers{
|
DockerContainers{
|
||||||
"barbar": &docker.APIContainers{
|
"barbar": &docker.APIContainers{
|
||||||
ID: "barbar",
|
ID: "barbar",
|
||||||
Names: []string{"/k8s_foo_abc_5678_42"},
|
Names: []string{"/k8s_foo_abc_ns_5678_42"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -69,7 +69,7 @@ type SyncHandler interface {
|
||||||
SyncPods(pods []api.BoundPod, podSyncTypes map[types.UID]metrics.SyncPodType, startTime time.Time) error
|
SyncPods(pods []api.BoundPod, podSyncTypes map[types.UID]metrics.SyncPodType, startTime time.Time) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type SourceReadyFn func(source string) bool
|
type SourcesReadyFn func() bool
|
||||||
|
|
||||||
type volumeMap map[string]volume.Interface
|
type volumeMap map[string]volume.Interface
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ func NewMainKubelet(
|
||||||
pullBurst int,
|
pullBurst int,
|
||||||
minimumGCAge time.Duration,
|
minimumGCAge time.Duration,
|
||||||
maxContainerCount int,
|
maxContainerCount int,
|
||||||
sourceReady SourceReadyFn,
|
sourcesReady SourcesReadyFn,
|
||||||
clusterDomain string,
|
clusterDomain string,
|
||||||
clusterDNS net.IP,
|
clusterDNS net.IP,
|
||||||
masterServiceNamespace string,
|
masterServiceNamespace string,
|
||||||
|
@ -135,7 +135,7 @@ func NewMainKubelet(
|
||||||
pullBurst: pullBurst,
|
pullBurst: pullBurst,
|
||||||
minimumGCAge: minimumGCAge,
|
minimumGCAge: minimumGCAge,
|
||||||
maxContainerCount: maxContainerCount,
|
maxContainerCount: maxContainerCount,
|
||||||
sourceReady: sourceReady,
|
sourcesReady: sourcesReady,
|
||||||
clusterDomain: clusterDomain,
|
clusterDomain: clusterDomain,
|
||||||
clusterDNS: clusterDNS,
|
clusterDNS: clusterDNS,
|
||||||
serviceLister: serviceLister,
|
serviceLister: serviceLister,
|
||||||
|
@ -185,7 +185,7 @@ type Kubelet struct {
|
||||||
podInfraContainerImage string
|
podInfraContainerImage string
|
||||||
podWorkers *podWorkers
|
podWorkers *podWorkers
|
||||||
resyncInterval time.Duration
|
resyncInterval time.Duration
|
||||||
sourceReady SourceReadyFn
|
sourcesReady SourcesReadyFn
|
||||||
|
|
||||||
// Protects the pods array
|
// Protects the pods array
|
||||||
// We make complete array copies out of this while locked, which is OK because once added to this array,
|
// We make complete array copies out of this while locked, which is OK because once added to this array,
|
||||||
|
@ -1402,10 +1402,16 @@ func (kl *Kubelet) SyncPods(allPods []api.BoundPod, podSyncTypes map[types.UID]m
|
||||||
metrics.ContainersPerPodCount.Observe(float64(len(pod.Spec.Containers)))
|
metrics.ContainersPerPodCount.Observe(float64(len(pod.Spec.Containers)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the workers for no-longer existing pods.
|
// Stop the workers for no-longer existing pods.
|
||||||
kl.podWorkers.ForgetNonExistingPodWorkers(desiredPods)
|
kl.podWorkers.ForgetNonExistingPodWorkers(desiredPods)
|
||||||
|
|
||||||
|
if !kl.sourcesReady() {
|
||||||
|
// If the sources aren't ready, skip deletion, as we may accidentally delete pods
|
||||||
|
// for sources that haven't reported yet.
|
||||||
|
glog.V(4).Infof("Skipping deletes, sources aren't ready yet.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Kill any containers we don't need.
|
// Kill any containers we don't need.
|
||||||
killed := []string{}
|
killed := []string{}
|
||||||
for ix := range dockerContainers {
|
for ix := range dockerContainers {
|
||||||
|
@ -1415,13 +1421,7 @@ func (kl *Kubelet) SyncPods(allPods []api.BoundPod, podSyncTypes map[types.UID]m
|
||||||
// syncPod() will handle this one.
|
// syncPod() will handle this one.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, _, podAnnotations := ParsePodFullName(podFullName)
|
|
||||||
if source := podAnnotations[ConfigSourceAnnotationKey]; !kl.sourceReady(source) {
|
|
||||||
// If the source for this container is not ready, skip deletion, so that we don't accidentally
|
|
||||||
// delete containers for sources that haven't reported yet.
|
|
||||||
glog.V(4).Infof("Skipping delete of container (%q), source (%s) aren't ready yet.", podFullName, source)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pc := podContainer{podFullName, uid, containerName}
|
pc := podContainer{podFullName, uid, containerName}
|
||||||
if _, ok := desiredContainers[pc]; !ok {
|
if _, ok := desiredContainers[pc]; !ok {
|
||||||
glog.V(1).Infof("Killing unwanted container %+v", pc)
|
glog.V(1).Infof("Killing unwanted container %+v", pc)
|
||||||
|
|
|
@ -78,7 +78,7 @@ func newTestKubelet(t *testing.T) (*Kubelet, *dockertools.FakeDockerClient, *syn
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
recorder)
|
recorder)
|
||||||
kubelet.sourceReady = func(source string) bool { return true }
|
kubelet.sourcesReady = func() bool { return true }
|
||||||
kubelet.masterServiceNamespace = api.NamespaceDefault
|
kubelet.masterServiceNamespace = api.NamespaceDefault
|
||||||
kubelet.serviceLister = testServiceLister{}
|
kubelet.serviceLister = testServiceLister{}
|
||||||
kubelet.readiness = newReadinessStates()
|
kubelet.readiness = newReadinessStates()
|
||||||
|
@ -396,12 +396,12 @@ func TestSyncPodsDoesNothing(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// format is // k8s_<container-id>_<pod-fullname>_<pod-uid>_<random>
|
// format is // k8s_<container-id>_<pod-fullname>_<pod-uid>_<random>
|
||||||
Names: []string{"/k8s_bar." + strconv.FormatUint(dockertools.HashContainer(&container), 16) + "_foo.new.test_12345678_0"},
|
Names: []string{"/k8s_bar." + strconv.FormatUint(dockertools.HashContainer(&container), 16) + "_foo_new_12345678_0"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_0"},
|
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,6 @@ func TestSyncPodsDoesNothing(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -442,7 +441,6 @@ func TestSyncPodsWithTerminationLog(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -489,7 +487,6 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -521,8 +518,8 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fakeDocker.Created) != 2 ||
|
if len(fakeDocker.Created) != 2 ||
|
||||||
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) ||
|
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo_new_", fakeDocker.Created[0]) ||
|
||||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[1]) {
|
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo_new_", fakeDocker.Created[1]) {
|
||||||
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
||||||
}
|
}
|
||||||
fakeDocker.Unlock()
|
fakeDocker.Unlock()
|
||||||
|
@ -540,7 +537,6 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -566,8 +562,8 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fakeDocker.Created) != 2 ||
|
if len(fakeDocker.Created) != 2 ||
|
||||||
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) ||
|
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo_new_", fakeDocker.Created[0]) ||
|
||||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[1]) {
|
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo_new_", fakeDocker.Created[1]) {
|
||||||
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
||||||
}
|
}
|
||||||
fakeDocker.Unlock()
|
fakeDocker.Unlock()
|
||||||
|
@ -578,7 +574,7 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_0"},
|
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -588,7 +584,6 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -609,7 +604,7 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
||||||
|
|
||||||
fakeDocker.Lock()
|
fakeDocker.Lock()
|
||||||
if len(fakeDocker.Created) != 1 ||
|
if len(fakeDocker.Created) != 1 ||
|
||||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) {
|
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo_new_", fakeDocker.Created[0]) {
|
||||||
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
||||||
}
|
}
|
||||||
fakeDocker.Unlock()
|
fakeDocker.Unlock()
|
||||||
|
@ -622,7 +617,7 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_0"},
|
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -632,7 +627,6 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -664,7 +658,7 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
||||||
|
|
||||||
fakeDocker.Lock()
|
fakeDocker.Lock()
|
||||||
if len(fakeDocker.Created) != 1 ||
|
if len(fakeDocker.Created) != 1 ||
|
||||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) {
|
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo_new_", fakeDocker.Created[0]) {
|
||||||
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
||||||
}
|
}
|
||||||
fakeDocker.Unlock()
|
fakeDocker.Unlock()
|
||||||
|
@ -678,7 +672,7 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// format is // k8s_<container-id>_<pod-fullname>_<pod-uid>
|
// format is // k8s_<container-id>_<pod-fullname>_<pod-uid>
|
||||||
Names: []string{"/k8s_bar_foo.new.test_12345678_0"},
|
Names: []string{"/k8s_bar_foo_new_12345678_0"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -688,7 +682,6 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -722,17 +715,17 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
||||||
func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) {
|
func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) {
|
||||||
ready := false
|
ready := false
|
||||||
kubelet, fakeDocker, _ := newTestKubelet(t)
|
kubelet, fakeDocker, _ := newTestKubelet(t)
|
||||||
kubelet.sourceReady = func(source string) bool { return ready }
|
kubelet.sourcesReady = func() bool { return ready }
|
||||||
|
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
// the k8s prefix is required for the kubelet to manage the container
|
||||||
Names: []string{"/k8s_foo_bar.new.test_12345678_42"},
|
Names: []string{"/k8s_foo_bar_new_12345678_42"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -762,78 +755,17 @@ func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncPodsDeletesWhenContainerSourceReady(t *testing.T) {
|
|
||||||
ready := false
|
|
||||||
kubelet, fakeDocker, _ := newTestKubelet(t)
|
|
||||||
kubelet.sourceReady = func(source string) bool {
|
|
||||||
if source == "testSource" {
|
|
||||||
return ready
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
|
||||||
{
|
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
|
||||||
Names: []string{"/k8s_boo_bar.default.testSource_12345678_42"},
|
|
||||||
ID: "7492",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pod infra container
|
|
||||||
Names: []string{"/k8s_POD_boo.default.testSource_12345678_42"},
|
|
||||||
ID: "3542",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
|
||||||
Names: []string{"/k8s_foo_bar.new.otherSource_12345678_42"},
|
|
||||||
ID: "1234",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// pod infra container
|
|
||||||
Names: []string{"/k8s_POD_foo.new.otherSource_12345678_42"},
|
|
||||||
ID: "9876",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := kubelet.SyncPods([]api.BoundPod{}, emptyPodUIDs, time.Now()); err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
// Validate nothing happened.
|
|
||||||
verifyCalls(t, fakeDocker, []string{"list"})
|
|
||||||
fakeDocker.ClearCalls()
|
|
||||||
|
|
||||||
ready = true
|
|
||||||
if err := kubelet.SyncPods([]api.BoundPod{}, emptyPodUIDs, time.Now()); err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
verifyCalls(t, fakeDocker, []string{"list", "stop", "stop", "inspect_container", "inspect_container"})
|
|
||||||
|
|
||||||
// Validate container for testSource are killed because testSource is reported as seen, but
|
|
||||||
// containers for otherSource are not killed because otherSource has not.
|
|
||||||
expectedToStop := map[string]bool{
|
|
||||||
"7492": true,
|
|
||||||
"3542": true,
|
|
||||||
"1234": false,
|
|
||||||
"9876": false,
|
|
||||||
}
|
|
||||||
if len(fakeDocker.Stopped) != 2 ||
|
|
||||||
!expectedToStop[fakeDocker.Stopped[0]] ||
|
|
||||||
!expectedToStop[fakeDocker.Stopped[1]] {
|
|
||||||
t.Errorf("Wrong containers were stopped: %v", fakeDocker.Stopped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSyncPodsDeletes(t *testing.T) {
|
func TestSyncPodsDeletes(t *testing.T) {
|
||||||
kubelet, fakeDocker, _ := newTestKubelet(t)
|
kubelet, fakeDocker, _ := newTestKubelet(t)
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
// the k8s prefix is required for the kubelet to manage the container
|
||||||
Names: []string{"/k8s_foo_bar.new.test_12345678_42"},
|
Names: []string{"/k8s_foo_bar_new_12345678_42"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -866,17 +798,17 @@ func TestSyncPodDeletesDuplicate(t *testing.T) {
|
||||||
dockerContainers := dockertools.DockerContainers{
|
dockerContainers := dockertools.DockerContainers{
|
||||||
"1234": &docker.APIContainers{
|
"1234": &docker.APIContainers{
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
// the k8s prefix is required for the kubelet to manage the container
|
||||||
Names: []string{"/k8s_foo_bar.new.test_12345678_1111"},
|
Names: []string{"/k8s_foo_bar_new_12345678_1111"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
"9876": &docker.APIContainers{
|
"9876": &docker.APIContainers{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_bar.new.test_12345678_2222"},
|
Names: []string{"/k8s_POD_bar_new_12345678_2222"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
"4567": &docker.APIContainers{
|
"4567": &docker.APIContainers{
|
||||||
// Duplicate for the same container.
|
// Duplicate for the same container.
|
||||||
Names: []string{"/k8s_foo_bar.new.test_12345678_3333"},
|
Names: []string{"/k8s_foo_bar_new_12345678_3333"},
|
||||||
ID: "4567",
|
ID: "4567",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -885,7 +817,6 @@ func TestSyncPodDeletesDuplicate(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -911,12 +842,12 @@ func TestSyncPodBadHash(t *testing.T) {
|
||||||
dockerContainers := dockertools.DockerContainers{
|
dockerContainers := dockertools.DockerContainers{
|
||||||
"1234": &docker.APIContainers{
|
"1234": &docker.APIContainers{
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
// the k8s prefix is required for the kubelet to manage the container
|
||||||
Names: []string{"/k8s_bar.1234_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_bar.1234_foo_new_12345678_42"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
"9876": &docker.APIContainers{
|
"9876": &docker.APIContainers{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -925,7 +856,6 @@ func TestSyncPodBadHash(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -960,12 +890,12 @@ func TestSyncPodUnhealthy(t *testing.T) {
|
||||||
dockerContainers := dockertools.DockerContainers{
|
dockerContainers := dockertools.DockerContainers{
|
||||||
"1234": &docker.APIContainers{
|
"1234": &docker.APIContainers{
|
||||||
// the k8s prefix is required for the kubelet to manage the container
|
// the k8s prefix is required for the kubelet to manage the container
|
||||||
Names: []string{"/k8s_bar_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_bar_foo_new_12345678_42"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
},
|
},
|
||||||
"9876": &docker.APIContainers{
|
"9876": &docker.APIContainers{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -974,7 +904,6 @@ func TestSyncPodUnhealthy(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -1295,11 +1224,11 @@ func TestGetContainerInfo(t *testing.T) {
|
||||||
ID: containerID,
|
ID: containerID,
|
||||||
// pod id: qux
|
// pod id: qux
|
||||||
// container id: foo
|
// container id: foo
|
||||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
stats, err := kubelet.GetContainerInfo("qux", "", "foo", cadvisorReq)
|
stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", cadvisorReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1369,11 +1298,11 @@ func TestGetContainerInfoWhenCadvisorFailed(t *testing.T) {
|
||||||
ID: containerID,
|
ID: containerID,
|
||||||
// pod id: qux
|
// pod id: qux
|
||||||
// container id: foo
|
// container id: foo
|
||||||
Names: []string{"/k8s_foo_qux_uuid_1234"},
|
Names: []string{"/k8s_foo_qux_ns_uuid_1234"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
stats, err := kubelet.GetContainerInfo("qux", "uuid", "foo", cadvisorReq)
|
stats, err := kubelet.GetContainerInfo("qux_ns", "uuid", "foo", cadvisorReq)
|
||||||
if stats != nil {
|
if stats != nil {
|
||||||
t.Errorf("non-nil stats on error")
|
t.Errorf("non-nil stats on error")
|
||||||
}
|
}
|
||||||
|
@ -1428,7 +1357,7 @@ func TestGetContainerInfoWithNoContainers(t *testing.T) {
|
||||||
kubelet.cadvisorClient = mockCadvisor
|
kubelet.cadvisorClient = mockCadvisor
|
||||||
|
|
||||||
kubelet.dockerClient = &errorTestingDockerClient{listContainersError: nil}
|
kubelet.dockerClient = &errorTestingDockerClient{listContainersError: nil}
|
||||||
stats, err := kubelet.GetContainerInfo("qux", "", "foo", nil)
|
stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error from cadvisor client, got none")
|
t.Errorf("Expected error from cadvisor client, got none")
|
||||||
}
|
}
|
||||||
|
@ -1449,12 +1378,12 @@ func TestGetContainerInfoWithNoMatchingContainers(t *testing.T) {
|
||||||
containerList := []docker.APIContainers{
|
containerList := []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: "fakeId",
|
ID: "fakeId",
|
||||||
Names: []string{"/k8s_bar_qux_1234_42"},
|
Names: []string{"/k8s_bar_qux_ns_1234_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
kubelet.dockerClient = &errorTestingDockerClient{listContainersError: nil, containerList: containerList}
|
kubelet.dockerClient = &errorTestingDockerClient{listContainersError: nil, containerList: containerList}
|
||||||
stats, err := kubelet.GetContainerInfo("qux", "", "foo", nil)
|
stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error from cadvisor client, got none")
|
t.Errorf("Expected error from cadvisor client, got none")
|
||||||
}
|
}
|
||||||
|
@ -1540,7 +1469,7 @@ func TestRunInContainer(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: containerID,
|
ID: containerID,
|
||||||
Names: []string{"/k8s_" + containerName + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
Names: []string{"/k8s_" + containerName + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,7 +1480,6 @@ func TestRunInContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: podName,
|
Name: podName,
|
||||||
Namespace: podNamespace,
|
Namespace: podNamespace,
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
"",
|
"",
|
||||||
|
@ -1581,7 +1509,7 @@ func TestRunHandlerExec(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: containerID,
|
ID: containerID,
|
||||||
Names: []string{"/k8s_" + containerName + "_" + podName + "." + podNamespace + "_12345678_42"},
|
Names: []string{"/k8s_" + containerName + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1595,7 +1523,7 @@ func TestRunHandlerExec(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := kubelet.runHandler(podName+"."+podNamespace, "", &container, container.Lifecycle.PostStart)
|
err := kubelet.runHandler(podName+"_"+podNamespace, "", &container, container.Lifecycle.PostStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1637,7 +1565,7 @@ func TestRunHandlerHttp(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := kubelet.runHandler(podName+"."+podNamespace, "", &container, container.Lifecycle.PostStart)
|
err := kubelet.runHandler(podName+"_"+podNamespace, "", &container, container.Lifecycle.PostStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1685,7 +1613,7 @@ func TestSyncPodEventHandlerFails(t *testing.T) {
|
||||||
dockerContainers := dockertools.DockerContainers{
|
dockerContainers := dockertools.DockerContainers{
|
||||||
"9876": &docker.APIContainers{
|
"9876": &docker.APIContainers{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||||
ID: "9876",
|
ID: "9876",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1694,7 +1622,6 @@ func TestSyncPodEventHandlerFails(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -1736,17 +1663,17 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
||||||
containers: []docker.APIContainers{
|
containers: []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "1876",
|
ID: "1876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "2876",
|
ID: "2876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "3876",
|
ID: "3876",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1766,22 +1693,22 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
||||||
containers: []docker.APIContainers{
|
containers: []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "1876",
|
ID: "1876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "2876",
|
ID: "2876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "3876",
|
ID: "3876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "4876",
|
ID: "4876",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1808,7 +1735,7 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
||||||
containers: []docker.APIContainers{
|
containers: []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "1876",
|
ID: "1876",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1818,32 +1745,32 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
||||||
containers: []docker.APIContainers{
|
containers: []docker.APIContainers{
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo2.new.test_.beefbeef_40"},
|
Names: []string{"/k8s_POD_foo2_new_.beefbeef_40"},
|
||||||
ID: "1706",
|
ID: "1706",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo2.new.test_.beefbeef_40"},
|
Names: []string{"/k8s_POD_foo2_new_.beefbeef_40"},
|
||||||
ID: "2706",
|
ID: "2706",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo2.new.test_.beefbeef_40"},
|
Names: []string{"/k8s_POD_foo2_new_.beefbeef_40"},
|
||||||
ID: "3706",
|
ID: "3706",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "1876",
|
ID: "1876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "2876",
|
ID: "2876",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pod infra container
|
// pod infra container
|
||||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||||
ID: "3876",
|
ID: "3876",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2055,7 +1982,6 @@ func TestSyncPodsWithPullPolicy(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -2851,7 +2777,7 @@ func TestExecInContainerNoSuchContainer(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: "notfound",
|
ID: "notfound",
|
||||||
Names: []string{"/k8s_notfound_" + podName + "." + podNamespace + ".test_12345678_42"},
|
Names: []string{"/k8s_notfound_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2860,7 +2786,6 @@ func TestExecInContainerNoSuchContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: podName,
|
Name: podName,
|
||||||
Namespace: podNamespace,
|
Namespace: podNamespace,
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
}}),
|
}}),
|
||||||
"",
|
"",
|
||||||
containerID,
|
containerID,
|
||||||
|
@ -2909,7 +2834,7 @@ func TestExecInContainer(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: containerID,
|
ID: containerID,
|
||||||
Names: []string{"/k8s_" + containerID + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
Names: []string{"/k8s_" + containerID + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2918,7 +2843,6 @@ func TestExecInContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: podName,
|
Name: podName,
|
||||||
Namespace: podNamespace,
|
Namespace: podNamespace,
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
}}),
|
}}),
|
||||||
"",
|
"",
|
||||||
containerID,
|
containerID,
|
||||||
|
@ -2987,7 +2911,7 @@ func TestPortForwardNoSuchContainer(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: "notfound",
|
ID: "notfound",
|
||||||
Names: []string{"/k8s_notfound_" + podName + "." + podNamespace + ".test_12345678_42"},
|
Names: []string{"/k8s_notfound_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2996,7 +2920,6 @@ func TestPortForwardNoSuchContainer(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: podName,
|
Name: podName,
|
||||||
Namespace: podNamespace,
|
Namespace: podNamespace,
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
}}),
|
}}),
|
||||||
"",
|
"",
|
||||||
port,
|
port,
|
||||||
|
@ -3027,11 +2950,11 @@ func TestPortForward(t *testing.T) {
|
||||||
fakeDocker.ContainerList = []docker.APIContainers{
|
fakeDocker.ContainerList = []docker.APIContainers{
|
||||||
{
|
{
|
||||||
ID: infraContainerID,
|
ID: infraContainerID,
|
||||||
Names: []string{"/k8s_" + kubelet.podInfraContainerImage + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
Names: []string{"/k8s_" + kubelet.podInfraContainerImage + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: containerID,
|
ID: containerID,
|
||||||
Names: []string{"/k8s_" + containerID + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
Names: []string{"/k8s_" + containerID + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3040,7 +2963,6 @@ func TestPortForward(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: podName,
|
Name: podName,
|
||||||
Namespace: podNamespace,
|
Namespace: podNamespace,
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
}}),
|
}}),
|
||||||
"",
|
"",
|
||||||
port,
|
port,
|
||||||
|
|
|
@ -76,7 +76,7 @@ func TestRunOnce(t *testing.T) {
|
||||||
}
|
}
|
||||||
podContainers := []docker.APIContainers{
|
podContainers := []docker.APIContainers{
|
||||||
{
|
{
|
||||||
Names: []string{"/k8s_bar." + strconv.FormatUint(dockertools.HashContainer(&api.Container{Name: "bar"}), 16) + "_foo.new.test_12345678_42"},
|
Names: []string{"/k8s_bar." + strconv.FormatUint(dockertools.HashContainer(&api.Container{Name: "bar"}), 16) + "_foo_new_12345678_42"},
|
||||||
ID: "1234",
|
ID: "1234",
|
||||||
Status: "running",
|
Status: "running",
|
||||||
},
|
},
|
||||||
|
@ -133,7 +133,6 @@ func TestRunOnce(t *testing.T) {
|
||||||
UID: "12345678",
|
UID: "12345678",
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Namespace: "new",
|
Namespace: "new",
|
||||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
|
|
@ -129,9 +129,6 @@ func newServerTest() *serverTestFramework {
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: name,
|
Name: name,
|
||||||
Annotations: map[string]string{
|
|
||||||
ConfigSourceAnnotationKey: "etcd",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}, true
|
}, true
|
||||||
},
|
},
|
||||||
|
@ -157,6 +154,14 @@ func readResp(resp *http.Response) (string, error) {
|
||||||
return string(body), err
|
return string(body), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A helper function to return the correct pod name.
|
||||||
|
func getPodName(name, namespace string) string {
|
||||||
|
if namespace == "" {
|
||||||
|
namespace = NamespaceDefault
|
||||||
|
}
|
||||||
|
return name + "_" + namespace
|
||||||
|
}
|
||||||
|
|
||||||
func TestPodStatus(t *testing.T) {
|
func TestPodStatus(t *testing.T) {
|
||||||
fw := newServerTest()
|
fw := newServerTest()
|
||||||
expected := api.PodStatus{
|
expected := api.PodStatus{
|
||||||
|
@ -165,7 +170,7 @@ func TestPodStatus(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fw.fakeKubelet.statusFunc = func(name string) (api.PodStatus, error) {
|
fw.fakeKubelet.statusFunc = func(name string) (api.PodStatus, error) {
|
||||||
if name == "goodpod.default.etcd" {
|
if name == "goodpod_default" {
|
||||||
return expected, nil
|
return expected, nil
|
||||||
}
|
}
|
||||||
return api.PodStatus{}, fmt.Errorf("bad pod %s", name)
|
return api.PodStatus{}, fmt.Errorf("bad pod %s", name)
|
||||||
|
@ -191,7 +196,7 @@ func TestContainerInfo(t *testing.T) {
|
||||||
fw := newServerTest()
|
fw := newServerTest()
|
||||||
expectedInfo := &info.ContainerInfo{}
|
expectedInfo := &info.ContainerInfo{}
|
||||||
podID := "somepod"
|
podID := "somepod"
|
||||||
expectedPodID := "somepod" + ".default.etcd"
|
expectedPodID := getPodName(podID, "")
|
||||||
expectedContainerName := "goodcontainer"
|
expectedContainerName := "goodcontainer"
|
||||||
fw.fakeKubelet.containerInfoFunc = func(podID string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
fw.fakeKubelet.containerInfoFunc = func(podID string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||||
if podID != expectedPodID || containerName != expectedContainerName {
|
if podID != expectedPodID || containerName != expectedContainerName {
|
||||||
|
@ -220,7 +225,7 @@ func TestContainerInfoWithUidNamespace(t *testing.T) {
|
||||||
expectedInfo := &info.ContainerInfo{}
|
expectedInfo := &info.ContainerInfo{}
|
||||||
podID := "somepod"
|
podID := "somepod"
|
||||||
expectedNamespace := "custom"
|
expectedNamespace := "custom"
|
||||||
expectedPodID := "somepod" + "." + expectedNamespace + ".etcd"
|
expectedPodID := getPodName(podID, expectedNamespace)
|
||||||
expectedContainerName := "goodcontainer"
|
expectedContainerName := "goodcontainer"
|
||||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||||
fw.fakeKubelet.containerInfoFunc = func(podID string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
fw.fakeKubelet.containerInfoFunc = func(podID string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||||
|
@ -344,7 +349,7 @@ func TestServeRunInContainer(t *testing.T) {
|
||||||
output := "foo bar"
|
output := "foo bar"
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedCommand := "ls -a"
|
expectedCommand := "ls -a"
|
||||||
fw.fakeKubelet.runFunc = func(podFullName string, uid types.UID, containerName string, cmd []string) ([]byte, error) {
|
fw.fakeKubelet.runFunc = func(podFullName string, uid types.UID, containerName string, cmd []string) ([]byte, error) {
|
||||||
|
@ -384,7 +389,7 @@ func TestServeRunInContainerWithUID(t *testing.T) {
|
||||||
output := "foo bar"
|
output := "foo bar"
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedUID := "7e00838d_-_3523_-_11e4_-_8421_-_42010af0a720"
|
expectedUID := "7e00838d_-_3523_-_11e4_-_8421_-_42010af0a720"
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedCommand := "ls -a"
|
expectedCommand := "ls -a"
|
||||||
|
@ -509,9 +514,6 @@ func setPodByNameFunc(fw *serverTestFramework, namespace, pod, container string)
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: pod,
|
Name: pod,
|
||||||
Annotations: map[string]string{
|
|
||||||
ConfigSourceAnnotationKey: "etcd",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -548,7 +550,7 @@ func TestContainerLogs(t *testing.T) {
|
||||||
output := "foo bar"
|
output := "foo bar"
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + ".other.etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedTail := ""
|
expectedTail := ""
|
||||||
expectedFollow := false
|
expectedFollow := false
|
||||||
|
@ -575,7 +577,7 @@ func TestContainerLogsWithTail(t *testing.T) {
|
||||||
output := "foo bar"
|
output := "foo bar"
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + ".other.etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedTail := "5"
|
expectedTail := "5"
|
||||||
expectedFollow := false
|
expectedFollow := false
|
||||||
|
@ -602,7 +604,7 @@ func TestContainerLogsWithFollow(t *testing.T) {
|
||||||
output := "foo bar"
|
output := "foo bar"
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + ".other.etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedTail := ""
|
expectedTail := ""
|
||||||
expectedFollow := true
|
expectedFollow := true
|
||||||
|
@ -693,7 +695,7 @@ func TestServeExecInContainer(t *testing.T) {
|
||||||
|
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedCommand := "ls -a"
|
expectedCommand := "ls -a"
|
||||||
|
@ -955,7 +957,7 @@ func TestServePortForward(t *testing.T) {
|
||||||
|
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
expectedPodName := getPodName(podName, podNamespace)
|
||||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
|
|
@ -18,10 +18,8 @@ package kubelet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/golang/glog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const ConfigSourceAnnotationKey = "kubernetes.io/config.source"
|
const ConfigSourceAnnotationKey = "kubernetes.io/config.source"
|
||||||
|
@ -52,6 +50,8 @@ const (
|
||||||
ApiserverSource = "api"
|
ApiserverSource = "api"
|
||||||
// Updates from all sources
|
// Updates from all sources
|
||||||
AllSource = "*"
|
AllSource = "*"
|
||||||
|
|
||||||
|
NamespaceDefault = api.NamespaceDefault
|
||||||
)
|
)
|
||||||
|
|
||||||
// PodUpdate defines an operation sent on the channel. You can add or remove single services by
|
// PodUpdate defines an operation sent on the channel. You can add or remove single services by
|
||||||
|
@ -71,22 +71,12 @@ type PodUpdate struct {
|
||||||
|
|
||||||
// GetPodFullName returns a name that uniquely identifies a pod across all config sources.
|
// GetPodFullName returns a name that uniquely identifies a pod across all config sources.
|
||||||
func GetPodFullName(pod *api.BoundPod) string {
|
func GetPodFullName(pod *api.BoundPod) string {
|
||||||
return fmt.Sprintf("%s.%s.%s", pod.Name, pod.Namespace, pod.Annotations[ConfigSourceAnnotationKey])
|
// Use underscore as the delimiter because it is not allowed in pod name
|
||||||
|
// (DNS subdomain format), while allowed in the container name format.
|
||||||
|
return fmt.Sprintf("%s_%s", pod.Name, pod.Namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsePodFullName unpacks a pod full name and returns the pod name, namespace, and annotations.
|
// Build the pod full name from pod name and namespace.
|
||||||
// If the pod full name is invalid, empty strings are returend.
|
func BuildPodFullName(name, namespace string) string {
|
||||||
func ParsePodFullName(podFullName string) (podName, podNamespace string, podAnnotations map[string]string) {
|
return name + "_" + namespace
|
||||||
parts := strings.Split(podFullName, ".")
|
|
||||||
expectedNumFields := 3
|
|
||||||
actualNumFields := len(parts)
|
|
||||||
if actualNumFields != expectedNumFields {
|
|
||||||
glog.Errorf("found a podFullName (%q) with too few fields: expected %d, actual %d.", podFullName, expectedNumFields, actualNumFields)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
podName = parts[0]
|
|
||||||
podNamespace = parts[1]
|
|
||||||
podAnnotations = make(map[string]string)
|
|
||||||
podAnnotations[ConfigSourceAnnotationKey] = parts[2]
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
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 (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParsePodFullName(t *testing.T) {
|
|
||||||
// Arrange
|
|
||||||
podFullName := "ca4e7148-9ab9-11e4-924c-f0921cde18c1.default.etcd"
|
|
||||||
|
|
||||||
// Act
|
|
||||||
podName, podNamespace, podAnnotations := ParsePodFullName(podFullName)
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expectedPodName := "ca4e7148-9ab9-11e4-924c-f0921cde18c1"
|
|
||||||
expectedPodNamespace := "default"
|
|
||||||
expectedSource := "etcd"
|
|
||||||
if podName != expectedPodName {
|
|
||||||
t.Errorf("Unexpected PodName. Expected: %q Actual: %q", expectedPodName, podName)
|
|
||||||
}
|
|
||||||
if podNamespace != expectedPodNamespace {
|
|
||||||
t.Errorf("Unexpected PodNamespace. Expected: %q Actual: %q", expectedPodNamespace, podNamespace)
|
|
||||||
}
|
|
||||||
if podAnnotations[ConfigSourceAnnotationKey] != expectedSource {
|
|
||||||
t.Errorf("Unexpected PodSource. Expected: %q Actual: %q", expectedPodNamespace, podNamespace)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue