Skip to content

Commit

Permalink
Switch API objects to not register per version codecs
Browse files Browse the repository at this point in the history
Remove Codec from versionInterfaces in meta (RESTMapper is now agnostic
to codec and serialization). Register api/latest.Codecs as the codec
factory and use latest.Codecs.LegacyCodec(version) as an equvialent to
the previous codec.
  • Loading branch information
smarterclayton committed Jan 22, 2016
1 parent 125ef6f commit c1d932e
Show file tree
Hide file tree
Showing 54 changed files with 258 additions and 239 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor,
Expand Down Expand Up @@ -97,7 +96,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version {
case v1.SchemeGroupVersion:
return &meta.VersionInterfaces{
Codec: v1.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"k8s.io/kubernetes/pkg/runtime"
)

var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: ""}
var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: runtime.APIVersionInternal}

func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ limitations under the License.
package v1

import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
)

var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: "v1"}

var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)

func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme.
addKnownTypes(scheme)
Expand Down
5 changes: 0 additions & 5 deletions pkg/api/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,9 @@ import (
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/intstr"
)

// Codec is the identity codec for this package - it can only convert itself
// to itself.
var Codec = runtime.CodecFor(Scheme, unversioned.GroupVersion{})

func init() {
Scheme.AddDefaultingFuncs(
func(obj *ListOptions) {
Expand Down
13 changes: 7 additions & 6 deletions pkg/api/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/runtime"
)

func BenchmarkPodConversion(b *testing.B) {
Expand All @@ -30,7 +31,7 @@ func BenchmarkPodConversion(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var pod api.Pod
if err := api.Scheme.DecodeInto(data, &pod); err != nil {
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &pod); err != nil {
b.Fatalf("Unexpected error decoding pod: %v", err)
}

Expand All @@ -41,7 +42,7 @@ func BenchmarkPodConversion(b *testing.B) {
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.GroupVersion().Group].String())
obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String())
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
Expand All @@ -58,7 +59,7 @@ func BenchmarkNodeConversion(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var node api.Node
if err := api.Scheme.DecodeInto(data, &node); err != nil {
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}

Expand All @@ -69,7 +70,7 @@ func BenchmarkNodeConversion(b *testing.B) {
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.GroupVersion().Group].String())
obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String())
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
Expand All @@ -86,7 +87,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var replicationController api.ReplicationController
if err := api.Scheme.DecodeInto(data, &replicationController); err != nil {
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}

Expand All @@ -97,7 +98,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) {
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.GroupVersion().Group].String())
obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String())
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/copy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func doDeepCopyTest(t *testing.T, kind unversioned.GroupVersionKind, f *fuzz.Fuz
}

if !reflect.DeepEqual(item, itemCopy) {
t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, util.ObjectDiff(item, itemCopy))
t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, util.ObjectGoPrintSideBySide(item, itemCopy))
}
}

Expand Down
8 changes: 5 additions & 3 deletions pkg/api/deep_copy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"testing"

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/runtime"
)

func BenchmarkPodCopy(b *testing.B) {
Expand All @@ -29,7 +31,7 @@ func BenchmarkPodCopy(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var pod api.Pod
if err := api.Scheme.DecodeInto(data, &pod); err != nil {
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &pod); err != nil {
b.Fatalf("Unexpected error decoding pod: %v", err)
}

Expand All @@ -52,7 +54,7 @@ func BenchmarkNodeCopy(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var node api.Node
if err := api.Scheme.DecodeInto(data, &node); err != nil {
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}

Expand All @@ -75,7 +77,7 @@ func BenchmarkReplicationControllerCopy(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var replicationController api.ReplicationController
if err := api.Scheme.DecodeInto(data, &replicationController); err != nil {
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}

Expand Down
9 changes: 3 additions & 6 deletions pkg/api/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ import (
"github.com/golang/glog"

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/util/sets"

"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apimachinery"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
)

const importPrefix = "k8s.io/kubernetes/pkg/api"
Expand Down Expand Up @@ -75,7 +74,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor,
Expand Down Expand Up @@ -127,7 +125,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version {
case v1.SchemeGroupVersion:
return &meta.VersionInterfaces{
Codec: v1.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
Expand Down
19 changes: 16 additions & 3 deletions pkg/api/install/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package install

import (
"encoding/json"
"reflect"
"testing"

internal "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/runtime"
)

func TestResourceVersioner(t *testing.T) {
Expand All @@ -49,7 +51,7 @@ func TestCodec(t *testing.T) {
pod := internal.Pod{}
// We do want to use package registered rather than testapi here, because we
// want to test if the package install and package registered work as expected.
data, err := registered.GroupOrDie(internal.GroupName).Codec.Encode(&pod)
data, err := runtime.Encode(internal.Codecs.LegacyCodec(registered.GroupOrDie(internal.GroupName).GroupVersion), &pod)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand Down Expand Up @@ -100,8 +102,8 @@ func TestRESTMapper(t *testing.T) {
}

interfaces, _ := registered.GroupOrDie(internal.GroupName).InterfacesFor(version)
if mapping.Codec != interfaces.Codec {
t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces)
if mapping.ObjectConvertor != interfaces.ObjectConvertor {
t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
}

rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}}
Expand All @@ -114,3 +116,14 @@ func TestRESTMapper(t *testing.T) {
}
}
}

func TestUnversioned(t *testing.T) {
for _, obj := range []runtime.Object{
&unversioned.Status{},
&unversioned.ExportOptions{},
} {
if unversioned, ok := internal.Scheme.IsUnversioned(obj); !unversioned || !ok {
t.Errorf("%v is expected to be unversioned", reflect.TypeOf(obj))
}
}
}
2 changes: 1 addition & 1 deletion pkg/api/meta/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func SetList(list runtime.Object, objects []runtime.Object) error {
} else if src.Type().ConvertibleTo(dest.Type()) {
dest.Set(src.Convert(dest.Type()))
} else {
return fmt.Errorf("item[%d]: Type mismatch: Expected %v, got %v", i, dest.Type(), src.Type())
return fmt.Errorf("item[%d]: can't assign or convert %v into %v", i, src.Type(), dest.Type())
}
}
items.Set(slice)
Expand Down
2 changes: 0 additions & 2 deletions pkg/api/meta/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (

// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
type VersionInterfaces struct {
runtime.Codec
runtime.ObjectConvertor
MetadataAccessor
}
Expand Down Expand Up @@ -142,7 +141,6 @@ type RESTMapping struct {
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
Scope RESTScope

runtime.Codec
runtime.ObjectConvertor
MetadataAccessor
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/api/meta/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestAPIObjectMeta(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if e, a := "/a", typeAccessor.GetAPIVersion(); e != a {
if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "b", typeAccessor.GetKind(); e != a {
Expand Down Expand Up @@ -102,7 +102,7 @@ func TestAPIObjectMeta(t *testing.T) {
if e, a := types.UID("other"), j.UID; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "/c", j.APIVersion; e != a {
if e, a := "c", j.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "d", j.Kind; e != a {
Expand All @@ -117,7 +117,7 @@ func TestAPIObjectMeta(t *testing.T) {

typeAccessor.SetAPIVersion("d")
typeAccessor.SetKind("e")
if e, a := "/d", j.APIVersion; e != a {
if e, a := "d", j.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "e", j.Kind; e != a {
Expand Down Expand Up @@ -308,7 +308,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if e, a := "/a", apiVersion; e != a {
if e, a := "a", apiVersion; e != a {
t.Errorf("expected %v, got %v", e, a)
}
kind, err := accessor.Kind(j)
Expand Down Expand Up @@ -392,7 +392,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
if e, a := "other", j.TypeMeta.UID; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "/c", j.TypeMeta.APIVersion; e != a {
if e, a := "c", j.TypeMeta.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "d", j.TypeMeta.Kind; e != a {
Expand Down Expand Up @@ -757,7 +757,7 @@ func BenchmarkAccessorSetReflection(b *testing.B) {
Name: "foo",
GenerateName: "prefix",
UID: "uid",
APIVersion: "/a",
APIVersion: "a",
Kind: "b",
ResourceVersion: "1",
SelfLink: "some/place/only/we/know",
Expand Down
11 changes: 7 additions & 4 deletions pkg/api/meta/restmapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"strings"

"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
)

Expand Down Expand Up @@ -84,15 +85,15 @@ type DefaultRESTMapper struct {

var _ RESTMapper = &DefaultRESTMapper{}

// VersionInterfacesFunc returns the appropriate codec, typer, and metadata accessor for a
// VersionInterfacesFunc returns the appropriate typer, and metadata accessor for a
// given api version, or an error if no such api version exists.
type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInterfaces, error)

// NewDefaultRESTMapper initializes a mapping between Kind and APIVersion
// to a resource name and back based on the objects in a runtime.Scheme
// and the Kubernetes API conventions. Takes a group name, a priority list of the versions
// to search when an object has no default version (set empty to return an error),
// and a function that retrieves the correct codec and metadata for a given version.
// and a function that retrieves the correct metadata for a given version.
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f VersionInterfacesFunc) *DefaultRESTMapper {
resourceToKind := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionKind)
kindToPluralResource := make(map[unversioned.GroupVersionKind]unversioned.GroupVersionResource)
Expand Down Expand Up @@ -251,6 +252,9 @@ func (m *DefaultRESTMapper) ResourceFor(resource unversioned.GroupVersionResourc

func (m *DefaultRESTMapper) KindsFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
resource := input.GroupVersion().WithResource(strings.ToLower(input.Resource))
if resource.Version == runtime.APIVersionInternal {
resource.Version = ""
}

hasResource := len(resource.Resource) > 0
hasGroup := len(resource.Group) > 0
Expand Down Expand Up @@ -412,7 +416,7 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st
var gvk *unversioned.GroupVersionKind
hadVersion := false
for _, version := range versions {
if len(version) == 0 {
if len(version) == 0 || version == runtime.APIVersionInternal {
continue
}

Expand Down Expand Up @@ -472,7 +476,6 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st
GroupVersionKind: *gvk,
Scope: scope,

Codec: interfaces.Codec,
ObjectConvertor: interfaces.ObjectConvertor,
MetadataAccessor: interfaces.MetadataAccessor,
}
Expand Down
Loading

0 comments on commit c1d932e

Please sign in to comment.