kafo 5.1.0 → 6.0.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
  SHA256:
3
- metadata.gz: a5bb233f06b493ded5dfc032260f4069329eecf431cdfe6c6b93ea20ed7303af
4
- data.tar.gz: f8af42dfbbf78ddb16971c776f1e658a7d0aa0306216f7b06ccd984f912c0a96
3
+ metadata.gz: f5cb69151feb9aff8869369e3c3d16b1899bd51248ab4cb8a2cf08f862d78c72
4
+ data.tar.gz: f7760b031fb5f00e4ad853d8ac7c139555cc0606dcbd40ba542f340bfbe08135
5
5
  SHA512:
6
- metadata.gz: 26c1cde782d8ad9e78f63627223492471b66504efb82491f723ee1a8d9efbd427455fc2219b92eee190217158788b1c42091633dd1a162a6a9e5502c671d4007
7
- data.tar.gz: e546068a983e2e6d45cd61e08945eb02903c366f9aebbc03d70bbf90df94af8b74d4d86e4034970c77d9b3bda145981bc9861e64323d84e0f9210c40477f90b9
6
+ metadata.gz: 27baf9be9b11280cd352cc418b62955473396b9d4b3245bc558e9e335e353d209c904acce90936644a9b023e82f60b5fba78ab902eb1aafd8068ae92d34e14ea
7
+ data.tar.gz: aa2ff036cca2d1d24fa11003272ffecaa51d1a8a03a482471a2074adf92edbbe94b17b82e998a79134635f207e611056d9e91187a6a4ce88191f36836588dbd1
data/README.md CHANGED
@@ -736,6 +736,7 @@ We currently support the following hooks.
736
736
  * pre_commit - after validations or interactive wizard have completed, all parameter values are set but not yet stored in the answer file
737
737
  * pre - just before puppet is executed to converge system, after parameter values are stored in the answer file
738
738
  * post - just after puppet is executed to converge system
739
+ * pre_exit - happens during exit handling, before exit is completed
739
740
 
740
741
  For better understanding when the hooks are executed see the [diagram](doc/kafo_run.png).
741
742
 
Binary file
@@ -105,5 +105,7 @@
105
105
 
106
106
  #Greenyellow:**post**|
107
107
 
108
+ #Greenyellow:**pre_exit**|
109
+
108
110
  stop
109
111
  @enduml
Binary file
@@ -0,0 +1,19 @@
1
+ require_relative 'definition'
2
+
3
+ module Kafo
4
+ module AppOption
5
+ module Declaration
6
+
7
+ include Clamp::Option::Declaration
8
+
9
+ def app_option(switches, type, description, opts = {}, &block)
10
+ AppOption::Definition.new(switches, type, description, opts).tap do |option|
11
+ block ||= option.default_conversion_block
12
+ define_accessors_for(option, &block)
13
+ declared_options << option
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module Kafo
2
+ module AppOption
3
+ class Definition < Clamp::Option::Definition
4
+
5
+ def initialize(switches, type, description, options = {})
6
+ @advanced = options.fetch(:advanced, false)
7
+ super(switches, type, description, options)
8
+ end
9
+
10
+ def advanced?
11
+ @advanced
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -15,9 +15,11 @@ module Kafo
15
15
  :description => '',
16
16
  :enabled => true,
17
17
  :log_dir => '/var/log/kafo',
18
+ :log_owner => nil,
19
+ :log_group => nil,
18
20
  :store_dir => '',
19
21
  :log_name => 'configuration.log',
20
- :log_level => 'info',
22
+ :log_level => 'notice',
21
23
  :no_prefix => false,
22
24
  :mapping => {},
23
25
  :answer_file => './config/answers.yaml',
@@ -26,11 +28,20 @@ module Kafo
26
28
  :colors => Kafo::ColorScheme.colors_possible?,
27
29
  :color_of_background => :dark,
28
30
  :hook_dirs => [],
31
+ :check_dirs => nil,
29
32
  :custom => {},
30
33
  :facts => {},
31
34
  :low_priority_modules => [],
32
- :verbose_log_level => 'info',
33
- :skip_puppet_version_check => false
35
+ :verbose => false,
36
+ :verbose_log_level => 'notice',
37
+ :skip_puppet_version_check => false,
38
+ :parser_cache_path => nil,
39
+ :ignore_undocumented => nil,
40
+ :order => nil,
41
+ :hiera_config => nil,
42
+ :kafo_modules_dir => nil,
43
+ :config_header_file => nil,
44
+ :dont_save_answers => nil,
34
45
  }
35
46
 
36
47
  def self.get_scenario_id(filename)
@@ -57,10 +68,17 @@ module Kafo
57
68
 
58
69
  def save_configuration(configuration)
59
70
  return true unless @persist
71
+
72
+ trimmed = configuration.reject do |key, value|
73
+ !DEFAULT.key?(key) || value.nil?
74
+ end
75
+
60
76
  begin
61
77
  FileUtils.touch @config_file
62
78
  File.chmod 0600, @config_file
63
- File.open(@config_file, 'w') { |file| file.write(format(YAML.dump(configuration))) }
79
+ File.open(@config_file, 'w') do |file|
80
+ file.write(format(YAML.dump(trimmed.sort.to_h)))
81
+ end
64
82
  rescue Errno::EACCES
65
83
  puts "Insufficient permissions to write to #{@config_file}, can not continue"
66
84
  KafoConfigure.exit(:insufficient_permissions)
@@ -179,7 +197,7 @@ module Kafo
179
197
  }
180
198
  EOS
181
199
 
182
- @logger.info 'Loading default values from puppet modules...'
200
+ @logger.notice 'Loading default values from puppet modules...'
183
201
  command = PuppetCommand.new(dump_manifest, [], puppetconf, self).command
184
202
  stdout, stderr, status = Open3.capture3(*PuppetCommand.format_command(command))
185
203
 
@@ -204,7 +222,7 @@ EOS
204
222
  end
205
223
  end
206
224
 
207
- @logger.info "... finished"
225
+ @logger.notice "... finished"
208
226
 
209
227
  load_yaml_from_output(stdout.split($/))
210
228
  end
@@ -309,7 +327,7 @@ EOS
309
327
  save_configuration(app)
310
328
  store(answers)
311
329
  migrations.store_applied
312
- @logger.info("#{migrations.migrations.count} migration/s were applied. Updated configuration was saved.")
330
+ @logger.notice("#{migrations.migrations.count} migration/s were applied. Updated configuration was saved.")
313
331
  end
314
332
  migrations.migrations.count
315
333
  end
@@ -26,8 +26,8 @@ module Kafo
26
26
  def exit(code, &block)
27
27
  @exit_code = translate_exit_code(code)
28
28
  block.call if block
29
+ KafoConfigure.hooking.execute(:pre_exit, log_stage: false)
29
30
  logger.debug "Exit with status code: #{@exit_code} (signal was #{code})"
30
- logger.dump_errors unless KafoConfigure.verbose
31
31
  cleanup
32
32
  Kernel.exit(@exit_code)
33
33
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Kafo
4
4
  module HelpBuilders
5
- DEFAULT_GROUP_NAME = 'Basic'
6
- DEFAULT_MODULE_NAME = 'Generic'
5
+ DEFAULT_GROUP_NAME = 'Basic'
6
+ DEFAULT_MODULE_NAME = 'Generic'
7
7
  IGNORE_IN_GROUP_NAME = /\s*parameters:?/
8
8
 
9
9
  class Base < Clamp::Help::Builder
@@ -15,12 +15,14 @@ module Kafo
15
15
  end
16
16
 
17
17
  def add_list(heading, items)
18
+ return if items.empty?
18
19
  if heading == 'Options'
19
20
  puts "\n#{heading}:"
20
21
 
21
22
  data = by_module(items)
23
+
22
24
  sorted_keys(data).each do |section|
23
- if section == 'Generic'
25
+ if section == DEFAULT_MODULE_NAME
24
26
  add_list(header(1, section), data[section])
25
27
  else
26
28
  add_module(section, data[section])
@@ -4,8 +4,15 @@ module Kafo
4
4
  module HelpBuilders
5
5
  class Basic < Base
6
6
  def add_module(name, items)
7
- data = by_parameter_groups(except_resets(items))
8
- add_list(module_header(name), data['Basic'])
7
+ pruned = except_resets(items)
8
+ pruned = except_advanced(pruned)
9
+ data = by_parameter_groups(pruned)
10
+ add_list(module_header(name), data[DEFAULT_GROUP_NAME])
11
+ end
12
+
13
+ def add_list(heading, items)
14
+ pruned = except_advanced(items)
15
+ super(heading, pruned)
9
16
  end
10
17
 
11
18
  def string
@@ -17,6 +24,10 @@ module Kafo
17
24
  def except_resets(items)
18
25
  items.select { |i| !i.help.first.strip.start_with?('--reset-') || !i.help.last.include?('to the default value (') }
19
26
  end
27
+
28
+ def except_advanced(items)
29
+ items.reject { |item| item.respond_to?(:advanced?) && item.advanced? }
30
+ end
20
31
  end
21
32
  end
22
33
  end
@@ -3,28 +3,36 @@ require 'kafo/base_context'
3
3
 
4
4
  module Kafo
5
5
  class HookContext < BaseContext
6
+ # @return [Kafo::KafoConfigure]
6
7
  attr_reader :kafo
7
8
 
8
- def self.execute(kafo, &hook)
9
- new(kafo).instance_eval(&hook)
10
- end
11
-
12
- def initialize(kafo)
13
- @kafo = kafo
14
- end
15
-
16
9
  # some of hooks won't print any message because logger is not yet configured
17
10
  # configuration of logger depends on application configration (log level etc.)
18
- # examples:
11
+ #
12
+ # @return [Kafo::Logger]
13
+ #
14
+ # @example
19
15
  # logger.warn "this combindation of parameters is untested"
20
- def logger
21
- self.kafo.logger
16
+ attr_reader :logger
17
+
18
+ def self.execute(kafo, logger, &hook)
19
+ new(kafo, logger).instance_eval(&hook)
20
+ end
21
+
22
+ def initialize(kafo, logger)
23
+ @kafo = kafo
24
+ @logger = logger
22
25
  end
23
26
 
24
27
  # if you want to add new app_option be sure to do as soon as possible (usually boot hook)
25
28
  # otherwise it may be too late (e.g. when displaying help)
26
- # examples:
29
+ #
30
+ # @return [Clamp::Option]
31
+ #
32
+ # @example
27
33
  # app_option '--log-level', 'LEVEL', 'Log level for log file output', :default => config.app[:log_level]:
34
+ #
35
+ # @example
28
36
  # app_option ['-n', '--noop'], :flag, 'Run puppet in noop mode?', :default => false
29
37
  def app_option(*args)
30
38
  self.kafo.class.app_option(*args)
@@ -32,19 +40,34 @@ module Kafo
32
40
 
33
41
  # Returns whether the given app option exists. This is useful when there's a conditional option that is
34
42
  # determined during boot; this helper can be used in later hooks to determine whether the option exists.
43
+ #
44
+ # @param [Symbol, String] option
35
45
  def app_option?(option)
36
46
  self.kafo.config.app.key?(option.to_sym)
37
47
  end
38
48
 
39
- # examples:
49
+ # @param [Symbol, String] option
50
+ #
51
+ # @example
40
52
  # app_value(:log_level)
53
+ #
41
54
  # note the dash to underscore convention
42
55
  def app_value(option)
43
56
  self.kafo.config.app[option.to_sym]
44
57
  end
45
58
 
46
- # examples:
59
+ # Return the parameter of a module. Note that the module may not actually
60
+ # be enabled.
61
+ #
62
+ # @param [String] module_name
63
+ # @param [String] parameter_name
64
+ #
65
+ # @return [Kafo::Param, nil]
66
+ #
67
+ # @example
47
68
  # param('foreman', 'interface').value = 'eth0'
69
+ #
70
+ # @example
48
71
  # param('foreman', 'interface').value = app_option('bind_on_interface')
49
72
  def param(module_name, parameter_name)
50
73
  self.kafo.param(module_name, parameter_name)
@@ -55,8 +78,14 @@ module Kafo
55
78
  # part of answer file so it also preserves parameter values between runs. It also list
56
79
  # its options in help output. You can also specify mapping for this module as a second
57
80
  # parameter.
58
- # examples:
81
+ #
82
+ # @param [String] module_name
83
+ # @param [Hash, nil] mapping
84
+ #
85
+ # @example
59
86
  # add_module('my_module')
87
+ #
88
+ # @example
60
89
  # add_module('foreman::plugin::staypuft', {:dir_name => 'foreman', :manifest_name => 'plugin/staypuft'})
61
90
  def add_module(module_name, mapping = nil)
62
91
  self.kafo.config.add_mapping(module_name, mapping) if mapping
@@ -64,7 +93,10 @@ module Kafo
64
93
  end
65
94
 
66
95
  # Check if a module is enabled in the current configuration.
67
- # examples:
96
+ #
97
+ # @param [String] module_name
98
+ #
99
+ # @example
68
100
  # module_enabled?('example')
69
101
  def module_enabled?(module_name)
70
102
  mod = self.kafo.module(module_name)
@@ -72,7 +104,10 @@ module Kafo
72
104
  end
73
105
 
74
106
  # Check if a module is present in the current configuration.
75
- # examples:
107
+ #
108
+ # @param [String] module_name
109
+ #
110
+ # @example
76
111
  # module_present?('example')
77
112
  def module_present?(module_name)
78
113
  mod = self.kafo.module(module_name)
@@ -82,25 +117,37 @@ module Kafo
82
117
  # You can trigger installer exit by this method. You must specify exit code as a first
83
118
  # argument. You can also specify a symbol alias which is built-in (see exit_handler.rb
84
119
  # for more details).
85
- # examples:
120
+ #
121
+ # @param [Integer, Symbol] code
122
+ #
123
+ # @example
86
124
  # exit(0)
125
+ #
126
+ # @example
87
127
  # exit(:manifest_error)
88
128
  def exit(code)
89
129
  self.kafo.class.exit(code)
90
130
  end
91
131
 
92
132
  # You can load a custom config value that has been saved using store_custom_config
133
+ #
134
+ # @param [Symbol] key
93
135
  def get_custom_config(key)
94
136
  self.kafo.config.get_custom(key)
95
137
  end
96
138
 
97
139
  # You can save any value into kafo configuration file, this is useful if you need to
98
140
  # share a value between more hooks and persist the values for next run
141
+ #
142
+ # @param [Symbol] key
143
+ # @param [Object] value
99
144
  def store_custom_config(key, value)
100
145
  self.kafo.config.set_custom(key, value)
101
146
  end
102
147
 
103
148
  # Load a custom fact from the custom fact storage as saved by store_custom_fact
149
+ #
150
+ # @param [Symbol] key
104
151
  def get_custom_fact(key)
105
152
  self.kafo.config.get_custom_fact(key)
106
153
  end
@@ -110,28 +157,44 @@ module Kafo
110
157
  # obvious ones such as strings, integers, booleans.
111
158
  #
112
159
  # These facts can also be used in Hiera hierachy definitions.
160
+ #
161
+ # @param [Symbol] key
162
+ # @param [Object] value
113
163
  def store_custom_fact(key, value)
114
164
  self.kafo.config.set_custom_fact(key, value)
115
165
  end
116
166
 
117
167
  # Check whether a custom fact exists, regardless of whether or not it has a value.
168
+ #
169
+ # @param [Symbol] key
118
170
  def has_custom_fact?(key)
119
171
  self.kafo.config.has_custom_fact?(key)
120
172
  end
121
173
 
122
174
  # Return the id of the current scenario
175
+ #
176
+ # @return [String]
123
177
  def scenario_id
124
178
  self.kafo.config.scenario_id
125
179
  end
126
180
 
127
181
  # Return the path to the current scenario
182
+ #
183
+ # @return [String]
128
184
  def scenario_path
129
185
  self.kafo.config.config_file
130
186
  end
131
187
 
132
188
  # Return the actual data in the current scenario
189
+ #
190
+ # @return [Hash]
133
191
  def scenario_data
134
192
  self.kafo.config.app
135
193
  end
194
+
195
+ # Return the current exit code
196
+ def exit_code
197
+ self.kafo.exit_code
198
+ end
136
199
  end
137
200
  end
@@ -2,15 +2,16 @@ require 'kafo/hook_context'
2
2
 
3
3
  module Kafo
4
4
  class Hooking
5
- # pre_migrations - just after kafo reads its configuration - useful for config file updates. Only in this stage it is posible to request config reload (`Kafo.request_config_reload`) to get in our changes
6
- # boot - before kafo is ready to work, useful for adding new app arguments, logger won't work yet
7
- # init - just after hooking is initialized and kafo is configured, parameters have no values yet
8
- # pre_values - just before value from CLI is set to parameters (they already have default values)
9
- # 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
10
- # pre_commit - after validations or interactive wizard have completed, all parameter values are set but not yet stored in the answer file
11
- # pre - just before puppet is executed to converge system
12
- # post - just after puppet is executed to converge system
13
- TYPES = [:pre_migrations, :boot, :init, :pre, :post, :pre_values, :pre_validations, :pre_commit]
5
+ # * pre_migrations - just after kafo reads its configuration - useful for config file updates. Only in this stage it is posible to request config reload (`Kafo.request_config_reload`) to get in our changes
6
+ # * boot - before kafo is ready to work, useful for adding new app arguments, logger won't work yet
7
+ # * init - just after hooking is initialized and kafo is configured, parameters have no values yet
8
+ # * pre_values - just before value from CLI is set to parameters (they already have default values)
9
+ # * 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
10
+ # * pre_commit - after validations or interactive wizard have completed, all parameter values are set but not yet stored in the answer file
11
+ # * pre - just before puppet is executed to converge system
12
+ # * post - just after puppet is executed to converge system
13
+ # * pre_exit - happens during exit handling, before exit is completed
14
+ TYPES = [:pre_migrations, :boot, :init, :pre_values, :pre_validations, :pre_commit, :pre, :post, :pre_exit]
14
15
 
15
16
  attr_accessor :hooks, :kafo
16
17
 
@@ -44,14 +45,16 @@ module Kafo
44
45
  @loaded
45
46
  end
46
47
 
47
- def execute(group)
48
- logger.info "Executing hooks in group #{group}"
48
+ def execute(group, log_stage: true)
49
+ logger = Logger.new(group)
50
+ logger.notice "Executing hooks in group #{group}" if log_stage
49
51
  self.hooks[group].keys.sort_by(&:to_s).each do |name|
50
52
  hook = self.hooks[group][name]
51
- result = HookContext.execute(self.kafo, &hook)
53
+ result = HookContext.execute(self.kafo, logger, &hook)
52
54
  logger.debug "Hook #{name} returned #{result.inspect}"
53
55
  end
54
- logger.info "All hooks in group #{group} finished"
56
+ logger.notice "All hooks in group #{group} finished" if log_stage
57
+ @group = nil
55
58
  end
56
59
 
57
60
  def register_pre_migrations(name, &block)
@@ -86,6 +89,10 @@ module Kafo
86
89
  register(:post, name, &block)
87
90
  end
88
91
 
92
+ def register_pre_exit(name, &block)
93
+ register(:pre_exit, name, &block)
94
+ end
95
+
89
96
  private
90
97
 
91
98
  def register(group, name, &block)