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

enhancements: compound-bundle-constraints #97

Merged
merged 3 commits into from
Nov 30, 2021
Merged

enhancements: compound-bundle-constraints #97

merged 3 commits into from
Nov 30, 2021

Conversation

estroz
Copy link
Member

@estroz estroz commented Oct 20, 2021

Signed-off-by: Eric Stroczynski [email protected]

@estroz
Copy link
Member Author

estroz commented Oct 20, 2021

/cc @joelanford @kevinrizza @dinhxuanvu

@estroz
Copy link
Member Author

estroz commented Oct 20, 2021

/cc @dmesser

@openshift-ci openshift-ci bot requested a review from dmesser October 20, 2021 19:49
Copy link
Member

@joelanford joelanford left a comment

Choose a reason for hiding this comment

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

Overall, looks pretty solid. A couple of comments/questions.

Comment on lines +270 to +316
- There is no quick way to determine whether an expression is unsatisfiable
other than by using a SAT solver, which the resolver uses internally.
Compound constraints must be vetted by hand.
Copy link
Member

Choose a reason for hiding this comment

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

Not in scope for this EP, but this is another good use case for making the resolver usable in other contexts (e.g. verifying that a bundle's properties and constraints are not internally unsatisfiable)


### Graduation Criteria

The alpha feature gate will be removed and this feature will be on permanently by OLM v1.0.0.
Copy link
Member

Choose a reason for hiding this comment

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

We probably need to go into a little bit more detail here, and v1.0.0 seems somewhat arbitrary. Why not a v0.y or v1.1+?

Specific areas to address are:

  • Why are we introducing as tech preview?
  • What do we hope to learn while this feature is in tech preview and how do we plan to learn it?
  • What will trigger us to graduate this feature from tech preview to GA?

Copy link
Member Author

Choose a reason for hiding this comment

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

This decision was arbitrary. Perhaps v0.(y+2) from release is better, since we want feedback on how well this feature tackles the outlined use cases vs. improvements to the spec that result in breaking changes.

enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
schema: olm.bundle
name: baz.v1.0.0
properties:
- type: olm.none.required
Copy link
Member

Choose a reason for hiding this comment

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

this is interesting, but I think it more matches "conflicts" constraints in the resolver than it does negation.

negation would let you say things like A && B || A && !C etc

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 am unclear on what you mean. Negation here intentionally means "use any GVK/package that satisfies other constraints except these GVKs/packages". Are you saying this is not useful, or just that the implementation of negation in the resolver is "conflicts"?

enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
@estroz
Copy link
Member Author

estroz commented Nov 9, 2021

Any showstoppers for this getting merged? The plan is to start this feature off in alpha, so if changes to the spec are needed based on the higher level constraint vs. property discussion, they can be made easily and I'll update this EP then.

@joelanford
Copy link
Member

Any showstoppers for this getting merged? The plan is to start this feature off in alpha, so if changes to the spec are needed based on the higher level constraint vs. property discussion, they can be made easily and I'll update this EP then.

Can you call this out specifically in the EP as a risk or open question, and then describe what the remediation will be?

It seems like this is well-defined enough to begin implementation, but if we're pretty confident that the syntax will change (even slightly), I think we'd do ourselves a favor if we kept the code related to parsing the constraint in a separate branch so it doesn't get merged downstream until we're confident it aligns with the discussion in #91.

Do you think its worthwhile running through another prototype demo based on what exists here to get something concrete in front of folks. I'd be interested in getting this on the agenda of one of our upstream meetings to get community feedback.

@cdjohnson Any comments/questions?

@estroz
Copy link
Member Author

estroz commented Nov 10, 2021

Do you think its worthwhile running through another prototype demo based on what exists here to get something concrete in front of folks. I'd be interested in getting this on the agenda of one of our upstream meetings to get community feedback.

Most definitely. Let me update the POC and add that to the agenda for the next OLM upstream meeting.

@perdasilva
Copy link

perdasilva commented Nov 12, 2021

One thing that's kind of bother me a little is the interchange b/w property and constraint. E.g. if I just want a simple package level constraint, then that's a property. The same structure however would be re-used under constraint in the nested example. Maybe we should just use property everywhere?

@cdjohnson
Copy link

Question on Interoperability:

  • Older versions of OLM (compound constraints are not known) will ignore the new constraint properties and continue to honor the old required properties at the root level.
  • Newer versions of OLM (compound constraint aware) will honor BOTH the new and old properties.

I think we need a way to signal OLM to ignore the old properties if the new properties are present, or use the fact that there is an olm.all|any|none.required property at the top level to IGNORE the non-constraint properties at the top. It seems like we would want to deprecate the ability specify constraints at the top level and always express them in a compound dependency.

For example, if I wanted to build a Bundle that works on both, I could do something like this:

- type: olm.package.required
  value:
    description:  This is for legacy versions of OLM.
    packageName: bar
    versionRange: '>=1.0.0'
- type: olm.gvk.required
  value:
    description:  This is for legacy versions of OLM.
    group: etcd.database.coreos.com
    kind: EtcdBackup
    version: v1beta2
- type: olm.all.required
  value:
    constraints:
      - type: olm.package.required
        value:
          packageName: bar
          versionRange: '>=1.0.0'
      - type: olm.none.required
        value:
          - type: olm.package.required
            value:
              description: This package provides the same GVK, but I don't work with this one.
              packageName: brokenbar
              versionRange: '>=1.0.0'
      - type: olm.gvk.required
        value:
          description:  This is for legacy versions of OLM.
          group: etcd.database.coreos.com
          kind: EtcdBackup
          version: v1beta2

If the new version of OLM honors BOTH the old and new formats, then the new compound constraints will be ignored in this case.

@cdjohnson
Copy link

Question on resolver scope:
Is each constraint applied to a single bundle? Or on the entire visible domain of operators (catalog sources and installed bundles)?

Example: I want GVK and Package to be served by the same bundle. Not by two different bundles.

@estroz
Copy link
Member Author

estroz commented Nov 12, 2021

One thing that's kind of bother me a little is the interchange b/w property and constraint. E.g. if I just want a simple package level constraint, then that's a property. The same structure however would be re-used under constraint in the nested example. Maybe we should just use property everywhere?

@perdasilva this is being resolved in #91 (comment). All constraints are properties, but not all properties are constraints, hence the distinction.

I think we need a way to signal OLM to ignore the old properties if the new properties are present, or use the fact that there is an olm.all|any|none.required property at the top level to IGNORE the non-constraint properties at the top.

@cdjohnson I think this is a good idea for backwards-compatibility of bundles with OLM. The resolver can infer what to use by the presence of a compound constraint. I will say though, mixing both "legacy" and compound constraints in this way is confusing. I'll call out that this behavior needs to be documented and have warnings logged when this scenario is encountered.

Is each constraint applied to a single bundle? Or on the entire visible domain of operators (catalog sources and installed bundles)?

If I understand what you're asking, the latter. This is the same scope as for existing constraints.

@cdjohnson
Copy link

@estroz

Is each constraint applied to a single bundle? Or on the entire visible domain of operators (catalog sources and installed bundles)?

If I understand what you're asking, the latter. This is the same scope as for existing constraints.

After re-reading and talking to @dmesser, it appears that each Constraint Root (top level property) must evaluate to true for a single bundle. This wasn't clear to me until I re-read the old resolver EP. Essentially each Tree of constraints is evaluated independently against each bundle. So, by having a Compound Constraint they must evaluate to TRUE for a single bundle. I was incorrectly (I hope) thinking that the compound constraints were applied more broadly. I think it would be helpful to re-describe how the resolver uses this information (one tree at a time).

@cdjohnson
Copy link

I think we need a way to signal OLM to ignore the old properties if the new properties are present, or use the fact that there is an olm.all|any|none.required property at the top level to IGNORE the non-constraint properties at the top.

@cdjohnson I think this is a good idea for backwards-compatibility of bundles with OLM. The resolver can infer what to use by the presence of a compound constraint. I will say though, mixing both "legacy" and compound constraints in this way is confusing. I'll call out that this behavior needs to be documented and have warnings logged when this scenario is encountered.

@estroz I can think of a few alternatives:

  1. Force catalogs and bundles to introduce OLM-Version-Specific versions of itself. Not a fan of this if we can help it.
  2. Add an additional property to the legacy top-level value to explicitly ignore it by the "new compound-enabled resolver", to make it a bit more explicit.

Example:

- type: olm.package.required
  value:
    description:  This is for legacy versions of OLM.
    packageName: bar
    versionRange: '>=1.0.0'
    ignore: true

Old OLM versions ignore the ignore: true

@estroz
Copy link
Member Author

estroz commented Nov 12, 2021

Essentially each Tree of constraints is evaluated independently against each bundle. So, by having a Compound Constraint they must evaluate to TRUE for a single bundle. I was incorrectly (I hope) thinking that the compound constraints were applied more broadly.

Not exactly. A single bundle may never satisfy all constraints because one or more may reference GVKs/a package outside of that bundle's, so the resolver chooses a set of bundles from the universe (cluster) that satisfy all of a bundle's constraints.

I can think of a few alternatives

Thanks, it's worth calling out alternatives. I am not a fan of either approach though. The first makes ignoring top-level constraints in new OLM versions superfluous, since you're breaking backwards-compat anyway. The second adds a field with no context: why is this field ignored, and when should it be ignored?

There's a change currently being worked on by @dinhxuanvu in #91 that moves all constraints under the olm.constraints property. The "legacy" top-level constraints will be respected unless that property is defined, as we're discussing here. This change combined with docs and logs should raise this behavior's visibility appropriately.

Comment on lines 150 to 155
I also propose that `olm.gvk.required` and `olm.package.required` are redefined as
`gvk` and `package` fields to align with other properties under `olm.constraint`.
The only other difference between existing and new GVK/package constraint schemas
is the new schemas cannot be specified as top-level, non-compound fields; they must
always be housed under one of `all`, `any`, or `none`. Given this difference,
OLM will only interpret one set of schemas or the other as inputs to the resolver:
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it also be possible to have something like this:

type: olm.constraint
value:
  gvk:
    group: example.com
    version: v1
    kind: MyApp

Basically you can only use gvk and package within an olm.constraint value. But I don't think it should be required that these two types are nested within a compound constraint.

Copy link
Member Author

Choose a reason for hiding this comment

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

My thought process was that top-level constraints are always a conjunction, so why not make it explicit as all. I am ok relaxing this given most users will probably not need compound constraints.

Comment on lines 157 to 158
1. If at least one `olm.constraint` is present, interpret only `olm.constraint` properties
and ignore all other constraint properties.
Copy link
Member

Choose a reason for hiding this comment

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

So anyone wanting use to a cel expression from #91 would need to also translate their olm.gvk.required and olm.package.required properties to be olm.constraint properties with gvk and package sub-fields?

I'm trying to understand the motivation for new versions of OLM ignoring the existing root level olm.package.required and olm.gvk.required.

@joelanford
Copy link
Member

joelanford commented Nov 18, 2021

What effect does this EP have on the current GRPC API, which has requiredAPIs and dependencies fields in the Bundle object?

@estroz
Copy link
Member Author

estroz commented Nov 18, 2021

What effect does this EP have on the current GRPC API, which has requiredAPIs and dependencies fields in the Bundle object?

Is this change not being handled by #91? I would expect that olm.constraint's value is just sent wholesale over the gRPC API as a dependency, and requiredAPIs is left as-is since there isn't a good way to say what is required anymore. How would requiredAPIs be populated by a cel expression, for example?

@joelanford
Copy link
Member

Is this change not being handled by #91? I would expect that olm.constraint's value is just sent wholesale over the gRPC API as a dependency, and requiredAPIs is left as-is since there isn't a good way to say what is required anymore. How would requiredAPIs be populated by a cel expression, for example?

I'm not sure #91 specifically covered this topic. Maybe we should revisit it there?

In general, this all makes sense. I'm just worried about something on the consuming end that doesn't know that requiredGVKs and dependencies are now a little more complicated and may not fully describe the constraints like they used to. I wonder if these fields need to be deprecated from the GRPC API.

@estroz
Copy link
Member Author

estroz commented Nov 18, 2021

Since #91 introduced olm.constraint and cel we should revisit it there.

I wonder if these fields need to be deprecated from the GRPC API.

Agreed, and perhaps a constraints field should be added to the API with contains all requiredAPIs plus the serialized values of new constraints. This further enforces the idea that constraints are properties and arbitrary, but can now be explicitly differentiated from properties as olm.constraints.

@estroz
Copy link
Member Author

estroz commented Nov 19, 2021

Updates:

  • Allow gvk and package to be directly specified as olm.constraint values
  • OLM will interpret old and new constraints simultaneously
  • List OLM being able to choose between constraint schemas as an alternative

@estroz estroz requested a review from joelanford November 19, 2021 00:33
The above bundle `foo.v1.0.0` requires that both a bundle in package `bar` that is of at least
version 1.0.0 _and_ a bundle that provides the `EtcdBackup` API in group `etcd.database.coreos.com`
and at version `v1beta2`. The resolver will translate those constraints into a boolean expression
that is evaluated over all installed bundles's properties in the cluster; if both `bar` and `etcd`

Choose a reason for hiding this comment

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

Suggested change
that is evaluated over all installed bundles's properties in the cluster; if both `bar` and `etcd`
that is evaluated over all installed bundles' properties in the cluster; if both `bar` and `etcd`

kind: Foo
```

The maximum raw size of an `olm.constraint` is 64KB to limit resource exhaustion attacks.

Choose a reason for hiding this comment

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

Nice!

Copy link

@perdasilva perdasilva left a comment

Choose a reason for hiding this comment

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

lgtm - this is great work! Thank you for the amazing effort!

enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
enhancements/compound-bundle-constraints.md Outdated Show resolved Hide resolved
Signed-off-by: Eric Stroczynski <[email protected]>
@joelanford
Copy link
Member

/approve

@joelanford
Copy link
Member

/approve cancel

One last question is around Tech Preview vs. GA. I'm personally satisfied with the state of this EP being GA'd immediately. If others feel we need a release or two of Tech Preview time, I think we may need an update to this EP clarifying a few things about the Tech Preview state of this feature:

  • Is OLM upgradable if the feature is enabled?
  • How can a customer enable the feature gate? (OLMConfig object? CVO Unmanaged + manual change to OLM deployment?)
  • What would happen if a bundle specifies compound constraints but the feature is not enabled?

Signed-off-by: Eric Stroczynski <[email protected]>
@joelanford
Copy link
Member

/approve

Great work @estroz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants