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

Give better error when previous installation folder is insecure to remove #7030

Merged
merged 2 commits into from
Oct 28, 2023

Conversation

deivid-rodriguez
Copy link
Member

@deivid-rodriguez deivid-rodriguez commented Oct 3, 2023

What was the end-user or developer problem that led to this PR?

In #6460, user was getting a Bundler error due to the previous gem installation folder having insecure permissions.

However, and even if we've lately improved the message, it's still too verbose and real culprit is a bit hidden.

What is your fix for the problem, implemented in this PR?

This error is about insecure permissions of the parent install folder for a gem, so it's independent of the particular gem that it's being uninstalled. Hence, even if you're running 8 installation jobs in parallel, the error should be displayed just once.

So my fix is to create a special error class for this that goes straight to the user, instead of being reported once per installation job.

Before

$ bundle install --force --jobs 2
[DEPRECATED] The `--force` option has been renamed to `--redownload`
Fetching gem metadata from https://rubygems.org/.......
Installing minitest 5.20.0
Installing concurrent-ruby 1.2.2
Installing zeitwerk 2.6.12
Installing public_suffix 5.0.3
Installing did_you_mean 1.6.3
Installing bindata 2.4.15
Installing plist 3.7.0
Installing ruby-macho 4.0.0
Installing sorbet-runtime 0.5.10461
Installing warning 1.3.0
Bundler::DirectoryRemovalError: Could not delete previous installation of `/Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.2.2`.
The underlying error was ArgumentError: parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort:
"/Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.2.2" (parent directory mode 40777), with backtrace:
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/vendor/fileutils/lib/fileutils.rb:1387:in `remove_entry_secure'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler.rb:332:in `rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:111:in `strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:19:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/source/rubygems.rb:203:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:156:in `do_install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:147:in `block in worker_pool'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:62:in `apply_func'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `loop'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

Bundler Error Backtrace:
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:115:in `rescue in strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:110:in `strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:19:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/source/rubygems.rb:203:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:156:in `do_install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:147:in `block in worker_pool'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:62:in `apply_func'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `loop'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

An error occurred while installing concurrent-ruby (1.2.2), and Bundler cannot continue.

In Gemfile:
  activesupport was resolved to 6.1.7.6, which depends on
    i18n was resolved to 1.14.1, which depends on
      concurrent-ruby


Bundler::DirectoryRemovalError: Could not delete previous installation of `/Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems/minitest-5.20.0`.
The underlying error was ArgumentError: parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort:
"/Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems/minitest-5.20.0" (parent directory mode 40777), with backtrace:
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/vendor/fileutils/lib/fileutils.rb:1387:in `remove_entry_secure'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler.rb:332:in `rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:111:in `strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:19:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/source/rubygems.rb:203:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:156:in `do_install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:147:in `block in worker_pool'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:62:in `apply_func'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `loop'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

Bundler Error Backtrace:
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:115:in `rescue in strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:110:in `strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:19:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/source/rubygems.rb:203:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:156:in `do_install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:147:in `block in worker_pool'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:62:in `apply_func'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `loop'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

An error occurred while installing minitest (5.20.0), and Bundler cannot continue.

In Gemfile:
  activesupport was resolved to 6.1.7.6, which depends on
    minitest


Bundler::DirectoryRemovalError: Could not delete previous installation of `/Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.6.12`.
The underlying error was ArgumentError: parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort:
"/Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.6.12" (parent directory mode 40777), with backtrace:
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/vendor/fileutils/lib/fileutils.rb:1387:in `remove_entry_secure'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler.rb:332:in `rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:111:in `strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:19:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/source/rubygems.rb:203:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:156:in `do_install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:147:in `block in worker_pool'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:62:in `apply_func'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `loop'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

Bundler Error Backtrace:
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:115:in `rescue in strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:110:in `strict_rm_rf'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/rubygems_gem_installer.rb:19:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/source/rubygems.rb:203:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:156:in `do_install'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/installer/parallel_installer.rb:147:in `block in worker_pool'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:62:in `apply_func'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `loop'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:54:in `process_queue'
  /Users/deivid/.asdf/installs/ruby/2.6.10/lib/ruby/site_ruby/2.6.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

An error occurred while installing zeitwerk (2.6.12), and Bundler cannot continue.

In Gemfile:
  activesupport was resolved to 6.1.7.6, which depends on
    zeitwerk

After

$ bundle install --force --jobs 2
[DEPRECATED] The `--force` option has been renamed to `--redownload`
Fetching gem metadata from https://rubygems.org/.......
Installing minitest 5.20.0
Installing concurrent-ruby 1.2.2
Installing zeitwerk 2.6.12
Installing public_suffix 5.0.3
Installing bindata 2.4.15
Installing did_you_mean 1.6.3
Installing plist 3.7.0
Installing ruby-macho 4.0.0
Installing sorbet-runtime 0.5.10461
Installing warning 1.3.0
Your installation path /Users/deivid/Code/playground/world-writable/vendor/bundle/ruby/2.6.0/gems has insecure permissions (it's both world-writable and does not have the sticky bit set), so Bundler can't
reinstall any gems into it since it needs to remove previous installations which is insecure.

Make sure the following tasks are checked

@deivid-rodriguez deivid-rodriguez marked this pull request as ready for review October 6, 2023 05:39
bundler/lib/bundler/errors.rb Outdated Show resolved Hide resolved
bundler/spec/bundler/bundler_spec.rb Show resolved Hide resolved
@martinemde
Copy link
Member

Just a note that this and #6374 define exit status 37. Whichever merges first, the other needs an update (probably bundler checksums, but mentioning just in case so we don't forget.)

Copy link
Member

@martinemde martinemde left a comment

Choose a reason for hiding this comment

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

Now that's a nice looking message, haha ;)

I see you got the exit status code too. Looks good!

@martinemde martinemde merged commit a5f8835 into master Oct 28, 2023
92 checks passed
@martinemde martinemde deleted the better-parallel-install-errors branch October 28, 2023 15:26
deivid-rodriguez pushed a commit that referenced this pull request Nov 8, 2023
deivid-rodriguez pushed a commit that referenced this pull request Nov 8, 2023
deivid-rodriguez pushed a commit that referenced this pull request Nov 8, 2023
deivid-rodriguez pushed a commit that referenced this pull request Nov 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants