Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Unknown
-
Resolution: Fixed
-
Affects Version/s: 10.12.0
-
Fix Version/s: 10.14.0
-
Component/s: None
-
Labels:None
Description
The Rubygems provider contains the following code
##
# Installs the gem, using either the gems API or shelling out to `gem`
# according to the following criteria:
# 1. Use gems API (Gem::DependencyInstaller) by default
# 2. shell out to `gem install` when a String of options is given
# 3. use gems API with options if a hash of options is given
def install_package(name, version)
if source_is_remote? && @new_resource.gem_binary.nil?
if @new_resource.options.nil?
@gem_env.install(gem_dependency, :sources => gem_sources)
elsif @new_resource.options.kind_of?(Hash)
options = @new_resource.options
options[:sources] = gem_sources
@gem_env.install(gem_dependency, options)
else
install_via_gem_command(name, version)
end
elsif @new_resource.gem_binary.nil?
@gem_env.install(@new_resource.source)
else
install_via_gem_command(name,version)
end
true
end
Note that if gem_binary.nil? is false, we will end up in the final else statement, regardless of whether we passed a Hash or a String for the options attribute. install_via_gem_command() will implicitly coerce the Hash into a string and pass it directly on the shell command line, producing errors like this:
DEBUG: Re-raising exception: Mixlib::ShellOut::ShellCommandFailed - gem_package[i18n] (CENSORED) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of /usr/bin/gem install i18n -q --no-rdoc --no-ri -v "" {:no_rdoc=>true, :no_ri=>true} ----
STDOUT:
STDERR: ERROR: While executing gem ... (ArgumentError)
Illformed requirement [""]
---- End output of /usr/bin/gem install i18n -q --no-rdoc --no-ri -v "" {:no_rdoc=>true, :no_ri=>true} ----
Ran /usr/bin/gem install i18n -q --no-rdoc --no-ri -v "" {:no_rdoc=>true, :no_ri=>true} returned 1
Note that we warn about this condition in some cases:
def initialize(new_resource, run_context=nil)
super
if new_resource.gem_binary
if new_resource.options && new_resource.options.kind_of?(Hash)
msg = "options cannot be given as a hash when using an explicit gem_binary\n"
msg << "in #{new_resource} from #{new_resource.source_line}"
raise ArgumentError, msg
end
@gem_env = AlternateGemEnvironment.new(new_resource.gem_binary)
Chef::Log.debug("#{@new_resource} using gem '#{new_resource.gem_binary}'")
elsif is_omnibus? && (!@new_resource.instance_of? Chef::Resource::ChefGem)
# Opscode Omnibus - The ruby that ships inside omnibus is only used for Chef
# Default to installing somewhere more functional
gem_location = find_gem_by_path
@new_resource.gem_binary gem_location
@gem_env = AlternateGemEnvironment.new(gem_location)
Chef::Log.debug("#{@new_resource} using gem '#{gem_location}'")
else
@gem_env = CurrentGemEnvironment.new
Chef::Log.debug("#{@new_resource} using gem from running ruby environment")
end
end
but, we set the gem_binary option to the gem_location if we are running under omnibus without checking if options was specified as a String or a Hash.
Activity
- All
- Comments
- History
- Activity
- Transitions Summary
commit b6c6342cb91cfb45cd80684b177f9980bac63786 on 10-stable of chef -
CHEF-3276:Fixed rubygems provider to issue a warning if options are passed as hash instead of string && using the omnibus installer && gem binary is specified.