Skip to content

ASP-based solver: account for deprecated versions#23491

Merged
tgamblin merged 1 commit intospack:developfrom
alalazo:fixes/clingo_deprecated_versions
May 12, 2021
Merged

ASP-based solver: account for deprecated versions#23491
tgamblin merged 1 commit intospack:developfrom
alalazo:fixes/clingo_deprecated_versions

Conversation

@alalazo
Copy link
Copy Markdown
Member

@alalazo alalazo commented May 7, 2021

fixes #22351

The ASP-based solver now accounts for the presence in the DAG of deprecated versions and tries to minimize their number at highest priority.

@alalazo alalazo added concretization bugfix Something wasn't working, here's a fix concretizer-use-case interesting dependency hierarchy that would challenge the current concretizer labels May 7, 2021
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 7, 2021

@eugeneswalker

@alalazo alalazo marked this pull request as ready for review May 7, 2021 09:25
@alalazo alalazo requested a review from tgamblin May 7, 2021 09:25
haampie
haampie previously approved these changes May 7, 2021
@haampie
Copy link
Copy Markdown
Member

haampie commented May 7, 2021

This is great, this means we have a strong guarantee that no deprecated packages will ever be installed, unless it is unavoidable by the constraints in the packages (e.g. ruby@:2.3)

Edit: i think this is even nicer; spack solve ruby@:2.3 toggles ~openssl to avoid installing a deprecated version :D you'd have to specify spack solve ruby@:2.3 +openssl to get a deprecated openssl.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 7, 2021

@haampie Yeah, the first priority of the solver is to avoid using deprecated versions. It must be obliged to do that to put one into the DAG 😆

@alalazo alalazo mentioned this pull request May 7, 2021
1 task
Copy link
Copy Markdown
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

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

Looks mostly good to me, but I think we should warn if a deprecated version was the only option. Can you add deprecated/1 to the shown atoms in display.lp and use that to show a warning if the result is deprecated?

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 7, 2021

@tgamblin I added a warning that currently looks like:
Screenshot from 2021-05-07 16-06-55

Let me know if you want it formatted differently

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented May 7, 2021

Do you think we should actually error out if only a deprecated version is possible? And have them run with --allow-deprecated or set a config option to allow it? It seems like we should be louder about this by default.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented May 7, 2021

You could imagine someone using this with a buildcache and —cache-only — it would make you add some config to your env if the only available versions end up being deprecated.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 7, 2021

Do you think we should actually error out if only a deprecated version is possible? And have them run with --allow-deprecated or set a config option to allow it?

For security related deprecations like openssl I would say definitely. Not sure about other software where versions are deprecated because of obsolete build systems or lack of some features.

What if we extend packages.yaml to have this in our defaults:

packages:
  all:
    allow_deprecated_versions: False

and allow people to either override this behavior or selectively opt-out with:

packages:
  glib:
    allow_deprecated_version: True

?

@haampie
Copy link
Copy Markdown
Member

haampie commented May 7, 2021

Or we could distinguish between 'vulnerable' and 'deprecated'? In case of openssl they deprecated 1.0 after the abi breaking 1.1 release, but only some and not all of 1.0 and 1.1 were known to be vulnerable.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented May 7, 2021

I like @haampie's suggestion but what if we just add a reason for deprecation?

version(..., deprecated="vuln")
version(..., deprecated="bug")
version(..., deprecated=True)

We could then decide on the solver side how to handle the different categories.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 7, 2021

Would this logic (in pseudo-code) be good:

if reason is True or reason == 'vuln':
    tty.die(msg)
tty.warn(msg)

?

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 7, 2021

With the last commit Spack will error out if deprecated == "True" or deprecated == "vuln":
Screenshot from 2021-05-07 18-24-05
and emit a warning for other reasons. No configuration handles at the moment.

@alalazo alalazo force-pushed the fixes/clingo_deprecated_versions branch from f80e027 to d96c7db Compare May 10, 2021 11:20
@alalazo alalazo requested a review from tgamblin May 10, 2021 12:10
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 10, 2021

@tgamblin This is ready for another review Pinging also @adamjstewart and @sethrj since this PR extends what done in #20767

* - 'bug'
- Serious bugs reported
* - 'unavailable'
- No longer available for download
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should there be an "unsupported" category indicating that the version series is no longer maintained and may eventually be incompatible with newer OS frameworks (often seen for GUI packages on macOS) or more strict compilers?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm absolutely open to modify this list, either adding new reasons or removing ones that are already there.The current implementation allows the use of any string as a deprecation reason, so adding new reasons in the future should just be matter of documenting them.

Copy link
Copy Markdown
Contributor

@sethrj sethrj left a comment

Choose a reason for hiding this comment

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

This is a nice new capability, but the deprecation strings probably need further thought, since the two main reasons ('bug' and 'vuln') are very open-ended and often overlapping.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 10, 2021

This is a nice new capability, but the deprecation strings probably need further thought, since the two main reasons ('bug' and 'vuln') are very open-ended and often overlapping.

Fair point, let me know if you have suggestions. I interpreted vuln as denoting software with vulnerabilities e.g. something in the CVE list, and bug as some bug not related to security e.g. some typo leading to numeric errors etc. but I agree this is not clear from docs.

@adamjstewart
Copy link
Copy Markdown
Member

I personally don't love this solution. As mentioned in https://spack.readthedocs.io/en/latest/packaging_guide.html#deprecating-old-versions, there are many different reasons why a version could be deprecated. I don't see any point in enumerating all of those reasons. Instead, I would keep deprecated as a Boolean and avoid it regardless of the reason for deprecation. That will keep the API simple and only involve minor changes to the optimization logic.

@sethrj
Copy link
Copy Markdown
Contributor

sethrj commented May 10, 2021

I tend to agree with @adamjstewart because of the potential granularity issues with descriptions. It might be helpful to look at a couple of example cases and try to classify how/why they'd be "deprecated". For example, OpenSSL regularly fixes bugs in older versions, but the bugs are various levels of severity. Similarly, its "vulnerabilities" are classified into levels of severity as well -- would you mark an older version with a significant bug and a minor vulnerability as deprecated='vuln' or 'bug'?

A simple boolean avoids having to ask those kind of difficult questions. A version should be non-deprecated if and only if it's the latest patch of a still-supported branch.

Examples:

  • HDF5 has version branches for 1.12, 1.10, 1.8 ; everything but the latest versions of those should be deprecated
  • OpenMPI lists 4.1 and 4.0 as "still supported", older versions are "retired" (last patch 18 Mar 2020) and should be deprecated.

However there might be room for a middle ground:

  • Qt has "official releases" for 5.12, 5.15, 6.0, and 6.1. Some apps require older Qt5 versions though and it would be useful to have e.g. a flag indicating that "version 5.9.234 is the last supported one so is less bad than choosing 5.10.123 which was actually released a year earlier". And even though Qt4 is ridiculously obsolete, we've been helping it limp along with patches because numerous software still requires it.
  • Likewise there's going to be a "long tail" for apps that haven't converted over from python 2, so it might be useful to mark the final version 2.7.18 as "less deprecated" than 3.1.5 .

...but again there we start worrying about granularity in the deprecation scale.

Ultimately I think this is like trying to give something a 5-star rating vs thumbs up/down. Fewer options tends toward less subjectivity in how a version will be graded.

@haampie
Copy link
Copy Markdown
Member

haampie commented May 10, 2021

Thinking about it a bit more, it seems to me that a concretization error for a deprecated package may be a bit too pedantic. (Maybe someone needs an old version of Ruby for some reason?) As long as it's explicitly confirmed by the user (which is the default already) it should be OK? In automated builds it'll fail unless you add the --deprecated flag (which nobody does by default...). And then distinguishing between different forms of deprecation might be unnecessary.

@sethrj
Copy link
Copy Markdown
Contributor

sethrj commented May 10, 2021

Oh I missed that the default is now to raise an error for deprecated versions. It seems to me that the config option should be a 'silent/verbose/error' choice when concretization results in deprecated packages. And that perhaps deprecated versions whose source is completely unavailable (heaven forfend) do need a special treatment that errors out on concretization rather than at fetch time... but then again there are the cases of externally installed packages as well as alternative source caches... so maybe fetch-time is the right way to handle that.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 10, 2021

I'm personally fine with any solution be it minimal or with more fine-grained control on what deprecation means. The first commit in this PR is sufficient for clingo to avoid using as much as possible deprecated versions (but won't prevent using them if that's the only choice). The following commits build on the first to give some handles to customize behavior (so user can decide to error on certain types of deprecation and warn on others). I'm also fine splitting this into two PRs if merging the first commit as a standalone is considered an option. Let me know how to proceed with that.

I don't see any point in enumerating all of those reasons. Instead, I would keep deprecated as a Boolean and avoid it regardless of the reason for deprecation.

I think the definition of "avoid" enters this PR. Would that mean "avoid if not absolutely necessary" or "error if I need to use a deprecated version"? What I can do as a middle ground is to move to concretization the behavior that is now in the fetcher:

  1. If deprecated: false Spack would error on concretization
  2. If deprecated: true Spack would just warn that you're using a deprecated version and proceed

and leave deprecated= as just a boolean. Would that be a sensible behavior for the use cases we are interested in?

@adamjstewart
Copy link
Copy Markdown
Member

I think it would be a good idea to split this into two separate PRs, it sounds like the first commit is non-controversial.

As for whether it should error or warn, I don't have a strong preference. If the only possible way to install a particular configuration is to use a deprecated version, I think we should allow that.

@alalazo alalazo force-pushed the fixes/clingo_deprecated_versions branch from d96c7db to 49e7c03 Compare May 11, 2021 13:12
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 11, 2021

Went back to a minimal version that tries to avoid deprecated versions and warn users if they end up in the spec.

sethrj
sethrj previously approved these changes May 11, 2021
adamjstewart
adamjstewart previously approved these changes May 11, 2021
tgamblin
tgamblin previously approved these changes May 11, 2021
Copy link
Copy Markdown
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

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

I think it's probably best to split this into two PRs as @adamjstewart said.

@tgamblin
Copy link
Copy Markdown
Member

@alalazo looks like this is now conflicted.

fixes spack#22351

The ASP-based solver now accounts for the presence
in the DAG of deprecated versions and tries to minimize
their number at highest priority.
@alalazo alalazo dismissed stale reviews from tgamblin, adamjstewart, and sethrj via 36b9f25 May 11, 2021 20:37
@alalazo alalazo force-pushed the fixes/clingo_deprecated_versions branch from 49e7c03 to 36b9f25 Compare May 11, 2021 20:37
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented May 12, 2021

@tgamblin Already split, conflict resolved

@tgamblin tgamblin merged commit fc2ac09 into spack:develop May 12, 2021
@alalazo alalazo deleted the fixes/clingo_deprecated_versions branch May 12, 2021 14:20
@haampie
Copy link
Copy Markdown
Member

haampie commented May 12, 2021

Thanks! :)

RikkiButler20 pushed a commit to RikkiButler20/spack that referenced this pull request Jun 9, 2021
fixes spack#22351

The ASP-based solver now accounts for the presence
in the DAG of deprecated versions and tries to minimize
their number at highest priority.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Something wasn't working, here's a fix concretization concretizer-use-case interesting dependency hierarchy that would challenge the current concretizer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clingo should try harder to avoid deprecated packages

5 participants