mirror of https://github.com/k3s-io/k3s
Adding a script to update etcd objects
parent
c4fa78509d
commit
fa9f864782
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
|
@ -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, ", "))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"}}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{},
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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{},
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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{},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
func addDefaultingFuncs() {
|
||||
api.Scheme.AddDefaultingFuncs(
|
||||
func(obj *ReplicationController) {
|
||||
var labels map[string]string
|
||||
|
|
|
@ -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{},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue