diff options
author | Thom May <thom@may.lt> | 2015-04-25 14:06:23 +0100 |
---|---|---|
committer | Thom May <thom@may.lt> | 2015-04-25 14:06:23 +0100 |
commit | 07aedb0eabbbf364f9d96127c34fd81b16011d4f (patch) | |
tree | afbe959b3dd4d509a3060c3be9a0b4972bdf3274 | |
parent | 391c9a62143e43a623cdbebbf6f460653b66e94d (diff) | |
parent | 9c5deecf8da150ca44b0494573f8c6b0d80d40fa (diff) | |
download | chef-07aedb0eabbbf364f9d96127c34fd81b16011d4f.tar.gz |
Merge pull request #3166 from chef/ssd/find-python
Use the same python interpreter as yum when possible
-rw-r--r-- | lib/chef/provider/package/yum.rb | 30 | ||||
-rw-r--r-- | spec/unit/provider/package/yum_spec.rb | 36 |
2 files changed, 64 insertions, 2 deletions
diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb index 49c6f6beb5..b3d3d72844 100644 --- a/lib/chef/provider/package/yum.rb +++ b/lib/chef/provider/package/yum.rb @@ -19,6 +19,7 @@ require 'chef/config' require 'chef/provider/package' require 'chef/mixin/shell_out' +require 'chef/mixin/which' require 'chef/resource/package' require 'singleton' require 'chef/mixin/get_source_from_package' @@ -647,6 +648,7 @@ class Chef # Cache for our installed and available packages, pulled in from yum-dump.py class YumCache include Chef::Mixin::Command + include Chef::Mixin::Which include Chef::Mixin::ShellOut include Singleton @@ -713,7 +715,7 @@ class Chef status = nil begin - status = shell_out!("/usr/bin/python #{helper}#{opts}", :timeout => Chef::Config[:yum_timeout]) + status = shell_out!("#{python_bin} #{helper}#{opts}", :timeout => Chef::Config[:yum_timeout]) status.stdout.each_line do |line| one_line = true @@ -779,6 +781,32 @@ class Chef @next_refresh = :none end + def python_bin + yum_executable = which("yum") + if yum_executable && shabang?(yum_executable) + extract_interpreter(yum_executable) + else + Chef::Log.warn("Yum executable not found or doesn't start with #!. Using default python.") + "/usr/bin/python" + end + rescue StandardError => e + Chef::Log.warn("An error occured attempting to determine correct python executable. Using default.") + Chef::Log.debug(e) + "/usr/bin/python" + end + + def extract_interpreter(file) + ::File.open(file, 'r', &:readline)[2..-1].chomp + end + + def shabang?(file) + ::File.open(file, 'r') do |f| + f.read(2) == '#!' + end + rescue Errno::ENOENT + false + end + def reload @next_refresh = :all end diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb index 865dce23fa..8f4bde7f62 100644 --- a/spec/unit/provider/package/yum_spec.rb +++ b/spec/unit/provider/package/yum_spec.rb @@ -17,6 +17,7 @@ # require 'spec_helper' +require 'securerandom' describe Chef::Provider::Package::Yum do before(:each) do @@ -1659,6 +1660,14 @@ describe Chef::Provider::Package::Yum::YumCache do end end + let(:yum_exe) { + StringIO.new("#!/usr/bin/python\n\naldsjfa\ldsajflkdsjf\lajsdfj") + } + + let(:bin_exe) { + StringIO.new(SecureRandom.random_bytes) + } + before(:each) do @stdin = double("STDIN", :nil_object => true) @stdout = double("STDOUT", :nil_object => true) @@ -1704,12 +1713,19 @@ file: file://///etc/yum.repos.d/CentOS-Base.repo, line: 12 'qeqwewe\n' EOF @status = double("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_good, :stderr => @stderr) - # new singleton each time Chef::Provider::Package::Yum::YumCache.reset_instance @yc = Chef::Provider::Package::Yum::YumCache.instance # load valid data allow(@yc).to receive(:shell_out!).and_return(@status) + allow_any_instance_of(described_class).to receive(:which).with("yum").and_return("/usr/bin/yum") + allow(::File).to receive(:open).with("/usr/bin/yum", "r") do |&block| + res = block.call(yum_exe) + # a bit of a hack. rewind this since it seem that no matter what + # I do, we get the same StringIO objects on multiple calls to + # ::File.open + yum_exe.rewind; res + end end describe "initialize" do @@ -1726,6 +1742,24 @@ EOF end end + describe "python_bin" do + it "should return the default python if an error occurs" do + allow(::File).to receive(:open).with("/usr/bin/yum", "r").and_raise(StandardError) + expect(@yc.python_bin).to eq("/usr/bin/python") + end + + it "should return the default python if the yum-executable doesn't start with #!" do + allow(::File).to receive(:open).with("/usr/bin/yum", "r") { |&b| r = b.call(bin_exe); bin_exe.rewind; r} + expect(@yc.python_bin).to eq("/usr/bin/python") + end + + it "should return the interpreter for yum" do + other = StringIO.new("#!/usr/bin/super_python\n\nlasjdfdsaljf\nlasdjfs") + allow(::File).to receive(:open).with("/usr/bin/yum", "r") { |&b| r = b.call(other); other.rewind; r} + expect(@yc.python_bin).to eq("/usr/bin/super_python") + end + end + describe "refresh" do it "should implicitly call yum-dump.py only once by default after being instantiated" do expect(@yc).to receive(:shell_out!).once |