diff options
author | Jesse Wolfe <jes5199@gmail.com> | 2010-04-30 16:05:43 -0700 |
---|---|---|
committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
commit | d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1 (patch) | |
tree | 6ff89deef467aa58b8b50ea06200b5d2f2dc97ac /lib/puppet | |
parent | 7656ba73ddfd883b36a01c81147ae69e80773bce (diff) | |
download | puppet-d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1.tar.gz puppet-d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1.tar.xz puppet-d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1.zip |
Refactor #3706 Reify eigenclasses of Applications
The Puppet::Application DSL is complicated by the fact that it operates
on eigenclasses of instances of Puppet::Application, rather than
subclassing it.
This patch reifies the eigenclasses as subclasses of
Puppet::Application.
Signed-off-by: Jesse Wolfe <jes5199@gmail.com>
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/application.rb | 196 | ||||
-rw-r--r-- | lib/puppet/application/agent.rb | 20 | ||||
-rw-r--r-- | lib/puppet/application/apply.rb | 18 | ||||
-rw-r--r-- | lib/puppet/application/cert.rb | 6 | ||||
-rw-r--r-- | lib/puppet/application/describe.rb | 9 | ||||
-rw-r--r-- | lib/puppet/application/doc.rb | 22 | ||||
-rw-r--r-- | lib/puppet/application/filebucket.rb | 20 | ||||
-rw-r--r-- | lib/puppet/application/kick.rb | 15 | ||||
-rw-r--r-- | lib/puppet/application/master.rb | 20 | ||||
-rw-r--r-- | lib/puppet/application/queue.rb | 11 | ||||
-rw-r--r-- | lib/puppet/application/resource.rb | 8 |
11 files changed, 156 insertions, 189 deletions
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb index 7b404a906..49a146ffe 100644 --- a/lib/puppet/application.rb +++ b/lib/puppet/application.rb @@ -8,26 +8,28 @@ require 'optparse' # * representing execution status # # === Usage -# The application is a Puppet::Application object that register itself in the list -# of available application. Each application needs a +name+ and a getopt +options+ -# description array. +# An application is a subclass of Puppet::Application. # -# The executable uses the application object like this: +# For legacy compatibility, # Puppet::Application[:example].run +# is equivalent to +# Puppet::Application::Example.new.run # # -# Puppet::Application.new(:example) do +# class Puppet::Application::Example << Puppet::Application # -# preinit do +# def preinit # # perform some pre initialization # @all = false # end # -# # dispatch is called to know to what command to call -# dispatch do -# Puppet::Util::CommandLine.args.shift +# # run_command is called to actually run the specified command +# def run_command +# send Puppet::Util::CommandLine.args.shift # end # +# # option uses metaprogramming to create a method +# # and also tells the option parser how to invoke that method # option("--arg ARGUMENT") do |v| # @args << v # end @@ -40,18 +42,18 @@ require 'optparse' # @all = v # end # -# unknown do |opt,arg| +# def handle_unknown(opt,arg) # # last chance to manage an option # ... # # let's say to the framework we finally handle this option # true # end # -# command(:read) do +# def read # # read action # end # -# command(:write) do +# def write # # writeaction # end # @@ -117,9 +119,6 @@ class Puppet::Application BINDIRS = %w{sbin bin}.map{|dir| File.expand_path(File.dirname(__FILE__)) + "/../../#{dir}/*"}.join(" ") - @@applications = {} - def self.applications; @@applications end - class << self include Puppet::Util @@ -172,128 +171,97 @@ class Puppet::Application Process.kill(:HUP, $$) if restart_requested? result end - end - attr_reader :options, :opt_parser + def should_parse_config + @parse_config = true + end - def self.[](name) - name = symbolize(name) - @@applications[name] - end + def should_not_parse_config + @parse_config = false + end - def should_parse_config - @parse_config = true - end + def should_parse_config? + if ! defined? @parse_config + @parse_config = true + end + return @parse_config + end - def should_not_parse_config - @parse_config = false - end + # used to declare code that handle an option + def option(*options, &block) + long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_') + fname = symbolize("handle_#{long}") + if (block_given?) + define_method(fname, &block) + else + define_method(fname) do |value| + self.options["#{long}".to_sym] = value + end + end + @opt_parser_commands ||= [] + @opt_parser_commands << [options, fname] + end - def should_parse_config? - unless @parse_config.nil? - return @parse_config + def banner(banner = nil) + @banner = banner unless banner.nil? end - @parse_config = true - end - # used to declare a new command - def command(name, &block) - meta_def(symbolize(name), &block) - end + def new_option_parser( target ) + @banner ||= nil - # used as a catch-all for unknown option - def unknown(&block) - meta_def(:handle_unknown, &block) - end + opt_parser = OptionParser.new(@banner) - # used to declare code that handle an option - def option(*options, &block) - long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_') - fname = "handle_#{long}" - if (block_given?) - meta_def(symbolize(fname), &block) - else - meta_def(symbolize(fname)) do |value| - self.options["#{long}".to_sym] = value + @opt_parser_commands ||= [] + @opt_parser_commands.each do |options, fname| + opt_parser.on(*options) do |value| + target.send(fname, value) + end end + opt_parser end - @opt_parser.on(*options) do |value| - self.send(symbolize(fname), value) + + def find(name) + self.const_get(name.to_s.capitalize) end - end - # used to declare accessor in a more natural way in the - # various applications - def attr_accessor(*args) - args.each do |arg| - meta_def(arg) do - instance_variable_get("@#{arg}".to_sym) - end - meta_def("#{arg}=") do |value| - instance_variable_set("@#{arg}".to_sym, value) - end + def [](name) + find(name).new end end - # used to declare code run instead the default setup - def setup(&block) - meta_def(:run_setup, &block) - end + attr_reader :options, :opt_parser - # used to declare code to choose which command to run - def dispatch(&block) - meta_def(:get_command, &block) + # Every app responds to --version + option("--version", "-V") do |arg| + puts "%s" % Puppet.version + exit end - # used to execute code before running anything else - def preinit(&block) - meta_def(:run_preinit, &block) + # Every app responds to --help + option("--help", "-h") do |v| + help end - def initialize(name, banner = nil, &block) - @opt_parser = OptionParser.new(banner) - - @name = symbolize(name) - - init_default - - @options = {} - - instance_eval(&block) if block_given? - - @@applications[@name] = self + def should_parse_config? + self.class.should_parse_config? end - # initialize default application behaviour - def init_default - setup do - default_setup - end - - dispatch do - :main - end - - # empty by default - preinit do - end + # override to execute code before running anything else + def preinit + end - option("--version", "-V") do |arg| - puts "%s" % Puppet.version - exit - end + def initialize + @opt_parser = self.class.new_option_parser( self ) - option("--help", "-h") do |v| - help - end + @options = {} end # This is the main application entry point def run - exit_on_fail("initialize") { run_preinit } + exit_on_fail("initialize") { preinit } exit_on_fail("parse options") { parse_options } exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config? - exit_on_fail("prepare for execution") { run_setup } + exit_on_fail("prepare for execution") { setup } exit_on_fail("run") { run_command } end @@ -302,14 +270,10 @@ class Puppet::Application end def run_command - if command = get_command() and respond_to?(command) - send(command) - else - main - end + main end - def default_setup + def setup # Handle the logging settings if options[:debug] or options[:verbose] Puppet::Util::Log.newdestination(:console) @@ -370,10 +334,14 @@ class Puppet::Application exit(code) end + def name + self.class.to_s.sub(/.*::/,"").downcase.to_sym + end + def help if Puppet.features.usage? # RH:FIXME: My goodness, this is ugly. - ::RDoc.const_set("PuppetSourceFile", @name) + ::RDoc.const_set("PuppetSourceFile", name) def (::RDoc).caller docfile = `grep -l 'Puppet::Application\\[:#{::RDoc::PuppetSourceFile}\\]' #{BINDIRS}`.chomp super << "#{docfile}:0" @@ -384,7 +352,7 @@ class Puppet::Application exit end rescue Errno::ENOENT - puts "No help available for puppet #@name" + puts "No help available for puppet #{name}" exit end diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb index 985d87dd0..093e5b94d 100644 --- a/lib/puppet/application/agent.rb +++ b/lib/puppet/application/agent.rb @@ -5,13 +5,13 @@ require 'puppet/daemon' require 'puppet/configurer' require 'puppet/network/client' -Puppet::Application.new(:agent) do +class Puppet::Application::Agent < Puppet::Application should_parse_config attr_accessor :explicit_waitforcert, :args, :agent, :daemon, :host - preinit do + def preinit # Do an initial trap, so that cancels don't get a stack trace. trap(:INT) do $stderr.puts "Cancelling startup" @@ -96,13 +96,13 @@ Puppet::Application.new(:agent) do @args[:Port] = arg end - dispatch do - return :fingerprint if options[:fingerprint] - return :onetime if options[:onetime] - return :main + def run_command + return fingerprint if options[:fingerprint] + return onetime if options[:onetime] + return main end - command(:fingerprint) do + def fingerprint unless cert = host.certificate || host.certificate_request $stderr.puts "Fingerprint asked but no certificate nor certificate request have yet been issued" exit(1) @@ -114,7 +114,7 @@ Puppet::Application.new(:agent) do Puppet.notice fingerprint end - command(:onetime) do + def onetime unless options[:client] $stderr.puts "onetime is specified but there is no client" exit(43) @@ -141,7 +141,7 @@ Puppet::Application.new(:agent) do end end - command(:main) do + def main Puppet.notice "Starting Puppet client version %s" % [Puppet.version] @daemon.start @@ -207,7 +207,7 @@ Puppet::Application.new(:agent) do @daemon.server = server end - setup do + def setup setup_test if options[:test] setup_logs diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb index d977cf1d0..88385f0a0 100644 --- a/lib/puppet/application/apply.rb +++ b/lib/puppet/application/apply.rb @@ -4,7 +4,7 @@ require 'puppet/configurer' require 'puppet/network/handler' require 'puppet/network/client' -Puppet::Application.new(:apply) do +class Puppet::Application::Apply < Puppet::Application should_parse_config @@ -30,17 +30,17 @@ Puppet::Application.new(:apply) do end end - dispatch do + def run_command if options[:catalog] - :apply + apply elsif Puppet[:parseonly] - :parseonly + parseonly else - :main + main end end - command(:apply) do + def apply require 'puppet/configurer' if options[:catalog] == "-" @@ -64,7 +64,7 @@ Puppet::Application.new(:apply) do configurer.run :catalog => catalog end - command(:parseonly) do + def parseonly # Set our code or file to use. if options[:code] or Puppet::Util::CommandLine.args.length == 0 Puppet[:code] = options[:code] || STDIN.read @@ -80,7 +80,7 @@ Puppet::Application.new(:apply) do exit 0 end - command(:main) do + def main # Set our code or file to use. if options[:code] or Puppet::Util::CommandLine.args.length == 0 Puppet[:code] = options[:code] || STDIN.read @@ -153,7 +153,7 @@ Puppet::Application.new(:apply) do end end - setup do + def setup if Puppet.settings.print_configs? exit(Puppet.settings.print_configs ? 0 : 1) end diff --git a/lib/puppet/application/cert.rb b/lib/puppet/application/cert.rb index 7a7784b09..92da03ca7 100644 --- a/lib/puppet/application/cert.rb +++ b/lib/puppet/application/cert.rb @@ -2,7 +2,7 @@ require 'puppet' require 'puppet/application' require 'puppet/ssl/certificate_authority' -Puppet::Application.new(:cert) do +class Puppet::Application::Cert < Puppet::Application should_parse_config @@ -40,7 +40,7 @@ Puppet::Application.new(:cert) do Puppet::Util::Log.level = :info end - command(:main) do + def main if @all hosts = :all else @@ -56,7 +56,7 @@ Puppet::Application.new(:cert) do end end - setup do + def setup if Puppet.settings.print_configs? exit(Puppet.settings.print_configs ? 0 : 1) end diff --git a/lib/puppet/application/describe.rb b/lib/puppet/application/describe.rb index ea4ac162c..45f017a48 100644 --- a/lib/puppet/application/describe.rb +++ b/lib/puppet/application/describe.rb @@ -175,7 +175,8 @@ class TypeDoc end -Puppet::Application.new(:describe,"#{$0} [options] [type]") do +class Puppet::Application::Describe < Puppet::Application + banner "puppet describe [options] [type]" should_not_parse_config @@ -187,11 +188,11 @@ Puppet::Application.new(:describe,"#{$0} [options] [type]") do option("--list", "-l") option("--meta","-m") - preinit do + def preinit options[:parameters] = true end - command(:main) do + def main doc = TypeDoc.new if options[:list] @@ -201,7 +202,7 @@ Puppet::Application.new(:describe,"#{$0} [options] [type]") do end end - setup do + def setup options[:types] = Puppet::Util::CommandLine.args.dup unless options[:list] || options[:types].size > 0 handle_help(nil) diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb index 0a11d6045..295cd6771 100644 --- a/lib/puppet/application/doc.rb +++ b/lib/puppet/application/doc.rb @@ -7,13 +7,13 @@ require 'puppet/util/rdoc' $tab = " " Reference = Puppet::Util::Reference -Puppet::Application.new(:doc) do +class Puppet::Application::Doc < Puppet::Application should_not_parse_config attr_accessor :unknown_args, :manifest - preinit do + def preinit {:references => [], :mode => :text, :format => :to_rest }.each do |name,value| options[name] = value end @@ -52,17 +52,17 @@ Puppet::Application.new(:doc) do options[:references] << arg.intern end - unknown do |opt, arg| + def handle_unknown( opt, arg ) @unknown_args << {:opt => opt, :arg => arg } true end - dispatch do - return options[:mode] if [:rdoc, :trac, :markdown].include?(options[:mode]) - return :other + def run_command + return send(options[:mode]) if [:rdoc, :trac, :markdown].include?(options[:mode]) + return other end - command(:rdoc) do + def rdoc exit_code = 0 files = [] unless @manifest @@ -93,7 +93,7 @@ Puppet::Application.new(:doc) do exit exit_code end - command(:trac) do + def trac options[:references].each do |name| section = Puppet::Util::Reference.reference(name) or raise "Could not find section %s" % name unless options[:mode] == :pdf @@ -102,7 +102,7 @@ Puppet::Application.new(:doc) do end end - command(:markdown) do + def markdown text = "" with_contents = false exit_code = 0 @@ -127,7 +127,7 @@ Puppet::Application.new(:doc) do exit exit_code end - command(:other) do + def other text = "" if options[:references].length > 1 with_contents = false @@ -165,7 +165,7 @@ Puppet::Application.new(:doc) do exit exit_code end - setup do + def setup # sole manifest documentation if Puppet::Util::CommandLine.args.size > 0 options[:mode] = :rdoc diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/application/filebucket.rb index cd7c854af..ddc46e394 100644 --- a/lib/puppet/application/filebucket.rb +++ b/lib/puppet/application/filebucket.rb @@ -2,7 +2,7 @@ require 'puppet' require 'puppet/application' require 'puppet/file_bucket/dipper' -Puppet::Application.new(:filebucket) do +class Puppet::Application::Filebucket < Puppet::Application should_not_parse_config @@ -12,22 +12,22 @@ Puppet::Application.new(:filebucket) do option("--remote","-r") option("--verbose","-v") - class << self - attr :args - end + attr :args - dispatch do + def run_command @args = Puppet::Util::CommandLine.args - args.shift + command = args.shift + return send(command) if %w[get backup restore].include? command + help end - command(:get) do + def get md5 = args.shift out = @client.getfile(md5) print out end - command(:backup) do + def backup args.each do |file| unless FileTest.exists?(file) $stderr.puts "%s: no such file" % file @@ -42,13 +42,13 @@ Puppet::Application.new(:filebucket) do end end - command(:restore) do + def restore file = args.shift md5 = args.shift @client.restore(file, md5) end - setup do + def setup Puppet::Log.newdestination(:console) @client = nil diff --git a/lib/puppet/application/kick.rb b/lib/puppet/application/kick.rb index 7b4993bb4..37d3e533f 100644 --- a/lib/puppet/application/kick.rb +++ b/lib/puppet/application/kick.rb @@ -4,7 +4,7 @@ require 'puppet/application' Puppet.warning "RubyGems not installed" unless Puppet.features.rubygems? Puppet.warning "Failed to load ruby LDAP library. LDAP functionality will not be available" unless Puppet.features.ldap? -Puppet::Application.new(:kick) do +class Puppet::Application::Kick < Puppet::Application should_not_parse_config @@ -41,17 +41,16 @@ Puppet::Application.new(:kick) do end end - - dispatch do - options[:test] ? :test : :main + def run_command + options[:test] ? test : main end - command(:test) do + def test puts "Skipping execution in test mode" exit(0) end - command(:main) do + def main require 'puppet/network/client' require 'puppet/util/ldap/connection' @@ -147,7 +146,7 @@ Puppet::Application.new(:kick) do end end - preinit do + def preinit [:INT, :TERM].each do |signal| trap(signal) do $stderr.puts "Cancelling" @@ -165,7 +164,7 @@ Puppet::Application.new(:kick) do @tags = [] end - setup do + def setup if options[:debug] Puppet::Util::Log.level = :debug else diff --git a/lib/puppet/application/master.rb b/lib/puppet/application/master.rb index 8f1c0cd95..2433780c2 100644 --- a/lib/puppet/application/master.rb +++ b/lib/puppet/application/master.rb @@ -4,7 +4,7 @@ require 'puppet/daemon' require 'puppet/network/server' require 'puppet/network/http/rack' if Puppet.features.rack? -Puppet::Application.new(:master) do +class Puppet::Application::Master < Puppet::Application should_parse_config @@ -30,7 +30,7 @@ Puppet::Application.new(:master) do end end - preinit do + def preinit trap(:INT) do $stderr.puts "Cancelling startup" exit(0) @@ -41,17 +41,17 @@ Puppet::Application.new(:master) do @daemon.argv = ARGV.dup end - dispatch do + def run_command if options[:node] - :compile + compile elsif Puppet[:parseonly] - :parseonly + parseonly else - :main + main end end - command(:compile) do + def compile Puppet::Util::Log.newdestination :console raise ArgumentError, "Cannot render compiled catalogs without pson support" unless Puppet.features.pson? begin @@ -67,7 +67,7 @@ Puppet::Application.new(:master) do exit(0) end - command(:parseonly) do + def parseonly begin Puppet::Resource::TypeCollection.new(Puppet[:environment]).perform_initial_import rescue => detail @@ -77,7 +77,7 @@ Puppet::Application.new(:master) do exit(0) end - command(:main) do + def main require 'etc' require 'puppet/file_serving/content' require 'puppet/file_serving/metadata' @@ -124,7 +124,7 @@ Puppet::Application.new(:master) do end end - setup do + def setup # Handle the logging settings. if options[:debug] or options[:verbose] if options[:debug] diff --git a/lib/puppet/application/queue.rb b/lib/puppet/application/queue.rb index 13fb3e107..4b3aa57b5 100644 --- a/lib/puppet/application/queue.rb +++ b/lib/puppet/application/queue.rb @@ -5,13 +5,12 @@ require 'puppet/resource/catalog' require 'puppet/indirector/catalog/queue' require 'puppet/util' -Puppet::Application.new(:queue) do - extend Puppet::Util +class Puppet::Application::Queue < Puppet::Application should_parse_config attr_accessor :daemon - preinit do + def preinit @daemon = Puppet::Daemon.new @daemon.argv = ARGV.dup Puppet::Util::Log.newdestination(:console) @@ -41,13 +40,13 @@ Puppet::Application.new(:queue) do option("--debug","-d") option("--verbose","-v") - command(:main) do + def main Puppet.notice "Starting puppetqd %s" % Puppet.version Puppet::Resource::Catalog::Queue.subscribe do |catalog| # Once you have a Puppet::Resource::Catalog instance, calling save() on it should suffice # to put it through to the database via its active_record indirector (which is determined # by the terminus_class = :active_record setting above) - benchmark(:notice, "Processing queued catalog for %s" % catalog.name) do + Puppet::Util.benchmark(:notice, "Processing queued catalog for %s" % catalog.name) do begin catalog.save rescue => detail @@ -72,7 +71,7 @@ Puppet::Application.new(:queue) do end end - setup do + def setup unless Puppet.features.stomp? raise ArgumentError, "Could not load the 'stomp' library, which must be present for queueing to work. You must install the required library." end diff --git a/lib/puppet/application/resource.rb b/lib/puppet/application/resource.rb index 78aed95c5..52320e7a1 100644 --- a/lib/puppet/application/resource.rb +++ b/lib/puppet/application/resource.rb @@ -2,13 +2,13 @@ require 'puppet' require 'puppet/application' require 'facter' -Puppet::Application.new(:resource) do +class Puppet::Application::Resource < Puppet::Application should_not_parse_config attr_accessor :host, :extra_params - preinit do + def preinit @extra_params = [] @host = nil Facter.loadfacts @@ -37,7 +37,7 @@ Puppet::Application.new(:resource) do @extra_params << arg.to_sym end - command(:main) do + def main args = Puppet::Util::CommandLine.args type = args.shift or raise "You must specify the type to display" typeobj = Puppet::Type.type(type) or raise "Could not find type #{type}" @@ -109,7 +109,7 @@ Puppet::Application.new(:resource) do end end - setup do + def setup Puppet::Util::Log.newdestination(:console) # Now parse the config |