sigs.k8s.io/kubebuilder/v3@v3.14.0/docs/migration_guide.md (about)

     1  # Migration guide from v0 project to v1 project
     2  
     3  This document describes how to migrate a project created by kubebuilder v0 to a project created by kubebuilder v1. Before jumping into the detailed instructions, please take a look at the list of [major differences between kubebuilder v0 and kubebuilder v1](kubebuilder_v0_v1_difference.md).
     4  
     5  The recommended way of migrating a v0 project to a v1 project is to create a new v1 project and copy/modify the code from v0 project to it.
     6  
     7  ## Init a v1 project
     8  Find project's domain name from the old project's pkg/apis/doc.go and use it to initiate a new project with
     9  `kubebuilder init --project-version v1 --domain <domain>`
    10  
    11  ## Create api
    12  Find the group/version/kind names from the project's pkg/apis. The group and version names are directory names while the kind name can be found from *_types.go. Note that the kind name should be capitalized. 
    13  
    14  Create api in the new project with
    15  `kubebuilder create api --group <group> --version <version> --kind <kind>`
    16  
    17  If there are several resources in the old project, repeat the `kubebuilder create api` command to create all of them.
    18  
    19  ## Copy types.go
    20  Copy the content of `<type>_types.go` from the old project into the file `<type>_types.go` in the new project.
    21  Note that in the v1 project, there is a section containing `<type>List` and `init` function. Please keep this section.
    22  ```
    23  // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
    24  // +genclient:nonNamespaced
    25  
    26  // HelloList contains a list of Hello
    27  type HelloList struct {
    28  	metav1.TypeMeta `json:",inline"`
    29  	metav1.ListMeta `json:"metadata,omitempty"`
    30  	Items           []Hello `json:"items"`
    31  }
    32  
    33  func init() {
    34  	SchemeBuilder.Register(&Hello{}, &HelloList{})
    35  }
    36  ```
    37  
    38  ## Copy and modify controller code
    39  
    40  ### copy and update reconcile function
    41  Note that in v0 and v1 projects, the `Reconcile`
    42  functions have different arguments and return types.
    43  
    44  - `Reconcile` function in v0 project: `func (bc *<kind>Controller) Reconcile(k types.ReconcileKey) error`
    45  
    46  - `Reconcile` function in v1 project: `func (r *Reconcile<kind>) Reconcile(request reconcile.Request) (reconcile.Result, error)`
    47  
    48  Remove the original body of `Reconcile` function inside the v1 project and copy the body of the `Reconcile` function from the v0 project to the v1 project. Then apply following changes:
    49  - add `reconcile.Result{}` as the first value in every `return` statement
    50  - change the call of client functions such as `Get`, `Create`, `Update`. In v0 projects, the call of client functions has the format like `bc.<kind>Lister.<kind>().Get()` or `bc.KubernetesClientSet.<group>.<version>.<Kind>.Get()`. They can be replaced by `r.Client` functions. Here are several examples of updating the client function from v0 project to v1 project:
    51  
    52  ```
    53  # in v0 project
    54  mc, err := bc.memcachedLister.Memcacheds(k.Namespace).Get(k.Name)
    55  # in v1 project, change to
    56  mc := &myappsv1alpha1.Memcached{}
    57  err := r.Client.Get(context.TODO(), request.NamespacedName, mc)
    58  
    59  
    60  # in v0 project
    61  dp, err := bc.KubernetesInformers.Apps().V1().Deployments().Lister().Deployments(mc.Namespace).Get(mc.Name)
    62  # in v1 project, change to
    63  dp := &appsv1.Deployment{}
    64  err := r.Client.Get(context.TODO(), request.NamespacedName, dp)
    65  
    66  
    67  dep := &appsv1.Deployment{...}
    68  # in v0 project
    69  dp, err := bc.KubernetesClientSet.AppsV1().Deployments(mc.Namespace).Create(dep)
    70  # in v1 project, change to
    71  err := r.Client.Create(context.TODO(), dep)
    72  
    73  
    74  dep := &appsv1.Deployment{...}
    75  # in v0 project
    76  dp, err = bc.KubernetesClientSet.AppsV1().Deployments(mc.Namespace).Update(deploymentForMemcached(mc))
    77  # in v1 project, change to
    78  err := r.Client.Update(context.TODO(), dep)
    79  
    80  
    81  labelSelector := labels.SelectorFrom{...}
    82  # in v0 project
    83  pods, err := bc.KubernetesInformers.Core().V1().Pods().Lister().Pods(mc.Namespace).List(labelSelector)
    84  # in v1 project, change to
    85  pods := &v1.PodList{}
    86  err = r.Client.List(context.TODO(), &client.ListOptions{LabelSelector: labelSelector}, pods)
    87  ```
    88  - add library imports used in the v0 project to v1 project such as log, fmt or k8s libraries. Note that libraries from kubebuilder or from the old project's client package shouldn't be added.
    89  
    90  
    91  ### update add function
    92  
    93  In a v0 project controller file, there is a `ProvideController` function creating a controller and adding some watches. In v1 projects, the corresponding function is `add`. For this part, you don't need to copy any code from v0 project to v1 project. You need to add some watchers in v1 project's `add` function based on what `watch` functions are called in v0 project's `ProvideController` function.
    94  
    95  Here are several examples:
    96  
    97  ```
    98  gc := &controller.GenericController{...}
    99  gc.Watch(&myappsv1alpha1.Memcached{})
   100  gc.WatchControllerOf(&v1.Pod{}, eventhandlers.Path{bc.LookupRS, bc.LookupDeployment, bc.LookupMemcached})
   101  ```
   102  
   103  need to be changed to:
   104  
   105  ```
   106  c, err := controller.New{...}
   107  c.Watch(&source.Kind{Type: &myappsv1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{})
   108  c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{
   109  		IsController: true,
   110  		OwnerType:    &myappsv1alpha1.Memcached{},
   111  	})
   112  ```
   113  
   114  ### copy other functions
   115  If `reconcile` function depends on some other user defined functions, copy those function as well into the v1 project.
   116  
   117  ## Copy user libraries
   118  If there are some user defined libraries in the old project, make sure to copy them as well into the new project.
   119  
   120  ## Update dependency
   121  
   122  Open the Gopkg.toml file in the old project and find if there is user defined dependency in this block:
   123  
   124  ```
   125  # Users add deps lines here
   126  
   127  [prune]
   128    go-tests = true
   129    #unused-packages = true
   130  
   131  # Note: Stanzas below are generated by Kubebuilder and may be rewritten when
   132  # upgrading kubebuilder versions.
   133  
   134  # DO NOT MODIFY BELOW THIS LINE.
   135  ```
   136  Copy those dependencies into the new project's Gopkg.toml file **before** the line
   137  ```
   138  # STANZAS BELOW ARE GENERATED AND MAY BE WRITTEN - DO NOT MODIFY BELOW THIS LINE.
   139  ```
   140  
   141  ## Copy other user files
   142  If there are other user created files in the old project, such as any build scripts, README.md files. Copy those files into the new project.
   143  
   144  ## Confirmation
   145  Run `make` to make sure the new project can build and pass all the tests.
   146  Run `make install` and `make run` to make sure the api and controller work well on cluster.