什么是GroupMetaFactory

GroupMetaFactory表示一个Group,主要包含两部信息,GroupMetaFactoryArgs表示Group的信息;GroupversionFactoryArgs表示Version的信息。GroupMetaFactory还提供了向APIRegistrationManager注册的功能。

接下来看下GroupMetaFactory的定义,定义在/pkg/apimachinery/announced/group_factory.go中:

1
2
3
4
5
6
7
8
type GroupMetaFactory struct {
GroupArgs *GroupMetaFactoryArgs
// map of version name to version factory
VersionArgs map[string]*GroupVersionFactoryArgs
// assembled by Register()
prioritizedVersionList []unversioned.GroupVersion
}

其中:

  • GroupArgs: 类型为GroupMetaFactoryArgs,表示Group的信息;
  • VersionArgs: 类型为的map,表示VersionArgs的信息;
  • prioritizedVersionList: 表示GV的优化级。

再来看下GroupMetaFactoryArgs的定义(/pkg/apimachinery/announced/group_factory.go):

1
2
3
4
5
6
7
8
9
10
11
12
13
// GroupMetaFactoryArgs contains the group-level args of a GroupMetaFactory.
type GroupMetaFactoryArgs struct {
GroupName string
VersionPreferenceOrder []string
ImportPrefix string
RootScopedKinds sets.String // nil is allowed
IgnoredKinds sets.String // nil is allowed
// May be nil if there are no internal objects.
//***AddInternalObjectsToScheme func***//
AddInternalObjectsToScheme SchemeFunc
}

其中:

  • GroupName: Group的名字;
  • VersionPreferenceOrder: GV优先级;
  • ImportPrefix:如”k8s.io/kubernetes/pkg/apis/apps”;
  • RootScopedKinds: RootScoped的类型;
  • IgnoredKinds: 非资源的类型;
  • AddInternalObjectsToScheme:内部类型添加函数,里面定义有哪些内部结构体要添加到Scheme中,因为内部结构体与版本无关,所以放在Group下。

接着看下GroupVersionFactoryArgs的定义(/pkg/apimachinery/announced/group_factory.go):

1
2
3
4
5
6
7
8
// GroupVersionFactoryArgs contains all the per-version parts of a GroupMetaFactory.
type GroupVersionFactoryArgs struct {
GroupName string
VersionName string
//***AddToScheme func***//
AddToScheme SchemeFunc
}

其中:

  • GroupName: 表示Group的名字;
  • VersionName: 表示Version的名字,如”v1beta1”;
  • AddToScheme: 表示添加到Scheme的函数,里面定义有哪些结构体需要添加到Scheme中。

Announce()

Announce()可以理解为向DefaultGroupFactoryRegistry中注册,当然DefaultGroupFactoryRegistry还在开发中。

1
2
3
4
5
6
func (gmf *GroupMetaFactory) Announce() *GroupMetaFactory {
if err := DefaultGroupFactoryRegistry.AnnouncePreconstructedFactory(gmf); err != nil {
panic(err)
}
return gmf
}

Register()

Register()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Register constructs the finalized prioritized version list and sanity checks
// the announced group & versions. Then it calls register.
func (gmf *GroupMetaFactory) Register(m *registered.APIRegistrationManager) error {
if gmf.GroupArgs == nil {
return fmt.Errorf("partially announced groups are not allowed, only got versions: %#v", gmf.VersionArgs)
}
if len(gmf.VersionArgs) == 0 {
return fmt.Errorf("group %v announced but no versions announced", gmf.GroupArgs.GroupName)
}
pvSet := sets.NewString(gmf.GroupArgs.VersionPreferenceOrder...)
if pvSet.Len() != len(gmf.GroupArgs.VersionPreferenceOrder) {
return fmt.Errorf("preference order for group %v has duplicates: %v", gmf.GroupArgs.GroupName, gmf.GroupArgs.VersionPreferenceOrder)
}
prioritizedVersions := []unversioned.GroupVersion{}
for _, v := range gmf.GroupArgs.VersionPreferenceOrder {
prioritizedVersions = append(
prioritizedVersions,
unversioned.GroupVersion{
Group: gmf.GroupArgs.GroupName,
Version: v,
},
)
}
// Go through versions that weren't explicitly prioritized.
//***Fankang***//
//***收集不在VersionPreferenceOrder中的version***//
unprioritizedVersions := []unversioned.GroupVersion{}
for _, v := range gmf.VersionArgs {
if v.GroupName != gmf.GroupArgs.GroupName {
return fmt.Errorf("found %v/%v in group %v?", v.GroupName, v.VersionName, gmf.GroupArgs.GroupName)
}
if pvSet.Has(v.VersionName) {
pvSet.Delete(v.VersionName)
continue
}
unprioritizedVersions = append(unprioritizedVersions, unversioned.GroupVersion{Group: v.GroupName, Version: v.VersionName})
}
//***Fankang***//
//***不能有多于1个的unprioritized version***//
if len(unprioritizedVersions) > 1 {
glog.Warningf("group %v has multiple unprioritized versions: %#v. They will have an arbitrary preference order!", gmf.GroupArgs.GroupName, unprioritizedVersions)
}
if pvSet.Len() != 0 {
return fmt.Errorf("group %v has versions in the priority list that were never announced: %s", gmf.GroupArgs.GroupName, pvSet)
}
//***Fankang***//
//***把unprioritizedVersions纳入到prioritizedVersions***//
prioritizedVersions = append(prioritizedVersions, unprioritizedVersions...)
//***Fankang***//
//***向APIRegistrationManager中注册versions***//
m.RegisterVersions(prioritizedVersions)
gmf.prioritizedVersionList = prioritizedVersions
return nil
}

Enable()

Enable()方法先调用每个GroupVersion对应的GroupVersionFactoryArg中的AddToScheme,把版本中的types注册到Scheme中;然后调用GroupArgs中的AddInternalObjectsToScheme注册内部版本的types;最后构造GroupMeta,并向DefaultAPIRegistrationManager中注册。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Enable enables group versions that are allowed, adds methods to the scheme, etc.
func (gmf *GroupMetaFactory) Enable(m *registered.APIRegistrationManager, scheme *runtime.Scheme) error {
externalVersions := []unversioned.GroupVersion{}
for _, v := range gmf.prioritizedVersionList {
if !m.IsAllowedVersion(v) {
continue
}
externalVersions = append(externalVersions, v)
if err := m.EnableVersions(v); err != nil {
return err
}
//***注册具体版本的类型,如:v1beta1.AddToScheme***//
gmf.VersionArgs[v.Version].AddToScheme(scheme)
}
if len(externalVersions) == 0 {
glog.V(4).Infof("No version is registered for group %v", gmf.GroupArgs.GroupName)
return nil
}
//***注册内部版本的类型,如:apps.AddToScheme***//
if gmf.GroupArgs.AddInternalObjectsToScheme != nil {
gmf.GroupArgs.AddInternalObjectsToScheme(scheme)
}
preferredExternalVersion := externalVersions[0]
accessor := meta.NewAccessor()
groupMeta := &apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions,
SelfLinker: runtime.SelfLinker(accessor),
}
for _, v := range externalVersions {
gvf := gmf.VersionArgs[v.Version]
if err := groupMeta.AddVersionInterfaces(
unversioned.GroupVersion{Group: gvf.GroupName, Version: gvf.VersionName},
&meta.VersionInterfaces{
ObjectConvertor: scheme,
MetadataAccessor: accessor,
},
); err != nil {
return err
}
}
groupMeta.InterfacesFor = groupMeta.DefaultInterfacesFor
//***生成RESTMapper***//
groupMeta.RESTMapper = gmf.newRESTMapper(scheme, externalVersions, groupMeta)
//***向APIRegistrationManager注册groupMeta***//
if err := m.RegisterGroup(*groupMeta); err != nil {
return err
}
return nil
}

RegisterAndEnable()

RegisterAndEnable()是对Register()方法和Enable()方法的封装,从这里可以看出,默认使用是的DefaultAPIregistrationManager和api.Scheme。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// RegisterAndEnable is provided only to allow this code to get added in multiple steps.
// It's really bad that this is called in init() methods, but supporting this
// temporarily lets us do the change incrementally.
func (gmf *GroupMetaFactory) RegisterAndEnable() error {
if err := gmf.Register(registered.DefaultAPIRegistrationManager); err != nil {
return err
}
//***向api.Scheme注册***//
if err := gmf.Enable(registered.DefaultAPIRegistrationManager, api.Scheme); err != nil {
return err
}
return nil
}

调用例子

在/pkg/apis/apps/install/install.go中,有如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func init() {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: apps.GroupName,
VersionPreferenceOrder: []string{v1beta1.SchemeGroupVersion.Version},
ImportPrefix: "k8s.io/kubernetes/pkg/apis/apps",
AddInternalObjectsToScheme: apps.AddToScheme,
},
announced.VersionToSchemeFunc{
v1beta1.SchemeGroupVersion.Version: v1beta1.AddToScheme,
},
).Announce().RegisterAndEnable(); err != nil {
panic(err)
}
}

可知,代码最后调用了RegisterAndEnable()完成向registered.DefaultGroupFactoryRegistry和api.Scheme的注册。