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.MinimumGCAge,
|
||||
kc.MaxContainerCount,
|
||||
pc.IsSourceSeen,
|
||||
pc.SeenAllSources,
|
||||
kc.ClusterDomain,
|
||||
net.IP(kc.ClusterDNS),
|
||||
kc.MasterServiceNamespace,
|
||||
|
|
|
@ -18,6 +18,7 @@ package config
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
|
@ -55,6 +56,10 @@ type PodConfig struct {
|
|||
|
||||
// the channel of denormalized changes passed to listeners
|
||||
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
|
||||
|
@ -66,6 +71,7 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder)
|
|||
pods: storage,
|
||||
mux: config.NewMux(storage),
|
||||
updates: updates,
|
||||
sources: util.StringSet{},
|
||||
}
|
||||
return podConfig
|
||||
}
|
||||
|
@ -73,17 +79,20 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder)
|
|||
// Channel creates or returns a config source channel. The channel
|
||||
// only accepts PodUpdates
|
||||
func (c *PodConfig) Channel(source string) chan<- interface{} {
|
||||
c.sourcesLock.Lock()
|
||||
defer c.sourcesLock.Unlock()
|
||||
c.sources.Insert(source)
|
||||
return c.mux.Channel(source)
|
||||
}
|
||||
|
||||
// IsSourceSeen returns true if the specified source string has previously
|
||||
// been marked as seen.
|
||||
func (c *PodConfig) IsSourceSeen(source string) bool {
|
||||
// SeenAllSources returns true if this config has received a SET
|
||||
// message from all configured sources, false otherwise.
|
||||
func (c *PodConfig) SeenAllSources() bool {
|
||||
if c.pods == nil {
|
||||
return false
|
||||
}
|
||||
glog.V(6).Infof("Looking for %v, have seen %v", source, c.pods.sourcesSeen)
|
||||
return c.pods.seenSources(source)
|
||||
glog.V(6).Infof("Looking for %v, have seen %v", c.sources.List(), c.pods.sourcesSeen)
|
||||
return c.pods.seenSources(c.sources.List()...)
|
||||
}
|
||||
|
||||
// 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)
|
||||
for _, ref := range filtered {
|
||||
name := podUniqueName(ref)
|
||||
name := kubelet.GetPodFullName(ref)
|
||||
if existing, found := pods[name]; found {
|
||||
if !reflect.DeepEqual(existing.Spec, ref.Spec) {
|
||||
// this is an update
|
||||
|
@ -221,7 +230,7 @@ func (s *podStorage) merge(source string, change interface{}) (adds, updates, de
|
|||
case kubelet.REMOVE:
|
||||
glog.V(4).Infof("Removing a pod %v", update)
|
||||
for _, value := range update.Pods {
|
||||
name := podUniqueName(&value)
|
||||
name := kubelet.GetPodFullName(&value)
|
||||
if existing, found := pods[name]; found {
|
||||
// this is a delete
|
||||
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)
|
||||
for _, ref := range filtered {
|
||||
name := podUniqueName(ref)
|
||||
name := kubelet.GetPodFullName(ref)
|
||||
if existing, found := oldPods[name]; found {
|
||||
pods[name] = existing
|
||||
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 -
|
||||
// even Name could be bad.
|
||||
} else {
|
||||
name := podUniqueName(pod)
|
||||
name := kubelet.GetPodFullName(pod)
|
||||
if names.Has(name) {
|
||||
errlist = append(errlist, apierrs.NewFieldDuplicate("name", pod.Name))
|
||||
} else {
|
||||
|
@ -341,12 +350,6 @@ func (s *podStorage) MergedState() interface{} {
|
|||
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 {
|
||||
namespace := pod.Namespace
|
||||
if namespace == "" {
|
||||
|
@ -358,3 +361,11 @@ func bestPodIdentString(pod *api.BoundPod) string {
|
|||
}
|
||||
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 {
|
||||
// Backwards compatibility with old api servers
|
||||
// TODO: Remove this after 1.0 release.
|
||||
if len(pod.Namespace) == 0 {
|
||||
pod.Namespace = api.NamespaceDefault
|
||||
}
|
||||
// Always overrides the namespace provided by the etcd event.
|
||||
pod.Namespace = kubelet.NamespaceDefault
|
||||
pods = append(pods, pod)
|
||||
}
|
||||
|
||||
|
|
|
@ -102,8 +102,14 @@ func TestEventToPods(t *testing.T) {
|
|||
},
|
||||
},
|
||||
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,
|
||||
},
|
||||
|
@ -116,7 +122,9 @@ func TestEventToPods(t *testing.T) {
|
|||
},
|
||||
},
|
||||
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,
|
||||
},
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash/adler32"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -186,17 +185,16 @@ func extractFromFile(filename string) (api.BoundPod, error) {
|
|||
// completely deprecate ContainerManifest.
|
||||
if len(pod.Name) == 0 {
|
||||
pod.Name = string(pod.UID)
|
||||
glog.V(5).Infof("Generated Name %q for UID %q from file %s", pod.Name, pod.UID, filename)
|
||||
}
|
||||
if len(pod.Namespace) == 0 {
|
||||
hasher := adler32.New()
|
||||
fmt.Fprint(hasher, 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)
|
||||
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)
|
||||
|
||||
// Always overrides the namespace provided by the file.
|
||||
pod.Namespace = kubelet.NamespaceDefault
|
||||
glog.V(5).Infof("Using 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
|
||||
// about Pod directly, we can use SelfLinker defined in package: latest
|
||||
// Currently just simply follow the same format in resthandler.go
|
||||
|
|
|
@ -54,8 +54,9 @@ func ExampleManifestAndPod(id string) (v1beta1.ContainerManifest, api.BoundPod)
|
|||
}
|
||||
expectedPod := api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: id,
|
||||
UID: types.UID(id),
|
||||
Name: id,
|
||||
UID: types.UID(id),
|
||||
Namespace: kubelet.NamespaceDefault,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -131,27 +132,30 @@ func TestReadFromFile(t *testing.T) {
|
|||
update := got.(kubelet.PodUpdate)
|
||||
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "test",
|
||||
Name: "",
|
||||
UID: "12345",
|
||||
Namespace: "",
|
||||
Namespace: kubelet.NamespaceDefault,
|
||||
SelfLink: "",
|
||||
},
|
||||
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
|
||||
// it will be defaulted.
|
||||
if !strings.HasPrefix(update.Pods[0].ObjectMeta.Namespace, "file-") {
|
||||
t.Errorf("Unexpected namespace: %s", update.Pods[0].ObjectMeta.Namespace)
|
||||
if update.Pods[0].Namespace != kubelet.NamespaceDefault {
|
||||
t.Errorf("Unexpected namespace: %s", update.Pods[0].Namespace)
|
||||
}
|
||||
update.Pods[0].ObjectMeta.Namespace = ""
|
||||
|
||||
// SelfLink depends on namespace.
|
||||
if !strings.HasPrefix(update.Pods[0].ObjectMeta.SelfLink, "/api/") {
|
||||
t.Errorf("Unexpected selflink: %s", update.Pods[0].ObjectMeta.SelfLink)
|
||||
if !strings.HasPrefix(update.Pods[0].SelfLink, "/api/") {
|
||||
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) {
|
||||
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
||||
}
|
||||
|
@ -179,7 +183,7 @@ func TestReadFromFileWithoutID(t *testing.T) {
|
|||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "",
|
||||
UID: "12345",
|
||||
Namespace: "",
|
||||
Namespace: kubelet.NamespaceDefault,
|
||||
SelfLink: "",
|
||||
},
|
||||
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 {
|
||||
t.Errorf("Name did not get defaulted")
|
||||
}
|
||||
update.Pods[0].ObjectMeta.Name = ""
|
||||
update.Pods[0].ObjectMeta.Namespace = ""
|
||||
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) {
|
||||
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
||||
}
|
||||
|
@ -218,17 +221,17 @@ func TestReadV1Beta2FromFile(t *testing.T) {
|
|||
update := got.(kubelet.PodUpdate)
|
||||
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "test",
|
||||
Name: "",
|
||||
UID: "12345",
|
||||
Namespace: "",
|
||||
Namespace: kubelet.NamespaceDefault,
|
||||
SelfLink: "",
|
||||
},
|
||||
Spec: api.PodSpec{Containers: []api.Container{{Image: "test/image"}}},
|
||||
})
|
||||
|
||||
update.Pods[0].ObjectMeta.Namespace = ""
|
||||
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) {
|
||||
t.Fatalf("Expected %#v, Got %#v", expected, update)
|
||||
}
|
||||
|
@ -252,8 +255,8 @@ func TestReadFromFileWithDefaults(t *testing.T) {
|
|||
select {
|
||||
case got := <-ch:
|
||||
update := got.(kubelet.PodUpdate)
|
||||
if update.Pods[0].ObjectMeta.UID == "" {
|
||||
t.Errorf("Unexpected UID: %s", update.Pods[0].ObjectMeta.UID)
|
||||
if update.Pods[0].UID == "" {
|
||||
t.Errorf("Unexpected UID: %s", update.Pods[0].UID)
|
||||
}
|
||||
|
||||
case <-time.After(time.Second):
|
||||
|
@ -337,12 +340,16 @@ func TestExtractFromDir(t *testing.T) {
|
|||
|
||||
update := (<-ch).(kubelet.PodUpdate)
|
||||
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 = ""
|
||||
}
|
||||
expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, 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(expected.Pods))
|
||||
|
@ -351,7 +358,7 @@ func TestExtractFromDir(t *testing.T) {
|
|||
}
|
||||
for i := range update.Pods {
|
||||
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"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash/adler32"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
@ -92,7 +91,9 @@ func (s *sourceURL) extractFromURL() error {
|
|||
return singleErr
|
||||
}
|
||||
// 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}
|
||||
return nil
|
||||
}
|
||||
|
@ -114,7 +115,9 @@ func (s *sourceURL) extractFromURL() error {
|
|||
// Assume it parsed.
|
||||
for i := range pods.Items {
|
||||
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}
|
||||
return nil
|
||||
|
@ -180,7 +183,7 @@ func tryDecodeList(data []byte) (parsed bool, manifests []v1beta1.ContainerManif
|
|||
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 {
|
||||
hasher := md5.New()
|
||||
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
|
||||
// completely deprecate ContainerManifest.
|
||||
var err error
|
||||
if len(pod.Name) == 0 {
|
||||
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 {
|
||||
hasher := adler32.New()
|
||||
fmt.Fprint(hasher, url)
|
||||
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)
|
||||
pod.Name, err = GeneratePodName(pod.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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 (
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -117,6 +117,8 @@ func TestExtractInvalidManifest(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestExtractFromHTTP(t *testing.T) {
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
var testCases = []struct {
|
||||
desc string
|
||||
manifests interface{}
|
||||
|
@ -131,7 +133,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "111",
|
||||
Name: "foo",
|
||||
Name: "foo" + "-" + hostname,
|
||||
Namespace: "foobar",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
|
@ -153,7 +155,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "111",
|
||||
Name: "111",
|
||||
Name: "111" + "-" + hostname,
|
||||
Namespace: "foobar",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
|
@ -171,7 +173,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "111",
|
||||
Name: "foo",
|
||||
Name: "foo" + "-" + hostname,
|
||||
Namespace: "foobar",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
|
@ -198,7 +200,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "111",
|
||||
Name: "foo",
|
||||
Name: "foo" + "-" + hostname,
|
||||
Namespace: "foobar",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
|
@ -214,7 +216,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "222",
|
||||
Name: "bar",
|
||||
Name: "bar" + "-" + hostname,
|
||||
Namespace: "foobar",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
|
@ -234,6 +236,7 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
expected: CreatePodUpdate(kubelet.SET, kubelet.HTTPSource),
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
data, err := json.Marshal(testCase.manifests)
|
||||
if err != nil {
|
||||
|
@ -256,8 +259,8 @@ func TestExtractFromHTTP(t *testing.T) {
|
|||
for i := range update.Pods {
|
||||
// There's no way to provide namespace in ContainerManifest, so
|
||||
// it will be defaulted.
|
||||
if !strings.HasPrefix(update.Pods[i].ObjectMeta.Namespace, "url-") {
|
||||
t.Errorf("Unexpected namespace: %s", update.Pods[0].ObjectMeta.Namespace)
|
||||
if update.Pods[i].Namespace != kubelet.NamespaceDefault {
|
||||
t.Errorf("Unexpected namespace: %s", update.Pods[0].Namespace)
|
||||
}
|
||||
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 {
|
||||
return
|
||||
}
|
||||
if len(parts) < 5 {
|
||||
if len(parts) < 6 {
|
||||
// We have at least 5 fields. We may have more in the future.
|
||||
// Anything with less fields than this is not something we can
|
||||
// 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
|
||||
}
|
||||
|
||||
|
@ -739,11 +739,10 @@ func ParseDockerName(name string) (podFullName string, podUID types.UID, contain
|
|||
}
|
||||
|
||||
// Pod fullname.
|
||||
podFullName = parts[2]
|
||||
podFullName = parts[2] + "_" + parts[3]
|
||||
|
||||
// Pod UID.
|
||||
podUID = types.UID(parts[3])
|
||||
|
||||
podUID = types.UID(parts[4])
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,11 @@ func TestGetContainerID(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
{
|
||||
ID: "barbar",
|
||||
Names: []string{"/k8s_bar_qux_2565_42"},
|
||||
Names: []string{"/k8s_bar_qux_ns_2565_42"},
|
||||
},
|
||||
}
|
||||
fakeDocker.Container = &docker.Container{
|
||||
|
@ -73,7 +73,7 @@ func TestGetContainerID(t *testing.T) {
|
|||
t.Errorf("Expected %#v, Got %#v", fakeDocker.ContainerList, dockerContainers)
|
||||
}
|
||||
verifyCalls(t, fakeDocker, []string{"list"})
|
||||
dockerContainer, found, _ := dockerContainers.FindPodContainer("qux", "", "foo")
|
||||
dockerContainer, found, _ := dockerContainers.FindPodContainer("qux_ns", "", "foo")
|
||||
if dockerContainer == nil || !found {
|
||||
t.Errorf("Failed to find container %#v", dockerContainer)
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func verifyPackUnpack(t *testing.T, podNamespace, podUID, podName, containerName
|
|||
hasher := adler32.New()
|
||||
util.DeepHashObject(hasher, *container)
|
||||
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)
|
||||
returnedPodFullName, returnedUID, returnedContainerName, hash := ParseDockerName(name)
|
||||
if podFullName != returnedPodFullName || podUID != string(returnedUID) || containerName != returnedContainerName || computedHash != hash {
|
||||
|
@ -111,8 +111,8 @@ func TestContainerManifestNaming(t *testing.T) {
|
|||
container := &api.Container{Name: "container"}
|
||||
podName := "foo"
|
||||
podNamespace := "test"
|
||||
name := fmt.Sprintf("k8s_%s_%s.%s_%s_42", container.Name, podName, podNamespace, podUID)
|
||||
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
||||
name := fmt.Sprintf("k8s_%s_%s_%s_%s_42", container.Name, podName, podNamespace, podUID)
|
||||
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
||||
|
||||
returnedPodFullName, returnedPodUID, returnedContainerName, hash := ParseDockerName(name)
|
||||
if returnedPodFullName != podFullName || string(returnedPodUID) != podUID || returnedContainerName != container.Name || hash != 0 {
|
||||
|
@ -463,15 +463,15 @@ func TestFindContainersByPod(t *testing.T) {
|
|||
DockerContainers{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"barbar": &docker.APIContainers{
|
||||
ID: "barbar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"baz": &docker.APIContainers{
|
||||
ID: "baz",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
},
|
||||
types.UID("1234"),
|
||||
|
@ -479,15 +479,15 @@ func TestFindContainersByPod(t *testing.T) {
|
|||
DockerContainers{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"barbar": &docker.APIContainers{
|
||||
ID: "barbar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"baz": &docker.APIContainers{
|
||||
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{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"barbar": &docker.APIContainers{
|
||||
ID: "barbar",
|
||||
Names: []string{"/k8s_foo_qux_2343_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_2343_42"},
|
||||
},
|
||||
"baz": &docker.APIContainers{
|
||||
ID: "baz",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
},
|
||||
types.UID("1234"),
|
||||
|
@ -511,11 +511,11 @@ func TestFindContainersByPod(t *testing.T) {
|
|||
DockerContainers{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"baz": &docker.APIContainers{
|
||||
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{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"barbar": &docker.APIContainers{
|
||||
ID: "barbar",
|
||||
Names: []string{"/k8s_foo_qux_2343_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_2343_42"},
|
||||
},
|
||||
"baz": &docker.APIContainers{
|
||||
ID: "baz",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
},
|
||||
types.UID("5678"),
|
||||
|
@ -542,7 +542,7 @@ func TestFindContainersByPod(t *testing.T) {
|
|||
DockerContainers{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"barbar": &docker.APIContainers{
|
||||
ID: "barbar",
|
||||
|
@ -550,7 +550,7 @@ func TestFindContainersByPod(t *testing.T) {
|
|||
},
|
||||
"baz": &docker.APIContainers{
|
||||
ID: "baz",
|
||||
Names: []string{"/k8s_foo_qux_5678_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_5678_42"},
|
||||
},
|
||||
},
|
||||
types.UID("5678"),
|
||||
|
@ -558,7 +558,7 @@ func TestFindContainersByPod(t *testing.T) {
|
|||
DockerContainers{
|
||||
"baz": &docker.APIContainers{
|
||||
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{
|
||||
"foobar": &docker.APIContainers{
|
||||
ID: "foobar",
|
||||
Names: []string{"/k8s_foo_qux_1234_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_1234_42"},
|
||||
},
|
||||
"barbar": &docker.APIContainers{
|
||||
ID: "barbar",
|
||||
Names: []string{"/k8s_foo_abc_5678_42"},
|
||||
Names: []string{"/k8s_foo_abc_ns_5678_42"},
|
||||
},
|
||||
"baz": &docker.APIContainers{
|
||||
ID: "baz",
|
||||
Names: []string{"/k8s_foo_qux_5678_42"},
|
||||
Names: []string{"/k8s_foo_qux_ns_5678_42"},
|
||||
},
|
||||
},
|
||||
"",
|
||||
"abc",
|
||||
"abc_ns",
|
||||
DockerContainers{
|
||||
"barbar": &docker.APIContainers{
|
||||
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
|
||||
}
|
||||
|
||||
type SourceReadyFn func(source string) bool
|
||||
type SourcesReadyFn func() bool
|
||||
|
||||
type volumeMap map[string]volume.Interface
|
||||
|
||||
|
@ -86,7 +86,7 @@ func NewMainKubelet(
|
|||
pullBurst int,
|
||||
minimumGCAge time.Duration,
|
||||
maxContainerCount int,
|
||||
sourceReady SourceReadyFn,
|
||||
sourcesReady SourcesReadyFn,
|
||||
clusterDomain string,
|
||||
clusterDNS net.IP,
|
||||
masterServiceNamespace string,
|
||||
|
@ -135,7 +135,7 @@ func NewMainKubelet(
|
|||
pullBurst: pullBurst,
|
||||
minimumGCAge: minimumGCAge,
|
||||
maxContainerCount: maxContainerCount,
|
||||
sourceReady: sourceReady,
|
||||
sourcesReady: sourcesReady,
|
||||
clusterDomain: clusterDomain,
|
||||
clusterDNS: clusterDNS,
|
||||
serviceLister: serviceLister,
|
||||
|
@ -185,7 +185,7 @@ type Kubelet struct {
|
|||
podInfraContainerImage string
|
||||
podWorkers *podWorkers
|
||||
resyncInterval time.Duration
|
||||
sourceReady SourceReadyFn
|
||||
sourcesReady SourcesReadyFn
|
||||
|
||||
// Protects the pods 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)))
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the workers for no-longer existing pods.
|
||||
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.
|
||||
killed := []string{}
|
||||
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.
|
||||
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}
|
||||
if _, ok := desiredContainers[pc]; !ok {
|
||||
glog.V(1).Infof("Killing unwanted container %+v", pc)
|
||||
|
|
|
@ -78,7 +78,7 @@ func newTestKubelet(t *testing.T) (*Kubelet, *dockertools.FakeDockerClient, *syn
|
|||
return err
|
||||
},
|
||||
recorder)
|
||||
kubelet.sourceReady = func(source string) bool { return true }
|
||||
kubelet.sourcesReady = func() bool { return true }
|
||||
kubelet.masterServiceNamespace = api.NamespaceDefault
|
||||
kubelet.serviceLister = testServiceLister{}
|
||||
kubelet.readiness = newReadinessStates()
|
||||
|
@ -396,22 +396,21 @@ func TestSyncPodsDoesNothing(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
// 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",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_0"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -439,10 +438,9 @@ func TestSyncPodsWithTerminationLog(t *testing.T) {
|
|||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -486,10 +484,9 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
|
|||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -521,8 +518,8 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) {
|
|||
}
|
||||
|
||||
if len(fakeDocker.Created) != 2 ||
|
||||
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) ||
|
||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[1]) {
|
||||
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo_new_", fakeDocker.Created[0]) ||
|
||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo_new_", fakeDocker.Created[1]) {
|
||||
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
||||
}
|
||||
fakeDocker.Unlock()
|
||||
|
@ -537,10 +534,9 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
|
|||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -566,8 +562,8 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
|
|||
}
|
||||
|
||||
if len(fakeDocker.Created) != 2 ||
|
||||
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) ||
|
||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[1]) {
|
||||
!matchString(t, "k8s_POD\\.[a-f0-9]+_foo_new_", fakeDocker.Created[0]) ||
|
||||
!matchString(t, "k8s_bar\\.[a-f0-9]+_foo_new_", fakeDocker.Created[1]) {
|
||||
t.Errorf("Unexpected containers created %v", fakeDocker.Created)
|
||||
}
|
||||
fakeDocker.Unlock()
|
||||
|
@ -578,17 +574,16 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_0"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -609,7 +604,7 @@ func TestSyncPodsWithPodInfraCreatesContainer(t *testing.T) {
|
|||
|
||||
fakeDocker.Lock()
|
||||
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)
|
||||
}
|
||||
fakeDocker.Unlock()
|
||||
|
@ -622,17 +617,16 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_0"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_0"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -664,7 +658,7 @@ func TestSyncPodsWithPodInfraCreatesContainerCallsHandler(t *testing.T) {
|
|||
|
||||
fakeDocker.Lock()
|
||||
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)
|
||||
}
|
||||
fakeDocker.Unlock()
|
||||
|
@ -678,17 +672,16 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
// 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",
|
||||
},
|
||||
}
|
||||
kubelet.pods = []api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -722,17 +715,17 @@ func TestSyncPodsDeletesWithNoPodInfraContainer(t *testing.T) {
|
|||
func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) {
|
||||
ready := false
|
||||
kubelet, fakeDocker, _ := newTestKubelet(t)
|
||||
kubelet.sourceReady = func(source string) bool { return ready }
|
||||
kubelet.sourcesReady = func() bool { return ready }
|
||||
|
||||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
// 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",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||
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) {
|
||||
kubelet, fakeDocker, _ := newTestKubelet(t)
|
||||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
// 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",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||
ID: "9876",
|
||||
},
|
||||
{
|
||||
|
@ -866,26 +798,25 @@ func TestSyncPodDeletesDuplicate(t *testing.T) {
|
|||
dockerContainers := dockertools.DockerContainers{
|
||||
"1234": &docker.APIContainers{
|
||||
// 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",
|
||||
},
|
||||
"9876": &docker.APIContainers{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_bar.new.test_12345678_2222"},
|
||||
Names: []string{"/k8s_POD_bar_new_12345678_2222"},
|
||||
ID: "9876",
|
||||
},
|
||||
"4567": &docker.APIContainers{
|
||||
// Duplicate for the same container.
|
||||
Names: []string{"/k8s_foo_bar.new.test_12345678_3333"},
|
||||
Names: []string{"/k8s_foo_bar_new_12345678_3333"},
|
||||
ID: "4567",
|
||||
},
|
||||
}
|
||||
bound := api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "bar",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "bar",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -911,21 +842,20 @@ func TestSyncPodBadHash(t *testing.T) {
|
|||
dockerContainers := dockertools.DockerContainers{
|
||||
"1234": &docker.APIContainers{
|
||||
// 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",
|
||||
},
|
||||
"9876": &docker.APIContainers{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
bound := api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -960,21 +890,20 @@ func TestSyncPodUnhealthy(t *testing.T) {
|
|||
dockerContainers := dockertools.DockerContainers{
|
||||
"1234": &docker.APIContainers{
|
||||
// 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",
|
||||
},
|
||||
"9876": &docker.APIContainers{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
bound := api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -1295,11 +1224,11 @@ func TestGetContainerInfo(t *testing.T) {
|
|||
ID: containerID,
|
||||
// pod id: qux
|
||||
// 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 {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -1369,11 +1298,11 @@ func TestGetContainerInfoWhenCadvisorFailed(t *testing.T) {
|
|||
ID: containerID,
|
||||
// pod id: qux
|
||||
// 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 {
|
||||
t.Errorf("non-nil stats on error")
|
||||
}
|
||||
|
@ -1428,7 +1357,7 @@ func TestGetContainerInfoWithNoContainers(t *testing.T) {
|
|||
kubelet.cadvisorClient = mockCadvisor
|
||||
|
||||
kubelet.dockerClient = &errorTestingDockerClient{listContainersError: nil}
|
||||
stats, err := kubelet.GetContainerInfo("qux", "", "foo", nil)
|
||||
stats, err := kubelet.GetContainerInfo("qux_ns", "", "foo", nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error from cadvisor client, got none")
|
||||
}
|
||||
|
@ -1449,12 +1378,12 @@ func TestGetContainerInfoWithNoMatchingContainers(t *testing.T) {
|
|||
containerList := []docker.APIContainers{
|
||||
{
|
||||
ID: "fakeId",
|
||||
Names: []string{"/k8s_bar_qux_1234_42"},
|
||||
Names: []string{"/k8s_bar_qux_ns_1234_42"},
|
||||
},
|
||||
}
|
||||
|
||||
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 {
|
||||
t.Errorf("Expected error from cadvisor client, got none")
|
||||
}
|
||||
|
@ -1540,7 +1469,7 @@ func TestRunInContainer(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
ID: containerID,
|
||||
Names: []string{"/k8s_" + containerName + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
||||
Names: []string{"/k8s_" + containerName + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1548,10 +1477,9 @@ func TestRunInContainer(t *testing.T) {
|
|||
_, err := kubelet.RunInContainer(
|
||||
GetPodFullName(&api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
},
|
||||
}),
|
||||
"",
|
||||
|
@ -1581,7 +1509,7 @@ func TestRunHandlerExec(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
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 {
|
||||
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 {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -1685,16 +1613,15 @@ func TestSyncPodEventHandlerFails(t *testing.T) {
|
|||
dockerContainers := dockertools.DockerContainers{
|
||||
"9876": &docker.APIContainers{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_12345678_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_12345678_42"},
|
||||
ID: "9876",
|
||||
},
|
||||
}
|
||||
bound := api.BoundPod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -1736,17 +1663,17 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
|||
containers: []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "1876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "2876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "3876",
|
||||
},
|
||||
},
|
||||
|
@ -1766,22 +1693,22 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
|||
containers: []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "1876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "2876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "3876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "4876",
|
||||
},
|
||||
},
|
||||
|
@ -1808,7 +1735,7 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
|||
containers: []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "1876",
|
||||
},
|
||||
},
|
||||
|
@ -1818,32 +1745,32 @@ func TestKubeletGarbageCollection(t *testing.T) {
|
|||
containers: []docker.APIContainers{
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo2.new.test_.beefbeef_40"},
|
||||
Names: []string{"/k8s_POD_foo2_new_.beefbeef_40"},
|
||||
ID: "1706",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo2.new.test_.beefbeef_40"},
|
||||
Names: []string{"/k8s_POD_foo2_new_.beefbeef_40"},
|
||||
ID: "2706",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo2.new.test_.beefbeef_40"},
|
||||
Names: []string{"/k8s_POD_foo2_new_.beefbeef_40"},
|
||||
ID: "3706",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "1876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "2876",
|
||||
},
|
||||
{
|
||||
// pod infra container
|
||||
Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"},
|
||||
Names: []string{"/k8s_POD_foo_new_.deadbeef_42"},
|
||||
ID: "3876",
|
||||
},
|
||||
},
|
||||
|
@ -2052,10 +1979,9 @@ func TestSyncPodsWithPullPolicy(t *testing.T) {
|
|||
err := kubelet.SyncPods([]api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -2851,16 +2777,15 @@ func TestExecInContainerNoSuchContainer(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
ID: "notfound",
|
||||
Names: []string{"/k8s_notfound_" + podName + "." + podNamespace + ".test_12345678_42"},
|
||||
Names: []string{"/k8s_notfound_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||
},
|
||||
}
|
||||
|
||||
err := kubelet.ExecInContainer(
|
||||
GetPodFullName(&api.BoundPod{ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
}}),
|
||||
"",
|
||||
containerID,
|
||||
|
@ -2909,16 +2834,15 @@ func TestExecInContainer(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
ID: containerID,
|
||||
Names: []string{"/k8s_" + containerID + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
||||
Names: []string{"/k8s_" + containerID + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||
},
|
||||
}
|
||||
|
||||
err := kubelet.ExecInContainer(
|
||||
GetPodFullName(&api.BoundPod{ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
}}),
|
||||
"",
|
||||
containerID,
|
||||
|
@ -2987,16 +2911,15 @@ func TestPortForwardNoSuchContainer(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
ID: "notfound",
|
||||
Names: []string{"/k8s_notfound_" + podName + "." + podNamespace + ".test_12345678_42"},
|
||||
Names: []string{"/k8s_notfound_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||
},
|
||||
}
|
||||
|
||||
err := kubelet.PortForward(
|
||||
GetPodFullName(&api.BoundPod{ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
}}),
|
||||
"",
|
||||
port,
|
||||
|
@ -3027,20 +2950,19 @@ func TestPortForward(t *testing.T) {
|
|||
fakeDocker.ContainerList = []docker.APIContainers{
|
||||
{
|
||||
ID: infraContainerID,
|
||||
Names: []string{"/k8s_" + kubelet.podInfraContainerImage + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
||||
Names: []string{"/k8s_" + kubelet.podInfraContainerImage + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||
},
|
||||
{
|
||||
ID: containerID,
|
||||
Names: []string{"/k8s_" + containerID + "_" + podName + "." + podNamespace + ".test_12345678_42"},
|
||||
Names: []string{"/k8s_" + containerID + "_" + podName + "_" + podNamespace + "_12345678_42"},
|
||||
},
|
||||
}
|
||||
|
||||
err := kubelet.PortForward(
|
||||
GetPodFullName(&api.BoundPod{ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
}}),
|
||||
"",
|
||||
port,
|
||||
|
|
|
@ -76,7 +76,7 @@ func TestRunOnce(t *testing.T) {
|
|||
}
|
||||
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",
|
||||
Status: "running",
|
||||
},
|
||||
|
@ -130,10 +130,9 @@ func TestRunOnce(t *testing.T) {
|
|||
results, err := kb.runOnce([]api.BoundPod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
Annotations: map[string]string{ConfigSourceAnnotationKey: "test"},
|
||||
UID: "12345678",
|
||||
Name: "foo",
|
||||
Namespace: "new",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
|
|
@ -129,9 +129,6 @@ func newServerTest() *serverTestFramework {
|
|||
ObjectMeta: api.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Annotations: map[string]string{
|
||||
ConfigSourceAnnotationKey: "etcd",
|
||||
},
|
||||
},
|
||||
}, true
|
||||
},
|
||||
|
@ -157,6 +154,14 @@ func readResp(resp *http.Response) (string, error) {
|
|||
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) {
|
||||
fw := newServerTest()
|
||||
expected := api.PodStatus{
|
||||
|
@ -165,7 +170,7 @@ func TestPodStatus(t *testing.T) {
|
|||
},
|
||||
}
|
||||
fw.fakeKubelet.statusFunc = func(name string) (api.PodStatus, error) {
|
||||
if name == "goodpod.default.etcd" {
|
||||
if name == "goodpod_default" {
|
||||
return expected, nil
|
||||
}
|
||||
return api.PodStatus{}, fmt.Errorf("bad pod %s", name)
|
||||
|
@ -191,7 +196,7 @@ func TestContainerInfo(t *testing.T) {
|
|||
fw := newServerTest()
|
||||
expectedInfo := &info.ContainerInfo{}
|
||||
podID := "somepod"
|
||||
expectedPodID := "somepod" + ".default.etcd"
|
||||
expectedPodID := getPodName(podID, "")
|
||||
expectedContainerName := "goodcontainer"
|
||||
fw.fakeKubelet.containerInfoFunc = func(podID string, uid types.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||
if podID != expectedPodID || containerName != expectedContainerName {
|
||||
|
@ -220,7 +225,7 @@ func TestContainerInfoWithUidNamespace(t *testing.T) {
|
|||
expectedInfo := &info.ContainerInfo{}
|
||||
podID := "somepod"
|
||||
expectedNamespace := "custom"
|
||||
expectedPodID := "somepod" + "." + expectedNamespace + ".etcd"
|
||||
expectedPodID := getPodName(podID, expectedNamespace)
|
||||
expectedContainerName := "goodcontainer"
|
||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||
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"
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedContainerName := "baz"
|
||||
expectedCommand := "ls -a"
|
||||
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"
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedUID := "7e00838d_-_3523_-_11e4_-_8421_-_42010af0a720"
|
||||
expectedContainerName := "baz"
|
||||
expectedCommand := "ls -a"
|
||||
|
@ -509,9 +514,6 @@ func setPodByNameFunc(fw *serverTestFramework, namespace, pod, container string)
|
|||
ObjectMeta: api.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Name: pod,
|
||||
Annotations: map[string]string{
|
||||
ConfigSourceAnnotationKey: "etcd",
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
|
@ -548,7 +550,7 @@ func TestContainerLogs(t *testing.T) {
|
|||
output := "foo bar"
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + ".other.etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedContainerName := "baz"
|
||||
expectedTail := ""
|
||||
expectedFollow := false
|
||||
|
@ -575,7 +577,7 @@ func TestContainerLogsWithTail(t *testing.T) {
|
|||
output := "foo bar"
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + ".other.etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedContainerName := "baz"
|
||||
expectedTail := "5"
|
||||
expectedFollow := false
|
||||
|
@ -602,7 +604,7 @@ func TestContainerLogsWithFollow(t *testing.T) {
|
|||
output := "foo bar"
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + ".other.etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedContainerName := "baz"
|
||||
expectedTail := ""
|
||||
expectedFollow := true
|
||||
|
@ -693,7 +695,7 @@ func TestServeExecInContainer(t *testing.T) {
|
|||
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||
expectedContainerName := "baz"
|
||||
expectedCommand := "ls -a"
|
||||
|
@ -955,7 +957,7 @@ func TestServePortForward(t *testing.T) {
|
|||
|
||||
podNamespace := "other"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
||||
expectedPodName := getPodName(podName, podNamespace)
|
||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||
|
||||
for i, test := range tests {
|
||||
|
|
|
@ -18,10 +18,8 @@ package kubelet
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const ConfigSourceAnnotationKey = "kubernetes.io/config.source"
|
||||
|
@ -52,6 +50,8 @@ const (
|
|||
ApiserverSource = "api"
|
||||
// Updates from all sources
|
||||
AllSource = "*"
|
||||
|
||||
NamespaceDefault = api.NamespaceDefault
|
||||
)
|
||||
|
||||
// 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.
|
||||
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.
|
||||
// If the pod full name is invalid, empty strings are returend.
|
||||
func ParsePodFullName(podFullName string) (podName, podNamespace string, podAnnotations map[string]string) {
|
||||
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
|
||||
// Build the pod full name from pod name and namespace.
|
||||
func BuildPodFullName(name, namespace string) string {
|
||||
return name + "_" + namespace
|
||||
}
|
||||
|
|
|
@ -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