官术网_书友最值得收藏!

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

主站蜘蛛池模板: 旬邑县| 赣州市| 健康| 江安县| 措美县| 晋江市| 龙胜| 色达县| 缙云县| 成都市| 泉州市| 米林县| 苏尼特左旗| 古交市| 莱芜市| 城步| 伊金霍洛旗| 焉耆| 丹阳市| 枣阳市| 平舆县| 谷城县| 乐安县| 隆安县| 逊克县| 红原县| 洛浦县| 德兴市| 偃师市| 得荣县| 云南省| 大兴区| 乌审旗| 汝城县| 青河县| 沈阳市| 南涧| 佳木斯市| 马公市| 黎城县| 乌拉特中旗|