kafo 0.6.12 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +181 -41
- data/bin/kafo-export-params +1 -1
- data/bin/kafofy +36 -18
- data/config/kafo.yaml.example +12 -4
- data/lib/kafo/color_scheme.rb +11 -4
- data/lib/kafo/configuration.rb +137 -20
- data/lib/kafo/exit_handler.rb +4 -2
- data/lib/kafo/hooking.rb +6 -1
- data/lib/kafo/kafo_configure.rb +97 -28
- data/lib/kafo/logger.rb +18 -10
- data/lib/kafo/migration_context.rb +21 -0
- data/lib/kafo/migrations.rb +54 -0
- data/lib/kafo/param.rb +1 -1
- data/lib/kafo/param_builder.rb +1 -1
- data/lib/kafo/params/password.rb +1 -1
- data/lib/kafo/puppet_command.rb +7 -6
- data/lib/kafo/puppet_module.rb +13 -6
- data/lib/kafo/scenario_manager.rb +221 -0
- data/lib/kafo/system_checker.rb +3 -1
- data/lib/kafo/validator.rb +5 -3
- data/lib/kafo/version.rb +1 -1
- data/lib/kafo/wizard.rb +0 -1
- metadata +33 -2
data/lib/kafo/logger.rb
CHANGED
@@ -37,6 +37,13 @@ module Kafo
|
|
37
37
|
COLOR_LAYOUT = Logging::Layouts::Pattern.new(:pattern => PATTERN, :color_scheme => 'bright')
|
38
38
|
NOCOLOR_LAYOUT = Logging::Layouts::Pattern.new(:pattern => PATTERN, :color_scheme => nil)
|
39
39
|
|
40
|
+
def self.setup_fatal_logger(layout)
|
41
|
+
fatal_logger = Logging.logger['fatal']
|
42
|
+
fatal_logger.level = 'fatal'
|
43
|
+
fatal_logger.appenders = [::Logging.appenders.stderr(:layout => layout)]
|
44
|
+
self.loggers << fatal_logger
|
45
|
+
end
|
46
|
+
|
40
47
|
def self.setup
|
41
48
|
begin
|
42
49
|
FileUtils.mkdir_p(KafoConfigure.config.app[:log_dir], :mode => 0750)
|
@@ -45,7 +52,7 @@ module Kafo
|
|
45
52
|
end
|
46
53
|
|
47
54
|
logger = Logging.logger['main']
|
48
|
-
filename =
|
55
|
+
filename = KafoConfigure.config.log_file
|
49
56
|
begin
|
50
57
|
logger.appenders = ::Logging.appenders.rolling_file('configure',
|
51
58
|
:filename => filename,
|
@@ -59,19 +66,15 @@ module Kafo
|
|
59
66
|
end
|
60
67
|
|
61
68
|
logger.level = KafoConfigure.config.app[:log_level]
|
69
|
+
self.loggers << logger
|
62
70
|
|
63
|
-
|
64
|
-
fatal_logger.level = 'fatal'
|
65
|
-
layout = KafoConfigure.config.app[:colors] ? COLOR_LAYOUT : NOCOLOR_LAYOUT
|
66
|
-
fatal_logger.appenders = [::Logging.appenders.stderr(:layout => layout)]
|
67
|
-
|
68
|
-
self.loggers = [logger, fatal_logger]
|
71
|
+
setup_fatal_logger(color_layout) unless loggers.detect {|l| l.name == 'verbose'}
|
69
72
|
end
|
70
73
|
|
71
74
|
def self.setup_verbose
|
72
75
|
logger = Logging.logger['verbose']
|
73
|
-
logger.level = KafoConfigure.config.app[:verbose_log_level]
|
74
|
-
layout =
|
76
|
+
logger.level = (KafoConfigure.config && KafoConfigure.config.app[:verbose_log_level]) || :info
|
77
|
+
layout = color_layout
|
75
78
|
logger.appenders = [::Logging.appenders.stdout(:layout => layout)]
|
76
79
|
self.loggers<< logger
|
77
80
|
end
|
@@ -89,8 +92,9 @@ module Kafo
|
|
89
92
|
end
|
90
93
|
|
91
94
|
def self.dump_errors
|
95
|
+
setup_fatal_logger(color_layout) if loggers.empty?
|
92
96
|
unless self.error_buffer.empty?
|
93
|
-
loggers.each { |logger| logger.error '
|
97
|
+
loggers.each { |logger| logger.error 'Errors encountered during run:' }
|
94
98
|
self.dump_buffer(self.error_buffer)
|
95
99
|
end
|
96
100
|
end
|
@@ -106,6 +110,10 @@ module Kafo
|
|
106
110
|
buffer.clear
|
107
111
|
end
|
108
112
|
|
113
|
+
def self.color_layout
|
114
|
+
KafoConfigure.use_colors? ? COLOR_LAYOUT : NOCOLOR_LAYOUT
|
115
|
+
end
|
116
|
+
|
109
117
|
def log(name, *args, &block)
|
110
118
|
if self.class.buffering?
|
111
119
|
self.class.to_buffer(self.class.buffer, name, args, &block)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Kafo
|
2
|
+
class MigrationContext
|
3
|
+
|
4
|
+
attr_accessor :scenario, :answers
|
5
|
+
|
6
|
+
def self.execute(scenario, answers, &migration)
|
7
|
+
context = new(scenario, answers)
|
8
|
+
context.instance_eval(&migration)
|
9
|
+
return context.scenario, context.answers
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(scenario, answers)
|
13
|
+
@scenario = scenario
|
14
|
+
@answers = answers
|
15
|
+
end
|
16
|
+
|
17
|
+
def logger
|
18
|
+
KafoConfigure.logger
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'kafo/migration_context'
|
3
|
+
|
4
|
+
module Kafo
|
5
|
+
class Migrations
|
6
|
+
|
7
|
+
attr_reader :migrations
|
8
|
+
|
9
|
+
def initialize(migrations_dir)
|
10
|
+
@migrations_dir = migrations_dir
|
11
|
+
@migrations = {}
|
12
|
+
@applied_file = File.join(@migrations_dir, '.applied')
|
13
|
+
load_migrations
|
14
|
+
end
|
15
|
+
|
16
|
+
def applied
|
17
|
+
@applied ||= load_applied
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_migrations
|
21
|
+
Dir.glob(@migrations_dir + "/*.rb").each do |file|
|
22
|
+
next if applied.include?(File.basename(file))
|
23
|
+
KafoConfigure.logger.debug "Loading migration #{file}"
|
24
|
+
migration = File.read(file)
|
25
|
+
migration_block = proc { instance_eval(migration, file, 1) }
|
26
|
+
add_migration(file, &migration_block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_migration(name, &block)
|
31
|
+
@migrations[name] = block
|
32
|
+
end
|
33
|
+
|
34
|
+
def run(scenario, answers)
|
35
|
+
@migrations.keys.sort.each do |name|
|
36
|
+
KafoConfigure.logger.debug "Executing migration #{name}"
|
37
|
+
migration = @migrations[name]
|
38
|
+
scenario, answers = Kafo::MigrationContext.execute(scenario, answers, &migration)
|
39
|
+
applied << File.basename(name.to_s)
|
40
|
+
end
|
41
|
+
return scenario, answers
|
42
|
+
end
|
43
|
+
|
44
|
+
def store_applied
|
45
|
+
File.open(@applied_file, 'w') { |f| f.write(applied.to_yaml) }
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def load_applied
|
51
|
+
File.exist?(@applied_file) ? YAML.load_file(@applied_file) : []
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/kafo/param.rb
CHANGED
data/lib/kafo/param_builder.rb
CHANGED
data/lib/kafo/params/password.rb
CHANGED
data/lib/kafo/puppet_command.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
module Kafo
|
3
3
|
class PuppetCommand
|
4
|
-
def initialize(command, options = [])
|
4
|
+
def initialize(command, options = [], configuration = KafoConfigure.config)
|
5
|
+
@configuration = configuration
|
5
6
|
@command = command
|
6
7
|
|
7
8
|
# Expand the modules_path to work around the fact that Puppet doesn't
|
@@ -21,9 +22,9 @@ module Kafo
|
|
21
22
|
|
22
23
|
def command
|
23
24
|
result = [
|
24
|
-
"echo '$kafo_config_file=\"#{
|
25
|
+
"echo '$kafo_config_file=\"#{@configuration.config_file}\" #{custom_answer_file} #{add_progress} #{@command}'",
|
25
26
|
'|',
|
26
|
-
"RUBYLIB=#{["#{
|
27
|
+
"RUBYLIB=#{["#{@configuration.gem_root}/modules", ::ENV['RUBYLIB']].join(File::PATH_SEPARATOR)}",
|
27
28
|
"puppet apply #{@options.join(' ')} #{@suffix}",
|
28
29
|
].join(' ')
|
29
30
|
@logger.debug result
|
@@ -39,9 +40,9 @@ module Kafo
|
|
39
40
|
|
40
41
|
def modules_path
|
41
42
|
[
|
42
|
-
|
43
|
-
|
44
|
-
].join(':')
|
43
|
+
@configuration.module_dirs,
|
44
|
+
@configuration.kafo_modules_dir,
|
45
|
+
].flatten.join(':')
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
data/lib/kafo/puppet_module.rb
CHANGED
@@ -9,16 +9,23 @@ module Kafo
|
|
9
9
|
PRIMARY_GROUP_NAME = 'Parameters'
|
10
10
|
|
11
11
|
attr_reader :name, :identifier, :params, :dir_name, :class_name, :manifest_name, :manifest_path,
|
12
|
-
:groups, :params_path, :params_class_name
|
12
|
+
:groups, :params_path, :params_class_name, :configuration
|
13
13
|
|
14
|
-
def initialize(identifier, parser = KafoParsers::PuppetModuleParser)
|
14
|
+
def initialize(identifier, parser = KafoParsers::PuppetModuleParser, configuration = KafoConfigure.config)
|
15
15
|
@identifier = identifier
|
16
|
+
@configuration = configuration
|
16
17
|
@name = get_name
|
17
18
|
@dir_name = get_dir_name
|
18
19
|
@manifest_name = get_manifest_name
|
19
20
|
@class_name = get_class_name
|
20
21
|
@params = []
|
21
|
-
@
|
22
|
+
if @configuration.module_dirs.count == 1
|
23
|
+
module_dir = @configuration.module_dirs.first
|
24
|
+
else
|
25
|
+
module_dir = @configuration.module_dirs.find { |dir| File.exists?(File.join(dir, module_manifest_path)) } ||
|
26
|
+
warn("Manifest #{module_manifest_path} was not found in #{@configuration.module_dirs.join(', ')}")
|
27
|
+
end
|
28
|
+
@manifest_path = File.join(module_dir, module_manifest_path)
|
22
29
|
@parser = parser
|
23
30
|
@validations = []
|
24
31
|
@logger = KafoConfigure.logger
|
@@ -28,7 +35,7 @@ module Kafo
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def enabled?
|
31
|
-
@enabled.nil? ? @enabled =
|
38
|
+
@enabled.nil? ? @enabled = @configuration.module_enabled?(self) : @enabled
|
32
39
|
end
|
33
40
|
|
34
41
|
def disable
|
@@ -78,7 +85,7 @@ module Kafo
|
|
78
85
|
end
|
79
86
|
|
80
87
|
def <=> o
|
81
|
-
|
88
|
+
@configuration.app[:low_priority_modules].each do |module_name|
|
82
89
|
return 1 if self.name.include?(module_name) && !o.name.include?(module_name)
|
83
90
|
return -1 if !self.name.include?(module_name) && o.name.include?(module_name)
|
84
91
|
if self.name.include?(module_name) && o.name.include?(module_name)
|
@@ -103,7 +110,7 @@ module Kafo
|
|
103
110
|
|
104
111
|
# mapping from configuration with stringified keys
|
105
112
|
def mapping
|
106
|
-
@mapping ||= Hash[
|
113
|
+
@mapping ||= Hash[@configuration.app[:mapping].map { |k, v| [k.to_s, v] }]
|
107
114
|
end
|
108
115
|
|
109
116
|
# custom module directory name
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'kafo_wizards'
|
3
|
+
|
4
|
+
module Kafo
|
5
|
+
class ScenarioManager
|
6
|
+
attr_reader :config_dir, :last_scenario_link, :previous_scenario
|
7
|
+
|
8
|
+
def initialize(config, last_scenario_link_name='last_scenario.yaml')
|
9
|
+
@config_dir = File.file?(config) ? File.dirname(config) : config
|
10
|
+
@last_scenario_link = File.join(config_dir, last_scenario_link_name)
|
11
|
+
@previous_scenario = File.realpath(last_scenario_link) if File.exists?(last_scenario_link)
|
12
|
+
end
|
13
|
+
|
14
|
+
def available_scenarios
|
15
|
+
# assume that *.yaml file in config_dir that has key :name is scenario definition
|
16
|
+
@available_scenarios ||= Dir.glob(File.join(config_dir, '*.yaml')).reject { |f| f =~ /#{last_scenario_link}$/ }.inject({}) do |scns, scn_file|
|
17
|
+
begin
|
18
|
+
content = YAML.load_file(scn_file)
|
19
|
+
if content.is_a?(Hash) && content.has_key?(:answer_file)
|
20
|
+
# add scenario name for legacy configs
|
21
|
+
content[:name] = File.basename(scn_file, '.yaml') unless content.has_key?(:name)
|
22
|
+
scns[scn_file] = content
|
23
|
+
end
|
24
|
+
rescue Psych::SyntaxError => e
|
25
|
+
warn "Warning: #{e}"
|
26
|
+
end
|
27
|
+
scns
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def list_available_scenarios
|
32
|
+
say ::HighLine.color("Available scenarios", :info)
|
33
|
+
available_scenarios.each do |config_file, content|
|
34
|
+
scenario = File.basename(config_file, '.yaml')
|
35
|
+
use = (File.expand_path(config_file) == @previous_scenario ? 'INSTALLED' : "use: --scenario #{scenario}")
|
36
|
+
say ::HighLine.color(" #{content[:name]} ", :title)
|
37
|
+
say "(#{use})"
|
38
|
+
say " " + content[:description] if !content[:description].nil? && !content[:description].empty?
|
39
|
+
end
|
40
|
+
say " No available scenarios found in #{config_dir}" if available_scenarios.empty?
|
41
|
+
KafoConfigure.exit(0)
|
42
|
+
end
|
43
|
+
|
44
|
+
def scenario_selection_wizard
|
45
|
+
wizard = KafoWizards.wizard(:cli, 'Select installation scenario',
|
46
|
+
:description => "Please select one of the pre-set installation scenarios. You can customize your setup later during the installation.")
|
47
|
+
f = wizard.factory
|
48
|
+
available_scenarios.keys.each do |scn|
|
49
|
+
label = available_scenarios[scn][:name].to_s
|
50
|
+
label += ": #{available_scenarios[scn][:description]}" if available_scenarios[scn][:description]
|
51
|
+
wizard.entries << f.button(scn, :label => label, :default => true)
|
52
|
+
end
|
53
|
+
wizard.entries << f.button(:cancel, :label => 'Cancel Installation', :default => false)
|
54
|
+
wizard
|
55
|
+
end
|
56
|
+
|
57
|
+
def select_scenario_interactively
|
58
|
+
# let the user select if in interactive mode
|
59
|
+
if (ARGV & ['--interactive', '-i']).any?
|
60
|
+
res = scenario_selection_wizard.run
|
61
|
+
if res == :cancel
|
62
|
+
say 'Installation was cancelled by user'
|
63
|
+
KafoConfigure.exit(0)
|
64
|
+
end
|
65
|
+
res
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def scenario_changed?(scenario)
|
70
|
+
scenario = File.realpath(scenario) if File.symlink?(scenario)
|
71
|
+
!!previous_scenario && scenario != previous_scenario
|
72
|
+
end
|
73
|
+
|
74
|
+
def configured?
|
75
|
+
!!(defined?(CONFIG_DIR) && CONFIG_DIR)
|
76
|
+
end
|
77
|
+
|
78
|
+
def scenario_from_args
|
79
|
+
# try scenario provided in the args via -S or --scenario
|
80
|
+
parsed = ARGV.join(" ").match /(--scenario|-S)(\s+|[=]?)(\S+)/
|
81
|
+
if parsed
|
82
|
+
scenario_file = File.join(config_dir, "#{parsed[3]}.yaml")
|
83
|
+
return scenario_file if File.exists?(scenario_file)
|
84
|
+
KafoConfigure.logger.fatal "Scenario (#{scenario_file}) was not found, can not continue"
|
85
|
+
KafoConfigure.exit(:unknown_scenario)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def select_scenario
|
90
|
+
scenario = scenario_from_args || previous_scenario ||
|
91
|
+
(available_scenarios.keys.count == 1 && available_scenarios.keys.first) ||
|
92
|
+
select_scenario_interactively
|
93
|
+
if scenario.nil?
|
94
|
+
fail_now("Scenario was not selected, can not continue. Use --list-scenarios to list available options.", :unknown_scenario)
|
95
|
+
end
|
96
|
+
scenario
|
97
|
+
end
|
98
|
+
|
99
|
+
def scenario_from_args
|
100
|
+
# try scenario provided in the args via -S or --scenario
|
101
|
+
parsed = ARGV.join(" ").match /(--scenario|-S)(\s+|[=]?)(\S+)/
|
102
|
+
if parsed
|
103
|
+
scenario_file = File.join(config_dir, "#{parsed[3]}.yaml")
|
104
|
+
return scenario_file if File.exists?(scenario_file)
|
105
|
+
fail_now("Scenario (#{scenario_file}) was not found, can not continue", :unknown_scenario)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def show_scenario_diff(prev_scenario, new_scenario)
|
110
|
+
say ::HighLine.color("Scenarios are being compared, that may take a while...", :info)
|
111
|
+
prev_conf = load_and_setup_configuration(prev_scenario)
|
112
|
+
new_conf = load_and_setup_configuration(new_scenario)
|
113
|
+
print_scenario_diff(prev_conf, new_conf)
|
114
|
+
end
|
115
|
+
|
116
|
+
def check_scenario_change(scenario)
|
117
|
+
if scenario_changed?(scenario)
|
118
|
+
if ARGV.include? '--compare-scenarios'
|
119
|
+
show_scenario_diff(@previous_scenario, scenario)
|
120
|
+
dump_log_and_exit(0)
|
121
|
+
else
|
122
|
+
confirm_scenario_change(scenario)
|
123
|
+
KafoConfigure.logger.info "Scenario #{scenario} was selected"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def confirm_scenario_change(new_scenario)
|
129
|
+
unless ARGV.include?('--force')
|
130
|
+
if (ARGV & ['--interactive', '-i']).any?
|
131
|
+
show_scenario_diff(@previous_scenario, new_scenario)
|
132
|
+
|
133
|
+
wizard = KafoWizards.wizard(:cli, 'Confirm installation scenario selection',
|
134
|
+
:description => "You are trying to replace existing installation with different scenario. This may lead to unpredictable states. Please confirm that you want to proceed.")
|
135
|
+
wizard.entries << wizard.factory.button(:proceed, :label => 'Proceed with selected installation scenario', :default => false)
|
136
|
+
wizard.entries << wizard.factory.button(:cancel, :label => 'Cancel Installation', :default => true)
|
137
|
+
result = wizard.run
|
138
|
+
if result == :cancel
|
139
|
+
say 'Installation was cancelled by user'
|
140
|
+
dump_log_and_exit(0)
|
141
|
+
end
|
142
|
+
else
|
143
|
+
message = "You are trying to replace existing installation with different scenario. This may lead to unpredictable states. " +
|
144
|
+
"Use --force to override. You can use --compare-scenarios to see the differences"
|
145
|
+
KafoConfigure.logger.error(message)
|
146
|
+
dump_log_and_exit(:scenario_error)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def print_scenario_diff(prev_conf, new_conf)
|
152
|
+
missing = new_conf.params_missing(prev_conf)
|
153
|
+
changed = new_conf.params_changed(prev_conf)
|
154
|
+
|
155
|
+
say "\n" + ::HighLine.color("Overview of modules used in the scenarios (#{prev_conf.app[:name]} -> #{new_conf.app[:name]}):", :title)
|
156
|
+
modules = Hash.new { |h, k| h[k] = {} }
|
157
|
+
modules = prev_conf.modules.inject(modules) { |mods, mod| mods[mod.name][:prev] = mod.enabled?; mods }
|
158
|
+
modules = new_conf.modules.inject(modules) { |mods, mod| mods[mod.name][:new] = mod.enabled?; mods }
|
159
|
+
printables = { "" => 'N/A', 'true' => 'ENABLED', 'false' => 'DISABLED' }
|
160
|
+
modules.each do |mod, status|
|
161
|
+
module_line = "%-50s: %-09s -> %s" % [mod, printables[status[:prev].to_s], printables[status[:new].to_s]]
|
162
|
+
# highlight modules that will be disabled
|
163
|
+
module_line = ::HighLine.color(module_line, :important) if status[:prev] == true && (status[:new] == false || status[:new].nil?)
|
164
|
+
say module_line
|
165
|
+
end
|
166
|
+
|
167
|
+
say "\n" + ::HighLine.color("Defaults that will be updated with values from previous installation:", :title)
|
168
|
+
if changed.empty?
|
169
|
+
say " No values will be updated from previous scenario"
|
170
|
+
else
|
171
|
+
changed.each { |param| say " #{param.module.class_name}::#{param.name}: #{param.value} -> #{prev_conf.param(param.module.class_name, param.name).value}" }
|
172
|
+
end
|
173
|
+
say "\n" + ::HighLine.color("Values from previous installation that will be lost by scenario change:", :title)
|
174
|
+
if missing.empty?
|
175
|
+
say " No values from previous installation will be lost"
|
176
|
+
else
|
177
|
+
missing.each { |param| say " #{param.module.class_name}::#{param.name}: #{param.value}\n" }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def link_last_scenario(config_file)
|
182
|
+
link_path = last_scenario_link
|
183
|
+
if last_scenario_link
|
184
|
+
File.delete(last_scenario_link) if File.exist?(last_scenario_link)
|
185
|
+
File.symlink(config_file, last_scenario_link)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def load_and_setup_configuration(config_file)
|
190
|
+
conf = load_configuration(config_file)
|
191
|
+
conf.preset_defaults_from_puppet
|
192
|
+
conf.preset_defaults_from_yaml
|
193
|
+
conf
|
194
|
+
end
|
195
|
+
|
196
|
+
def load_configuration(config_file)
|
197
|
+
Configuration.new(config_file)
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def fail_now(message, exit_code)
|
203
|
+
say "ERROR: #{message}"
|
204
|
+
KafoConfigure.logger.error message
|
205
|
+
KafoConfigure.exit(exit_code)
|
206
|
+
end
|
207
|
+
|
208
|
+
def dump_log_and_exit(code)
|
209
|
+
if Logger.buffering? && Logger.buffer.any?
|
210
|
+
Logger.setup_verbose
|
211
|
+
KafoConfigure.verbose = true
|
212
|
+
if !KafoConfigure.config.nil?
|
213
|
+
Logger.setup
|
214
|
+
KafoConfigure.logger.info("Log was be written to #{KafoConfigure.config.log_file}")
|
215
|
+
end
|
216
|
+
KafoConfigure.logger.info('Logs flushed')
|
217
|
+
end
|
218
|
+
KafoConfigure.exit(code)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|