Kubebuilder: Using conversion-gen with multi-versioning

Created on 27 May 2020  路  4Comments  路  Source: kubernetes-sigs/kubebuilder

Hi folks,
I have been wondering if there is an effective means for using conversion-gen to generate the conversions for the "rote conversions" as described at https://book.kubebuilder.io/multiversion-tutorial/conversion.html . It is of course possible to write up all conversions copying over most of the unchanged src spec to the dest but can get tedious (leading to typos !) with large CRDs with structure and repetitions across multiple versions. I did not see the multi-version examples use conversion-gen but it sounds like the tool that might help here. I am assuming other have been down this path. Thanks for any suggestions to make this simpler !

kinsupport lifecyclstale

Most helpful comment

This was the approach we took recently, it amounted to:

  1. In each spoke version packages, we added the +k8s:conversion-gen directive pointing to the hub version package (it must be in docs.go); we also added a var localSchemeBuilder = &SchemeBuilder.SchemeBuilder in groupversion_info.go so the auto-generated code would compile.
  2. Update the make file to run conversion-gen on the spoke versions to produce a zz_generated.conversion.go in the spoke version package.
  3. Add a {kind}_conversion.go to implement Convertible for each type. When conversion-gen stops generating methods because of incompatibilities or we need to override the behavior, we stick them in this source file.

When we implemented Convertible, we just used the local SchemeBuilder.Build() to get a new scheme (the auto-generated code will register the necessary conversion methods because of the variable declaration) and used it to call Convert; i.e.:

$(CONVERSION_GEN) --go-header-file "./hack/boilerplate.go.txt" --input-dirs "./api/{spokeversion}" \
        --output-base "." --output-file-base="zz_generated.conversion" --skip-unsafe=true
package {spokeversionpkg}

import (
    "{hubversionpkg}"
    "k8s.io/apimachinery/pkg/conversion"
    conv "sigs.k8s.io/controller-runtime/pkg/conversion"
)

var _ conv.Convertible = &MyKind{}

func (in *MyKind) ConvertTo(hub conv.Hub) error {
    s, err := SchemeBuilder.Build()
    if err != nil {
        return err
    }
    return s.Convert(in, hub.(*{hubversionpkg}.MyKind), nil)
}

func (in *MyKind) ConvertFrom(hub conv.Hub) error {
    s, err := SchemeBuilder.Build()
    if err != nil {
        return err
    }
    return s.Convert(hub.(*{hubversionpkg}.MyKind), in, nil)
}

All 4 comments

faced similar issue. writing that logic is too much error-prone. Appreciate any help

This was the approach we took recently, it amounted to:

  1. In each spoke version packages, we added the +k8s:conversion-gen directive pointing to the hub version package (it must be in docs.go); we also added a var localSchemeBuilder = &SchemeBuilder.SchemeBuilder in groupversion_info.go so the auto-generated code would compile.
  2. Update the make file to run conversion-gen on the spoke versions to produce a zz_generated.conversion.go in the spoke version package.
  3. Add a {kind}_conversion.go to implement Convertible for each type. When conversion-gen stops generating methods because of incompatibilities or we need to override the behavior, we stick them in this source file.

When we implemented Convertible, we just used the local SchemeBuilder.Build() to get a new scheme (the auto-generated code will register the necessary conversion methods because of the variable declaration) and used it to call Convert; i.e.:

$(CONVERSION_GEN) --go-header-file "./hack/boilerplate.go.txt" --input-dirs "./api/{spokeversion}" \
        --output-base "." --output-file-base="zz_generated.conversion" --skip-unsafe=true
package {spokeversionpkg}

import (
    "{hubversionpkg}"
    "k8s.io/apimachinery/pkg/conversion"
    conv "sigs.k8s.io/controller-runtime/pkg/conversion"
)

var _ conv.Convertible = &MyKind{}

func (in *MyKind) ConvertTo(hub conv.Hub) error {
    s, err := SchemeBuilder.Build()
    if err != nil {
        return err
    }
    return s.Convert(in, hub.(*{hubversionpkg}.MyKind), nil)
}

func (in *MyKind) ConvertFrom(hub conv.Hub) error {
    s, err := SchemeBuilder.Build()
    if err != nil {
        return err
    }
    return s.Convert(hub.(*{hubversionpkg}.MyKind), in, nil)
}

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

Shows that it was sorted out, so I am closing this one. however, please feel free to raise new issues and/or contributing to the project as well, for example, by raising a PR with a doc for that.

Was this page helpful?
0 / 5 - 0 ratings