lib/kafo/kafo_configure.rb in kafo-0.1.0 vs lib/kafo/kafo_configure.rb in kafo-0.2.0
- old
+ new
@@ -11,30 +11,39 @@
require 'kafo/puppet_command'
require 'kafo/progress_bar'
class KafoConfigure < Clamp::Command
include StringHelper
- attr_reader :logger
class << self
attr_accessor :config, :root_dir, :config_file, :gem_root, :temp_config_file,
- :modules_dir, :kafo_modules_dir, :verbose
+ :modules_dir, :kafo_modules_dir, :verbose, :app_options, :logger
end
def initialize(*args)
+ self.class.logger = Logger.new
self.class.config_file = config_file
self.class.config = Configuration.new(self.class.config_file)
self.class.root_dir = File.expand_path(self.class.config.app[:installer_dir])
modules_dir = self.class.config.app[:module_dir] || (self.class.config.app[:installer_dir] + '/modules')
self.class.modules_dir = File.expand_path(modules_dir)
self.class.gem_root = File.join(File.dirname(__FILE__), '../../')
self.class.kafo_modules_dir = self.class.config.app[:kafo_modules_dir] || (self.class.gem_root + '/modules')
- Logger.setup
- @logger = Logging.logger.root
@progress_bar = nil
+
super
- set_parameters
+
+ set_app_options
+ allowed = self.class.app_options.map(&:switches).flatten
+ allowed.map! { |s| s.include?('[no-]') ? [s.sub('[no-]', ''), s.sub('[no-]', 'no-')] : s }.flatten!
+ # we need to parse app config params using clamp even before run method does it
+ # so we limit parsing only to app config options (because of --help and later defined params)
+ parse ARGV.select { |a| a =~ /([a-zA-Z0-9_-]*)([= ].*)?/ && allowed.include?($1) }
+ parse_app_arguments
+ Logger.setup
+
+ set_parameters # here the params gets parsed and we need app config populated
set_options
end
def config
self.class.config
@@ -43,13 +52,13 @@
def execute
catch :exit do
parse_cli_arguments
if (self.class.verbose = verbose?)
- logger.appenders = logger.appenders << ::Logging.appenders.stdout(:layout => Logger::COLOR_LAYOUT)
+ Logger.setup_verbose
else
- @progress_bar = ProgressBar.new
+ @progress_bar = self.class.config.app[:colors] ? ProgressBars::Colored.new : ProgressBars::BlackWhite.new
end
unless SystemChecker.check
puts "Your system does not meet configuration criteria"
exit(:invalid_system)
@@ -109,19 +118,25 @@
else
raise "Unknown code #{code}"
end
end
+ def self.app_option(*args, &block)
+ self.app_options ||= []
+ self.app_options.push self.option(*args, &block)
+ self.app_options.last
+ end
+
def params
@params ||= modules.map(&:params).flatten
rescue ModuleName => e
puts e
exit(:unknown_module)
end
def modules
- config.modules
+ config.modules.sort
end
def module(name)
modules.detect { |m| m.name == name}
end
@@ -130,10 +145,14 @@
params.detect { |p| p.name == name && p.module.name == mod }
end
private
+ def logger
+ self.class.logger
+ end
+
def exit(code)
self.class.exit(code)
end
def set_parameters
@@ -143,31 +162,51 @@
# set values based on YAML
param.set_value_by_config(config)
end
end
- def set_options
- self.class.option ['-i', '--interactive'], :flag, 'Run in interactive mode'
- self.class.option ['-v', '--verbose'], :flag, 'Display log on STDOUT instead of progressbar'
- self.class.option ['-n', '--noop'], :flag, 'Run puppet in noop mode?', :default => false
- self.class.option ['-d', '--dont-save-answers'], :flag, 'Skip saving answers to answers.yaml?',
- :default => !!config.app[:dont_save_answers]
+ def set_app_options
+ self.class.app_option ['--[no-]colors'], :flag, 'Use color output on STDOUT',
+ :default => !!config.app[:colors]
+ self.class.app_option ['-d', '--dont-save-answers'], :flag, 'Skip saving answers to answers.yaml?',
+ :default => !!config.app[:dont_save_answers]
+ self.class.app_option '--ignore-undocumented', :flag, 'Ignore inconsistent parameters documentation',
+ :default => false
+ self.class.app_option ['-i', '--interactive'], :flag, 'Run in interactive mode'
+ self.class.app_option '--log-level', 'LEVEL', 'Log level for log file output',
+ :default => config.app[:log_level]
+ self.class.app_option ['-n', '--noop'], :flag, 'Run puppet in noop mode?',
+ :default => false
+ self.class.app_option ['-v', '--verbose'], :flag, 'Display log on STDOUT instead of progressbar'
+ self.class.app_option ['-l', '--verbose-log-level'], 'LEVEL', 'Log level for verbose mode output',
+ :default => 'info'
+ end
- config.modules.each do |mod|
+ def set_options
+ modules.each do |mod|
self.class.option d("--[no-]enable-#{mod.name}"),
:flag,
"Enable puppet module #{mod.name}?",
:default => mod.enabled?
end
- params.each do |param|
+ params.sort.each do |param|
doc = param.doc.nil? ? 'UNDOCUMENTED' : param.doc.join("\n")
self.class.option parametrize(param), '', doc,
:default => param.value, :multivalued => param.multivalued?
end
end
+ def parse_app_arguments
+ self.class.app_options.each do |option|
+ name = option.attribute_name
+ name = "#{name}?" if option.flag?
+ value = send(name)
+ config.app[name.to_sym] = value.nil? ? option.default_value : value
+ end
+ end
+
def parse_cli_arguments
# enable/disable modules according to CLI
config.modules.each { |mod| send("enable_#{mod.name}?") ? mod.enable : mod.disable }
# set values coming from CLI arguments
@@ -186,18 +225,19 @@
def validate_all(logging = true)
logger.info 'Running validation checks'
results = params.map do |param|
result = param.valid?
- logger.error "Parameter #{param.name} invalid" if logging && !result
+ progress_log(:error, "Parameter #{with_prefix(param)} invalid") if logging && !result
result
end
results.all?
end
def run_installation
exit_code = 0
+ exit_status = nil
options = [
'--verbose',
'--debug',
'--color=false',
'--show_diff',
@@ -207,33 +247,37 @@
begin
command = PuppetCommand.new('include kafo_configure', options).command
PTY.spawn(command) do |stdin, stdout, pid|
begin
stdin.each do |line|
- puppet_log(*puppet_parse(line))
+ progress_log(*puppet_parse(line))
@progress_bar.update(line) if @progress_bar
end
- rescue Errno::EIO
- if PTY.respond_to?(:check) # ruby >= 1.9.2
- exit_code = PTY.check(pid, true).exitstatus
- else # ruby < 1.9.2
- Process.wait(pid) rescue Errno::ECHILD
- exit_code = $?.exitstatus
+ rescue Errno::EIO # we reach end of input
+ exit_status = PTY.check(pid, true) if PTY.respond_to?(:check) # ruby >= 1.9.2
+ if exit_status.nil? # process is still running or we have old ruby so we don't know
+ begin
+ Process.wait(pid)
+ rescue Errno::ECHILD # process could exit meanwhile so we rescue
+ end
+ exit_code = $?.exitstatus # after check $? should be set correctly
+ else # this should never happen (unless they change PTY.check behavior) in new ruby
+ exit_code = exit_code.exitstatus
end
end
end
- rescue PTY::ChildExited => e
+ rescue PTY::ChildExited => e # could be raised by Process.wait on older ruby or by PTY.check
exit_code = e.status.exitstatus
end
@progress_bar.close if @progress_bar
logger.info "Puppet has finished, bye!"
FileUtils.rm(temp_config_file, :force => true)
exit(exit_code)
end
- def puppet_log(method, message)
- @progress_bar.print ANSI::Code.red { message + "\n" } if method == :error && @progress_bar
- Logging.logger['puppet'].send(method, message)
+ def progress_log(method, message)
+ @progress_bar.print_error(message + "\n") if method == :error && @progress_bar
+ logger.send(method, message)
end
def puppet_parse(line)
method, message = case
when line =~ /^Error:(.*)/i || line =~ /^Err:(.*)/i