diff --git a/hack/test-cmd.sh b/hack/test-cmd.sh index 6e8fdcf5692..a1a8743e6f7 100755 --- a/hack/test-cmd.sh +++ b/hack/test-cmd.sh @@ -77,15 +77,6 @@ APISERVER_PID=$! kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver: " -kube_cmd=( - "${KUBE_OUTPUT_HOSTBIN}/kubectl" -) - -kube_flags=( - -s "http://127.0.0.1:${API_PORT}" - --match-server-version -) - # Start controller manager kube::log::status "Starting CONTROLLER-MANAGER" "${KUBE_OUTPUT_HOSTBIN}/kube-controller-manager" \ @@ -95,45 +86,56 @@ CTLRMGR_PID=$! kube::util::wait_for_url "http://127.0.0.1:${CTLRMGR_PORT}/healthz" "controller-manager: " -kube::log::status "Testing kubectl(pods)" -"${kube_cmd[@]}" get pods "${kube_flags[@]}" -"${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}" -"${kube_cmd[@]}" get pods "${kube_flags[@]}" -"${kube_cmd[@]}" get pod redis-master "${kube_flags[@]}" -[[ "$("${kube_cmd[@]}" get pod redis-master -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master" ]] -output_pod=$("${kube_cmd[@]}" get pod redis-master -o json --output-version=v1beta1 "${kube_flags[@]}") -"${kube_cmd[@]}" delete pod redis-master "${kube_flags[@]}" -[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}") -eq 0 ]] -echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}" -[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}") -eq 1 ]] -"${kube_cmd[@]}" get pods -o yaml "${kube_flags[@]}" | grep -q "id: redis-master" -"${kube_cmd[@]}" describe pod redis-master "${kube_flags[@]}" | grep -q 'Name:.*redis-master' -"${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}" +kube_cmd=( + "${KUBE_OUTPUT_HOSTBIN}/kubectl" +) +kube_api_versions=( + v1beta1 + v1beta2 +) +for version in "${kube_api_versions[@]}"; do + kube_flags=( + -s "http://127.0.0.1:${API_PORT}" + --match-server-version + --api-version="${version}" + ) -kube::log::status "Testing kubectl(services)" -"${kube_cmd[@]}" get services "${kube_flags[@]}" -"${kube_cmd[@]}" create -f examples/guestbook/frontend-service.json "${kube_flags[@]}" -"${kube_cmd[@]}" get services "${kube_flags[@]}" -"${kube_cmd[@]}" delete service frontend "${kube_flags[@]}" + kube::log::status "Testing kubectl(pods)" + "${kube_cmd[@]}" get pods "${kube_flags[@]}" + "${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}" + "${kube_cmd[@]}" get pods "${kube_flags[@]}" + "${kube_cmd[@]}" get pod redis-master "${kube_flags[@]}" + [[ "$("${kube_cmd[@]}" get pod redis-master -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master" ]] + output_pod=$("${kube_cmd[@]}" get pod redis-master -o json --output-version=v1beta1 "${kube_flags[@]}") + "${kube_cmd[@]}" delete pod redis-master "${kube_flags[@]}" + before="$("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}")" + echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}" + after="$("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}")" + [[ "$((${after} - ${before}))" -eq 1 ]] + "${kube_cmd[@]}" get pods -o yaml "${kube_flags[@]}" | grep -q "id: redis-master" + "${kube_cmd[@]}" describe pod redis-master "${kube_flags[@]}" | grep -q 'Name:.*redis-master' + "${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}" -kube::log::status "Testing kubectl(replicationcontrollers)" -"${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}" -"${kube_cmd[@]}" create -f examples/guestbook/frontend-controller.json "${kube_flags[@]}" -"${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}" -"${kube_cmd[@]}" describe replicationcontroller frontendController "${kube_flags[@]}" | grep -q 'Replicas:.*3 desired' + kube::log::status "Testing kubectl(services)" + "${kube_cmd[@]}" get services "${kube_flags[@]}" + "${kube_cmd[@]}" create -f examples/guestbook/frontend-service.json "${kube_flags[@]}" + "${kube_cmd[@]}" get services "${kube_flags[@]}" + "${kube_cmd[@]}" delete service frontend "${kube_flags[@]}" -kube::log::status "Testing kubectl(minions)" -"${kube_cmd[@]}" get minions "${kube_flags[@]}" -"${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}" + kube::log::status "Testing kubectl(replicationcontrollers)" + "${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}" + "${kube_cmd[@]}" create -f examples/guestbook/frontend-controller.json "${kube_flags[@]}" + "${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}" + "${kube_cmd[@]}" describe replicationcontroller frontendController "${kube_flags[@]}" | grep -q 'Replicas:.*3 desired' + "${kube_cmd[@]}" delete rc frontendController "${kube_flags[@]}" -kube::log::status "Testing kubectl(nodes)" -"${kube_cmd[@]}" get nodes "${kube_flags[@]}" -"${kube_cmd[@]}" describe nodes 127.0.0.1 "${kube_flags[@]}" + kube::log::status "Testing kubectl(minions)" + "${kube_cmd[@]}" get minions "${kube_flags[@]}" + "${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}" + + kube::log::status "Testing kubectl(nodes)" + "${kube_cmd[@]}" get nodes "${kube_flags[@]}" + "${kube_cmd[@]}" describe nodes 127.0.0.1 "${kube_flags[@]}" +done kube::log::status "TEST PASSED" - -# Start proxy -#PROXY_LOG=/tmp/kube-proxy.log -#${KUBE_OUTPUT_HOSTBIN}/kube-proxy \ -# --etcd_servers="http://127.0.0.1:${ETCD_PORT}" 1>&2 & -#PROXY_PID=$! diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index cf4738941b7..bb61e648d3a 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -19,6 +19,7 @@ package apiserver import ( "bytes" "encoding/json" + "fmt" "io/ioutil" "net/http" "path" @@ -283,16 +284,14 @@ func APIVersionHandler(versions ...string) restful.RouteFunction { func writeJSON(statusCode int, codec runtime.Codec, object runtime.Object, w http.ResponseWriter) { output, err := codec.Encode(object) if err != nil { - // Note: If codec is broken, this results in an infinite recursion - errorJSON(err, codec, w) + errorJSONFatal(err, codec, w) return } // PR #2243: Pretty-print JSON by default. formatted := &bytes.Buffer{} err = json.Indent(formatted, output, "", " ") if err != nil { - // Note: If codec is broken, this results in an infinite recursion - errorJSON(err, codec, w) + errorJSONFatal(err, codec, w) return } w.Header().Set("Content-Type", "application/json") @@ -306,6 +305,20 @@ func errorJSON(err error, codec runtime.Codec, w http.ResponseWriter) { writeJSON(status.Code, codec, status, w) } +// errorJSONFatal renders an error to the response, and if codec fails will render plaintext +func errorJSONFatal(err error, codec runtime.Codec, w http.ResponseWriter) { + status := errToAPIStatus(err) + output, err := codec.Encode(status) + if err != nil { + w.WriteHeader(status.Code) + fmt.Fprintf(w, "%s: %s", status.Reason, status.Message) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status.Code) + w.Write(output) +} + // writeRawJSON writes a non-API object in JSON. func writeRawJSON(statusCode int, object interface{}, w http.ResponseWriter) { // PR #2243: Pretty-print JSON by default. diff --git a/pkg/util/list.go b/pkg/util/list.go index a64e0fcf34c..440a8bbba68 100644 --- a/pkg/util/list.go +++ b/pkg/util/list.go @@ -33,3 +33,7 @@ func (sl *StringList) Set(value string) error { } return nil } + +func (*StringList) Type() string { + return "stringList" +} diff --git a/pkg/util/net.go b/pkg/util/net.go index 53e3c64e366..f36b1cae3fd 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -37,6 +37,10 @@ func (ip *IP) Set(value string) error { return nil } +func (*IP) Type() string { + return "ip" +} + // IPNet adapts net.IPNet for use as a flag. type IPNet net.IPNet @@ -53,3 +57,7 @@ func (ipnet *IPNet) Set(value string) error { *ipnet = IPNet(*n) return nil } + +func (*IPNet) Type() string { + return "ipNet" +}