test-kitchen 1.3.1 → 1.4.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +2 -0
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +45 -0
  5. data/Rakefile +15 -0
  6. data/features/kitchen_action_commands.feature +12 -9
  7. data/features/kitchen_defaults.feature +38 -0
  8. data/features/kitchen_init_command.feature +0 -1
  9. data/features/kitchen_list_command.feature +2 -2
  10. data/features/kitchen_login_command.feature +7 -1
  11. data/features/kitchen_test_command.feature +4 -4
  12. data/lib/kitchen.rb +40 -11
  13. data/lib/kitchen/cli.rb +38 -22
  14. data/lib/kitchen/command/list.rb +5 -2
  15. data/lib/kitchen/config.rb +45 -18
  16. data/lib/kitchen/configurable.rb +137 -1
  17. data/lib/kitchen/data_munger.rb +248 -17
  18. data/lib/kitchen/driver.rb +1 -1
  19. data/lib/kitchen/driver/base.rb +1 -83
  20. data/lib/kitchen/driver/dummy.rb +0 -5
  21. data/lib/kitchen/driver/ssh_base.rb +177 -22
  22. data/lib/kitchen/instance.rb +140 -20
  23. data/lib/kitchen/logger.rb +43 -8
  24. data/lib/kitchen/login_command.rb +14 -5
  25. data/lib/kitchen/platform.rb +19 -0
  26. data/lib/kitchen/provisioner.rb +5 -3
  27. data/lib/kitchen/provisioner/base.rb +46 -48
  28. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -0
  29. data/lib/kitchen/provisioner/chef_base.rb +179 -286
  30. data/lib/kitchen/provisioner/chef_solo.rb +11 -5
  31. data/lib/kitchen/provisioner/chef_zero.rb +108 -94
  32. data/lib/kitchen/provisioner/dummy.rb +47 -0
  33. data/lib/kitchen/provisioner/shell.rb +45 -12
  34. data/lib/kitchen/rake_tasks.rb +1 -1
  35. data/lib/kitchen/ssh.rb +1 -1
  36. data/lib/kitchen/thor_tasks.rb +1 -1
  37. data/lib/kitchen/transport.rb +54 -0
  38. data/lib/kitchen/transport/base.rb +146 -0
  39. data/lib/kitchen/transport/dummy.rb +75 -0
  40. data/lib/kitchen/transport/ssh.rb +325 -0
  41. data/lib/kitchen/transport/winrm.rb +508 -0
  42. data/lib/kitchen/transport/winrm/command_executor.rb +188 -0
  43. data/lib/kitchen/transport/winrm/file_transporter.rb +454 -0
  44. data/lib/kitchen/transport/winrm/logging.rb +50 -0
  45. data/lib/kitchen/transport/winrm/template.rb +74 -0
  46. data/lib/kitchen/transport/winrm/tmp_zip.rb +187 -0
  47. data/lib/kitchen/verifier.rb +55 -0
  48. data/lib/kitchen/verifier/base.rb +191 -0
  49. data/lib/kitchen/verifier/busser.rb +266 -0
  50. data/lib/kitchen/verifier/dummy.rb +75 -0
  51. data/lib/kitchen/version.rb +1 -1
  52. data/spec/kitchen/cli_spec.rb +56 -0
  53. data/spec/kitchen/config_spec.rb +61 -20
  54. data/spec/kitchen/configurable_spec.rb +327 -1
  55. data/spec/kitchen/data_munger_spec.rb +777 -14
  56. data/spec/kitchen/driver/base_spec.rb +7 -38
  57. data/spec/kitchen/driver/dummy_spec.rb +0 -29
  58. data/spec/kitchen/driver/ssh_base_spec.rb +580 -236
  59. data/spec/kitchen/driver_spec.rb +1 -0
  60. data/spec/kitchen/instance_spec.rb +383 -83
  61. data/spec/kitchen/login_command_spec.rb +29 -10
  62. data/spec/kitchen/platform_spec.rb +58 -2
  63. data/spec/kitchen/provisioner/base_spec.rb +170 -18
  64. data/spec/kitchen/provisioner/chef_base_spec.rb +454 -104
  65. data/spec/kitchen/provisioner/chef_solo_spec.rb +307 -104
  66. data/spec/kitchen/provisioner/chef_zero_spec.rb +561 -230
  67. data/spec/kitchen/provisioner/dummy_spec.rb +91 -0
  68. data/spec/kitchen/provisioner/shell_spec.rb +158 -56
  69. data/spec/kitchen/provisioner_spec.rb +37 -0
  70. data/spec/kitchen/ssh_spec.rb +19 -19
  71. data/spec/kitchen/transport/base_spec.rb +89 -0
  72. data/spec/kitchen/transport/ssh_spec.rb +1147 -0
  73. data/spec/kitchen/transport/winrm/command_executor_spec.rb +400 -0
  74. data/spec/kitchen/transport/winrm/file_transporter_spec.rb +876 -0
  75. data/spec/kitchen/transport/winrm/logging_spec.rb +92 -0
  76. data/spec/kitchen/transport/winrm/template_spec.rb +51 -0
  77. data/spec/kitchen/transport/winrm/tmp_zip_spec.rb +132 -0
  78. data/spec/kitchen/transport/winrm_spec.rb +1069 -0
  79. data/spec/kitchen/transport_spec.rb +112 -0
  80. data/spec/kitchen/verifier/base_spec.rb +310 -0
  81. data/spec/kitchen/verifier/busser_spec.rb +540 -0
  82. data/spec/kitchen/verifier/dummy_spec.rb +91 -0
  83. data/spec/kitchen/verifier_spec.rb +120 -0
  84. data/spec/kitchen_spec.rb +7 -0
  85. data/spec/spec_helper.rb +8 -0
  86. data/spec/support/powershell_max_size_spec.rb +40 -0
  87. data/support/busser_install_command.ps1 +14 -0
  88. data/support/busser_install_command.sh +15 -0
  89. data/support/check_files.ps1.erb +48 -0
  90. data/support/chef_base_init_command.ps1 +18 -0
  91. data/support/chef_base_init_command.sh +2 -0
  92. data/support/chef_base_install_command.ps1 +76 -0
  93. data/support/chef_base_install_command.sh +137 -0
  94. data/support/chef_zero_prepare_command_legacy.ps1 +9 -0
  95. data/support/chef_zero_prepare_command_legacy.sh +10 -0
  96. data/support/decode_files.ps1.erb +61 -0
  97. data/test-kitchen.gemspec +2 -0
  98. metadata +97 -8
  99. data/lib/kitchen/busser.rb +0 -316
  100. data/spec/kitchen/busser_spec.rb +0 -490
  101. data/support/chef_helpers.sh +0 -16
@@ -21,6 +21,7 @@ require "pathname"
21
21
  require "json"
22
22
 
23
23
  require "kitchen/provisioner/chef/berkshelf"
24
+ require "kitchen/provisioner/chef/common_sandbox"
24
25
  require "kitchen/provisioner/chef/librarian"
25
26
  require "kitchen/util"
26
27
 
@@ -35,7 +36,6 @@ module Kitchen
35
36
 
36
37
  default_config :require_chef_omnibus, true
37
38
  default_config :chef_omnibus_url, "https://www.chef.io/chef/install.sh"
38
- default_config :chef_omnibus_root, "/opt/chef"
39
39
  default_config :chef_omnibus_install_options, nil
40
40
  default_config :run_list, []
41
41
  default_config :attributes, {}
@@ -46,6 +46,18 @@ module Kitchen
46
46
  providers/**/* recipes/**/* resources/**/* templates/**/*
47
47
  ].join(",")
48
48
 
49
+ default_config :chef_metadata_url do |provisioner|
50
+ provisioner.default_windows_chef_metadata_url if provisioner.windows_os?
51
+ end
52
+
53
+ default_config :chef_omnibus_root do |provisioner|
54
+ if provisioner.windows_os?
55
+ "$env:systemdrive\\opscode\\chef"
56
+ else
57
+ "/opt/chef"
58
+ end
59
+ end
60
+
49
61
  default_config :data_path do |provisioner|
50
62
  provisioner.calculate_path("data")
51
63
  end
@@ -81,106 +93,72 @@ module Kitchen
81
93
  end
82
94
  expand_path_for :encrypted_data_bag_secret_key_path
83
95
 
84
- # (see Base#install_command)
85
- def install_command
86
- return unless config[:require_chef_omnibus]
96
+ # (see Base#create_sandbox)
97
+ def create_sandbox
98
+ super
99
+ Chef::CommonSandbox.new(config, sandbox_path, instance).populate
100
+ end
87
101
 
88
- lines = [Util.shell_helpers, chef_shell_helpers, chef_install_function]
89
- Util.wrap_command(lines.join("\n"))
102
+ # @return [String] a metadata URL for the Chef Omnitruck API suitable
103
+ # for installing a Windows MSI package
104
+ def default_windows_chef_metadata_url
105
+ version = config[:require_chef_omnibus]
106
+ version = "latest" if version == true
107
+ base = if config[:chef_omnibus_url] =~ %r{/install.sh$}
108
+ "#{File.dirname(config[:chef_omnibus_url])}/"
109
+ else
110
+ "https://www.chef.io/chef/"
111
+ end
112
+
113
+ url = "#{base}#{metadata_project_from_options}"
114
+ url << "?p=windows&m=x86_64&pv=2008r2" # same pacakge for all versions
115
+ url << "&v=#{version.to_s.downcase}"
116
+ url
90
117
  end
91
118
 
92
119
  # (see Base#init_command)
93
120
  def init_command
94
121
  dirs = %w[cookbooks data data_bags environments roles clients].
95
- map { |dir| File.join(config[:root_path], dir) }.join(" ")
96
- lines = ["#{sudo("rm")} -rf #{dirs}", "mkdir -p #{config[:root_path]}"]
122
+ sort.map { |dir| remote_path_join(config[:root_path], dir) }
97
123
 
98
- Util.wrap_command(lines.join("\n"))
99
- end
124
+ vars = if powershell_shell?
125
+ init_command_vars_for_powershell(dirs)
126
+ else
127
+ init_command_vars_for_bourne(dirs)
128
+ end
100
129
 
101
- # (see Base#create_sandbox)
102
- def create_sandbox
103
- super
104
- prepare_json
105
- prepare_cache
106
- prepare_cookbooks
107
- prepare(:data)
108
- prepare(:data_bags)
109
- prepare(:environments)
110
- prepare(:nodes)
111
- prepare(:roles)
112
- prepare(:clients)
113
- prepare(
114
- :secret,
115
- :type => :file,
116
- :dest_name => "encrypted_data_bag_secret",
117
- :key_name => :encrypted_data_bag_secret_key_path
118
- )
130
+ shell_code_from_file(vars, "chef_base_init_command")
119
131
  end
120
132
 
121
- private
133
+ # (see Base#install_command)
134
+ def install_command
135
+ return unless config[:require_chef_omnibus]
122
136
 
123
- # Load cookbook dependency resolver code, if required.
124
- #
125
- # (see Base#load_needed_dependencies!)
126
- def load_needed_dependencies!
127
- if File.exist?(berksfile)
128
- debug("Berksfile found at #{berksfile}, loading Berkshelf")
129
- Chef::Berkshelf.load!(logger)
130
- elsif File.exist?(cheffile)
131
- debug("Cheffile found at #{cheffile}, loading Librarian-Chef")
132
- Chef::Librarian.load!(logger)
137
+ version = config[:require_chef_omnibus].to_s.downcase
138
+
139
+ vars = if powershell_shell?
140
+ install_command_vars_for_powershell(version)
141
+ else
142
+ install_command_vars_for_bourne(version)
133
143
  end
134
- end
135
144
 
136
- # Returns shell code with chef-related functions.
137
- #
138
- # @return [String] shell code
139
- # @api private
140
- def chef_shell_helpers
141
- IO.read(File.join(
142
- File.dirname(__FILE__), %w[.. .. .. support chef_helpers.sh]
143
- ))
145
+ shell_code_from_file(vars, "chef_base_install_command")
144
146
  end
145
147
 
146
- # Generates the shell code to conditionally install a Chef Omnibus
147
- # package onto an instance.
148
- #
149
- # @return [String] shell code
150
- # @api private
151
- def chef_install_function
152
- version = config[:require_chef_omnibus].to_s.downcase
153
- pretty_version = case version
154
- when "true" then "install only if missing"
155
- when "latest" then "always install latest version"
156
- else version
157
- end
158
- install_flags = %w[latest true].include?(version) ? "" : "-v #{version}"
159
- if config[:chef_omnibus_install_options]
160
- install_flags << " " << config[:chef_omnibus_install_options]
161
- end
148
+ private
162
149
 
163
- <<-INSTALL.gsub(/^ {10}/, "")
164
- if should_update_chef "#{config[:chef_omnibus_root]}" "#{version}" ; then
165
- echo "-----> Installing Chef Omnibus (#{pretty_version})"
166
- do_download #{config[:chef_omnibus_url]} /tmp/install.sh
167
- #{sudo("sh")} /tmp/install.sh #{install_flags.strip}
168
- else
169
- echo "-----> Chef Omnibus installation detected (#{pretty_version})"
170
- fi
171
- INSTALL
150
+ # @return [String] an absolute path to a Berksfile, relative to the
151
+ # kitchen root
152
+ # @api private
153
+ def berksfile
154
+ File.join(config[:kitchen_root], "Berksfile")
172
155
  end
173
156
 
174
- # Generates a rendered client.rb/solo.rb/knife.rb formatted file as a
175
- # String.
176
- #
177
- # @param data [Hash] a key/value pair hash of configuration
178
- # @return [String] a rendered Chef config file as a String
157
+ # @return [String] an absolute path to a Cheffile, relative to the
158
+ # kitchen root
179
159
  # @api private
180
- def format_config_file(data)
181
- data.each.map { |attr, value|
182
- [attr, value.inspect].join(" ")
183
- }.join("\n")
160
+ def cheffile
161
+ File.join(config[:kitchen_root], "Cheffile")
184
162
  end
185
163
 
186
164
  # Generates a Hash with default values for a solo.rb or client.rb Chef
@@ -188,256 +166,171 @@ module Kitchen
188
166
  #
189
167
  # @return [Hash] a configuration hash
190
168
  # @api private
191
- def default_config_rb
192
- root = config[:root_path]
169
+ def default_config_rb # rubocop:disable Metrics/MethodLength
170
+ root = config[:root_path].gsub("$env:TEMP", "\#{ENV['TEMP']\}")
193
171
 
194
172
  {
195
173
  :node_name => instance.name,
196
- :checksum_path => "#{root}/checksums",
197
- :file_cache_path => "#{root}/cache",
198
- :file_backup_path => "#{root}/backup",
199
- :cookbook_path => ["#{root}/cookbooks", "#{root}/site-cookbooks"],
200
- :data_bag_path => "#{root}/data_bags",
201
- :environment_path => "#{root}/environments",
202
- :node_path => "#{root}/nodes",
203
- :role_path => "#{root}/roles",
204
- :client_path => "#{root}/clients",
205
- :user_path => "#{root}/users",
206
- :validation_key => "#{root}/validation.pem",
207
- :client_key => "#{root}/client.pem",
174
+ :checksum_path => remote_path_join(root, "checksums"),
175
+ :file_cache_path => remote_path_join(root, "cache"),
176
+ :file_backup_path => remote_path_join(root, "backup"),
177
+ :cookbook_path => [
178
+ remote_path_join(root, "cookbooks"),
179
+ remote_path_join(root, "site-cookbooks")
180
+ ],
181
+ :data_bag_path => remote_path_join(root, "data_bags"),
182
+ :environment_path => remote_path_join(root, "environments"),
183
+ :node_path => remote_path_join(root, "nodes"),
184
+ :role_path => remote_path_join(root, "roles"),
185
+ :client_path => remote_path_join(root, "clients"),
186
+ :user_path => remote_path_join(root, "users"),
187
+ :validation_key => remote_path_join(root, "validation.pem"),
188
+ :client_key => remote_path_join(root, "client.pem"),
208
189
  :chef_server_url => "http://127.0.0.1:8889",
209
- :encrypted_data_bag_secret => "#{root}/encrypted_data_bag_secret"
190
+ :encrypted_data_bag_secret => remote_path_join(
191
+ root, "encrypted_data_bag_secret"
192
+ )
210
193
  }
211
194
  end
212
195
 
213
- # Prepares a generic Chef component source directory or file for
214
- # inclusion in the sandbox path. These components might includes nodes,
215
- # roles, etc.
216
- #
217
- # @param component [Symbol,String] a component name such as `:node`
218
- # @param opts [Hash] optional configuration
219
- # @option opts [Symbol] :type whether the component is a directory or
220
- # file (default: `:directory`)
221
- # @option opts [Symbol] :key_name the key name in the config hash from
222
- # which to pull the source path (default: `"#{component}_path"`)
223
- # @option opts [String] :dest_name the destination file or directory
224
- # basename in the sandbox path (default: `component.to_s`)
225
- # @api private
226
- def prepare(component, opts = {})
227
- opts = { :type => :directory }.merge(opts)
228
- key_name = opts.fetch(:key_name, "#{component}_path")
229
- src = config[key_name.to_sym]
230
- return if src.nil?
231
-
232
- info("Preparing #{component}")
233
- debug("Using #{component} from #{src}")
234
-
235
- dest = File.join(sandbox_path, opts.fetch(:dest_name, component.to_s))
236
-
237
- case opts[:type]
238
- when :directory
239
- FileUtils.mkdir_p(dest)
240
- FileUtils.cp_r(Dir.glob("#{src}/*"), dest)
241
- when :file
242
- FileUtils.mkdir_p(File.dirname(dest))
243
- FileUtils.cp_r(src, dest)
244
- end
245
- end
246
-
247
- # Prepares a Chef JSON file, sometimes called a dna.json or
248
- # first-boot.json, for inclusion in the sandbox path.
249
- #
250
- # @api private
251
- def prepare_json
252
- dna = config[:attributes].merge(:run_list => config[:run_list])
253
-
254
- info("Preparing dna.json")
255
- debug("Creating dna.json from #{dna.inspect}")
256
-
257
- File.open(File.join(sandbox_path, "dna.json"), "wb") do |file|
258
- file.write(dna.to_json)
259
- end
260
- end
261
-
262
- # Prepares a cache directory for inclusion in the sandbox path.
196
+ # Generates a rendered client.rb/solo.rb/knife.rb formatted file as a
197
+ # String.
263
198
  #
199
+ # @param data [Hash] a key/value pair hash of configuration
200
+ # @return [String] a rendered Chef config file as a String
264
201
  # @api private
265
- def prepare_cache
266
- FileUtils.mkdir_p(File.join(sandbox_path, "cache"))
202
+ def format_config_file(data)
203
+ data.each.map { |attr, value|
204
+ [attr, format_value(value)].join(" ")
205
+ }.join("\n")
267
206
  end
268
207
 
269
- # Prepares Chef cookbooks for inclusion in the sandbox path.
208
+ # Converts a Ruby object to a String interpretation suitable for writing
209
+ # out to a client.rb/solo.rb/knife.rb file.
270
210
  #
211
+ # @param obj [Object] an object
212
+ # @return [String] a string representation
271
213
  # @api private
272
- def prepare_cookbooks
273
- if File.exist?(berksfile)
274
- resolve_with_berkshelf
275
- elsif File.exist?(cheffile)
276
- resolve_with_librarian
277
- cp_site_cookbooks if File.directory?(site_cookbooks_dir)
278
- elsif File.directory?(cookbooks_dir)
279
- cp_cookbooks
280
- elsif File.exist?(metadata_rb)
281
- cp_this_cookbook
214
+ def format_value(obj)
215
+ if obj.is_a?(String)
216
+ %{"#{obj.gsub(/\\/, "\\\\\\\\")}"}
217
+ elsif obj.is_a?(Array)
218
+ %{[#{obj.map { |i| format_value(i) }.join(", ")}]}
282
219
  else
283
- make_fake_cookbook
220
+ obj.inspect
284
221
  end
285
-
286
- filter_only_cookbook_files
287
222
  end
288
223
 
289
- # Removes all non-cookbook files in the sandbox path.
224
+ # Generates the init command variables for Bourne shell-based platforms.
290
225
  #
226
+ # @param dirs [Array<String>] directories
227
+ # @return [String] shell variable lines
291
228
  # @api private
292
- def filter_only_cookbook_files
293
- info("Removing non-cookbook files before transfer")
294
- FileUtils.rm(all_files_in_cookbooks - only_cookbook_files)
229
+ def init_command_vars_for_bourne(dirs)
230
+ [
231
+ shell_var("sudo_rm", sudo("rm")),
232
+ shell_var("dirs", dirs.join(" ")),
233
+ shell_var("root_path", config[:root_path])
234
+ ].join("\n")
295
235
  end
296
236
 
297
- # Generates a list of all files in the cookbooks directory in the
298
- # sandbox path.
237
+ # Generates the init command variables for PowerShell-based platforms.
299
238
  #
300
- # @return [Array<String>] an array of absolute paths to files
239
+ # @param dirs [Array<String>] directories
240
+ # @return [String] shell variable lines
301
241
  # @api private
302
- def all_files_in_cookbooks
303
- Dir.glob(File.join(tmpbooks_dir, "**/*"), File::FNM_DOTMATCH).
304
- select { |fn| File.file?(fn) && ! %w[. ..].include?(fn) }
242
+ def init_command_vars_for_powershell(dirs)
243
+ [
244
+ %{$dirs = @(#{dirs.map { |d| %{"#{d}"} }.join(", ")})},
245
+ shell_var("root_path", config[:root_path])
246
+ ].join("\n")
305
247
  end
306
248
 
307
- # Generates a list of all typical cookbook files needed in a Chef run,
308
- # located in the cookbooks directory in the sandbox path.
249
+ # Generates the install command variables for Bourne shell-based
250
+ # platforms.
309
251
  #
310
- # @return [Array<String>] an array of absolute paths to files
311
- # @api private
312
- def only_cookbook_files
313
- glob = File.join(tmpbooks_dir, "*", "{#{config[:cookbook_files_glob]}}")
314
-
315
- Dir.glob(glob, File::FNM_DOTMATCH).
316
- select { |fn| File.file?(fn) && ! %w[. ..].include?(fn) }
317
- end
318
-
319
- # @return [String] an absolute path to a Berksfile, relative to the
320
- # kitchen root
321
- # @api private
322
- def berksfile
323
- File.join(config[:kitchen_root], "Berksfile")
324
- end
325
-
326
- # @return [String] an absolute path to a Cheffile, relative to the
327
- # kitchen root
252
+ # @param version [String] version string
253
+ # @return [String] shell variable lines
328
254
  # @api private
329
- def cheffile
330
- File.join(config[:kitchen_root], "Cheffile")
331
- end
332
-
333
- # @return [String] an absolute path to a metadata.rb, relative to the
334
- # kitchen root
335
- # @api private
336
- def metadata_rb
337
- File.join(config[:kitchen_root], "metadata.rb")
338
- end
339
-
340
- # @return [String] an absolute path to a cookbooks/ directory, relative
341
- # to the kitchen root
342
- # @api private
343
- def cookbooks_dir
344
- File.join(config[:kitchen_root], "cookbooks")
345
- end
346
-
347
- # @return [String] an absolute path to a site-cookbooks/ directory,
348
- # relative to the kitchen root
349
- # @api private
350
- def site_cookbooks_dir
351
- File.join(config[:kitchen_root], "site-cookbooks")
352
- end
353
-
354
- # @return [String] an absolute path to a cookbooks/ directory in the
355
- # sandbox path
356
- # @api private
357
- def tmpbooks_dir
358
- File.join(sandbox_path, "cookbooks")
359
- end
360
-
361
- # @return [String] an absolute path to a site cookbooks directory in the
362
- # sandbox path
363
- # @api private
364
- def tmpsitebooks_dir
365
- File.join(sandbox_path, "cookbooks")
366
- end
367
-
368
- # Copies a cookbooks/ directory into the sandbox path.
369
- def cp_cookbooks
370
- info("Preparing cookbooks from project directory")
371
- debug("Using cookbooks from #{cookbooks_dir}")
372
-
373
- FileUtils.mkdir_p(tmpbooks_dir)
374
- FileUtils.cp_r(File.join(cookbooks_dir, "."), tmpbooks_dir)
255
+ def install_command_vars_for_bourne(version)
256
+ install_flags = %w[latest true].include?(version) ? "" : "-v #{version}"
257
+ if config[:chef_omnibus_install_options]
258
+ install_flags << " " << config[:chef_omnibus_install_options]
259
+ end
375
260
 
376
- cp_site_cookbooks if File.directory?(site_cookbooks_dir)
377
- cp_this_cookbook if File.exist?(metadata_rb)
261
+ [
262
+ shell_var("chef_omnibus_root", config[:chef_omnibus_root]),
263
+ shell_var("chef_omnibus_url", config[:chef_omnibus_url]),
264
+ shell_var("install_flags", install_flags.strip),
265
+ shell_var("pretty_version", pretty_version(version)),
266
+ shell_var("sudo_sh", sudo("sh")),
267
+ shell_var("version", version)
268
+ ].join("\n")
378
269
  end
379
270
 
380
- # Copies a site-cookbooks/ directory into the sandbox path.
271
+ # Generates the install command variables for PowerShell-based platforms.
381
272
  #
273
+ # @param version [String] version string
274
+ # @return [String] shell variable lines
382
275
  # @api private
383
- def cp_site_cookbooks
384
- info("Preparing site-cookbooks from project directory")
385
- debug("Using cookbooks from #{site_cookbooks_dir}")
386
-
387
- FileUtils.mkdir_p(tmpsitebooks_dir)
388
- FileUtils.cp_r(File.join(site_cookbooks_dir, "."), tmpsitebooks_dir)
276
+ def install_command_vars_for_powershell(version)
277
+ [
278
+ shell_var("chef_metadata_url", config[:chef_metadata_url]),
279
+ shell_var("chef_omnibus_root", config[:chef_omnibus_root]),
280
+ shell_var("msi", "$env:TEMP\\chef-#{version}.msi"),
281
+ shell_var("pretty_version", pretty_version(version)),
282
+ shell_var("version", version)
283
+ ].join("\n")
389
284
  end
390
285
 
391
- # Copies the current project, assumed to be a Chef cookbook into the
392
- # sandbox path.
286
+ # Load cookbook dependency resolver code, if required.
393
287
  #
394
- # @api private
395
- def cp_this_cookbook
396
- info("Preparing current project directory as a cookbook")
397
- debug("Using metadata.rb from #{metadata_rb}")
398
-
399
- cb_name = MetadataChopper.extract(metadata_rb).first || raise(UserError,
400
- "The metadata.rb does not define the 'name' key." \
401
- " Please add: `name '<cookbook_name>'` to metadata.rb and retry")
402
-
403
- cb_path = File.join(tmpbooks_dir, cb_name)
404
-
405
- glob = Dir.glob("#{config[:kitchen_root]}/**")
406
-
407
- FileUtils.mkdir_p(cb_path)
408
- FileUtils.cp_r(glob, cb_path)
288
+ # (see Base#load_needed_dependencies!)
289
+ def load_needed_dependencies!
290
+ super
291
+ if File.exist?(berksfile)
292
+ debug("Berksfile found at #{berksfile}, loading Berkshelf")
293
+ Chef::Berkshelf.load!(logger)
294
+ elsif File.exist?(cheffile)
295
+ debug("Cheffile found at #{cheffile}, loading Librarian-Chef")
296
+ Chef::Librarian.load!(logger)
297
+ end
409
298
  end
410
299
 
411
- # Creates a minimal, no-op cookbook in the sandbox path.
412
- #
300
+ # @return the correct Chef Omnitruck API metadata endpoint, based on
301
+ # project type which could live in
302
+ # `config[:chef_omnibus_install_options]`
413
303
  # @api private
414
- def make_fake_cookbook
415
- info("Berksfile, Cheffile, cookbooks/, or metadata.rb not found " \
416
- "so Chef will run with effectively no cookbooks. Is this intended?")
417
- name = File.basename(config[:kitchen_root])
418
- fake_cb = File.join(tmpbooks_dir, name)
419
- FileUtils.mkdir_p(fake_cb)
420
- File.open(File.join(fake_cb, "metadata.rb"), "wb") do |file|
421
- file.write(%{name "#{name}"\n})
304
+ def metadata_project_from_options
305
+ match = /\s*-P (\w+)\s*/.match(config[:chef_omnibus_install_options])
306
+
307
+ if match.nil? || match[1].downcase == "chef"
308
+ "metadata"
309
+ else
310
+ "metadata-#{match[1].downcase}"
422
311
  end
423
312
  end
424
313
 
425
- # Performs a Berkshelf cookbook resolution inside a common mutex.
426
- #
314
+ # @return [String] a pretty/helpful representation of a Chef Omnibus
315
+ # package version
427
316
  # @api private
428
- def resolve_with_berkshelf
429
- Kitchen.mutex.synchronize do
430
- Chef::Berkshelf.new(berksfile, tmpbooks_dir, logger).resolve
317
+ def pretty_version(version)
318
+ case version
319
+ when "true" then "install only if missing"
320
+ when "latest" then "always install latest version"
321
+ else version
431
322
  end
432
323
  end
433
324
 
434
- # Performs a Librarin-Chef cookbook resolution inside a common mutex.
435
- #
325
+ # @return [String] a powershell command to reload the `PATH` environment
326
+ # variable, only to be used to support old Omnibus Chef packages that
327
+ # require `PATH` to find the `ruby.exe` binary
436
328
  # @api private
437
- def resolve_with_librarian
438
- Kitchen.mutex.synchronize do
439
- Chef::Librarian.new(cheffile, tmpbooks_dir, logger).resolve
440
- end
329
+ def reload_ps1_path
330
+ [
331
+ %{$env:PATH},
332
+ %{[System.Environment]::GetEnvironmentVariable("PATH","Machine")\n\n}
333
+ ].join(" = ")
441
334
  end
442
335
  end
443
336
  end