chef 15.11.3-universal-mingw32 → 15.15.0-universal-mingw32

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.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -9
  3. data/README.md +3 -3
  4. data/chef-universal-mingw32.gemspec +2 -2
  5. data/chef.gemspec +12 -3
  6. data/distro/powershell/chef/chef.psm1 +3 -3
  7. data/distro/templates/powershell/chef/chef.psm1.erb +3 -3
  8. data/lib/chef/api_client/registration.rb +2 -2
  9. data/lib/chef/application/apply.rb +1 -1
  10. data/lib/chef/chef_fs/file_system/repository/base_file.rb +1 -0
  11. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_dir.rb +2 -2
  12. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb +1 -1
  13. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +2 -2
  14. data/lib/chef/chef_fs/file_system/repository/directory.rb +1 -1
  15. data/lib/chef/chef_fs/file_system/repository/file_system_entry.rb +1 -1
  16. data/lib/chef/chef_fs/path_utils.rb +3 -3
  17. data/lib/chef/cookbook/file_system_file_vendor.rb +1 -1
  18. data/lib/chef/data_bag.rb +2 -2
  19. data/lib/chef/data_collector/error_handlers.rb +1 -1
  20. data/lib/chef/deprecated.rb +12 -0
  21. data/lib/chef/dsl/declare_resource.rb +1 -1
  22. data/lib/chef/dsl/platform_introspection.rb +2 -0
  23. data/lib/chef/environment.rb +2 -2
  24. data/lib/chef/exceptions.rb +3 -0
  25. data/lib/chef/http.rb +2 -1
  26. data/lib/chef/knife/bootstrap.rb +8 -10
  27. data/lib/chef/knife/bootstrap/templates/chef-full.erb +9 -9
  28. data/lib/chef/knife/bootstrap/train_connector.rb +1 -0
  29. data/lib/chef/knife/cookbook_download.rb +1 -1
  30. data/lib/chef/knife/cookbook_metadata.rb +1 -1
  31. data/lib/chef/knife/core/gem_glob_loader.rb +1 -1
  32. data/lib/chef/knife/core/hashed_command_loader.rb +3 -2
  33. data/lib/chef/knife/core/subcommand_loader.rb +1 -1
  34. data/lib/chef/knife/exec.rb +2 -2
  35. data/lib/chef/knife/ssh.rb +20 -1
  36. data/lib/chef/log.rb +1 -1
  37. data/lib/chef/mixin/openssl_helper.rb +26 -3
  38. data/lib/chef/mixin/template.rb +1 -0
  39. data/lib/chef/node_map.rb +5 -2
  40. data/lib/chef/provider/mount/solaris.rb +0 -1
  41. data/lib/chef/provider/package/cab.rb +1 -1
  42. data/lib/chef/provider/package/chocolatey.rb +1 -1
  43. data/lib/chef/provider/package/msu.rb +1 -0
  44. data/lib/chef/provider/package/powershell.rb +5 -1
  45. data/lib/chef/provider/package/snap.rb +96 -27
  46. data/lib/chef/provider/package/zypper.rb +0 -1
  47. data/lib/chef/provider/service/arch.rb +2 -2
  48. data/lib/chef/provider/service/debian.rb +1 -1
  49. data/lib/chef/provider/service/gentoo.rb +2 -2
  50. data/lib/chef/provider/service/macosx.rb +2 -2
  51. data/lib/chef/provider/service/openbsd.rb +1 -1
  52. data/lib/chef/provider/service/redhat.rb +2 -2
  53. data/lib/chef/provider/service/upstart.rb +1 -1
  54. data/lib/chef/provider/yum_repository.rb +1 -1
  55. data/lib/chef/provider/zypper_repository.rb +31 -11
  56. data/lib/chef/resource.rb +2 -0
  57. data/lib/chef/resource/archive_file.rb +28 -8
  58. data/lib/chef/resource/cron_access.rb +13 -5
  59. data/lib/chef/resource/cron_d.rb +2 -1
  60. data/lib/chef/resource/homebrew_cask.rb +3 -3
  61. data/lib/chef/resource/hostname.rb +19 -18
  62. data/lib/chef/resource/locale.rb +1 -1
  63. data/lib/chef/resource/lwrp_base.rb +7 -0
  64. data/lib/chef/resource/msu_package.rb +5 -0
  65. data/lib/chef/resource/ssh_known_hosts_entry.rb +1 -1
  66. data/lib/chef/resource/sudo.rb +2 -2
  67. data/lib/chef/resource/windows_feature_powershell.rb +6 -2
  68. data/lib/chef/resource/windows_font.rb +2 -1
  69. data/lib/chef/role.rb +2 -2
  70. data/lib/chef/shell.rb +1 -1
  71. data/lib/chef/shell/shell_session.rb +2 -0
  72. data/lib/chef/util/diff.rb +1 -1
  73. data/lib/chef/util/powershell/cmdlet.rb +1 -1
  74. data/lib/chef/version.rb +2 -2
  75. data/lib/chef/win32/file.rb +2 -2
  76. data/spec/functional/knife/ssh_spec.rb +4 -4
  77. data/spec/functional/resource/aix_service_spec.rb +0 -1
  78. data/spec/functional/resource/aixinit_service_spec.rb +7 -8
  79. data/spec/functional/resource/apt_package_spec.rb +0 -1
  80. data/spec/functional/resource/bff_spec.rb +2 -2
  81. data/spec/functional/resource/cookbook_file_spec.rb +1 -1
  82. data/spec/functional/resource/cron_spec.rb +0 -1
  83. data/spec/functional/resource/dsc_resource_spec.rb +1 -1
  84. data/spec/functional/resource/insserv_spec.rb +4 -5
  85. data/spec/functional/resource/link_spec.rb +17 -17
  86. data/spec/functional/resource/msu_package_spec.rb +5 -2
  87. data/spec/functional/resource/rpm_spec.rb +2 -2
  88. data/spec/functional/resource/user/dscl_spec.rb +1 -1
  89. data/spec/functional/resource/user/mac_user_spec.rb +1 -1
  90. data/spec/functional/resource/windows_certificate_spec.rb +3 -3
  91. data/spec/functional/resource/windows_font_spec.rb +49 -0
  92. data/spec/functional/resource/windows_task_spec.rb +8 -8
  93. data/spec/functional/run_lock_spec.rb +2 -1
  94. data/spec/functional/shell_spec.rb +5 -5
  95. data/spec/functional/util/powershell/cmdlet_spec.rb +1 -1
  96. data/spec/functional/version_spec.rb +1 -1
  97. data/spec/functional/win32/service_manager_spec.rb +1 -1
  98. data/spec/integration/recipes/accumulator_spec.rb +1 -1
  99. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +2 -2
  100. data/spec/integration/recipes/lwrp_spec.rb +1 -1
  101. data/spec/integration/recipes/notifies_spec.rb +1 -1
  102. data/spec/integration/recipes/notifying_block_spec.rb +1 -1
  103. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -1
  104. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +2 -0
  105. data/spec/integration/recipes/resource_load_spec.rb +1 -0
  106. data/spec/integration/recipes/unified_mode_spec.rb +1 -1
  107. data/spec/scripts/ssl-serve.rb +1 -1
  108. data/spec/spec_helper.rb +26 -8
  109. data/spec/support/chef_helpers.rb +1 -1
  110. data/spec/support/platform_helpers.rb +12 -42
  111. data/spec/support/platforms/win32/spec_service.rb +1 -1
  112. data/spec/support/shared/functional/directory_resource.rb +1 -1
  113. data/spec/support/shared/functional/execute_resource.rb +1 -1
  114. data/spec/support/shared/functional/file_resource.rb +2 -2
  115. data/spec/support/shared/functional/win32_service.rb +1 -1
  116. data/spec/support/shared/functional/windows_script.rb +3 -3
  117. data/spec/support/shared/integration/knife_support.rb +2 -5
  118. data/spec/unit/application_spec.rb +7 -0
  119. data/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb +2 -4
  120. data/spec/unit/cookbook/gem_installer_spec.rb +2 -1
  121. data/spec/unit/data_bag_spec.rb +1 -1
  122. data/spec/unit/data_collector_spec.rb +1 -1
  123. data/spec/unit/dsl/platform_introspection_spec.rb +1 -0
  124. data/spec/unit/environment_spec.rb +7 -7
  125. data/spec/unit/event_dispatch/dispatcher_spec.rb +3 -0
  126. data/spec/unit/file_access_control_spec.rb +1 -1
  127. data/spec/unit/json_compat_spec.rb +1 -1
  128. data/spec/unit/knife/bootstrap_spec.rb +16 -16
  129. data/spec/unit/knife/cookbook_download_spec.rb +4 -4
  130. data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +1 -1
  131. data/spec/unit/knife/cookbook_upload_spec.rb +5 -6
  132. data/spec/unit/knife/core/hashed_command_loader_spec.rb +3 -3
  133. data/spec/unit/knife/ssh_spec.rb +2 -2
  134. data/spec/unit/knife/supermarket_share_spec.rb +1 -1
  135. data/spec/unit/lwrp_spec.rb +4 -4
  136. data/spec/unit/mixin/securable_spec.rb +0 -1
  137. data/spec/unit/mixin/user_context_spec.rb +1 -9
  138. data/spec/unit/property_spec.rb +6 -6
  139. data/spec/unit/provider/apt_repository_spec.rb +2 -2
  140. data/spec/unit/provider/package/dnf/python_helper_spec.rb +1 -1
  141. data/spec/unit/provider/package/powershell_spec.rb +95 -86
  142. data/spec/unit/provider/package/rubygems_spec.rb +5 -10
  143. data/spec/unit/provider/package/snap_spec.rb +1 -1
  144. data/spec/unit/provider/package/windows_spec.rb +30 -53
  145. data/spec/unit/provider/service/arch_service_spec.rb +3 -2
  146. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  147. data/spec/unit/provider/service/gentoo_service_spec.rb +7 -7
  148. data/spec/unit/provider/service/macosx_spec.rb +3 -3
  149. data/spec/unit/provider/service/redhat_spec.rb +2 -2
  150. data/spec/unit/provider/service/upstart_service_spec.rb +3 -3
  151. data/spec/unit/provider/service/windows_spec.rb +2 -6
  152. data/spec/unit/provider/systemd_unit_spec.rb +28 -24
  153. data/spec/unit/provider/zypper_repository_spec.rb +75 -25
  154. data/spec/unit/provider_spec.rb +1 -0
  155. data/spec/unit/resource/archive_file_spec.rb +11 -2
  156. data/spec/unit/resource/msu_package_spec.rb +4 -0
  157. data/spec/unit/resource/windows_dns_record_spec.rb +3 -3
  158. data/spec/unit/resource/windows_dns_zone_spec.rb +2 -2
  159. data/spec/unit/resource/windows_feature_powershell_spec.rb +30 -4
  160. data/spec/unit/resource/windows_package_spec.rb +1 -0
  161. data/spec/unit/resource/windows_task_spec.rb +1 -1
  162. data/spec/unit/resource/windows_uac_spec.rb +2 -2
  163. data/spec/unit/resource/yum_repository_spec.rb +21 -21
  164. data/spec/unit/resource_reporter_spec.rb +1 -1
  165. data/spec/unit/resource_spec.rb +1 -1
  166. data/spec/unit/role_spec.rb +11 -11
  167. data/spec/unit/run_context/cookbook_compiler_spec.rb +1 -1
  168. data/spec/unit/run_lock_spec.rb +1 -1
  169. data/spec/unit/scan_access_control_spec.rb +1 -1
  170. data/spec/unit/util/threaded_job_queue_spec.rb +9 -0
  171. data/spec/unit/win32/security_spec.rb +4 -3
  172. data/tasks/rspec.rb +5 -13
  173. metadata +38 -19
@@ -185,50 +185,50 @@ if test "x$tmp_dir" != "x"; then
185
185
  rm -r "$tmp_dir"
186
186
  fi
187
187
 
188
- mkdir -p <%= ChefConfig::Config.etc_chef_dir(false) %>
188
+ mkdir -p /etc/chef
189
189
 
190
190
  <% if client_pem -%>
191
- (umask 077 && (cat > <%= ChefConfig::Config.etc_chef_dir(false) %>/client.pem <<'EOP'
191
+ (umask 077 && (cat > /etc/chef/client.pem <<'EOP'
192
192
  <%= ::File.read(::File.expand_path(client_pem)) %>
193
193
  EOP
194
194
  )) || exit 1
195
195
  <% end -%>
196
196
 
197
197
  <% if validation_key -%>
198
- (umask 077 && (cat > <%= ChefConfig::Config.etc_chef_dir(false) %>/validation.pem <<'EOP'
198
+ (umask 077 && (cat > /etc/chef/validation.pem <<'EOP'
199
199
  <%= validation_key %>
200
200
  EOP
201
201
  )) || exit 1
202
202
  <% end -%>
203
203
 
204
204
  <% if encrypted_data_bag_secret -%>
205
- (umask 077 && (cat > <%= ChefConfig::Config.etc_chef_dir(false) %>/encrypted_data_bag_secret <<'EOP'
205
+ (umask 077 && (cat > /etc/chef/encrypted_data_bag_secret <<'EOP'
206
206
  <%= encrypted_data_bag_secret %>
207
207
  EOP
208
208
  )) || exit 1
209
209
  <% end -%>
210
210
 
211
211
  <% unless trusted_certs.empty? -%>
212
- mkdir -p <%= ChefConfig::Config.etc_chef_dir(false) %>/trusted_certs
212
+ mkdir -p /etc/chef/trusted_certs
213
213
  <%= trusted_certs %>
214
214
  <% end -%>
215
215
 
216
216
  <%# Generate Ohai Hints -%>
217
217
  <% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
218
- mkdir -p <%= ChefConfig::Config.etc_chef_dir(false) %>/ohai/hints
218
+ mkdir -p /etc/chef/ohai/hints
219
219
 
220
220
  <% @chef_config[:knife][:hints].each do |name, hash| -%>
221
- cat > <%= ChefConfig::Config.etc_chef_dir(false) %>/ohai/hints/<%= name %>.json <<'EOP'
221
+ cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
222
222
  <%= Chef::JSONCompat.to_json(hash) %>
223
223
  EOP
224
224
  <% end -%>
225
225
  <% end -%>
226
226
 
227
- cat > <%= ChefConfig::Config.etc_chef_dir(false) %>/client.rb <<'EOP'
227
+ cat > /etc/chef/client.rb <<'EOP'
228
228
  <%= config_content %>
229
229
  EOP
230
230
 
231
- cat > <%= ChefConfig::Config.etc_chef_dir(false) %>/first-boot.json <<'EOP'
231
+ cat > /etc/chef/first-boot.json <<'EOP'
232
232
  <%= Chef::JSONCompat.to_json(first_boot) %>
233
233
  EOP
234
234
 
@@ -322,6 +322,7 @@ class Chef
322
322
 
323
323
  class RemoteExecutionFailed < StandardError
324
324
  attr_reader :exit_status, :command, :hostname, :stdout, :stderr
325
+
325
326
  def initialize(hostname, command, result)
326
327
  @hostname = hostname
327
328
  @exit_status = result.exit_status
@@ -73,7 +73,7 @@ class Chef
73
73
  manifest = cookbook.cookbook_manifest
74
74
 
75
75
  basedir = File.join(config[:download_directory], "#{@cookbook_name}-#{cookbook.version}")
76
- if File.exists?(basedir)
76
+ if File.exist?(basedir)
77
77
  if config[:force]
78
78
  Chef::Log.trace("Deleting #{basedir}")
79
79
  FileUtils.rm_rf(basedir)
@@ -62,7 +62,7 @@ class Chef
62
62
  def generate_metadata(cookbook)
63
63
  Array(config[:cookbook_path]).reverse_each do |path|
64
64
  file = File.expand_path(File.join(path, cookbook, "metadata.rb"))
65
- if File.exists?(file)
65
+ if File.exist?(file)
66
66
  generate_metadata_from_file(cookbook, file)
67
67
  else
68
68
  validate_metadata_json(path, cookbook)
@@ -47,7 +47,7 @@ class Chef
47
47
 
48
48
  def find_subcommands_via_dirglob
49
49
  # The "require paths" of the core knife subcommands bundled with chef
50
- files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../../knife", __FILE__)), "*.rb")]
50
+ files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../knife", __dir__)), "*.rb")]
51
51
  subcommand_files = {}
52
52
  files.each do |knife_file|
53
53
  rel_path = knife_file[/#{CHEF_ROOT}#{Regexp.escape(File::SEPARATOR)}(.*)\.rb/, 1]
@@ -27,6 +27,7 @@ class Chef
27
27
  KEY = "_autogenerated_command_paths".freeze
28
28
 
29
29
  attr_accessor :manifest
30
+
30
31
  def initialize(chef_config_dir, plugin_manifest)
31
32
  super(chef_config_dir)
32
33
  @manifest = plugin_manifest
@@ -52,7 +53,7 @@ class Chef
52
53
  paths = manifest[KEY]["plugins_paths"][command]
53
54
  if paths && paths.is_a?(Array)
54
55
  # It is only an error if all the paths don't exist
55
- if paths.all? { |sc| !File.exists?(sc) }
56
+ if paths.all? { |sc| !File.exist?(sc) }
56
57
  errors[command] = paths
57
58
  end
58
59
  end
@@ -76,7 +77,7 @@ class Chef
76
77
  false
77
78
  else
78
79
  paths.each do |sc|
79
- if File.exists?(sc)
80
+ if File.exist?(sc)
80
81
  Kernel.load sc
81
82
  else
82
83
  return false
@@ -125,7 +125,7 @@ class Chef
125
125
  #
126
126
  def find_subcommands_via_dirglob
127
127
  # The "require paths" of the core knife subcommands bundled with chef
128
- files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../../knife", __FILE__)), "*.rb")]
128
+ files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../knife", __dir__)), "*.rb")]
129
129
  subcommand_files = {}
130
130
  files.each do |knife_file|
131
131
  rel_path = knife_file[/#{CHEF_ROOT}#{Regexp.escape(File::SEPARATOR)}(.*)\.rb/, 1]
@@ -76,7 +76,7 @@ class Chef::Knife::Exec < Chef::Knife
76
76
  def find_script(x)
77
77
  # Try to find a script. First try expanding the path given.
78
78
  script = File.expand_path(x)
79
- return script if File.exists?(script)
79
+ return script if File.exist?(script)
80
80
 
81
81
  # Failing that, try searching the script path. If we can't find
82
82
  # anything, fail gracefully.
@@ -86,7 +86,7 @@ class Chef::Knife::Exec < Chef::Knife
86
86
  path = File.expand_path(path)
87
87
  test = File.join(path, x)
88
88
  Chef::Log.trace("Testing: #{test}")
89
- if File.exists?(test)
89
+ if File.exist?(test)
90
90
  script = test
91
91
  Chef::Log.trace("Found: #{test}")
92
92
  return script
@@ -298,6 +298,10 @@ class Chef
298
298
  opts[:keepalive] = true
299
299
  opts[:keepalive_interval] = ssh_config[:keepalive_interval]
300
300
  end
301
+ # maintain support for legacy key types / ciphers / key exchange algorithms.
302
+ # most importantly this adds back support for DSS host keys
303
+ # See https://github.com/net-ssh/net-ssh/pull/709
304
+ opts[:append_all_supported_algorithms] = true
301
305
  end
302
306
  end
303
307
 
@@ -358,11 +362,21 @@ class Chef
358
362
  subsession ||= session
359
363
  command = fixup_sudo(command)
360
364
  command.force_encoding("binary") if command.respond_to?(:force_encoding)
365
+ begin
366
+ open_session(subsession, command)
367
+ rescue => e
368
+ open_session(subsession, command, true)
369
+ end
370
+ end
371
+
372
+ def open_session(subsession, command, pty = false)
373
+ stderr = ""
374
+ exit_status = 0
361
375
  subsession.open_channel do |chan|
362
376
  if config[:on_error] && exit_status != 0
363
377
  chan.close
364
378
  else
365
- chan.request_pty
379
+ chan.request_pty if pty
366
380
  chan.exec command do |ch, success|
367
381
  raise ArgumentError, "Cannot execute #{command}" unless success
368
382
 
@@ -373,6 +387,11 @@ class Chef
373
387
  ichannel.send_data("#{get_password}\n")
374
388
  end
375
389
  end
390
+
391
+ ch.on_extended_data do |_, _type, data|
392
+ stderr += data
393
+ end
394
+
376
395
  ch.on_request "exit-status" do |ichannel, data|
377
396
  exit_status = [exit_status, data.read_long].max
378
397
  end
@@ -47,7 +47,7 @@ class Chef
47
47
  def self.caller_location
48
48
  # Pick the first caller that is *not* part of the Chef gem, that's the
49
49
  # thing the user wrote. Or failing that, the most recent caller.
50
- chef_gem_path = File.expand_path("../..", __FILE__)
50
+ chef_gem_path = File.expand_path("..", __dir__)
51
51
  caller(0..20).find { |c| !c.start_with?(chef_gem_path) } || caller(0..1)[0]
52
52
  end
53
53
 
@@ -282,7 +282,9 @@ class Chef
282
282
  ef.issuer_certificate = info["issuer"]
283
283
  end
284
284
  ef.subject_certificate = cert
285
- ef.config = ::OpenSSL::Config.load(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
285
+ if openssl_config = __openssl_config
286
+ ef.config = openssl_config
287
+ end
286
288
 
287
289
  cert.extensions = extension
288
290
  cert.add_extension ef.create_extension("subjectKeyIdentifier", "hash")
@@ -313,7 +315,9 @@ class Chef
313
315
  crl.last_update = Time.now
314
316
  crl.next_update = Time.now + 3600 * 24 * info["validity"]
315
317
 
316
- ef.config = ::OpenSSL::Config.load(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
318
+ if openssl_config = __openssl_config
319
+ ef.config = openssl_config
320
+ end
317
321
  ef.issuer_certificate = info["issuer"]
318
322
 
319
323
  crl.add_extension ::OpenSSL::X509::Extension.new("crlNumber", ::OpenSSL::ASN1::Integer(1))
@@ -391,7 +395,9 @@ class Chef
391
395
  crl.next_update = crl.last_update + 3600 * 24 * info["validity"]
392
396
 
393
397
  ef = ::OpenSSL::X509::ExtensionFactory.new
394
- ef.config = ::OpenSSL::Config.load(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
398
+ if openssl_config = __openssl_config
399
+ ef.config = openssl_config
400
+ end
395
401
  ef.issuer_certificate = info["issuer"]
396
402
 
397
403
  crl.extensions = [ ::OpenSSL::X509::Extension.new("crlNumber",
@@ -422,6 +428,23 @@ class Chef
422
428
 
423
429
  resp
424
430
  end
431
+
432
+ private
433
+
434
+ def __openssl_config
435
+ path = if File.exist?(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
436
+ OpenSSL::Config::DEFAULT_CONFIG_FILE
437
+ else
438
+ Dir[File.join(RbConfig::CONFIG["prefix"], "**", "openssl.cnf")].first
439
+ end
440
+
441
+ if File.exist?(path)
442
+ ::OpenSSL::Config.load(path)
443
+ else
444
+ Chef::Log.warn("Couldn't find OpenSSL config file")
445
+ nil
446
+ end
447
+ end
425
448
  end
426
449
  end
427
450
  end
@@ -213,6 +213,7 @@ class Chef
213
213
 
214
214
  class TemplateError < RuntimeError
215
215
  attr_reader :original_exception, :context, :options
216
+
216
217
  SOURCE_CONTEXT_WINDOW = 2
217
218
 
218
219
  def initialize(original_exception, template, context, options)
@@ -35,10 +35,13 @@
35
35
  #
36
36
  # XXX: confusingly, in the *_priority_map the :klass may be an array of Strings of class names
37
37
  #
38
+
39
+ require_relative "dist"
40
+
38
41
  class Chef
39
42
  class NodeMap
40
43
  COLLISION_WARNING = <<~EOH.gsub(/\s+/, " ").strip
41
- %{type_caps} %{key} from the client is overriding the %{type} from a cookbook. Please upgrade your cookbook
44
+ %{type_caps} %{key} built into %{client_name} is being overridden by the %{type} from a cookbook. Please upgrade your cookbook
42
45
  or remove the cookbook from your run_list.
43
46
  EOH
44
47
 
@@ -84,7 +87,7 @@ class Chef
84
87
  else
85
88
  klass.superclass.to_s
86
89
  end
87
- Chef::Log.warn( COLLISION_WARNING % { type: type_of_thing, key: key, type_caps: type_of_thing.capitalize } )
90
+ Chef::Log.warn( COLLISION_WARNING % { type: type_of_thing, key: key, type_caps: type_of_thing.capitalize, client_name: Chef::Dist::PRODUCT } )
88
91
  end
89
92
 
90
93
  # The map is sorted in order of preference already; we just need to find
@@ -1,4 +1,3 @@
1
- # Encoding: utf-8
2
1
  # Author:: Hugo Fichter
3
2
  # Author:: Lamont Granquist (<lamont@chef.io>)
4
3
  # Author:: Joshua Timberman (<joshua@chef.io>)
@@ -94,7 +94,7 @@ class Chef
94
94
  split_package_identity(p["package_identity"])
95
95
  end
96
96
  found_packages = existing_package_identities.select do |existing_package_ident|
97
- existing_package_ident["name"] == package["name"]
97
+ existing_package_ident["version"] == package["version"].chomp && existing_package_ident["name"] == package["name"]
98
98
  end
99
99
  if found_packages.empty?
100
100
  nil
@@ -251,7 +251,7 @@ class Chef
251
251
  end
252
252
 
253
253
  # Helper to convert choco.exe list output to a Hash
254
- # (names are downcased for case-insenstive matching)
254
+ # (names are downcased for case-insensitive matching)
255
255
  #
256
256
  # @param cmd [String] command to run
257
257
  # @return [Hash] list output converted to ruby Hash
@@ -109,6 +109,7 @@ class Chef
109
109
  @cab_files.each do |cab_file|
110
110
  declare_resource(:cab_package, new_resource.name) do
111
111
  source cab_file
112
+ timeout new_resource.timeout
112
113
  action :install
113
114
  end
114
115
  end
@@ -53,6 +53,9 @@ class Chef
53
53
 
54
54
  # Installs the package specified with the version passed else latest version will be installed
55
55
  def install_package(names, versions)
56
+ # To enable tls 1.2, which is disabled by default in some OS
57
+ powershell_out("[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12")
58
+
56
59
  names.each_with_index do |name, index|
57
60
  cmd = powershell_out(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
58
61
  next if cmd.nil?
@@ -115,7 +118,8 @@ class Chef
115
118
  command = [command] unless command.is_a?(Array)
116
119
  cmdlet_name = command.first
117
120
  command.unshift("(")
118
- %w{-Force -ForceBootstrap}.each do |arg|
121
+ # -WarningAction SilentlyContinue is used to suppress the warnings from stdout
122
+ %w{-Force -ForceBootstrap -WarningAction SilentlyContinue}.each do |arg|
119
123
  command.push(arg)
120
124
  end
121
125
  command.push("-RequiredVersion #{version}") if version
@@ -59,15 +59,14 @@ class Chef
59
59
  def get_current_versions
60
60
  package_name_array.each_with_index.map do |pkg, i|
61
61
  installed_version(i)
62
- end
62
+ end.compact
63
63
  end
64
64
 
65
65
  def install_package(names, versions)
66
66
  if new_resource.source
67
67
  install_snap_from_source(names, new_resource.source)
68
68
  else
69
- resolved_names = names.each_with_index.map { |name, i| available_version(i).to_s unless name.nil? }
70
- install_snaps(resolved_names)
69
+ install_snaps(names)
71
70
  end
72
71
  end
73
72
 
@@ -75,14 +74,16 @@ class Chef
75
74
  if new_resource.source
76
75
  install_snap_from_source(names, new_resource.source)
77
76
  else
78
- resolved_names = names.each_with_index.map { |name, i| available_version(i).to_s unless name.nil? }
79
- update_snaps(resolved_names)
77
+ if get_current_versions.empty?
78
+ install_snaps(names, versions)
79
+ else
80
+ update_snaps(names)
81
+ end
80
82
  end
81
83
  end
82
84
 
83
85
  def remove_package(names, versions)
84
- resolved_names = names.each_with_index.map { |name, i| installed_version(i).to_s unless name.nil? }
85
- uninstall_snaps(resolved_names)
86
+ uninstall_snaps(names)
86
87
  end
87
88
 
88
89
  alias purge_package remove_package
@@ -129,19 +130,73 @@ class Chef
129
130
  "Accept: application/json\r\n" +
130
131
  "Content-Type: application/json\r\n"
131
132
  if method == "POST"
132
- request.concat("Content-Length: #{post_data.bytesize}\r\n\r\n#{post_data}")
133
+ pdata = post_data.to_json.to_s
134
+ request.concat("Content-Length: #{pdata.bytesize}\r\n\r\n#{pdata}")
133
135
  end
134
136
  request.concat("\r\n")
135
- # While it is expected to allow clients to connect using HTTPS over a TCP socket,
136
- # at this point only a UNIX socket is supported. The socket is /run/snapd.socket
137
- # Note - UNIXSocket is not defined on windows systems
137
+
138
+ # while it is expected to allow clients to connect using https over
139
+ # a tcp socket, at this point only a unix socket is supported. the
140
+ # socket is /run/snapd.socket note - unixsocket is not defined on
141
+ # windows systems
138
142
  if defined?(::UNIXSocket)
139
143
  UNIXSocket.open("/run/snapd.socket") do |socket|
140
- # Send request, read the response, split the response and parse the body
141
- socket.print(request)
142
- response = socket.read
143
- headers, body = response.split("\r\n\r\n", 2)
144
- JSON.parse(body)
144
+ # send request, read the response, split the response and parse
145
+ # the body
146
+ socket.write(request)
147
+
148
+ # WARNING!!! HERE BE DRAGONs
149
+ #
150
+ # So snapd doesn't return an EOF at the end of its body, so
151
+ # doing a normal read will just hang forever.
152
+ #
153
+ # Well, sort of. if, after it writes everything, you then send
154
+ # yet-another newline, it'll then send its EOF and promptly
155
+ # disconnect closing the pipe and preventing reading. so, you
156
+ # have to read first, and therein lies the EOF problem.
157
+ #
158
+ # So you can do non-blocking reads with selects, but it
159
+ # makes every read take about 5 seconds. If, instead, we
160
+ # read the last line char-by-char, it's about half a second.
161
+ #
162
+ # Reading a character at a time isn't efficient, and since we
163
+ # know that http headers always have a blank line after them,
164
+ # we can read lines until we find a blank line and *then* read
165
+ # a character at a time. snap returns all the json on a single
166
+ # line, so once you pass headers you must read a character a
167
+ # time.
168
+ #
169
+ # - jaymzh
170
+
171
+ Chef::Log.trace(
172
+ "snap_package[#{new_resource.package_name}]: reading headers"
173
+ )
174
+ loop do
175
+ response = socket.readline
176
+ break if response.strip.empty? # finished headers
177
+ end
178
+ Chef::Log.trace(
179
+ "snap_package[#{new_resource.package_name}]: past headers, " +
180
+ "onto the body..."
181
+ )
182
+ result = nil
183
+ body = ""
184
+ socket.each_char do |c|
185
+ body << c
186
+ # we know we're not done if we don't have a char that
187
+ # can end JSON
188
+ next unless ["}", "]"].include?(c)
189
+
190
+ begin
191
+ result = JSON.parse(body)
192
+ # if we get here, we were able to parse the json so we
193
+ # are done reading
194
+ break
195
+ rescue JSON::ParserError
196
+ next
197
+ end
198
+ end
199
+ result
145
200
  end
146
201
  end
147
202
  end
@@ -211,20 +266,22 @@ class Chef
211
266
  response.error!
212
267
  end
213
268
 
214
- def install_snaps(snap_names)
215
- response = post_snaps(snap_names, "install", new_resource.channel, new_resource.options)
216
- id = get_id_from_async_response(response)
217
- wait_for_completion(id)
269
+ def install_snaps(snap_names, versions)
270
+ snap_names.each do |snap|
271
+ response = post_snap(snap, "install", new_resource.channel, new_resource.options)
272
+ id = get_id_from_async_response(response)
273
+ wait_for_completion(id)
274
+ end
218
275
  end
219
276
 
220
277
  def update_snaps(snap_names)
221
- response = post_snaps(snap_names, "refresh", new_resource.channel, new_resource.options)
278
+ response = post_snaps(snap_names, "refresh", nil, new_resource.options)
222
279
  id = get_id_from_async_response(response)
223
280
  wait_for_completion(id)
224
281
  end
225
282
 
226
283
  def uninstall_snaps(snap_names)
227
- response = post_snaps(snap_names, "remove", new_resource.channel, new_resource.options)
284
+ response = post_snaps(snap_names, "remove", nil, new_resource.options)
228
285
  id = get_id_from_async_response(response)
229
286
  wait_for_completion(id)
230
287
  end
@@ -278,18 +335,20 @@ class Chef
278
335
  "action" => action,
279
336
  "snaps" => snap_names,
280
337
  }
281
- if %w{install refresh switch}.include?(action)
338
+ if %w{install refresh switch}.include?(action) && channel
282
339
  request["channel"] = channel
283
340
  end
284
341
 
285
342
  # No defensive handling of params
286
343
  # Snap will throw the proper exception if called improperly
287
344
  # And we can provide that exception to the end user
288
- request["classic"] = true if options["classic"]
289
- request["devmode"] = true if options["devmode"]
290
- request["jailmode"] = true if options["jailmode"]
345
+ if options
346
+ request["classic"] = true if options.include?("classic")
347
+ request["devmode"] = true if options.include?("devmode")
348
+ request["jailmode"] = true if options.include?("jailmode")
349
+ request["ignore_validation"] = true if options.include?("ignore-validation")
350
+ end
291
351
  request["revision"] = revision unless revision.nil?
292
- request["ignore_validation"] = true if options["ignore-validation"]
293
352
  request
294
353
  end
295
354
 
@@ -305,12 +364,22 @@ class Chef
305
364
  call_snap_api("POST", "/v2/snaps", json)
306
365
  end
307
366
 
367
+ def post_snap(snap_name, action, channel, options, revision = nil)
368
+ json = generate_snap_json(snap_name, action, channel, options, revision = nil)
369
+ json.delete("snaps")
370
+ call_snap_api("POST", "/v2/snaps/#{snap_name}", json)
371
+ end
372
+
308
373
  def get_latest_package_version(name, channel)
309
374
  json = call_snap_api("GET", "/v2/find?name=#{name}")
310
375
  if json["status-code"] != 200
311
376
  raise Chef::Exceptions::Package, json["result"], caller
312
377
  end
313
378
 
379
+ unless json["result"][0]["channels"]["latest/#{channel}"]
380
+ raise Chef::Exceptions::Package, "No version of #{name} in channel #{channel}", caller
381
+ end
382
+
314
383
  # Return the version matching the channel
315
384
  json["result"][0]["channels"]["latest/#{channel}"]["version"]
316
385
  end