diff options
author | AJ Christensen <aj@junglist.gen.nz> | 2009-05-12 03:41:41 +1200 |
---|---|---|
committer | AJ Christensen <aj@junglist.gen.nz> | 2009-05-12 03:41:41 +1200 |
commit | df158ac7c86197bf3fe7d83d4c214b9abdb120e8 (patch) | |
tree | f4757fb8806caa61acb2e3feaec50773907c1415 | |
parent | 0cb51561736c163edd7fcc7ea3e57452d0310c10 (diff) | |
download | chef-df158ac7c86197bf3fe7d83d4c214b9abdb120e8.tar.gz |
CHEF-151: Upfactor chef application classes.
Implement Mixlib for Config and Log classes.
-rw-r--r-- | chef/lib/chef/application.rb | 87 | ||||
-rw-r--r-- | chef/lib/chef/application/agent.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/application/client.rb | 102 | ||||
-rw-r--r-- | chef/lib/chef/application/indexer.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/application/server.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/application/solo.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/config.rb | 244 | ||||
-rw-r--r-- | chef/lib/chef/log.rb | 75 | ||||
-rw-r--r-- | chef/lib/chef/log/formatter.rb | 56 |
9 files changed, 146 insertions, 426 deletions
diff --git a/chef/lib/chef/application.rb b/chef/lib/chef/application.rb index f346848dbb..1e410457a4 100644 --- a/chef/lib/chef/application.rb +++ b/chef/lib/chef/application.rb @@ -1,5 +1,5 @@ # -# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Author:: AJ Christensen (<aj@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -15,19 +15,45 @@ # See the License for the specific language governing permissions and # limitations under the License. -require 'optparse' -require 'chef' +require 'mixlib/cli' require 'chef/exceptions' require 'chef/log' +require 'chef/config' + class Chef::Application + include Mixlib::CLI - attr_accessor :argv, :config, :options - + option :config_file, + :short => "-c CONFIG", + :long => "--config CONFIG", + :default => 'config.rb', + :description => "The configuration file to use" + + option :log_level, + :short => "-l LEVEL", + :long => "--log_level LEVEL", + :description => "Set the log level (debug, info, warn, error, fatal)", + :required => true, + :proc => Proc.new { |l| l.to_sym } + + option :log_location, + :short => "-L LOGLOCATION", + :long => "--logfile LOGLOCATION", + :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing", + :proc => nil } + + option :help, + :short => "-h", + :long => "--help", + :description => "Show this message", + :on => :tail, + :boolean => true, + :show_options => true, + :exit => 0 + def initialize @argv = ARGV.dup - @config = {} - @options = {} trap("INT") do Chef::Application.fatal!("SIGINT received, stopping", 2) @@ -45,7 +71,6 @@ class Chef::Application # Reconfigure the application. You'll want to override and super this method. def reconfigure - configure_opt_parser configure_chef configure_logging end @@ -56,52 +81,12 @@ class Chef::Application setup_application run_application end - - # Build an Option Parser, merge the default options and then parse the command line arguments into the config hash - def configure_opt_parser - OptionParser.new do |opts| - opts.banner = "Usage: #{$0} (options)" - - default_options = { - :config_file => { - :short => "-c CONFIG", - :long => "--config CONFIG", - :description => "The Chef Config file to use", - :proc => nil }, - :log_level => { - :short => "-l LEVEL", - :long => "--loglevel LEVEL", - :description => "Set the log level (debug, info, warn, error, fatal)", - :proc => lambda { |p| p.to_sym} }, - :log_location => { - :short => "-L LOGLOCATION", - :long => "--logfile LOGLOCATION", - :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing", - :proc => nil } - } - - # just a step to the left - @options = default_options.merge(@options) - - # Add the CLI options into OptionParser - @options.each do |opt_key, opt_val| - opts.on(opt_val[:short], opt_val[:long], opt_val[:description]) do |c| - # Update our internal Chef::Config hash, to be merged later. - @config[opt_key] = (opt_val[:proc] && opt_val[:proc].call(c)) || c - end - end - opts.on_tail("-h", "--help", "Show this message") do - puts opts - Chef::Application.fatal!("Exiting", 0) - end - end.parse!(@argv) - end - # Parse the configuration file def configure_chef - Chef::Config.from_file(@config[:config_file]) if @config[:config_file] - Chef::Config.configure { |c| c.merge!(@config).rehash } + parse_options(@argv) + Chef::Config.from_file(config[:config_file]) if config[:config_file] + Chef::Config.merge!(config) end # Initialize and configure the logger diff --git a/chef/lib/chef/application/agent.rb b/chef/lib/chef/application/agent.rb index 37974f40ac..4823a53570 100644 --- a/chef/lib/chef/application/agent.rb +++ b/chef/lib/chef/application/agent.rb @@ -1,5 +1,5 @@ # -# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Author:: AJ Christensen (<aj@opscode.comz>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # diff --git a/chef/lib/chef/application/client.rb b/chef/lib/chef/application/client.rb index 5f902355e8..92ccb86b45 100644 --- a/chef/lib/chef/application/client.rb +++ b/chef/lib/chef/application/client.rb @@ -1,5 +1,5 @@ # -# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Author:: AJ Christensen (<aj@opscode.com) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -22,60 +22,56 @@ require 'chef/daemon' class Chef::Application::Client < Chef::Application + option :user, + :short => "-u USER", + :long => "--user USER", + :description => "User to change uid to before daemonizing", + :proc => nil + + option :group, + :short => "-g GROUP", + :long => "--group GROUP", + :description => "Group to change gid to before daemonizing", + :proc => nil + + option :daemonize, + :short => "-d", + :long => "--daemonize", + :description => "Daemonize the process", + :proc => lambda { |p| true } + + option :interval, + :short => "-i SECONDS", + :long => "--interval SECONDS", + :description => "Run chef-client periodically, in seconds", + :proc => lambda { |s| s.to_i } + + option :json_attribs, + :short => "-j JSON_ATTRIBS", + :long => "--json-attributes JSON_ATTRIBS", + :description => "Load attributes from a JSON file or URL", + :proc => nil + + option :node_name, + :short => "-N NODE_NAME", + :long => "--node-name NODE_NAME", + :description => "The node name for this client", + :proc => nil + + option :splay, + :short => "-s SECONDS", + :long => "--splay SECONDS", + :description => "The splay time for running at intervals, in seconds", + :proc => lambda { |s| s.to_i } + + option :validation_token, + :short => "-t TOKEN", + :long => "--token TOKEN", + :description => "Set the openid validation token", + :proc => nil + def initialize super - - @options = { - :user => { - :short => "-u USER", - :long => "--user USER", - :description => "User to change uid to before daemonizing", - :proc => nil - }, - :group => { - :short => "-g GROUP", - :long => "--group GROUP", - :description => "Group to change gid to before daemonizing", - :proc => nil - }, - :daemonize => { - :short => "-d", - :long => "--daemonize", - :description => "Daemonize the process", - :proc => lambda { |p| true} - }, - :interval => { - :short => "-i SECONDS", - :long => "--interval SECONDS", - :description => "Run chef-client periodically, in seconds", - :proc => lambda { |s| s.to_i } - }, - :json_attribs => { - :short => "-j JSON_ATTRIBS", - :long => "--json-attributes JSON_ATTRIBS", - :description => "Load attributes from a JSON file or URL", - :proc => nil - }, - :node_name => { - :short => "-N NODE_NAME", - :long => "--node-name NODE_NAME", - :description => "The node name for this client", - :proc => nil - }, - :splay => { - :short => "-s SECONDS", - :long => "--splay SECONDS", - :description => "The splay time for running at intervals, in seconds", - :proc => lambda { |s| s.to_i } - }, - :validation_token => { - :short => "-t TOKEN", - :long => "--token TOKEN", - :description => "Set the openid validation token", - :proc => nil - }, - } - @chef_client = nil @chef_client_json = nil end diff --git a/chef/lib/chef/application/indexer.rb b/chef/lib/chef/application/indexer.rb index 37974f40ac..e16f9c6e24 100644 --- a/chef/lib/chef/application/indexer.rb +++ b/chef/lib/chef/application/indexer.rb @@ -1,5 +1,5 @@ # -# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Author:: AJ Christensen (<aj@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # diff --git a/chef/lib/chef/application/server.rb b/chef/lib/chef/application/server.rb index 37974f40ac..e16f9c6e24 100644 --- a/chef/lib/chef/application/server.rb +++ b/chef/lib/chef/application/server.rb @@ -1,5 +1,5 @@ # -# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Author:: AJ Christensen (<aj@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # diff --git a/chef/lib/chef/application/solo.rb b/chef/lib/chef/application/solo.rb index 37974f40ac..e16f9c6e24 100644 --- a/chef/lib/chef/application/solo.rb +++ b/chef/lib/chef/application/solo.rb @@ -1,5 +1,5 @@ # -# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Author:: AJ Christensen (<aj@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # diff --git a/chef/lib/chef/config.rb b/chef/lib/chef/config.rb index 2626c05cf4..40de9ebcc2 100644 --- a/chef/lib/chef/config.rb +++ b/chef/lib/chef/config.rb @@ -1,6 +1,7 @@ # # Author:: Adam Jacob (<adam@opscode.com>) # Author:: Christopher Brown (<cb@opscode.com>) +# Author:: AJ Christensen (<aj@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -16,197 +17,58 @@ # See the License for the specific language governing permissions and # limitations under the License. -require 'chef/mixin/check_helper' -require 'chef/mixin/from_file' +require 'mixlib/config' -# Chef::Config[:variable] -# @config = Chef::Config.new() -# -# Chef::ConfigFast << Chef::Config -# -# Chef::Config.from_file(foo) -# Chef::Resource.from_file (NoMethodError) -# Chef::Config[:cookbook_path] -# Chef::Config.cookbook_path -# Chef::Config.cookbook_path "one", "two" - -class Chef - class Config - include Chef::Mixin::CheckHelper - - @configuration = { - :daemonize => nil, - :user => nil, - :group => nil, - :pid_file => nil, - :delay => 0, - :interval => 1800, - :splay => nil, - :solo => false, - :json_attribs => nil, - :cookbook_path => [ "/var/chef/site-cookbooks", "/var/chef/cookbooks" ], - :validation_token => nil, - :node_path => "/var/chef/node", - :file_store_path => "/var/chef/store", - :search_index_path => "/var/chef/search_index", - :log_level => :info, - :log_location => STDOUT, - :openid_providers => nil, - :ssl_verify_mode => :verify_none, - :ssl_client_cert => "", - :ssl_client_key => "", - :rest_timeout => 60, - :couchdb_url => "http://localhost:5984", - :registration_url => "http://localhost:4000", - :openid_url => "http://localhost:4001", - :template_url => "http://localhost:4000", - :remotefile_url => "http://localhost:4000", - :search_url => "http://localhost:4000", - :couchdb_version => nil, - :couchdb_database => "chef", - :openid_store_couchdb => false, - :openid_cstore_couchdb => false, - :openid_store_path => "/var/chef/openid/db", - :openid_cstore_path => "/var/chef/openid/cstore", - :file_cache_path => "/var/chef/cache", - :node_name => nil, - :executable_path => ENV['PATH'] ? ENV['PATH'].split(File::PATH_SEPARATOR) : [], - :http_retry_delay => 5, - :http_retry_count => 5, - :queue_retry_delay => 5, - :queue_retry_count => 5, - :queue_retry_delay => 5, - :queue_retry_count => 5, - :queue_user => "", - :queue_password => "", - :queue_host => "localhost", - :queue_port => 61613, - :run_command_stdout_timeout => 120, - :run_command_stderr_timeout => 120, - :authorized_openid_identifiers => nil - } - - class << self - include Chef::Mixin::FromFile - - # Pass Chef::Config.configure() a block, and it will yield @configuration. - # - # === Parameters - # <block>:: A block that takes @configure as it's argument - def configure(&block) - yield @configuration - end - - # Manages the chef secret session key - # === Returns - # <newkey>:: A new or retrieved session key - # - def manage_secret_key - newkey = nil - if Chef::FileCache.has_key?("chef_server_cookie_id") - newkey = Chef::FileCache.load("chef_server_cookie_id") - else - chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a - newkey = "" - 40.times { |i| newkey << chars[rand(chars.size-1)] } - Chef::FileCache.store("chef_server_cookie_id", newkey) - end - newkey - end - - # Get the value of a configuration option - # - # === Parameters - # config_option<Symbol>:: The configuration option to return - # - # === Returns - # value:: The value of the configuration option - # - # === Raises - # <ArgumentError>:: If the configuration option does not exist - def [](config_option) - if @configuration.has_key?(config_option.to_sym) - @configuration[config_option.to_sym] - else - raise ArgumentError, "Cannot find configuration option #{config_option.to_s}" - end - end - - # Override the config dispatch to set the value of log_location configuration option - # - # === Parameters - # location<IO||String>:: Logging location as either an IO stream or string representing log file path - # - def log_location=(location) - @configuration[:log_location]=(location.respond_to?(:sync=) ? location : File.new(location, "w+")) - end - - # Internal dispatch setter, calling either the real defined method or setting the - # hash value directly - # - # === Parameters - # method_symbol<Symbol>:: Name of the method (variable setter) - # value<Object>:: Value to be set in config hash - # - def internal_set(method_symbol,value) - method_name = method_symbol.id2name - if self.public_methods.include?("#{method_name}=") - self.send("#{method_name}=", value) - else - @configuration[method_symbol] = value - end - end - - private :internal_set - - # Set the value of a configuration option - # - # === Parameters - # config_option<Symbol>:: The configuration option to set (within the []) - # value:: The value for the configuration option - # - # === Returns - # value:: The new value of the configuration option - def []=(config_option, value) - internal_set(config_option,value) - end - - # Check if Chef::Config has a configuration option. - # - # === Parameters - # key<Symbol>:: The configuration option to check for - # - # === Returns - # <True>:: If the configuration option exists - # <False>:: If the configuration option does not exist - def has_key?(key) - @configuration.has_key?(key.to_sym) - end - - # Allows for simple lookups and setting of configuration options via method calls - # on Chef::Config. If there any arguments to the method, they are used to set - # the value of the configuration option. Otherwise, it's a simple get operation. - # - # === Parameters - # method_symbol<Symbol>:: The method called. Must match a configuration option. - # *args:: Any arguments passed to the method - # - # === Returns - # value:: The value of the configuration option. - # - # === Raises - # <ArgumentError>:: If the method_symbol does not match a configuration option. - def method_missing(method_symbol, *args) - if @configuration.has_key?(method_symbol) - if args.length > 0 - internal_set(method_symbol,(args.length==1 ? args[0] : args)) - end - return @configuration[method_symbol] - else - raise ArgumentError, "Cannot find configuration option #{method_symbol.to_s}" - end - end +class Chef::Config + extend(Mixlib::Config) - end # class << self - end + daemonize nil + user nil + group nil + pid_file nil + delay 0 + interval 1800 + splay nil + solo false + json_attribs nil + cookbook_path [ "/var/chef/site-cookbooks", "/var/chef/cookbooks" ] + validation_token nil + node_path "/var/chef/node" + file_store_path "/var/chef/store" + search_index_path "/var/chef/search_index" + log_level :info + log_location STDOUT + openid_providers nil + ssl_verify_mode :verify_none + ssl_client_cert "" + ssl_client_key "" + rest_timeout 60 + couchdb_url "http://localhost:5984" + registration_url "http://localhost:4000" + openid_url "http://localhost:4001" + template_url "http://localhost:4000" + remotefile_url "http://localhost:4000" + search_url "http://localhost:4000" + couchdb_version nil + couchdb_database "chef" + openid_store_couchdb false + openid_cstore_couchdb false + openid_store_path "/var/chef/openid/db" + openid_cstore_path "/var/chef/openid/cstore" + file_cache_path "/var/chef/cache" + node_name nil + executable_path ENV['PATH'] ? ENV['PATH'].split(File::PATH_SEPARATOR) : [] + http_retry_delay 5 + http_retry_count 5 + queue_retry_delay 5 + queue_retry_count 5 + queue_retry_delay 5 + queue_retry_count 5 + queue_user "" + queue_password "" + queue_host "localhost" + queue_port 61613 + run_command_stdout_timeout 120 + run_command_stderr_timeout 120 + authorized_openid_identifiers nil end diff --git a/chef/lib/chef/log.rb b/chef/lib/chef/log.rb index 4a5c1fbeeb..a0d86bcbaa 100644 --- a/chef/lib/chef/log.rb +++ b/chef/lib/chef/log.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: AJ Christensen (<@aj@opsocde.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -16,76 +17,8 @@ # limitations under the License. require 'chef/config' -require 'chef/log/formatter' -require 'logger' +require 'mixlib/log' -class Chef - class Log - - @logger = nil - - class << self - attr_accessor :logger #:nodoc - - # Use Chef::Logger.init when you want to set up the logger manually. Arguments to this method - # get passed directly to Logger.new, so check out the documentation for the standard Logger class - # to understand what to do here. - # - # If this method is called with no arguments, it will log to STDOUT at the :info level. - # - # It also configures the Logger instance it creates to use the custom Chef::Log::Formatter class. - def init(*opts) - if opts.length == 0 - @logger = Logger.new(STDOUT) - # Turn off any buffering that Ruby might do on stdout to ensure that the log output appears as - # soon as possible. - $stdout.sync = true - else - @logger = Logger.new(*opts) - end - @logger.formatter = Chef::Log::Formatter.new() - level(Chef::Config[:log_level]) - end - - # Sets the level for the Logger object by symbol. Valid arguments are: - # - # :debug - # :info - # :warn - # :error - # :fatal - # - # Throws an ArgumentError if you feed it a bogus log level. - def level(loglevel) - init() unless @logger - case loglevel - when :debug - @logger.level = Logger::DEBUG - when :info - @logger.level = Logger::INFO - when :warn - @logger.level = Logger::WARN - when :error - @logger.level = Logger::ERROR - when :fatal - @logger.level = Logger::FATAL - else - raise ArgumentError, "Log level must be one of :debug, :info, :warn, :error, or :fatal" - end - end - - # Passes any other method calls on directly to the underlying Logger object created with init. If - # this method gets hit before a call to Chef::Logger.init has been made, it will call - # Chef::Logger.init() with no arguments. - def method_missing(method_symbol, *args) - init() unless @logger - if args.length > 0 - @logger.send(method_symbol, *args) - else - @logger.send(method_symbol) - end - end - - end # class << self - end +class Chef::Log + extend Mixlib::Log end
\ No newline at end of file diff --git a/chef/lib/chef/log/formatter.rb b/chef/lib/chef/log/formatter.rb deleted file mode 100644 index f290aaf955..0000000000 --- a/chef/lib/chef/log/formatter.rb +++ /dev/null @@ -1,56 +0,0 @@ -# -# Author:: Adam Jacob (<adam@opscode.com>) -# Copyright:: Copyright (c) 2008 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'logger' -require 'time' - -class Chef - class Log - class Formatter < Logger::Formatter - @@show_time = true - - def self.show_time=(show=false) - @@show_time = show - end - - # Prints a log message as '[time] severity: message' if Chef::Log::Formatter.show_time == true. - # Otherwise, doesn't print the time. - def call(severity, time, progname, msg) - if @@show_time - sprintf("[%s] %s: %s\n", time.rfc2822(), severity, msg2str(msg)) - else - sprintf("%s: %s\n", severity, msg2str(msg)) - end - end - - # Converts some argument to a Logger.severity() call to a string. Regular strings pass through like - # normal, Exceptions get formatted as "message (class)\nbacktrace", and other random stuff gets - # put through "object.inspect" - def msg2str(msg) - case msg - when ::String - msg - when ::Exception - "#{ msg.message } (#{ msg.class })\n" << - (msg.backtrace || []).join("\n") - else - msg.inspect - end - end - end - end -end
\ No newline at end of file |