From 11fcace0c4d5c7c803dddb81b0c6ebafa69e768f Mon Sep 17 00:00:00 2001 From: JenTing Hsiao Date: Fri, 9 Jul 2021 13:23:19 +0800 Subject: [PATCH] Update script to generate both v1beta1 and v1 CRDs Signed-off-by: JenTing Hsiao --- hack/crd-gen/v1/main.go | 136 ++++++++++++++++++ hack/crd-gen/{ => v1beta1}/main.go | 8 +- hack/restore-crd-patch-v1.json | 3 + ...ch.json => restore-crd-patch-v1beta1.json} | 0 hack/update-generated-crd-code.sh | 36 ++--- hack/verify-generated-crd-code.sh | 19 +-- 6 files changed, 174 insertions(+), 28 deletions(-) create mode 100644 hack/crd-gen/v1/main.go rename hack/crd-gen/{ => v1beta1}/main.go (93%) create mode 100644 hack/restore-crd-patch-v1.json rename hack/{restore-crd-patch.json => restore-crd-patch-v1beta1.json} (100%) diff --git a/hack/crd-gen/v1/main.go b/hack/crd-gen/v1/main.go new file mode 100644 index 000000000..9bb05a400 --- /dev/null +++ b/hack/crd-gen/v1/main.go @@ -0,0 +1,136 @@ +/* +Copyright the Velero contributors. + +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 code embeds the CRD manifests in config/crd/v1/bases in +// config/crd/v1/crds/crds.go. + +package main + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "text/template" +) + +// This is relative to config/crd/crds +const goHeaderFile = "../../../../hack/boilerplate.go.txt" + +const tpl = `{{.GoHeader}} +// Code generated by crds_generate.go; DO NOT EDIT. + +package crds + +import ( + "bytes" + "compress/gzip" + "io/ioutil" + + apiextinstall "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/client-go/kubernetes/scheme" +) + +var rawCRDs = [][]byte{ +{{- range .RawCRDs }} + []byte({{ . }}), +{{- end }} +} + +var CRDs = crds() + +func crds() []*apiextv1.CustomResourceDefinition { + apiextinstall.Install(scheme.Scheme) + decode := scheme.Codecs.UniversalDeserializer().Decode + var objs []*apiextv1.CustomResourceDefinition + for _, crd := range rawCRDs { + gzr, err := gzip.NewReader(bytes.NewReader(crd)) + if err != nil { + panic(err) + } + bytes, err := ioutil.ReadAll(gzr) + if err != nil { + panic(err) + } + gzr.Close() + + obj, _, err := decode(bytes, nil, nil) + if err != nil { + panic(err) + } + objs = append(objs, obj.(*apiextv1.CustomResourceDefinition)) + } + return objs +} +` + +type templateData struct { + GoHeader string + RawCRDs []string +} + +func main() { + headerBytes, err := ioutil.ReadFile(goHeaderFile) + if err != nil { + log.Fatalln(err) + } + + data := templateData{ + GoHeader: string(headerBytes), + } + + // This is relative to config/crd/crds + manifests, err := ioutil.ReadDir("../bases") + if err != nil { + log.Fatalln(err) + } + + for _, crd := range manifests { + file, err := os.Open("../bases/" + crd.Name()) + if err != nil { + log.Fatalln(err) + } + + // gzip compress manifest + var buf bytes.Buffer + gzw := gzip.NewWriter(&buf) + if _, err := io.Copy(gzw, file); err != nil { + log.Fatalln(err) + } + file.Close() + gzw.Close() + + data.RawCRDs = append(data.RawCRDs, fmt.Sprintf("%q", buf.Bytes())) + } + + t, err := template.New("crd").Parse(tpl) + if err != nil { + log.Fatalln(err) + } + + out, err := os.Create("crds.go") + if err != nil { + log.Fatalln(err) + } + + if err := t.Execute(out, data); err != nil { + log.Fatalln(err) + } +} diff --git a/hack/crd-gen/main.go b/hack/crd-gen/v1beta1/main.go similarity index 93% rename from hack/crd-gen/main.go rename to hack/crd-gen/v1beta1/main.go index 4b44990aa..2f204a0d2 100644 --- a/hack/crd-gen/main.go +++ b/hack/crd-gen/v1beta1/main.go @@ -1,5 +1,5 @@ /* -Copyright 2019 the Velero contributors. +Copyright the Velero contributors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This code embeds the CRD manifests in config/crd/bases in -// config/crd/crds/crds.go. +// This code embeds the CRD manifests in config/crd/v1beta1/bases in +// config/crd/v1beta1/crds/crds.go. package main @@ -31,7 +31,7 @@ import ( ) // This is relative to config/crd/crds -const goHeaderFile = "../../../hack/boilerplate.go.txt" +const goHeaderFile = "../../../../hack/boilerplate.go.txt" const tpl = `{{.GoHeader}} // Code generated by crds_generate.go; DO NOT EDIT. diff --git a/hack/restore-crd-patch-v1.json b/hack/restore-crd-patch-v1.json new file mode 100644 index 000000000..b8b729d0d --- /dev/null +++ b/hack/restore-crd-patch-v1.json @@ -0,0 +1,3 @@ +[ + { "op": "replace", "path": "/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/hooks/properties/resources/items/properties/postHooks/items/properties/init/properties/initContainers/items/properties/ports/items/required", "value": [ "containerPort", "protocol"] } +] diff --git a/hack/restore-crd-patch.json b/hack/restore-crd-patch-v1beta1.json similarity index 100% rename from hack/restore-crd-patch.json rename to hack/restore-crd-patch-v1beta1.json diff --git a/hack/update-generated-crd-code.sh b/hack/update-generated-crd-code.sh index 193fa121c..35bd93927 100755 --- a/hack/update-generated-crd-code.sh +++ b/hack/update-generated-crd-code.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2017 the Velero contributors. +# Copyright the Velero contributors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -44,20 +44,24 @@ ${GOPATH}/src/k8s.io/code-generator/generate-groups.sh \ --output-base ../../.. \ $@ -# Generate manifests e.g. CRD, RBAC etc. -controller-gen \ - crd:crdVersions=v1beta1,preserveUnknownFields=false,trivialVersions=true \ - paths=./pkg/apis/velero/v1/... \ - paths=./pkg/controller/... \ - output:crd:artifacts:config=config/crd/bases +# Generate both apiextensions.k8s.io/v1beta1 and apiextensions.k8s.io/v1 +for version in v1beta1 v1 +do + # Generate manifests e.g. CRD, RBAC etc. + controller-gen \ + crd:crdVersions=$version,preserveUnknownFields=false,trivialVersions=true \ + paths=./pkg/apis/velero/v1/... \ + paths=./pkg/controller/... \ + output:crd:artifacts:config=config/crd/$version/bases -# this is a super hacky workaround for https://github.com/kubernetes/kubernetes/issues/91395 -# which a result of fixing the validation on CRD objects. The validation ensures the fields that are list map keys, are either marked -# as required or have default values to ensure merging of list map items work as expected. -# With "containerPort" and "protocol" being considered as x-kubernetes-list-map-keys in the container ports, and "protocol" was not -# a required field, the CRD would fail validation with errors similar to the one reported in https://github.com/kubernetes/kubernetes/issues/91395. -# once controller-gen (above) is able to generate CRDs with `protocol` as a required field, this hack can be removed. -kubectl patch -f config/crd/bases/velero.io_restores.yaml -p "$(cat hack/restore-crd-patch.json)" --type=json --local=true -o yaml > /tmp/velero.io_restores-yaml.patched -mv /tmp/velero.io_restores-yaml.patched config/crd/bases/velero.io_restores.yaml + # this is a super hacky workaround for https://github.com/kubernetes/kubernetes/issues/91395 + # which a result of fixing the validation on CRD objects. The validation ensures the fields that are list map keys, are either marked + # as required or have default values to ensure merging of list map items work as expected. + # With "containerPort" and "protocol" being considered as x-kubernetes-list-map-keys in the container ports, and "protocol" was not + # a required field, the CRD would fail validation with errors similar to the one reported in https://github.com/kubernetes/kubernetes/issues/91395. + # once controller-gen (above) is able to generate CRDs with `protocol` as a required field, this hack can be removed. + kubectl patch -f config/crd/$version/bases/velero.io_restores.yaml -p "$(cat hack/restore-crd-patch-$version.json)" --type=json --local=true -o yaml > /tmp/velero.io_restores-yaml.patched + mv /tmp/velero.io_restores-yaml.patched config/crd/$version/bases/velero.io_restores.yaml -go generate ./config/crd/crds + go generate ./config/crd/$version/crds +done diff --git a/hack/verify-generated-crd-code.sh b/hack/verify-generated-crd-code.sh index 287522db3..90d1f04b9 100755 --- a/hack/verify-generated-crd-code.sh +++ b/hack/verify-generated-crd-code.sh @@ -1,6 +1,6 @@ #!/bin/bash -e # -# Copyright 2017 the Velero contributors. +# Copyright the Velero contributors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,11 +19,14 @@ HACK_DIR=$(dirname "${BASH_SOURCE}") ${HACK_DIR}/update-generated-crd-code.sh --verify-only # ensure no changes to generated CRDs -if ! git diff --exit-code config/crd/crds/crds.go >/dev/null; then - # revert changes to state before running CRD generation to stay consistent - # with code-generator `--verify-only` option which discards generated changes - git checkout config/crd +for version in v1beta1 v1 +do + if ! git diff --exit-code config/crd/$version/crds/crds.go >/dev/null; then + # revert changes to state before running CRD generation to stay consistent + # with code-generator `--verify-only` option which discards generated changes + git checkout config/crd - echo "CRD verification - failed! Generated CRDs are out-of-date, please run 'make update' and 'git add' the generated file(s)." - exit 1 -fi \ No newline at end of file + echo "CRD verification - failed! Generated CRDs are out-of-date, please run 'make update' and 'git add' the generated file(s)." + exit 1 + fi +done