Possible wrong condition in `build_extensions' ? #796

Closed
dunric opened this Issue Jan 21, 2014 · 6 comments

Projects

None yet

3 participants

@dunric
Contributor
dunric commented Jan 21, 2014

Hi,

I think the test at https://github.com/rubygems/rubygems/blob/master/lib/rubygems/specification.rb#L1421 is not right. It stops extension's build attempt if base_dir is not writeable and if #{base_dir}/extensions does not exist. I find it wrong as it causes building in #{base_dir}/extensions even if there are no write permissions.
This issue hit me after an upgrade to Ruby 2.1.0 with newer Rubygems version 2.2.0 . After an system installation of Nokogiri gem, even invoking irb as a normal non-root user failed badly with

$ irb
/usr/lib64/ruby/2.1.0/fileutils.rb:250:in `mkdir': Permission denied @ dir_s_mkdir - /usr/lib64/ruby/gems/2.1.0/extensions/x86_64-linux (Errno::EACCES)
        from /usr/lib64/ruby/2.1.0/fileutils.rb:250:in `fu_mkdir'
        from /usr/lib64/ruby/2.1.0/fileutils.rb:224:in `block (2 levels) in mkdir_p'
        from /usr/lib64/ruby/2.1.0/fileutils.rb:222:in `reverse_each'
        from /usr/lib64/ruby/2.1.0/fileutils.rb:222:in `block in mkdir_p'
        from /usr/lib64/ruby/2.1.0/fileutils.rb:208:in `each'
        from /usr/lib64/ruby/2.1.0/fileutils.rb:208:in `mkdir_p'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:210:in `write_gem_make_out'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:132:in `build_error'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:171:in `rescue in build_extension'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:156:in `build_extension'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:198:in `block in build_extensions'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:195:in `each'
        from /usr/lib64/ruby/2.1.0/rubygems/ext/builder.rb:195:in `build_extensions'
        from /usr/lib64/ruby/2.1.0/rubygems/specification.rb:1436:in `block in build_extensions'

I'd suggest to change the second condition so the expression would look like

return if !File.writable?(base_dir) ||
              !File.writable?(File.join(base_dir, 'extensions'))

or even omit the 2nd option at all (if base_dir is not writable do you expect its subdirectory would ?).

Owner
drbrain commented Jan 22, 2014

Is this the correct way to reproduce?

  1. Install nokogiri with rubygems 2.1.0 to system directory (sudo gem install nokogiri)
  2. Ensure system directory is not writable by user process
  3. Upgrade to RubyGems 2.2
  4. Run ruby -rnokogiri -e0
Contributor
dunric commented Jan 25, 2014

You can reproduce the issue if nokogiri gem is built with different version of one of its extensions like libxml than the version available in system or remove the compiled lib completely. Invoking even such innocent tool like irb (under unprivileged user account) will detect required extension is missing or in different version and attempts to rebuild it and fails due to insufficient privileges.

Owner
drbrain commented Jan 27, 2014

So your steps to reproduce are:

  1. install libxml version X
  2. install nokogiri
  3. remove libxml version X
  4. install libxml version Y

Note that "reinstall nokogiri" is not included here. If these are your steps, this is not something RubyGems can fix. If you change the library dependencies from underneath a compiled gem you must reinstall the gem.

Owner
evanphx commented Jan 27, 2014

The issue is gems installed by root into a system ruby path. Here are steps

  1. Install ruby as root
  2. Install bundler
  3. As a normal user, run bundle.
Owner
drbrain commented Jan 28, 2014

@evanphx for your case, bundler is not compatibly installing extensions.

@drbrain drbrain added a commit that referenced this issue Jan 29, 2014
@drbrain drbrain Add Specification#missing_extensions?
This will allow us to have better behavior when extensions have not been
built for the current platform.

Part of #796
6062fbc
@drbrain drbrain added a commit that referenced this issue Jan 29, 2014
@drbrain drbrain Warn about extension building once per gem
Part of #796
da3be98
@drbrain drbrain added a commit that referenced this issue Jan 29, 2014
@drbrain drbrain Add #796 to History 11f3bc9
Owner
drbrain commented Jan 29, 2014

After discussion with @evanphx we decided it was better to no longer attempt to build extensions during activation. Instead a warning is given.

This will require a fix in bundler before it can be released because bundler is not correctly building extensions.

@drbrain drbrain closed this Jan 29, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment