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 +4 -4
- data/README.md +1 -0
- data/doc/kafo_run.png +0 -0
- data/doc/kafo_run.uml +2 -0
- data/doc/plantuml.jar +0 -0
- data/lib/kafo/app_option/declaration.rb +19 -0
- data/lib/kafo/app_option/definition.rb +16 -0
- data/lib/kafo/configuration.rb +25 -7
- data/lib/kafo/exit_handler.rb +1 -1
- data/lib/kafo/help_builders/base.rb +5 -3
- data/lib/kafo/help_builders/basic.rb +13 -2
- data/lib/kafo/hook_context.rb +81 -18
- data/lib/kafo/hooking.rb +20 -13
- data/lib/kafo/kafo_configure.rb +127 -116
- data/lib/kafo/logger.rb +13 -123
- data/lib/kafo/logging.rb +127 -0
- data/lib/kafo/puppet_log_parser.rb +10 -4
- data/lib/kafo/scenario_manager.rb +10 -11
- data/lib/kafo/system_checker.rb +1 -1
- data/lib/kafo/version.rb +1 -1
- data/lib/kafo/wizard.rb +7 -7
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5cb69151feb9aff8869369e3c3d16b1899bd51248ab4cb8a2cf08f862d78c72
|
4
|
+
data.tar.gz: f7760b031fb5f00e4ad853d8ac7c139555cc0606dcbd40ba542f340bfbe08135
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
|
data/doc/kafo_run.png
CHANGED
Binary file
|
data/doc/kafo_run.uml
CHANGED
data/doc/plantuml.jar
ADDED
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
|
data/lib/kafo/configuration.rb
CHANGED
@@ -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 => '
|
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
|
-
:
|
33
|
-
:
|
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')
|
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.
|
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.
|
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.
|
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
|
data/lib/kafo/exit_handler.rb
CHANGED
@@ -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
|
6
|
-
DEFAULT_MODULE_NAME
|
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 ==
|
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
|
-
|
8
|
-
|
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
|
data/lib/kafo/hook_context.rb
CHANGED
@@ -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
|
-
#
|
11
|
+
#
|
12
|
+
# @return [Kafo::Logger]
|
13
|
+
#
|
14
|
+
# @example
|
19
15
|
# logger.warn "this combindation of parameters is untested"
|
20
|
-
|
21
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
data/lib/kafo/hooking.rb
CHANGED
@@ -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
|
-
|
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
|
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.
|
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)
|