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

[RFC 0127] Nixpkgs "problem" infrastructure #127

Merged
merged 25 commits into from
Jul 12, 2023
Merged
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
60cb23d
[RFC 0127] Nixpkgs issues and warnings (#127)
piegamesde Jun 11, 2022
ee72999
Add URLs as structured information
piegamesde Jun 15, 2022
c109c31
Update rfcs/0127-issues-warnings.md
piegamesde Sep 12, 2022
ff2e2d4
Update rfcs/0127-issues-warnings.md
piegamesde Sep 12, 2022
f83067a
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
2daf978
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
2b63424
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
e5c0e13
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
3212d31
RFC 127 update shepherds
piegamesde Sep 13, 2022
ecdbe2c
RFC 127 rework
piegamesde Sep 13, 2022
c907adb
Point out that the previous warnings system was not documented
piegamesde Sep 13, 2022
d232a2d
Rework ignore mechanism
piegamesde Sep 17, 2022
ff6e33d
Update rfcs/0127-issues-warnings.md
piegamesde Oct 14, 2022
6ffce6d
Update rfcs/0127-issues-warnings.md
piegamesde Oct 14, 2022
24a8985
Remove "resolved" attribute again
piegamesde Oct 15, 2022
1b1424e
Incorporate review feedback
piegamesde Oct 15, 2022
1e6725e
Rewrite (again)
piegamesde Dec 12, 2022
81564e6
Rename throw->error, trace->warn
piegamesde Jan 21, 2023
c5c64ec
Make meta.problems an attrset
piegamesde Jan 31, 2023
2a78241
Rewrite *again*, most change is in the configuration options
piegamesde Apr 28, 2023
4f311de
Review update (WIP)
piegamesde May 15, 2023
b253df1
Review update
piegamesde May 30, 2023
7939f49
Update shepherds list
piegamesde Jun 1, 2023
33ec9a6
Meeting update
piegamesde Jun 19, 2023
83319ec
Typos
piegamesde Jun 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
294 changes: 294 additions & 0 deletions rfcs/0127-issues-warnings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
---
feature: issues-warnings
start-date: 2022-06-11
author: piegames
co-authors: —
shepherd-team: @lheckemann, @mweinelt, @fgaz
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
shepherd-leader: @mweinelt
related-issues: https://github.com/NixOS/nixpkgs/pull/177272
---

# RFC: Nixpkgs "problem" infrastructure

## Summary
[summary]: #summary

Inspired by the various derivation checks like for broken and insecure packages, a new system called "problems" is introduced. It is planned to eventually replace the previously mentioned systems where possible, as well as the current – undocumented – "warnings" (which currently only prints a trace message for unmaintained packages). A `config.problemHandler` and `problemHandlerDefaultMatchers` option is added to the nixpkgs configuration, with centralized and granular control over how to handle problems that arise: "error" (fail evaluation), "warn" (print a trace message) or "ignore" (do nothing).

Additionally, `meta.problems` is added to derivations, which can be used to manually declare that a package has a certain problem. This will then be used to inform users about packages that are in need of maintenance, for example security vulnerabilities or deprecated dependencies.

Using the newly introduced features, we may create a process for removing packages from nixpkgs that is easier to maintain and friendlier to users than just replacing packages with `throw` directly.

## Motivation
[motivation]: #motivation

Nixpkgs has the problem that it is often treated as "append-only", i.e. packages only get added but not removed. There are a lot of packages that are broken for a long time, have end-of-life dependencies with known security vulnerabilities or that are otherwise unmaintained.

Let's take the end of life of Python 2 as an example. (This applies to other ecosystems as well, and will come up again and again in the future.) It has sparked a few bulk package removal actions by dedicated persons, but those are pretty work intensive and prone to burn out maintainers. A goal of this RFC is to provide a way to notify all users of a package about the outstanding issues. This will hopefully draw more attention to abandoned packages, and spread the work load. It can also help soften the removal of packages by providing a period for users to migrate away at their own pace.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

For some use cases, like for packages without maintainers, we do not want to break evaluation of a package and simply warn the user instead. We want the users to configure all these according to their needs and through a single standardized interface.

## Detailed design
[design]: #detailed-design

### Package problems

A new attribute is added to the `meta` section of a package: `problems`. If present, it is a an attribute set of attrsets which each have at least the following fields:

- `kind`: The 'kind' of the problem, see [problem kinds](#problem-kinds) for allowed values. Defaults to the attribute set key.
- `message`: Required. A string message describing the issue with the package. The value should:
- Start with the "This package", "The application" or equivalent, or simply with the package name.
- Be capitalized (unless it starts with the package name).
- Use a period at the end.
- `date`: Required. An ISO 8601 `yyyy-mm-dd`-formatted date from when the issue was added.
- `urls`: Optional, list of strings. Can be used to link issues, pull requests and other related items.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

Problem kinds may specify additional attributes. Apart from that, other attributes are not allowed.

Example values:

```nix
meta.problems = {
# This one will have the name "python2-eol"
python2-eol = {
kind = "deprecated";
message = "This package depends on Python 2, which has reached end of life.";
date = "1970-01-01";
urls = [ "https://github.com/NixOS/nixpkgs/issues/148779" ];
};
# This one will have the name "removal"
removal = {
# kind = "removal"; # Inferred from attribute key
message = "The application has been abandoned upstream, use libfoo instead.";
date = "1970-01-01";
};
};
```

### Problem kinds
Copy link
Member

Choose a reason for hiding this comment

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

I think this section should introduce the different handler values and show the default one for each problem kind.


At the moment, the following values for the `kind` field of a warning are known:

- `removal`: The package is scheduled for removal some time in the future.
- `deprecated`: The package has been abandoned upstream or has end of life dependencies.
Copy link
Member

@infinisil infinisil May 15, 2023

Choose a reason for hiding this comment

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

I don't think packages that have EOL dependencies should be marked as deprecated, they can still be maintained while having EOL dependencies.

Suggested change
- `deprecated`: The package has been abandoned upstream or has end of life dependencies.
- `deprecated`: The package is deprecated or abandoned upstream.

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 general concept here is correct, although I agree that the name may be misleading. The representative use case for "deprecated" is the Python 2 EOL: some packages can be fixed by upgrading to Python 3 or otherwise removing the Python 2 dependency, others are probably hopeless and doomed.

they can still be maintained while having EOL dependencies.

IMO it's the other way around: packages with EOL dependencies are in need of maintenance

Copy link
Member

Choose a reason for hiding this comment

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

Also, EOL packages receive security fixes or maintenance only via paid subscriptions usually.

Copy link
Member

Choose a reason for hiding this comment

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

(But I'm open to an EOL explicit flag.)

Copy link

@bew bew Jun 19, 2023

Choose a reason for hiding this comment

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

Hello, came to read the rfc after fcp was announced, this is the only thing that bugged me while reading..

It seems there was no conclusion to this comment.

The distinction can be hard to grasp, but I think deprecated and eol/obsolete are clearly different and should be handled differently.

Mozilla's JS docs uses deprecated/obsolete here:

deprecated: still available but planned for removal
obsolete: no longer usable

To me (french, not english-native), obsolete also means that something else took its place. eol would be stronger and wouldn't mean that.

Random guy on english stackexchange says:

Deprecated is more or less a "marker", saying that it should not be used, something else that has the same effect has been created, and it is soon to be deleted. It may still work as expected, but it will vanish soon.
Obsolete means that it no longer works as expected, or doesn't do anything at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

@bew, I don't see how this distinction is relevant in this context. The idea behind "deprecation" is, that some package has a problem related to software for which upstream dropped support, and thus needs fixing or removal. Whether or not it currently works is not relevant to me, since this is from a maintainer perspective and not a user perspective.

Copy link
Member

Choose a reason for hiding this comment

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

While I wanted also a distinction, I feel like it's not that important from a maintainer perspective, and I agree with @bew ; though, if, in practice, we found ourselves wanting more, we can always discuss this after extensive experience with that RFC in production.

Copy link

@bew bew Jun 21, 2023

Choose a reason for hiding this comment

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

Ok for the distinction between deprecated/obsolete/eol.

I'm now also thinking about the wording vs semantic difference between removal and deprecated.

Something that is marked for removal should not be used anymore, this actually looks like the definition of deprecated 🤔

Might be confusing, maybe we can rename:

  • removal to deprecated (or don't use rhe word deprecated at all?)
  • deprecated to obsolete/eol

What do you think? @piegamesde @RaitoBezarius

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 fine with changing names as long as we keep the originally intended semantics. I'd prefer to keep "removal" because it's for things "that are about to be removed" so I find it quite fitting. "removal" is a least resort measure, and "deprecated" would be too weak of a word for it.

I'd be fine with renaming "deprecated" to "obsolete" or "eol". Personally I don't mind "deprecated" and don't think the alternatives are a big improvement, but they're fine so if people prefer it we can do that.

- `maintainerless`: `meta.maintainers` is empty. Cannot be manually declared in `meta.problems`.
- `insecure`: (Reserved for future use.) The package has some security vulnerabilities.
- `broken`: (Reserved for future use.) The package is broken in some way.
- `unsupported`: (Reserved for future use.) The package is not expected to build on this platform.

Not all values make sense for declaration in `meta.problems`: Some may be automatically generated from other `meta` attributes (for example `maintainerless`). New kinds may be added in the future. Furthermore, some kinds are expected to be present only up to once per derivation: for example, we have no use for having multiple `maintainerless` problems.

### Nixpkgs configuration

The following new config options are added to nixpkgs: `config.problemHandler` and `config.problemHandlerDefaultMatchers`. The (currently undocumented) option `config.showDerivationWarnings` will be removed.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

Handler values can be either `"error"`, `"warn"` or `"ignore"`. `"error"` maps to `throw`, `"warn"` maps to `trace`. Future values may be added in the future.

`config.problemHandlers` is the simple and most user-facing configuration value. It is a simple doubly-nested attribute set, of style `pkgName.problemName`. The package name is taken from `lib.getName`, which currently yields its `pname` attribute.

```nix
config.problemHandlers = {
myPackage.maintainerless = "warn";
otherPackage.CVE1234 = "ignore";
}
```

Some times, there is the need to set the handler for multiple problems on a package, or for one problem kind across all packages. For this, `config.problemHandlerDefaultMatchers` exists. It is a list of matchers (currently package name, problem name or problem kind), with an associated handler. If multiple matchers match a single package, the one with the highest level (error > warn > ignore) will be used. Since the user configuration is merged with the default configuration, this means that one can not decrease the handler level below the default value. This is to protect users against accidentally disabling entire classes of notifications. Values from `config.problemHandlers` take precedence.

```nix
config.problemHandlerDefaultMatchers = [
{ # Wildcard matcher for everything
handler = "warn";
}
{ # Match all security warnings on "hello"
package = "hello";
kind = "insecure";
handler = "error";
}
{ # Match all packages affected by the python2 deprecation
name = "python2-eol";
handler = "error";
}
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
{ # Has no effect: the default value is higher
kind = "insecure";
handler = "ignore";
}
{ # Disallowed: Non-wildcards are better handled by using `problemHandlers` instead
# The equivalent would be: `config.problemHandlers.hello.CVE1234 = "error";
package = "hello";
name = "CVE1234";
handler = "error";
}
]
```

To make it more explicit, a matches is an attribute set which may contain the following fields:

- `package`: Match only problems of a specified package.
- `kind`: Match only problems of a specific kind.
- `name`: Match only problems with a specific name.
- `handler`: Required. Sets the level for packages that have been matched by this matcher.

## Examples and Interactions
[examples-and-interactions]: #examples-and-interactions

### Propagation across transitive dependencies

When a package has a problem that `throw`s, all packages that depend on it will fail to evaluate until that problem is ignored or resolved. Most of the time, this is sufficient.

When the problem requires actions on dependents however, it does not sufficiently inform about all packages that need action. Multiple packages may be annotated with the same problem, in that case it should be given a name and the name should be the same across all instances. Other values like the message or the URL list do not need to be the same and may be adapted sensibly.

### Backwards compatbility, Backporting and stable releases

New problems generally should not be added to stable branches if possible, and also not be backported to them, since it may break evaluation. The same rule applies to other changes to a package or its `meta` which may generate a problem and thus lead to evaluation failure too. Scenarios where evaluation failure is a desired goal, for example with unfixable security issues, are obviously exempt from this.

### Removal of packages

The plan is to eventually remove packages with long outstanding problems of some kinds. The details will be part of future work, but users will be warned sufficiently in advance to give them the chance to intervene.

If a package needs to be removed for some other reason, the problem kind `removal` should be used instead:
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

```nix
meta.problems = {
removal = {
message = "This package will be removed from Nixpkgs.";
date = "1970-01-01";
};
};
```

## Drawbacks
[drawbacks]: #drawbacks

- Too much warnigns may cause Alarm fatigue
Copy link

Choose a reason for hiding this comment

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

When I was deciding between gentoo and nixpkgs, this was the major strike against gentoo. The OS sends you email. And you sort of have to read it, because all the other users do.

That, plus wanting less Python in my life rather than more, is what tipped the balance.

Let's not go that way.

Copy link
Member Author

Choose a reason for hiding this comment

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

Currently, nixpkgs errs on the other side of the spectrum. It is difficult for you to get notified about changes you care about, especially on the unstable channel. This RFC has started because people wanted to do some backwards-incompatible changes but did not have a good way to properly inform all stakeholders.

piegamesde marked this conversation as resolved.
Show resolved Hide resolved
- One idea I had is to be more verbose on the unstable channels, and then tune down the noise after branch-off.
- New lints to packages should be introduced gradually, by making them "silent" by default on start and only going to "warn" after most problems in nixpkgs itself are resolved.
- People have voiced strong negative opinions about the prospect of removing packages from nixpkgs at all, especially when they still *technically* work.
- We do not want to encourage the use of unmaintained software likely to contain security vulnerabilities, and we do not have the bandwidth to maintain packages deprecated by upstream. Nothing is lost though, because we have complete binary cache coverage of old nixpkgs versions, providing a comparatively easy way to pin old very package versions.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
Copy link

@ghost ghost Jan 21, 2023

Choose a reason for hiding this comment

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

We do not want to encourage the use of unmaintained software

This "unmaintained" boogeyman is a problem endemic to poorly-scoped software. Cough cough browsers cough.

dnscache, tinydns, and runit have been "unmaintained" for over a decade and work better than most of their competitors. The same is true of unfs3, but its alternatives (i.e. in-kernel nfs) can't be run in an unprivileged sandbox, which turns the whole unmainained==insecure on its head.

Is this RFC going to affect their presence in nixpkgs?

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 is not the kind of "unmaintained" the sentence is referring to. Yes, eventually people may start to enforce maintainers != [] using the features provided by this RFC if they want to, but this will be a new and separate discussion for sure.

This sentence is about all a) packages that are effectively unmaintained, i.e. they require some work to keep going but there is nobody and b) packages that are unmaintained or abandoned by upstream with no hope of fixing.

And no, "unmaintained" does not imply it's insecure by any means. Personally, I'd like to get to a point where we treat "end of life" as kind-of insecure. And this is not only about security, but also about workload: I do not want us to patch things on software if it is end of life, instead we should have a graceful way of removing it from nixpkgs.

- This change is a general improvement in the ecosystem even if we do not end up using it to remove any packages.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- "in-band" maintenance of this data means that users have to upgrade their nixpkgs to become aware of new issues.
- The proposed approach has significantly less overhead than designing and maintaining a separate database along with tools to combine its data with nixpkgs. We are open to an alternative approach in the future, but do not want to incur such high maintenance costs at this time.

Copy link
Member Author

Choose a reason for hiding this comment

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

Add as sub-point: out of band warnings would be impure if they stopped evaluation like they currently do.

Copy link
Member

Choose a reason for hiding this comment

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

I imagine such a tool not blocking evaluation at all, but providing the metadata, comparing it to local policy, annotating the drvs produced with said metadata, and (when used interactively) providing a "continue anyway" knob if anything happens that's not already permitted by local policy.

I don't count that as an impurity, since I don't want it to be able to modify the evaluation results at all -- only observe evaluation and decide what to do afterwards (which also allows getting all the warnings at once, and displaying all those that local policy considers as "blocking" at once).

## Alternatives
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
[alternatives]: #alternatives

This project has gone through multiple iterations, and grown quite in scope during that. Therefore this section doubles a chronology of previous attempts of implementing it.

Alternative to the current solution, we could just continue to add new systems to `check-meta.nix` when specific use cases arise. The downside is that they are mostly similar yet not 100% consistent, resulting in both code duplication and user confusion.

The original proposal only wanted to deal with eval-breaking problems, and grew in scope since. Removing warnings from the equation makes the implementation simpler, however we would then miss out on things like tracing aliases. Maybe we should have a distinct mechanism for evaluation warnings.

The following sections discuss alternative ways of implementing the current feature proposal.

### Naming

A lot of names have been considered so far for this feature, currently "problems" is the "least bad" proposal.

- Problem: Extremely generic "kind of fits all use cases but not that well" word
- Issue: Colliding with GitHub issues
- Warning: People might expect that it would never break evaluation
- Error: This is too harsh of a word for things that are minor issues, like unmaintained packages
- Advisory: Too focused on security issues

Consider that the name should work as well as possible for all of the following cases, even if there are no current plans to replace all of these with our new feature: "removal", "deprecated", "maintainerless", "insecure", "broken", "unsupported", "unfree".

### Problem declaration

*n.b.: the terminology of the feature has multiple times since the earlier proposals were made*

An alternative design would be to have issues as a separate list (not part of the package). ~~Instead of allowing individual packages, one could ignore individual warnings (they'd need an identifying number for that). The advantage of doing this is that one could have one issue and apply it for a lot of packages (e.g. "Python 2 is deprecated"). The main drawback there is that it is more complex.~~ The advantages of that approach have been integrated while keeping the downsides small: Warnings are ignored with a per-kind granularity, but one may give some of them a name to allow finer control where necessary.

A few other sketches about how the declaration syntax might look like in different scenarios:

```nix
{
# Using a list instead of attribute set. Slightly less complexity, but also slightly more verbose.
meta.issues = [{
kind = "deprecated";
name = "python2-eol";
message = "deprecation: Python 2 is EOL. #12345";
# (Other fields omitted for brevity)
}];

# Issues are defined elsewhere in some nixpkgs-global table, only get referenced in packages
meta.issues = [ "1234-python-deprecation" ];

# Attempt to unify both approaches to allow both ad-hoc and cross-package declaration
meta.issues = {
"1234-python-deprecation" = {
message = "deprecation: Python 2 is deprecated #12345";
};
};

# Proposal by @matthiasbeyer
meta.issues = [
{ transitive = pkgs.python2.issues }
];
}
```

Some more design options that were considered:

```nix
meta.problems = {
"deprecated/python2-eol" = {
message = "This package depends on Python 2, which has reached end of life.";
date = "1970-01-01";
urls = [ "https://github.com/NixOS/nixpkgs/issues/148779" ];
};
removal = {
message = "The application has been abandoned upstream, use libfoo instead";
date = "1970-01-01";
};
};

meta.problems = {
"deprecated" = [{
name = "python2-eol";
message = "This package depends on Python 2, which has reached end of life.";
date = "1970-01-01";
urls = [ "https://github.com/NixOS/nixpkgs/issues/148779" ];
}];
removal = {
message = "The application has been abandoned upstream, use libfoo instead";
date = "1970-01-01";
};
};
```

These have the advantage of enforcing the presence of a name if there are multiple problems of the same kind, at the cost of some additional nesting in those cases.

### Problem resolution

On the nixpkgs configuration side, the first iteration used a generic "predicate" system for ignoring packages, similar to `allowUnfreePredicate` and `allowInsecurePredicate`. This turned out to be both too flexible and not convenient enough to use, so this was complemented with a list of packages to ignore and "smart" default values generation.

A second approach used a list type: `list of ("packageName.warningKind" or "packageName.*" or "*.warningKind" or "*.*")`. This was a binary choice (compared to the ternary value today), with an additional boolean `traceIgnoredWarnings` option. One downside is that it does not allow granular control over warnings, only evaluation failures. A bigger issue is that due to how the merge rules on lists work, it would have been difficult to provide good default values for the nixpkgs confinguration while keeping backwards compatibility.

A third approach used a two-level attribute set, similarly to the list above, but with the value setting the handler instead of it being a binary choice. `"*"."*" = "error";`, `myPackage."*" = "ignore";`, `"*".maintainerless = "ignore";`, etc. This provides better merging behavior than a list, while also being more granular. However, people voiced concerns about people accidentally wildcard-ignoring everything. Also, it is ambiguous on matching problem name vs problem kind, which mostly works fine but might lead to weird things happening in the case where new kinds are introduced.

## Unresolved questions
[unresolved]: #unresolved-questions

- ~~From above: "Ignoring a package without issues (i.e. they have all been resolved) results in a warning at evaluation time". How could this be implemented, and efficiently?~~
- ~~More generally, how do we tell users that their ignored warning can be removed, so that they won't accidentally miss future warnings?~~
- ~~Issues have a `resolved` attribute that may be used for that purpose.~~
- Properly implementing this turned out to be non-trivial, so this feature was cut for the sake of simplicity as it was not of high importance anyways.
- The ignore mechanism has been refined so that there is less risk of missing future warnings.
- ~~Should issues be a list or an attrset?~~·
- ~~We are using a list for now, there is always the possibility to also allow attrsets in the future.~~
- Current design uses an attribute set
- Currently, many of the relevant nixpkgs configuration options can also be set impurely via environment variables. The `config.problemHandler` option does however not easily map to some environment variable.
- When merging existing features into the problems system, existing environment variable will keep working in the future.
- Maybe using less environment variables is all for the better?
- We may always add specific environment variables for specific use cases where needed without having to expose the full expression power of the configuration options.

Choose a reason for hiding this comment

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

I consider environment variables to overwrite the "refusing of evaluation" quite important.
For example, i quite often install packages with nix profile (previously with nix-env), because it is faster and i don't want to edit my NixOS configuration for these minor package additions. I also use allowUnfreePredicate to only enable some unfree Packages. Sometimes the need arises to install an unfree package with nix profile, so i do

env NIXPKGS_ALLOW_UNFREE=1 nix profile install --impure nixpkgs#hello-unfree

I haven't done that for broken packages, yet, but i can imagine it being an inconvenience if it wasn't possible for the issue handlers to be overwritten impurely.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just to be clear: Existing environment variables will continue working.

Copy link
Member

Choose a reason for hiding this comment

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

At the same time, they will be the only way to mass-override unsupported?

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 not sure I understand your question. Why the only way?

Copy link
Member

Choose a reason for hiding this comment

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

Can you lower from error to warn via matchers? I thought that handlers need to be package-by-package, and matchers cannot lower severity below the default?

(Presumably if unsupported replaces platforms it defaults to error)

Copy link
Member

Choose a reason for hiding this comment

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

That's a good point. Arguably problems like unsupported or broken should be safe to ignore generally, while insecure ones aren't..

Maybe the distinction here is that unsupported and broken are errors at evaluation time that would otherwise happen at build/runtime, while insecure wouldn't give any other error.

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've personally almost never interacted with unsupported and only rarely with broken, do you think that not being able to mass-disable them is a big issue?

On the other hand, my previous design for this RFC included some pretty YOLO wildcard capabilities, so I'll have no problems with selectively relaxing the "no downgrade" restriction should there be need for it.

Also, for better or for worse, the existing environment variables will keep working for a long time due to backwards compatibility. It's a bit weird, but there's nothing we can really do about it.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe some thing can be downgraded to warn but not to nothing.

The use case for mass-overriding unsupported/broken/etc. is e.g. «so with the new and improved stdenv for this kind of BSD which has partial Linux compatibility, which of the presumed-Linux-only-packages will now build?»

Sure, on non-cross Linux broken usually is in some connection to reality; for new or reworked exotic stdenvs (Tier 3 or 4 platforms, including cross or maybe musl or whatever) «there were reasons to guess Linux-only or x86_64-only, and nobody had a setup to try» is pretty normal and quickly estimating the amount of work to get something working is useful.


## Future work
[future]: #future-work

- The actual process of removing packages is only sketched out here to show how the new infrastructure may improve the situation. It is intentionally left as vague as possible, and details should be figured out in a follow-up discussion.
- The problems system is designed in a way that it supersedes a lot of our "insecure"/"unfree"/"unsupported" packages infrastructure. There is a lot of code duplication between them. In theory, we could migrate some of these to make use of problems. At the very least, we hope that problems are general enough so that no new similar features will have to be added in the future anymore.
- Migrating the existing systems may end up being tricky due to backwards compatibility issues.
- Inspired by the automation of aliases, we could build tooling for this as well. This is deemed out of scope of this RFC because only real world usage will tell which actions will be worthwhile automating, but it should definitely be considered in the future.
- There will likely be need for tooling that lists problems on all nixpkgs packages, filtered by kind or sorted chronologically.
- Automatically removing packages based on time will likely require providing more information whether it is safe to do so or not.
- > If the advisories were a list, and we also added them for modules, maybe we could auto-generate most release notes, and move release notes closer to the code they change. [[source]](https://discourse.nixos.org/t/pre-rfc-package-advisories/19509/4)
- Issues can certainly be automatically integrated into the release notes somehow. However, this alone would not allow us to move most of our release notes into the packages, because for many release entries breaking eval would be overkill.
- There has been discussion about introducing "tracing aliases", aliases that don't `throw` by default. Such an implementation may make use of the problem infrastructure.