Make manifest url reader accept both single and multiple manifests.

This commit is contained in:
Daniel Smith 2014-06-23 15:47:25 -07:00
parent e4c47f0219
commit 9d8a16f180
2 changed files with 76 additions and 7 deletions

View File

@ -493,14 +493,43 @@ func (kl *Kubelet) extractFromHTTP(url string, updateChannel chan<- manifestUpda
return err return err
} }
defer response.Body.Close() defer response.Body.Close()
manifest, err := kl.extractSingleFromReader(response.Body) data, err := ioutil.ReadAll(response.Body)
if err != nil { if err != nil {
return err return err
} }
if len(data) == 0 {
return fmt.Errorf("zero-length data received from %v", url)
}
// First try as if it's a single manifest
var manifest api.ContainerManifest
singleErr := yaml.Unmarshal(data, &manifest)
if singleErr == nil && manifest.Version == "" {
singleErr = fmt.Errorf("got blank version field")
}
if singleErr == nil {
updateChannel <- manifestUpdate{httpClientSource, []api.ContainerManifest{manifest}} updateChannel <- manifestUpdate{httpClientSource, []api.ContainerManifest{manifest}}
return nil return nil
} }
// That didn't work, so try an array of manifests.
var manifests []api.ContainerManifest
multiErr := yaml.Unmarshal(data, &manifests)
if multiErr == nil && len(manifests) == 0 {
multiErr = fmt.Errorf("no elements in ContainerManifest array")
}
if multiErr == nil && manifests[0].Version == "" {
multiErr = fmt.Errorf("got blank version field")
}
if multiErr == nil {
updateChannel <- manifestUpdate{httpClientSource, manifests}
return nil
}
return fmt.Errorf("%v: received '%v', but couldn't parse as a "+
"single manifest (%v: %#v) or as multiple manifests (%v: %#v).\n",
url, string(data), singleErr, manifest, multiErr, manifests)
}
// Take an etcd Response object, and turn it into a structured list of containers // Take an etcd Response object, and turn it into a structured list of containers
// Return a list of containers, or an error if one occurs. // Return a list of containers, or an error if one occurs.
func (kl *Kubelet) ResponseToManifests(response *etcd.Response) ([]api.ContainerManifest, error) { func (kl *Kubelet) ResponseToManifests(response *etcd.Response) ([]api.ContainerManifest, error) {

View File

@ -827,16 +827,16 @@ func TestExtractFromHttpBadness(t *testing.T) {
} }
} }
func TestExtractFromHttp(t *testing.T) { func TestExtractFromHttpSingle(t *testing.T) {
kubelet := Kubelet{} kubelet := Kubelet{}
updateChannel := make(chan manifestUpdate) updateChannel := make(chan manifestUpdate)
reader := startReading(updateChannel) reader := startReading(updateChannel)
manifests := []api.ContainerManifest{ manifests := []api.ContainerManifest{
{Id: "foo"}, {Version: "v1beta1", Id: "foo"},
} }
// TODO: provide a mechanism for taking arrays of // Taking a single-manifest from a URL allows kubelet to be used
// manifests or a single manifest. // in the implementation of google's container VM image.
data, err := json.Marshal(manifests[0]) data, err := json.Marshal(manifests[0])
fakeHandler := util.FakeHandler{ fakeHandler := util.FakeHandler{
@ -855,6 +855,46 @@ func TestExtractFromHttp(t *testing.T) {
if len(read) != 1 { if len(read) != 1 {
t.Errorf("Unexpected list: %#v", read) t.Errorf("Unexpected list: %#v", read)
return
}
if !reflect.DeepEqual(manifests, read[0]) {
t.Errorf("Unexpected difference. Expected: %#v, Saw: %#v", manifests, read[0])
}
}
func TestExtractFromHttpMultiple(t *testing.T) {
kubelet := Kubelet{}
updateChannel := make(chan manifestUpdate)
reader := startReading(updateChannel)
manifests := []api.ContainerManifest{
{Version: "v1beta1", Id: "foo"},
{Version: "v1beta1", Id: "bar"},
}
data, err := json.Marshal(manifests)
if err != nil {
t.Fatalf("Some weird json problem: %v", err)
}
t.Logf("Serving: %v", string(data))
fakeHandler := util.FakeHandler{
StatusCode: 200,
ResponseBody: string(data),
}
testServer := httptest.NewServer(&fakeHandler)
err = kubelet.extractFromHTTP(testServer.URL, updateChannel)
if err != nil {
t.Errorf("Unexpected error: %#v", err)
}
close(updateChannel)
read := reader.GetList()
if len(read) != 1 {
t.Errorf("Unexpected list: %#v", read)
return
} }
if !reflect.DeepEqual(manifests, read[0]) { if !reflect.DeepEqual(manifests, read[0]) {
t.Errorf("Unexpected difference. Expected: %#v, Saw: %#v", manifests, read[0]) t.Errorf("Unexpected difference. Expected: %#v, Saw: %#v", manifests, read[0])