summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAJ Christensen <aj@junglist.gen.nz>2009-05-12 03:41:41 +1200
committerAJ Christensen <aj@junglist.gen.nz>2009-05-12 03:41:41 +1200
commitdf158ac7c86197bf3fe7d83d4c214b9abdb120e8 (patch)
treef4757fb8806caa61acb2e3feaec50773907c1415
parent0cb51561736c163edd7fcc7ea3e57452d0310c10 (diff)
downloadchef-df158ac7c86197bf3fe7d83d4c214b9abdb120e8.tar.gz
CHEF-151: Upfactor chef application classes.
Implement Mixlib for Config and Log classes.
-rw-r--r--chef/lib/chef/application.rb87
-rw-r--r--chef/lib/chef/application/agent.rb2
-rw-r--r--chef/lib/chef/application/client.rb102
-rw-r--r--chef/lib/chef/application/indexer.rb2
-rw-r--r--chef/lib/chef/application/server.rb2
-rw-r--r--chef/lib/chef/application/solo.rb2
-rw-r--r--chef/lib/chef/config.rb244
-rw-r--r--chef/lib/chef/log.rb75
-rw-r--r--chef/lib/chef/log/formatter.rb56
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