api-upgrade-instruction
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
unversioned
as the hub version, other versions(v1alpha1
andv1beta1
) as spoke versions. New versions would be added as spoke versions.Create new API version by
kubebuilder
command:
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
v1alpha1
tov1beta1
.Create an
unversioned
API by manually copying the existing types fromv1alpha1
tounversioned
askubebuilder
doesn't supportunversioned
as version value.In each spoke version package, add marker
+k8s:conversion-gen
directive 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.go
and add marker+kubebuilder:object:generate=true
so 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.go
so the auto-generated code could compile.In hub(
unversioned
) version package, add marker+kubebuilder:skip
to each API and remove all other markers so that skip kubebuilder processing it.Mark
v1beta1
as the storage version by adding marker+kubebuilder:storageversion
to 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 generate
to generate CRD objects, DeepCopy methods and conversion methods.zz_generated.conversion.go
andzz_generated.deepcopy.go
would 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
Test
toStoreSpec
in bothunversioned
and 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.go
inv1alpha1
package, we could see errors indicating thatConvert_unversioned_StoreSpec_To_v1alpha1_StoreSpec()
was not declared. Now we could create a new filestore_conversion.go
inv1alpha1
package, 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