# class Chef::Provider::Package::Yum::YumCache

Cache for our installed and available packages, pulled in from yum-dump.py

### Attributes

extra_repo_control[R]

### Public Class Methods

new() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 653
    def initialize
      @rpmdb = RPMDb.new

      # Next time @rpmdb is accessed:
      #  :all       - Trigger a run of "yum-dump.py --options --installed-provides", updates
      #               yum's cache and parses options from /etc/yum.conf. Pulls in Provides
      #               dependency data for installed packages only - this data is slow to
      #               gather.
      #  :provides  - Same as :all but pulls in Provides data for available packages as well.
      #               Used as a last resort when we can't find a Provides match.
      #  :installed - Trigger a run of "yum-dump.py --installed", only reads the local rpm
      #               db. Used between client runs for a quick refresh.
      #  :none      - Do nothing, a call to one of the reload methods is required.
      @next_refresh = :all

      @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

### Public Instance Methods

allow_multi_install() click to toggle source

Return an array of packages allowed to be installed multiple times, such as the kernel

    # File lib/chef/provider/package/yum.rb, line 862
    def allow_multi_install
      refresh
      @allow_multi_install
    end

available_version(package_name, arch=nil) click to toggle source

Return the latest available version for a package.arch

    # File lib/chef/provider/package/yum.rb, line 851
    def available_version(package_name, arch=nil)
      version(package_name, arch, true, false)
    end

Also aliased as: candidate_version
candidate_version(package_name, arch=nil)
Alias for: available_version
disable_extra_repo_control() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 875
    def disable_extra_repo_control
      # Only force reload when set
      if @extra_repo_control
        @extra_repo_control = nil
        reload
      end
    end

enable_extra_repo_control(arg) click to toggle source

    # File lib/chef/provider/package/yum.rb, line 867
    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

installed_version(package_name, arch=nil) click to toggle source

Return the currently installed version for a package.arch

    # File lib/chef/provider/package/yum.rb, line 857
    def installed_version(package_name, arch=nil)
      version(package_name, arch, false, true)
    end

package_available?(package_name) click to toggle source

Check for package by name or name+arch

    # File lib/chef/provider/package/yum.rb, line 805
    def package_available?(package_name)
      refresh

      if @rpmdb.lookup(package_name)
        return true
      else
        if package_name =~ %r{^(.*)\.(.*)$}
          pkg_name = $1
          pkg_arch = $2

          if matches = @rpmdb.lookup(pkg_name)
            matches.each do |m|
              return true if m.arch == pkg_arch
            end
          end
        end
      end

      return false
    end

package_repository(package_name, desired_version, arch=nil) click to toggle source

Return the source repository for a package-version.arch

    # File lib/chef/provider/package/yum.rb, line 842
    def package_repository(package_name, desired_version, arch=nil)
      package(package_name, arch, true, false) do |pkg|
        return pkg.repoid if desired_version == pkg.version.to_s
      end

      return nil
    end

packages_from_require(rpmdep) click to toggle source

Returns a array of packages satisfying an RPMDependency

    # File lib/chef/provider/package/yum.rb, line 827
    def packages_from_require(rpmdep)
      refresh
      @rpmdb.whatprovides(rpmdep)
    end

refresh() click to toggle source

Cache management

    # File lib/chef/provider/package/yum.rb, line 683
    def refresh
      case @next_refresh
      when :none
        return nil
      when :installed
        reset_installed
        # fast
        opts=" --installed"
      when :all
        reset
        # medium
        opts=" --options --installed-provides"
      when :provides
        reset
        # slow!
        opts=" --options --all-provides"
      else
        raise ArgumentError, "Unexpected value in next_refresh: #{@next_refresh}"
      end

      if @extra_repo_control
        opts << " #{@extra_repo_control}"
      end

      one_line = false
      error = nil

      helper = ::File.join(::File.dirname(__FILE__), 'yum-dump.py')
      status = nil

      begin
        status = shell_out!("/usr/bin/python #{helper}#{opts}", :timeout => Chef::Config[:yum_timeout])
        status.stdout.each_line do |line|
          one_line = true

          line.chomp!

          if line =~ %r{\[option (.*)\] (.*)}
            if $1 == "installonlypkgs"
              @allow_multi_install = $2.split
            else
              raise Chef::Exceptions::Package, "Strange, unknown option line '#{line}' from yum-dump.py"
            end
            next
          end

          if line =~ %r{^(\S+) ([0-9]+) (\S+) (\S+) (\S+) \[(.*)\] ([i,a,r]) (\S+)$}
            name     = $1
            epoch    = $2
            version  = $3
            release  = $4
            arch     = $5
            provides = parse_provides($6)
            type     = $7
            repoid   = $8
          else
            Chef::Log.warn("Problem parsing line '#{line}' from yum-dump.py! " +
                           "Please check your yum configuration.")
            next
          end

          case type
          when "i"
            # if yum-dump was called with --installed this may not be true, but it's okay
            # since we don't touch the @available Set in reload_installed
            available = false
            installed = true
          when "a"
            available = true
            installed = false
          when "r"
            available = true
            installed = true
          end

          pkg = RPMDbPackage.new(name, epoch, version, release, arch, provides, installed, available, repoid)
          @rpmdb << pkg
        end

        error = status.stderr
      rescue Mixlib::ShellOut::CommandTimeout => e
        Chef::Log.error("#{helper} exceeded timeout #{Chef::Config[:yum_timeout]}")
        raise(e)
      end

      if status.exitstatus != 0
        raise Chef::Exceptions::Package, "Yum failed - #{status.inspect} - returns: #{error}"
      else
        unless one_line
          Chef::Log.warn("Odd, no output from yum-dump.py. Please check " +
                         "your yum configuration.")
        end
      end

      # A reload method must be called before the cache is altered
      @next_refresh = :none
    end

reload() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 781
    def reload
      @next_refresh = :all
    end

reload_installed() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 785
    def reload_installed
      @next_refresh = :installed
    end

reload_provides() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 789
    def reload_provides
      @next_refresh = :provides
    end

reset() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 793
    def reset
      @rpmdb.clear
    end

reset_installed() click to toggle source

    # File lib/chef/provider/package/yum.rb, line 797
    def reset_installed
      @rpmdb.clear_installed
    end

version_available?(package_name, desired_version, arch=nil) click to toggle source

Check if a package-version.arch is available to install

    # File lib/chef/provider/package/yum.rb, line 833
    def version_available?(package_name, desired_version, arch=nil)
      version(package_name, arch, true, false) do |v|
        return true if desired_version == v
      end

      return false
    end