Skip to content

WIP: "spack uninstall": don't modify env#26766

Closed
scheibelp wants to merge 23 commits intospack:developfrom
scheibelp:features/uninstall-dont-modify-env
Closed

WIP: "spack uninstall": don't modify env#26766
scheibelp wants to merge 23 commits intospack:developfrom
scheibelp:features/uninstall-dont-modify-env

Conversation

@scheibelp
Copy link
Copy Markdown
Member

@scheibelp scheibelp commented Oct 15, 2021

Currently if you run spack uninstall x in an environment, and x refers to a user spec (e.g. something added with spack add), Spack will update the spack.yaml to remove that spec. This changes the behavior so that spack uninstall just uninstalls the spec: if you immediately run spack install in the environment (which in Spack is a request to install all specs registered with the environment), then - with this PR - it would reinstall the spec.

This is anticipated to be useful if a user is modifying the package.py for a package in their environment: they may want to uninstall and then reinstall it to get the latest state (at the moment, modifications to the package.py don't affect the hash that Spack uses to compute the install prefix and thereby to distinguish it from other installed specs).

spack rm can already remove specs, so there is still a command line mechanism available to edit the environment.

This could interfere with scripts that depend on the current behavior of spack uninstall, although I consider that unlikely since this I don't think users would generally script uninstall actions.

If you have environments e1 and e2, and specs [X, Y] such that [X, Y] is in e1, and [X] is in e2

  • spack uninstall y in e1: uninstalls the spec (but with this PR it stays in e1)
  • spack uninstall x in e1: complains because x is also in e2
  • (new) spack uninstall --remove x in e1: removes x from e1 but does not actually uninstall the spec
  • spack uninstall -f x in e1: uninstalls the spec (both e1 and e2 are now "missing" this spec)

If you have environments e1 and e2, and specs [P, Q, R] such that P->R, Q->R, and [P, R] are in e1 and [Q, R] are in e2

  • spack uninstall p in e1: uninstalls the spec
  • spack uninstall r in e1: will fail for two reasons: (1) P needs R in e1 and (2) e2 needs R
  • spack uninstall --dependents r in e1: will fail because e2 needs R
  • (new) spack uninstall --dependents --remove r in e1: removes R from e1 (but does not uninstall it) and uninstalls (and removes) P
  • [C0] spack uninstall -f --dependents r in e1: will uninstall P, Q, and R (i.e. e2 will have dependent specs uninstalled as a side effect)
  • (new) spack uninstall -f --dependents --remove r in e1: this uninstalls P, Q, and R, and removes [P, R] from e1
  • (new) spack uninstall -f --remove r in e1: uninstalls R (so it is "missing" in both environments) and removes R from e1 (note that e1 would still install R as a dependency of P, but it would no longer be listed as a root spec)

(This is now handled) This PR does not remove the complementary behavior from spack install: if a user runs spack install x in an environment, it will add x to the list of user specs recorded for the environment. This could easily be removed, although I think this behavior could be useful: without this, if you want to install a new spec to an environment, you would have to run spack add x followed by spack install.

spack install has also been updated: by default it will not modify an environment unless you specify --add (previously, you had to specify --no-add to prevent Spack from updating the current active environment).

Other notes:

  • If you spack uninstall -f a spec that is wanted by existing environments, their corresponding views are not updated (this was the case before, I'm just noting that explicitly here).

TODOs:

  • Update tests
  • Add test for case [C0] above
  • Update spack install so that it doesn't modify the active environment by default
  • Make the original behavior optional: add --add and --remove options to spack install and spack uninstall, respectively

@haampie
Copy link
Copy Markdown
Member

haampie commented Oct 15, 2021

Only read the title, but this sounds good!

@spackbot-app spackbot-app bot added the tests General test capability(ies) label Oct 15, 2021
Comment on lines +319 to +320
if env:
env.regenerate_views()
Copy link
Copy Markdown
Member

@haampie haampie Oct 16, 2021

Choose a reason for hiding this comment

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

Notice that elsewhere we do:

            with self.write_transaction():
                self.regenerate_views()

.. I'd be a fan not to use write_transaction, because it has the side-effect of deserializing the environment from disk, even if the in-memory representation is newer, making environments hard to use as in-memory objects in scripts where you don't need to store a spack.yaml (#25532)

Copy link
Copy Markdown
Member Author

@scheibelp scheibelp Oct 22, 2021

Choose a reason for hiding this comment

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

not to use write_transaction, because it has the side-effect of deserializing the environment from disk

I'm not sure what you mean here: a write transaction takes a lock on the file - AFAIK it is the only way to ensure that the disk and in-memory representation are in sync (which I think is the opposite of what you are saying).

making environments hard to use as in-memory objects in scripts where you don't need to store a spack.yaml

This could be handled by either (a) do all your modifications inside of transactions (if you are interacting with disk) or (b) do none of them inside transactions. I think (a) is safer because I don't know if our API guarantees not using transactions (perhaps that is covered in #25532)

@tgamblin tgamblin self-assigned this Nov 24, 2021
@iarspider
Copy link
Copy Markdown
Contributor

Can't wait for this to be merged.

if $list_options
then
SPACK_COMPREPLY="-h --help --only -u --until -j --jobs --reuse --overwrite --fail-fast --keep-prefix --keep-stage --dont-restage --use-cache --no-cache --cache-only --monitor --monitor-save-local --monitor-tags --monitor-keep-going --monitor-host --monitor-prefix --include-build-deps --no-check-signature --require-full-hash-match --show-log-on-error --source -n --no-checksum --deprecated -v --verbose --fake --only-concrete --no-add -f --file --clean --dirty --test --run-tests --log-format --log-file --help-cdash --cdash-upload-url --cdash-build --cdash-site --cdash-track --cdash-buildstamp -y --yes-to-all"
SPACK_COMPREPLY="-h --help --only -u --until -j --jobs --reuse --overwrite --fail-fast --keep-prefix --keep-stage --dont-restage --use-cache --no-cache --cache-only --monitor --monitor-save-local --monitor-tags --monitor-keep-going --monitor-host --monitor-prefix --include-build-deps --no-check-signature --require-full-hash-match --show-log-on-error --source -n --no-checksum --deprecated -v --verbose --fake --only-concrete --add -f --file --clean --dirty --test --run-tests --log-format --log-file --help-cdash --cdash-upload-url --cdash-build --cdash-site --cdash-track --cdash-buildstamp -y --yes-to-all"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should keep the --no-add flag so that people who are already using it don't have their scripts broken (it's just overspecified for the default behavior now).

Comment on lines +231 to +233
msg = ('You asked to install {0}, which is not in '
'the current environment, but did not also '
'specify --add'.format(abstract.name))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this could be clearer. Maybe

"Cannot install '{0}' because it is not in the current environment. You can add it to the environment with 'spack add {0}', or as part of the install command with 'spack install --add {0}'.format(abstract)

# one or more of the specs to be uninstalled. There may also be
# packages in those envs which depend on the base set of packages
# to uninstall, but this covers that scenario.
or (not args.remove and spec_to_other_envs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should still display this message even if the removal portion will work, since the uninstall portion will not

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Nov 8, 2022

Superseded by #33711.

@tgamblin tgamblin closed this Nov 8, 2022
@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Nov 8, 2022

This was merged as #33711.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands tests General test capability(ies) WIP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants