diff --git a/bin/puppetdoc b/bin/puppetdoc index 8185ed773..2c7b1879b 100755 --- a/bin/puppetdoc +++ b/bin/puppetdoc @@ -1,346 +1,405 @@ #!/usr/bin/env ruby # # = Synopsis # # Generate a reference for all Puppet types. Largely meant for internal Reductive # Labs use. # # = Usage # # puppetdoc [-h|--help] [-a|--arguments] [-t|--types] # # = Description # # This command generates a restructured-text document describing all installed # Puppet types or all allowable arguments to puppet executables. It is largely # meant for internal use and is used to generate the reference document # available on the Reductive Labs web site. # # = Options # # arguments:: # Print the documentation for arguments. # # help:: # Print this help message # # types:: # Print the argumenst for Puppet types. This is the default. # # = Example # # $ puppetdoc > /tmp/reference.rst # # = Author # # Luke Kanies # # = Copyright # # Copyright (c) 2005 Reductive Labs, LLC # Licensed under the GNU Public License require 'puppet' require 'getoptlong' $haveusage = true begin require 'rdoc/usage' rescue Exception $haveusage = false end result = GetoptLong.new( [ "--arguments", "-a", GetoptLong::NO_ARGUMENT ], [ "--types", "-t", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ) debug = false $tab = " " mode = :types begin result.each { |opt,arg| case opt when "--arguments" mode = :arguments when "--types" mode = :types when "--help" if $haveusage RDoc::usage && exit else puts "No help available unless you have RDoc::usage installed" exit end end } rescue GetoptLong::InvalidOption => detail $stderr.puts "Try '#{$0} --help'" #if $haveusage # RDoc::usage_no_exit('usage') #end exit(1) end def scrub(text) # Stupid markdown #text = text.gsub("<%=", "<%=") # For text with no carriage returns, there's nothing to do. if text !~ /\n/ return text end indent = nil # If we can match an indentation, then just remove that same level of # indent from every line. if text =~ /^(\s+)/ indent = $1 begin return text.gsub(/^#{indent}/,'') rescue => detail puts detail.backtrace puts detail end else return text end end # Indent every line in the chunk except those which begin with '..'. def indent(text, tab) return text.gsub(/(^|\A)/, tab).gsub(/^ +\.\./, "..") end def paramwrap(name, text, namevar = false) if namevar name = name.to_s + " (*namevar*)" end puts "#### %s" % name puts text puts "" end # Print the docs for arguments def self.arguments puts %{--- inMenu: true title: Configuration Reference orderInfo: 6 --- # Puppet Configuration Reference Every Puppet executable (with the exception of ``puppetdoc``) accepts all of these arguments, but not all of the arguments make sense for every executable. Each argument has a section listed with it in parentheses; often, that section will map to an executable (e.g., ``puppetd``), in which case it probably only makes sense for that one executable. If ``puppet`` is listed as the section, it is most likely an option that is valid for everyone. This will not always be the case. I have tried to be as thorough as possible in the descriptions of the arguments, so it should be obvious whether an -argument is approprite or not. +argument is appropriate or not. + +These arguments can be supplied to the executables either as command-line +arugments or in the configuration file for the appropriate executable. For +instance, the command-line invocation below would set the configuration directory +to /private/puppet + + $ puppetd --confdir=/private/puppet + +Note that boolean options are turned on and off with a slightly different syntax +on the command line: + + $ puppetd --storeconfigs + + $ puppetd --no-storeconfigs + +The invocations above will enable and disable, respectively, the storage of +the client configuration. + +As mentioned above, the configuration parameters can also be stored in a +configuration file located in the configuration directory (`/etc/puppet` +by default). The file is named for the executable it is intended for, for +example `/etc/puppetd.conf` is the configuration file for `puppetd`. + +The file, which follows INI-style formatting, should contain a bracketed +heading named for the executable, followed by pairs of parameters with their +values. Here is an example of a very simple `puppetd.conf` file: + + [puppetd] + confdir = /private/puppet + storeconfigs = true + +Note that boolean parameters must be explicitly specified as `true` or +`false` as seen above. + +If you're starting out with a fresh configuration, you may wish to let +the executable generate a template configuration file for you by invoking +the executable in question with the `--genconfig` command. The executable +will print a template configuration to standard output, which can be +redirected to a file like so: + + $ puppetd --genconfig > /etc/puppet/puppetd.conf + +Note that this invocation will "clobber" (throw away) the contents of any +pre-existing `puppetd.conf` file, so make a backup of your present config +if it contains valuable information. + +Like the `--genconfig` argument, the executables also accept a `--genmanifest` +argument, which will generate a manifest that can be used to manage all of +Puppet's directories and files and prints it to standard output. This can +likewise be redirected to a file: + + $ puppetd --genmanifest > /etc/puppet/manifests/site.pp + +Puppet can also create user and group accounts for itself (one `puppet` group +and one `puppet` user) if it is invoked as `root` with the `--mkusers` argument: + + $ puppetd --mkusers + + Any default values are in ``block type`` at the end of the description. } docs = {} Puppet.config.each do |name, object| docs[name] = object end docs.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, object| # Make each name an anchor puts %{#### #{name.to_s} (#{object.section.to_s})} puts "" default = "" if val = object.value and val != "" default = " ``%s``" % val end begin puts object.desc.gsub(/\n/, " ") + default rescue => detail puts detail.backtrace puts detail end puts "" end end # Print the docs for types def self.types puts %{--- inMenu: true title: Type Reference orderInfo: 4 --- # Type Reference } types = {} Puppet::Type.loadall Puppet::Type.eachtype { |type| next if type.name == :puppet next if type.name == :component types[type.name] = type } # Build a simple TOC puts "## Table of Contents" puts "1. Meta-Parameters" types.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, type| puts "1. %s" % [type.name, type.name.to_s.capitalize] end puts %{

Meta-Parameters

Metaparameters are parameters that work with any element; they are part of the Puppet framework itself rather than being part of the implementation of any given instance. Thus, any defined metaparameter can be used with any instance in your manifest, including defined components. } begin params = [] Puppet::Type.eachmetaparam { |param| params << param } params.sort { |a,b| a.to_s <=> b.to_s }.each { |param| paramwrap(param.to_s, scrub(Puppet::Type.metaparamdoc(param))) #puts "
" + param.to_s + "
" #puts tab(1) + Puppet::Type.metaparamdoc(param).scrub.indent($tab)gsub(/\n\s*/,' ') #puts "
" #puts indent(scrub(Puppet::Type.metaparamdoc(param)), $tab) #puts scrub(Puppet::Type.metaparamdoc(param)) #puts "
" #puts "" } rescue => detail puts detail.backtrace puts "incorrect metaparams: %s" % detail exit(1) end puts %{ ## Types - *namevar* is the parameter used to uniquely identify a type instance. This is the parameter that gets assigned when a string is provided before the colon in a type declaration. In general, only developers will need to worry about which parameter is the ``namevar``. In the following code: file { "/etc/passwd": owner => root, group => root, mode => 644 } "/etc/passwd" is considered the name of the file object (used for things like dependency handling), and because ``path`` is the namevar for ``file``, that string is assigned to the ``path`` parameter. - *parameters* determine the specific configuration of the instance. They either directly modify the system (internally, these are called states) or they affect how the instance behaves (e.g., adding a search path for ``exec`` instances or determining recursion on ``file`` instances). When required binaries are specified for providers, fully qualifed paths indicate that the binary must exist at that specific path and unqualified binaries indicate that Puppet will search for the binary using the shell path. } types.sort { |a,b| a.to_s <=> b.to_s }.each { |name,type| puts " ---------------- " puts "

%s

" % [name, name] puts scrub(type.doc) + "\n\n" docs = {} type.validstates.sort { |a,b| a.to_s <=> b.to_s }.reject { |sname| state = type.statebyname(sname) state.nodoc }.each { |sname| state = type.statebyname(sname) unless state raise "Could not retrieve state %s on type %s" % [sname, type.name] end doc = nil str = nil unless doc = state.doc $stderr.puts "No docs for %s[%s]" % [type, sname] next end doc = doc.dup str = doc str = scrub(str) #str = indent(str, $tab) docs[sname] = str } puts "\n### %s Parameters\n" % name.to_s.capitalize type.parameters.sort { |a,b| a.to_s <=> b.to_s }.each { |name,param| #docs[name] = indent(scrub(type.paramdoc(name)), $tab) docs[name] = scrub(type.paramdoc(name)) } docs.sort { |a, b| a[0].to_s <=> b[0].to_s }.each { |name, doc| namevar = type.namevar == name and name != :name paramwrap(name, doc, namevar) } puts "\n" } end send(mode) puts " ---------------- " puts "\n*This page autogenerated on %s*" % Time.now # $Id$