diff options
author | Matthew Kent <mkent@magoazul.com> | 2012-10-28 00:23:16 -0700 |
---|---|---|
committer | Bryan McLellan <btm@opscode.com> | 2012-12-14 08:33:06 -0800 |
commit | cfbba7b061039be4f8290a9c368ffb04c17e6022 (patch) | |
tree | 42012519ab24e1d717f1825bdaa4769302712520 /chef | |
parent | 0c0f9fa8c636a1c65cfb37e5fc20f66c72b91e86 (diff) | |
download | chef-cfbba7b061039be4f8290a9c368ffb04c17e6022.tar.gz |
CHEF-2427: Teach the yum provider how to handle --(enable|disable)repo passed
as options.
We collect these options while preserving their order, dump the cache, then
pass them along to yum-dump.py during the refresh. yum-dump can now parse these
options and enable/disable repos in exactly the same manner yum itself does,
thus preserving our cache sanity. The next yum package resource that loads and
doesn't have the same options set will blow away the cache.
Under the current caching implementation passing these options will add client
run time as the cache is rebuilt to account for the differences in package
availability. As such I strongly suggest globally enabling/disabling the repo
whenever possible.
Diffstat (limited to 'chef')
-rw-r--r-- | chef/lib/chef/provider/package/yum-dump.py | 20 | ||||
-rw-r--r-- | chef/lib/chef/provider/package/yum.rb | 41 | ||||
-rw-r--r-- | chef/spec/unit/provider/package/yum_spec.rb | 90 |
3 files changed, 140 insertions, 11 deletions
diff --git a/chef/lib/chef/provider/package/yum-dump.py b/chef/lib/chef/provider/package/yum-dump.py index 99136eceec..407eb8f408 100644 --- a/chef/lib/chef/provider/package/yum-dump.py +++ b/chef/lib/chef/provider/package/yum-dump.py @@ -107,6 +107,14 @@ def setup(yb, options): elif YUM_MAJOR == 2: yb.conf.setConfigOption('cache', options.cache) + # Handle repo toggle via id or glob exactly like yum + for opt, repos in options.repo_control: + for repo in repos: + if opt == '--enablerepo': + yb.repos.enableRepo(repo) + elif opt == '--disablerepo': + yb.repos.disableRepo(repo) + return 0 def dump_packages(yb, list, output_provides): @@ -239,6 +247,12 @@ def yum_dump(options): print >> sys.stderr, "yum-dump Unlock Error: %s" % e return 200 +# Preserve order of enable/disable repo args like yum does +def gather_repo_opts(option, opt, value, parser): + if getattr(parser.values, option.dest, None) is None: + setattr(parser.values, option.dest, []) + getattr(parser.values, option.dest).append((opt, value.split(','))) + def main(): usage = "Usage: %prog [options]\n" + \ "Output a list of installed, available and re-installable packages via yum" @@ -261,6 +275,12 @@ def main(): parser.add_option("-a", "--available", action="store_const", const="available", dest="package_list", default="all", help="output only available and re-installable packages") + parser.add_option("--enablerepo", + action="callback", callback=gather_repo_opts, type="string", dest="repo_control", default=[], + help="enable disabled repositories by id or glob") + parser.add_option("--disablerepo", + action="callback", callback=gather_repo_opts, type="string", dest="repo_control", default=[], + help="disable repositories by id or glob") (options, args) = parser.parse_args() diff --git a/chef/lib/chef/provider/package/yum.rb b/chef/lib/chef/provider/package/yum.rb index 9048048b83..f67262ef6f 100644 --- a/chef/lib/chef/provider/package/yum.rb +++ b/chef/lib/chef/provider/package/yum.rb @@ -664,12 +664,16 @@ class Chef @allow_multi_install = [] + @extra_repo_control = nil + # these are for subsequent runs if we are on an interval Chef::Client.when_run_starts do YumCache.instance.reload end end + attr_reader :extra_repo_control + # Cache management # @@ -693,6 +697,10 @@ class Chef raise ArgumentError, "Unexpected value in next_refresh: #{@next_refresh}" end + if @extra_repo_control + opts << " #{@extra_repo_control}" + end + one_line = false error = nil @@ -848,6 +856,22 @@ class Chef @allow_multi_install end + def enable_extra_repo_control(arg) + # Don't touch cache if it's the same repos as the last load + unless @extra_repo_control == arg + @extra_repo_control = arg + reload + end + end + + def disable_extra_repo_control + # Only force reload when set + if @extra_repo_control + @extra_repo_control = nil + reload + end + end + private def version(package_name, arch=nil, is_available=false, is_installed=false) @@ -995,6 +1019,23 @@ class Chef @yum.reload end + if @new_resource.options + repo_control = [] + @new_resource.options.split.each do |opt| + if opt =~ %r{--(enable|disable)repo=.+} + repo_control << opt + end + end + + if repo_control.size > 0 + @yum.enable_extra_repo_control(repo_control.join(" ")) + else + @yum.disable_extra_repo_control + end + else + @yum.disable_extra_repo_control + end + # At this point package_name could be: # # 1) a package name, eg: "foo" diff --git a/chef/spec/unit/provider/package/yum_spec.rb b/chef/spec/unit/provider/package/yum_spec.rb index 4b890b1549..375ae0966b 100644 --- a/chef/spec/unit/provider/package/yum_spec.rb +++ b/chef/spec/unit/provider/package/yum_spec.rb @@ -34,7 +34,8 @@ describe Chef::Provider::Package::Yum do :package_available? => true, :version_available? => true, :allow_multi_install => [ "kernel" ], - :package_repository => "base" + :package_repository => "base", + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -92,6 +93,7 @@ describe Chef::Provider::Package::Yum do end end @yum_cache.stub!(:package_available?).and_return(true) + @yum_cache.stub!(:disable_extra_repo_control).and_return(true) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @provider.load_current_resource @@ -125,6 +127,7 @@ describe Chef::Provider::Package::Yum do nil end @yum_cache.stub!(:package_available?).and_return(true) + @yum_cache.stub!(:disable_extra_repo_control).and_return(true) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) # annoying side effect of the fun stub'ing above @@ -155,6 +158,7 @@ describe Chef::Provider::Package::Yum do nil end @yum_cache.stub!(:package_available?).and_return(true) + @yum_cache.stub!(:disable_extra_repo_control).and_return(true) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @provider.load_current_resource @@ -189,6 +193,7 @@ describe Chef::Provider::Package::Yum do end end.and_return("something") @yum_cache.stub!(:package_available?).and_return(true) + @yum_cache.stub!(:disable_extra_repo_control).and_return(true) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @provider.load_current_resource @@ -209,6 +214,24 @@ describe Chef::Provider::Package::Yum do @provider.load_current_resource end + it "should detect --enablerepo or --disablerepo when passed among options, collect them preserving order and notify the yum cache" do + @new_resource.stub!(:options).and_return("--stuff --enablerepo=foo --otherthings --disablerepo=a,b,c --enablerepo=bar") + @yum_cache.should_receive(:enable_extra_repo_control).with("--enablerepo=foo --disablerepo=a,b,c --enablerepo=bar") + @provider.load_current_resource + end + + it "should let the yum cache know extra repos are disabled if --enablerepo or --disablerepo aren't among options" do + @new_resource.stub!(:options).and_return("--stuff --otherthings") + @yum_cache.should_receive(:disable_extra_repo_control) + @provider.load_current_resource + end + + it "should let the yum cache know extra repos are disabled if options aren't set" do + @new_resource.stub!(:options).and_return(nil) + @yum_cache.should_receive(:disable_extra_repo_control) + @provider.load_current_resource + end + it "should search provides if package name can't be found then set package_name to match" do @yum_cache = mock( 'Chef::Provider::Yum::YumCache', @@ -217,7 +240,8 @@ describe Chef::Provider::Package::Yum do :installed_version => "1.2.4-11.18.el5", :candidate_version => "1.2.4-11.18.el5", :package_available? => false, - :version_available? => true + :version_available? => true, + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "1.2.4-11.18.el5", "x86_64", []) @@ -235,7 +259,8 @@ describe Chef::Provider::Package::Yum do :installed_version => "1.2.4-11.18.el5", :candidate_version => "1.2.4-11.18.el5", :package_available? => false, - :version_available? => true + :version_available? => true, + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) pkg_x = Chef::Provider::Package::Yum::RPMPackage.new("test-package-x", "1.2.4-11.18.el5", "x86_64", []) @@ -255,7 +280,8 @@ describe Chef::Provider::Package::Yum do :installed_version => "1.2.4-11.18.el5", :candidate_version => "1.2.4-11.18.el5", :package_available? => false, - :version_available? => true + :version_available? => true, + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @yum_cache.should_receive(:packages_from_require).twice.and_return([]) @@ -272,7 +298,8 @@ describe Chef::Provider::Package::Yum do :installed_version => "1.2.4-11.18.el5", :candidate_version => "1.2.4-11.18.el5", :package_available? => false, - :version_available? => true + :version_available? => true, + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -295,7 +322,8 @@ describe Chef::Provider::Package::Yum do :installed_version => "1.2.4-11.18.el5", :candidate_version => "1.2.4-11.18.el5", :package_available? => false, - :version_available? => true + :version_available? => true, + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @yum_cache.should_receive(:packages_from_require).twice.and_return([]) @@ -363,7 +391,8 @@ describe Chef::Provider::Package::Yum do :installed_version => "1.2.4-11.18.el5", :candidate_version => "1.2.4-11.18.el5_2.3", :package_available? => true, - :version_available? => nil + :version_available? => nil, + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -380,7 +409,8 @@ describe Chef::Provider::Package::Yum do :candidate_version => "1.2.4-11.15.el5", :package_available? => true, :version_available? => true, - :allow_multi_install => [ "kernel" ] + :allow_multi_install => [ "kernel" ], + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -398,7 +428,8 @@ describe Chef::Provider::Package::Yum do :package_available? => true, :version_available? => true, :allow_multi_install => [ "cups" ], - :package_repository => "base" + :package_repository => "base", + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -420,7 +451,8 @@ describe Chef::Provider::Package::Yum do :package_available? => true, :version_available? => true, :allow_multi_install => [], - :package_repository => "base" + :package_repository => "base", + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -485,7 +517,8 @@ describe Chef::Provider::Package::Yum do :candidate_version => "1.2.4-11.15.el5", :package_available? => true, :version_available? => true, - :allow_multi_install => [ "kernel" ] + :allow_multi_install => [ "kernel" ], + :disable_extra_repo_control => true ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) @@ -1609,6 +1642,12 @@ EOF @yc.refresh end + it "should pass extra_repo_control args to yum-dump.py" do + @yc.enable_extra_repo_control("--enablerepo=foo --disablerepo=bar") + @yc.should_receive(:popen4).with(%r{^/usr/bin/python .*/yum-dump.py --options --installed-provides --enablerepo=foo --disablerepo=bar$}, :waitlast=>true) + @yc.refresh + end + it "should warn about invalid data with too many separators" do @yc.stub!(:popen4).and_yield(@pid, @stdin, @stdout_bad_separators, @stderr).and_return(@status) Chef::Log.should_receive(:warn).exactly(3).times.with(%r{Problem parsing}) @@ -1788,4 +1827,33 @@ EOF end end + describe "enable_extra_repo_control" do + it "should set @extra_repo_control to arg" do + @yc.enable_extra_repo_control("--enablerepo=test") + @yc.extra_repo_control.should be == "--enablerepo=test" + end + + it "should call reload once when set to flag cache for update" do + @yc.should_receive(:reload).once + @yc.enable_extra_repo_control("--enablerepo=test") + @yc.enable_extra_repo_control("--enablerepo=test") + end + end + + describe "disable_extra_repo_control" do + it "should set @extra_repo_control to nil" do + @yc.enable_extra_repo_control("--enablerepo=test") + @yc.disable_extra_repo_control + @yc.extra_repo_control.should be == nil + end + + it "should call reload once when cleared to flag cache for update" do + @yc.should_receive(:reload).once + @yc.enable_extra_repo_control("--enablerepo=test") + @yc.should_receive(:reload).once + @yc.disable_extra_repo_control + @yc.disable_extra_repo_control + end + end + end |