-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
introduce v1alpha2 api with auto conversion #1529
Conversation
This introduces a new api version `v1alpha2` while still allowing user to use `v1alpha1` API. - Only one version of the CRD can be stored, so `v1alpha1` is the one stored - All the version of the CRD **must** be schema compatible (before 1.16) - `v1alpha1` gets **all** the fields, meaning : - the new ones (from `v1alpha2`, …) - the old deprecated ones (that will be removed from `v1alpha2`) - we may *only* document the "frozen" `v1alpha1` field (and not the new one that are coming from the other api versions) - `kubectl` get returns the highest priority version, aka the most recent one, here `v1alpha2`. To make *sure* any object created from any version are valid (while getting), we convert them using the admission webhook (#blackmagic 🧙). - Object created using `v1alpha1` API will automatically be converted (see below) - This has the downsize of not being able to `get` v1alpha1 object anymore (although it should be possible using the `client-go` and some even more #blackmagic 🧙 hack on the webhook side probably) - One benefit of this approach (`apis.Convertible`) is that once we *only* support 1.16 (the release with conversion webhook), this will be usable almost as is (for the conversion webhook) 👼. This is done in a quick and dirty way: - Lot's of code is duplicated where it would not be needed, it was just quicker to do so at that point in time - I completely skipped the *variable interpolation* validation for `Parameters` as those values would/will need to be automatically transformed too (but it was a bit complicated for what I wanted to experiment on) - I did not implement the **reconcilier** part of this. It should be simple as: - it will use only one object (the store one, aka `v1alpha1`) - it will make the assumption that the objects are fully transformed (either by the webhook or in-memory by the controller), meaning there will be no *handling backward-compatible* piece of code in the reconcilier (all is contained in the `Validable`, `Defaultable` and `Convertible` impl.). Possible next steps are: - Split this into smaller PR. - Introduce a `v1alpha2` package early but not exposing it before we are ready to. This will allow us to not have to rush this for 0.9, **and** to increment over this in smaller step. - Decide what `v1alpha2` should look like — I did this experiment with `TaskSpec.Inputs.Params` to `TaskSpec.Params` but we should decide what we want to change and target that. - Reduce duplication by reusing anything that didn't change from `v1alpha1` to `v1alpha2` in `v1alpha1` (aka refering the same type in go) - Related to this experiment, implement the variable interpolation validation thing **and** the reconcilier part too. - Need to figure out if the definition types (`Task`, `Pipeline`, …) need a `controller` (I don't think so but…) Signed-off-by: Vincent Demeester <[email protected]>
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -104,7 +113,7 @@ func main() { | |||
|
|||
// Decorate contexts with the current state of the config. | |||
ctxFunc := func(ctx context.Context) context.Context { | |||
return v1alpha1.WithDefaultConfigurationName(store.ToContext(ctx)) | |||
return v1alpha2.WithUpgradeViaDefaulting(store.ToContext(ctx)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tells the webhook to do the conversion 👼
versions: | ||
- name: v1alpha1 | ||
served: true | ||
storage: true | ||
- name: v1alpha2 | ||
served: true | ||
storage: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v1alpha1
is the stored version, but both are served
The following is the coverage report on pkg/.
|
@@ -1,5 +1,5 @@ | |||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This files contains v1alpha2
and v1alpha1
Tasks
@@ -42,7 +42,7 @@ ${GOPATH}/bin/deepcopy-gen \ | |||
# Knative Injection | |||
${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \ | |||
github.com/tektoncd/pipeline/pkg/client github.com/tektoncd/pipeline/pkg/apis \ | |||
"pipeline:v1alpha1" \ | |||
"pipeline:v1alpha1,v1alpha2" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This updates codegen to generate v1alpha1 and v1alpha2 clientset, informers, …
"knative.dev/pkg/apis" | ||
) | ||
|
||
func (source *Task) ConvertUp(ctx context.Context, obj apis.Convertible) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows us to take a v1alpha1
object and "convert it up" to a more recent version (that will be passed, by the webhook or the reconcilier for in-memory upgrade)
} | ||
|
||
func (sink *Task) ConvertDown(ctx context.Context, obj apis.Convertible) error { | ||
switch source := obj.(type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does the opposite of ConvertUp
, it takes a "higher" version of the Task object and converts it "back" to v1alpha1
(hence the need for v1alpha1
types to have all the fields
if v1alpha2.IsUpgradeViaDefaulting(ctx) { | ||
fmt.Println("********************************************") | ||
v := v1alpha2.TaskSpec{} | ||
if ts.ConvertUp(ctx, &v) == nil { | ||
fmt.Printf("v: %+v\n", v) | ||
fmt.Printf("v.inputs: %+v\n", v.Inputs) | ||
fmt.Printf("v.outputs: %+v\n", v.Outputs) | ||
alpha1 := TaskSpec{} | ||
if alpha1.ConvertDown(ctx, v) == nil { | ||
*ts = alpha1 | ||
} | ||
} | ||
} | ||
fmt.Printf("ts: %+v\n", ts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This combined with https://github.com/tektoncd/pipeline/pull/1529/files#diff-58de452513b7e8d8d3cfea23eb4ae6a8R116 make the conversion automatic from v1alpha1
to a v1alpha2
compatible object (still stored as v1alpha1
)
// must be supplied as inputs in TaskRuns unless they declare a default | ||
// value. | ||
// +optional | ||
Params []ParamSpec `json:"params,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fields comes from v1alpha2
"struct" and "might not be documented"
// must be supplied as inputs in TaskRuns unless they declare a default | ||
// value. | ||
// +optional | ||
Params []ParamSpec `json:"params,omitempty"` | ||
DeprecatedParams []ParamSpec `json:"params,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming it makes it easier to know it's deprecated and we shouldn't depend/looking at it in the reconcilier
/* | ||
if err := validateInputParameterVariables(ts.Steps, ts.Inputs); err != nil { | ||
return err | ||
} | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said in the comments, this is commented to skip the "auto" migrate variable interpolation
btw, this is how |
@vdemeester: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
I'll start tackling this next week, especially the following items 👼
|
@@ -131,7 +131,7 @@ spec: | |||
- "w" | |||
- "-i" | |||
- "$(inputs.params.yqArg)" | |||
- "$(inputs.params.path)" | |||
- "$kube(inputs.params.path)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, it looks like this line of code has one more word “kube” .
I am going to close as split work has started 😉 |
@vdemeester: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Changes
This is related to #1526 and #1379.
This introduces a new api version
v1alpha2
while still allowing userto use
v1alpha1
API.v1alpha1
is the onestored
v1alpha1
gets all the fields, meaning :v1alpha2
, …)v1alpha2
)v1alpha1
field (and not thenew one that are coming from the other api versions)
kubectl
get returns the highest priority version, aka the mostrecent one, here
v1alpha2
. To make sure any object created fromany version are valid (while getting), we convert them using the
admission webhook (#blackmagic 🧙).
v1alpha1
API will automatically beconverted (see below)
get
v1alpha1 objectanymore (although it should be possible using the
client-go
andsome even more #blackmagic 🧙 hack on the webhook side probably)
apis.Convertible
) is that oncewe only support 1.16 (the release with conversion webhook), this
will be usable almost as is (for the conversion webhook) 👼.
This is done in a quick and dirty way:
just quicker to do so at that point in time
Parameters
as those values would/will need to be automaticallytransformed too (but it was a bit complicated for what I wanted to
experiment on)
simple as:
v1alpha1
)transformed (either by the webhook or in-memory by the
controller), meaning there will be no handling
backward-compatible piece of code in the reconcilier (all is
contained in the
Validable
,Defaultable
andConvertible
impl.).Possible next steps are:
v1alpha2
package early but not exposing it before weare ready to. This will allow us to not have to rush this for
0.9, and to increment over this in smaller step.
v1alpha2
should look like — I did this experiment withTaskSpec.Inputs.Params
toTaskSpec.Params
but we should decidewhat we want to change and target that.
v1alpha1
tov1alpha2
inv1alpha1
(aka refering the same typein go)
validation thing and the reconcilier part too.
Task
,Pipeline
, …)need a
controller
(I don't think so but…)Example of conversion
becomes the following at creation
Putting an hold as this is not meant to be merged, ever !
/hold
/cc @bobcatfish @skaegi @imjasonh @afrittoli @abayer
Signed-off-by: Vincent Demeester [email protected]
Submitter Checklist
These are the criteria that every PR should meet, please check them off as you
review them:
See the contribution guide for more details.
Double check this list of stuff that's easy to miss:
cmd
dir, please updatethe release Task to build and release this image.
Reviewer Notes
If API changes are included, additive changes must be approved by at least two OWNERS and backwards incompatible changes must be approved by more than 50% of the OWNERS, and they must first be added in a backwards compatible way.