chef 12.5.1 → 12.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -1
  3. data/README.md +6 -4
  4. data/Rakefile +1 -4
  5. data/chef-windows.gemspec +21 -0
  6. data/chef.gemspec +58 -0
  7. data/lib/chef/api_client/registration.rb +9 -4
  8. data/lib/chef/application.rb +3 -84
  9. data/lib/chef/application/apply.rb +9 -2
  10. data/lib/chef/application/client.rb +8 -3
  11. data/lib/chef/application/solo.rb +7 -1
  12. data/lib/chef/application/windows_service.rb +21 -6
  13. data/lib/chef/application/windows_service_manager.rb +2 -3
  14. data/lib/chef/audit/runner.rb +1 -0
  15. data/lib/chef/chef_class.rb +1 -11
  16. data/lib/chef/chef_fs/chef_fs_data_store.rb +181 -2
  17. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +5 -0
  18. data/lib/chef/chef_fs/file_system/file_system_entry.rb +11 -7
  19. data/lib/chef/client.rb +28 -1
  20. data/lib/chef/cookbook/cookbook_collection.rb +14 -1
  21. data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
  22. data/lib/chef/cookbook/metadata.rb +115 -9
  23. data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
  24. data/lib/chef/cookbook_version.rb +6 -2
  25. data/lib/chef/data_bag.rb +1 -1
  26. data/lib/chef/data_bag_item.rb +1 -1
  27. data/lib/chef/digester.rb +5 -1
  28. data/lib/chef/dsl/chef_provisioning.rb +57 -0
  29. data/lib/chef/dsl/cheffish.rb +64 -0
  30. data/lib/chef/dsl/declare_resource.rb +108 -0
  31. data/lib/chef/dsl/platform_introspection.rb +3 -3
  32. data/lib/chef/dsl/recipe.rb +3 -73
  33. data/lib/chef/dsl/resources.rb +27 -1
  34. data/lib/chef/event_dispatch/base.rb +3 -0
  35. data/lib/chef/event_dispatch/dispatcher.rb +5 -0
  36. data/lib/chef/event_dispatch/events_output_stream.rb +8 -0
  37. data/lib/chef/exceptions.rb +21 -1
  38. data/lib/chef/file_access_control/unix.rb +12 -12
  39. data/lib/chef/file_content_management/deploy/cp.rb +2 -2
  40. data/lib/chef/file_content_management/deploy/mv_unix.rb +4 -4
  41. data/lib/chef/file_content_management/deploy/mv_windows.rb +1 -1
  42. data/lib/chef/formatters/base.rb +7 -0
  43. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
  44. data/lib/chef/formatters/indentable_output_stream.rb +5 -0
  45. data/lib/chef/http.rb +19 -3
  46. data/lib/chef/http/decompressor.rb +2 -2
  47. data/lib/chef/json_compat.rb +1 -0
  48. data/lib/chef/knife.rb +16 -2
  49. data/lib/chef/knife/bootstrap.rb +55 -10
  50. data/lib/chef/knife/cookbook_site_install.rb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +2 -1
  52. data/lib/chef/knife/core/node_presenter.rb +1 -1
  53. data/lib/chef/knife/ssh.rb +30 -16
  54. data/lib/chef/knife/ssl_check.rb +4 -2
  55. data/lib/chef/knife/ssl_fetch.rb +3 -2
  56. data/lib/chef/knife/status.rb +14 -1
  57. data/lib/chef/log.rb +14 -0
  58. data/lib/chef/mixin/get_source_from_package.rb +7 -2
  59. data/lib/chef/mixin/properties.rb +302 -0
  60. data/lib/chef/mixin/proxified_socket.rb +38 -0
  61. data/lib/chef/mixin/subclass_directive.rb +37 -0
  62. data/lib/chef/node.rb +13 -5
  63. data/lib/chef/platform/query_helpers.rb +14 -3
  64. data/lib/chef/platform/service_helpers.rb +20 -38
  65. data/lib/chef/policy_builder/expand_node_object.rb +3 -0
  66. data/lib/chef/policy_builder/policyfile.rb +1 -0
  67. data/lib/chef/property.rb +51 -12
  68. data/lib/chef/provider.rb +40 -35
  69. data/lib/chef/provider/deploy.rb +1 -1
  70. data/lib/chef/provider/dsc_resource.rb +54 -20
  71. data/lib/chef/provider/execute.rb +25 -4
  72. data/lib/chef/provider/group.rb +1 -1
  73. data/lib/chef/provider/lwrp_base.rb +1 -0
  74. data/lib/chef/provider/package.rb +76 -30
  75. data/lib/chef/provider/package/dpkg.rb +152 -69
  76. data/lib/chef/provider/package/openbsd.rb +6 -8
  77. data/lib/chef/provider/package/solaris.rb +2 -0
  78. data/lib/chef/provider/package/windows.rb +95 -14
  79. data/lib/chef/provider/package/windows/exe.rb +129 -0
  80. data/lib/chef/provider/package/windows/msi.rb +37 -13
  81. data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +89 -0
  82. data/lib/chef/provider/package/yum.rb +13 -3
  83. data/lib/chef/provider/powershell_script.rb +3 -0
  84. data/lib/chef/provider/remote_file/cache_control_data.rb +37 -4
  85. data/lib/chef/provider/remote_file/http.rb +1 -1
  86. data/lib/chef/provider/script.rb +1 -0
  87. data/lib/chef/provider/service.rb +13 -10
  88. data/lib/chef/provider/service/solaris.rb +43 -17
  89. data/lib/chef/provider/service/upstart.rb +3 -3
  90. data/lib/chef/provider/user.rb +1 -1
  91. data/lib/chef/provider/user/dscl.rb +111 -100
  92. data/lib/chef/provider/user/windows.rb +5 -3
  93. data/lib/chef/recipe.rb +3 -5
  94. data/lib/chef/resource.rb +77 -320
  95. data/lib/chef/resource/action_class.rb +4 -0
  96. data/lib/chef/resource/dpkg_package.rb +4 -3
  97. data/lib/chef/resource/dsc_resource.rb +40 -2
  98. data/lib/chef/resource/execute.rb +9 -1
  99. data/lib/chef/resource/ksh.rb +32 -0
  100. data/lib/chef/resource/lwrp_base.rb +6 -10
  101. data/lib/chef/resource/package.rb +8 -9
  102. data/lib/chef/resource/registry_key.rb +1 -1
  103. data/lib/chef/resource/resource_notification.rb +14 -1
  104. data/lib/chef/resource/script.rb +1 -1
  105. data/lib/chef/resource/windows_package.rb +1 -1
  106. data/lib/chef/resource_builder.rb +14 -7
  107. data/lib/chef/resource_reporter.rb +6 -0
  108. data/lib/chef/resources.rb +1 -7
  109. data/lib/chef/rest.rb +1 -1
  110. data/lib/chef/run_context.rb +45 -2
  111. data/lib/chef/run_list/run_list_expansion.rb +47 -0
  112. data/lib/chef/runner.rb +25 -0
  113. data/lib/chef/search/query.rb +16 -2
  114. data/lib/chef/util/diff.rb +2 -2
  115. data/lib/chef/util/powershell/ps_credential.rb +2 -3
  116. data/lib/chef/version.rb +1 -1
  117. data/lib/chef/win32/api/file.rb +51 -1
  118. data/lib/chef/win32/file.rb +5 -0
  119. data/lib/chef/win32/file/version_info.rb +93 -0
  120. data/lib/chef/win32/mutex.rb +1 -1
  121. data/spec/data/apt/chef-integration-test2-1.0/debian/changelog +5 -0
  122. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.debhelper.log +45 -0
  123. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.substvars +1 -0
  124. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/conffiles +1 -0
  125. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/control +10 -0
  126. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/md5sums +1 -0
  127. data/spec/data/apt/chef-integration-test2-1.0/debian/compat +1 -0
  128. data/spec/data/apt/chef-integration-test2-1.0/debian/conffiles +1 -0
  129. data/spec/data/apt/chef-integration-test2-1.0/debian/control +13 -0
  130. data/spec/data/apt/chef-integration-test2-1.0/debian/copyright +34 -0
  131. data/spec/data/apt/chef-integration-test2-1.0/debian/files +1 -0
  132. data/spec/data/apt/chef-integration-test2-1.0/debian/rules +13 -0
  133. data/spec/data/apt/chef-integration-test2-1.0/debian/source/format +1 -0
  134. data/spec/data/apt/chef-integration-test2_1.0-1.debian.tar.gz +0 -0
  135. data/spec/data/apt/chef-integration-test2_1.0-1.dsc +18 -0
  136. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.build +91 -0
  137. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.changes +31 -0
  138. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.deb +0 -0
  139. data/spec/data/apt/chef-integration-test2_1.0.orig.tar.gz +0 -0
  140. data/spec/functional/application_spec.rb +1 -1
  141. data/spec/functional/audit/runner_spec.rb +4 -0
  142. data/spec/functional/knife/ssh_spec.rb +5 -5
  143. data/spec/functional/notifications_spec.rb +74 -4
  144. data/spec/functional/resource/aix_service_spec.rb +2 -2
  145. data/spec/functional/resource/dpkg_package_spec.rb +339 -0
  146. data/spec/functional/resource/ifconfig_spec.rb +3 -1
  147. data/spec/functional/resource/mount_spec.rb +5 -2
  148. data/spec/functional/resource/package_spec.rb +1 -1
  149. data/spec/functional/resource/user/windows_spec.rb +8 -0
  150. data/spec/functional/resource/windows_package_spec.rb +177 -0
  151. data/spec/functional/win32/version_info_spec.rb +50 -0
  152. data/spec/integration/client/client_spec.rb +80 -0
  153. data/spec/integration/knife/download_spec.rb +9 -0
  154. data/spec/integration/knife/upload_spec.rb +28 -1
  155. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +93 -23
  156. data/spec/integration/recipes/resource_action_spec.rb +211 -116
  157. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +72 -0
  158. data/spec/integration/solo/solo_spec.rb +34 -0
  159. data/spec/spec_helper.rb +11 -1
  160. data/spec/support/platform_helpers.rb +8 -0
  161. data/spec/support/shared/integration/integration_helper.rb +6 -0
  162. data/spec/support/shared/unit/execute_resource.rb +5 -0
  163. data/spec/support/shared/unit/platform_introspector.rb +7 -0
  164. data/spec/tiny_server.rb +6 -2
  165. data/spec/unit/api_client/registration_spec.rb +5 -4
  166. data/spec/unit/application_spec.rb +1 -181
  167. data/spec/unit/chef_fs/file_system/cookbook_subdir_spec.rb +34 -0
  168. data/spec/unit/cookbook/metadata_spec.rb +122 -2
  169. data/spec/unit/http_spec.rb +102 -0
  170. data/spec/unit/knife/bootstrap_spec.rb +55 -13
  171. data/spec/unit/knife/core/bootstrap_context_spec.rb +10 -3
  172. data/spec/unit/knife/ssl_check_spec.rb +7 -3
  173. data/spec/unit/knife/ssl_fetch_spec.rb +2 -2
  174. data/spec/unit/knife/status_spec.rb +13 -13
  175. data/spec/unit/knife_spec.rb +26 -2
  176. data/spec/unit/lwrp_spec.rb +1 -1
  177. data/spec/unit/mixin/properties_spec.rb +97 -0
  178. data/spec/unit/mixin/proxified_socket_spec.rb +94 -0
  179. data/spec/unit/mixin/subclass_directive_spec.rb +45 -0
  180. data/spec/unit/node_spec.rb +9 -1
  181. data/spec/unit/policy_builder/policyfile_spec.rb +2 -0
  182. data/spec/unit/property/validation_spec.rb +14 -12
  183. data/spec/unit/property_spec.rb +56 -0
  184. data/spec/unit/provider/deploy_spec.rb +1 -1
  185. data/spec/unit/provider/dsc_resource_spec.rb +63 -24
  186. data/spec/unit/provider/execute_spec.rb +95 -28
  187. data/spec/unit/provider/package/dpkg_spec.rb +185 -96
  188. data/spec/unit/provider/package/windows/exe_spec.rb +251 -0
  189. data/spec/unit/provider/package/windows/msi_spec.rb +94 -10
  190. data/spec/unit/provider/package/windows_spec.rb +227 -26
  191. data/spec/unit/provider/package/yum_spec.rb +6 -0
  192. data/spec/unit/provider/package_spec.rb +495 -366
  193. data/spec/unit/provider/remote_file/cache_control_data_spec.rb +62 -36
  194. data/spec/unit/provider/script_spec.rb +2 -2
  195. data/spec/unit/provider/service/solaris_smf_service_spec.rb +110 -39
  196. data/spec/unit/provider/service/upstart_service_spec.rb +19 -0
  197. data/spec/unit/provider/user/dscl_spec.rb +14 -0
  198. data/spec/unit/provider/user/windows_spec.rb +2 -2
  199. data/spec/unit/provider/user_spec.rb +9 -0
  200. data/spec/unit/provider_resolver_spec.rb +6 -30
  201. data/spec/unit/recipe_spec.rb +46 -20
  202. data/spec/unit/resource/chef_gem_spec.rb +1 -1
  203. data/spec/unit/resource/dsc_resource_spec.rb +14 -3
  204. data/spec/unit/resource/ksh_spec.rb +40 -0
  205. data/spec/unit/resource/registry_key_spec.rb +2 -2
  206. data/spec/unit/resource/resource_notification_spec.rb +44 -45
  207. data/spec/unit/resource_reporter_spec.rb +7 -0
  208. data/spec/unit/resource_spec.rb +268 -253
  209. data/spec/unit/rest_spec.rb +2 -2
  210. data/spec/unit/run_list/run_list_expansion_spec.rb +18 -3
  211. data/spec/unit/search/query_spec.rb +19 -1
  212. data/spec/unit/util/powershell/ps_credential_spec.rb +8 -1
  213. data/spec/unit/windows_service_spec.rb +83 -38
  214. data/tasks/external_tests.rb +19 -9
  215. data/tasks/rspec.rb +1 -1
  216. metadata +64 -15
  217. data/spec/support/pedant/Gemfile +0 -3
  218. data/spec/support/pedant/pedant_config.rb +0 -129
  219. data/spec/support/pedant/run_pedant.rb +0 -63
  220. data/spec/support/pedant/stickywicket.pem +0 -27
  221. data/spec/unit/provider/package_spec.rbe +0 -0
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Seth Falcon (<seth@opscode.com>)
4
- # Copyright:: Copyright 2008-2010 Opscode, Inc.
4
+ # Copyright:: Copyright 2008-2015 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,7 +30,7 @@ describe Chef::Cookbook::Metadata do
30
30
  :maintainer_email, :license, :platforms, :dependencies,
31
31
  :recommendations, :suggestions, :conflicting, :providing,
32
32
  :replacing, :attributes, :groupings, :recipes, :version,
33
- :source_url, :issues_url, :privacy ]
33
+ :source_url, :issues_url, :privacy, :ohai_versions, :chef_versions ]
34
34
  end
35
35
 
36
36
  it "does not depend on object identity for equality" do
@@ -326,6 +326,110 @@ describe Chef::Cookbook::Metadata do
326
326
  end
327
327
  end
328
328
 
329
+ describe "chef_version" do
330
+ def expect_chef_version_works(*args)
331
+ ret = []
332
+ args.each do |arg|
333
+ metadata.send(:chef_version, *arg)
334
+ ret << Gem::Dependency.new("chef", *arg)
335
+ end
336
+ expect(metadata.send(:chef_versions)).to eql(ret)
337
+ end
338
+
339
+ it "should work with a single simple constraint" do
340
+ expect_chef_version_works(["~> 12"])
341
+ end
342
+
343
+ it "should work with a single complex constraint" do
344
+ expect_chef_version_works([">= 12.0.1", "< 12.5.1"])
345
+ end
346
+
347
+ it "should work with multiple simple constraints" do
348
+ expect_chef_version_works(["~> 12.5.1"],["~> 11.18.10"])
349
+ end
350
+
351
+ it "should work with multiple complex constraints" do
352
+ expect_chef_version_works([">= 11.14.2", "< 11.18.10"],[">= 12.2.1", "< 12.5.1"])
353
+ end
354
+
355
+ it "should fail validation on a simple pessimistic constraint" do
356
+ expect_chef_version_works(["~> 999.0"])
357
+ expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch)
358
+ end
359
+
360
+ it "should fail validation when that valid chef versions are too big" do
361
+ expect_chef_version_works([">= 999.0", "< 999.9"])
362
+ expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch)
363
+ end
364
+
365
+ it "should fail validation when that valid chef versions are too small" do
366
+ expect_chef_version_works([">= 0.0.1", "< 0.0.9"])
367
+ expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch)
368
+ end
369
+
370
+ it "should fail validation when all ranges fail" do
371
+ expect_chef_version_works([">= 999.0", "< 999.9"],[">= 0.0.1", "< 0.0.9"])
372
+ expect { metadata.validate_chef_version! }.to raise_error(Chef::Exceptions::CookbookChefVersionMismatch)
373
+ end
374
+
375
+ it "should pass validation when one constraint passes" do
376
+ expect_chef_version_works([">= 999.0", "< 999.9"],["= #{Chef::VERSION}"])
377
+ expect { metadata.validate_chef_version! }.not_to raise_error
378
+ end
379
+ end
380
+
381
+ describe "ohai_version" do
382
+ def expect_ohai_version_works(*args)
383
+ ret = []
384
+ args.each do |arg|
385
+ metadata.send(:ohai_version, *arg)
386
+ ret << Gem::Dependency.new("ohai", *arg)
387
+ end
388
+ expect(metadata.send(:ohai_versions)).to eql(ret)
389
+ end
390
+
391
+ it "should work with a single simple constraint" do
392
+ expect_ohai_version_works(["~> 12"])
393
+ end
394
+
395
+ it "should work with a single complex constraint" do
396
+ expect_ohai_version_works([">= 12.0.1", "< 12.5.1"])
397
+ end
398
+
399
+ it "should work with multiple simple constraints" do
400
+ expect_ohai_version_works(["~> 12.5.1"],["~> 11.18.10"])
401
+ end
402
+
403
+ it "should work with multiple complex constraints" do
404
+ expect_ohai_version_works([">= 11.14.2", "< 11.18.10"],[">= 12.2.1", "< 12.5.1"])
405
+ end
406
+
407
+ it "should fail validation on a simple pessimistic constraint" do
408
+ expect_ohai_version_works(["~> 999.0"])
409
+ expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch)
410
+ end
411
+
412
+ it "should fail validation when that valid chef versions are too big" do
413
+ expect_ohai_version_works([">= 999.0", "< 999.9"])
414
+ expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch)
415
+ end
416
+
417
+ it "should fail validation when that valid chef versions are too small" do
418
+ expect_ohai_version_works([">= 0.0.1", "< 0.0.9"])
419
+ expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch)
420
+ end
421
+
422
+ it "should fail validation when all ranges fail" do
423
+ expect_ohai_version_works([">= 999.0", "< 999.9"],[">= 0.0.1", "< 0.0.9"])
424
+ expect { metadata.validate_ohai_version! }.to raise_error(Chef::Exceptions::CookbookOhaiVersionMismatch)
425
+ end
426
+
427
+ it "should pass validation when one constraint passes" do
428
+ expect_ohai_version_works([">= 999.0", "< 999.9"],["= #{Ohai::VERSION}"])
429
+ expect { metadata.validate_ohai_version! }.not_to raise_error
430
+ end
431
+ end
432
+
329
433
  describe "attribute groupings" do
330
434
  it "should allow you set a grouping" do
331
435
  group = {
@@ -684,9 +788,14 @@ describe Chef::Cookbook::Metadata do
684
788
  metadata.attribute "bizspark/has_login",
685
789
  :display_name => "You have nothing"
686
790
  metadata.version "1.2.3"
791
+ metadata.chef_version ">= 11.14.2", "< 11.18.10"
792
+ metadata.chef_version ">= 12.2.1", "< 12.5.1"
793
+ metadata.ohai_version ">= 7.1.0", "< 7.5.0"
794
+ metadata.ohai_version ">= 8.0.1", "< 8.6.0"
687
795
  end
688
796
 
689
797
  it "should produce the same output from to_json and Chef::JSONCompat" do
798
+ # XXX: fairly certain this is testing ruby method dispatch
690
799
  expect(metadata.to_json).to eq(Chef::JSONCompat.to_json(metadata))
691
800
  end
692
801
 
@@ -723,6 +832,15 @@ describe Chef::Cookbook::Metadata do
723
832
  expect(deserialized_metadata[t]).to eq(metadata.send(t.to_sym))
724
833
  end
725
834
  end
835
+
836
+ %w{
837
+ ohai_versions
838
+ chef_versions
839
+ }.each do |t|
840
+ it "should include '#{t}'" do
841
+ expect(deserialized_metadata[t]).to eq(metadata.gem_requirements_to_array(*metadata.send(t.to_sym)))
842
+ end
843
+ end
726
844
  end
727
845
 
728
846
  describe "deserialize" do
@@ -754,6 +872,8 @@ describe Chef::Cookbook::Metadata do
754
872
  source_url
755
873
  issues_url
756
874
  privacy
875
+ chef_versions
876
+ ohai_versions
757
877
  }.each do |t|
758
878
  it "should match '#{t}'" do
759
879
  expect(deserialized_metadata.send(t.to_sym)).to eq(metadata.send(t.to_sym))
@@ -89,4 +89,106 @@ describe Chef::HTTP do
89
89
 
90
90
  end # head
91
91
 
92
+ describe "retrying connection errors" do
93
+
94
+ let(:uri) { "https://chef.example/organizations/default/" }
95
+
96
+ subject(:http) { Chef::HTTP.new(uri) }
97
+
98
+ # http#http_client gets stubbed later, so eager create
99
+ let!(:low_level_client) { http.http_client(URI(uri)) }
100
+
101
+ let(:http_ok_response) do
102
+ Net::HTTPOK.new("1.1", 200, "OK").tap do |r|
103
+ allow(r).to receive(:read_body).and_return("")
104
+ end
105
+ end
106
+
107
+ before do
108
+ allow(http).to receive(:http_client).with(URI(uri)).and_return(low_level_client)
109
+ end
110
+
111
+ shared_examples_for "retriable_request_errors" do
112
+
113
+ before do
114
+ expect(low_level_client).to receive(:request).exactly(5).times.and_raise(exception)
115
+ expect(http).to receive(:sleep).exactly(5).times.and_return(1)
116
+ expect(low_level_client).to receive(:request).and_return([low_level_client, http_ok_response])
117
+ end
118
+
119
+ it "retries the request 5 times" do
120
+ http.get('/')
121
+ end
122
+
123
+ end
124
+
125
+ shared_examples_for "errors_that_are_not_retried" do
126
+
127
+ before do
128
+ expect(low_level_client).to receive(:request).exactly(1).times.and_raise(exception)
129
+ expect(http).to_not receive(:sleep)
130
+ end
131
+
132
+ it "raises the error without retrying or sleeping" do
133
+ # We modify the strings to give addtional context, but the exception class should be the same
134
+ expect { http.get("/") }.to raise_error(exception.class)
135
+ end
136
+ end
137
+
138
+ context "when ECONNRESET is raised" do
139
+
140
+ let(:exception) { Errno::ECONNRESET.new("example error") }
141
+
142
+ include_examples "retriable_request_errors"
143
+
144
+ end
145
+
146
+ context "when SocketError is raised" do
147
+
148
+ let(:exception) { SocketError.new("example error") }
149
+
150
+ include_examples "retriable_request_errors"
151
+
152
+ end
153
+
154
+ context "when ETIMEDOUT is raised" do
155
+
156
+ let(:exception) { Errno::ETIMEDOUT.new("example error") }
157
+
158
+ include_examples "retriable_request_errors"
159
+
160
+ end
161
+
162
+ context "when ECONNREFUSED is raised" do
163
+
164
+ let(:exception) { Errno::ECONNREFUSED.new("example error") }
165
+
166
+ include_examples "retriable_request_errors"
167
+
168
+ end
169
+
170
+ context "when Timeout::Error is raised" do
171
+
172
+ let(:exception) { Timeout::Error.new("example error") }
173
+
174
+ include_examples "retriable_request_errors"
175
+
176
+ end
177
+
178
+ context "when OpenSSL::SSL::SSLError is raised" do
179
+
180
+ let(:exception) { OpenSSL::SSL::SSLError.new("example error") }
181
+
182
+ include_examples "retriable_request_errors"
183
+
184
+ end
185
+
186
+ context "when OpenSSL::SSL::SSLError is raised for certificate validation failure" do
187
+
188
+ let(:exception) { OpenSSL::SSL::SSLError.new("ssl_connect returned=1 errno=0 state=sslv3 read server certificate b: certificate verify failed") }
189
+
190
+ include_examples "errors_that_are_not_retried"
191
+
192
+ end
193
+ end
92
194
  end
@@ -235,12 +235,39 @@ describe Chef::Knife::Bootstrap do
235
235
  expect(knife.render_template).to eq('{"run_list":["role[base]","recipe[cupcakes]"]}')
236
236
  end
237
237
 
238
- it "should have foo => {bar => baz} in the first_boot" do
239
- knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
240
- knife.merge_configs
241
- expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
242
- actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
243
- expect(actual_hash).to eq(expected_hash)
238
+ context "with bootstrap_attribute options" do
239
+ let(:jsonfile) {
240
+ file = Tempfile.new (['node', '.json'])
241
+ File.open(file.path, "w") {|f| f.puts '{"foo":{"bar":"baz"}}' }
242
+ file
243
+ }
244
+
245
+ it "should have foo => {bar => baz} in the first_boot from cli" do
246
+ knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
247
+ knife.merge_configs
248
+ expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
249
+ actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
250
+ expect(actual_hash).to eq(expected_hash)
251
+ end
252
+
253
+ it "should have foo => {bar => baz} in the first_boot from file" do
254
+ knife.parse_options(["--json-attribute-file", jsonfile.path])
255
+ knife.merge_configs
256
+ expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
257
+ actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
258
+ expect(actual_hash).to eq(expected_hash)
259
+ jsonfile.close
260
+ end
261
+
262
+ context "when --json-attributes and --json-attribute-file were both passed" do
263
+ it "raises a Chef::Exceptions::BootstrapCommandInputError with the proper error message" do
264
+ knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
265
+ knife.parse_options(["--json-attribute-file", jsonfile.path])
266
+ knife.merge_configs
267
+ expect{ knife.run }.to raise_error(Chef::Exceptions::BootstrapCommandInputError)
268
+ jsonfile.close
269
+ end
270
+ end
244
271
  end
245
272
  end
246
273
 
@@ -445,6 +472,21 @@ describe Chef::Knife::Bootstrap do
445
472
 
446
473
  end
447
474
 
475
+ # https://github.com/chef/chef/issues/4131
476
+ # Arguably a bug in the plugin: it shouldn't be setting this to nil, but it
477
+ # worked before, so make it work now.
478
+ context "when a plugin sets the run list option to nil" do
479
+
480
+ before do
481
+ knife.config[:run_list] = nil
482
+ end
483
+
484
+ it "passes options validation" do
485
+ expect { knife.validate_options! }.to_not raise_error
486
+ end
487
+
488
+ end
489
+
448
490
  end
449
491
 
450
492
  describe "when configuring the underlying knife ssh command" do
@@ -457,7 +499,7 @@ describe Chef::Knife::Bootstrap do
457
499
  Chef::Config[:knife][:ssh_user] = nil
458
500
  Chef::Config[:knife][:ssh_port] = nil
459
501
  knife.config[:forward_agent] = true
460
- knife.config[:identity_file] = "~/.ssh/me.rsa"
502
+ knife.config[:ssh_identity_file] = "~/.ssh/me.rsa"
461
503
  allow(knife).to receive(:render_template).and_return("")
462
504
  knife.knife_ssh
463
505
  end
@@ -483,7 +525,7 @@ describe Chef::Knife::Bootstrap do
483
525
  end
484
526
 
485
527
  it "configures the ssh identity file" do
486
- expect(knife_ssh.config[:identity_file]).to eq('~/.ssh/me.rsa')
528
+ expect(knife_ssh.config[:ssh_identity_file]).to eq('~/.ssh/me.rsa')
487
529
  end
488
530
  end
489
531
 
@@ -518,7 +560,7 @@ describe Chef::Knife::Bootstrap do
518
560
  Chef::Config[:knife][:ssh_user] = "curiosity"
519
561
  Chef::Config[:knife][:ssh_port] = "2430"
520
562
  Chef::Config[:knife][:forward_agent] = true
521
- Chef::Config[:knife][:identity_file] = "~/.ssh/you.rsa"
563
+ Chef::Config[:knife][:ssh_identity_file] = "~/.ssh/you.rsa"
522
564
  Chef::Config[:knife][:ssh_gateway] = "towel.blinkenlights.nl"
523
565
  Chef::Config[:knife][:host_key_verify] = true
524
566
  allow(knife).to receive(:render_template).and_return("")
@@ -540,7 +582,7 @@ describe Chef::Knife::Bootstrap do
540
582
  end
541
583
 
542
584
  it "configures the ssh identity file" do
543
- expect(knife_ssh.config[:identity_file]).to eq('~/.ssh/you.rsa')
585
+ expect(knife_ssh.config[:ssh_identity_file]).to eq('~/.ssh/you.rsa')
544
586
  end
545
587
 
546
588
  it "configures the ssh gateway" do
@@ -556,7 +598,7 @@ describe Chef::Knife::Bootstrap do
556
598
  let(:knife_ssh_with_password_auth) do
557
599
  knife.name_args = ["foo.example.com"]
558
600
  knife.config[:ssh_user] = "rooty"
559
- knife.config[:identity_file] = "~/.ssh/me.rsa"
601
+ knife.config[:ssh_identity_file] = "~/.ssh/me.rsa"
560
602
  allow(knife).to receive(:render_template).and_return("")
561
603
  k = knife.knife_ssh
562
604
  allow(k).to receive(:get_password).and_return('typed_in_password')
@@ -569,7 +611,7 @@ describe Chef::Knife::Bootstrap do
569
611
  end
570
612
 
571
613
  it "configures knife not to use the identity file that didn't work previously" do
572
- expect(knife_ssh_with_password_auth.config[:identity_file]).to be_nil
614
+ expect(knife_ssh_with_password_auth.config[:ssh_identity_file]).to be_nil
573
615
  end
574
616
  end
575
617
  end
@@ -585,7 +627,7 @@ describe Chef::Knife::Bootstrap do
585
627
  knife.name_args = ["foo.example.com"]
586
628
  knife.config[:chef_node_name] = "foo.example.com"
587
629
  knife.config[:ssh_user] = "rooty"
588
- knife.config[:identity_file] = "~/.ssh/me.rsa"
630
+ knife.config[:ssh_identity_file] = "~/.ssh/me.rsa"
589
631
  allow(knife).to receive(:render_template).and_return("")
590
632
  knife_ssh = knife.knife_ssh
591
633
  allow(knife).to receive(:knife_ssh).and_return(knife_ssh)
@@ -20,7 +20,7 @@ require 'spec_helper'
20
20
  require 'chef/knife/core/bootstrap_context'
21
21
 
22
22
  describe Chef::Knife::Core::BootstrapContext do
23
- let(:config) { {:foo => :bar} }
23
+ let(:config) { {:foo => :bar, :color => true} }
24
24
  let(:run_list) { Chef::RunList.new('recipe[tmux]', 'role[base]') }
25
25
  let(:chef_config) do
26
26
  {
@@ -43,12 +43,19 @@ describe Chef::Knife::Core::BootstrapContext do
43
43
  end
44
44
 
45
45
  describe "when in verbosity mode" do
46
- let(:config) { {:verbosity => 2} }
46
+ let(:config) { {:verbosity => 2, :color => true} }
47
47
  it "adds '-l debug' when verbosity is >= 2" do
48
48
  expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json -l debug"
49
49
  end
50
50
  end
51
51
 
52
+ describe "when no color value has been set in config" do
53
+ let(:config) { {:color => false } }
54
+ it "adds '--no-color' when color is false" do
55
+ expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json --no-color"
56
+ end
57
+ end
58
+
52
59
  it "reads the validation key" do
53
60
  expect(bootstrap_context.validation_key).to eq IO.read(File.join(CHEF_SPEC_DATA, 'ssl', 'private_key.pem'))
54
61
  end
@@ -91,7 +98,7 @@ EXPECTED
91
98
  end
92
99
 
93
100
  describe "when bootstrapping into a specific environment" do
94
- let(:chef_config){ {:environment => "prodtastic"} }
101
+ let(:config){ {:environment => "prodtastic", :color => true} }
95
102
  it "starts chef in the configured environment" do
96
103
  expect(bootstrap_context.start_chef).to eq('chef-client -j /etc/chef/first-boot.json -E prodtastic')
97
104
  end
@@ -145,7 +145,7 @@ E
145
145
  let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket) }
146
146
 
147
147
  before do
148
- expect(TCPSocket).to receive(:new).with("foo.example.com", 8443).and_return(tcp_socket)
148
+ expect(ssl_check).to receive(:proxified_socket).with("foo.example.com", 8443).and_return(tcp_socket)
149
149
  expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_check.verify_peer_ssl_context).and_return(ssl_socket)
150
150
  end
151
151
 
@@ -181,9 +181,9 @@ E
181
181
  let(:self_signed_crt) { OpenSSL::X509::Certificate.new(File.read(self_signed_crt_path)) }
182
182
 
183
183
  before do
184
- trap(:INT, "DEFAULT")
184
+ @old_signal = trap(:INT, "DEFAULT")
185
185
 
186
- expect(TCPSocket).to receive(:new).
186
+ expect(ssl_check).to receive(:proxified_socket).
187
187
  with("foo.example.com", 8443).
188
188
  and_return(tcp_socket_for_debug)
189
189
  expect(OpenSSL::SSL::SSLSocket).to receive(:new).
@@ -191,6 +191,10 @@ E
191
191
  and_return(ssl_socket_for_debug)
192
192
  end
193
193
 
194
+ after do
195
+ trap(:INT, @old_signal)
196
+ end
197
+
194
198
  context "when the certificate's CN does not match the hostname" do
195
199
  before do
196
200
  expect(ssl_check).to receive(:verify_X509).and_return(true) # X509 valid certs