- Kubernetes源碼剖析
- 鄭東旭
- 2378字
- 2020-07-23 17:12:16
2.5 代碼生成器
頂層Makefile中定義了generated_files命令,該命令用于構(gòu)建代碼生成器,下面看一下generated_files在Makefile.generated_files中的定義:

generated_files中定義了5個代碼生成器,執(zhí)行make all命令后,這些二進(jìn)制文件被輸出至_output/bin/目錄,如下面的輸出內(nèi)容所示。如果二進(jìn)制文件不存在,也可以通過make generated_files命令單獨(dú)構(gòu)建代碼生成器的二進(jìn)制工具。下面分別介紹這些代碼生成器,如表2-1所示。

表2-1 代碼生成器說明

除了以上5個代碼生成器,Kubernetes實(shí)際上還支持更多的代碼生成器,例如client-gen、lister-gen、informer-gen等代碼生成器。這些代碼生成器會在后面的章節(jié)中進(jìn)行介紹,本節(jié)提及的這5個代碼生成器是構(gòu)建Kubernetes源碼過程中所需要的。
2.5.1 Tags
代碼生成器通過Tags(標(biāo)簽)來識別一個包是否需要生成代碼及確定生成代碼的方式,Kubernetes提供的Tags可以分為如下兩種。
● 全局Tags:定義在每個包的doc.go文件中,對整個包中的類型自動生成代碼。
● 局部Tags:定義在Go語言的類型聲明上方,只對指定的類型自動生成代碼。
Tags的定義規(guī)則通常為//+tag-name或//+tag-name=value,它們被定義在注釋中。
1.全局Tags
全局Tags定義在pkg/apis/<group>/<version>/doc.go中,代碼示例如下:

全局Tags告訴deepcopy-gen代碼生成器為該包中的每個類型自動生成DeepCopy函數(shù)。其中的//+groupName定義了資源組名稱,資源組名稱一般使用域名形式命名。
2.局部Tags
局部Tags定義在Go語言的類型聲明上方,代碼示例如下:
代碼路徑:pkg/apis/core/types.go

局部Tags定義在Pod資源類型的上方,它定義了該類型有兩個代碼生成器,分別為genclient(即client-gen)和deepcopy-gen。其中g(shù)enclient代碼生成器為這個資源類型自動生成對應(yīng)的客戶端代碼,deepcopy-gen代碼生成器為這個資源類型自動生成DeepCopy函數(shù)。
注意:關(guān)于Tags的位置,局部Tags一般定義在類型聲明的上方,但如果該類型有注釋信息,則局部Tags的定義需要與類型聲明的注釋信息之間至少有一個空行。例如:

這是因為Kubernetes的API文檔生成器會根據(jù)類型聲明的注釋信息(comment-block)生成文檔。為了避免Tags信息出現(xiàn)在文檔中,故將Tags定義在注釋的上方并空一行。
2.5.2 deepcopy-gen代碼生成器
deepcopy-gen是一個自動生成DeepCopy函數(shù)的代碼生成器。給定一個包的目錄路徑作為輸入源,它可以為其生成DeepCopy相關(guān)函數(shù),這些函數(shù)可以有效地執(zhí)行每種類型的深復(fù)制操作。
為整個包生成DeepCopy相關(guān)函數(shù)時,其Tags形式如下:

為單個類型生成DeepCopy相關(guān)函數(shù)時,其Tags形式如下:

為整個包生成DeepCopy相關(guān)函數(shù)時,可以忽略單個類型,其Tags形式如下:

有時在Kubernetes源碼里會看到deepcopy-gen的Tags被定義成runtime.Object,這時deepcopy-gen會為該類型生成返回值為runtime.Obejct類型的DeepCopyObject函數(shù),代碼示例如下:

生成如下代碼:

下面介紹deepcopy-gen的使用示例和生成規(guī)則。
1.deepcopy-gen的使用示例

構(gòu)建deepcopy-gen二進(jìn)制文件,并執(zhí)行deepcopy-gen代碼生成器,為k8s.io/kubernetes/pkg/apis/abac/v1beta1包生成zz_generated.deepcopy.go代碼文件。
2.deepcopy-gen的生成規(guī)則
代碼路徑:vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go

deepcopy-gen會遍歷包中的所有類型,若類型為types.Struct,則會為該類型生成深復(fù)制函數(shù)。
2.5.3 defaulter-gen代碼生成器
defaulter-gen是一個自動生成Defaulter函數(shù)的代碼生成器。給定一個包的目錄路徑作為輸入源,它可以為其生成Defaulter相關(guān)函數(shù),這些函數(shù)可以為資源對象生成默認(rèn)值。
為擁有TypeMeta屬性的類型生成Defaulter相關(guān)函數(shù)時,其Tags形式如下:

為擁有ListMeta屬性的類型生成Defaulter相關(guān)函數(shù)時,其Tags形式如下:

為擁有ObjectMeta屬性的類型生成Defaulter相關(guān)函數(shù)時,其Tags形式如下:

defaulter-gen的Tags都屬于全局Tags,沒有局部Tags。其值可以為TypeMeta、ListMeta、ObjectMeta,最常用的是TypeMeta。有時在Kubernetes源碼里會看到defaulter-gen-input,這說明當(dāng)前包會依賴于指定的路徑包,代碼示例如下:

下面介紹defaulter-gen的使用示例和生成規(guī)則。
1.defaulter-gen的使用示例

構(gòu)建defaulter-gen二進(jìn)制文件,并執(zhí)行defaulter-gen代碼生成器,為k8s.io/kubernetes/pkg/apis/rbac/v1包生成zz_generated.defaults.go代碼文件。
2.defaulter-gen的生成規(guī)則
代碼路徑:k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go

defaulter-gen會遍歷包中的所有類型,若類型屬性擁有特定類型(如TypeMeta、ListMeta、ObjectMeta),則為該類型生成Defaulter函數(shù),并為其生成RegisterDefaults注冊函數(shù),代碼示例如下:
代碼路徑:pkg/apis/rbac/v1/defaults.go

生成的Defaults函數(shù)如下:
代碼路徑:pkg/apis/rbac/v1/zz_generated.defaults.go

在defaults.go中定義了rbacv1.ClusterRoleBinding類型,該類型擁有TypeMeta屬性,并為該屬性生成SetObjectDefaults_ClusterRoleBinding函數(shù)。
2.5.4 conversion-gen代碼生成器
conversion-gen是一個自動生成Convert函數(shù)的代碼生成器。給定一個包的目錄路徑作為輸入源,它可以為其生成Convert相關(guān)函數(shù),這些函數(shù)可以為對象在內(nèi)部和外部類型之間提供轉(zhuǎn)換函數(shù)。
為整個包生成Convert相關(guān)函數(shù)時,其Tags形式如下:

其中的<peer-pkg>用于定義包的導(dǎo)入路徑,例如k8s.io/kubernetes/pkg/apis/abac。
為整個包生成Convert相關(guān)函數(shù)且依賴其他包時,其Tags形式如下:

其中的<type-pkg>用于定義其他包的路徑,例如k8s.io/api/autoscaling/v1。
在排除某個屬性后生成Convert相關(guān)函數(shù)時,其Tags形式如下:

下面介紹conversion-gen的使用示例和生成規(guī)則。
1.conversion-gen的使用示例

構(gòu)建conversion-gen二進(jìn)制文件,并執(zhí)行conversion-gen代碼生成器,為k8s.io/kubernetes/pkg/apis/abac/v1beta1包生成zz_generated.conversion.go代碼文件。
2.conversion-gen的生成規(guī)則
代碼路徑:vendor/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go

conversion-gen會遍歷包中的所有類型,若類型為types.Struct且過濾掉了私有的Struct類型,則為該類型生成Convert函數(shù),并為該類型同時生成RegisterConversions注冊函數(shù),代碼示例如下:
代碼路徑:pkg/apis/abac/v1beta1/types.go

生成的Convert函數(shù)如下:
代碼路徑:pkg/apis/abac/v1beta1/zz_generated.conversion.go

在types.go中定義了Policy類型,conversion-gen為該類型生成了Convert函數(shù),例如從v1beta1轉(zhuǎn)換為internal內(nèi)部版本,從internal內(nèi)部版本轉(zhuǎn)換為v1版本,代碼示例如下:

定義old變量為v1beta1資源版本,通過Convert函數(shù)將v1beta1版本轉(zhuǎn)換為內(nèi)部版本(即internal變量)。
2.5.5 openapi-gen代碼生成器
openapi-gen是一個自動生成OpenAPI定義文件(OpenAPI Definition File)的代碼生成器,給定一個包的目錄路徑作為輸入源,它可以為其生成OpenAPI定義文件,該文件用于kube-apiserver服務(wù)上的OpenAPI規(guī)范的生成。更多關(guān)于OpenAPI規(guī)范的內(nèi)容,詳情請參考7.1.3節(jié)“OpenAPI/Swagger核心原理”。
為特定類型或包生成OpenAPI定義文件時,其Tags形式如下:

排除為特定類型或包生成OpenAPI定義文件時,其Tags形式如下:

下面介紹openapi-gen的使用示例和生成規(guī)則。
1.openapi-gen的使用示例

構(gòu)建openapi-gen二進(jìn)制文件,并執(zhí)行openapi-gen代碼生成器,為k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1包生成zz_generated.openapi.go代碼文件,該代碼文件存放在k8s.io/kubernetes/pkg/generated/openapi目錄下。
2.openapi-gen的生成規(guī)則
代碼路徑:vendor/k8s.io/kube-openapi/pkg/generators/openapi.go

openapi-gen會遍歷包中的所有類型,若類型為types.Struct并忽略其他類型,則為types.Struct類型生成OpenAPI定義文件。例如:
代碼路徑:vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go

生成的OpenAPIDefinition如下:
代碼路徑:pkg/generated/openapi/zz_generated.openapi.go

在types.go中定義了CustomResourceDefinitionSpec類型,openapi-gen為該類型生成了OpenAPIDefinition。
2.5.6 go-bindata代碼生成器
go-bindata是一個第三方工具,它能夠?qū)㈧o態(tài)資源文件嵌入Go語言中,例如在Web開發(fā)中,它可以將靜態(tài)的HTML、JavaScript等靜態(tài)資源文件嵌入Go語言代碼文件中并提供一些操作方法。給定一個靜態(tài)資源目錄路徑作為輸入源,go-bindata可以為其生成go文件。go-bindata使用示例如下:

generate-bindata.sh腳本重點(diǎn)執(zhí)行如下代碼:

構(gòu)建go-bindata二進(jìn)制文件,并執(zhí)行g(shù)o-bindata代碼生成器,為translations靜態(tài)資源目錄生成pkg/kubectl/generated/bindata.go.tmp文件。translations目錄存放的是與i18n(國際化)語言包相關(guān)的文件,在不修改內(nèi)部代碼的情況下支持不同語言及地區(qū)。例如,Zh語言包的二進(jìn)制數(shù)據(jù)在Go語言中的存儲內(nèi)容如下:
代碼路徑:pkg/kubectl/generated/bindata.go

- SoapUI Cookbook
- Visual Basic程序開發(fā)(學(xué)習(xí)筆記)
- C/C++算法從菜鳥到達(dá)人
- AIRAndroid應(yīng)用開發(fā)實(shí)戰(zhàn)
- Mastering LibGDX Game Development
- The DevOps 2.5 Toolkit
- C++新經(jīng)典
- PHP 7+MySQL 8動態(tài)網(wǎng)站開發(fā)從入門到精通(視頻教學(xué)版)
- 深度學(xué)習(xí):Java語言實(shí)現(xiàn)
- Learning Bootstrap 4(Second Edition)
- OpenCV 3.0 Computer Vision with Java
- 基于MATLAB的控制系統(tǒng)仿真及應(yīng)用
- Clojure編程樂趣
- Mastering Unity 2017 Game Development with C#(Second Edition)
- Java EE互聯(lián)網(wǎng)輕量級框架整合開發(fā):SSM+Redis+Spring微服務(wù)(上下冊)