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

Add new "semver" constraint #6699

Merged
merged 4 commits into from
Nov 19, 2019
Merged

Add new "semver" constraint #6699

merged 4 commits into from
Nov 19, 2019

Conversation

schmichael
Copy link
Member

@schmichael schmichael commented Nov 13, 2019

The existing version constraint uses logic optimized for package
managers, not schedulers, when checking prereleases:

  • 1.3.0-beta1 will not satisfy ">= 0.6.1"
  • 1.7.0-rc1 will not satisfy ">= 1.6.0-beta1"

This is due to package managers wishing to favor final releases over
prereleases.

In a scheduler versions more often represent the earliest release all
required features/APIs are available in a system. Whether the constraint
or the version being evaluated are prereleases has no impact on
ordering.

This commit adds a new constraint - semver - which will use Semver
v2.0 ordering when evaluating constraints. Given the above examples:

  • 1.3.0-beta1 satisfies ">= 0.6.1" using semver
  • 1.7.0-rc1 satisfies ">= 1.6.0-beta1" using semver

Since existing jobspecs may rely on the old behavior, a new constraint
was added and the implicit Consul Connect and Vault constraints were
updated to use it.

@dadgar
Copy link
Contributor

dadgar commented Nov 14, 2019

@schmichael Is it not just a bug in go-version? Doesn't this https://semver.org/#spec-item-11 state that precedence is defined left to right? So given our constraint is 0.6.1 and the current version is 0.13.1-beta1, you would see 6 < 13?

@dadgar
Copy link
Contributor

dadgar commented Nov 14, 2019

This comment gives more details: hashicorp/go-version#36 (comment)

I guess for Terraform this makes... sense? I worry that the two constraints are so nearly identical it will be confusing to have both. Did you talk to James Bardin to see if removing the prerelease constraints is something they'd be willing to do or if it is a hard requirement for Terraform?

@schmichael
Copy link
Member Author

schmichael commented Nov 14, 2019

I guess for Terraform this makes... sense?

Yes, that was the internal consensus. The current go-version behavior is modelled after npm where if you have a constraint of ">= 1.0" and the package is at "1.1-beta1", you'd rather download "1.0" than use a prerelease.

Nomad and other non-package-manager use cases just don't have the luxury of being able to download an artifact to satisfy missing constraints, so it's a different situation.

Likewise I completely dropped the ~> pessimistic operator because I feel like it only makes sense for package managers who are likely able to download the "right" version of a package if the constraint isn't immediately satisfied.

I worry that the two constraints are so nearly identical it will be confusing to have both.

Indeed. I just didn't see an alternative. Nomad doesn't even define the behavior of version in our docs: we instead point users to the go-version library directly. I can't imagine why someone would be relying on this behavior, but they may be relying on it without even knowing (eg some machines have prereleases of nvidia drivers that cause them to only get used when jobs specifically target that prerelease).

Did you talk to James Bardin to see if removing the prerelease constraints is something they'd be willing to do?

Yup, and Martin on the Terraform team. Martin wasn't too excited about me calling it "semver" because technically semver only covers ordering/precedence, and does not explicitly cover constraints semantics. I chose it anyway because (a) I couldn't think of another name that was less confusing and (b) reading the semver spec is sufficient to understand the operator's behavior.

helper/semvercon/semvercon.go Outdated Show resolved Hide resolved
helper/semvercon/semvercon.go Outdated Show resolved Hide resolved
helper/semvercon/semvercon.go Outdated Show resolved Hide resolved
helper/semvercon/semvercon_test.go Outdated Show resolved Hide resolved
scheduler/feasible.go Show resolved Hide resolved
scheduler/feasible.go Show resolved Hide resolved
scheduler/feasible.go Outdated Show resolved Hide resolved
@@ -601,7 +606,7 @@ func checkLexicalOrder(op string, lVal, rVal interface{}) bool {

// checkVersionMatch is used to compare a version on the
// left hand side with a set of constraints on the right hand side
func checkVersionMatch(ctx Context, lVal, rVal interface{}) bool {
func checkVersionMatch(ctx Context, parse VerConstraintParser, lVal, rVal interface{}) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Love how DRY you made this 🎉

scheduler/feasible.go Outdated Show resolved Hide resolved
scheduler/feasible.go Outdated Show resolved Hide resolved
@dadgar
Copy link
Contributor

dadgar commented Nov 18, 2019

@schmichael Looking really good. Feel free to ping when you want the final review (its still marked draft so I assume you have some more changes?)

The existing version constraint uses logic optimized for package
managers, not schedulers, when checking prereleases:

- 1.3.0-beta1 will *not* satisfy ">= 0.6.1"
- 1.7.0-rc1 will *not* satisfy ">= 1.6.0-beta1"

This is due to package managers wishing to favor final releases over
prereleases.

In a scheduler versions more often represent the earliest release all
required features/APIs are available in a system. Whether the constraint
or the version being evaluated are prereleases has no impact on
ordering.

This commit adds a new constraint - `semver` - which will use Semver
v2.0 ordering when evaluating constraints. Given the above examples:

- 1.3.0-beta1 satisfies ">= 0.6.1" using `semver`
- 1.7.0-rc1 satisfies ">= 1.6.0-beta1" using `semver`

Since existing jobspecs may rely on the old behavior, a new constraint
was added and the implicit Consul Connect and Vault constraints were
updated to use it.
@schmichael schmichael marked this pull request as ready for review November 19, 2019 16:48
@schmichael schmichael self-assigned this Nov 19, 2019
@schmichael schmichael added this to the 0.10.2 milestone Nov 19, 2019
@schmichael
Copy link
Member Author

@dadgar Ready for final review. Rebased on master, squashed commits, added docs.

Copy link
Member

@tgross tgross left a comment

Choose a reason for hiding this comment

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

LGTM

helper/constraints/semver/constraints_test.go Show resolved Hide resolved
@schmichael
Copy link
Member Author

Going to merge to get the 0.10.2-rc1 train rolling, but there's still time to address any feedback you might have in a followup @dadgar

@schmichael schmichael merged commit 6275132 into master Nov 19, 2019
@schmichael schmichael deleted the f-semver-constraints branch November 19, 2019 20:18
Copy link
Contributor

@dadgar dadgar left a comment

Choose a reason for hiding this comment

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

LGTM

@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants