Adding a script to update etcd objects

pull/6/head
nikhiljindal 2015-05-05 16:53:22 -07:00
parent c4fa78509d
commit fa9f864782
23 changed files with 472 additions and 82 deletions

View File

@ -33,6 +33,7 @@ script:
- node_modules/karma/bin/karma start www/master/karma.conf.js --single-run --browsers PhantomJS
- PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/test-cmd.sh
- PATH=$HOME/gopath/bin:./third_party/etcd:$PATH KUBE_TEST_API_VERSIONS="${KUBE_TEST_API_VERSIONS}" KUBE_INTEGRATION_TEST_MAX_CONCURRENCY=4 LOG_LEVEL=4 ./hack/test-integration.sh
- PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/test-update-storage-objects.sh
notifications:
irc: "chat.freenode.net#google-containers"

112
cluster/update-storage-objects.sh Executable file
View File

@ -0,0 +1,112 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors 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.
# Script to update etcd objects as per the latest API Version.
# This just reads all objects and then writes them back as is to ensure that
# they are written using the latest API version.
#
# Steps to use this script to upgrade the cluster to a new version:
# https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/cluster_management.md#updgrading-to-a-different-api-version
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/hack/lib/init.sh"
KUBECTL="${KUBE_OUTPUT_HOSTBIN}/kubectl"
# List of resources to be updated.
# TODO: Get this list of resources from server once
# https://github.com/GoogleCloudPlatform/kubernetes/issues/2057 is fixed.
declare -a resources=(
"endpoints"
"events"
"limitranges"
"namespaces"
"nodes"
"pods"
"persistentvolumes"
"persistentvolumeclaims"
"replicationcontrollers"
"resourcequotas"
"secrets"
"services"
)
# Find all the namespaces.
namespaces=( $("${KUBECTL}" get namespaces -o template -t "{{range.items}}{{.metadata.name}} {{end}}"))
if [ -z "${namespaces:-}" ]
then
echo "Unexpected: No namespace found. Nothing to do."
exit 1
fi
for resource in "${resources[@]}"
do
for namespace in "${namespaces[@]}"
do
instances=( $("${KUBECTL}" get "${resource}" --namespace="${namespace}" -o template -t "{{range.items}}{{.metadata.name}} {{end}}"))
# Nothing to do if there is no instance of that resource.
if [[ -z "${instances:-}" ]]
then
continue
fi
for instance in "${instances[@]}"
do
# Read and then write it back as is.
# Update can fail if the object was updated after we fetched the
# object, but before we could update it. We, hence, try the update
# operation multiple times. But 5 continuous failures indicate some other
# problem.
success=0
for (( tries=0; tries<5; ++tries ))
do
filename="/tmp/k8s-${namespace}-${resource}-${instance}.json"
( "${KUBECTL}" get "${resource}" "${instance}" --namespace="${namespace}" -o json > "${filename}" ) || true
if [[ ! -s "${filename}" ]]
then
# This happens when the instance has been deleted. We can hence ignore
# this instance.
echo "Looks like ${instance} got deleted. Ignoring it"
continue
fi
output=$("${KUBECTL}" update -f "${filename}" --namespace="${namespace}") || true
rm "${filename}"
if [ -n "${output:-}" ]
then
success=1
break
fi
done
if [[ "${success}" -eq 0 ]]
then
echo "Error: failed to update ${resource}/${instance} in ${namespace} namespace after 5 tries"
exit 1
fi
done
if [[ "${resource}" == "namespaces" ]] || [[ "${resource}" == "nodes" ]]
then
# These resources are namespace agnostic. No need to update them for every
# namespace.
break
fi
done
done
echo "All objects updated successfully!!"
exit 0

View File

@ -178,7 +178,7 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged, "If true, allow privileged containers.")
fs.Var(&s.PortalNet, "portal-net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.")
fs.StringVar(&s.MasterServiceNamespace, "master-service-namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods")
fs.Var(&s.RuntimeConfig, "runtime-config", "A set of key=value pairs that describe runtime configuration that may be passed to the apiserver.")
fs.Var(&s.RuntimeConfig, "runtime-config", "A set of key=value pairs that describe runtime configuration that may be passed to the apiserver. api/<version> key can be used to turn on/off specific api versions. api/all and api/legacy are special keys to control all and legacy api versions respectively.")
client.BindKubeletClientConfigFlags(fs, &s.KubeletConfig)
fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster")
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
@ -238,19 +238,39 @@ func (s *APIServer) Run(_ []string) error {
glog.Fatalf("Failure to start kubelet client: %v", err)
}
disableV1beta3 := false
v1beta3FlagValue, ok := s.RuntimeConfig["api/v1beta3"]
if ok && v1beta3FlagValue == "false" {
disableV1beta3 = true
// "api/all=false" allows users to selectively enable specific api versions.
disableAllAPIs := false
allAPIFlagValue, ok := s.RuntimeConfig["api/all"]
if ok && allAPIFlagValue == "false" {
disableAllAPIs = true
}
_, enableV1 := s.RuntimeConfig["api/v1"]
// "api/legacy=false" allows users to disable legacy api versions.
// Right now, v1beta1 and v1beta2 are considered legacy.
disableLegacyAPIs := false
legacyAPIFlagValue, ok := s.RuntimeConfig["api/legacy"]
if ok && legacyAPIFlagValue == "false" {
disableLegacyAPIs = true
}
// "api/v1beta1={true|false} allows users to enable/disable v1beta1 API.
// This takes preference over api/all and api/legacy, if specified.
disableV1beta1 := disableAllAPIs || disableLegacyAPIs
disableV1beta1 = !s.getRuntimeConfigValue("api/v1beta1", !disableV1beta1)
// "api/v1beta2={true|false} allows users to enable/disable v1beta2 API.
// This takes preference over api/all and api/legacy, if specified.
disableV1beta2 := disableAllAPIs || disableLegacyAPIs
disableV1beta2 = !s.getRuntimeConfigValue("api/v1beta2", !disableV1beta2)
// "api/v1beta3={true|false} allows users to enable/disable v1beta3 API.
// This takes preference over api/all and api/legacy, if specified.
disableV1beta3 := disableAllAPIs
disableV1beta3 = !s.getRuntimeConfigValue("api/v1beta3", !disableV1beta3)
// V1 is disabled by default. Users can enable it using "api/v1={true}".
_, enableV1 := s.RuntimeConfig["api/v1"]
// TODO: expose same flags as client.BindClientConfigFlags but for a server
clientConfig := &client.Config{
Host: net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)),
@ -337,7 +357,8 @@ func (s *APIServer) Run(_ []string) error {
SupportsBasicAuth: len(s.BasicAuthFile) > 0,
Authorizer: authorizer,
AdmissionControl: admissionController,
DisableLegacyAPIs: disableLegacyAPIs,
DisableV1Beta1: disableV1beta1,
DisableV1Beta2: disableV1beta2,
DisableV1Beta3: disableV1beta3,
EnableV1: enableV1,
MasterServiceNamespace: s.MasterServiceNamespace,
@ -445,3 +466,18 @@ func (s *APIServer) Run(_ []string) error {
glog.Fatal(http.ListenAndServe())
return nil
}
func (s *APIServer) getRuntimeConfigValue(apiKey string, defaultValue bool) bool {
flagValue, ok := s.RuntimeConfig[apiKey]
if ok {
if flagValue == "" {
return true
}
boolValue, err := strconv.ParseBool(flagValue)
if err != nil {
glog.Fatalf("Invalid value of %s: %s", apiKey, flagValue)
}
return boolValue
}
return defaultValue
}

View File

@ -10,18 +10,20 @@ The `cluster/kube-push.sh` script will do a rudimentary update; it is a 1.0 road
There is a sequence of steps to upgrade to a new API version.
1. Turn on the new version.
1. Turn on the new api version
2. Upgrade the cluster's storage to use the new version.
3. Upgrade all config files. Identify users of the old api version endpoints.
4. Update existing objects in the storage to new version by running cluster/update-storage-objects.sh
3. Turn off the old version.
### Turn on or off an API version for your cluster
TODO: There's an apiserver flag for this.
Specific API versions can be turned on or off by passing --runtime-config=api/<version> flag while bringing up the server. For example: to turn off v1beta3 API, pass --runtime-config=api/v1beta3=false.
runtime-config also supports 2 special keys: api/all and api/legacy to control all and legacy APIs respectively. For example, for turning off all api versions except v1beta3, pass --runtime-config=api/all=false,api/v1beta3=true.
### Switching your cluster's storage API version
TODO: This functionality hasn't been written yet.
KUBE_API_VERSIONS env var controls the API versions that are supported in the cluster. The first version in the list is used as the cluster's storage version. Hence, to set a specific version as the storage version, bring it to the front of list of versions in the value of KUBE_API_VERSIONS.
### Switching your config files to a new API version

View File

@ -30,7 +30,6 @@ function cleanup()
[[ -n ${APISERVER_PID-} ]] && kill ${APISERVER_PID} 1>&2 2>/dev/null
[[ -n ${CTLRMGR_PID-} ]] && kill ${CTLRMGR_PID} 1>&2 2>/dev/null
[[ -n ${KUBELET_PID-} ]] && kill ${KUBELET_PID} 1>&2 2>/dev/null
[[ -n ${PROXY_PID-} ]] && kill ${PROXY_PID} 1>&2 2>/dev/null
kube::etcd::cleanup
rm -rf "${KUBE_TEMP}"

View File

@ -0,0 +1,127 @@
#!/bin/bash
# Copyright 2014 The Kubernetes Authors 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.
# Script to test cluster/update-storage-objects.sh works as expected.
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/hack/lib/init.sh"
# The api version in which objects are currently stored in etcd.
KUBE_OLD_API_VERSION=${KUBE_OLD_API_VERSION:-"v1beta1"}
# The api version in which our etcd objects should be converted to.
# The new api version
KUBE_NEW_API_VERSION=${KUBE_NEW_API_VERSION:-"v1beta3"}
ETCD_HOST=${ETCD_HOST:-127.0.0.1}
ETCD_PORT=${ETCD_PORT:-4001}
API_PORT=${API_PORT:-8080}
API_HOST=${API_HOST:-127.0.0.1}
KUBELET_PORT=${KUBELET_PORT:-10250}
KUBE_API_VERSIONS=""
RUNTIME_CONFIG=""
KUBECTL="${KUBE_OUTPUT_HOSTBIN}/kubectl"
UPDATE_ETCD_OBJECTS_SCRIPT="${KUBE_ROOT}/cluster/update-storage-objects.sh"
function startApiServer() {
kube::log::status "Starting kube-apiserver with KUBE_API_VERSIONS: ${KUBE_API_VERSIONS} and runtime_config: ${RUNTIME_CONFIG}"
KUBE_API_VERSIONS="${KUBE_API_VERSIONS}" \
"${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \
--address="127.0.0.1" \
--public_address_override="127.0.0.1" \
--port="${API_PORT}" \
--etcd_servers="http://${ETCD_HOST}:${ETCD_PORT}" \
--public_address_override="127.0.0.1" \
--kubelet_port=${KUBELET_PORT} \
--runtime_config="${RUNTIME_CONFIG}" \
--cert_dir="${TMPDIR:-/tmp/}" \
--portal_net="10.0.0.0/24" 1>&2 &
APISERVER_PID=$!
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver: "
}
function killApiServer() {
kube::log::status "Killing api server"
[[ -n ${APISERVER_PID-} ]] && kill ${APISERVER_PID} 1>&2 2>/dev/null
unset APISERVER_PID
}
function cleanup() {
killApiServer
kube::etcd::cleanup
kube::log::status "Clean up complete"
}
trap cleanup EXIT SIGINT
kube::etcd::start
kube::log::status "Running test for update etcd object scenario"
"${KUBE_ROOT}/hack/build-go.sh"
#######################################################
# Step 1: Start a server which supports both the old and new api versions,
# but KUBE_OLD_API_VERSION is the latest (storage) version.
#######################################################
KUBE_API_VERSIONS="${KUBE_OLD_API_VERSION},${KUBE_NEW_API_VERSION}"
RUNTIME_CONFIG="api/all=false,api/${KUBE_OLD_API_VERSION}=true,api/${KUBE_NEW_API_VERSION}=true"
startApiServer
# Create a pod
kube::log::status "Creating a pod"
${KUBECTL} create -f examples/pod.yaml
killApiServer
#######################################################
# Step 2: Start a server which supports both the old and new api versions,
# but KUBE_NEW_API_VERSION is the latest (storage) version.
#######################################################
KUBE_API_VERSIONS="${KUBE_NEW_API_VERSION},${KUBE_OLD_API_VERSION}"
RUNTIME_CONFIG="api/all=false,api/${KUBE_OLD_API_VERSION}=true,api/${KUBE_NEW_API_VERSION}=true"
startApiServer
# Update etcd objects, so that will now be stored in the new api version.
${UPDATE_ETCD_OBJECTS_SCRIPT}
killApiServer
#######################################################
# Step 3 : Start a server which supports only the new api version.
#######################################################
KUBE_API_VERSIONS="${KUBE_NEW_API_VERSION}"
RUNTIME_CONFIG="api/all=false,api/${KUBE_NEW_API_VERSION}=true"
startApiServer
# Verify that the server is able to read the object.
# This will fail if the object is in a version that is not understood by the
# master.
${KUBECTL} get pods

View File

@ -18,19 +18,17 @@ package latest
import (
"fmt"
"os"
"sort"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
)
// Version is the string that represents the current external default version.
@ -68,63 +66,14 @@ var RESTMapper meta.RESTMapper
// userResources is a group of resources mostly used by a kubectl user
var userResources = []string{"rc", "svc", "pods", "pvc"}
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
// string, or an error if the version is not known.
func InterfacesFor(version string) (*meta.VersionInterfaces, error) {
switch version {
case "v1beta1":
return &meta.VersionInterfaces{
Codec: v1beta1.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
case "v1beta2":
return &meta.VersionInterfaces{
Codec: v1beta2.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
case "v1beta3":
return &meta.VersionInterfaces{
Codec: v1beta3.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
case "v1":
return &meta.VersionInterfaces{
Codec: v1.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
default:
return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", "))
}
}
func init() {
// The list of valid API versions to test that KUBE_API_VERSIONS does not contain an invalid version.
// Note that the list is in ascending sorted order.
validAPIVersions := []string{"v1", "v1beta1", "v1beta2", "v1beta3"}
// Env var KUBE_API_VERSIONS is a comma separated list of supported API versions.
// The versions should be in the order of most preferred to the least.
supportedVersions := os.Getenv("KUBE_API_VERSIONS")
if supportedVersions == "" {
supportedVersions = "v1beta3,v1beta1,v1beta2,v1"
}
versions := strings.Split(supportedVersions, ",")
// The first version in the list is the latest version.
Version = versions[0]
// Use the first API version in the list of registered versions as the latest.
Version = registered.RegisteredVersions[0]
Codec = runtime.CodecFor(api.Scheme, Version)
// Put the versions in Versions in reverse order.
// Put the registered versions in Versions in reverse order.
versions := registered.RegisteredVersions
Versions = []string{}
for i := len(versions) - 1; i >= 0; i-- {
version := versions[i]
// Verify that the version is valid.
searchIndex := sort.SearchStrings(validAPIVersions, version)
if searchIndex == len(validAPIVersions) || validAPIVersions[searchIndex] != version {
// Not a valid API version.
glog.Fatalf("invalid api version: %s in KUBE_API_VERSIONS: %s. List of valid API versions: %s", version, os.Getenv("KUBE_API_VERSIONS"), strings.Join(validAPIVersions, ", "))
}
Versions = append(Versions, versions[i])
}
@ -195,3 +144,36 @@ func init() {
}
RESTMapper = mapper
}
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
// string, or an error if the version is not known.
func InterfacesFor(version string) (*meta.VersionInterfaces, error) {
switch version {
case "v1beta1":
return &meta.VersionInterfaces{
Codec: v1beta1.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
case "v1beta2":
return &meta.VersionInterfaces{
Codec: v1beta2.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
case "v1beta3":
return &meta.VersionInterfaces{
Codec: v1beta3.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
case "v1":
return &meta.VersionInterfaces{
Codec: v1.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
default:
return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", "))
}
}

View File

@ -98,7 +98,7 @@ func TestRESTMapper(t *testing.T) {
interfaces, _ := InterfacesFor(version)
if mapping.Codec != interfaces.Codec {
t.Errorf("unexpected codec: %#v", mapping)
t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces)
}
rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}}

View File

@ -0,0 +1,68 @@
/*
Copyright 2015 The Kubernetes Authors 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 to keep track of API Versions that should be registered in api.Scheme.
package registered
import (
"os"
"strings"
"github.com/golang/glog"
)
// List of registered API versions.
// The list is in the order of most preferred to the least.
var RegisteredVersions []string
func init() {
validAPIVersions := map[string]bool{
"v1": true,
"v1beta1": true,
"v1beta2": true,
"v1beta3": true,
}
// The default list of supported api versions, in order of most preferred to the least.
defaultSupportedVersions := "v1beta3,v1beta1,v1beta2,v1"
// Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme.
// The versions should be in the order of most preferred to the least.
supportedVersions := os.Getenv("KUBE_API_VERSIONS")
if supportedVersions == "" {
supportedVersions = defaultSupportedVersions
}
versions := strings.Split(supportedVersions, ",")
for _, version := range versions {
// Verify that the version is valid.
valid, ok := validAPIVersions[version]
if !ok || !valid {
// Not a valid API version.
glog.Fatalf("invalid api version: %s in KUBE_API_VERSIONS: %s. List of valid API versions: %v",
version, os.Getenv("KUBE_API_VERSIONS"), validAPIVersions)
}
RegisteredVersions = append(RegisteredVersions, version)
}
}
// Returns true if the given api version is one of the registered api versions.
func IsRegisteredAPIVersion(version string) bool {
for _, apiVersion := range RegisteredVersions {
if apiVersion == version {
return true
}
}
return false
}

View File

@ -24,7 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)
func init() {
func addConversionFuncs() {
err := newer.Scheme.AddConversionFuncs(
convert_v1_Container_To_api_Container,
convert_api_Container_To_v1_Container,

View File

@ -25,7 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func init() {
func addDefaultingFuncs() {
api.Scheme.AddDefaultingFuncs(
func(obj *ReplicationController) {
var labels map[string]string

View File

@ -18,6 +18,7 @@ package v1
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
@ -25,6 +26,19 @@ import (
var Codec = runtime.CodecFor(api.Scheme, "v1")
func init() {
// Check if v1 is in the list of supported API versions.
if !registered.IsRegisteredAPIVersion("v1") {
return
}
// Register the API.
addKnownTypes()
addConversionFuncs()
addDefaultingFuncs()
}
// Adds the list of known types to api.Scheme.
func addKnownTypes() {
api.Scheme.AddKnownTypes("v1",
&Pod{},
&PodList{},

View File

@ -28,7 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func init() {
func addConversionFuncs() {
// Our TypeMeta was split into two different structs.
newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.TypeMeta{}, "TypeMeta")
newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.ObjectMeta{}, "ObjectMeta")

View File

@ -26,7 +26,7 @@ import (
"github.com/golang/glog"
)
func init() {
func addDefaultingFuncs() {
api.Scheme.AddDefaultingFuncs(
func(obj *ReplicationController) {
if len(obj.DesiredState.ReplicaSelector) == 0 {

View File

@ -18,6 +18,7 @@ package v1beta1
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
@ -31,6 +32,19 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta1")
const Dependency = true
func init() {
// Check if v1beta1 is in the list of supported API versions.
if !registered.IsRegisteredAPIVersion("v1beta1") {
return
}
// Register the API.
addKnownTypes()
addConversionFuncs()
addDefaultingFuncs()
}
// Adds the list of known types to api.Scheme.
func addKnownTypes() {
api.Scheme.AddKnownTypes("v1beta1",
&Pod{},
&PodStatusResult{},

View File

@ -28,7 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
func init() {
func addConversionFuncs() {
// Our TypeMeta was split into two different structs.
newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.TypeMeta{}, "TypeMeta")
newer.Scheme.AddStructFieldConversion(TypeMeta{}, "TypeMeta", newer.ObjectMeta{}, "ObjectMeta")

View File

@ -26,7 +26,7 @@ import (
"github.com/golang/glog"
)
func init() {
func addDefaultingFuncs() {
api.Scheme.AddDefaultingFuncs(
func(obj *ReplicationController) {
if len(obj.DesiredState.ReplicaSelector) == 0 {

View File

@ -18,6 +18,7 @@ package v1beta2
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
@ -31,6 +32,19 @@ var Codec = runtime.CodecFor(api.Scheme, "v1beta2")
const Dependency = true
func init() {
// Check if v1beta2 is in the list of supported API versions.
if !registered.IsRegisteredAPIVersion("v1beta2") {
return
}
// Register the API.
addKnownTypes()
addConversionFuncs()
addDefaultingFuncs()
}
// Adds the list of known types to api.Scheme.
func addKnownTypes() {
api.Scheme.AddKnownTypes("v1beta2",
&Pod{},
&PodStatusResult{},

View File

@ -24,7 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)
func init() {
func addConversionFuncs() {
// Add non-generated conversion functions
err := newer.Scheme.AddConversionFuncs(
convert_v1beta3_Container_To_api_Container,

View File

@ -24,7 +24,7 @@ import (
"github.com/golang/glog"
)
func init() {
func addDefaultingFuncs() {
api.Scheme.AddDefaultingFuncs(
func(obj *ReplicationController) {
var labels map[string]string

View File

@ -18,6 +18,7 @@ package v1beta3
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/registered"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
@ -25,6 +26,19 @@ import (
var Codec = runtime.CodecFor(api.Scheme, "v1beta3")
func init() {
// Check if v1beta3 is in the list of supported API versions.
if !registered.IsRegisteredAPIVersion("v1beta3") {
return
}
// Register the API.
addKnownTypes()
addConversionFuncs()
addDefaultingFuncs()
}
// Adds the list of known types to api.Scheme.
func addKnownTypes() {
api.Scheme.AddKnownTypes("v1beta3",
&Pod{},
&PodList{},

View File

@ -92,8 +92,10 @@ type Config struct {
EnableUISupport bool
// allow downstream consumers to disable swagger
EnableSwaggerSupport bool
// allow v1beta1 and v1beta2 to be conditionally disabled
DisableLegacyAPIs bool
// allow v1beta1 to be conditionally disabled
DisableV1Beta1 bool
// allow v1beta2 to be conditionally disabled
DisableV1Beta2 bool
// allow v1beta3 to be conditionally disabled
DisableV1Beta3 bool
// allow v1 to be conditionally enabled
@ -162,7 +164,8 @@ type Master struct {
authorizer authorizer.Authorizer
admissionControl admission.Interface
masterCount int
legacyAPIs bool
v1beta1 bool
v1beta2 bool
v1beta3 bool
v1 bool
requestContextMapper api.RequestContextMapper
@ -307,7 +310,8 @@ func New(c *Config) *Master {
authenticator: c.Authenticator,
authorizer: c.Authorizer,
admissionControl: c.AdmissionControl,
legacyAPIs: !c.DisableLegacyAPIs,
v1beta1: !c.DisableV1Beta1,
v1beta2: !c.DisableV1Beta2,
v1beta3: !c.DisableV1Beta3,
v1: c.EnableV1,
requestContextMapper: c.RequestContextMapper,
@ -465,11 +469,13 @@ func (m *Master) init(c *Config) {
}
apiVersions := []string{}
if m.legacyAPIs {
if m.v1beta1 {
if err := m.api_v1beta1().InstallREST(m.handlerContainer); err != nil {
glog.Fatalf("Unable to setup API v1beta1: %v", err)
}
apiVersions = append(apiVersions, "v1beta1")
}
if m.v1beta2 {
if err := m.api_v1beta2().InstallREST(m.handlerContainer); err != nil {
glog.Fatalf("Unable to setup API v1beta2: %v", err)
}

View File

@ -36,6 +36,7 @@ script:
- KUBE_RACE="-race" KUBE_COVER="y" KUBE_GOVERALLS_BIN="$HOME/gopath/bin/goveralls" KUBE_TIMEOUT='-timeout 300s' KUBE_COVERPROCS=8 KUBE_TEST_ETCD_PREFIXES="${KUBE_TEST_ETCD_PREFIXES}" KUBE_TEST_API_VERSIONS="${KUBE_TEST_API_VERSIONS}" ./hack/test-go.sh -- -p=2
- PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/test-cmd.sh
- PATH=$HOME/gopath/bin:./third_party/etcd:$PATH KUBE_TEST_API_VERSIONS="${KUBE_TEST_API_VERSIONS}" KUBE_INTEGRATION_TEST_MAX_CONCURRENCY=4 LOG_LEVEL=4 ./hack/test-integration.sh
- PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/test-update-storage-objects.sh
notifications:
irc: "chat.freenode.net#google-containers"