mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #42722 from sttts/sttts-federation-core-group
Automatic merge from submit-queue (batch tested with PRs 43870, 30302, 42722, 43736) federation: avoid double core group registration The federation apiserver installed its custom core group into the global `pkg/api` registry, leading to double registration. Luckily (or maybe unfortunately) we did not fail hard in this case, but the init funcs just ignored the error. This PR creates an extra apigroup registry based on the already existing federation `core.Scheme`. This decouples the two core groups (which happen to co-exist in hyperkube).
This commit is contained in:
commit
e864b31ca4
@ -13,6 +13,8 @@ go_library(
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery/registered",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||
|
@ -14,12 +14,9 @@ go_library(
|
||||
deps = [
|
||||
"//federation/apis/core:go_default_library",
|
||||
"//federation/apis/core/v1:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery/registered",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
||||
],
|
||||
)
|
||||
|
@ -17,123 +17,39 @@ limitations under the License.
|
||||
package install
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apimachinery"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
core "k8s.io/kubernetes/federation/apis/core"
|
||||
core_v1 "k8s.io/kubernetes/federation/apis/core/v1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/federation/apis/core"
|
||||
corev1 "k8s.io/kubernetes/federation/apis/core/v1"
|
||||
)
|
||||
|
||||
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 = []schema.GroupVersion{core_v1.SchemeGroupVersion}
|
||||
|
||||
func init() {
|
||||
api.Registry.RegisterVersions(availableVersions)
|
||||
externalVersions := []schema.GroupVersion{}
|
||||
for _, v := range availableVersions {
|
||||
if api.Registry.IsAllowedVersion(v) {
|
||||
externalVersions = append(externalVersions, v)
|
||||
}
|
||||
}
|
||||
if len(externalVersions) == 0 {
|
||||
glog.V(4).Infof("No version is registered for group %v", core.GroupName)
|
||||
return
|
||||
}
|
||||
|
||||
if err := api.Registry.EnableVersions(externalVersions...); err != nil {
|
||||
glog.V(4).Infof("%v", err)
|
||||
return
|
||||
}
|
||||
if err := enableVersions(externalVersions); err != nil {
|
||||
glog.V(4).Infof("%v", err)
|
||||
return
|
||||
}
|
||||
Install(core.GroupFactoryRegistry, core.Registry, core.Scheme)
|
||||
}
|
||||
|
||||
// TODO: enableVersions should be centralized rather than spread in each API
|
||||
// group.
|
||||
// We can combine api.Registry.RegisterVersions, api.Registry.EnableVersions and
|
||||
// api.Registry.RegisterGroup once we have moved enableVersions there.
|
||||
func enableVersions(externalVersions []schema.GroupVersion) error {
|
||||
addVersionsToScheme(externalVersions...)
|
||||
preferredExternalVersion := externalVersions[0]
|
||||
|
||||
groupMeta := apimachinery.GroupMeta{
|
||||
GroupVersion: preferredExternalVersion,
|
||||
GroupVersions: externalVersions,
|
||||
RESTMapper: newRESTMapper(externalVersions),
|
||||
SelfLinker: runtime.SelfLinker(accessor),
|
||||
InterfacesFor: interfacesFor,
|
||||
}
|
||||
|
||||
if err := api.Registry.RegisterGroup(groupMeta); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newRESTMapper(externalVersions []schema.GroupVersion) meta.RESTMapper {
|
||||
// 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
|
||||
rootScoped := sets.NewString(
|
||||
"Namespace",
|
||||
)
|
||||
|
||||
// these kinds should be excluded from the list of resources
|
||||
ignoredKinds := sets.NewString(
|
||||
"ListOptions",
|
||||
"DeleteOptions",
|
||||
"Status")
|
||||
|
||||
mapper := meta.NewDefaultRESTMapperFromScheme(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped, core.Scheme)
|
||||
|
||||
return 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 schema.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
switch version {
|
||||
case core_v1.SchemeGroupVersion:
|
||||
return &meta.VersionInterfaces{
|
||||
ObjectConvertor: core.Scheme,
|
||||
MetadataAccessor: accessor,
|
||||
}, nil
|
||||
default:
|
||||
g, _ := api.Registry.Group(core.GroupName)
|
||||
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions)
|
||||
}
|
||||
}
|
||||
|
||||
func addVersionsToScheme(externalVersions ...schema.GroupVersion) {
|
||||
// add the internal version to Scheme
|
||||
if err := core.AddToScheme(core.Scheme); err != nil {
|
||||
// Programmer error, detect immediately
|
||||
// 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: core.GroupName,
|
||||
VersionPreferenceOrder: []string{corev1.SchemeGroupVersion.Version},
|
||||
ImportPrefix: "k8s.io/kubernetes/federation/apis/core",
|
||||
AddInternalObjectsToScheme: core.AddToScheme,
|
||||
RootScopedKinds: sets.NewString(
|
||||
"Namespace",
|
||||
),
|
||||
IgnoredKinds: sets.NewString(
|
||||
"ListOptions",
|
||||
"DeleteOptions",
|
||||
"Status",
|
||||
),
|
||||
},
|
||||
announced.VersionToSchemeFunc{
|
||||
corev1.SchemeGroupVersion.Version: corev1.AddToScheme,
|
||||
},
|
||||
).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// add the enabled external versions to Scheme
|
||||
for _, v := range externalVersions {
|
||||
if !api.Registry.IsEnabledVersion(v) {
|
||||
glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v)
|
||||
continue
|
||||
}
|
||||
switch v {
|
||||
case core_v1.SchemeGroupVersion:
|
||||
if err := core_v1.AddToScheme(core.Scheme); err != nil {
|
||||
// Programmer error, detect immediately
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ limitations under the License.
|
||||
package core
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -24,6 +28,17 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NOTE: the registry, scheme and codecs are created here to allow to install a federation core group
|
||||
// that is completely independent from the Kubernetes core group. It's only used for the core group itself.
|
||||
// The other apigroups in the federation apiserver use the Kubernetes registry, scheme and codecs.
|
||||
|
||||
// GroupFactoryRegistry is the APIGroupFactoryRegistry (overlaps a bit with Registry, see comments in package for details)
|
||||
var GroupFactoryRegistry = make(announced.APIGroupFactoryRegistry)
|
||||
|
||||
// Registry is an instance of an API registry. This is an interim step to start removing the idea of a global
|
||||
// API registry.
|
||||
var Registry = registered.NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user