test-kitchen 1.0.0.beta.4 → 1.0.0.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -1
- data/Gemfile +1 -1
- data/README.md +18 -7
- data/Rakefile +8 -1
- data/features/kitchen_init_command.feature +90 -11
- data/features/step_definitions/git_steps.rb +3 -0
- data/lib/kitchen/busser.rb +79 -45
- data/lib/kitchen/cli.rb +14 -13
- data/lib/kitchen/config.rb +79 -138
- data/lib/kitchen/data_munger.rb +224 -0
- data/lib/kitchen/driver/base.rb +4 -31
- data/lib/kitchen/driver/ssh_base.rb +6 -16
- data/lib/kitchen/driver.rb +4 -0
- data/lib/kitchen/generator/init.rb +20 -9
- data/lib/kitchen/instance.rb +53 -58
- data/lib/kitchen/lazy_hash.rb +50 -0
- data/lib/kitchen/platform.rb +2 -31
- data/lib/kitchen/provisioner/base.rb +55 -9
- data/lib/kitchen/provisioner/chef/berkshelf.rb +76 -0
- data/lib/kitchen/provisioner/chef/librarian.rb +72 -0
- data/lib/kitchen/provisioner/chef_base.rb +159 -78
- data/lib/kitchen/provisioner/chef_solo.rb +6 -36
- data/lib/kitchen/provisioner/chef_zero.rb +70 -59
- data/lib/kitchen/provisioner/dummy.rb +28 -0
- data/lib/kitchen/provisioner.rb +6 -4
- data/lib/kitchen/shell_out.rb +2 -5
- data/lib/kitchen/ssh.rb +1 -1
- data/lib/kitchen/suite.rb +10 -79
- data/lib/kitchen/util.rb +2 -2
- data/lib/kitchen/version.rb +2 -2
- data/lib/kitchen.rb +5 -0
- data/spec/kitchen/config_spec.rb +84 -123
- data/spec/kitchen/data_munger_spec.rb +1412 -0
- data/spec/kitchen/driver/base_spec.rb +30 -0
- data/spec/kitchen/instance_spec.rb +868 -86
- data/spec/kitchen/lazy_hash_spec.rb +63 -0
- data/spec/kitchen/platform_spec.rb +0 -22
- data/spec/kitchen/provisioner/base_spec.rb +210 -0
- data/spec/kitchen/provisioner_spec.rb +70 -0
- data/spec/kitchen/suite_spec.rb +25 -38
- data/spec/spec_helper.rb +1 -0
- data/support/chef-client-zero.rb +51 -35
- data/support/dummy-validation.pem +27 -0
- data/templates/init/kitchen.yml.erb +10 -22
- data/test-kitchen.gemspec +1 -2
- metadata +20 -18
data/lib/kitchen/cli.rb
CHANGED
@@ -43,7 +43,7 @@ module Kitchen
|
|
43
43
|
Kitchen.logger = Kitchen.default_file_logger
|
44
44
|
@config = Kitchen::Config.new(
|
45
45
|
:loader => Kitchen::Loader::YAML.new(ENV['KITCHEN_YAML']),
|
46
|
-
:log_level => ENV
|
46
|
+
:log_level => ENV.fetch('KITCHEN_LOG', "info").downcase.to_sym
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
@@ -52,7 +52,10 @@ module Kitchen
|
|
52
52
|
:desc => "List the name of each instance only, one per line"
|
53
53
|
method_option :debug, :aliases => "-d", :type => :boolean,
|
54
54
|
:desc => "Show computed driver configuration for each instance"
|
55
|
+
method_option :log_level, :aliases => "-l",
|
56
|
+
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
55
57
|
def list(*args)
|
58
|
+
update_config!
|
56
59
|
result = parse_subcommand(args.first)
|
57
60
|
if options[:debug]
|
58
61
|
Array(result).each { |i| debug_instance(i) }
|
@@ -327,7 +330,7 @@ module Kitchen
|
|
327
330
|
[
|
328
331
|
color_pad(instance.name),
|
329
332
|
color_pad(instance.driver.name),
|
330
|
-
color_pad(
|
333
|
+
color_pad(instance.provisioner.name),
|
331
334
|
format_last_action(instance.last_action)
|
332
335
|
]
|
333
336
|
end
|
@@ -335,15 +338,17 @@ module Kitchen
|
|
335
338
|
def debug_instance(instance)
|
336
339
|
say "--------"
|
337
340
|
say "Instance: #{instance.name}"
|
338
|
-
say "Driver
|
339
|
-
say "Driver Config:"
|
341
|
+
say "Driver (#{instance.driver.name}):"
|
340
342
|
instance.driver.config_keys.sort.each do |key|
|
341
|
-
say " #{key}: #{instance.driver[key]}"
|
343
|
+
say " #{key}: #{instance.driver[key].inspect}"
|
342
344
|
end
|
343
|
-
|
344
|
-
|
345
|
-
say "
|
346
|
-
|
345
|
+
say "Provisioner (#{instance.provisioner.name}):"
|
346
|
+
instance.provisioner.config_keys.sort.each do |key|
|
347
|
+
say " #{key}: #{instance.provisioner[key].inspect}"
|
348
|
+
end
|
349
|
+
say "Busser (#{instance.busser.name}):"
|
350
|
+
instance.busser.config_keys.sort.each do |key|
|
351
|
+
say " #{key}: #{instance.busser[key].inspect}"
|
347
352
|
end
|
348
353
|
say ""
|
349
354
|
end
|
@@ -363,10 +368,6 @@ module Kitchen
|
|
363
368
|
end
|
364
369
|
end
|
365
370
|
|
366
|
-
def format_provisioner(name)
|
367
|
-
name.split('_').map { |word| word.capitalize }.join(' ')
|
368
|
-
end
|
369
|
-
|
370
371
|
def update_config!
|
371
372
|
if options[:log_level]
|
372
373
|
level = options[:log_level].downcase.to_sym
|
data/lib/kitchen/config.rb
CHANGED
@@ -16,8 +16,6 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require 'vendor/hash_recursive_merge'
|
20
|
-
|
21
19
|
module Kitchen
|
22
20
|
|
23
21
|
# Base configuration class for Kitchen. This class exposes configuration such
|
@@ -26,193 +24,136 @@ module Kitchen
|
|
26
24
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
27
25
|
class Config
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
attr_reader :kitchen_root
|
28
|
+
attr_reader :log_root
|
29
|
+
attr_reader :test_base_path
|
30
|
+
attr_reader :loader
|
31
31
|
attr_accessor :log_level
|
32
|
-
attr_writer :platforms
|
33
|
-
attr_writer :suites
|
34
|
-
|
35
|
-
# Default driver plugin to use
|
36
|
-
DEFAULT_DRIVER_PLUGIN = "dummy".freeze
|
37
|
-
|
38
|
-
# Default provisioner to use
|
39
|
-
DEFAULT_PROVISIONER = "chef_solo".freeze
|
40
32
|
|
41
33
|
# Creates a new configuration.
|
42
34
|
#
|
43
35
|
# @param [Hash] options configuration
|
44
36
|
# @option options [#read] :loader
|
45
37
|
# @option options [String] :kitchen_root
|
38
|
+
# @option options [String] :log_root
|
46
39
|
# @option options [String] :test_base_path
|
47
40
|
# @option options [Symbol] :log_level
|
48
41
|
def initialize(options = {})
|
49
|
-
@loader = options
|
50
|
-
@kitchen_root = options
|
51
|
-
@
|
52
|
-
@
|
42
|
+
@loader = options.fetch(:loader) { Kitchen::Loader::YAML.new }
|
43
|
+
@kitchen_root = options.fetch(:kitchen_root) { Dir.pwd }
|
44
|
+
@log_level = options.fetch(:log_level) { Kitchen::DEFAULT_LOG_LEVEL }
|
45
|
+
@log_root = options.fetch(:log_root) { default_log_root }
|
46
|
+
@test_base_path = options.fetch(:test_base_path) { default_test_base_path }
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Array<Instance>] all instances, resulting from all platform and
|
50
|
+
# suite combinations
|
51
|
+
def instances
|
52
|
+
@instances ||= Collection.new(build_instances)
|
53
53
|
end
|
54
54
|
|
55
55
|
# @return [Array<Platform>] all defined platforms which will be used in
|
56
56
|
# convergence integration
|
57
57
|
def platforms
|
58
58
|
@platforms ||= Collection.new(
|
59
|
-
|
59
|
+
data.platform_data.map { |pdata| Platform.new(pdata) })
|
60
60
|
end
|
61
61
|
|
62
62
|
# @return [Array<Suite>] all defined suites which will be used in
|
63
63
|
# convergence integration
|
64
64
|
def suites
|
65
65
|
@suites ||= Collection.new(
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
# @return [Array<Instance>] all instances, resulting from all platform and
|
70
|
-
# suite combinations
|
71
|
-
def instances
|
72
|
-
@instances ||= build_instances
|
66
|
+
data.suite_data.map { |sdata| Suite.new(sdata) })
|
73
67
|
end
|
74
68
|
|
75
69
|
private
|
76
70
|
|
77
|
-
def new_suite(hash)
|
78
|
-
path_hash = {
|
79
|
-
:data_bags_path => calculate_path("data_bags", hash[:name], hash[:data_bags_path]),
|
80
|
-
:roles_path => calculate_path("roles", hash[:name], hash[:roles_path]),
|
81
|
-
:nodes_path => calculate_path("nodes", hash[:name], hash[:nodes_path]),
|
82
|
-
}
|
83
|
-
|
84
|
-
Suite.new(hash.rmerge(path_hash))
|
85
|
-
end
|
86
|
-
|
87
|
-
def new_platform(hash)
|
88
|
-
Platform.new(hash)
|
89
|
-
end
|
90
|
-
|
91
|
-
def new_driver(hash)
|
92
|
-
hash[:driver_config] ||= Hash.new
|
93
|
-
hash[:driver_config][:kitchen_root] = kitchen_root
|
94
|
-
hash[:driver_config][:provisioner] = hash[:provisioner]
|
95
|
-
|
96
|
-
Driver.for_plugin(hash[:driver_plugin], hash[:driver_config])
|
97
|
-
end
|
98
|
-
|
99
71
|
def build_instances
|
100
|
-
|
101
|
-
|
102
|
-
arr[0].excludes.include?(arr[1].name)
|
103
|
-
end
|
104
|
-
filtered_instances.each_with_index do |arr, index|
|
105
|
-
results << new_instance(arr[0], arr[1], index)
|
72
|
+
filter_instances.map.with_index do |(suite, platform), index|
|
73
|
+
new_instance(suite, platform, index)
|
106
74
|
end
|
107
|
-
Collection.new(results)
|
108
|
-
end
|
109
|
-
|
110
|
-
def new_instance(suite, platform, index)
|
111
|
-
platform_hash = platform_driver_hash(platform.name)
|
112
|
-
platform_hash[:driver_config].rmerge!(suite.driver_config)
|
113
|
-
driver = new_driver(merge_driver_hash(platform_hash))
|
114
|
-
provisioner = driver[:provisioner]
|
115
|
-
|
116
|
-
instance = Instance.new(
|
117
|
-
:suite => extend_suite(suite, provisioner),
|
118
|
-
:platform => extend_platform(platform, provisioner),
|
119
|
-
:driver => driver,
|
120
|
-
:logger => new_instance_logger(index)
|
121
|
-
)
|
122
|
-
extend_instance(instance, provisioner)
|
123
75
|
end
|
124
76
|
|
125
|
-
def
|
126
|
-
|
127
|
-
when /^chef_/ then suite.dup.extend(Suite::Cheflike)
|
128
|
-
when /^puppet_/ then suite.dup.extend(Suite::Puppetlike)
|
129
|
-
else suite.dup
|
130
|
-
end
|
77
|
+
def data
|
78
|
+
@data ||= DataMunger.new(loader.read, kitchen_config)
|
131
79
|
end
|
132
80
|
|
133
|
-
def
|
134
|
-
|
135
|
-
when /^chef_/ then platform.dup.extend(Platform::Cheflike)
|
136
|
-
else platform.dup
|
137
|
-
end
|
81
|
+
def default_log_root
|
82
|
+
File.join(kitchen_root, Kitchen::DEFAULT_LOG_DIR)
|
138
83
|
end
|
139
84
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
85
|
+
def default_test_base_path
|
86
|
+
File.join(kitchen_root, Kitchen::DEFAULT_TEST_DIR)
|
87
|
+
end
|
88
|
+
|
89
|
+
def filter_instances
|
90
|
+
suites.product(platforms).select do |suite, platform|
|
91
|
+
if !suite.includes.empty?
|
92
|
+
suite.includes.include?(platform.name)
|
93
|
+
elsif !suite.excludes.empty?
|
94
|
+
!suite.excludes.include?(platform.name)
|
95
|
+
else
|
96
|
+
true
|
97
|
+
end
|
145
98
|
end
|
146
99
|
end
|
147
100
|
|
148
|
-
def
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
def platform_driver_hash(platform_name)
|
153
|
-
h = data[:platforms].find { |p| p[:name] == platform_name } || Hash.new
|
154
|
-
h[:driver_config] ||= {}
|
155
|
-
|
156
|
-
h.select do |key, value|
|
157
|
-
[:driver_plugin, :driver_config, :provisioner].include?(key)
|
158
|
-
end
|
101
|
+
def instance_name(suite, platform)
|
102
|
+
Instance.name_for(suite, platform)
|
159
103
|
end
|
160
104
|
|
161
|
-
def
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
105
|
+
def kitchen_config
|
106
|
+
@kitchen_config ||= {
|
107
|
+
:defaults => {
|
108
|
+
:driver => Driver::DEFAULT_PLUGIN,
|
109
|
+
:provisioner => Provisioner::DEFAULT_PLUGIN
|
110
|
+
},
|
111
|
+
:kitchen_root => kitchen_root,
|
112
|
+
:test_base_path => test_base_path,
|
113
|
+
:log_level => log_level,
|
114
|
+
}
|
171
115
|
end
|
172
116
|
|
173
|
-
def
|
174
|
-
|
117
|
+
def new_busser(suite, platform)
|
118
|
+
bdata = data.busser_data_for(suite.name, platform.name)
|
119
|
+
Busser.new(suite.name, bdata)
|
175
120
|
end
|
176
121
|
|
177
|
-
def
|
178
|
-
|
122
|
+
def new_driver(suite, platform)
|
123
|
+
ddata = data.driver_data_for(suite.name, platform.name)
|
124
|
+
Driver.for_plugin(ddata[:name], ddata)
|
179
125
|
end
|
180
126
|
|
181
|
-
def
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
elsif File.directory?(common_path)
|
192
|
-
common_path
|
193
|
-
elsif File.directory?(top_level_path)
|
194
|
-
top_level_path
|
195
|
-
else
|
196
|
-
nil
|
197
|
-
end
|
127
|
+
def new_instance(suite, platform, index)
|
128
|
+
Instance.new(
|
129
|
+
:busser => new_busser(suite, platform),
|
130
|
+
:driver => new_driver(suite, platform),
|
131
|
+
:logger => new_logger(suite, platform, index),
|
132
|
+
:suite => suite,
|
133
|
+
:platform => platform,
|
134
|
+
:provisioner => new_provisioner(suite, platform),
|
135
|
+
:state_file => new_state_file(suite, platform)
|
136
|
+
)
|
198
137
|
end
|
199
138
|
|
200
|
-
def
|
201
|
-
|
202
|
-
|
203
|
-
:
|
204
|
-
:
|
205
|
-
|
139
|
+
def new_logger(suite, platform, index)
|
140
|
+
name = instance_name(suite, platform)
|
141
|
+
Logger.new(
|
142
|
+
:stdout => STDOUT,
|
143
|
+
:color => Color::COLORS[index % Color::COLORS.size].to_sym,
|
144
|
+
:logdev => File.join(log_root, "#{name}.log"),
|
145
|
+
:level => Util.to_logger_level(self.log_level),
|
146
|
+
:progname => name
|
147
|
+
)
|
206
148
|
end
|
207
149
|
|
208
|
-
def
|
209
|
-
data.
|
210
|
-
|
211
|
-
end
|
150
|
+
def new_provisioner(suite, platform)
|
151
|
+
pdata = data.provisioner_data_for(suite.name, platform.name)
|
152
|
+
Provisioner.for_plugin(pdata[:name], pdata)
|
212
153
|
end
|
213
154
|
|
214
|
-
def
|
215
|
-
|
155
|
+
def new_state_file(suite, platform)
|
156
|
+
StateFile.new(kitchen_root, instance_name(suite, platform))
|
216
157
|
end
|
217
158
|
end
|
218
159
|
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'vendor/hash_recursive_merge'
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
|
23
|
+
# Class to handle recursive merging of configuration between platforms,
|
24
|
+
# suites, and common data.
|
25
|
+
#
|
26
|
+
# This object will mutate the data Hash passed into its constructor and so
|
27
|
+
# should not be reused or shared across threads.
|
28
|
+
#
|
29
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
30
|
+
class DataMunger
|
31
|
+
|
32
|
+
def initialize(data, kitchen_config = {})
|
33
|
+
@data = data
|
34
|
+
@kitchen_config = kitchen_config
|
35
|
+
convert_legacy_driver_format!
|
36
|
+
convert_legacy_chef_paths_format!
|
37
|
+
convert_legacy_require_chef_omnibus_format!
|
38
|
+
move_chef_data_to_provisioner!
|
39
|
+
end
|
40
|
+
|
41
|
+
def busser_data_for(suite, platform)
|
42
|
+
merged_data_for(:busser, suite, platform, :version).tap do |bdata|
|
43
|
+
set_kitchen_config_at!(bdata, :kitchen_root)
|
44
|
+
set_kitchen_config_at!(bdata, :test_base_path)
|
45
|
+
set_kitchen_config_at!(bdata, :log_level)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def driver_data_for(suite, platform)
|
50
|
+
merged_data_for(:driver, suite, platform).tap do |ddata|
|
51
|
+
set_kitchen_config_at!(ddata, :kitchen_root)
|
52
|
+
set_kitchen_config_at!(ddata, :test_base_path)
|
53
|
+
set_kitchen_config_at!(ddata, :log_level)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def platform_data
|
58
|
+
data.fetch(:platforms, [])
|
59
|
+
end
|
60
|
+
|
61
|
+
def provisioner_data_for(suite, platform)
|
62
|
+
merged_data_for(:provisioner, suite, platform).tap do |pdata|
|
63
|
+
set_kitchen_config_at!(pdata, :kitchen_root)
|
64
|
+
set_kitchen_config_at!(pdata, :test_base_path)
|
65
|
+
set_kitchen_config_at!(pdata, :log_level)
|
66
|
+
combine_arrays!(pdata, :run_list, :platform, :suite)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def suite_data
|
71
|
+
data.fetch(:suites, [])
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
attr_reader :data, :kitchen_config
|
77
|
+
|
78
|
+
def combine_arrays!(root, key, *namespaces)
|
79
|
+
if root.has_key?(key)
|
80
|
+
root[key] = namespaces.
|
81
|
+
map { |namespace| root.fetch(key).fetch(namespace, []) }.flatten.
|
82
|
+
compact
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def convert_legacy_chef_paths_format!
|
87
|
+
data.fetch(:suites, []).each do |suite|
|
88
|
+
%w{data data_bags environments nodes roles}.each do |key|
|
89
|
+
move_chef_data_to_provisioner_at!(suite, "#{key}_path".to_sym)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def convert_legacy_driver_format!
|
95
|
+
convert_legacy_driver_format_at!(data)
|
96
|
+
data.fetch(:platforms, []).each do |platform|
|
97
|
+
convert_legacy_driver_format_at!(platform)
|
98
|
+
end
|
99
|
+
data.fetch(:suites, []).each do |suite|
|
100
|
+
convert_legacy_driver_format_at!(suite)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def convert_legacy_driver_format_at!(root)
|
105
|
+
if root.has_key?(:driver_config)
|
106
|
+
ddata = root.fetch(:driver, Hash.new)
|
107
|
+
ddata = { :name => ddata } if ddata.is_a?(String)
|
108
|
+
root[:driver] = root.delete(:driver_config).rmerge(ddata)
|
109
|
+
end
|
110
|
+
|
111
|
+
if root.has_key?(:driver_plugin)
|
112
|
+
ddata = root.fetch(:driver, Hash.new)
|
113
|
+
ddata = { :name => ddata } if ddata.is_a?(String)
|
114
|
+
root[:driver] = { :name => root.delete(:driver_plugin) }.rmerge(ddata)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def convert_legacy_require_chef_omnibus_format!
|
119
|
+
convert_legacy_require_chef_omnibus_format_at!(data)
|
120
|
+
data.fetch(:platforms, []).each do |platform|
|
121
|
+
convert_legacy_require_chef_omnibus_format_at!(platform)
|
122
|
+
end
|
123
|
+
data.fetch(:suites, []).each do |suite|
|
124
|
+
convert_legacy_require_chef_omnibus_format_at!(suite)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def convert_legacy_require_chef_omnibus_format_at!(root)
|
129
|
+
key = :require_chef_omnibus
|
130
|
+
ddata = root.fetch(:driver, Hash.new)
|
131
|
+
|
132
|
+
if ddata.is_a?(Hash) && ddata.has_key?(key)
|
133
|
+
pdata = root.fetch(:provisioner, Hash.new)
|
134
|
+
pdata = { :name => pdata } if pdata.is_a?(String)
|
135
|
+
root[:provisioner] =
|
136
|
+
{ key => root.fetch(:driver).delete(key) }.rmerge(pdata)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def merged_data_for(key, suite, platform, default_key = :name)
|
141
|
+
ddata = normalized_default_data(key, default_key)
|
142
|
+
cdata = normalized_common_data(key, default_key)
|
143
|
+
pdata = normalized_platform_data(key, default_key, platform)
|
144
|
+
sdata = normalized_suite_data(key, default_key, suite)
|
145
|
+
|
146
|
+
ddata.rmerge(cdata.rmerge(pdata.rmerge(sdata)))
|
147
|
+
end
|
148
|
+
|
149
|
+
def move_chef_data_to_provisioner!
|
150
|
+
data.fetch(:suites, []).each do |suite|
|
151
|
+
move_chef_data_to_provisioner_at!(suite, :attributes)
|
152
|
+
move_chef_data_to_provisioner_at!(suite, :run_list)
|
153
|
+
end
|
154
|
+
|
155
|
+
data.fetch(:platforms, []).each do |platform|
|
156
|
+
move_chef_data_to_provisioner_at!(platform, :attributes)
|
157
|
+
move_chef_data_to_provisioner_at!(platform, :run_list)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def move_chef_data_to_provisioner_at!(root, key)
|
162
|
+
if root.has_key?(key)
|
163
|
+
pdata = root.fetch(:provisioner, Hash.new)
|
164
|
+
pdata = { :name => pdata } if pdata.is_a?(String)
|
165
|
+
if ! root.fetch(key, nil).nil?
|
166
|
+
root[:provisioner] = pdata.rmerge({ key => root.delete(key) })
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def namespace_array!(root, key, bucket)
|
172
|
+
root[key] = { bucket => root.fetch(key) } if root.has_key?(key)
|
173
|
+
end
|
174
|
+
|
175
|
+
def normalized_common_data(key, default_key)
|
176
|
+
cdata = data.fetch(key, Hash.new)
|
177
|
+
cdata = cdata.nil? ? Hash.new : cdata.dup
|
178
|
+
cdata = { default_key => cdata } if cdata.is_a?(String)
|
179
|
+
cdata
|
180
|
+
end
|
181
|
+
|
182
|
+
def normalized_default_data(key, default_key)
|
183
|
+
ddata = kitchen_config.fetch(:defaults, Hash.new).fetch(key, Hash.new).dup
|
184
|
+
ddata = { default_key => ddata } if ddata.is_a?(String)
|
185
|
+
ddata
|
186
|
+
end
|
187
|
+
|
188
|
+
def normalized_platform_data(key, default_key, platform)
|
189
|
+
pdata = platform_data_for(platform).fetch(key, Hash.new)
|
190
|
+
pdata = pdata.nil? ? Hash.new : pdata.dup
|
191
|
+
pdata = { default_key => pdata } if pdata.is_a?(String)
|
192
|
+
namespace_array!(pdata, :run_list, :platform)
|
193
|
+
pdata
|
194
|
+
end
|
195
|
+
|
196
|
+
def normalized_suite_data(key, default_key, suite)
|
197
|
+
sdata = suite_data_for(suite).fetch(key, Hash.new)
|
198
|
+
sdata = sdata.nil? ? Hash.new : sdata.dup
|
199
|
+
sdata = { default_key => sdata } if sdata.is_a?(String)
|
200
|
+
namespace_array!(sdata, :run_list, :suite)
|
201
|
+
sdata
|
202
|
+
end
|
203
|
+
|
204
|
+
def platform_data_for(name)
|
205
|
+
data.fetch(:platforms, Hash.new).find(lambda { Hash.new }) do |platform|
|
206
|
+
platform.fetch(:name, nil) == name
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def set_kitchen_config_at!(root, key)
|
211
|
+
kdata = data.fetch(:kitchen, Hash.new)
|
212
|
+
|
213
|
+
root.delete(key) if root.has_key?(key)
|
214
|
+
root[key] = kitchen_config.fetch(key) if kitchen_config.has_key?(key)
|
215
|
+
root[key] = kdata.fetch(key) if kdata.has_key?(key)
|
216
|
+
end
|
217
|
+
|
218
|
+
def suite_data_for(name)
|
219
|
+
data.fetch(:suites, Hash.new).find(lambda { Hash.new }) do |suite|
|
220
|
+
suite.fetch(:name, nil) == name
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|