kafo 5.0.1 → 6.1.2
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/Rakefile +7 -0
- data/doc/kafo_run.png +0 -0
- data/doc/kafo_run.uml +2 -0
- data/lib/kafo/app_option/declaration.rb +17 -0
- data/lib/kafo/app_option/definition.rb +14 -0
- data/lib/kafo/color_scheme.rb +1 -1
- data/lib/kafo/configuration.rb +30 -8
- 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 +87 -19
- data/lib/kafo/hooking.rb +20 -13
- data/lib/kafo/kafo_configure.rb +147 -122
- data/lib/kafo/logger.rb +13 -123
- data/lib/kafo/logging.rb +128 -0
- data/lib/kafo/param.rb +3 -3
- data/lib/kafo/puppet_command.rb +8 -1
- data/lib/kafo/puppet_log_parser.rb +11 -5
- data/lib/kafo/puppet_module.rb +6 -6
- data/lib/kafo/scenario_manager.rb +10 -11
- data/lib/kafo/store.rb +1 -1
- data/lib/kafo/string_helper.rb +1 -1
- data/lib/kafo/system_checker.rb +1 -1
- data/lib/kafo/version.rb +1 -1
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5b062b74a81972dc7e0029799071d8b634ff87d50921e971bea9160ac007179
|
4
|
+
data.tar.gz: 91d16fcc9ce37cece41968d07ca8f44150016ac58cdc66adaef07ec9efa21d9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57abd42df5d5718db2a0ad815fac3c9b7c7e670baa394c9227cedadf3cd0c18f433168d035f23b8aaf4e48d8fe2d2ae17a19371dc8f8756b0857eb31878b5a8c
|
7
|
+
data.tar.gz: ef4f963505fc2e6315fbe19ed8e71e69faa44bf852491b0eebcb3ac778a8ecd86d03989bb2784735e6502ff539f026bd5ae51a12062c01d467601c03fea5ea3e
|
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/Rakefile
CHANGED
data/doc/kafo_run.png
CHANGED
Binary file
|
data/doc/kafo_run.uml
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'definition'
|
2
|
+
|
3
|
+
module Kafo
|
4
|
+
module AppOption
|
5
|
+
module Declaration
|
6
|
+
include Clamp::Option::Declaration
|
7
|
+
|
8
|
+
def app_option(switches, type, description, opts = {}, &block)
|
9
|
+
AppOption::Definition.new(switches, type, description, opts).tap do |option|
|
10
|
+
block ||= option.default_conversion_block
|
11
|
+
define_accessors_for(option, &block)
|
12
|
+
declared_options << option
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kafo
|
2
|
+
module AppOption
|
3
|
+
class Definition < Clamp::Option::Definition
|
4
|
+
def initialize(switches, type, description, options = {})
|
5
|
+
@advanced = options.fetch(:advanced, false)
|
6
|
+
super(switches, type, description, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def advanced?
|
10
|
+
@advanced
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/kafo/color_scheme.rb
CHANGED
@@ -7,7 +7,7 @@ module Kafo
|
|
7
7
|
::ENV['TERM'] && !`which tput 2> /dev/null`.empty? && `tput colors`.to_i > 0
|
8
8
|
end
|
9
9
|
|
10
|
-
def initialize(options={})
|
10
|
+
def initialize(options = {})
|
11
11
|
@background = options[:background].nil? ? :dark : options[:background]
|
12
12
|
@colors = options[:colors].nil? ? self.class.colors_possible? : options[:colors]
|
13
13
|
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)
|
@@ -104,6 +122,10 @@ module Kafo
|
|
104
122
|
custom_fact_storage[key.to_s] = value
|
105
123
|
end
|
106
124
|
|
125
|
+
def has_custom_fact?(key)
|
126
|
+
custom_fact_storage.key?(key.to_s)
|
127
|
+
end
|
128
|
+
|
107
129
|
def modules
|
108
130
|
@modules ||= begin
|
109
131
|
register_data_types
|
@@ -148,7 +170,7 @@ module Kafo
|
|
148
170
|
save_configuration(app)
|
149
171
|
end
|
150
172
|
|
151
|
-
def migrate_configuration(from_config, options={})
|
173
|
+
def migrate_configuration(from_config, options = {})
|
152
174
|
keys_to_skip = options.fetch(:skip, [])
|
153
175
|
keys = [:log_dir, :log_name, :log_level, :no_prefix,
|
154
176
|
:colors, :color_of_background, :custom, :verbose_log_level]
|
@@ -175,7 +197,7 @@ module Kafo
|
|
175
197
|
}
|
176
198
|
EOS
|
177
199
|
|
178
|
-
@logger.
|
200
|
+
@logger.notice 'Loading default values from puppet modules...'
|
179
201
|
command = PuppetCommand.new(dump_manifest, [], puppetconf, self).command
|
180
202
|
stdout, stderr, status = Open3.capture3(*PuppetCommand.format_command(command))
|
181
203
|
|
@@ -200,7 +222,7 @@ EOS
|
|
200
222
|
end
|
201
223
|
end
|
202
224
|
|
203
|
-
@logger.
|
225
|
+
@logger.notice "... finished"
|
204
226
|
|
205
227
|
load_yaml_from_output(stdout.split($/))
|
206
228
|
end
|
@@ -305,7 +327,7 @@ EOS
|
|
305
327
|
save_configuration(app)
|
306
328
|
store(answers)
|
307
329
|
migrations.store_applied
|
308
|
-
@logger.
|
330
|
+
@logger.notice("#{migrations.migrations.count} migration/s were applied. Updated configuration was saved.")
|
309
331
|
end
|
310
332
|
migrations.migrations.count
|
311
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,51 +117,84 @@ 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
|
107
154
|
|
108
|
-
# Store
|
155
|
+
# Store any custom fact. This will show up as kafo.scenario.custom.your_fact.
|
109
156
|
# It is possible to use structures such as arrays and hashes besides the
|
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
|
|
167
|
+
# Check whether a custom fact exists, regardless of whether or not it has a value.
|
168
|
+
#
|
169
|
+
# @param [Symbol] key
|
170
|
+
def has_custom_fact?(key)
|
171
|
+
self.kafo.config.has_custom_fact?(key)
|
172
|
+
end
|
173
|
+
|
117
174
|
# Return the id of the current scenario
|
175
|
+
#
|
176
|
+
# @return [String]
|
118
177
|
def scenario_id
|
119
178
|
self.kafo.config.scenario_id
|
120
179
|
end
|
121
180
|
|
122
181
|
# Return the path to the current scenario
|
182
|
+
#
|
183
|
+
# @return [String]
|
123
184
|
def scenario_path
|
124
185
|
self.kafo.config.config_file
|
125
186
|
end
|
126
187
|
|
127
188
|
# Return the actual data in the current scenario
|
189
|
+
#
|
190
|
+
# @return [Hash]
|
128
191
|
def scenario_data
|
129
192
|
self.kafo.config.app
|
130
193
|
end
|
194
|
+
|
195
|
+
# Return the current exit code
|
196
|
+
def exit_code
|
197
|
+
self.kafo.exit_code
|
198
|
+
end
|
131
199
|
end
|
132
200
|
end
|