kafo 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc890988e785b3514243e664fcd8ab858f74b6ef
4
- data.tar.gz: 4b84e1e6f28d24c5dac79ca85755c148cb173d8d
3
+ metadata.gz: 1cc4327a27559f176db6c995f84dc34e424f925a
4
+ data.tar.gz: 1c63544e953e0fa5925781976140869a0bbc71ab
5
5
  SHA512:
6
- metadata.gz: 109405f2e35a020736882fab93fa4bb682ded92035942bb44687a7c9c8898485ac189a8effb5ef5d1aa22e02a66722059399b35ab65431659d80a3b7d3a8ef5d
7
- data.tar.gz: 31ed272c0a8600d1dd77a99811be8e4aed0f974c3c0f59722d7919bef70eaefe0b1f2627ebc2db030156c78777f4f188825c5c87e2df77636527694f60392027
6
+ metadata.gz: 5e41350fd8bc174f1be04dfeef37c270e1f36daa8495ca4c5c0ef7fabcb9347c28152ad98e87119b62e076bc95c88f50c594f46f8c6a780bff6dbf61f78cb729
7
+ data.tar.gz: 8b6635f0ac9c160f26357e5750eb19cb4555b2151cbb4a9b4a1afa8b0dfaed4b03c05c0abb7b1276423e9faf1228172671ce085826aeaf94bef36d90580dd83c
data/README.md CHANGED
@@ -498,6 +498,7 @@ several hooks.
498
498
  * boot - before kafo is ready to work, useful for adding new installer arguments, logger won't work yet
499
499
  * init - just after hooking is initialized and kafo is configured, parameters have no values yet
500
500
  * pre_values - just before value from CLI is set to parameters (they already have default values)
501
+ * pre_validations - just after system checks and before validations are executed (and before interactive wizard is started), at this point all parameter values are already set but not yet stored in answer file
501
502
  * pre - just before puppet is executed to converge system
502
503
  * post - just after puppet is executed to converge system
503
504
 
@@ -538,8 +539,10 @@ new installer option using ```app_option```. These option values can be accessed
538
539
  using ```param('module name', 'parameter name')``` accessor. You can register your own module
539
540
  that is not specified in answer file using ```add_module```. Custom mapping is also supported.
540
541
  This is useful if you need to add some module to existing installer based on kafo but you don't
541
- have control over it's source code. Last but not least you have access to logger.
542
- For more details, see [hook_context.rb](https://github.com/theforeman/kafo/blob/master/lib/kafo/hook_context.rb).
542
+ have control over its source code. You can use custom config storage which persists among
543
+ kafo runs using ```get_custom_config``` and ```store_custom_config```.
544
+ Last but not least you have access to logger. For more details, see
545
+ [hook_context.rb](https://github.com/theforeman/kafo/blob/master/lib/kafo/hook_context.rb).
543
546
 
544
547
  If you don't want to modify you installer script you can place your hooks into
545
548
  hooks directory. By default hooks dir is searched for ruby files in subdirectories
@@ -582,6 +585,8 @@ in installer configuration file.
582
585
  You can register as many hooks as you need. The order of execution for particular hook type
583
586
  is based on hook file name.
584
587
 
588
+ If you want to cancel installation you can use ```exit``` method and specify an exit code.
589
+
585
590
  ## Colors
586
591
 
587
592
  Everybody loves colors right? In case you don't you can disable them using ```--no-colors```
@@ -42,3 +42,8 @@
42
42
  # when you specify your directory, it will be search for $yourdir/$type/*.rb
43
43
  # :hook_dirs:
44
44
  # - /opt/hooks
45
+
46
+ # custom storage is handy if you use hooks and you must store some configuration
47
+ # which should persist among installer runs. It can be also used for passing
48
+ # value from one hook to another.
49
+ # :custom: {}
@@ -24,7 +24,8 @@ module Kafo
24
24
  :default_values_dir => '/tmp',
25
25
  :colors => Configuration.colors_possible?,
26
26
  :color_of_background => :dark,
27
- :hook_dirs => []
27
+ :hook_dirs => [],
28
+ :custom => {}
28
29
  }
29
30
 
30
31
  def initialize(file, persist = true)
@@ -71,6 +72,14 @@ module Kafo
71
72
  end
72
73
  end
73
74
 
75
+ def get_custom(key)
76
+ custom_storage[key.to_sym]
77
+ end
78
+
79
+ def set_custom(key, value)
80
+ custom_storage[key.to_sym] = value
81
+ end
82
+
74
83
  def modules
75
84
  @modules ||= @data.keys.map { |mod| PuppetModule.new(mod).parse }
76
85
  end
@@ -92,7 +101,7 @@ module Kafo
92
101
  @params_default_values ||= begin
93
102
  @logger.debug "Creating tmp dir within #{app[:default_values_dir]}..."
94
103
  temp_dir = Dir.mktmpdir(nil, app[:default_values_dir])
95
- KafoConfigure.register_cleanup_path temp_dir
104
+ KafoConfigure.exit_handler.register_cleanup_path temp_dir
96
105
  @logger.info "Parsing default values from puppet modules..."
97
106
  command = PuppetCommand.new("$temp_dir=\"#{temp_dir}\" #{includes} dump_values(#{params})").append('2>&1').command
98
107
  @logger.debug `#{command}`
@@ -134,6 +143,10 @@ module Kafo
134
143
 
135
144
  private
136
145
 
146
+ def custom_storage
147
+ app[:custom]
148
+ end
149
+
137
150
  def includes
138
151
  modules.map do |mod|
139
152
  params_file = File.join(KafoConfigure.modules_dir, mod.params_path)
@@ -0,0 +1,53 @@
1
+ module Kafo
2
+ class ExitHandler
3
+ attr_accessor :cleanup_paths, :exit_code, :logger
4
+
5
+ def initialize
6
+ @cleanup_paths = []
7
+ @exit_code = 0
8
+ @logger = KafoConfigure.logger
9
+ end
10
+
11
+ def error_codes
12
+ @error_codes ||= {
13
+ :invalid_system => 20,
14
+ :invalid_values => 21,
15
+ :manifest_error => 22,
16
+ :no_answer_file => 23,
17
+ :unknown_module => 24,
18
+ :defaults_error => 25
19
+ }
20
+ end
21
+
22
+ def exit(code, &block)
23
+ @exit_code = translate_exit_code(code)
24
+ block.call if block
25
+ KafoConfigure.logger.debug "Exit with status code: #{@exit_code} (signal was #{code})"
26
+ KafoConfigure.logger.dump_errors
27
+ cleanup
28
+ Kernel.exit(@exit_code)
29
+ end
30
+
31
+ def translate_exit_code(code)
32
+ return code if code.is_a?(Fixnum)
33
+ if error_codes.has_key?(code)
34
+ return error_codes[code]
35
+ else
36
+ raise "Unknown code #{code}"
37
+ end
38
+ end
39
+
40
+ def cleanup
41
+ # make sure default values are removed from /tmp
42
+ (self.cleanup_paths + ['/tmp/default_values.yaml']).each do |file|
43
+ logger.debug "Cleaning #{file}"
44
+ FileUtils.rm_rf(file)
45
+ end
46
+ end
47
+
48
+ def register_cleanup_path(path)
49
+ self.cleanup_paths<< path
50
+ end
51
+
52
+ end
53
+ end
@@ -60,5 +60,26 @@ module Kafo
60
60
  self.kafo.config.add_mapping(module_name, mapping) if mapping
61
61
  self.kafo.add_module(module_name)
62
62
  end
63
+
64
+ # You can trigger installer exit by this method. You must specify exit code as a first
65
+ # argument. You can also specify a symbol alias which is built-in (see exit_handler.rb
66
+ # for more details).
67
+ # examples:
68
+ # exit(0)
69
+ # exit(:manifest_error)
70
+ def exit(code)
71
+ self.kafo.exit(code)
72
+ end
73
+
74
+ # You can load a custom config value that has been saved using store_custom_config
75
+ def get_custom_config(key)
76
+ self.kafo.config.get_custom(key)
77
+ end
78
+
79
+ # You can save any value into kafo configuration file, this is useful if you need to
80
+ # share a value between more hooks and persist the values for next run
81
+ def store_custom_config(key, value)
82
+ self.kafo.config.set_custom(key, value)
83
+ end
63
84
  end
64
85
  end
data/lib/kafo/hooking.rb CHANGED
@@ -5,9 +5,10 @@ module Kafo
5
5
  # boot - before kafo is ready to work, useful for adding new app arguments, logger won't work yet
6
6
  # init - just after hooking is initialized and kafo is configured, parameters have no values yet
7
7
  # pre_values - just before value from CLI is set to parameters (they already have default values)
8
+ # pre_validations - just after system checks and before validations are executed (and before interactive wizard is started), at this point all parameter values are already set but not yet stored in answer file
8
9
  # pre - just before puppet is executed to converge system
9
10
  # post - just after puppet is executed to converge system
10
- TYPES = [:boot, :init, :pre, :post, :pre_values]
11
+ TYPES = [:boot, :init, :pre, :post, :pre_values, :pre_validations]
11
12
 
12
13
  attr_accessor :hooks, :kafo
13
14
 
@@ -62,6 +63,10 @@ module Kafo
62
63
  register(:pre_values, name, &block)
63
64
  end
64
65
 
66
+ def register_pre_validations(name, &block)
67
+ register(:pre_validations, name, &block)
68
+ end
69
+
65
70
  def register_pre(name, &block)
66
71
  register(:pre, name, &block)
67
72
  end
@@ -20,6 +20,7 @@ require 'kafo/system_checker'
20
20
  require 'kafo/puppet_command'
21
21
  require 'kafo/progress_bar'
22
22
  require 'kafo/hooking'
23
+ require 'kafo/exit_handler'
23
24
 
24
25
  module Kafo
25
26
  class KafoConfigure < Clamp::Command
@@ -27,13 +28,10 @@ module Kafo
27
28
 
28
29
  class << self
29
30
  attr_accessor :config, :root_dir, :config_file, :gem_root, :temp_config_file,
30
- :modules_dir, :kafo_modules_dir, :verbose, :app_options, :logger
31
+ :modules_dir, :kafo_modules_dir, :verbose, :app_options, :logger,
32
+ :exit_handler
31
33
  attr_writer :hooking
32
34
 
33
- def cleanup_paths
34
- @cleanup_paths ||= []
35
- end
36
-
37
35
  def hooking
38
36
  @hooking ||= Hooking.new
39
37
  end
@@ -41,6 +39,7 @@ module Kafo
41
39
 
42
40
  def initialize(*args)
43
41
  self.class.logger = Logger.new
42
+ self.class.exit_handler = ExitHandler.new
44
43
  self.class.config_file = config_file
45
44
  self.class.config = Configuration.new(self.class.config_file)
46
45
  self.class.root_dir = File.expand_path(self.class.config.app[:installer_dir])
@@ -77,97 +76,60 @@ module Kafo
77
76
  end
78
77
 
79
78
  def execute
80
- catch :exit do
81
- parse_cli_arguments
79
+ parse_cli_arguments
82
80
 
83
- if (self.class.verbose = verbose?)
84
- Logger.setup_verbose
85
- else
86
- @progress_bar = self.class.config.app[:colors] ? ProgressBars::Colored.new : ProgressBars::BlackWhite.new
87
- end
81
+ if (self.class.verbose = !!verbose?)
82
+ Logger.setup_verbose
83
+ else
84
+ @progress_bar = self.class.config.app[:colors] ? ProgressBars::Colored.new : ProgressBars::BlackWhite.new
85
+ end
88
86
 
89
- unless SystemChecker.check
90
- puts "Your system does not meet configuration criteria"
91
- exit(:invalid_system)
92
- end
87
+ unless SystemChecker.check
88
+ puts "Your system does not meet configuration criteria"
89
+ self.class.exit(:invalid_system)
90
+ end
93
91
 
94
- if interactive?
95
- wizard = Wizard.new(self)
96
- wizard.run
97
- else
98
- unless validate_all
99
- puts "Error during configuration, exiting"
100
- exit(:invalid_values)
101
- end
92
+ self.class.hooking.execute(:pre_validations)
93
+ if interactive?
94
+ wizard = Wizard.new(self)
95
+ wizard.run
96
+ else
97
+ unless validate_all
98
+ puts "Error during configuration, exiting"
99
+ self.class.exit(:invalid_values)
102
100
  end
101
+ end
103
102
 
104
- if dont_save_answers?
105
- self.class.temp_config_file = temp_config_file
106
- store_params(temp_config_file)
107
- else
108
- store_params
109
- end
110
- run_installation
103
+ if dont_save_answers?
104
+ self.class.temp_config_file = temp_config_file
105
+ store_params(temp_config_file)
106
+ else
107
+ store_params
111
108
  end
109
+ run_installation
110
+ return self
111
+ rescue SystemExit
112
112
  return self
113
113
  end
114
114
 
115
115
  def self.run
116
- catch :exit do
117
- return super
118
- end
119
- Kernel.exit(self.exit_code) # fail in initialize
120
- end
121
-
122
- def exit_code
123
- self.class.exit_code
116
+ return super
117
+ rescue SystemExit => e
118
+ self.exit_handler.exit(self.exit_code) # fail in initialize
124
119
  end
125
120
 
126
121
  def self.exit(code, &block)
127
- @exit_code = translate_exit_code(code)
128
- block.call if block
129
- cleanup
130
- throw :exit
122
+ exit_handler.exit(code, &block)
131
123
  end
132
124
 
133
125
  def self.exit_code
134
- @exit_code ||= 0
135
- end
136
-
137
- def self.translate_exit_code(code)
138
- return code if code.is_a? Fixnum
139
- error_codes = { :invalid_system => 20,
140
- :invalid_values => 21,
141
- :manifest_error => 22,
142
- :no_answer_file => 23,
143
- :unknown_module => 24,
144
- :defaults_error => 25 }
145
- if error_codes.has_key? code
146
- return error_codes[code]
147
- else
148
- raise "Unknown code #{code}"
149
- end
150
- end
151
-
152
- def self.cleanup
153
- # make sure default values are removed from /tmp
154
- (self.cleanup_paths + ['/tmp/default_values.yaml']).each do |file|
155
- logger.debug "Cleaning #{file}"
156
- FileUtils.rm_rf(file)
157
- end
126
+ self.exit_handler.exit_code
158
127
  end
159
128
 
160
- def self.register_cleanup_path(path)
161
- self.cleanup_paths<< path
129
+ def exit_code
130
+ self.class.exit_code
162
131
  end
163
132
 
164
- def register_cleanup_path(path)
165
- self.class.register_cleanup_path(path)
166
- end
167
-
168
- def cleanup_paths
169
- self.class.cleanup_paths
170
- end
171
133
 
172
134
  def help
173
135
  self.class.help(invocation_path, self)
@@ -190,7 +152,7 @@ module Kafo
190
152
  @params ||= modules.map(&:params).flatten
191
153
  rescue KafoParsers::ModuleName => e
192
154
  puts e
193
- exit(:unknown_module)
155
+ self.class.exit(:unknown_module)
194
156
  end
195
157
 
196
158
  def reset_params_cache
@@ -218,10 +180,6 @@ module Kafo
218
180
 
219
181
  private
220
182
 
221
- def exit(code, &block)
222
- self.class.exit(code, &block)
223
- end
224
-
225
183
  def set_parameters
226
184
  # set values based on default_values
227
185
  params.each do |param|
@@ -377,7 +335,7 @@ module Kafo
377
335
  @progress_bar.close if @progress_bar
378
336
  logger.info "Puppet has finished, bye!"
379
337
  FileUtils.rm(temp_config_file, :force => true)
380
- exit(exit_code) do
338
+ self.class.exit(exit_code) do
381
339
  self.class.hooking.execute(:post)
382
340
  end
383
341
  end
data/lib/kafo/logger.rb CHANGED
@@ -8,7 +8,15 @@ module Kafo
8
8
  attr_writer :loggers
9
9
 
10
10
  def loggers
11
- @loggers || []
11
+ @loggers ||= []
12
+ end
13
+
14
+ def buffer
15
+ @buffer ||= []
16
+ end
17
+
18
+ def error_buffer
19
+ @error_buffer ||= []
12
20
  end
13
21
  end
14
22
 
@@ -68,10 +76,56 @@ module Kafo
68
76
  self.loggers<< logger
69
77
  end
70
78
 
71
- %w(fatal error warn info debug).each do |name|
72
- define_method(name) do |*args, &block|
79
+ def self.buffering?
80
+ KafoConfigure.verbose.nil? || ((KafoConfigure.verbose && !loggers.detect {|l| l.name == 'verbose'}) || self.loggers.empty?)
81
+ end
82
+
83
+ def self.dump_needed?
84
+ !self.buffer.empty?
85
+ end
86
+
87
+ def self.to_buffer(buffer, *args)
88
+ buffer << args
89
+ end
90
+
91
+ def self.dump_errors
92
+ unless self.error_buffer.empty?
93
+ loggers.each { |logger| logger.error 'Repeating errors encountered during run:' }
94
+ self.dump_buffer(self.error_buffer)
95
+ end
96
+ end
97
+
98
+ def dump_errors
99
+ self.class.dump_errors
100
+ end
101
+
102
+ def self.dump_buffer(buffer)
103
+ buffer.each do |log|
104
+ self.loggers.each { |logger| logger.send log[0], *log[1], &log[2] }
105
+ end
106
+ buffer.clear
107
+ end
108
+
109
+ def log(name, *args, &block)
110
+ if self.class.buffering?
111
+ self.class.to_buffer(self.class.buffer, name, args, &block)
112
+ else
113
+ self.class.dump_buffer(self.class.buffer) if self.class.dump_needed?
73
114
  self.class.loggers.each { |logger| logger.send name, *args, &block }
74
115
  end
75
116
  end
117
+
118
+ %w(warn info debug).each do |name|
119
+ define_method(name) do |*args, &block|
120
+ self.log(name, *args, &block)
121
+ end
122
+ end
123
+
124
+ %w(fatal error).each do |name|
125
+ define_method(name) do |*args, &block|
126
+ self.class.to_buffer(self.class.error_buffer, name, *args, &block)
127
+ self.log(name, *args, &block)
128
+ end
129
+ end
76
130
  end
77
131
  end
data/lib/kafo/param.rb CHANGED
@@ -42,12 +42,19 @@ module Kafo
42
42
  if default == 'UNSET'
43
43
  self.value = nil
44
44
  else
45
- self.value = (value = defaults[default]) == :undef ? nil : value
45
+ # if we don't have default value from dump (can happen for modules added from hooks)
46
+ # we fallback to their own default values
47
+ if defaults.has_key?(default)
48
+ value = defaults[default]
49
+ self.value = (value == :undef ? nil : value)
50
+ else
51
+ self.value = self.default
52
+ end
46
53
  end
47
54
  end
48
55
 
49
56
  def set_value_by_config(config)
50
- base = config[module_name]
57
+ base = config[self.module.class_name]
51
58
  self.value = base[name] if base.has_key?(name)
52
59
  end
53
60
 
data/lib/kafo/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module Kafo
3
- VERSION = "0.5.5"
3
+ VERSION = "0.6.0"
4
4
  end
data/lib/kafo/wizard.rb CHANGED
@@ -34,7 +34,7 @@ END
34
34
  main_menu
35
35
  rescue Interrupt
36
36
  puts "Got interrupt, exiting"
37
- exit(0)
37
+ KafoConfigure.exit(0)
38
38
  end
39
39
 
40
40
  private
@@ -60,7 +60,8 @@ END
60
60
  finished = true
61
61
  end
62
62
  menu.choice HighLine.color('Cancel run without Saving', :cancel) do
63
- say("Bye!"); exit 0
63
+ say("Bye!")
64
+ KafoConfigure.exit(0)
64
65
  end
65
66
  end
66
67
  end
@@ -2,7 +2,7 @@ require 'kafo_configure/lib/kafo/puppet/report_wrapper'
2
2
 
3
3
  module Puppet::Parser::Functions
4
4
  newfunction(:add_progress) do |args|
5
- supported = %w(2.6. 2.7. 3.0. 3.1. 3.2. 3.3. 3.4. 3.5.)
5
+ supported = %w(2.6. 2.7. 3.0. 3.1. 3.2. 3.3. 3.4. 3.5. 3.6.)
6
6
  if supported.any? { |version| Puppet::PUPPETVERSION.start_with?(version) }
7
7
  # Monkey patch the transaction to put our wrapper around the report object
8
8
  require 'puppet/transaction'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kafo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marek Hulan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-13 00:00:00.000000000 Z
11
+ date: 2014-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -197,6 +197,7 @@ files:
197
197
  - lib/kafo/puppet_module.rb
198
198
  - lib/kafo/password_manager.rb
199
199
  - lib/kafo/configuration.rb
200
+ - lib/kafo/exit_handler.rb
200
201
  - lib/kafo/validator.rb
201
202
  - lib/kafo/exceptions.rb
202
203
  - lib/kafo/system_checker.rb