From 9d8a16f1806c4e2cfc011496c946987ed82070c8 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Mon, 23 Jun 2014 15:47:25 -0700 Subject: [PATCH] Make manifest url reader accept both single and multiple manifests. --- pkg/kubelet/kubelet.go | 35 ++++++++++++++++++++++++--- pkg/kubelet/kubelet_test.go | 48 +++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 617269f3c8f..4367c57d0dc 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -493,12 +493,41 @@ func (kl *Kubelet) extractFromHTTP(url string, updateChannel chan<- manifestUpda return err } defer response.Body.Close() - manifest, err := kl.extractSingleFromReader(response.Body) + data, err := ioutil.ReadAll(response.Body) if err != nil { return err } - updateChannel <- manifestUpdate{httpClientSource, []api.ContainerManifest{manifest}} - return nil + 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}} + 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 diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 6bc76651fcd..46edd1ee408 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -827,16 +827,16 @@ func TestExtractFromHttpBadness(t *testing.T) { } } -func TestExtractFromHttp(t *testing.T) { +func TestExtractFromHttpSingle(t *testing.T) { kubelet := Kubelet{} updateChannel := make(chan manifestUpdate) reader := startReading(updateChannel) manifests := []api.ContainerManifest{ - {Id: "foo"}, + {Version: "v1beta1", Id: "foo"}, } - // TODO: provide a mechanism for taking arrays of - // manifests or a single manifest. + // Taking a single-manifest from a URL allows kubelet to be used + // in the implementation of google's container VM image. data, err := json.Marshal(manifests[0]) fakeHandler := util.FakeHandler{ @@ -855,6 +855,46 @@ func TestExtractFromHttp(t *testing.T) { if len(read) != 1 { 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]) { t.Errorf("Unexpected difference. Expected: %#v, Saw: %#v", manifests, read[0])