API Upgrade Instructions
It's normal and inevitable to move CRD APIs to newer versions as the project
moves to a more stable stage. This doc lists the steps for the first version
bump-up from v1alpha1 to v1beta1, which can be referenced when we need to have
new API versions in the future.
Upgrade steps from v1alpha1 to v1beta1
Controller-runtime models conversion between versions in terms of a "hub and spoke" model. In Ratify, we mark the
unversionedas the hub version, other versions(v1alpha1andv1beta1) as spoke versions. New versions would be added as spoke versions.Create new API version by
kubebuildercommand:
kubebuilder create api --group config.ratify.deislabs.io --version v1beta1 --kind <kind>
kind could be Store, Verifier and CertificateStore respectively.
Copy over existing types from
v1alpha1tov1beta1.Create an
unversionedAPI by manually copying the existing types fromv1alpha1tounversionedaskubebuilderdoesn't supportunversionedas version value.In each spoke version package, add marker
+k8s:conversion-gendirective pointing to the hub(unversioned) version, which must be indoc.go. Example:
// +k8s:conversion-gen=github.com/deislabs/ratify/api/unversioned
package v1alpha1
- In hub(
unversioned) version package, createdoc.goand add marker+kubebuilder:object:generate=trueso that the object generator can use it. Example:
package unversioned
// +kubebuilder:object:generate=true
In spoke version packages, add a
localSchemeBuilder = runtime.NewSchemeBuilder(SchemeBuilder.AddToScheme)ingroupversion_info.goso the auto-generated code could compile.In hub(
unversioned) version package, add marker+kubebuilder:skipto each API and remove all other markers so that skip kubebuilder processing it.Mark
v1beta1as the storage version by adding marker+kubebuilder:storageversionto the root types. Example:
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:storageversion
// Store is the Schema for the stores API
type Store struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec StoreSpec `json:"spec,omitempty"`
Status StoreStatus `json:"status,omitempty"`
}
- In the outdated spoke version package, add marker
+kubebuilder:deprecatedversion:warning=<msg>to the root type of each API. Example:
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:deprecatedversion:warning="v1alpha1 of the Store API has been deprecated. Please migrate to v1beta1."
// Store is the Schema for the stores API
type Store struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec StoreSpec `json:"spec,omitempty"`
Status StoreStatus `json:"status,omitempty"`
}
- Run
make manifests generateto generate CRD objects, DeepCopy methods and conversion methods.zz_generated.conversion.goandzz_generated.deepcopy.gowould be generated in each spoke version package.
Additional steps while incompatibilities introduced
There is no real change between v1alpha1 and v1beta1, which makes it easier
than making incompatible upgrade. If there is an incompatible change introduced
in a new version, we could follow the above 11 steps first and then follow the
below instruction. Let's take the example of adding a new Test field to StoreSpec.
Add a string field
TesttoStoreSpecin bothunversionedand new version(v1beta1) packages.After executing
make manifests generate, we would get errors similar to:
E0308 02:20:37.752749 4053005 conversion.go:756] Warning: could not find nor generate a final Conversion function for github.com/deislabs/ratify/api/unversioned.StoreSpec -> github.com/binbin-li/ratify/api/v1alpha1.StoreSpec
E0308 02:20:37.752867 4053005 conversion.go:757] the following fields need manual conversion:
E0308 02:20:37.752874 4053005 conversion.go:759] - Test
It means that we need to manually implement the conversion method from unversioned
to v1alpha1.
- Check the generated
zz_generated.conversion.goinv1alpha1package, we could see errors indicating thatConvert_unversioned_StoreSpec_To_v1alpha1_StoreSpec()was not declared. Now we could create a new filestore_conversion.goinv1alpha1package, and implement this method manually there to resolve the error.
Upgrade existing objects to a new stored version
It's safe to use both the old and new versions after upgraded. But if we really want to migrate stored objects to the new version, please follow the instruction: Upgrade existing objects to a new stored version
References
Kubebuilder tutorial on multi-version API