Only reuse externals when configured#41707
Conversation
c7b8824 to
490d068
Compare
490d068 to
6ee7e9a
Compare
becker33
left a comment
There was a problem hiding this comment.
We should add this to the upcoming major changes pinned discussion.
Also, I think we should include a feature to add all the externals associated with a given spec to be added to the config. For example, if I specify spack install foo ^bar/hash. Under this feature I may get an error that bar/hash depends on an external that is no longer configured. We should have an easy one-liner from that point to add the relevant externals to my config.
|
ping @alalazo who prefers when the database is the single source of truth instead of config files |
d6acbaa to
e36375a
Compare
bbccfa9 to
a91349e
Compare
|
@haampie as I was thinking about this more last night, I realized this would require additional functionality to add the externals from the cray manifest file to the packages configuration in addition to the database. This might prove tricky, since the cray externals from the manifest can have dependency information, and we don't currently allow dependency information from externals in the packages config. Allowing dependencies on externals looked challenging last time I looked at it, but I can take another stab at it now. The other option would be some more complex mapping between the externals in the database and the externals in the config. For example, externals in the db could store the yaml block in which they were defined, which would make identifying the correct external possible even if there are multiple satisfying externals |
|
I didn't think of the cray manifest at all, that's a bit of a blocker. |
|
@becker33 can't we keep track of how externals were added and use that to determine reuse or not? That could also help with undoing an import from a cray config file. I agree that migrating entries from db to config works, but doesn't really sound great. I don't understand what you meant with that |
|
I'll add my thoughts on this:
As for a more long term way forward, I still advocate for an intermediate DB to store externals. That will:
Footnotes
|
we don't keep track what file was used, so maybe easier to mark externals from config as such so we can apply different reuse conditions. Idk how to deal with reuse from build cache with imported cray manifest entries, that doesn't work now 🤔 currently I think that is fine; shouldn't affect many users, and if we allow reuse there, it can cause the same issue fixed by #35975 |
☝🏻 this times 💯. Maybe this is crazy talk, but I wish externals could be implemented as an in-memory artifact rather than registering them in a database. I'm sure in practice this is hard to do, but in principle that seems closer to reality. An external is not a spack artifact, just a spack registration. When system externals shift under us they usually affect low level specs that require a lot of rebuilding across the DAG. Often times the best thing to do is just delete everything and start from scratch. (Especially if uninstalling by hash is the other option 😝 ). If the system changed then spack's database is not valid anymore wrt to the external even if nothing changed in spack. AND the only way spack will be able to detect these changes ATM is if the users tell it. |
Users often learn the hard way that removing or modifying an external in packages.yaml is not enough to avoid an external from getting pick up in concretization. Since this such a footgun, and gets reported almost every week on Slack, I think it makes sense and is pretty clean to apply the same reuse rule we already apply to build caches also to the local database: only reuse those externals that are in config.
a91349e to
69f8add
Compare
|
Pushed that change |
becker33
left a comment
There was a problem hiding this comment.
This all looks perfect except it should have a test for local=True with a DB entry with origin="external-db".
4046965 to
6e4d555
Compare
6e4d555 to
d6b4470
Compare
Users expect that changes to the externals sections in packages.yaml config apply immediately, but reuse concretization caused this not to be the case. With this commit, the concretizer is only allowed to reuse externals previously imported from config if identical config exists.
Users expect that changes to the externals sections in packages.yaml config apply immediately, but reuse concretization caused this not to be the case. With this commit, the concretizer is only allowed to reuse externals previously imported from config if identical config exists.
Closes #40843
Followup to #35975
Users often learn the hard way that removing or modifying an external in
packages.yaml is not enough to avoid the original external from getting
picked up in concretization. To users it feels like their config changes have
no effect, or they think that Spack somehow caches their old config.
I don't think it's reasonable to expect users to understand that their old
config ended up as an "installed" spec in the database, and follows the
usual reuse rules of installed specs. This jargon makes barely any sense,
since users don't think of externals being "installed in the database" at all,
their externals are "installed on the system", and the only way they interact
with them is by registering them in config -- externals getting "installed"
is really just an implementation detail. Asking users to
spack uninstalltheir old external by hash also raises eyebrows.
It can be quite a time waster for users, in particular the case reported in
#40843, where the only change to config was fixing a typo in the module
list for the external. Barely any user would understand that config is copied
into the database, and it's never really exposed to the user. That means
that accidental reuse of the old external with the typo is a really fun and
time consuming debugging activity (in particular since it may not cause
and error on module load, and on cray systems module load related
problems are notoriously hard to troubleshoot)
Since this such a footgun, and gets reported almost every week on Slack,
I think it would be clean and consistent to apply the same reuse condition we
already apply to build caches also to the local database: reuse externals
that are configured in packages.yaml.