diff --git a/lib/puppet/provider/package/zypper.rb b/lib/puppet/provider/package/zypper.rb index f129ef6e6..b0caf2840 100644 --- a/lib/puppet/provider/package/zypper.rb +++ b/lib/puppet/provider/package/zypper.rb @@ -1,52 +1,83 @@ Puppet::Type.type(:package).provide :zypper, :parent => :rpm do desc "Support for SuSE `zypper` package manager. Found in SLES10sp2+ and SLES11" has_feature :versionable commands :zypper => "/usr/bin/zypper" - commands :rpm => "rpm" confine :operatingsystem => [:suse, :sles, :sled, :opensuse] + #on zypper versions <1.0, the version option returns 1 + #some versions of zypper output on stderr + def zypper_version + zypper "--version", { :failonfail => false, :combine => true} + end + # Install a package using 'zypper'. def install should = @resource.should(:ensure) self.debug "Ensuring => #{should}" wanted = @resource[:name] # XXX: We don't actually deal with epochs here. case should when true, false, Symbol # pass else # Add the package version wanted = "#{wanted}-#{should}" end - output = zypper "--quiet", :install, "-l", "-y", wanted + + #This has been tested with following zypper versions + #SLE 10.2: 0.6.104 + #SLE 11.0: 1.0.8 + #OpenSuse 10.2: 0.6.13 + #OpenSuse 11.2: 1.2.8 + #Assume that this will work on newer zypper versions + + #extract version numbers and convert to integers + major, minor, patch = zypper_version.scan(/\d+/).map{ |x| x.to_i } + self.debug "Detected zypper version #{major}.#{minor}.#{patch}" + + #zypper version < 1.0 does not support --quiet flag + quiet = "--quiet" + if major < 1 + quiet = "--terse" + end + + license = "--auto-agree-with-licenses" + noconfirm = "--no-confirm" + + #zypper 0.6.13 (OpenSuSE 10.2) does not support auto agree with licenses + if major < 1 and minor <= 6 and patch <= 13 + zypper quiet, :install, noconfirm, wanted + else + zypper quiet, :install, license, noconfirm, wanted + end unless self.query raise Puppet::ExecutionFailure.new( "Could not find package #{self.name}" ) end end # What's the latest package version available? def latest #zypper can only get a list of *all* available packages? output = zypper "list-updates" if output =~ /#{Regexp.escape @resource[:name]}\s*\|\s*([^\s\|]+)/ return $1 else # zypper didn't find updates, pretend the current # version is the latest return @property_hash[:ensure] end end def update # zypper install can be used for update, too self.install end end diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb index 4218b14c7..93a694d2d 100755 --- a/spec/unit/provider/package/zypper_spec.rb +++ b/spec/unit/provider/package/zypper_spec.rb @@ -1,80 +1,127 @@ #!/usr/bin/env rspec require 'spec_helper' provider_class = Puppet::Type.type(:package).provider(:zypper) describe provider_class do before(:each) do # Create a mock resource @resource = stub 'resource' # A catch all; no parameters set @resource.stubs(:[]).returns(nil) # But set name and source @resource.stubs(:[]).with(:name).returns "mypackage" @resource.stubs(:[]).with(:ensure).returns :installed @resource.stubs(:command).with(:zypper).returns "/usr/bin/zypper" @provider = provider_class.new(@resource) end it "should have an install method" do @provider = provider_class.new @provider.should respond_to(:install) end - it "should have a latest method" do + it "should have an uninstall method" do @provider = provider_class.new @provider.should respond_to(:uninstall) end it "should have an update method" do @provider = provider_class.new @provider.should respond_to(:update) end it "should have a latest method" do @provider = provider_class.new @provider.should respond_to(:latest) end - describe "when installing" do + describe "when installing with zypper version >= 1.0" do + it "should use a command-line with versioned package'" do + @resource.stubs(:should).with(:ensure).returns "1.2.3-4.5.6" + @provider.stubs(:zypper_version).returns "1.2.8" + + @provider.expects(:zypper).with('--quiet', :install, + '--auto-agree-with-licenses', '--no-confirm', 'mypackage-1.2.3-4.5.6') + @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64" + @provider.install + end + + it "should use a command-line without versioned package" do + @resource.stubs(:should).with(:ensure).returns :latest + @provider.stubs(:zypper_version).returns "1.2.8" + @provider.expects(:zypper).with('--quiet', :install, + '--auto-agree-with-licenses', '--no-confirm', 'mypackage') + @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64" + @provider.install + end + end + + describe "when installing with zypper version = 0.6.104" do it "should use a command-line with versioned package'" do @resource.stubs(:should).with(:ensure).returns "1.2.3-4.5.6" - @provider.expects(:zypper).with('--quiet', :install, '-l', '-y', 'mypackage-1.2.3-4.5.6') + @provider.stubs(:zypper_version).returns "0.6.104" + + @provider.expects(:zypper).with('--terse', :install, + '--auto-agree-with-licenses', '--no-confirm', 'mypackage-1.2.3-4.5.6') + @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64" + @provider.install + end + + it "should use a command-line without versioned package" do + @resource.stubs(:should).with(:ensure).returns :latest + @provider.stubs(:zypper_version).returns "0.6.104" + @provider.expects(:zypper).with('--terse', :install, + '--auto-agree-with-licenses', '--no-confirm', 'mypackage') + @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64" + @provider.install + end + end + + describe "when installing with zypper version = 0.6.13" do + it "should use a command-line with versioned package'" do + @resource.stubs(:should).with(:ensure).returns "1.2.3-4.5.6" + @provider.stubs(:zypper_version).returns "0.6.13" + + @provider.expects(:zypper).with('--terse', :install, + '--no-confirm', 'mypackage-1.2.3-4.5.6') @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64" @provider.install end it "should use a command-line without versioned package" do @resource.stubs(:should).with(:ensure).returns :latest - @provider.expects(:zypper).with('--quiet', :install, '-l', '-y', 'mypackage') + @provider.stubs(:zypper_version).returns "0.6.13" + @provider.expects(:zypper).with('--terse', :install, + '--no-confirm', 'mypackage') @provider.expects(:query).returns "mypackage 0 1.2.3 4.5.6 x86_64" @provider.install end end describe "when updating" do it "should call install method of instance" do @provider.expects(:install) @provider.update end end describe "when getting latest version" do it "should return a version string" do fake_data = "Loading repository data... Reading installed packages... S | Repository | Name | Version | Arch --+----------------+-----------------------+-----------------+------- v | SLES11-Updates | cups | 1.1.1 | x86_64 v | SLES11-Updates | mypackage | 1.3.9h-8.20.1 | x86_64" @provider.expects(:zypper).with("list-updates").returns fake_data @provider.latest.should == "1.3.9h-8.20.1" end end end