Skip to content
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

Proposal: Support . in param / result names #503

Merged
merged 3 commits into from
Sep 6, 2021

Conversation

mattmoor
Copy link
Member

No description provided.

@tekton-robot tekton-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 19, 2021
@tekton-robot tekton-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 19, 2021
@tekton-robot tekton-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 19, 2021
### Use Cases (optional)

See the [original issue](https://github.com/tektoncd/pipeline/issues/3590) for some
of these.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to go into more detail around these? i dont totally understand the use cases myself - and I'd like to understand the use cases we have for this that wouldn't be satisfied by having dictionary/object support (TEP-0075) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are completely unrelated. The motivation is to be able to define parameters to Tasks and Pipelines that enable a level of unambiguous matching of certain semantic characteristics. For instance, if a Task or Pipeline were parameterized by some workspace setup logic, being able to unambiguously identify that semantic through a highly scoped parameter name would be extremely useful. Ultimately this isn't about teaching tektoncd/pipelines any new tricks, but providing enough leeway that higher-level tooling (incl. potentially tkn) can create higher-level experiences.

I'm currently doing this extensively in mink, but with -, which leaves a lot to be desired. I enumerated a large number of potential use cases here: #504

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also happy to jump on a quick call if it'd be easier to talk through synchronously.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For instance, if a Task or Pipeline were parameterized by some workspace setup logic, being able to unambiguously identify that semantic through a highly scoped parameter name would be extremely useful.

I'm still not understanding why having dictionary parameter support wouldn't give you that.

In #504 you show this example:

      params:
        - name: dev.mink.kontext
          description: A self-extracting container image of source

If we had dictionary support (eventually nested dictionary support) that could be expressed as:

      params:
       - name: dev
         description: A self-extracting container image of source
         type: object
         properties:
         mink: {
              type: object
              properties: {
                 kontext: {
                     type:string
                }
              } 
          }

It's certainly a lot longer, so maybe it's the verbosity that makes you want to prefer encoding the namespacing into the string? The above structure would let you define other properties as part of your mink object as well - and as @wlynch had mentioned we could have predefined schemas for known types (like "mink params").

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the confusion is somewhat like conflating hierarchical package namespaces and nested object fields.

Yes, you could probably implement namespaces as very deeply nested objects, but it is both extremely verbose and obscures the fundamental motivation: unique naming.

Part of the point of this is to be an enabler for higher-level "ownership" conventions through things like domain-scoping, and in my example the presence of a domain is very clear, but in yours it is completely obfuscated. Similarly if Java had folks define:

class com {
   class google {
       class foo {
           class Bar {
           }
       }
   }
}

It would serve the purpose of enabling com.google.foo.Bar, but it gets especially rough when you consider that Java doesn't have open classes, so everything in com would have to go in that file! Similarly, everything in dev (and dev.mink) would have to be blended into a single shared schema, which also means these can't take advantage of things like SchemaRefs (assuming those eventually land) without a blending syntax.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to side with @mattmoor there, it's just about the name, not nested object fields, …
I see value with this to "namespace" some parameters ; that could, indeed, be used by higher-level tooling. I see value for openshift (and openshift tooling / consule), to be able to have io.openshift.* set of params, etc..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm still confused about the use case where a Task is being written such there are so many params that they don't need to be grouped but ownership needs to be defined.

In the openshift example, I'd think we have one of two things happening:

  1. A super generic task (e.g. git-clone or something) is being passed values that originated in some specific system (e.g. openshift) - in this case the task is still generic so I dont think it would have open shift specific params
  2. A task specific to openshift - i this case, i dont really understand why you'd need to namespace the params at all if the entire Task was specific to openshift (but being able to group them seems useful which is where i keep coming back to dictionaries)

Maybe in the context of a pipeline it would make more sense - you'd be receiving params from a variety of sources, maybe identifying the ones generated by openshift would make sense - but i still dont understant why you woudnt want to group them, i.e. the difference between something like:

      params:
        - name: openshift.foo
        - name: openshift.bar
        - name: openshift.baz

and

      params:
       - name: openshift
         type: object
         properties:
           foo : { type: string}
           bar : { type: string}
           baz : { type: string}

But anyway even though I'm not convinced about the specific use cases we probably don't need to set the bar as high as I'm trying to just to allow some specific character in a param name 😆 , as long as we have an unambiguous way of referring to it in our syntax.

but in yours it is completely obfuscated.

I don't totally understand what you mean @mattmoor - the structure of the dictionary does express the same information?

Similarly, everything in dev (and dev.mink) would have to be blended into a single shared schema, which also means these can't take advantage of things like SchemaRefs (assuming those eventually land) without a blending syntax.

maybe you could explain a bit more about the single shared schema and the blending you're mentioning?

(it sounds like you're saying if one Task had a param with the top level key "mink" that would prevent other Tasks from having the top level key "mink" with a different structure? if so i dont follow why that's the case)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the structure of the dictionary does express the same information

To a machine capable of deep structural analysis of the type? yes for this example. At a glance, absolutely not (thus the term "obfuscate").

I also don't think keys like openshift and mink are unambiguous enough that we should expect common users to avoid defining them, where it's a pretty well-worn precedent that domains are the purview of the domain owner.

I also had a thought this morning, which I think will help shine a light on the confusion and distinction I am trying to draw between namespaced field names and decomposing those same fields into objects themselves (see). If the plan with TEP 75 is to allow for structured params and results following JSON structure, then this TEP devolves to handling fields within those same objects with . in them (and JSON fields can have a lot more characters Tekton likely doesn't support today!). My point is that the same trick doesn't work here (from my linked comment):

         name: line
         type: object
         properties:
           "knative.dev/controller": { type: string}
           "knative.dev/key": { type: string}
           ...

... this TEP is really just a degenerate case of this in a world where only primitive types are supported.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm so what I'm taking away from this is that a different way of looking at this proposal might be something like: as we expand support for json based params, we should look at supporting more of the characters that json considers valid which we currently don't, including . (and / in the examples you added)

seems reasonable to me!

i tried to see if there was any reason why we are limiting the characters the way we are and it seems to come down to tektoncd/pipeline#472 where @vdemeester says:

I think this is a good "base" for variable name but might be too restrictive though

so it seems like it was arbitrary and expanding to include . makes sense (based on your example above would you want to include / as well? "knative.dev/controller" is a bit more readable for me personally than "dev.knative.controller" but that's just me)

@vdemeester vdemeester added the kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). label Aug 23, 2021
@jerop
Copy link
Member

jerop commented Aug 23, 2021

/assign @jerop @bobcatfish @vdemeester

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 24, 2021
@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 26, 2021
teps/0080-support-domainscoped-parameterresult-names.md Outdated Show resolved Hide resolved
### Use Cases (optional)

See the [original issue](https://github.com/tektoncd/pipeline/issues/3590) for some
of these.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to side with @mattmoor there, it's just about the name, not nested object fields, …
I see value with this to "namespace" some parameters ; that could, indeed, be used by higher-level tooling. I see value for openshift (and openshift tooling / consule), to be able to have io.openshift.* set of params, etc..

Copy link
Contributor

@bobcatfish bobcatfish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the discussion @mattmoor - im still not 100% sure what Tasks will look that use these domain scoped params but overall im in favor of the proposal (esp from the perspective of expanding our json based param support) and maybe when I see it in action it'll make sense to me

/approve

(including Kubernetes labels, CloudEvent types, Java import paths, ContainerD plugins,
and many more) of using a Domain-scoped naming convention to "claim" a segment of
names for the owner's exclusive use. This is of course conventional, but in practice
is generally good enough.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the additional info!

> _It is notable that with @bobcatfish [TEP for stronger
typing](https://github.com/tektoncd/community/pull/479) that these conventions should
also establish the types associated with those parameter names, and might form a good
case for SchemaRefs._
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

### Use Cases (optional)

See the [original issue](https://github.com/tektoncd/pipeline/issues/3590) for some
of these.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm so what I'm taking away from this is that a different way of looking at this proposal might be something like: as we expand support for json based params, we should look at supporting more of the characters that json considers valid which we currently don't, including . (and / in the examples you added)

seems reasonable to me!

i tried to see if there was any reason why we are limiting the characters the way we are and it seems to come down to tektoncd/pipeline#472 where @vdemeester says:

I think this is a good "base" for variable name but might be too restrictive though

so it seems like it was arbitrary and expanding to include . makes sense (based on your example above would you want to include / as well? "knative.dev/controller" is a bit more readable for me personally than "dev.knative.controller" but that's just me)

@tekton-robot tekton-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 1, 2021
@mattmoor
Copy link
Member Author

mattmoor commented Sep 2, 2021

👍 LMK if I can answer any more questions, or adjust any other aspects of this.

@tekton-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bobcatfish, vdemeester

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@bobcatfish
Copy link
Contributor

@mattmoor it totally slipped my mind that I've actually got another use case for this feature - in the pipeline to task run experimental control i'm taking the params from a bunch of tasks and squishing them down into one task - so I try to namespace them by the name of the original pipeline task! I wanted to use . for the namespacing but went with - because . wasn't supported XD (it ends up looking like this: https://github.com/tektoncd/experimental/blob/main/pipeline-to-taskrun/pkg/reconciler/pipelinetotaskrun/testdata/expected-taskrun.yaml ). and thinking about it, i dont think it would be reasonable (at least initially) to put these into dictionaries instead b/c it would mean having to change the way the values are written within the steps

so anyway TL;DR if you're looking for another use case for the proposal I've got one and I'll totally use this feature once it's available

@dlorenc
Copy link
Contributor

dlorenc commented Sep 4, 2021

This just reminded me of the funny -dot- escaping App Engine used to do to avoid nested subdomains and double wildcard certs :)

@mattmoor
Copy link
Member Author

mattmoor commented Sep 5, 2021

Mostly a TEP-noobie process question: What's left to merge this?

I'd be happy to try and implement this next week, but I think the API meeting Monday is cancelled due to Labor day.

I don't want to put the cart before the horse, so figured I'd ask here. thanks, and enjoy the long weekend (if you have one)

mattmoor added a commit to mattmoor/pipeline that referenced this pull request Sep 5, 2021
This change allow folks to use `.` in parameter names (e.g. `dev.mattmoor.my-param`), and reference them via the subscript operator (e.g. `params["dev.mattmoor.my-param"]`) to avoid ambiguity introduced by the mixing of `.`s.

TEP: tektoncd/community#503
mattmoor added a commit to mattmoor/pipeline that referenced this pull request Sep 5, 2021
This change allow folks to use `.` in parameter names (e.g. `dev.mattmoor.my-param`), and reference them via the subscript operator (e.g. `params["dev.mattmoor.my-param"]`) to avoid ambiguity introduced by the mixing of `.`s.

TEP: tektoncd/community#503
@vdemeester
Copy link
Member

@mattmoor 2 approve from 2 different company, we are just waiting for a lgtm from.. another owner and we are good to go 👼🏼

@dlorenc
Copy link
Contributor

dlorenc commented Sep 6, 2021

/lgtm

@tekton-robot tekton-robot added the lgtm Indicates that a PR is ready to be merged. label Sep 6, 2021
@tekton-robot tekton-robot merged commit f55bb88 into tektoncd:main Sep 6, 2021
@bobcatfish
Copy link
Contributor

btw link to the process @vdemeester and @dlorenc - we've been using an approach where approvers /approve and we do the final /lgtm in the API working group: https://github.com/tektoncd/community/tree/main/teps#tep-review-process-and-slos

@dlorenc
Copy link
Contributor

dlorenc commented Sep 7, 2021

It says here that anyone can add the final approval, given there was no API meeting this week for the holiday I felt it was fine:

Once all assigned reviewers have approved the PR, the final /lgtm can be added in the next API working group meeting or sooner by anyone with permission to if needed.

@bobcatfish
Copy link
Contributor

ah good point @dlorenc 👍 thanks for looking and pointing that out

tekton-robot pushed a commit to tektoncd/pipeline that referenced this pull request Sep 15, 2021
This change allow folks to use `.` in parameter names (e.g. `dev.mattmoor.my-param`), and reference them via the subscript operator (e.g. `params["dev.mattmoor.my-param"]`) to avoid ambiguity introduced by the mixing of `.`s.

TEP: tektoncd/community#503
@@ -0,0 +1,165 @@
---
status: proposed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh you know what @mattmoor - technically we need to update this to "implementable" - technically this should have happened before tektoncd/pipeline#4215 went in

it's a weird part of our process - often after a lot of back and forth on the initial PR we just update it to "implementable" right from the start, which we should have probably remembered to suggest here 🤦‍♀️

at this point maybe you could just update the proposal with "implemented"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, TIL. Will send a PR shortly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). lgtm Indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants