mirror of https://github.com/k3s-io/k3s
Revert "Merge pull request #51008 from kubernetes/revert-50789-fix-scheme"
This reverts commitpull/6/headf4afdecef8
, reversing changes made toe633a1604f
. This also fixes a bug where Kubemark was still using the core api scheme to manipulate the Kubelet's types, which was the cause of the initial revert.
parent
b2b079b95a
commit
a90d81620b
|
@ -41,6 +41,7 @@ go_library(
|
|||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubelet:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/cadvisor:go_default_library",
|
||||
"//pkg/kubelet/certificate:go_default_library",
|
||||
|
|
|
@ -12,11 +12,10 @@ go_library(
|
|||
"options.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/install:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/validation:go_default_library",
|
||||
"//pkg/util/taints:go_default_library",
|
||||
|
|
|
@ -25,14 +25,12 @@ import (
|
|||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletconfigvalidation "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation"
|
||||
// Need to make sure the kubeletconfig api is installed so defaulting funcs work
|
||||
_ "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/install"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
kubeletconfigvalidation "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation"
|
||||
utiltaints "k8s.io/kubernetes/pkg/util/taints"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -142,10 +140,14 @@ func ValidateKubeletFlags(f *KubeletFlags) error {
|
|||
|
||||
// NewKubeletConfiguration will create a new KubeletConfiguration with default values
|
||||
func NewKubeletConfiguration() (*kubeletconfig.KubeletConfiguration, error) {
|
||||
scheme, _, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
versioned := &v1alpha1.KubeletConfiguration{}
|
||||
api.Scheme.Default(versioned)
|
||||
scheme.Default(versioned)
|
||||
config := &kubeletconfig.KubeletConfiguration{}
|
||||
if err := api.Scheme.Convert(versioned, config, nil); err != nil {
|
||||
if err := scheme.Convert(versioned, config, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return config, nil
|
||||
|
|
|
@ -60,6 +60,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet"
|
||||
kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
kubeletconfigv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
|
||||
"k8s.io/kubernetes/pkg/kubelet/certificate"
|
||||
|
@ -188,20 +189,30 @@ func checkPermissions() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func setConfigz(cz *configz.Config, kc *kubeletconfiginternal.KubeletConfiguration) {
|
||||
tmp := kubeletconfigv1alpha1.KubeletConfiguration{}
|
||||
api.Scheme.Convert(kc, &tmp, nil)
|
||||
cz.Set(tmp)
|
||||
func setConfigz(cz *configz.Config, kc *kubeletconfiginternal.KubeletConfiguration) error {
|
||||
scheme, _, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
versioned := kubeletconfigv1alpha1.KubeletConfiguration{}
|
||||
if err := scheme.Convert(kc, &versioned, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
cz.Set(versioned)
|
||||
return nil
|
||||
}
|
||||
|
||||
func initConfigz(kc *kubeletconfiginternal.KubeletConfiguration) (*configz.Config, error) {
|
||||
func initConfigz(kc *kubeletconfiginternal.KubeletConfiguration) error {
|
||||
cz, err := configz.New("kubeletconfig")
|
||||
if err == nil {
|
||||
setConfigz(cz, kc)
|
||||
} else {
|
||||
if err != nil {
|
||||
glog.Errorf("unable to register configz: %s", err)
|
||||
return err
|
||||
}
|
||||
return cz, err
|
||||
if err := setConfigz(cz, kc); err != nil {
|
||||
glog.Errorf("unable to register config: %s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeEventRecorder sets up kubeDeps.Recorder if its nil. Its a no-op otherwise.
|
||||
|
@ -250,7 +261,7 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies) (err error) {
|
|||
}
|
||||
|
||||
// Register current configuration with /configz endpoint
|
||||
_, err = initConfigz(&s.KubeletConfiguration)
|
||||
err = initConfigz(&s.KubeletConfiguration)
|
||||
if err != nil {
|
||||
glog.Errorf("unable to register KubeletConfiguration with configz, error: %v", err)
|
||||
}
|
||||
|
@ -756,7 +767,8 @@ func parseResourceList(m kubeletconfiginternal.ConfigurationMap) (v1.ResourceLis
|
|||
}
|
||||
|
||||
// BootstrapKubeletConfigController constructs and bootstrap a configuration controller
|
||||
func BootstrapKubeletConfigController(flags *options.KubeletFlags,
|
||||
func BootstrapKubeletConfigController(
|
||||
flags *options.KubeletFlags,
|
||||
defaultConfig *kubeletconfiginternal.KubeletConfiguration) (*kubeletconfiginternal.KubeletConfiguration, *kubeletconfig.Controller, error) {
|
||||
var err error
|
||||
// Alpha Dynamic Configuration Implementation; this section only loads config from disk, it does not contact the API server
|
||||
|
@ -777,7 +789,10 @@ func BootstrapKubeletConfigController(flags *options.KubeletFlags,
|
|||
}
|
||||
|
||||
// get the latest KubeletConfiguration checkpoint from disk, or load the init or default config if no valid checkpoints exist
|
||||
kubeletConfigController := kubeletconfig.NewController(initConfigDir, dynamicConfigDir, defaultConfig)
|
||||
kubeletConfigController, err := kubeletconfig.NewController(initConfigDir, dynamicConfigDir, defaultConfig)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to construct controller, error: %v", err)
|
||||
}
|
||||
kubeletConfig, err := kubeletConfigController.Bootstrap()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to determine a valid configuration, error: %v", err)
|
||||
|
|
|
@ -89,7 +89,10 @@ func main() {
|
|||
}
|
||||
|
||||
// construct a KubeletServer from kubeletFlags and kubeletConfig
|
||||
kubeletServer := &options.KubeletServer{KubeletFlags: *kubeletFlags, KubeletConfiguration: *kubeletConfig}
|
||||
kubeletServer := &options.KubeletServer{
|
||||
KubeletFlags: *kubeletFlags,
|
||||
KubeletConfiguration: *kubeletConfig,
|
||||
}
|
||||
|
||||
// use kubeletServer to construct the default KubeletDeps
|
||||
kubeletDeps, err := app.UnsecuredDependencies(kubeletServer)
|
||||
|
|
|
@ -208,7 +208,6 @@ func TestRoundTripTypes(t *testing.T) {
|
|||
fuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs)
|
||||
|
||||
nonRoundTrippableTypes := map[schema.GroupVersionKind]bool{
|
||||
{Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeletConfiguration"}: true,
|
||||
{Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeProxyConfiguration"}: true,
|
||||
{Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeSchedulerConfiguration"}: true,
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ filegroup(
|
|||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubelet/apis/kubeletconfig/install:all-srcs",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:all-srcs",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:all-srcs",
|
||||
"//pkg/kubelet/apis/kubeletconfig/validation:all-srcs",
|
||||
],
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 install installs the experimental API group, making it available as
|
||||
// an option to all of the API encoding/decoding machinery.
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO(mtaufen): probably want to create a kubelet scheme rather than reusing the api scheme, but need to ask lavalamp
|
||||
Install(api.GroupFactoryRegistry, api.Registry, api.Scheme)
|
||||
}
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
|
||||
if err := announced.NewGroupMetaFactory(
|
||||
&announced.GroupMetaFactoryArgs{
|
||||
GroupName: kubeletconfig.GroupName,
|
||||
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
|
||||
AddInternalObjectsToScheme: kubeletconfig.AddToScheme,
|
||||
},
|
||||
announced.VersionToSchemeFunc{
|
||||
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
|
||||
},
|
||||
).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -1,23 +1,14 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["install.go"],
|
||||
tags = ["automanaged"],
|
||||
srcs = ["scheme.go"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -32,4 +23,5 @@ filegroup(
|
|||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
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 scheme
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
)
|
||||
|
||||
// Utility functions for the Kubelet's kubeletconfig API group
|
||||
|
||||
// NewSchemeAndCodecs is a utility funciton that returns a Scheme and CodecFactory
|
||||
// that understand the types in the kubeletconfig API group.
|
||||
func NewSchemeAndCodecs() (*runtime.Scheme, *serializer.CodecFactory, error) {
|
||||
scheme := runtime.NewScheme()
|
||||
if err := kubeletconfig.AddToScheme(scheme); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := v1alpha1.AddToScheme(scheme); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
return scheme, &codecs, nil
|
||||
}
|
|
@ -15,8 +15,8 @@ go_test(
|
|||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/kubeletconfig/util/codec:go_default_library",
|
||||
"//pkg/kubelet/kubeletconfig/util/test:go_default_library",
|
||||
|
@ -40,12 +40,14 @@ go_library(
|
|||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/kubeletconfig/util/codec:go_default_library",
|
||||
"//pkg/kubelet/kubeletconfig/util/log:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
type Checkpoint interface {
|
||||
// UID returns the UID of the config source object behind the Checkpoint
|
||||
UID() string
|
||||
// Parse parses the checkpoint into the internal KubeletConfiguration type
|
||||
// Parse extracts the KubeletConfiguration from the checkpoint, applies defaults, and converts to the internal type
|
||||
Parse() (*kubeletconfig.KubeletConfiguration, error)
|
||||
// Encode returns a []byte representation of the config source object behind the Checkpoint
|
||||
Encode() ([]byte, error)
|
||||
|
@ -56,6 +56,7 @@ func DecodeCheckpoint(data []byte) (Checkpoint, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert decoded object into a v1 ConfigMap, error: %v", err)
|
||||
}
|
||||
|
||||
return NewConfigMapCheckpoint(cm)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,20 +30,6 @@ import (
|
|||
utiltest "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/test"
|
||||
)
|
||||
|
||||
// newUnsupportedEncoded returns an encoding of an object that does not have a Checkpoint implementation
|
||||
func newUnsupportedEncoded(t *testing.T) []byte {
|
||||
encoder, err := utilcodec.NewJSONEncoder(apiv1.GroupName)
|
||||
if err != nil {
|
||||
t.Fatalf("could not create an encoder, error: %v", err)
|
||||
}
|
||||
unsupported := &apiv1.Node{}
|
||||
data, err := runtime.Encode(encoder, unsupported)
|
||||
if err != nil {
|
||||
t.Fatalf("could not encode object, error: %v", err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func TestDecodeCheckpoint(t *testing.T) {
|
||||
// generate correct Checkpoint for v1/ConfigMap test case
|
||||
cm, err := NewConfigMapCheckpoint(&apiv1.ConfigMap{ObjectMeta: metav1.ObjectMeta{UID: types.UID("uid")}})
|
||||
|
@ -87,3 +73,17 @@ func TestDecodeCheckpoint(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// newUnsupportedEncoded returns an encoding of an object that does not have a Checkpoint implementation
|
||||
func newUnsupportedEncoded(t *testing.T) []byte {
|
||||
encoder, err := utilcodec.NewJSONEncoder(apiv1.GroupName)
|
||||
if err != nil {
|
||||
t.Fatalf("could not create an encoder, error: %v", err)
|
||||
}
|
||||
unsupported := &apiv1.Node{}
|
||||
data, err := runtime.Encode(encoder, unsupported)
|
||||
if err != nil {
|
||||
t.Fatalf("could not encode object, error: %v", err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ import (
|
|||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
utilcodec "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/codec"
|
||||
)
|
||||
|
||||
|
@ -29,7 +31,8 @@ const configMapConfigKey = "kubelet"
|
|||
|
||||
// configMapCheckpoint implements Checkpoint, backed by a v1/ConfigMap config source object
|
||||
type configMapCheckpoint struct {
|
||||
configMap *apiv1.ConfigMap
|
||||
kubeletCodecs *serializer.CodecFactory // codecs for the KubeletConfiguration
|
||||
configMap *apiv1.ConfigMap
|
||||
}
|
||||
|
||||
// NewConfigMapCheckpoint returns a Checkpoint backed by `cm`. `cm` must be non-nil
|
||||
|
@ -40,7 +43,13 @@ func NewConfigMapCheckpoint(cm *apiv1.ConfigMap) (Checkpoint, error) {
|
|||
} else if len(cm.ObjectMeta.UID) == 0 {
|
||||
return nil, fmt.Errorf("ConfigMap must have a UID to be treated as a Checkpoint")
|
||||
}
|
||||
return &configMapCheckpoint{cm}, nil
|
||||
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &configMapCheckpoint{kubeletCodecs, cm}, nil
|
||||
}
|
||||
|
||||
// UID returns the UID of a configMapCheckpoint
|
||||
|
@ -48,25 +57,23 @@ func (c *configMapCheckpoint) UID() string {
|
|||
return string(c.configMap.UID)
|
||||
}
|
||||
|
||||
// implements Parse for v1/ConfigMap checkpoints
|
||||
// Parse extracts the KubeletConfiguration from v1/ConfigMap checkpoints, applies defaults, and converts to the internal type
|
||||
func (c *configMapCheckpoint) Parse() (*kubeletconfig.KubeletConfiguration, error) {
|
||||
const emptyCfgErr = "config was empty, but some parameters are required"
|
||||
|
||||
cm := c.configMap
|
||||
|
||||
if len(cm.Data) == 0 {
|
||||
if len(c.configMap.Data) == 0 {
|
||||
return nil, fmt.Errorf(emptyCfgErr)
|
||||
}
|
||||
|
||||
// TODO(mtaufen): Once the KubeletConfiguration type is decomposed, extend this to a key for each sub-object
|
||||
config, ok := cm.Data[configMapConfigKey]
|
||||
config, ok := c.configMap.Data[configMapConfigKey]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("key %q not found in ConfigMap", configMapConfigKey)
|
||||
} else if len(config) == 0 {
|
||||
return nil, fmt.Errorf(emptyCfgErr)
|
||||
}
|
||||
|
||||
return utilcodec.DecodeKubeletConfiguration([]byte(config))
|
||||
return utilcodec.DecodeKubeletConfiguration(c.kubeletCodecs, []byte(config))
|
||||
}
|
||||
|
||||
// Encode encodes a configMapCheckpoint
|
||||
|
|
|
@ -26,8 +26,8 @@ import (
|
|||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
kubeletconfigv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
utiltest "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/test"
|
||||
)
|
||||
|
@ -66,9 +66,15 @@ func TestNewConfigMapCheckpoint(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigMapCheckpointUID(t *testing.T) {
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
cases := []string{"", "uid", "376dfb73-56db-11e7-a01e-42010a800002"}
|
||||
for _, uidIn := range cases {
|
||||
cpt := &configMapCheckpoint{
|
||||
kubeletCodecs,
|
||||
&apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{UID: types.UID(uidIn)},
|
||||
},
|
||||
|
@ -82,11 +88,16 @@ func TestConfigMapCheckpointUID(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigMapCheckpointParse(t *testing.T) {
|
||||
kubeletScheme, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// get the built-in default configuration
|
||||
external := &kubeletconfigv1alpha1.KubeletConfiguration{}
|
||||
api.Scheme.Default(external)
|
||||
kubeletScheme.Default(external)
|
||||
defaultConfig := &kubeletconfig.KubeletConfiguration{}
|
||||
err := api.Scheme.Convert(external, defaultConfig, nil)
|
||||
err = kubeletScheme.Convert(external, defaultConfig, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -123,7 +134,7 @@ apiVersion: kubeletconfig/v1alpha1`}}, defaultConfig, ""},
|
|||
"kubelet": `{"kind":"KubeletConfiguration","apiVersion":"kubeletconfig/v1alpha1"}`}}, defaultConfig, ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
cpt := &configMapCheckpoint{c.cm}
|
||||
cpt := &configMapCheckpoint{kubeletCodecs, c.cm}
|
||||
kc, err := cpt.Parse()
|
||||
if utiltest.SkipRest(t, c.desc, err, c.err) {
|
||||
continue
|
||||
|
@ -136,6 +147,11 @@ apiVersion: kubeletconfig/v1alpha1`}}, defaultConfig, ""},
|
|||
}
|
||||
|
||||
func TestConfigMapCheckpointEncode(t *testing.T) {
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// only one case, based on output from the existing encoder, and since
|
||||
// this is hard to test (key order isn't guaranteed), we should probably
|
||||
// just stick to this test case and mostly rely on the round-trip test.
|
||||
|
@ -146,7 +162,7 @@ func TestConfigMapCheckpointEncode(t *testing.T) {
|
|||
}{
|
||||
// we expect Checkpoints to be encoded as a json representation of the underlying API object
|
||||
{"one-key",
|
||||
&configMapCheckpoint{&apiv1.ConfigMap{
|
||||
&configMapCheckpoint{kubeletCodecs, &apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "one-key"},
|
||||
Data: map[string]string{"one": ""}}},
|
||||
`{"kind":"ConfigMap","apiVersion":"v1","metadata":{"name":"one-key","creationTimestamp":null},"data":{"one":""}}
|
||||
|
@ -166,6 +182,11 @@ func TestConfigMapCheckpointEncode(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigMapCheckpointRoundTrip(t *testing.T) {
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
cpt *configMapCheckpoint
|
||||
|
@ -173,7 +194,7 @@ func TestConfigMapCheckpointRoundTrip(t *testing.T) {
|
|||
}{
|
||||
// empty data
|
||||
{"empty data",
|
||||
&configMapCheckpoint{&apiv1.ConfigMap{
|
||||
&configMapCheckpoint{kubeletCodecs, &apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "empty-data-sha256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
UID: "uid",
|
||||
|
@ -182,7 +203,7 @@ func TestConfigMapCheckpointRoundTrip(t *testing.T) {
|
|||
""},
|
||||
// two keys
|
||||
{"two keys",
|
||||
&configMapCheckpoint{&apiv1.ConfigMap{
|
||||
&configMapCheckpoint{kubeletCodecs, &apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "two-keys-sha256-2bff03d6249c8a9dc9a1436d087c124741361ccfac6615b81b67afcff5c42431",
|
||||
UID: "uid",
|
||||
|
@ -191,7 +212,7 @@ func TestConfigMapCheckpointRoundTrip(t *testing.T) {
|
|||
""},
|
||||
// missing uid
|
||||
{"missing uid",
|
||||
&configMapCheckpoint{&apiv1.ConfigMap{
|
||||
&configMapCheckpoint{kubeletCodecs, &apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "two-keys-sha256-2bff03d6249c8a9dc9a1436d087c124741361ccfac6615b81b67afcff5c42431",
|
||||
UID: "",
|
||||
|
|
|
@ -113,7 +113,6 @@ func (r *remoteConfigMap) UID() string {
|
|||
|
||||
func (r *remoteConfigMap) Download(client clientset.Interface) (Checkpoint, string, error) {
|
||||
var reason string
|
||||
|
||||
uid := string(r.source.ConfigMapRef.UID)
|
||||
|
||||
utillog.Infof("attempting to download ConfigMap with UID %q", uid)
|
||||
|
@ -131,8 +130,14 @@ func (r *remoteConfigMap) Download(client clientset.Interface) (Checkpoint, stri
|
|||
return nil, reason, fmt.Errorf(reason)
|
||||
}
|
||||
|
||||
checkpoint, err := NewConfigMapCheckpoint(cm)
|
||||
if err != nil {
|
||||
reason = fmt.Sprintf("invalid downloaded object")
|
||||
return nil, reason, fmt.Errorf("%s, error: %v", reason, err)
|
||||
}
|
||||
|
||||
utillog.Infof("successfully downloaded ConfigMap with UID %q", uid)
|
||||
return &configMapCheckpoint{cm}, "", nil
|
||||
return checkpoint, "", nil
|
||||
}
|
||||
|
||||
func (r *remoteConfigMap) Encode() ([]byte, error) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
fakeclient "k8s.io/client-go/kubernetes/fake"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
utiltest "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/test"
|
||||
)
|
||||
|
||||
|
@ -92,6 +93,11 @@ func TestRemoteConfigMapUID(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRemoteConfigMapDownload(t *testing.T) {
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
cm := &apiv1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
|
@ -118,7 +124,7 @@ func TestRemoteConfigMapDownload(t *testing.T) {
|
|||
// successful download
|
||||
{"object exists and reference is correct",
|
||||
&remoteConfigMap{&apiv1.NodeConfigSource{ConfigMapRef: &apiv1.ObjectReference{Name: "name", Namespace: "namespace", UID: "uid"}}},
|
||||
&configMapCheckpoint{cm}, ""},
|
||||
&configMapCheckpoint{kubeletCodecs, cm}, ""},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
|
|
|
@ -10,8 +10,10 @@ go_library(
|
|||
srcs = ["configfiles.go"],
|
||||
deps = [
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/kubeletconfig/util/codec:go_default_library",
|
||||
"//pkg/kubelet/kubeletconfig/util/filesystem:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@ import (
|
|||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
utilcodec "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/codec"
|
||||
utilfs "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/filesystem"
|
||||
)
|
||||
|
@ -35,16 +37,24 @@ type Loader interface {
|
|||
type fsLoader struct {
|
||||
// fs is the filesystem where the config files exist; can be mocked for testing
|
||||
fs utilfs.Filesystem
|
||||
// kubeletCodecs is the scheme used to decode config files
|
||||
kubeletCodecs *serializer.CodecFactory
|
||||
// configDir is the absolute path to the directory containing the configuration files
|
||||
configDir string
|
||||
}
|
||||
|
||||
// NewFSLoader returns a Loader that loads a KubeletConfiguration from the files in `configDir`
|
||||
func NewFSLoader(fs utilfs.Filesystem, configDir string) Loader {
|
||||
return &fsLoader{
|
||||
fs: fs,
|
||||
configDir: configDir,
|
||||
func NewFSLoader(fs utilfs.Filesystem, configDir string) (Loader, error) {
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &fsLoader{
|
||||
fs: fs,
|
||||
kubeletCodecs: kubeletCodecs,
|
||||
configDir: configDir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (loader *fsLoader) Load() (*kubeletconfig.KubeletConfiguration, error) {
|
||||
|
@ -62,5 +72,5 @@ func (loader *fsLoader) Load() (*kubeletconfig.KubeletConfiguration, error) {
|
|||
return nil, fmt.Errorf(errfmt, fmt.Errorf("config file was empty, but some parameters are required"))
|
||||
}
|
||||
|
||||
return utilcodec.DecodeKubeletConfiguration(data)
|
||||
return utilcodec.DecodeKubeletConfiguration(loader.kubeletCodecs, data)
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ const (
|
|||
// - validates configuration
|
||||
// - monitors for potential crash-loops caused by new configurations
|
||||
// - tracks the last-known-good configuration, and rolls-back to last-known-good when necessary
|
||||
// For more information, see the proposal: https://github.com/kubernetes/kubernetes/pull/29459
|
||||
// For more information, see the proposal: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/dynamic-kubelet-configuration.md
|
||||
type Controller struct {
|
||||
// dynamicConfig, if true, indicates that we should sync config from the API server
|
||||
dynamicConfig bool
|
||||
|
@ -90,12 +90,19 @@ type Controller struct {
|
|||
// If the `initConfigDir` is an empty string, skips trying to load the init config.
|
||||
// If the `dynamicConfigDir` is an empty string, skips trying to load checkpoints or download new config,
|
||||
// but will still sync the ConfigOK condition if you call StartSync with a non-nil client.
|
||||
func NewController(initConfigDir string, dynamicConfigDir string, defaultConfig *kubeletconfig.KubeletConfiguration) *Controller {
|
||||
func NewController(initConfigDir string,
|
||||
dynamicConfigDir string,
|
||||
defaultConfig *kubeletconfig.KubeletConfiguration) (*Controller, error) {
|
||||
var err error
|
||||
|
||||
fs := utilfs.DefaultFs{}
|
||||
|
||||
var initLoader configfiles.Loader
|
||||
if len(initConfigDir) > 0 {
|
||||
initLoader = configfiles.NewFSLoader(fs, initConfigDir)
|
||||
initLoader, err = configfiles.NewFSLoader(fs, initConfigDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
dynamicConfig := false
|
||||
if len(dynamicConfigDir) > 0 {
|
||||
|
@ -120,7 +127,7 @@ func NewController(initConfigDir string, dynamicConfigDir string, defaultConfig
|
|||
badConfigTracker: badconfig.NewFsTracker(fs, filepath.Join(dynamicConfigDir, badConfigTrackingDir, kubeletVersion)),
|
||||
startupTracker: startups.NewFsTracker(fs, filepath.Join(dynamicConfigDir, startupTrackingDir, kubeletVersion)),
|
||||
initLoader: initLoader,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Bootstrap attempts to return a valid KubeletConfiguration based on the configuration of the Controller,
|
||||
|
|
|
@ -12,9 +12,8 @@ go_library(
|
|||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/install:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/install:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -21,13 +21,11 @@ import (
|
|||
|
||||
// ensure the core apis are installed
|
||||
_ "k8s.io/kubernetes/pkg/api/install"
|
||||
// ensure the kubeletconfig apis are installed
|
||||
_ "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/install"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletconfigv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
)
|
||||
|
||||
// TODO(mtaufen): allow an encoder to be injected into checkpoint objects at creation time? (then we could ultimately instantiate only one encoder)
|
||||
|
@ -50,28 +48,18 @@ func NewJSONEncoder(groupName string) (runtime.Encoder, error) {
|
|||
return api.Codecs.EncoderForVersion(info.Serializer, versions[0]), nil
|
||||
}
|
||||
|
||||
// DecodeKubeletConfiguration decodes an encoded (v1alpha1) KubeletConfiguration object to the internal type
|
||||
func DecodeKubeletConfiguration(data []byte) (*kubeletconfig.KubeletConfiguration, error) {
|
||||
// decode the object, note we use the external version scheme to decode, because users provide the external version
|
||||
obj, err := runtime.Decode(api.Codecs.UniversalDecoder(kubeletconfigv1alpha1.SchemeGroupVersion), data)
|
||||
// DecodeKubeletConfiguration decodes a serialized KubeletConfiguration to the internal type
|
||||
func DecodeKubeletConfiguration(kubeletCodecs *serializer.CodecFactory, data []byte) (*kubeletconfig.KubeletConfiguration, error) {
|
||||
// the UniversalDecoder runs defaulting and returns the internal type by default
|
||||
obj, gvk, err := kubeletCodecs.UniversalDecoder().Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode, error: %v", err)
|
||||
}
|
||||
|
||||
externalKC, ok := obj.(*kubeletconfigv1alpha1.KubeletConfiguration)
|
||||
internalKC, ok := obj.(*kubeletconfig.KubeletConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to cast object to KubeletConfiguration, object: %#v", obj)
|
||||
return nil, fmt.Errorf("failed to cast object to KubeletConfiguration, unexpected type: %v", gvk)
|
||||
}
|
||||
|
||||
// TODO(mtaufen): confirm whether api.Codecs.UniversalDecoder runs the defaulting, which would make this redundant
|
||||
// run the defaulter on the decoded configuration before converting to internal type
|
||||
api.Scheme.Default(externalKC)
|
||||
|
||||
// convert to internal type
|
||||
internalKC := &kubeletconfig.KubeletConfiguration{}
|
||||
err = api.Scheme.Convert(externalKC, internalKC, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return internalKC, nil
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ go_library(
|
|||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubelet:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/cadvisor:go_default_library",
|
||||
"//pkg/kubelet/cm:go_default_library",
|
||||
"//pkg/kubelet/container/testing:go_default_library",
|
||||
|
|
|
@ -22,10 +22,8 @@ import (
|
|||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeletapp "k8s.io/kubernetes/cmd/kubelet/app"
|
||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/kubelet"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||
|
@ -117,12 +115,10 @@ func GetHollowKubeletConfig(
|
|||
}
|
||||
|
||||
// Config struct
|
||||
// Do the external -> internal conversion to make sure that defaults
|
||||
// are set for fields not overridden in NewHollowKubelet.
|
||||
tmp := &v1alpha1.KubeletConfiguration{}
|
||||
api.Scheme.Default(tmp)
|
||||
c := &kubeletconfig.KubeletConfiguration{}
|
||||
api.Scheme.Convert(tmp, c, nil)
|
||||
c, err := options.NewKubeletConfiguration()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c.ManifestURL = ""
|
||||
c.Address = "0.0.0.0" /* bind address */
|
||||
|
|
|
@ -25,11 +25,11 @@ go_library(
|
|||
"//conditions:default": [],
|
||||
}),
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/v1/pod:go_default_library",
|
||||
"//pkg/kubelet/apis/cri:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/apis/stats/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/metrics:go_default_library",
|
||||
|
|
|
@ -35,8 +35,8 @@ import (
|
|||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
kubeletconfigv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1"
|
||||
stats "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
|
||||
kubeletmetrics "k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
|
@ -259,13 +259,17 @@ func createConfigMap(f *framework.Framework, internalKC *kubeletconfig.KubeletCo
|
|||
|
||||
// constructs a ConfigMap, populating one of its keys with the KubeletConfiguration. Uses GenerateName.
|
||||
func makeKubeletConfigMap(internalKC *kubeletconfig.KubeletConfiguration) *v1.ConfigMap {
|
||||
externalKC := &kubeletconfigv1alpha1.KubeletConfiguration{}
|
||||
api.Scheme.Convert(internalKC, externalKC, nil)
|
||||
|
||||
encoder, err := newJSONEncoder(kubeletconfig.GroupName)
|
||||
scheme, _, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
data, err := runtime.Encode(encoder, externalKC)
|
||||
versioned := &kubeletconfigv1alpha1.KubeletConfiguration{}
|
||||
err = scheme.Convert(internalKC, versioned, nil)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
encoder, err := newKubeletConfigJSONEncoder()
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
data, err := runtime.Encode(encoder, versioned)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
cmap := &v1.ConfigMap{
|
||||
|
@ -274,7 +278,6 @@ func makeKubeletConfigMap(internalKC *kubeletconfig.KubeletConfiguration) *v1.Co
|
|||
"kubelet": string(data),
|
||||
},
|
||||
}
|
||||
|
||||
return cmap
|
||||
}
|
||||
|
||||
|
@ -310,21 +313,18 @@ func logKubeletMetrics(metricKeys ...string) {
|
|||
}
|
||||
}
|
||||
|
||||
func newJSONEncoder(groupName string) (runtime.Encoder, error) {
|
||||
// encode to json
|
||||
func newKubeletConfigJSONEncoder() (runtime.Encoder, error) {
|
||||
_, kubeletCodecs, err := kubeletscheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mediaType := "application/json"
|
||||
info, ok := runtime.SerializerInfoForMediaType(api.Codecs.SupportedMediaTypes(), mediaType)
|
||||
info, ok := runtime.SerializerInfoForMediaType(kubeletCodecs.SupportedMediaTypes(), mediaType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported media type %q", mediaType)
|
||||
}
|
||||
|
||||
versions := api.Registry.EnabledVersionsForGroup(groupName)
|
||||
if len(versions) == 0 {
|
||||
return nil, fmt.Errorf("no enabled versions for group %q", groupName)
|
||||
}
|
||||
|
||||
// the "best" version supposedly comes first in the list returned from api.Registry.EnabledVersionsForGroup
|
||||
return api.Codecs.EncoderForVersion(info.Serializer, versions[0]), nil
|
||||
return kubeletCodecs.EncoderForVersion(info.Serializer, kubeletconfigv1alpha1.SchemeGroupVersion), nil
|
||||
}
|
||||
|
||||
// runCommand runs the cmd and returns the combined stdout and stderr, or an
|
||||
|
|
|
@ -434,10 +434,6 @@ var ephemeralWhiteList = createEphemeralWhiteList(
|
|||
gvr("componentconfig", "v1alpha1", "kubeproxyconfigurations"), // not stored in etcd
|
||||
// --
|
||||
|
||||
// k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1
|
||||
gvr("kubeletconfig", "v1alpha1", "kubeletconfigurations"), // not stored in etcd
|
||||
// --
|
||||
|
||||
// k8s.io/kubernetes/pkg/apis/extensions/v1beta1
|
||||
gvr("extensions", "v1beta1", "deploymentrollbacks"), // used to rollback deployment, not stored in etcd
|
||||
gvr("extensions", "v1beta1", "replicationcontrollerdummies"), // not stored in etcd
|
||||
|
|
Loading…
Reference in New Issue