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
VersionArgs map [string ]*GroupVersionFactoryArgs
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
type GroupMetaFactoryArgs struct {
GroupName string
VersionPreferenceOrder []string
ImportPrefix string
RootScopedKinds sets.String
IgnoredKinds sets.String
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
type GroupVersionFactoryArgs struct {
GroupName string
VersionName string
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
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,
},
)
}
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})
}
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)
}
prioritizedVersions = append (prioritizedVersions, unprioritizedVersions...)
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
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
}
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
}
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
groupMeta.RESTMapper = gmf.newRESTMapper(scheme, externalVersions, 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
func (gmf *GroupMetaFactory) RegisterAndEnable () error {
if err := gmf.Register(registered.DefaultAPIRegistrationManager); err != nil {
return err
}
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的注册。