test-kitchen 1.0.0.beta.4 → 1.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -16,6 +16,8 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
+
require 'kitchen/lazy_hash'
|
20
|
+
|
19
21
|
module Kitchen
|
20
22
|
|
21
23
|
module Provisioner
|
@@ -27,10 +29,35 @@ module Kitchen
|
|
27
29
|
|
28
30
|
include Logging
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@
|
32
|
+
attr_accessor :instance
|
33
|
+
|
34
|
+
def initialize(config = {})
|
35
|
+
@config = LazyHash.new(config, self)
|
36
|
+
self.class.defaults.each do |attr, value|
|
37
|
+
@config[attr] = value unless @config.has_key?(attr)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the name of this driver, suitable for display in a CLI.
|
42
|
+
#
|
43
|
+
# @return [String] name of this driver
|
44
|
+
def name
|
45
|
+
self.class.name.split('::').last
|
46
|
+
end
|
47
|
+
|
48
|
+
# Provides hash-like access to configuration keys.
|
49
|
+
#
|
50
|
+
# @param attr [Object] configuration key
|
51
|
+
# @return [Object] value at configuration key
|
52
|
+
def [](attr)
|
53
|
+
config[attr]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns an array of configuration keys.
|
57
|
+
#
|
58
|
+
# @return [Array] array of configuration keys
|
59
|
+
def config_keys
|
60
|
+
config.keys
|
34
61
|
end
|
35
62
|
|
36
63
|
def install_command ; end
|
@@ -45,19 +72,38 @@ module Kitchen
|
|
45
72
|
|
46
73
|
def cleanup_sandbox ; end
|
47
74
|
|
48
|
-
def home_path ; end
|
49
|
-
|
50
75
|
protected
|
51
76
|
|
52
|
-
attr_reader :
|
77
|
+
attr_reader :config
|
78
|
+
|
79
|
+
def logger
|
80
|
+
instance ? instance.logger : Kitchen.logger
|
81
|
+
end
|
53
82
|
|
54
83
|
def sudo(script)
|
55
84
|
config[:sudo] ? "sudo -E #{script}" : script
|
56
85
|
end
|
57
86
|
|
58
|
-
def
|
59
|
-
|
87
|
+
def self.defaults
|
88
|
+
@defaults ||= Hash.new.merge(super_defaults)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.super_defaults
|
92
|
+
klass = self.superclass
|
93
|
+
|
94
|
+
if klass.respond_to?(:defaults)
|
95
|
+
klass.defaults
|
96
|
+
else
|
97
|
+
Hash.new
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.default_config(attr, value = nil, &block)
|
102
|
+
defaults[attr] = block_given? ? block : value
|
60
103
|
end
|
104
|
+
|
105
|
+
default_config :root_path, "/tmp/kitchen"
|
106
|
+
default_config :sudo, true
|
61
107
|
end
|
62
108
|
end
|
63
109
|
end
|
@@ -0,0 +1,76 @@
|
|
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 'kitchen/errors'
|
20
|
+
require 'kitchen/logging'
|
21
|
+
|
22
|
+
module Kitchen
|
23
|
+
|
24
|
+
module Provisioner
|
25
|
+
|
26
|
+
module Chef
|
27
|
+
|
28
|
+
# Chef cookbook resolver that uses Berkshelf and a Berksfile to calculate
|
29
|
+
# dependencies.
|
30
|
+
#
|
31
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
32
|
+
class Berkshelf
|
33
|
+
|
34
|
+
include Logging
|
35
|
+
|
36
|
+
def initialize(berksfile, path, logger = Kitchen.logger)
|
37
|
+
@berksfile = berksfile
|
38
|
+
@path = path
|
39
|
+
@logger = logger
|
40
|
+
end
|
41
|
+
|
42
|
+
def resolve
|
43
|
+
info("Resolving cookbook dependencies with Berkshelf...")
|
44
|
+
debug("Using Berksfile from #{berksfile}")
|
45
|
+
|
46
|
+
load_berkshelf!
|
47
|
+
|
48
|
+
::Berkshelf.ui.mute do
|
49
|
+
if ::Berkshelf::Berksfile.method_defined?(:vendor)
|
50
|
+
# Berkshelf 3.0 requires the directory to not exist
|
51
|
+
FileUtils.rm_rf(path)
|
52
|
+
::Berkshelf::Berksfile.from_file(berksfile).vendor(path)
|
53
|
+
else
|
54
|
+
::Berkshelf::Berksfile.from_file(berksfile).install(path: path)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_reader :berksfile, :path, :logger
|
62
|
+
|
63
|
+
def load_berkshelf!
|
64
|
+
require 'berkshelf'
|
65
|
+
rescue LoadError => e
|
66
|
+
fatal("The `berkshelf' gem is missing and must be installed" +
|
67
|
+
" or cannot be properly activated. Run" +
|
68
|
+
" `gem install berkshelf` or add the following to your" +
|
69
|
+
" Gemfile if you are using Bundler: `gem 'berkshelf'`.")
|
70
|
+
raise UserError,
|
71
|
+
"Could not load or activate Berkshelf (#{e.message})"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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 'kitchen/errors'
|
20
|
+
require 'kitchen/logging'
|
21
|
+
|
22
|
+
module Kitchen
|
23
|
+
|
24
|
+
module Provisioner
|
25
|
+
|
26
|
+
module Chef
|
27
|
+
|
28
|
+
# Chef cookbook resolver that uses Librarian-Chef and a Cheffile to
|
29
|
+
# calculate # dependencies.
|
30
|
+
#
|
31
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
32
|
+
class Librarian
|
33
|
+
|
34
|
+
include Logging
|
35
|
+
|
36
|
+
def initialize(cheffile, path, logger = Kitchen.logger)
|
37
|
+
@cheffile = cheffile
|
38
|
+
@path = path
|
39
|
+
@logger = logger
|
40
|
+
end
|
41
|
+
|
42
|
+
def resolve
|
43
|
+
info("Resolving cookbook dependencies with Librarian-Chef")
|
44
|
+
debug("Using Cheffile from #{cheffile}")
|
45
|
+
|
46
|
+
load_librarian!
|
47
|
+
|
48
|
+
env = ::Librarian::Chef::Environment.new(
|
49
|
+
:project_path => File.dirname(cheffile))
|
50
|
+
env.config_db.local["path"] = path
|
51
|
+
::Librarian::Action::Resolve.new(env).run
|
52
|
+
::Librarian::Action::Install.new(env).run
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_reader :cheffile, :path, :logger
|
56
|
+
|
57
|
+
def load_librarian!
|
58
|
+
require 'librarian/chef/environment'
|
59
|
+
require 'librarian/action/resolve'
|
60
|
+
require 'librarian/action/install'
|
61
|
+
rescue LoadError => e
|
62
|
+
fatal("The `librarian-chef' gem is missing and must be installed" +
|
63
|
+
" or cannot be properly activated. Run" +
|
64
|
+
" `gem install librarian-chef` or add the following to your" +
|
65
|
+
" Gemfile if you are using Bundler: `gem 'librarian-chef'`.")
|
66
|
+
raise UserError,
|
67
|
+
"Could not load or activate Librarian-Chef (#{e.message})"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -16,10 +16,12 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require 'buff/ignore'
|
20
19
|
require 'fileutils'
|
21
20
|
require 'pathname'
|
22
21
|
require 'json'
|
22
|
+
|
23
|
+
require 'kitchen/provisioner/chef/berkshelf'
|
24
|
+
require 'kitchen/provisioner/chef/librarian'
|
23
25
|
require 'kitchen/util'
|
24
26
|
|
25
27
|
module Kitchen
|
@@ -31,10 +33,47 @@ module Kitchen
|
|
31
33
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
32
34
|
class ChefBase < Base
|
33
35
|
|
36
|
+
default_config :require_chef_omnibus, true
|
37
|
+
default_config :chef_omnibus_url, "https://www.opscode.com/chef/install.sh"
|
38
|
+
default_config :run_list, []
|
39
|
+
default_config :attributes, {}
|
40
|
+
default_config :cookbook_files_glob, %w[README.* metadata.{json,rb}
|
41
|
+
attributes/**/* definitions/**/* files/**/* libraries/**/*
|
42
|
+
providers/**/* recipes/**/* resources/**/* templates/**/*].join(",")
|
43
|
+
|
44
|
+
default_config :data_path do |provisioner|
|
45
|
+
provisioner.calculate_path("data")
|
46
|
+
end
|
47
|
+
|
48
|
+
default_config :data_bags_path do |provisioner|
|
49
|
+
provisioner.calculate_path("data_bags")
|
50
|
+
end
|
51
|
+
|
52
|
+
default_config :environments_path do |provisioner|
|
53
|
+
provisioner.calculate_path("environments")
|
54
|
+
end
|
55
|
+
|
56
|
+
default_config :nodes_path do |provisioner|
|
57
|
+
provisioner.calculate_path("nodes")
|
58
|
+
end
|
59
|
+
|
60
|
+
default_config :roles_path do |provisioner|
|
61
|
+
provisioner.calculate_path("roles")
|
62
|
+
end
|
63
|
+
|
64
|
+
default_config :encrypted_data_bag_secret_key_path do |provisioner|
|
65
|
+
provisioner.calculate_path("encrypted_data_bag_secret", :file)
|
66
|
+
end
|
67
|
+
|
68
|
+
def instance=(instance)
|
69
|
+
@instance = instance
|
70
|
+
expand_paths!
|
71
|
+
end
|
72
|
+
|
34
73
|
def install_command
|
35
|
-
return
|
74
|
+
return unless config[:require_chef_omnibus]
|
36
75
|
|
37
|
-
url = config[:chef_omnibus_url]
|
76
|
+
url = config[:chef_omnibus_url]
|
38
77
|
flag = config[:require_chef_omnibus]
|
39
78
|
version = if flag.is_a?(String) && flag != "latest"
|
40
79
|
"-v #{flag.downcase}"
|
@@ -63,7 +102,9 @@ module Kitchen
|
|
63
102
|
end
|
64
103
|
|
65
104
|
def init_command
|
66
|
-
|
105
|
+
dirs = %w{cookbooks data data_bags environments roles}.
|
106
|
+
map { |dir| File.join(config[:root_path], dir) }.join(" ")
|
107
|
+
"#{sudo('rm')} -rf #{dirs} ; mkdir -p #{config[:root_path]}"
|
67
108
|
end
|
68
109
|
|
69
110
|
def cleanup_sandbox
|
@@ -73,8 +114,59 @@ module Kitchen
|
|
73
114
|
FileUtils.rmtree(tmpdir)
|
74
115
|
end
|
75
116
|
|
117
|
+
def calculate_path(path, type = :directory)
|
118
|
+
base = config[:test_base_path]
|
119
|
+
candidates = []
|
120
|
+
candidates << File.join(base, instance.suite.name, path)
|
121
|
+
candidates << File.join(base, path)
|
122
|
+
candidates << File.join(Dir.pwd, path)
|
123
|
+
|
124
|
+
candidates.find do |c|
|
125
|
+
type == :directory ? File.directory?(c) : File.file?(c)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
76
129
|
protected
|
77
130
|
|
131
|
+
attr_reader :tmpdir
|
132
|
+
|
133
|
+
def expand_paths!
|
134
|
+
paths = %w{test_base data data_bags environments nodes roles}
|
135
|
+
paths.map{ |p| "#{p}_path".to_sym }.each do |key|
|
136
|
+
unless config[key].nil?
|
137
|
+
config[key] = File.expand_path(config[key], config[:kitchen_root])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def format_config_file(data)
|
143
|
+
data.each.map { |attr, value|
|
144
|
+
[attr, (value.is_a?(Array) ? value.to_s : %{"#{value}"})].join(" ")
|
145
|
+
}.join("\n")
|
146
|
+
end
|
147
|
+
|
148
|
+
def default_config_rb
|
149
|
+
root = config[:root_path]
|
150
|
+
|
151
|
+
{
|
152
|
+
:node_name => instance.name,
|
153
|
+
:checksum_path => "#{root}/checksums",
|
154
|
+
:file_cache_path => "#{root}/cache",
|
155
|
+
:file_backup_path => "#{root}/backup",
|
156
|
+
:cookbook_path => ["#{root}/cookbooks", "#{root}/site-cookbooks"],
|
157
|
+
:data_bag_path => "#{root}/data_bags",
|
158
|
+
:environment_path => "#{root}/environments",
|
159
|
+
:node_path => "#{root}/nodes",
|
160
|
+
:role_path => "#{root}/roles",
|
161
|
+
:client_path => "#{root}/clients",
|
162
|
+
:user_path => "#{root}/users",
|
163
|
+
:validation_key => "#{root}/validation.pem",
|
164
|
+
:client_key => "#{root}/client.pem",
|
165
|
+
:chef_server_url => "http://127.0.0.1:8889",
|
166
|
+
:encrypted_data_bag_secret => "#{root}/encrypted_data_bag_secret",
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
78
170
|
def create_chef_sandbox
|
79
171
|
@tmpdir = Dir.mktmpdir("#{instance.name}-sandbox-")
|
80
172
|
File.chmod(0755, @tmpdir)
|
@@ -82,22 +174,36 @@ module Kitchen
|
|
82
174
|
|
83
175
|
yield if block_given?
|
84
176
|
prepare_json
|
177
|
+
prepare_cache
|
178
|
+
prepare_cookbooks
|
179
|
+
prepare_data
|
85
180
|
prepare_data_bags
|
86
|
-
prepare_roles
|
87
|
-
prepare_nodes
|
88
181
|
prepare_environments
|
182
|
+
prepare_nodes
|
183
|
+
prepare_roles
|
89
184
|
prepare_secret
|
90
|
-
prepare_cache
|
91
|
-
prepare_cookbooks
|
92
185
|
tmpdir
|
93
186
|
end
|
94
187
|
|
95
188
|
def prepare_json
|
189
|
+
dna = config[:attributes].merge({ :run_list => config[:run_list] })
|
190
|
+
|
96
191
|
File.open(File.join(tmpdir, "dna.json"), "wb") do |file|
|
97
|
-
file.write(
|
192
|
+
file.write(dna.to_json)
|
98
193
|
end
|
99
194
|
end
|
100
195
|
|
196
|
+
def prepare_data
|
197
|
+
return unless data
|
198
|
+
|
199
|
+
info("Preparing data")
|
200
|
+
debug("Using data from #{data}")
|
201
|
+
|
202
|
+
tmpdata_dir = File.join(tmpdir, "data")
|
203
|
+
FileUtils.mkdir_p(tmpdata_dir)
|
204
|
+
FileUtils.cp_r(Dir.glob("#{data}/*"), tmpdata_dir)
|
205
|
+
end
|
206
|
+
|
101
207
|
def prepare_data_bags
|
102
208
|
return unless data_bags
|
103
209
|
|
@@ -165,65 +271,71 @@ module Kitchen
|
|
165
271
|
elsif File.exists?(metadata_rb)
|
166
272
|
cp_this_cookbook
|
167
273
|
else
|
168
|
-
|
169
|
-
fatal("Berksfile, Cheffile, cookbooks/, or metadata.rb" +
|
170
|
-
" must exist in #{kitchen_root}")
|
171
|
-
raise UserError, "Cookbooks could not be found"
|
274
|
+
make_fake_cookbook
|
172
275
|
end
|
173
276
|
|
174
|
-
|
277
|
+
filter_only_cookbook_files
|
175
278
|
end
|
176
279
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
280
|
+
def filter_only_cookbook_files
|
281
|
+
info("Removing non-cookbook files in sandbox")
|
282
|
+
FileUtils.rm(all_files_in_cookbooks - only_cookbook_files)
|
283
|
+
end
|
284
|
+
|
285
|
+
def all_files_in_cookbooks
|
286
|
+
Dir.glob(File.join(tmpbooks_dir, "**/*"), File::FNM_DOTMATCH).
|
287
|
+
select { |fn| File.file?(fn) && ! %w{. ..}.include?(fn) }
|
288
|
+
end
|
289
|
+
|
290
|
+
def only_cookbook_files
|
291
|
+
glob = File.join(tmpbooks_dir, "*", "{#{config[:cookbook_files_glob]}}")
|
292
|
+
|
293
|
+
Dir.glob(glob, File::FNM_DOTMATCH).
|
294
|
+
select { |fn| File.file?(fn) && ! %w{. ..}.include?(fn) }
|
187
295
|
end
|
188
296
|
|
189
297
|
def berksfile
|
190
|
-
File.join(kitchen_root, "Berksfile")
|
298
|
+
File.join(config[:kitchen_root], "Berksfile")
|
191
299
|
end
|
192
300
|
|
193
301
|
def cheffile
|
194
|
-
File.join(kitchen_root, "Cheffile")
|
302
|
+
File.join(config[:kitchen_root], "Cheffile")
|
195
303
|
end
|
196
304
|
|
197
305
|
def metadata_rb
|
198
|
-
File.join(kitchen_root, "metadata.rb")
|
306
|
+
File.join(config[:kitchen_root], "metadata.rb")
|
199
307
|
end
|
200
308
|
|
201
309
|
def cookbooks_dir
|
202
|
-
File.join(kitchen_root, "cookbooks")
|
310
|
+
File.join(config[:kitchen_root], "cookbooks")
|
203
311
|
end
|
204
312
|
|
205
313
|
def site_cookbooks_dir
|
206
|
-
File.join(kitchen_root, "site-cookbooks")
|
314
|
+
File.join(config[:kitchen_root], "site-cookbooks")
|
207
315
|
end
|
208
316
|
|
209
317
|
def data_bags
|
210
|
-
|
318
|
+
config[:data_bags_path]
|
211
319
|
end
|
212
320
|
|
213
321
|
def roles
|
214
|
-
|
322
|
+
config[:roles_path]
|
215
323
|
end
|
216
324
|
|
217
325
|
def nodes
|
218
|
-
|
326
|
+
config[:nodes_path]
|
327
|
+
end
|
328
|
+
|
329
|
+
def data
|
330
|
+
config[:data_path]
|
219
331
|
end
|
220
332
|
|
221
333
|
def environments
|
222
|
-
|
334
|
+
config[:environments_path]
|
223
335
|
end
|
224
336
|
|
225
337
|
def secret
|
226
|
-
|
338
|
+
config[:encrypted_data_bag_secret_key_path]
|
227
339
|
end
|
228
340
|
|
229
341
|
def tmpbooks_dir
|
@@ -260,63 +372,32 @@ module Kitchen
|
|
260
372
|
|
261
373
|
cb_path = File.join(tmpbooks_dir, cb_name)
|
262
374
|
|
263
|
-
glob = Dir.glob("#{kitchen_root}/**")
|
375
|
+
glob = Dir.glob("#{config[:kitchen_root]}/**")
|
264
376
|
|
265
377
|
FileUtils.mkdir_p(cb_path)
|
266
378
|
FileUtils.cp_r(glob, cb_path)
|
267
379
|
end
|
268
380
|
|
269
|
-
def
|
270
|
-
info("
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
" or cannot be properly activated. Run" +
|
278
|
-
" `gem install berkshelf` or add the following to your" +
|
279
|
-
" Gemfile if you are using Bundler: `gem 'berkshelf'`.")
|
280
|
-
raise UserError,
|
281
|
-
"Could not load or activate Berkshelf (#{e.message})"
|
381
|
+
def make_fake_cookbook
|
382
|
+
info("Berksfile, Cheffile, cookbooks/, or metadata.rb not found " +
|
383
|
+
"so Chef will run with effectively no cookbooks. Is this intended?")
|
384
|
+
name = File.basename(config[:kitchen_root])
|
385
|
+
fake_cb = File.join(tmpbooks_dir, name)
|
386
|
+
FileUtils.mkdir_p(fake_cb)
|
387
|
+
File.open(File.join(fake_cb, "metadata.rb"), "wb") do |file|
|
388
|
+
file.write(%{name "#{name}\n"})
|
282
389
|
end
|
390
|
+
end
|
283
391
|
|
392
|
+
def resolve_with_berkshelf
|
284
393
|
Kitchen.mutex.synchronize do
|
285
|
-
Berkshelf
|
286
|
-
install(:path => tmpbooks_dir)
|
394
|
+
Chef::Berkshelf.new(berksfile, tmpbooks_dir, logger).resolve
|
287
395
|
end
|
288
396
|
end
|
289
397
|
|
290
398
|
def resolve_with_librarian
|
291
|
-
info("Resolving cookbook dependencies with Librarian-Chef")
|
292
|
-
debug("Using Cheffile from #{cheffile}")
|
293
|
-
|
294
|
-
begin
|
295
|
-
require 'librarian/chef/environment'
|
296
|
-
require 'librarian/action/resolve'
|
297
|
-
require 'librarian/action/install'
|
298
|
-
rescue LoadError => e
|
299
|
-
fatal("The `librarian-chef' gem is missing and must be installed" +
|
300
|
-
" or cannot be properly activated. Run" +
|
301
|
-
" `gem install librarian-chef` or add the following to your" +
|
302
|
-
" Gemfile if you are using Bundler: `gem 'librarian-chef'`.")
|
303
|
-
raise UserError,
|
304
|
-
"Could not load or activate Librarian-Chef (#{e.message})"
|
305
|
-
end
|
306
|
-
|
307
399
|
Kitchen.mutex.synchronize do
|
308
|
-
|
309
|
-
env.config_db.local["path"] = tmpbooks_dir
|
310
|
-
Librarian::Action::Resolve.new(env).run
|
311
|
-
Librarian::Action::Install.new(env).run
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
private
|
316
|
-
|
317
|
-
def cookbooks_in_tmpdir
|
318
|
-
Dir.glob(File.join(tmpbooks_dir, "*/")).each do |cookbook_path|
|
319
|
-
yield cookbook_path if block_given?
|
400
|
+
Chef::Librarian.new(cheffile, tmpbooks_dir, logger).resolve
|
320
401
|
end
|
321
402
|
end
|
322
403
|
end
|