Commit d020ca00 authored by Clayton Coleman's avatar Clayton Coleman

Pass hostname to all kubelet config sources instead of os.Hostname()

Make applyDefaults be tied to the current config source.
parent bd12cfea
...@@ -205,7 +205,8 @@ func startComponents(manifestURL, apiVersion string) (string, string) { ...@@ -205,7 +205,8 @@ func startComponents(manifestURL, apiVersion string) (string, string) {
scheduler.New(schedulerConfig).Run() scheduler.New(schedulerConfig).Run()
endpoints := service.NewEndpointController(cl) endpoints := service.NewEndpointController(cl)
go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) // ensure the service endpoints are sync'd several times within the window that the integration tests wait
go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*4)
controllerManager := replicationControllerPkg.NewReplicationManager(cl) controllerManager := replicationControllerPkg.NewReplicationManager(cl)
...@@ -277,7 +278,9 @@ func endpointsSet(c *client.Client, serviceNamespace, serviceID string, endpoint ...@@ -277,7 +278,9 @@ func endpointsSet(c *client.Client, serviceNamespace, serviceID string, endpoint
glog.Infof("Error on creating endpoints: %v", err) glog.Infof("Error on creating endpoints: %v", err)
return false, nil return false, nil
} }
glog.Infof("endpoints: %v", endpoints.Endpoints) for _, e := range endpoints.Endpoints {
glog.Infof("%s/%s endpoint: %s:%d %#v", serviceNamespace, serviceID, e.IP, e.Port, e.TargetRef)
}
return len(endpoints.Endpoints) == endpointCount, nil return len(endpoints.Endpoints) == endpointCount, nil
} }
} }
...@@ -299,6 +302,9 @@ func podNotFound(c *client.Client, podNamespace string, podID string) wait.Condi ...@@ -299,6 +302,9 @@ func podNotFound(c *client.Client, podNamespace string, podID string) wait.Condi
func podRunning(c *client.Client, podNamespace string, podID string) wait.ConditionFunc { func podRunning(c *client.Client, podNamespace string, podID string) wait.ConditionFunc {
return func() (bool, error) { return func() (bool, error) {
pod, err := c.Pods(podNamespace).Get(podID) pod, err := c.Pods(podNamespace).Get(podID)
if apierrors.IsNotFound(err) {
return false, nil
}
if err != nil { if err != nil {
return false, err return false, err
} }
...@@ -321,11 +327,15 @@ containers: ...@@ -321,11 +327,15 @@ containers:
ioutil.WriteFile(manifestFile.Name(), []byte(manifest), 0600) ioutil.WriteFile(manifestFile.Name(), []byte(manifest), 0600)
// Wait for the mirror pod to be created. // Wait for the mirror pod to be created.
hostname, _ := os.Hostname() podName := "static-pod-localhost"
podName := fmt.Sprintf("static-pod-%s", hostname)
namespace := kubelet.NamespaceDefault namespace := kubelet.NamespaceDefault
if err := wait.Poll(time.Second, time.Second*30, if err := wait.Poll(time.Second, time.Minute*2,
podRunning(c, namespace, podName)); err != nil { podRunning(c, namespace, podName)); err != nil {
if pods, err := c.Pods(namespace).List(labels.Everything()); err == nil {
for _, pod := range pods.Items {
glog.Infof("pod found: %s/%s", namespace, pod.Name)
}
}
glog.Fatalf("FAILED: mirror pod has not been created or is not running: %v", err) glog.Fatalf("FAILED: mirror pod has not been created or is not running: %v", err)
} }
// Delete the mirror pod, and wait for it to be recreated. // Delete the mirror pod, and wait for it to be recreated.
...@@ -713,7 +723,7 @@ func runServiceTest(client *client.Client) { ...@@ -713,7 +723,7 @@ func runServiceTest(client *client.Client) {
glog.Fatalf("Failed to create service: %v, %v", svc3, err) glog.Fatalf("Failed to create service: %v, %v", svc3, err)
} }
if err := wait.Poll(time.Second, time.Second*20, endpointsSet(client, svc1.Namespace, svc1.Name, 1)); err != nil { if err := wait.Poll(time.Second, time.Second*30, endpointsSet(client, svc1.Namespace, svc1.Name, 1)); err != nil {
glog.Fatalf("FAILED: unexpected endpoints: %v", err) glog.Fatalf("FAILED: unexpected endpoints: %v", err)
} }
// A second service with the same port. // A second service with the same port.
...@@ -732,7 +742,7 @@ func runServiceTest(client *client.Client) { ...@@ -732,7 +742,7 @@ func runServiceTest(client *client.Client) {
if err != nil { if err != nil {
glog.Fatalf("Failed to create service: %v, %v", svc2, err) glog.Fatalf("Failed to create service: %v, %v", svc2, err)
} }
if err := wait.Poll(time.Second, time.Second*20, endpointsSet(client, svc2.Namespace, svc2.Name, 1)); err != nil { if err := wait.Poll(time.Second, time.Second*30, endpointsSet(client, svc2.Namespace, svc2.Name, 1)); err != nil {
glog.Fatalf("FAILED: unexpected endpoints: %v", err) glog.Fatalf("FAILED: unexpected endpoints: %v", err)
} }
......
...@@ -358,13 +358,13 @@ func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig { ...@@ -358,13 +358,13 @@ func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig {
// define file config source // define file config source
if kc.ConfigFile != "" { if kc.ConfigFile != "" {
glog.Infof("Adding manifest file: %v", kc.ConfigFile) glog.Infof("Adding manifest file: %v", kc.ConfigFile)
config.NewSourceFile(kc.ConfigFile, kc.FileCheckFrequency, cfg.Channel(kubelet.FileSource)) config.NewSourceFile(kc.ConfigFile, kc.Hostname, kc.FileCheckFrequency, cfg.Channel(kubelet.FileSource))
} }
// define url config source // define url config source
if kc.ManifestURL != "" { if kc.ManifestURL != "" {
glog.Infof("Adding manifest url: %v", kc.ManifestURL) glog.Infof("Adding manifest url: %v", kc.ManifestURL)
config.NewSourceURL(kc.ManifestURL, kc.HTTPCheckFrequency, cfg.Channel(kubelet.HTTPSource)) config.NewSourceURL(kc.ManifestURL, kc.Hostname, kc.HTTPCheckFrequency, cfg.Channel(kubelet.HTTPSource))
} }
if kc.KubeClient != nil { if kc.KubeClient != nil {
glog.Infof("Watching apiserver") glog.Infof("Watching apiserver")
......
...@@ -26,8 +26,6 @@ import ( ...@@ -26,8 +26,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
const hostname string = "mcaa1"
type fakePodLW struct { type fakePodLW struct {
listResp runtime.Object listResp runtime.Object
watchResp watch.Interface watchResp watch.Interface
......
...@@ -21,8 +21,6 @@ import ( ...@@ -21,8 +21,6 @@ import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"os"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
...@@ -35,15 +33,10 @@ import ( ...@@ -35,15 +33,10 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
func applyDefaults(pod *api.Pod, source string, isFile bool) error { func applyDefaults(pod *api.Pod, source string, isFile bool, hostname string) error {
if len(pod.UID) == 0 { if len(pod.UID) == 0 {
hasher := md5.New() hasher := md5.New()
if isFile { if isFile {
hostname, err := os.Hostname() // TODO: kubelet name would be better
if err != nil {
return err
}
hostname = strings.ToLower(hostname)
fmt.Fprintf(hasher, "host:%s", hostname) fmt.Fprintf(hasher, "host:%s", hostname)
fmt.Fprintf(hasher, "file:%s", source) fmt.Fprintf(hasher, "file:%s", source)
} else { } else {
...@@ -60,7 +53,7 @@ func applyDefaults(pod *api.Pod, source string, isFile bool) error { ...@@ -60,7 +53,7 @@ func applyDefaults(pod *api.Pod, source string, isFile bool) error {
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 { if pod.Name, err = GeneratePodName(pod.Name, hostname); err != nil {
return err return err
} }
glog.V(5).Infof("Generated Name %q for UID %q from URL %s", pod.Name, pod.UID, source) glog.V(5).Infof("Generated Name %q for UID %q from URL %s", pod.Name, pod.UID, source)
...@@ -76,7 +69,9 @@ func applyDefaults(pod *api.Pod, source string, isFile bool) error { ...@@ -76,7 +69,9 @@ func applyDefaults(pod *api.Pod, source string, isFile bool) error {
return nil return nil
} }
func tryDecodeSinglePod(data []byte, source string, isFile bool) (parsed bool, pod api.Pod, err error) { type defaultFunc func(pod *api.Pod) error
func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod api.Pod, err error) {
obj, err := api.Scheme.Decode(data) obj, err := api.Scheme.Decode(data)
if err != nil { if err != nil {
return false, pod, err return false, pod, err
...@@ -88,7 +83,7 @@ func tryDecodeSinglePod(data []byte, source string, isFile bool) (parsed bool, p ...@@ -88,7 +83,7 @@ func tryDecodeSinglePod(data []byte, source string, isFile bool) (parsed bool, p
} }
newPod := obj.(*api.Pod) newPod := obj.(*api.Pod)
// Apply default values and validate the pod. // Apply default values and validate the pod.
if err = applyDefaults(newPod, source, isFile); err != nil { if err = defaultFn(newPod); err != nil {
return true, pod, err return true, pod, err
} }
if errs := validation.ValidatePod(newPod); len(errs) > 0 { if errs := validation.ValidatePod(newPod); len(errs) > 0 {
...@@ -98,7 +93,7 @@ func tryDecodeSinglePod(data []byte, source string, isFile bool) (parsed bool, p ...@@ -98,7 +93,7 @@ func tryDecodeSinglePod(data []byte, source string, isFile bool) (parsed bool, p
return true, *newPod, nil return true, *newPod, nil
} }
func tryDecodePodList(data []byte, source string, isFile bool) (parsed bool, pods api.PodList, err error) { func tryDecodePodList(data []byte, defaultFn defaultFunc) (parsed bool, pods api.PodList, err error) {
obj, err := api.Scheme.Decode(data) obj, err := api.Scheme.Decode(data)
if err != nil { if err != nil {
return false, pods, err return false, pods, err
...@@ -112,7 +107,7 @@ func tryDecodePodList(data []byte, source string, isFile bool) (parsed bool, pod ...@@ -112,7 +107,7 @@ func tryDecodePodList(data []byte, source string, isFile bool) (parsed bool, pod
// Apply default values and validate pods. // Apply default values and validate pods.
for i := range newPods.Items { for i := range newPods.Items {
newPod := &newPods.Items[i] newPod := &newPods.Items[i]
if err = applyDefaults(newPod, source, isFile); err != nil { if err = defaultFn(newPod); err != nil {
return true, pods, err return true, pods, err
} }
if errs := validation.ValidatePod(newPod); len(errs) > 0 { if errs := validation.ValidatePod(newPod); len(errs) > 0 {
...@@ -123,7 +118,7 @@ func tryDecodePodList(data []byte, source string, isFile bool) (parsed bool, pod ...@@ -123,7 +118,7 @@ func tryDecodePodList(data []byte, source string, isFile bool) (parsed bool, pod
return true, *newPods, err return true, *newPods, err
} }
func tryDecodeSingleManifest(data []byte, source string, isFile bool) (parsed bool, manifest v1beta1.ContainerManifest, pod api.Pod, err error) { func tryDecodeSingleManifest(data []byte, defaultFn defaultFunc) (parsed bool, manifest v1beta1.ContainerManifest, pod api.Pod, err error) {
// TODO: should be api.Scheme.Decode // TODO: should be api.Scheme.Decode
// This is awful. DecodeInto() expects to find an APIObject, which // This is awful. DecodeInto() expects to find an APIObject, which
// Manifest is not. We keep reading manifest for now for compat, but // Manifest is not. We keep reading manifest for now for compat, but
...@@ -149,14 +144,14 @@ func tryDecodeSingleManifest(data []byte, source string, isFile bool) (parsed bo ...@@ -149,14 +144,14 @@ func tryDecodeSingleManifest(data []byte, source string, isFile bool) (parsed bo
if err = api.Scheme.Convert(&newManifest, &pod); err != nil { if err = api.Scheme.Convert(&newManifest, &pod); err != nil {
return true, manifest, pod, err return true, manifest, pod, err
} }
if err = applyDefaults(&pod, source, isFile); err != nil { if err := defaultFn(&pod); err != nil {
return true, manifest, pod, err return true, manifest, pod, err
} }
// Success. // Success.
return true, manifest, pod, nil return true, manifest, pod, nil
} }
func tryDecodeManifestList(data []byte, source string, isFile bool) (parsed bool, manifests []v1beta1.ContainerManifest, pods api.PodList, err error) { func tryDecodeManifestList(data []byte, defaultFn defaultFunc) (parsed bool, manifests []v1beta1.ContainerManifest, pods api.PodList, err error) {
// TODO: should be api.Scheme.Decode // TODO: should be api.Scheme.Decode
// See the comment in tryDecodeSingle(). // See the comment in tryDecodeSingle().
if err = yaml.Unmarshal(data, &manifests); err != nil { if err = yaml.Unmarshal(data, &manifests); err != nil {
...@@ -179,7 +174,7 @@ func tryDecodeManifestList(data []byte, source string, isFile bool) (parsed bool ...@@ -179,7 +174,7 @@ func tryDecodeManifestList(data []byte, source string, isFile bool) (parsed bool
} }
for i := range pods.Items { for i := range pods.Items {
pod := &pods.Items[i] pod := &pods.Items[i]
if err = applyDefaults(pod, source, isFile); err != nil { if err := defaultFn(pod); err != nil {
return true, manifests, pods, err return true, manifests, pods, err
} }
} }
......
...@@ -18,9 +18,7 @@ package config ...@@ -18,9 +18,7 @@ package config
import ( import (
"fmt" "fmt"
"os"
"reflect" "reflect"
"strings"
"sync" "sync"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
...@@ -363,11 +361,6 @@ func bestPodIdentString(pod *api.Pod) string { ...@@ -363,11 +361,6 @@ func bestPodIdentString(pod *api.Pod) string {
return fmt.Sprintf("%s.%s", name, namespace) return fmt.Sprintf("%s.%s", name, namespace)
} }
func GeneratePodName(name string) (string, error) { func GeneratePodName(name, hostname string) (string, error) {
hostname, err := os.Hostname() //TODO: kubelet name would be better
if err != nil {
return "", err
}
hostname = strings.ToLower(hostname)
return fmt.Sprintf("%s-%s", name, hostname), nil return fmt.Sprintf("%s-%s", name, hostname), nil
} }
...@@ -33,14 +33,16 @@ import ( ...@@ -33,14 +33,16 @@ import (
) )
type sourceFile struct { type sourceFile struct {
path string path string
updates chan<- interface{} hostname string
updates chan<- interface{}
} }
func NewSourceFile(path string, period time.Duration, updates chan<- interface{}) { func NewSourceFile(path string, hostname string, period time.Duration, updates chan<- interface{}) {
config := &sourceFile{ config := &sourceFile{
path: path, path: path,
updates: updates, hostname: hostname,
updates: updates,
} }
glog.V(1).Infof("Watching path %q", path) glog.V(1).Infof("Watching path %q", path)
go util.Forever(config.run, period) go util.Forever(config.run, period)
...@@ -52,6 +54,10 @@ func (s *sourceFile) run() { ...@@ -52,6 +54,10 @@ func (s *sourceFile) run() {
} }
} }
func (s *sourceFile) applyDefaults(pod *api.Pod, source string) error {
return applyDefaults(pod, source, true, s.hostname)
}
func (s *sourceFile) extractFromPath() error { func (s *sourceFile) extractFromPath() error {
path := s.path path := s.path
statInfo, err := os.Stat(path) statInfo, err := os.Stat(path)
...@@ -66,14 +72,14 @@ func (s *sourceFile) extractFromPath() error { ...@@ -66,14 +72,14 @@ func (s *sourceFile) extractFromPath() error {
switch { switch {
case statInfo.Mode().IsDir(): case statInfo.Mode().IsDir():
pods, err := extractFromDir(path) pods, err := s.extractFromDir(path)
if err != nil { if err != nil {
return err return err
} }
s.updates <- kubelet.PodUpdate{pods, kubelet.SET, kubelet.FileSource} s.updates <- kubelet.PodUpdate{pods, kubelet.SET, kubelet.FileSource}
case statInfo.Mode().IsRegular(): case statInfo.Mode().IsRegular():
pod, err := extractFromFile(path) pod, err := s.extractFromFile(path)
if err != nil { if err != nil {
return err return err
} }
...@@ -89,7 +95,7 @@ func (s *sourceFile) extractFromPath() error { ...@@ -89,7 +95,7 @@ func (s *sourceFile) extractFromPath() error {
// Get as many pod configs as we can from a directory. Return an error iff something // Get as many pod configs as we can from a directory. Return an error iff something
// prevented us from reading anything at all. Do not return an error if only some files // prevented us from reading anything at all. Do not return an error if only some files
// were problematic. // were problematic.
func extractFromDir(name string) ([]api.Pod, error) { func (s *sourceFile) extractFromDir(name string) ([]api.Pod, error) {
dirents, err := filepath.Glob(filepath.Join(name, "[^.]*")) dirents, err := filepath.Glob(filepath.Join(name, "[^.]*"))
if err != nil { if err != nil {
return nil, fmt.Errorf("glob failed: %v", err) return nil, fmt.Errorf("glob failed: %v", err)
...@@ -112,7 +118,7 @@ func extractFromDir(name string) ([]api.Pod, error) { ...@@ -112,7 +118,7 @@ func extractFromDir(name string) ([]api.Pod, error) {
case statInfo.Mode().IsDir(): case statInfo.Mode().IsDir():
glog.V(1).Infof("Not recursing into config path %q", path) glog.V(1).Infof("Not recursing into config path %q", path)
case statInfo.Mode().IsRegular(): case statInfo.Mode().IsRegular():
pod, err := extractFromFile(path) pod, err := s.extractFromFile(path)
if err != nil { if err != nil {
glog.V(1).Infof("Can't process config file %q: %v", path, err) glog.V(1).Infof("Can't process config file %q: %v", path, err)
} else { } else {
...@@ -125,7 +131,7 @@ func extractFromDir(name string) ([]api.Pod, error) { ...@@ -125,7 +131,7 @@ func extractFromDir(name string) ([]api.Pod, error) {
return pods, nil return pods, nil
} }
func extractFromFile(filename string) (pod api.Pod, err error) { func (s *sourceFile) extractFromFile(filename string) (pod api.Pod, err error) {
glog.V(3).Infof("Reading config file %q", filename) glog.V(3).Infof("Reading config file %q", filename)
file, err := os.Open(filename) file, err := os.Open(filename)
if err != nil { if err != nil {
...@@ -138,7 +144,11 @@ func extractFromFile(filename string) (pod api.Pod, err error) { ...@@ -138,7 +144,11 @@ func extractFromFile(filename string) (pod api.Pod, err error) {
return pod, err return pod, err
} }
parsed, _, pod, manifestErr := tryDecodeSingleManifest(data, filename, true) defaultFn := func(pod *api.Pod) error {
return s.applyDefaults(pod, filename)
}
parsed, _, pod, manifestErr := tryDecodeSingleManifest(data, defaultFn)
if parsed { if parsed {
if manifestErr != nil { if manifestErr != nil {
// It parsed but could not be used. // It parsed but could not be used.
...@@ -147,7 +157,7 @@ func extractFromFile(filename string) (pod api.Pod, err error) { ...@@ -147,7 +157,7 @@ func extractFromFile(filename string) (pod api.Pod, err error) {
return pod, nil return pod, nil
} }
parsed, pod, podErr := tryDecodeSinglePod(data, filename, true) parsed, pod, podErr := tryDecodeSinglePod(data, defaultFn)
if parsed { if parsed {
if podErr != nil { if podErr != nil {
return pod, podErr return pod, podErr
......
...@@ -21,7 +21,6 @@ import ( ...@@ -21,7 +21,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"sort" "sort"
"strings"
"testing" "testing"
"time" "time"
...@@ -34,7 +33,7 @@ import ( ...@@ -34,7 +33,7 @@ import (
func TestExtractFromNonExistentFile(t *testing.T) { func TestExtractFromNonExistentFile(t *testing.T) {
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceFile{"/some/fake/file", ch} c := sourceFile{"/some/fake/file", "localhost", ch}
err := c.extractFromPath() err := c.extractFromPath()
if err == nil { if err == nil {
t.Errorf("Expected error") t.Errorf("Expected error")
...@@ -43,7 +42,7 @@ func TestExtractFromNonExistentFile(t *testing.T) { ...@@ -43,7 +42,7 @@ func TestExtractFromNonExistentFile(t *testing.T) {
func TestUpdateOnNonExistentFile(t *testing.T) { func TestUpdateOnNonExistentFile(t *testing.T) {
ch := make(chan interface{}) ch := make(chan interface{})
NewSourceFile("random_non_existent_path", time.Millisecond, ch) NewSourceFile("random_non_existent_path", "localhost", time.Millisecond, ch)
select { select {
case got := <-ch: case got := <-ch:
update := got.(kubelet.PodUpdate) update := got.(kubelet.PodUpdate)
...@@ -70,9 +69,7 @@ func writeTestFile(t *testing.T, dir, name string, contents string) *os.File { ...@@ -70,9 +69,7 @@ func writeTestFile(t *testing.T, dir, name string, contents string) *os.File {
} }
func TestReadFromFile(t *testing.T) { func TestReadFromFile(t *testing.T) {
hostname, _ := os.Hostname() hostname := "random-test-hostname"
hostname = strings.ToLower(hostname)
var testCases = []struct { var testCases = []struct {
desc string desc string
fileContents string fileContents string
...@@ -256,7 +253,7 @@ func TestReadFromFile(t *testing.T) { ...@@ -256,7 +253,7 @@ func TestReadFromFile(t *testing.T) {
defer os.Remove(file.Name()) defer os.Remove(file.Name())
ch := make(chan interface{}) ch := make(chan interface{})
NewSourceFile(file.Name(), time.Millisecond, ch) NewSourceFile(file.Name(), hostname, time.Millisecond, ch)
select { select {
case got := <-ch: case got := <-ch:
update := got.(kubelet.PodUpdate) update := got.(kubelet.PodUpdate)
...@@ -285,7 +282,7 @@ func TestReadManifestFromFileWithDefaults(t *testing.T) { ...@@ -285,7 +282,7 @@ func TestReadManifestFromFileWithDefaults(t *testing.T) {
defer os.Remove(file.Name()) defer os.Remove(file.Name())
ch := make(chan interface{}) ch := make(chan interface{})
NewSourceFile(file.Name(), time.Millisecond, ch) NewSourceFile(file.Name(), "localhost", time.Millisecond, ch)
select { select {
case got := <-ch: case got := <-ch:
update := got.(kubelet.PodUpdate) update := got.(kubelet.PodUpdate)
...@@ -303,7 +300,7 @@ func TestExtractFromBadDataFile(t *testing.T) { ...@@ -303,7 +300,7 @@ func TestExtractFromBadDataFile(t *testing.T) {
defer os.Remove(file.Name()) defer os.Remove(file.Name())
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceFile{file.Name(), ch} c := sourceFile{file.Name(), "localhost", ch}
err := c.extractFromPath() err := c.extractFromPath()
if err == nil { if err == nil {
t.Fatalf("Expected error") t.Fatalf("Expected error")
...@@ -319,7 +316,7 @@ func TestExtractFromEmptyDir(t *testing.T) { ...@@ -319,7 +316,7 @@ func TestExtractFromEmptyDir(t *testing.T) {
defer os.RemoveAll(dirName) defer os.RemoveAll(dirName)
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceFile{dirName, ch} c := sourceFile{dirName, "localhost", ch}
err = c.extractFromPath() err = c.extractFromPath()
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
...@@ -333,8 +330,7 @@ func TestExtractFromEmptyDir(t *testing.T) { ...@@ -333,8 +330,7 @@ func TestExtractFromEmptyDir(t *testing.T) {
} }
func ExampleManifestAndPod(id string) (v1beta1.ContainerManifest, api.Pod) { func ExampleManifestAndPod(id string) (v1beta1.ContainerManifest, api.Pod) {
hostname, _ := os.Hostname() hostname := "an-example-host"
hostname = strings.ToLower(hostname)
manifest := v1beta1.ContainerManifest{ manifest := v1beta1.ContainerManifest{
Version: "v1beta1", Version: "v1beta1",
...@@ -417,7 +413,7 @@ func TestExtractFromDir(t *testing.T) { ...@@ -417,7 +413,7 @@ func TestExtractFromDir(t *testing.T) {
} }
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceFile{dirName, ch} c := sourceFile{dirName, "an-example-host", ch}
err = c.extractFromPath() err = c.extractFromPath()
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
......
...@@ -32,16 +32,18 @@ import ( ...@@ -32,16 +32,18 @@ import (
) )
type sourceURL struct { type sourceURL struct {
url string url string
updates chan<- interface{} hostname string
data []byte updates chan<- interface{}
data []byte
} }
func NewSourceURL(url string, period time.Duration, updates chan<- interface{}) { func NewSourceURL(url, hostname string, period time.Duration, updates chan<- interface{}) {
config := &sourceURL{ config := &sourceURL{
url: url, url: url,
updates: updates, hostname: hostname,
data: nil, updates: updates,
data: nil,
} }
glog.V(1).Infof("Watching URL %s", url) glog.V(1).Infof("Watching URL %s", url)
go util.Forever(config.run, period) go util.Forever(config.run, period)
...@@ -53,6 +55,10 @@ func (s *sourceURL) run() { ...@@ -53,6 +55,10 @@ func (s *sourceURL) run() {
} }
} }
func (s *sourceURL) applyDefaults(pod *api.Pod) error {
return applyDefaults(pod, s.url, false, s.hostname)
}
func (s *sourceURL) extractFromURL() error { func (s *sourceURL) extractFromURL() error {
resp, err := http.Get(s.url) resp, err := http.Get(s.url)
if err != nil { if err != nil {
...@@ -78,7 +84,7 @@ func (s *sourceURL) extractFromURL() error { ...@@ -78,7 +84,7 @@ func (s *sourceURL) extractFromURL() error {
s.data = data s.data = data
// First try as if it's a single manifest // First try as if it's a single manifest
parsed, manifest, pod, singleErr := tryDecodeSingleManifest(data, s.url, false) parsed, manifest, pod, singleErr := tryDecodeSingleManifest(data, s.applyDefaults)
if parsed { if parsed {
if singleErr != nil { if singleErr != nil {
// It parsed but could not be used. // It parsed but could not be used.
...@@ -90,7 +96,7 @@ func (s *sourceURL) extractFromURL() error { ...@@ -90,7 +96,7 @@ func (s *sourceURL) extractFromURL() error {
} }
// That didn't work, so try an array of manifests. // That didn't work, so try an array of manifests.
parsed, manifests, pods, multiErr := tryDecodeManifestList(data, s.url, false) parsed, manifests, pods, multiErr := tryDecodeManifestList(data, s.applyDefaults)
if parsed { if parsed {
if multiErr != nil { if multiErr != nil {
// It parsed but could not be used. // It parsed but could not be used.
...@@ -112,7 +118,7 @@ func (s *sourceURL) extractFromURL() error { ...@@ -112,7 +118,7 @@ func (s *sourceURL) extractFromURL() error {
// Try to parse it as Pod(s). // Try to parse it as Pod(s).
// First try as it is a single pod. // First try as it is a single pod.
parsed, pod, singlePodErr := tryDecodeSinglePod(data, s.url, false) parsed, pod, singlePodErr := tryDecodeSinglePod(data, s.applyDefaults)
if parsed { if parsed {
if singlePodErr != nil { if singlePodErr != nil {
// It parsed but could not be used. // It parsed but could not be used.
...@@ -123,7 +129,7 @@ func (s *sourceURL) extractFromURL() error { ...@@ -123,7 +129,7 @@ func (s *sourceURL) extractFromURL() error {
} }
// That didn't work, so try a list of pods. // That didn't work, so try a list of pods.
parsed, pods, multiPodErr := tryDecodePodList(data, s.url, false) parsed, pods, multiPodErr := tryDecodePodList(data, s.applyDefaults)
if parsed { if parsed {
if multiPodErr != nil { if multiPodErr != nil {
// It parsed but could not be used. // It parsed but could not be used.
......
...@@ -19,8 +19,6 @@ package config ...@@ -19,8 +19,6 @@ package config
import ( import (
"encoding/json" "encoding/json"
"net/http/httptest" "net/http/httptest"
"os"
"strings"
"testing" "testing"
"time" "time"
...@@ -35,7 +33,7 @@ import ( ...@@ -35,7 +33,7 @@ import (
func TestURLErrorNotExistNoUpdate(t *testing.T) { func TestURLErrorNotExistNoUpdate(t *testing.T) {
ch := make(chan interface{}) ch := make(chan interface{})
NewSourceURL("http://localhost:49575/_not_found_", time.Millisecond, ch) NewSourceURL("http://localhost:49575/_not_found_", "localhost", time.Millisecond, ch)
select { select {
case got := <-ch: case got := <-ch:
t.Errorf("Expected no update, Got %#v", got) t.Errorf("Expected no update, Got %#v", got)
...@@ -45,7 +43,7 @@ func TestURLErrorNotExistNoUpdate(t *testing.T) { ...@@ -45,7 +43,7 @@ func TestURLErrorNotExistNoUpdate(t *testing.T) {
func TestExtractFromHttpBadness(t *testing.T) { func TestExtractFromHttpBadness(t *testing.T) {
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceURL{"http://localhost:49575/_not_found_", ch, nil} c := sourceURL{"http://localhost:49575/_not_found_", "other", ch, nil}
if err := c.extractFromURL(); err == nil { if err := c.extractFromURL(); err == nil {
t.Errorf("Expected error") t.Errorf("Expected error")
} }
...@@ -111,7 +109,7 @@ func TestExtractInvalidManifest(t *testing.T) { ...@@ -111,7 +109,7 @@ func TestExtractInvalidManifest(t *testing.T) {
testServer := httptest.NewServer(&fakeHandler) testServer := httptest.NewServer(&fakeHandler)
defer testServer.Close() defer testServer.Close()
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceURL{testServer.URL, ch, nil} c := sourceURL{testServer.URL, "localhost", ch, nil}
if err := c.extractFromURL(); err == nil { if err := c.extractFromURL(); err == nil {
t.Errorf("%s: Expected error", testCase.desc) t.Errorf("%s: Expected error", testCase.desc)
} }
...@@ -119,8 +117,7 @@ func TestExtractInvalidManifest(t *testing.T) { ...@@ -119,8 +117,7 @@ func TestExtractInvalidManifest(t *testing.T) {
} }
func TestExtractManifestFromHTTP(t *testing.T) { func TestExtractManifestFromHTTP(t *testing.T) {
hostname, _ := os.Hostname() hostname := "random-hostname"
hostname = strings.ToLower(hostname)
var testCases = []struct { var testCases = []struct {
desc string desc string
...@@ -263,7 +260,7 @@ func TestExtractManifestFromHTTP(t *testing.T) { ...@@ -263,7 +260,7 @@ func TestExtractManifestFromHTTP(t *testing.T) {
testServer := httptest.NewServer(&fakeHandler) testServer := httptest.NewServer(&fakeHandler)
defer testServer.Close() defer testServer.Close()
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceURL{testServer.URL, ch, nil} c := sourceURL{testServer.URL, hostname, ch, nil}
if err := c.extractFromURL(); err != nil { if err := c.extractFromURL(); err != nil {
t.Errorf("%s: Unexpected error: %v", testCase.desc, err) t.Errorf("%s: Unexpected error: %v", testCase.desc, err)
continue continue
...@@ -290,8 +287,7 @@ func TestExtractManifestFromHTTP(t *testing.T) { ...@@ -290,8 +287,7 @@ func TestExtractManifestFromHTTP(t *testing.T) {
} }
func TestExtractPodsFromHTTP(t *testing.T) { func TestExtractPodsFromHTTP(t *testing.T) {
hostname, _ := os.Hostname() hostname := "different-value"
hostname = strings.ToLower(hostname)
var testCases = []struct { var testCases = []struct {
desc string desc string
...@@ -454,7 +450,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { ...@@ -454,7 +450,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
testServer := httptest.NewServer(&fakeHandler) testServer := httptest.NewServer(&fakeHandler)
defer testServer.Close() defer testServer.Close()
ch := make(chan interface{}, 1) ch := make(chan interface{}, 1)
c := sourceURL{testServer.URL, ch, nil} c := sourceURL{testServer.URL, hostname, ch, nil}
if err := c.extractFromURL(); err != nil { if err := c.extractFromURL(); err != nil {
t.Errorf("%s: Unexpected error: %v", testCase.desc, err) t.Errorf("%s: Unexpected error: %v", testCase.desc, err)
continue continue
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment