code-generator: turn hack/update-codegen.sh into re-usable generate-{internal,}-groups.sh scripts

pull/6/head
Dr. Stefan Schimanski 2017-09-20 15:37:36 +02:00
parent 8a98063eab
commit cba2c0967f
15 changed files with 383 additions and 67 deletions

View File

@ -15,5 +15,5 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +groupName=testgroup.k8s.io
package testgroup // import "k8s.io/code-generator/_test/apis/testgroup"
// +groupName=example.apiserver.code-generator.k8s.io
package example // import "k8s.io/code-generator/_examples/apiserver/apis/example"

View File

@ -22,17 +22,17 @@ import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/code-generator/_examples/apis/testgroup"
"k8s.io/code-generator/_examples/apis/testgroup/v1"
"k8s.io/code-generator/_examples/apiserver/apis/example"
"k8s.io/code-generator/_examples/apiserver/apis/example/v1"
)
// Install registers the API group and adds types to a scheme
func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: testgroup.SchemeGroupVersion.Group,
GroupName: example.SchemeGroupVersion.Group,
VersionPreferenceOrder: []string{v1.SchemeGroupVersion.Version},
AddInternalObjectsToScheme: testgroup.AddToScheme,
AddInternalObjectsToScheme: example.AddToScheme,
},
announced.VersionToSchemeFunc{
v1.SchemeGroupVersion.Version: v1.AddToScheme,

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package testgroup
package example
import (
"k8s.io/apimachinery/pkg/runtime"

View File

@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package testgroup
package example
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TestType is a top-level type. A client is created for it.
type TestType struct {
metav1.TypeMeta
metav1.ObjectMeta
@ -29,6 +30,8 @@ type TestType struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TestTypeList is a top-level list type. The client methods for lists are automatically created.
// You are not supposed to create a separated client for this one.
type TestTypeList struct {
metav1.TypeMeta
metav1.ListMeta

View File

@ -0,0 +1,20 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=k8s.io/code-generator/_examples/apiserver/apis/example
// +groupName=example.apiserver.code-generator.k8s.io
package v1

View File

@ -0,0 +1,59 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var SchemeGroupVersion = schema.GroupVersion{Group: "example.apiserver.code-generator.k8s.io", Version: "v1"}
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&TestType{},
&TestTypeList{},
)
scheme.AddKnownTypes(SchemeGroupVersion,
&metav1.Status{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@ -21,6 +21,7 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TestType is a top-level type. A client is created for it.
type TestType struct {
metav1.TypeMeta `json:",inline"`
// +optional
@ -31,6 +32,8 @@ type TestType struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TestTypeList is a top-level list type. The client methods for lists are automatically created.
// You are not supposed to create a separated client for this one.
type TestTypeList struct {
metav1.TypeMeta `json:",inline"`
// +optional

View File

@ -0,0 +1,32 @@
// +build !ignore_autogenerated
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by defaulter-gen. Do not edit it manually!
package v1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
return nil
}

View File

@ -15,5 +15,5 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +groupName=testgroup.k8s.io
// +groupName=example.crd.code-generator.k8s.io
package v1

View File

@ -22,7 +22,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
)
var SchemeGroupVersion = schema.GroupVersion{Group: "testgroup.k8s.io", Version: "v1"}
var SchemeGroupVersion = schema.GroupVersion{Group: "example.crd.code-generator.k8s.io", Version: "v1"}
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.

View File

@ -0,0 +1,47 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TestType is a top-level type. A client is created for it.
type TestType struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// +optional
Status TestTypeStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// TestTypeList is a top-level list type. The client methods for lists are automatically created.
// You are not supposed to create a separated client for this one.
type TestTypeList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []TestType `json:"items"`
}
type TestTypeStatus struct {
Blah string
}

View File

@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit
set -o nounset
set -o pipefail
# generate-groups generates everything for a project with external types only, e.g. a project based
# on CustomResourceDefinitions.
if [ "$#" -le 4 ] || [ "${1}" == "--help" ]; then
cat <<EOF
Usage: $(basename $0) <generators> <output-package> <apis-package> <groups-versions> ...
<generators> the generators comma separated to run (deepcopy,defaulter,client,lister,informer) or "all".
<output-package> the output package name (e.g. github.com/example/project/pkg/generated).
<apis-package> the external types dir (e.g. github.com/example/api or github.com/example/project/pkg/apis).
<groups-versions> the groups and their versions in the format "groupA:v1,v2 groupB:v1 groupC:v2", relative
to <api-package>.
... arbitrary flags passed to all generator binaries.
Examples:
$(basename $0) all github.com/example/project/pkg/client github.com/example/project/pkg/apis "foo:v1 bar:v1alpha1,v1beta1"
$(basename $0) deepcopy,client github.com/example/project/pkg/client github.com/example/project/pkg/apis "foo:v1 bar:v1alpha1,v1beta1"
EOF
exit 0
fi
GENS="$1"
OUTPUT_PKG="$2"
APIS_PKG="$3"
GROUPS_WITH_VERSIONS="$4"
shift 4
go install ./$(dirname "${0}")/cmd/{defaulter-gen,client-gen,lister-gen,informer-gen,deepcopy-gen}
function codegen::join() { local IFS="$1"; shift; echo "$*"; }
# enumerate group versions
FQ_APIS=() # e.g. k8s.io/api/apps/v1
for GVs in ${GROUPS_WITH_VERSIONS}; do
IFS=: read G Vs <<<"${GVs}"
# enumerate versions
for V in ${Vs//,/ }; do
FQ_APIS+=(${APIS_PKG}/${G}/${V})
done
done
if [ "${GENS}" = "all" ] || grep -qw "deepcopy" <<<"${GENS}"; then
echo "Generating deepcopy funcs"
${GOPATH}/bin/deepcopy-gen --input-dirs $(codegen::join , "${FQ_APIS[@]}") -O zz_generated.deepcopy --bounding-dirs ${APIS_PKG} "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then
echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset"
${GOPATH}/bin/client-gen --clientset-name versioned --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --clientset-path ${OUTPUT_PKG}/clientset "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then
echo "Generating listers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/listers"
${GOPATH}/bin/lister-gen --input-dirs $(codegen::join , "${FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/listers "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then
echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers"
${GOPATH}/bin/informer-gen \
--input-dirs $(codegen::join , "${FQ_APIS[@]}") \
--versioned-clientset-package ${OUTPUT_PKG}/clientset/versioned \
--listers-package ${OUTPUT_PKG}/listers \
--output-package ${OUTPUT_PKG}/informers \
"$@"
fi

View File

@ -0,0 +1,109 @@
#!/usr/bin/env bash
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit
set -o nounset
set -o pipefail
# generate-internal-groups generates everything for a project with internal types, e.g. an
# user-provided API server based on k8s.io/apiserver.
if [ "$#" -le 5 ] || [ "${1}" == "--help" ]; then
cat <<EOF
Usage: $(basename $0) <generators> <output-package> <internal-apis-package> <extensiona-apis-package> <groups-versions> ...
<generators> the generators comma separated to run (deepcopy,defaulter,conversion,client,lister,informer) or "all".
<output-package> the output package name (e.g. github.com/example/project/pkg/generated).
<int-apis-package> the internal types dir (e.g. github.com/example/project/pkg/apis).
<ext-apis-package> the external types dir (e.g. github.com/example/project/pkg/apis or githubcom/example/apis).
<groups-versions> the groups and their versions in the format "groupA:v1,v2 groupB:v1 groupC:v2", relative
to <api-package>.
... arbitrary flags passed to all generator binaries.
Examples:
$(basename $0) all github.com/example/project/pkg/client github.com/example/project/pkg/apis github.com/example/project/pkg/apis "foo:v1 bar:v1alpha1,v1beta1"
$(basename $0) deepcopy,defaulter,conversion github.com/example/project/pkg/client github.com/example/project/pkg/apis github.com/example/project/apis "foo:v1 bar:v1alpha1,v1beta1"
EOF
exit 0
fi
GENS="$1"
OUTPUT_PKG="$2"
INT_APIS_PKG="$3"
EXT_APIS_PKG="$4"
GROUPS_WITH_VERSIONS="$5"
shift 5
go install ./$(dirname "${0}")/cmd/{defaulter-gen,conversion-gen,client-gen,lister-gen,informer-gen,deepcopy-gen}
function codegen::join() { local IFS="$1"; shift; echo "$*"; }
# enumerate group versions
ALL_FQ_APIS=() # e.g. k8s.io/kubernetes/pkg/apis/apps k8s.io/api/apps/v1
INT_FQ_APIS=() # e.g. k8s.io/kubernetes/pkg/apis/apps
EXT_FQ_APIS=() # e.g. k8s.io/api/apps/v1
for GVs in ${GROUPS_WITH_VERSIONS}; do
IFS=: read G Vs <<<"${GVs}"
if [ -n "${INT_APIS_PKG}" ]; then
ALL_FQ_APIS+=("${INT_APIS_PKG}/${G}")
INT_FQ_APIS+=("${INT_APIS_PKG}/${G}")
fi
# enumerate versions
for V in ${Vs//,/ }; do
ALL_FQ_APIS+=("${EXT_APIS_PKG}/${G}/${V}")
EXT_FQ_APIS+=("${EXT_APIS_PKG}/${G}/${V}")
done
done
if [ "${GENS}" = "all" ] || grep -qw "deepcopy" <<<"${GENS}"; then
echo "Generating deepcopy funcs"
${GOPATH}/bin/deepcopy-gen --input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") -O zz_generated.deepcopy --bounding-dirs ${INT_APIS_PKG},${EXT_APIS_PKG} "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "defaulter" <<<"${GENS}"; then
echo "Generating defaulters"
${GOPATH}/bin/defaulter-gen --input-dirs $(codegen::join , "${EXT_FQ_APIS[@]}") -O zz_generated.defaults "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "conversion" <<<"${GENS}"; then
echo "Generating conversions"
${GOPATH}/bin/conversion-gen --input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") -O zz_generated.conversion "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then
echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset"
if [ -n "${INT_APIS_PKG}" ]; then
${GOPATH}/bin/client-gen --clientset-name internalversion --input-base "" --input $(codegen::join "/," "${INT_FQ_APIS[@]}")/ --clientset-path ${OUTPUT_PKG}/clientset "$@"
fi
${GOPATH}/bin/client-gen --clientset-name versioned --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --clientset-path ${OUTPUT_PKG}/clientset "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then
echo "Generating listers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/listers"
${GOPATH}/bin/lister-gen --input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/listers "$@"
fi
if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then
echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers"
${GOPATH}/bin/informer-gen \
--input-dirs $(codegen::join , "${ALL_FQ_APIS[@]}") \
--versioned-clientset-package ${OUTPUT_PKG}/clientset/versioned \
--internal-clientset-package ${OUTPUT_PKG}/clientset/internalversion \
--listers-package ${OUTPUT_PKG}/listers \
--output-package ${OUTPUT_PKG}/informers \
"$@"
fi

View File

@ -18,58 +18,15 @@ set -o errexit
set -o nounset
set -o pipefail
SCRIPT_PACKAGE=k8s.io/code-generator
SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/..
SCRIPT_BASE=${SCRIPT_ROOT}/../..
CODEGEN_PKG=${CODEGEN_PKG:-$(ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo "k8s.io/code-generator")}
clientgen="${PWD}/client-gen-binary"
listergen="${PWD}/lister-gen"
informergen="${PWD}/informer-gen"
# Register function to be called on EXIT to remove generated binary.
function cleanup {
rm -f "${clientgen:-}"
rm -f "${listergen:-}"
rm -f "${informergen:-}"
}
trap cleanup EXIT
function generate_group() {
local GROUP_NAME=$1
local VERSION=$2
local CLIENT_PKG=${SCRIPT_PACKAGE}/_test/clientset
local LISTERS_PKG=${SCRIPT_PACKAGE}/_test/listers
local INFORMERS_PKG=${SCRIPT_PACKAGE}/_test/informers
local APIS_PKG=${SCRIPT_PACKAGE}/_test/apis
local INPUT_APIS=(
${GROUP_NAME}/
${GROUP_NAME}/${VERSION}
)
echo "Building client-gen"
go build -o "${clientgen}" ${CODEGEN_PKG}/cmd/client-gen
echo "generating clientset for group ${GROUP_NAME} and version ${VERSION} at ${SCRIPT_BASE}/${CLIENT_PKG}"
${clientgen} --clientset-name="internal" --input-base ${APIS_PKG} --input ${INPUT_APIS[@]} --clientset-path ${CLIENT_PKG} --output-base=${SCRIPT_BASE}
${clientgen} --clientset-name="versioned" --input-base ${APIS_PKG} --input ${GROUP_NAME}/${VERSION} --clientset-path ${CLIENT_PKG} --output-base=${SCRIPT_BASE}
echo "Building lister-gen"
go build -o "${listergen}" ${CODEGEN_PKG}/cmd/lister-gen
echo "generating listers for group ${GROUP_NAME} and version ${VERSION} at ${SCRIPT_BASE}/${LISTERS_PKG}"
${listergen} --input-dirs ${APIS_PKG}/${GROUP_NAME} --input-dirs ${APIS_PKG}/${GROUP_NAME}/${VERSION} --output-package ${LISTERS_PKG} --output-base ${SCRIPT_BASE}
echo "Building informer-gen"
go build -o "${informergen}" ${CODEGEN_PKG}/cmd/informer-gen
echo "generating informers for group ${GROUP_NAME} and version ${VERSION} at ${SCRIPT_BASE}/${INFORMERS_PKG}"
${informergen} \
--input-dirs ${APIS_PKG}/${GROUP_NAME} --input-dirs ${APIS_PKG}/${GROUP_NAME}/${VERSION} \
--versioned-clientset-package ${CLIENT_PKG}/versioned \
--internal-clientset-package ${CLIENT_PKG}/internal \
--listers-package ${LISTERS_PKG} \
--output-package ${INFORMERS_PKG} \
--output-base ${SCRIPT_BASE}
}
generate_group testgroup v1
# generate the code with:
# - --output-base because this script should also be able to run inside the vendor dir of
# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
# instead of the $GOPATH directly. For normal projects this can be dropped.
$(dirname ${BASH_SOURCE})/../generate-internal-groups.sh all \
k8s.io/code-generator/_examples/apiserver k8s.io/code-generator/_examples/apiserver/apis k8s.io/code-generator/_examples/apiserver/apis \
example:v1 \
--output-base "$(dirname ${BASH_SOURCE})/../../.."
$(dirname ${BASH_SOURCE})/../generate-groups.sh all \
k8s.io/code-generator/_examples/crd k8s.io/code-generator/_examples/crd/apis \
example:v1 \
--output-base "$(dirname ${BASH_SOURCE})/../../.."

View File

@ -21,8 +21,8 @@ set -o pipefail
SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/..
SCRIPT_BASE=${SCRIPT_ROOT}/../..
DIFFROOT="${SCRIPT_ROOT}/_test"
TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/_test"
DIFFROOT="${SCRIPT_ROOT}/_examples"
TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/_examples"
_tmp="${SCRIPT_ROOT}/_tmp"
cleanup() {