AmitKumarDas/Decisions

K8s: Code Generation for CR ~ Makefile

AmitKumarDas opened this issue ยท 1 comments

Steps below show how to generate all the code required to build controllers against custom resources:

  • This is how your project should look like.
    • This is old go setup. In other words non modules way.
    • ๐Ÿค“ Remember to add the doc.go file else deepcopy may not work.
  v1alpha1 > echo $GOPATH
/home/amit/work

  v1alpha1 > pwd
/home/amit/work/src/github.com/AmitKumarDas/storage-provisioner/pkg/apis/ddp/v1alpha1

  v1alpha1 > tree
.
โ”œโ”€โ”€ doc.go
โ”œโ”€โ”€ register.go
โ”œโ”€โ”€ types.go
  • This is how your doc.go should look like:
// +k8s:deepcopy-gen=package
// +groupName=ddp.mayadata.io

package v1alpha1
  • This is how your types.go look like:
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type Storage struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`

	Spec   StorageSpec   `json:"spec"`
	Status StorageStatus `json:"status,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type StorageList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []Storage `json:"items"`
}
  • This needs to be added against Gopkg.toml (i.e. dep way & not go mod way)
# Adding the generators here allows us to pin them to a particular version.
required = [
  "k8s.io/code-generator/cmd/deepcopy-gen",
  "k8s.io/code-generator/cmd/client-gen",
  "k8s.io/code-generator/cmd/lister-gen",
  "k8s.io/code-generator/cmd/informer-gen"
  ]
  • This is how your Makefile should look like:
PROJECT_ROOT := github.com/AmitKumarDas/storage-provisioner
PKG          := $(PROJECT_ROOT)/pkg
API_GROUPS   := ddp/v1alpha1

.PHONY: generated_files
generated_files: deepcopy clientset lister informer

# deepcopy installs the deepcopy-gen at $GOPATH/bin
# Then make use of this installed binary to generate
# deepcopy
.PHONY: deepcopy
deepcopy:
	@go install ./vendor/k8s.io/code-generator/cmd/deepcopy-gen
	@echo "+ Generating deepcopy funcs for $(API_GROUPS)"
	@deepcopy-gen \
		--input-dirs $(PKG)/apis/$(API_GROUPS) \
		--output-file-base zz_generated.deepcopy \
		--go-header-file ./hack/custom-boilerplate.go.txt

# clienset installs the client-gen at $GOPATH/bin
# Then make use of this installed binary to generate
# clienset
.PHONY: clientset
clientset:
	@go install ./vendor/k8s.io/code-generator/cmd/client-gen
	@echo "+ Generating clientsets for $(API_GROUPS)"
	@client-gen \
		--fake-clientset=false \
		--input $(API_GROUPS) \
		--input-base $(PKG)/apis \
		--go-header-file ./hack/custom-boilerplate.go.txt \
		--clientset-path $(PKG)/client/generated/clientset

# lister installs the lister-gen at $GOPATH/bin
# Then make use of this installed binary to generate
# lister
.PHONY: lister
lister:
	@go install ./vendor/k8s.io/code-generator/cmd/lister-gen
	@echo "+ Generating lister for $(API_GROUPS)"
	@lister-gen \
		--input-dirs $(PKG)/apis/$(API_GROUPS) \
		--go-header-file ./hack/custom-boilerplate.go.txt \
		--output-package $(PKG)/client/generated/lister

# informer installs the informer-gen at $GOPATH/bin
# Then make use of this installed binary to generate
# informer
.PHONY: informer
informer:
	@go install ./vendor/k8s.io/code-generator/cmd/informer-gen
	@echo "+ Generating informer for $(API_GROUPS)"
	@informer-gen \
		--input-dirs $(PKG)/apis/$(API_GROUPS) \
		--output-package $(PKG)/client/generated/informer \
		--versioned-clientset-package $(PKG)/client/generated/clientset/internalclientset \
		--go-header-file ./hack/custom-boilerplate.go.txt \
		--listers-package $(PKG)/client/generated/lister

This snippet shows code generation for custom resources via go modules & makefile:

PROJECT_ROOT := github.com/AmitKumarDas/storage-provisioner
PKG          := $(PROJECT_ROOT)/pkg
API_GROUPS   := ddp/v1alpha1

# I prefer using makefile targets instead of ./hack/update-codegen.sh
# since makefile based targets are more manageable than script based 
# approach. There are some differences between two approaches. 
#
# Makefile uses informer & lister as output package names instead of 
# plural forms i.e. informers & listers.
.PHONY: generated_files
generated_files: vendor deepcopy clientset lister informer

# deepcopy expects client-gen source code to be available at the 
# given vendor location. This source code is installed as a binary 
# i.e. deepcopy-gen at $GOPATH/bin
#
# Finally this installed binary is used to generate deepcopy
.PHONY: deepcopy
deepcopy:
	@GO111MODULE=on go install k8s.io/code-generator/cmd/deepcopy-gen
	@echo "+ Generating deepcopy funcs for $(API_GROUPS)"
	@deepcopy-gen \
		--input-dirs $(PKG)/apis/$(API_GROUPS) \
		--output-file-base zz_generated.deepcopy \
		--go-header-file ./hack/custom-boilerplate.go.txt

# clienset expects client-gen source code to be available at the 
# given vendor location. This source code is installed as a binary 
# i.e. client-gen at $GOPATH/bin
#
# Finally this installed binary is used to generate clienset
.PHONY: clientset
clientset:
	@GO111MODULE=on go install k8s.io/code-generator/cmd/client-gen
	@echo "+ Generating clientset for $(API_GROUPS)"
	@client-gen \
		--fake-clientset=false \
		--input $(API_GROUPS) \
		--input-base $(PKG)/apis \
		--go-header-file ./hack/custom-boilerplate.go.txt \
		--clientset-name versioned \
		--clientset-path $(PROJECT_ROOT)/client/generated/clientset

# lister expects client-gen source code to be available at the 
# given vendor location. This source code is installed as a binary 
# i.e. lister-gen at $GOPATH/bin
#
# Finally this installed binary is used to generate lister
.PHONY: lister
lister:
	@GO111MODULE=on go install k8s.io/code-generator/cmd/lister-gen
	@echo "+ Generating lister for $(API_GROUPS)"
	@lister-gen \
		--input-dirs $(PKG)/apis/$(API_GROUPS) \
		--go-header-file ./hack/custom-boilerplate.go.txt \
		--output-package $(PROJECT_ROOT)/client/generated/lister

# informer expects client-gen source code to be available at the 
# given vendor location. This source code is installed as a binary 
# i.e. informer-gen at $GOPATH/bin
#
# Finally this installed binary is used to generate informer
.PHONY: informer
informer:
	@GO111MODULE=on go install k8s.io/code-generator/cmd/informer-gen
	@echo "+ Generating informer for $(API_GROUPS)"
	@informer-gen \
		--input-dirs $(PKG)/apis/$(API_GROUPS) \
		--output-package $(PROJECT_ROOT)/client/generated/informer \
		--versioned-clientset-package $(PROJECT_ROOT)/client/generated/clientset/versioned \
		--go-header-file ./hack/custom-boilerplate.go.txt \
		--listers-package $(PROJECT_ROOT)/client/generated/lister