diff --git a/cmd/libs/go2idl/client-gen/testdata/apis/testgroup/install/install.go b/cmd/libs/go2idl/client-gen/testdata/apis/testgroup/install/install.go index 308252e559..7a456cc182 100644 --- a/cmd/libs/go2idl/client-gen/testdata/apis/testgroup/install/install.go +++ b/cmd/libs/go2idl/client-gen/testdata/apis/testgroup/install/install.go @@ -37,33 +37,39 @@ const importPrefix = "k8s.io/kubernetes/pkg/apis/testgroup" var accessor = meta.NewAccessor() +const groupName = "testgroup" + +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{{Group: groupName, Version: "v1"}} + func init() { registered.RegisteredGroupVersions = append(registered.RegisteredGroupVersions, v1.SchemeGroupVersion) - groupMeta, err := latest.RegisterGroup("testgroup") - if err != nil { + + externalVersions := availableVersions + preferredExternalVersion := externalVersions[0] + + groupMeta := latest.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion.String()), + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := latest.RegisterGroup(groupMeta); err != nil { glog.V(4).Infof("%v", err) return } - registeredGroupVersions := []unversioned.GroupVersion{ - { - "testgroup", - "v1", - }, - } - groupVersion := registeredGroupVersions[0] - *groupMeta = latest.GroupMeta{ - GroupVersion: groupVersion, - Codec: runtime.CodecFor(api.Scheme, groupVersion.String()), - } + api.RegisterRESTMapper(groupMeta.RESTMapper) +} +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { worstToBestGroupVersions := []unversioned.GroupVersion{} - for i := len(registeredGroupVersions) - 1; i >= 0; i-- { - worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i]) + for i := len(externalVersions) - 1; i >= 0; i-- { + worstToBestGroupVersions = append(worstToBestGroupVersions, externalVersions[i]) } - groupMeta.GroupVersions = registeredGroupVersions - - groupMeta.SelfLinker = runtime.SelfLinker(accessor) // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope @@ -71,9 +77,7 @@ func init() { ignoredKinds := sets.NewString() - groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) - api.RegisterRESTMapper(groupMeta.RESTMapper) - groupMeta.InterfacesFor = interfacesFor + return api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) } // InterfacesFor returns the default Codec and ResourceVersioner for a given version @@ -87,7 +91,7 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e MetadataAccessor: accessor, }, nil default: - g, _ := latest.Group("testgroup") + g, _ := latest.Group(groupName) return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) } } diff --git a/pkg/api/install/install.go b/pkg/api/install/install.go index d7aeb0cdcd..7ac03bb32e 100644 --- a/pkg/api/install/install.go +++ b/pkg/api/install/install.go @@ -34,35 +34,55 @@ import ( "k8s.io/kubernetes/pkg/runtime" ) -// userResources is a group of resources mostly used by a kubectl user -var userResources = []string{"rc", "svc", "pods", "pvc"} - const importPrefix = "k8s.io/kubernetes/pkg/api" var accessor = meta.NewAccessor() +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{v1.SchemeGroupVersion} + func init() { - groupMeta, err := latest.RegisterGroup(api.GroupName) - if err != nil { + externalVersions := []unversioned.GroupVersion{} + for _, allowedVersion := range registered.GroupVersionsForGroup(api.GroupName) { + for _, externalVersion := range availableVersions { + if externalVersion == allowedVersion { + externalVersions = append(externalVersions, externalVersion) + } + } + } + + if len(externalVersions) == 0 { + glog.V(4).Infof("No version is registered for group %v", api.GroupName) + return + } + + preferredExternalVersion := externalVersions[0] + + groupMeta := latest.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion.String()), + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := latest.RegisterGroup(groupMeta); err != nil { glog.V(4).Infof("%v", err) return } - // Use the first API version in the list of registered versions as the latest. - registeredGroupVersions := registered.GroupVersionsForGroup(api.GroupName) - groupVersion := registeredGroupVersions[0] - *groupMeta = latest.GroupMeta{ - GroupVersion: groupVersion, - Codec: runtime.CodecFor(api.Scheme, groupVersion.String()), - } + api.RegisterRESTMapper(groupMeta.RESTMapper) +} +// userResources is a group of resources mostly used by a kubectl user +var userResources = []string{"rc", "svc", "pods", "pvc"} + +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { worstToBestGroupVersions := []unversioned.GroupVersion{} - for i := len(registeredGroupVersions) - 1; i >= 0; i-- { - worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i]) + for i := len(externalVersions) - 1; i >= 0; i-- { + worstToBestGroupVersions = append(worstToBestGroupVersions, externalVersions[i]) } - groupMeta.GroupVersions = registeredGroupVersions - - groupMeta.SelfLinker = runtime.SelfLinker(accessor) // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope @@ -89,9 +109,8 @@ func init() { mapper := api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) // setup aliases for groups of resources mapper.AddResourceAlias("all", userResources...) - groupMeta.RESTMapper = mapper - api.RegisterRESTMapper(groupMeta.RESTMapper) - groupMeta.InterfacesFor = interfacesFor + + return mapper } // InterfacesFor returns the default Codec and ResourceVersioner for a given version @@ -105,9 +124,7 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e MetadataAccessor: accessor, }, nil default: - { - g, _ := latest.Group(api.GroupName) - return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) - } + g, _ := latest.Group(api.GroupName) + return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions) } } diff --git a/pkg/api/latest/latest.go b/pkg/api/latest/latest.go index 706c79236b..8a456b1f8a 100644 --- a/pkg/api/latest/latest.go +++ b/pkg/api/latest/latest.go @@ -22,7 +22,6 @@ import ( "strings" "k8s.io/kubernetes/pkg/api/meta" - "k8s.io/kubernetes/pkg/api/registered" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -52,16 +51,14 @@ var ExternalVersions = []unversioned.GroupVersion{ type GroupMetaMap map[string]*GroupMeta // RegisterGroup registers a group to GroupMetaMap. -func (g GroupMetaMap) RegisterGroup(group string) (*GroupMeta, error) { - _, found := g[group] - if found { - return nil, fmt.Errorf("group %v is already registered", g) +func (g GroupMetaMap) RegisterGroup(groupMeta GroupMeta) error { + groupName := groupMeta.GroupVersion.Group + if _, found := g[groupName]; found { + return fmt.Errorf("group %v is already registered", g) } - if len(registered.GroupVersionsForGroup(group)) == 0 { - return nil, fmt.Errorf("No version is registered for group %v", group) - } - g[group] = &GroupMeta{} - return g[group], nil + + g[groupName] = &groupMeta + return nil } // Group returns the metadata of a group if the gruop is registered, otherwise @@ -71,7 +68,8 @@ func (g GroupMetaMap) Group(group string) (*GroupMeta, error) { if !found { return nil, fmt.Errorf("no version is registered for group %v", group) } - return groupMeta, nil + groupMetaCopy := *groupMeta + return &groupMetaCopy, nil } // IsRegistered takes a string and determines if it's one of the registered groups @@ -93,7 +91,8 @@ func (g GroupMetaMap) GroupOrDie(group string) *GroupMeta { panic(fmt.Sprintf("No version is registered for group %s. ", group) + msg) } } - return groupMeta + groupMetaCopy := *groupMeta + return &groupMetaCopy } // AllPreferredGroupVersions returns the preferred versions of all registered diff --git a/pkg/apis/componentconfig/install/install.go b/pkg/apis/componentconfig/install/install.go index 39b0860c12..506104a774 100644 --- a/pkg/apis/componentconfig/install/install.go +++ b/pkg/apis/componentconfig/install/install.go @@ -38,27 +38,48 @@ const importPrefix = "k8s.io/kubernetes/pkg/apis/componentconfig" var accessor = meta.NewAccessor() +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{v1alpha1.SchemeGroupVersion} + func init() { - groupMeta, err := latest.RegisterGroup(componentconfig.GroupName) - if err != nil { + externalVersions := []unversioned.GroupVersion{} + for _, allowedVersion := range registered.GroupVersionsForGroup(componentconfig.GroupName) { + for _, externalVersion := range availableVersions { + if externalVersion == allowedVersion { + externalVersions = append(externalVersions, externalVersion) + } + } + } + + if len(externalVersions) == 0 { + glog.V(4).Infof("No version is registered for group %v", componentconfig.GroupName) + return + } + + preferredExternalVersion := externalVersions[0] + + groupMeta := latest.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion.String()), + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := latest.RegisterGroup(groupMeta); err != nil { glog.V(4).Infof("%v", err) return } - registeredGroupVersions := registered.GroupVersionsForGroup(componentconfig.GroupName) - groupVersion := registeredGroupVersions[0] - *groupMeta = latest.GroupMeta{ - GroupVersion: groupVersion, - Codec: runtime.CodecFor(api.Scheme, groupVersion.String()), - } + api.RegisterRESTMapper(groupMeta.RESTMapper) +} +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { worstToBestGroupVersions := []unversioned.GroupVersion{} - for i := len(registeredGroupVersions) - 1; i >= 0; i-- { - worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i]) + for i := len(externalVersions) - 1; i >= 0; i-- { + worstToBestGroupVersions = append(worstToBestGroupVersions, externalVersions[i]) } - groupMeta.GroupVersions = registeredGroupVersions - - groupMeta.SelfLinker = runtime.SelfLinker(accessor) // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope @@ -66,9 +87,7 @@ func init() { ignoredKinds := sets.NewString() - groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) - api.RegisterRESTMapper(groupMeta.RESTMapper) - groupMeta.InterfacesFor = interfacesFor + return api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) } // interfacesFor returns the default Codec and ResourceVersioner for a given version diff --git a/pkg/apis/extensions/install/install.go b/pkg/apis/extensions/install/install.go index 6c927a113d..814e7bb8f9 100644 --- a/pkg/apis/extensions/install/install.go +++ b/pkg/apis/extensions/install/install.go @@ -38,27 +38,48 @@ const importPrefix = "k8s.io/kubernetes/pkg/apis/extensions" var accessor = meta.NewAccessor() +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{v1beta1.SchemeGroupVersion} + func init() { - groupMeta, err := latest.RegisterGroup(extensions.GroupName) - if err != nil { + externalVersions := []unversioned.GroupVersion{} + for _, allowedVersion := range registered.GroupVersionsForGroup(extensions.GroupName) { + for _, externalVersion := range availableVersions { + if externalVersion == allowedVersion { + externalVersions = append(externalVersions, externalVersion) + } + } + } + + if len(externalVersions) == 0 { + glog.V(4).Infof("No version is registered for group %v", extensions.GroupName) + return + } + + preferredExternalVersion := externalVersions[0] + + groupMeta := latest.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion.String()), + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := latest.RegisterGroup(groupMeta); err != nil { glog.V(4).Infof("%v", err) return } - registeredGroupVersions := registered.GroupVersionsForGroup(extensions.GroupName) - groupVersion := registeredGroupVersions[0] - *groupMeta = latest.GroupMeta{ - GroupVersion: groupVersion, - Codec: runtime.CodecFor(api.Scheme, groupVersion.String()), - } + api.RegisterRESTMapper(groupMeta.RESTMapper) +} +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { worstToBestGroupVersions := []unversioned.GroupVersion{} - for i := len(registeredGroupVersions) - 1; i >= 0; i-- { - worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i]) + for i := len(externalVersions) - 1; i >= 0; i-- { + worstToBestGroupVersions = append(worstToBestGroupVersions, externalVersions[i]) } - groupMeta.GroupVersions = registeredGroupVersions - - groupMeta.SelfLinker = runtime.SelfLinker(accessor) // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope @@ -66,12 +87,10 @@ func init() { ignoredKinds := sets.NewString() - groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) - api.RegisterRESTMapper(groupMeta.RESTMapper) - groupMeta.InterfacesFor = interfacesFor + return api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) } -// InterfacesFor returns the default Codec and ResourceVersioner for a given version +// interfacesFor returns the default Codec and ResourceVersioner for a given version // string, or an error if the version is not known. func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) { switch version { diff --git a/pkg/apis/metrics/install/install.go b/pkg/apis/metrics/install/install.go index 5254c6828f..891b70e623 100644 --- a/pkg/apis/metrics/install/install.go +++ b/pkg/apis/metrics/install/install.go @@ -38,27 +38,48 @@ const importPrefix = "k8s.io/kubernetes/pkg/apis/metrics" var accessor = meta.NewAccessor() +// availableVersions lists all known external versions for this group from most preferred to least preferred +var availableVersions = []unversioned.GroupVersion{v1alpha1.SchemeGroupVersion} + func init() { - groupMeta, err := latest.RegisterGroup(metrics.GroupName) - if err != nil { + externalVersions := []unversioned.GroupVersion{} + for _, allowedVersion := range registered.GroupVersionsForGroup(metrics.GroupName) { + for _, externalVersion := range availableVersions { + if externalVersion == allowedVersion { + externalVersions = append(externalVersions, externalVersion) + } + } + } + + if len(externalVersions) == 0 { + glog.V(4).Infof("No version is registered for group %v", metrics.GroupName) + return + } + + preferredExternalVersion := externalVersions[0] + + groupMeta := latest.GroupMeta{ + GroupVersion: preferredExternalVersion, + GroupVersions: externalVersions, + Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion.String()), + RESTMapper: newRESTMapper(externalVersions), + SelfLinker: runtime.SelfLinker(accessor), + InterfacesFor: interfacesFor, + } + + if err := latest.RegisterGroup(groupMeta); err != nil { glog.V(4).Infof("%v", err) return } - registeredGroupVersions := registered.GroupVersionsForGroup(metrics.GroupName) - groupVersion := registeredGroupVersions[0] - *groupMeta = latest.GroupMeta{ - GroupVersion: groupVersion, - Codec: runtime.CodecFor(api.Scheme, groupVersion.String()), - } + api.RegisterRESTMapper(groupMeta.RESTMapper) +} +func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { worstToBestGroupVersions := []unversioned.GroupVersion{} - for i := len(registeredGroupVersions) - 1; i >= 0; i-- { - worstToBestGroupVersions = append(worstToBestGroupVersions, registeredGroupVersions[i]) + for i := len(externalVersions) - 1; i >= 0; i-- { + worstToBestGroupVersions = append(worstToBestGroupVersions, externalVersions[i]) } - groupMeta.GroupVersions = registeredGroupVersions - - groupMeta.SelfLinker = runtime.SelfLinker(accessor) // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope @@ -66,12 +87,10 @@ func init() { ignoredKinds := sets.NewString() - groupMeta.RESTMapper = api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) - api.RegisterRESTMapper(groupMeta.RESTMapper) - groupMeta.InterfacesFor = interfacesFor + return api.NewDefaultRESTMapper(worstToBestGroupVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) } -// InterfacesFor returns the default Codec and ResourceVersioner for a given version +// interfacesFor returns the default Codec and ResourceVersioner for a given version // string, or an error if the version is not known. func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) { switch version {