Skip to content

Commit 9f21ac8

Browse files
committed
doc/user/migrating-existing-apis.md: do not remove v1 API code, following kubernetes API conventions
1 parent 060ded5 commit 9f21ac8

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

doc/user/migrating-existing-apis.md

+29-27
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ In addition to creating a new API version, the command creates an `addtoscheme_o
8484

8585
### Moving shared type definitions and functions to a separate package
8686

87-
Now that `v2` and all related project structure exist, we can begin moving types and functions around. First, we must move anything shared between `CatalogSourceConfig` and `OperatorGroup` to a separate package that can be imported by both `v1` and `v2`. We've identified the files containing these types above: `phase.go`, `phase_types.go`, and `shared.go`.
87+
Now that `v2` and all related project structure exist, we can begin moving types and functions around. First, we must move anything shared between `CatalogSourceConfig` and `OperatorGroup` to a separate package that can be imported by `v2`, future versions, and potentially `v1`. We've identified the files containing these types above: `phase.go`, `phase_types.go`, and `shared.go`.
8888

8989
#### Creating a new 'shared' package
9090

@@ -114,58 +114,60 @@ Global annotations necessary for using `shared` types in API type fields:
114114
- `+k8s:deepcopy-gen=package,register`: directs [`deepcopy-gen`][deepcopy-gen] to generate `DeepCopy()` functions for all types in the `shared` package.
115115
- `+groupName=operators.example.com`: defines the fully qualified API group name for [`client-gen`][client-gen]. Note: this annotation *must* be on the line above `package shared`.
116116

117-
We recommend adding more comments explaining what types and functions exist in `shared` and how they are intended to be used. If you have any comments in `pkg/apis/operators/v1/doc.go` related to copied source code, ensure they are moved into `pkg/apis/operators/v2/doc.go`.
117+
Lastly, if you have any comments in `pkg/apis/operators/v1/doc.go` related to copied source code, ensure they are copied into `pkg/apis/operators/shared/doc.go`. Now that `shared` is a standalone library, more comments explaining what types and functions exist in `shared` and how they are intended to be used should be added.
118118

119-
#### Moving types to package shared
119+
#### Copying types to package shared
120120

121121
The three files containing shared code (`phase.go`, `phase_types.go`, and `shared.go`) can *almost* be copied as-is from `v1` to `shared`. The only changes necessary are:
122122

123123
- Changing the package statements in each file: `package v1` -> `package shared`.
124124
- Exporting types, their methods, and functions used by external API types.
125125

126-
This will regenerate deepcopy code for all tagged types in `pkg/apis`.
127-
128-
Additionally, `deepcopy-gen` must be run on the new package to generate `DeepCopy()` and `DeepCopyInto()` methods, which are necessary for all Kubernetes API code. Doing so will also remove deepcopy code for the now `shared` types from `v1`. To do so, run the following command:
126+
Additionally, `deepcopy-gen` must be run on the new package to generate `DeepCopy()` and `DeepCopyInto()` methods, which are necessary for all Kubernetes API types. To do so, run the following command:
129127

130128
```console
131129
$ operator-sdk generate k8s
132130
```
133131

134-
Now that shared types and functions have their own package we can update types in package `v1`, and any other package that imports them from `v1`, to use those in `shared`. The source file `catalogsourceconfig_types.go` imports and uses a type defined in `shared`, `ObjectPhase`, as a field in `CatalogSourceConfigSpec`.
132+
Now that shared types and functions have their own package we can update any package that imports those types from `v1` to use `shared`. The `CatalogSourceConfig` controller source file `pkg/controller/catalogsourceconfig/catalogsourceconfig_controller.go` imports and uses a type defined in `v1`, `PhaseRunning`, in its `Reconcile()` method. `PhaseRunning` should be imported from `shared` as follows:
135133

136134
```Go
137135
import (
136+
"context"
137+
138+
operatorsv1 "github.com/test-org/test-operator/pkg/apis/operators/v1"
139+
// New import
138140
"github.com/test-org/test-operator/pkg/apis/operators/shared"
139141

140-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
142+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
141143
)
142144

143145
...
144146

145-
type CatalogSourceConfig struct {
146-
metav1.TypeMeta `json:",inline"`
147-
metav1.ListMeta `json:"metadata,omitempty"`
148-
149-
Spec CatalogSourceConfigSpec `json:"spec,omitempty"`
150-
Status CatalogSourceConfigStatus `json:"status,omitempty"`
151-
}
152-
153-
type CatalogSourceConfigSpec struct {
147+
func (r *ReconcileCatalogSourceConfig) Reconcile(request reconcile.Request) (reconcile.Result, error) {
154148
...
155-
}
156149

157-
type CatalogSourceConfigStatus struct {
158-
// The type was previously ObjectPhase, now shared.ObjectPhase.
159-
CurrentPhase shared.ObjectPhase `json:"currentPhase,omitempty"`
160-
...
150+
config := &operatorsv1.CatalogSourceConfig{}
151+
err := r.client.Get(context.TODO(), request.NamespacedName, config)
152+
if err != nil {
153+
...
154+
}
155+
// Old
156+
if config.Status.CurrentPhase.Phase.Name != operatorsv1.PhaseRunning {
157+
...
158+
}
159+
// New
160+
if config.Status.CurrentPhase.Phase.Name != shared.PhaseRunning {
161+
...
162+
}
161163
}
162164
```
163165

164-
Do this for all instances of types previously in `v1` that are now in `shared`. Once done, remove `phase.go`, `phase_types.go`, and `shared.go` from `pkg/apis/operators/v1`.
166+
Do this for all instances of types previously in `v1` that are now in `shared`.
165167

166168
### Updating empty v2 types using v1 types
167169

168-
The `CatalogSourceConfig` type and schema code were generated by `operator-sdk add api`, but the types are not populated. We need to move existing type data from `v1` to `v2`. This process is similar to migrating shared code, except we do not need to export any types or functions.
170+
The `CatalogSourceConfig` type and schema code were generated by `operator-sdk add api`, but the types are not populated. We need to copy existing type data from `v1` to `v2`. This process is similar to migrating shared code, except we do not need to export any types or functions.
169171

170172
Remove `pkg/apis/operators/v2/catalogsourceconfig_types.go` and copy `catalogsourceconfig.go` and `catalogsourceconfig_types.go` from `pkg/apis/operators/v1` to `pkg/apis/operators/v2`:
171173

@@ -178,9 +180,9 @@ If you have any comments or custom code in `pkg/apis/operators/v1` related to so
178180

179181
You can now run `operator-sdk generate k8s` to generate deepcopy code for the migrated `v2` types. Once this is done, update all packages that import the migrated `v1` types to use those in `v2`.
180182

181-
The final step is to remove `catalogsourceconfig.go` and `catalogsourceconfig_types.go` and any related comments or custom code in `doc.go` or `register.go` from `pkg/apis/operators/v1`.
183+
Following Kubernetes API version upgrade conventions, code moved to `shared` from `v1` should be marked with "Deprecated" comments in `v1` instead of being removed. While leaving these types in `v1` duplicates code, it allows backwards compatibility for API users; deprecation comments direct users to switch to `v2` and `shared` types.
182184

183-
**Note:** updating package import paths will likely be the most pervasive change lines-of-code-wise in this process. Luckily the Go compiler will tell you which import path's you have missed once `CatalogSourceConfig` types are removed from `v1`!
185+
Alternatively, types and functions migrated to `shared` can be removed in `v1` to de-duplicate code. This breaks backwards compatibility because projects relying on exported types previously in `v1`, now in `shared`, will be forced to update their imports to use `shared` when upgrading VCS versions. If following this upgrade path, note that updating package import paths in your project will likely be the most pervasive change lines-of-code-wise in this process. Luckily the Go compiler will tell you which import path's you have missed once `CatalogSourceConfig` types are removed from `v1`!
184186

185187
### Updating CustomResourceDefinition manifests and generating OpenAPI code
186188

@@ -358,7 +360,7 @@ Each case is different; one may require many more changes than others. However,
358360
$ operator-sdk add api --api-version operators.example.com/v1 --kind CatalogSourceConfigurer
359361
```
360362

361-
1. Moving code from one Go package to another, ex. from `v1` to `v2` and `shared`.
363+
1. Copying code from one Go package to another, ex. from `v1` to `v2` and `shared`.
362364
1. Changing import paths in project Go source files to those of new packages.
363365
1. Updating CRD manifests.
364366
- In many cases, having sufficient [code annotations][kubebuilder-api-annotations] and running `operator-sdk generate openapi` will be enough.

0 commit comments

Comments
 (0)