From 3cc25541d1458bb9910094592e774cd2b260691d Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Wed, 29 Apr 2015 11:37:19 -0700 Subject: [PATCH 1/4] Fix YAML parsing for v1beta3 objects in the kubelet for file/http --- pkg/kubelet/config/common.go | 14 ++- pkg/kubelet/config/common_test.go | 156 ++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 pkg/kubelet/config/common_test.go diff --git a/pkg/kubelet/config/common.go b/pkg/kubelet/config/common.go index 401af5d65e..cb07511878 100644 --- a/pkg/kubelet/config/common.go +++ b/pkg/kubelet/config/common.go @@ -30,6 +30,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + utilyaml "github.com/GoogleCloudPlatform/kubernetes/pkg/util/yaml" "github.com/ghodss/yaml" "github.com/golang/glog" @@ -98,7 +99,12 @@ func getSelfLink(name, namespace string) string { 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) + // JSON is valid YAML, so this should work for everything. + json, err := utilyaml.ToJSON(data) + if err != nil { + return false, nil, err + } + obj, err := api.Scheme.Decode(json) if err != nil { return false, pod, err } @@ -120,7 +126,11 @@ func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *a } func tryDecodePodList(data []byte, defaultFn defaultFunc) (parsed bool, pods api.PodList, err error) { - obj, err := api.Scheme.Decode(data) + json, err := utilyaml.ToJSON(data) + if err != nil { + return false, api.PodList{}, err + } + obj, err := api.Scheme.Decode(json) if err != nil { return false, pods, err } diff --git a/pkg/kubelet/config/common_test.go b/pkg/kubelet/config/common_test.go new file mode 100644 index 0000000000..9f8d4da466 --- /dev/null +++ b/pkg/kubelet/config/common_test.go @@ -0,0 +1,156 @@ +/* +Copyright 2014 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 config + +import ( + "reflect" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + + "github.com/ghodss/yaml" +) + +func noDefault(*api.Pod) error { return nil } + +func TestDecodeSinglePod(t *testing.T) { + pod := &api.Pod{ + TypeMeta: api.TypeMeta{ + APIVersion: "", + }, + ObjectMeta: api.ObjectMeta{ + Name: "test", + UID: "12345", + Namespace: "mynamespace", + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{ + Name: "image", + Image: "test/image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePath: "/dev/termination-log", + }}, + }, + } + json, err := testapi.Codec().Encode(pod) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + parsed, podOut, err := tryDecodeSinglePod(json, noDefault) + if testapi.Version() == "v1beta1" { + // v1beta1 conversion leaves empty lists that should be nil + podOut.Spec.Containers[0].Resources.Limits = nil + podOut.Spec.Containers[0].Resources.Requests = nil + } + if !parsed { + t.Errorf("expected to have parsed file: (%s)", string(json)) + } + if err != nil { + t.Errorf("unexpected error: %v (%s)", err, string(json)) + } + if !reflect.DeepEqual(pod, podOut) { + t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json)) + } + + externalPod, err := testapi.Converter().ConvertToVersion(pod, "v1beta3") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + yaml, err := yaml.Marshal(externalPod) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + parsed, podOut, err = tryDecodeSinglePod(yaml, noDefault) + if !parsed { + t.Errorf("expected to have parsed file: (%s)", string(yaml)) + } + if err != nil { + t.Errorf("unexpected error: %v (%s)", err, string(yaml)) + } + if !reflect.DeepEqual(pod, podOut) { + t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(yaml)) + } +} + +func TestDecodePodList(t *testing.T) { + pod := &api.Pod{ + TypeMeta: api.TypeMeta{ + APIVersion: "", + }, + ObjectMeta: api.ObjectMeta{ + Name: "test", + UID: "12345", + Namespace: "mynamespace", + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{ + Name: "image", + Image: "test/image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePath: "/dev/termination-log", + }}, + }, + } + podList := &api.PodList{ + Items: []api.Pod{*pod}, + } + json, err := testapi.Codec().Encode(podList) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + parsed, podListOut, err := tryDecodePodList(json, noDefault) + if testapi.Version() == "v1beta1" { + // v1beta1 conversion leaves empty lists that should be nil + podListOut.Items[0].Spec.Containers[0].Resources.Limits = nil + podListOut.Items[0].Spec.Containers[0].Resources.Requests = nil + } + if !parsed { + t.Errorf("expected to have parsed file: (%s)", string(json)) + } + if err != nil { + t.Errorf("unexpected error: %v (%s)", err, string(json)) + } + if !reflect.DeepEqual(podList, &podListOut) { + t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", podList, &podListOut, string(json)) + } + + externalPodList, err := testapi.Converter().ConvertToVersion(podList, "v1beta3") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + yaml, err := yaml.Marshal(externalPodList) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + parsed, podListOut, err = tryDecodePodList(yaml, noDefault) + if !parsed { + t.Errorf("expected to have parsed file: (%s)", string(yaml)) + } + if err != nil { + t.Errorf("unexpected error: %v (%s)", err, string(yaml)) + } + if !reflect.DeepEqual(podList, &podListOut) { + t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, &podListOut, string(yaml)) + } +} From d52a5b22f3542a8d1827302a5a65c84f73c85732 Mon Sep 17 00:00:00 2001 From: Robert Bailey Date: Fri, 1 May 2015 13:51:59 -0700 Subject: [PATCH 2/4] Don't exit abruptly if there aren't yet any minions right after the cluster is created. --- cluster/validate-cluster.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster/validate-cluster.sh b/cluster/validate-cluster.sh index a3affc8606..81d75ef8d0 100755 --- a/cluster/validate-cluster.sh +++ b/cluster/validate-cluster.sh @@ -31,7 +31,7 @@ trap 'rm -rf "${MINIONS_FILE}"' EXIT attempt=0 while true; do "${KUBE_ROOT}/cluster/kubectl.sh" get nodes -o template -t $'{{range.items}}{{.metadata.name}}\n{{end}}' --api-version=v1beta3 > "${MINIONS_FILE}" - found=$(grep -c . "${MINIONS_FILE}") + found=$(grep -c . "${MINIONS_FILE}") || true if [[ ${found} == "${NUM_MINIONS}" ]]; then break else From 72a6a948403654c9943920f47bd2ebdece391594 Mon Sep 17 00:00:00 2001 From: Zach Loafman Date: Mon, 4 May 2015 10:42:44 -0700 Subject: [PATCH 3/4] Kubernetes version v0.16.2 --- pkg/version/base.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/version/base.go b/pkg/version/base.go index 93d2fa6084..bf57b2f399 100644 --- a/pkg/version/base.go +++ b/pkg/version/base.go @@ -36,8 +36,8 @@ package version var ( // TODO: Deprecate gitMajor and gitMinor, use only gitVersion instead. gitMajor string = "0" // major version, always numeric - gitMinor string = "16.1+" // minor version, numeric possibly followed by "+" - gitVersion string = "v0.16.1-dev" // version from git, output of $(git describe) + gitMinor string = "16.2" // minor version, numeric possibly followed by "+" + gitVersion string = "v0.16.2" // version from git, output of $(git describe) gitCommit string = "" // sha1 from git, output of $(git rev-parse HEAD) gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty" ) From 91bc1637a117c0e24da79a4aa12db6670ae3b9e4 Mon Sep 17 00:00:00 2001 From: Zach Loafman Date: Mon, 4 May 2015 10:42:55 -0700 Subject: [PATCH 4/4] Kubernetes version v0.16.2-dev --- pkg/version/base.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/version/base.go b/pkg/version/base.go index bf57b2f399..f681bdb9e8 100644 --- a/pkg/version/base.go +++ b/pkg/version/base.go @@ -36,8 +36,8 @@ package version var ( // TODO: Deprecate gitMajor and gitMinor, use only gitVersion instead. gitMajor string = "0" // major version, always numeric - gitMinor string = "16.2" // minor version, numeric possibly followed by "+" - gitVersion string = "v0.16.2" // version from git, output of $(git describe) + gitMinor string = "16.2+" // minor version, numeric possibly followed by "+" + gitVersion string = "v0.16.2-dev" // version from git, output of $(git describe) gitCommit string = "" // sha1 from git, output of $(git rev-parse HEAD) gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty" )