# This doesn't get stored in trac, since it changes every time. providers = Puppet::Util::Reference.newreference :providers, :title => "Provider Suitability Report", :depth => 1, :dynamic => true, :doc => "Which providers are valid for this machine" do types = [] Puppet::Type.loadall Puppet::Type.eachtype do |klass| next unless klass.providers.length > 0 types << klass end types.sort! { |a,b| a.name.to_s <=> b.name.to_s } unless ARGV.empty? types.reject! { |type| ! ARGV.include?(type.name.to_s) } end ret = "Details about this host:\n\n" # Throw some facts in there, so we know where the report is from. ["Ruby Version", "Puppet Version", "Operating System", "Operating System Release"].each do |label| name = label.gsub(/\s+/, '') value = Facter.value(name) ret += option(label, value) end ret += "\n" count = 1 # Produce output for each type. types.each do |type| features = type.features ret += "\n" # add a trailing newline # Now build up a table of provider suitability. headers = %w{Provider Suitable?} + features.collect { |f| f.to_s }.sort table_data = {} functional = false notes = [] begin default = type.defaultprovider.name rescue Puppet::DevError default = "none" end type.providers.sort { |a,b| a.to_s <=> b.to_s }.each do |pname| data = [] table_data[pname] = data provider = type.provider(pname) # Add the suitability note if missing = provider.suitable?(false) and missing.empty? data << "**X**" suit = true functional = true else data << "[%s]_" % [count] # A pointer to the appropriate footnote suit = false end # Add a footnote with the details about why this provider is unsuitable, if that's the case unless suit details = ".. [%s]\n" % count missing.each do |test, values| case test when :exists details += " - Missing files %s\n" % values.join(", ") when :variable values.each do |name, facts| if Puppet.settings.valid?(name) details += " - Setting %s (currently %s) not in list %s\n" % [name, Puppet.settings.value(name).inspect, facts.join(", ")] else details += " - Fact %s (currently %s) not in list %s\n" % [name, Facter.value(name).inspect, facts.join(", ")] end end when :true details += " - Got %s true tests that should have been false\n" % values when :false details += " - Got %s false tests that should have been true\n" % values when :feature details += " - Missing features %s\n" % values.collect { |f| f.to_s }.join(",") end end notes << details count += 1 end # Add a note for every feature features.each do |feature| if provider.features.include?(feature) data << "**X**" else data << "" end end end ret += h(type.name.to_s + "_", 2) ret += ".. _%s: %s\n\n" % [type.name, "http://reductivelabs.com/trac/puppet/wiki/TypeReference#%s" % type.name] ret += option("Default provider", default) ret += doctable(headers, table_data) notes.each do |note| ret += note + "\n" end ret += "\n" end ret += "\n" ret end providers.header = " Puppet resource types are usually backed by multiple implementations called ``providers``, which handle variance between platforms and tools. Different providers are suitable or unsuitable on different platforms based on things like the presence of a given tool. Here are all of the provider-backed types and their different providers. Any unmentioned types do not use providers yet. "