You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: designs/extensible-cli-and-scaffolding-plugins-phase-2.md
+11-11Lines changed: 11 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -103,14 +103,14 @@ Note: If the name is ambiguous, then the qualified name `myexternalplugin.my.dom
103
103
104
104
### What Plugin system should we use
105
105
106
-
I propose we use our own plugin system that passes JSON blobs back and forth across `stdin/stdout/stderr` and make this the only option for now as it’s a language-agnostic medium and it is easy to work with in most languages.
106
+
I propose we use our own plugin system that passes JSON blobs back and forth across `stdin/stdout/stderr` and make this the only option for now as it's a language-agnostic medium and it is easy to work with in most languages.
107
107
108
-
We came to the conclusion that a kubebuilder-specific plugin library should be written after evaluating plugin libraries such as the [built-in go-plugin library](https://golang.org/pkg/plugin/) and [Hashicorp’s plugin library](https://github.com/hashicorp/go-plugin):
108
+
We came to the conclusion that a kubebuilder-specific plugin library should be written after evaluating plugin libraries such as the [built-in go-plugin library](https://golang.org/pkg/plugin/) and [Hashicorp's plugin library](https://github.com/hashicorp/go-plugin):
109
109
110
-
* The built-in plugin library seems to be more suitable for in-tree plugins rather than out-of-tree plugins and it doesn’t offer cross-language support, thereby making it a non-starter.
111
-
* Hashicorp’s go plugin system is more suitable than the built-in go-plugin library as it enables crosslanguage/platform support. However, it is more suited for longrunning plugins as opposed to shortlived plugins and the usage of protobuf could be overkill as we will not be handling 10s of 1000s of deserializations.
110
+
* The built-in plugin library seems to be more suitable for in-tree plugins rather than out-of-tree plugins and it doesn't offer cross-language support, thereby making it a non-starter.
111
+
* Hashicorp's go plugin system is more suitable than the built-in go-plugin library as it enables cross-language/platform support. However, it is more suited for long-running plugins as opposed to short-lived plugins and the usage of protobuf could be overkill as we will not be handling 10s of 1000s of deserializations.
112
112
113
-
In the future, if a need arises (for example, users are hitting performance issues), we can then explore the possibility of using the Hashicorp’s go plugin library. From a design standpoint, to leave it architecturally open, I propose using a `type` field in the PROJECT file to potentially allow other plugin libraries in the future and make this a seperate field in the PROJECT file per plugin; and this field determines how the `universe` will be passed for a given plugin. However, for the sake of simplicity in initial design and not to introduce any breaking changes as Project version 3 would suffice for our needs, this option is out of scope in this proposal.
113
+
In the future, if a need arises (for example, users are hitting performance issues), we can then explore the possibility of using the Hashicorp's go plugin library. From a design standpoint, to leave it architecturally open, I propose using a `type` field in the PROJECT file to potentially allow other plugin libraries in the future and make this a separate field in the PROJECT file per plugin; and this field determines how the `universe` will be passed for a given plugin. However, for the sake of simplicity in initial design and not to introduce any breaking changes as Project version 3 would suffice for our needs, this option is out of scope in this proposal.
114
114
115
115
### Project configuration
116
116
@@ -165,14 +165,14 @@ resources:
165
165
166
166

167
167
168
-
* What to pass between `kubebuilder` and an external plugin?
168
+
* What should be passed between `kubebuilder` and an external plugin?
169
169
170
170
Message passing between `kubebuilder` and the external plugin will occur through a request / response mechanism. The `PluginRequest` will contain information that `kubebuilder` sends *to* the external plugin. The `PluginResponse` will contain information that `kubebuilder` receives *from* the external plugin.
171
171
172
-
The following scenarios shows what `kubebuilder` will send/receive to the external plugin:
172
+
The following scenarios show what `kubebuilder` will send/receive to the external plugin:
173
173
174
174
* `kubebuilder` to external plugin:
175
-
* `kubebuilder` constructs a `PluginRequest` that contains the `Command` (such as `init`, `create api`, or `create webhook`), `Args` containing all the raw flags from the CLI request and license boilerplate without comment delimiters, and an empty `Universe` that contains the current virtual state of file contents that is not written to the disk yet. `kubebuilder` writes the `PluginRequest` through `stdin`.
175
+
* `kubebuilder` constructs a `PluginRequest` that contains the `Command` (such as `init`, `create api`, or `create webhook`), `Args` containing all the raw flags from the CLI request and license boilerplate without comment delimiters, and an empty `Universe` that contains the current virtual state of file contents that are not written to disk yet. `kubebuilder` writes the `PluginRequest` through `stdin`.
176
176
177
177
* External plugin to `kubebuilder`:
178
178
* The plugin reads the `PluginRequest` through its `stdin` and processes the request based on the `Command` that was sent. If the `Command` doesn't match what the plugin supports, it writes back an error immediately without any further processing. If the `Command` matches what the plugin supports, it constructs a `PluginResponse` containing the `Command` that was executed by the plugin, and modified `Universe` based on the new files that were scaffolded by the external plugin, `Error` and `ErrorMsg` that add any error information, and writes the `PluginResponse` back to `kubebuilder` through `stdout`.
@@ -314,7 +314,7 @@ What happens when the above is invoked?
314
314
315
315
#### User specified file paths
316
316
317
-
A user will provide a list of file paths for `kubebuilder` to discover the plugins in. We will define a variable `KUBEBUILDER_PLUGINS_DIRS` that will take a list of file paths to search for the plugin name. It will also have a default value to search in, in case no file paths are provided. It will search for the plugin name that was provided to the `--plugins` flag in the CLI. `kubebuilder` will recursively search for all file paths until the plugin name is found and returns the successful match, and if it doesn’t exist, it returns an error message that the plugin is not found in the provided file paths. Also use the host system mechanism for PATH separation.
317
+
A user will provide a list of file paths for `kubebuilder` to discover the plugins in. We will define a variable `KUBEBUILDER_PLUGINS_DIRS` that will take a list of file paths to search for the plugin name. It will also have a default value to search in, in case no file paths are provided. It will search for the plugin name that was provided to the `--plugins` flag in the CLI. `kubebuilder` will recursively search for all file paths until the plugin name is found and returns the successful match, and if it doesn't exist, it returns an error message that the plugin is not found in the provided file paths. Also use the host system mechanism for PATH separation.
318
318
319
319
* Alternatively, this could be handled in a way that [helm kustomize plugin](https://helm.sh/docs/topics/advanced/#post-rendering) discovers the plugin based on the non-existence of a separator in the path provided, in which case `kubebuilder` will search in `$PATH`, otherwise resolve any relative paths to a fully qualified path.
320
320
@@ -330,9 +330,9 @@ A user will provide a list of file paths for `kubebuilder` to discover the plugi
330
330
Another approach is adding plugin executables with a prefix `kubebuilder-` followed by the plugin name to the PATH variable. This will enable `kubebuilder` to traverse through the PATH looking for the plugin executables starting with the prefix `kubebuilder-` and matching by the plugin name that was provided in the CLI. Furthermore, a check should be added to verify that the match is an executable or not and return an error if it's not an executable. This approach provides a lot of flexibility in terms of plugin discovery as all the user needs to do is to add the plugin executable to the PATH and `kubebuilder` will discover it.
331
331
332
332
* Pros
333
-
*`kubectl` and `git` follow the same approach for discovering plugins, so there’s prior art.
333
+
*`kubectl` and `git` follow the same approach for discovering plugins, so there's prior art.
334
334
335
-
* There’s a lot of flexibility in just dropping plugin binaries to PATH variable and enabling the discovery without having to enforce any other constraints on the placements of the plugins.
335
+
* There's a lot of flexibility in just dropping plugin binaries to PATH variable and enabling the discovery without having to enforce any other constraints on the placements of the plugins.
336
336
337
337
* Cons
338
338
* Enumerating the list of all available plugins might be a bit tough compared to having a single folder with the list of available plugins and having to enumerate those.
- You will run the command in the root directory of your project: `kubebuilder alpha generate`
38
38
- Then, the command will remove the content of your local directory and re-scaffold the project from the scratch
39
39
- It will allow you to compare your local branch with the remote branch of your project to re-add the code on top OR
40
-
if you do not use the flag `--no-backup` then you can compare the local directory with the copy of your project
41
-
copied to the path `.backup/project-name/` before the re-scaffold be done.
40
+
if you do not use the flag `--no-backup`, then you can compare the local directory with the copy of your project
41
+
copied to the path `.backup/project-name/` before the re-scaffold is done.
42
42
- Therefore, you can run make all and test the final result. You will have after all your project updated.
43
43
44
44
**To update the project with major changes provided**
@@ -66,16 +66,16 @@ A common scenario is to upgrade the project based on the newer Kubebuilder. The
66
66
The proposed command will automate the process at maximum, therefore helping operator authors with minimizing the manual effort.
67
67
68
68
The main motivation of this proposal is to provide a helper for upgrades and
69
-
make less painful this process. Examples:
69
+
make this process less painful. Examples:
70
70
71
71
- See the discussion [How to regenerate scaffolding?](https://github.com/kubernetes-sigs/kubebuilder/discussions/2864)
72
72
- From [slack channel By Paul Laffitte](https://kubernetes.slack.com/archives/CAR30FCJZ/p1675166014762669)
73
73
74
74
### Goals
75
75
76
76
- Help users upgrade their project with the latest changes
77
-
- Help users to re-scaffold projects from scratch based on what was done previously with the tool
78
-
- Make less painful the process to upgrade
77
+
- Help users re-scaffold projects from scratch based on what was done previously with the tool
78
+
- Make the upgrade process less painful
79
79
80
80
### Non-Goals
81
81
@@ -106,7 +106,7 @@ kubebuilder alpha generate \
106
106
- no-backup: [Optional] If not informed then, the current directory should be copied to the path `.backup/project-name`
107
107
- backup: [Optional] If not informed then, the backup will be copied to the path `.backup/project-name`
108
108
- plugins: [Optional] If not informed then, it is the same plugin chain available in the layout field
109
-
- binary: [Optional] If not informed then, the command will use KubeBuilder binary installed globaly.
109
+
- binary: [Optional] If not informed then, the command will use KubeBuilder binary installed globally.
110
110
111
111
> Note that the backup created in the current directory must be prefixed with `.`. Otherwise the tool
112
112
will not able to perform the scaffold to create a new project from the scratch.
@@ -116,12 +116,12 @@ This command would mainly perform the following operations:
116
116
-1. Check the flags
117
117
-2. If the backup flag be used, then check if is a valid path and make a backup of the current project
118
118
-3. Copy the whole current directory to `.backup/project-name`
119
-
-4. Ensure that the output path is clean. By default it is the current directory project where the project was scaffolded previously and it should be cleaned up before to do the re-scaffold.
119
+
-4. Ensure that the output path is clean. By default it is the current directory project where the project was scaffolded previously and it should be cleaned up before doing the re-scaffold.
120
120
Only the content under `.backup/project-name` should be kept.
121
-
-4. Read the [PROJECT config][project-config]
122
-
-5. Re-run all commands using the KubeBuilder binary to recreate the project in the output directory
121
+
-5. Read the [PROJECT config][project-config]
122
+
-6. Re-run all commands using the KubeBuilder binary to recreate the project in the output directory
123
123
124
-
The command should also provide a comprensive help with examples of the proposed workflows. So that, users
124
+
The command should also provide comprehensive help with examples of the proposed workflows. So that, users
125
125
are able to understand how to use it when run `--help`.
To unite Kubebuilder and Operator SDK around Kubebuilder’s project scaffolding, to move Operator SDK’s Go operator features upstream, where appropriate, and to join forces on maintaining Kubebuilder so that both Kubebuilder and Operator SDK support the same project structure and command line interface for Go-based operators.
9
+
To unite Kubebuilder and Operator SDK around Kubebuilder's project scaffolding, to move Operator SDK's Go operator features upstream, where appropriate, and to join forces on maintaining Kubebuilder so that both Kubebuilder and Operator SDK support the same project structure and command line interface for Go-based operators.
11
10
12
11
## Background
13
12
@@ -26,17 +25,17 @@ The Kubebuilder and Operator SDK contributors created a [GitHub project][kb-osdk
26
25
### Upstream code from Operator SDK
27
26
28
27
The Operator SDK project contains various features that can be used by Go operator developers regardless of whether the project is based on Kubebuilder or Operator SDK. These features will be upstreamed into `kubebuilder`, `controller-runtime`, and `controller-tools`, where appropriate. These include:
29
-
*a`DynamicRESTMapper` that enables an operator to dynamically and automatically discover new CRDs added to the cluster after the operator has started
30
-
*a`GenerationChangedPredicate` that can trigger reconciliation events when a resource's `metadata.generation` field has changed.
31
-
*flags and helpers that can be used to provide more fine-grained configuration when constructing the default `zap`-based logger.
28
+
*A`DynamicRESTMapper` that enables an operator to dynamically and automatically discover new CRDs added to the cluster after the operator has started
29
+
*A`GenerationChangedPredicate` that can trigger reconciliation events when a resource's `metadata.generation` field has changed
30
+
*Flags and helpers that can be used to provide more fine-grained configuration when constructing the default `zap`-based logger
32
31
33
32
The Operator SDK contributors plan to begin conducting all development of Go operator related code in upstream Kubebuilder (and related projects) and to spend more time helping the Kubebuilder contributors maintain these projects.
34
33
35
34
### Prototypes
36
35
37
36
To make Kubebuilder more extensible, the community has been discussing a proposal to add extension points to Kubebuilder to support different operator patterns. One example of an operator pattern is the [addon pattern][addon-pattern-pr] that uses an existing library to instantiate an opinionated API and controller.
38
37
39
-
More broadly, the idea is to add support for executable plugin-based extensions that can modify Kubebuilder’s base scaffolding before files are written to disk so that the project (e.g. Go code, kustomize templates, the project Makefile and Dockerfile) can have customized content provided by an extension.
38
+
More broadly, the idea is to add support for executable plugin-based extensions that can modify Kubebuilder's base scaffolding before files are written to disk so that the project (e.g. Go code, kustomize templates, the project Makefile and Dockerfile) can have customized content provided by an extension.
0 commit comments