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 a reinstall command #244

Open
nikolay opened this issue Oct 23, 2017 · 9 comments
Open

Add a reinstall command #244

nikolay opened this issue Oct 23, 2017 · 9 comments

Comments

@nikolay
Copy link

nikolay commented Oct 23, 2017

Sometimes, especially during development and troubleshooting, it would be nice to be able to reinstall a version in a similar manner to Homebrew. In its primitive form, it could be just uninstall and install chain, but take further, it could be done transactionally, too, i.e. a failure to install won't remove the previous instance.

@Stratus3D
Copy link
Member

Good feature. I like the idea of transactional reinstalls.

@Stratus3D
Copy link
Member

Stratus3D commented May 28, 2018

Should this be a separate command or just a flag to the install command as discussed in
#148?

I'm open to either approach, but transactional reinstalls are a must either way.

I'm closing #148 in favor of this issue.

@mig4
Copy link
Contributor

mig4 commented Oct 27, 2018

I started looking into this, unfortunately it doesn't look like transactional properties can be achieved without some support from the plugins.

While many of them are simple (download + extract) and this could be done by installing into temp dir, then uninstalling the old one, then moving the temp location into place, there are plugins like clojure which injects the install dir location into some installed scripts (so moving it after installation will make them invalid).

Also a lot of plugins use upstream installers or ./configure && make && make install so it's hard to tell whether moving directories after install would be safe (most likely it would require passing additional options to the installer, like DESTDIR with autotools).

@Stratus3D
Copy link
Member

I wonder if we could work around this issue by doing something like this:

  1. Move the currently installed version and copy it out of it's installed directory and into a temp directory (making it unusable)
  2. Tell the plugin to install that same version, with the name of the original directory containing the old version (so that if it succeeds it's in the right spot)
  3. If the new version installs successfully delete the temp dir containing the old install. Otherwise delete the directory containing the failed new install (or copy it elsewhere for debugging) and copy the original installation directory back to the original location (restoring the original version and making it usable again).

Would that work? And if so do you think we will run into any problems with this approach? Thanks for taking the time to look into this!

@Aethelflaed
Copy link

I had to reinstall erlang after installing a few dependencies to compile it again and I can say that at least asdf-erlang wouldn't work this way, as it keeps its own record of which version is installed, so moving the install directory doesn't work.

(Tried on Archlinux).

I saw there are some plugin-test, maybe it would be interesting to add some tests for this feature before shipping it, so those plugins have the time to adapt ?

@Stratus3D
Copy link
Member

@Aethelflaed I don't think the erlang plugin should be keeping a record of which versions of Erlang it installed. It uses kerl underneath, and kerl does typically keep records, but I think we altered it such that asdf-erlang doesn't rely on that behavior. If not we may need to change it. Generally plugins should not be keeping track of installed plugins on their own.

I'd like to do this without changing the plugins at all if possible. We may have to update a few plugins so they will work properly however.

@ashmckenzie
Copy link

ashmckenzie commented Apr 18, 2023

#1546 is a very naive implementation (is WIP and am more than happy to change) that simply installs, even if the install directory currently exists.

@hyperupcall
Copy link
Contributor

hyperupcall commented Apr 18, 2023

Would that work? And if so do you think we will run into any problems with this approach? Thanks for taking the time to look into this!

I like an approach of:

  1. Installing into a new directory (if that fails, then we just remove that directory and everything is the same)
  2. Atomically move the new directory to the location of the old directory

This is similar to the third approach mentioned above, except that that there is a final move instead of a final copy. HereHere is a link to atomically move a directory and even though it's a bit extra code, it's going to be faster, especially in cases where there is a lot of stuff in the installation directory. It's also going to ensure that there are no remnants files of the old installation (unless something like rsync is used). It's also important to note that wherever these temporary directories are, they must be in the same directory as the original directories. Otherwise, we risk that the temporary directory is on a different file system and the move may turn into a "copy".

I'm not a fan of the second approach because if we try to reinstall a tool where there's already directories and stuff existing, there likely will be failures since it's difficult to write fully idempotent installation scripts.

@highb
Copy link

highb commented Apr 27, 2023

If anyone is looking for a quick way to do this without fundamentally changing asdf:

PLUGIN=sometool asdf list $PLUGIN | awk '{print "asdf uninstall $PLUGIN " $1 "; asdf install $PLUGIN " $1}' | bash

This would do a reinstall on all versions of the $PLUGIN. Had to do this today to deal with the GPG signing key change for Terraform. 😅

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

No branches or pull requests

8 participants
@nikolay @ashmckenzie @Aethelflaed @highb @Stratus3D @hyperupcall @mig4 and others