chef 15.10.12 → 15.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -3
  3. data/Rakefile +1 -1
  4. data/lib/chef/application/apply.rb +1 -1
  5. data/lib/chef/application/exit_code.rb +2 -2
  6. data/lib/chef/chef_fs/chef_fs_data_store.rb +3 -3
  7. data/lib/chef/chef_fs/file_system/chef_server/policies_dir.rb +1 -1
  8. data/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb +1 -1
  9. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +1 -1
  10. data/lib/chef/cookbook_version.rb +4 -4
  11. data/lib/chef/deprecated.rb +1 -1
  12. data/lib/chef/dsl/platform_introspection.rb +1 -1
  13. data/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb +2 -2
  14. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +7 -7
  15. data/lib/chef/knife.rb +26 -20
  16. data/lib/chef/knife/bootstrap.rb +22 -21
  17. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +12 -8
  18. data/lib/chef/knife/bootstrap/client_builder.rb +23 -19
  19. data/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb +3 -1
  20. data/lib/chef/knife/cookbook_site_search.rb +1 -1
  21. data/lib/chef/knife/cookbook_site_show.rb +1 -1
  22. data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
  23. data/lib/chef/knife/core/windows_bootstrap_context.rb +18 -3
  24. data/lib/chef/knife/ssh.rb +1 -1
  25. data/lib/chef/mixin/create_path.rb +8 -8
  26. data/lib/chef/node/mixin/deep_merge_cache.rb +7 -7
  27. data/lib/chef/provider/package/chocolatey.rb +3 -2
  28. data/lib/chef/provider/service/simple.rb +3 -3
  29. data/lib/chef/provider/windows_task.rb +1 -1
  30. data/lib/chef/resource/build_essential.rb +1 -1
  31. data/lib/chef/resource/launchd.rb +4 -4
  32. data/lib/chef/resource/macos_userdefaults.rb +3 -3
  33. data/lib/chef/resource/windows_firewall_rule.rb +8 -4
  34. data/lib/chef/resource/windows_share.rb +4 -4
  35. data/lib/chef/resource/windows_task.rb +13 -13
  36. data/lib/chef/resource_inspector.rb +4 -3
  37. data/lib/chef/util/dsc/lcm_output_parser.rb +3 -3
  38. data/lib/chef/version.rb +1 -1
  39. data/lib/chef/win32/api/command_line_helper.rb +89 -0
  40. data/lib/chef/win32/api/file.rb +18 -18
  41. data/lib/chef/win32/file.rb +1 -1
  42. data/lib/chef/win32/process.rb +2 -2
  43. data/spec/functional/resource/chocolatey_package_spec.rb +29 -0
  44. data/spec/functional/resource/user/dscl_spec.rb +1 -1
  45. data/spec/functional/resource/user/mac_user_spec.rb +1 -1
  46. data/spec/spec_helper.rb +0 -11
  47. data/spec/support/shared/functional/file_resource.rb +1 -1
  48. data/spec/unit/knife/bootstrap_spec.rb +10 -13
  49. data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +6 -0
  50. data/spec/unit/knife/role_env_run_list_add_spec.rb +6 -6
  51. data/spec/unit/knife/role_env_run_list_clear_spec.rb +4 -4
  52. data/spec/unit/knife/role_env_run_list_remove_spec.rb +4 -4
  53. data/spec/unit/knife/role_env_run_list_replace_spec.rb +4 -4
  54. data/spec/unit/knife/role_env_run_list_set_spec.rb +4 -4
  55. data/spec/unit/knife/role_run_list_add_spec.rb +6 -6
  56. data/spec/unit/knife/role_run_list_clear_spec.rb +4 -4
  57. data/spec/unit/knife/role_run_list_remove_spec.rb +4 -4
  58. data/spec/unit/knife/role_run_list_replace_spec.rb +4 -4
  59. data/spec/unit/knife/role_run_list_set_spec.rb +4 -4
  60. data/spec/unit/provider/git_spec.rb +3 -3
  61. data/spec/unit/provider/osx_profile_spec.rb +2 -2
  62. data/spec/unit/provider/package/chocolatey_spec.rb +1 -1
  63. data/spec/unit/provider/package/msu_spec.rb +3 -3
  64. data/spec/unit/provider/service/gentoo_service_spec.rb +1 -1
  65. data/spec/unit/provider_resolver_spec.rb +9 -9
  66. data/spec/unit/run_context_spec.rb +1 -1
  67. metadata +7 -6
@@ -202,10 +202,12 @@ If !ERRORLEVEL!==0 (
202
202
  ) else (
203
203
  @echo Installation completed successfully
204
204
  del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
205
- )
205
+ )
206
206
 
207
207
  <% end %>
208
208
 
209
+ @rem This line is required to separate the key_create label from the "block boundary"
210
+ @rem Removing these lines will cause the error "The system cannot find the batch label specified - key_create"
209
211
  :key_create
210
212
  @endlocal
211
213
 
@@ -24,7 +24,7 @@ class Chef
24
24
  class Knife
25
25
  class CookbookSiteSearch < Knife::SupermarketSearch
26
26
 
27
- # Handle the subclassing (knife doesn't do this :()
27
+ # Handle the subclassing (knife doesn't do this :()
28
28
  dependency_loaders.concat(superclass.dependency_loaders)
29
29
 
30
30
  banner "knife cookbook site search QUERY (options)"
@@ -24,7 +24,7 @@ class Chef
24
24
  class Knife
25
25
  class CookbookSiteShow < Knife::SupermarketShow
26
26
 
27
- # Handle the subclassing (knife doesn't do this :()
27
+ # Handle the subclassing (knife doesn't do this :()
28
28
  dependency_loaders.concat(superclass.dependency_loaders)
29
29
 
30
30
  banner "knife cookbook site show COOKBOOK [VERSION] (options)"
@@ -25,7 +25,7 @@ class Chef
25
25
  class Knife
26
26
  class CookbookSiteUnshare < Knife::SupermarketUnshare
27
27
 
28
- # Handle the subclassing (knife doesn't do this :()
28
+ # Handle the subclassing (knife doesn't do this :()
29
29
  dependency_loaders.concat(superclass.dependency_loaders)
30
30
 
31
31
  banner "knife cookbook site unshare COOKBOOK (options)"
@@ -39,6 +39,21 @@ class Chef
39
39
  super(config, run_list, chef_config, secret)
40
40
  end
41
41
 
42
+ # This is a duplicate of ChefConfig::PathHelper.cleanpath, however
43
+ # this presumes Windows so we can avoid changing the method definitions
44
+ # across Chef, ChefConfig, and ChefUtils for the circumstance where
45
+ # the methods are being run for a system other than the one Ruby is
46
+ # executing on.
47
+ #
48
+ # We only need to cleanpath the paths that we are passing to cmd.exe,
49
+ # anything written to a configuration file or passed as an argument
50
+ # will be interpreted by ruby later and do the right thing.
51
+ def cleanpath(path)
52
+ path = Pathname.new(path).cleanpath.to_s
53
+ path = path.gsub(File::SEPARATOR, '\\')
54
+ path
55
+ end
56
+
42
57
  def validation_key
43
58
  if File.exist?(File.expand_path(@chef_config[:validation_key]))
44
59
  IO.read(File.expand_path(@chef_config[:validation_key]))
@@ -158,8 +173,8 @@ class Chef
158
173
 
159
174
  def start_chef
160
175
  bootstrap_environment_option = bootstrap_environment.nil? ? "" : " -E #{bootstrap_environment}"
161
- start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;#{ChefConfig::Config.c_opscode_dir}\\#{ChefConfig::Dist::DIR_SUFFIX}\\bin;#{ChefConfig::Config.c_opscode_dir}\\#{ChefConfig::Dist::DIR_SUFFIX}\\embedded\\bin\;%PATH%\"\n"
162
- start_chef << "chef-client -c #{ChefConfig::Config.etc_chef_dir(true)}/client.rb -j #{ChefConfig::Config.etc_chef_dir(true)}/first-boot.json#{bootstrap_environment_option}\n"
176
+ start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;#{ChefConfig::Config.c_opscode_dir}\\bin;#{ChefConfig::Config.c_opscode_dir}\\embedded\\bin\;%PATH%\"\n"
177
+ start_chef << "#{Chef::Dist::CLIENT} -c #{ChefConfig::Config.etc_chef_dir(true)}/client.rb -j #{ChefConfig::Config.etc_chef_dir(true)}/first-boot.json#{bootstrap_environment_option}\n"
163
178
  end
164
179
 
165
180
  def win_wget
@@ -260,7 +275,7 @@ class Chef
260
275
  end
261
276
 
262
277
  def bootstrap_directory
263
- ChefConfig::Config.etc_chef_dir(true)
278
+ cleanpath(ChefConfig::Config.etc_chef_dir(true))
264
279
  end
265
280
 
266
281
  def local_download_path
@@ -547,7 +547,7 @@ class Chef
547
547
  end
548
548
 
549
549
  def get_stripped_unfrozen_value(value)
550
- return nil if value.nil?
550
+ return nil unless value
551
551
 
552
552
  value.strip
553
553
  end
@@ -53,14 +53,14 @@ class Chef
53
53
  private
54
54
 
55
55
  def create_dir(path)
56
- # When doing multithreaded downloads into the file cache, the following
57
- # interleaving raises an error here:
58
- #
59
- # thread1 thread2
60
- # File.directory?(create_path) <- false
61
- # File.directory?(create_path) <- false
62
- # Dir.mkdir(create_path)
63
- # Dir.mkdir(create_path) <- raises Errno::EEXIST
56
+ # When doing multithreaded downloads into the file cache, the following
57
+ # interleaving raises an error here:
58
+ #
59
+ # thread1 thread2
60
+ # File.directory?(create_path) <- false
61
+ # File.directory?(create_path) <- false
62
+ # Dir.mkdir(create_path)
63
+ # Dir.mkdir(create_path) <- raises Errno::EEXIST
64
64
  Chef::Log.trace("Creating directory #{path}")
65
65
  Dir.mkdir(path)
66
66
  rescue Errno::EEXIST
@@ -19,9 +19,9 @@ class Chef
19
19
  class Node
20
20
  module Mixin
21
21
  module DeepMergeCache
22
- # Cache of deep merged values by top-level key. This is a simple hash which has keys that are the
23
- # top-level keys of the node object, and we save the computed deep-merge for that key here. There is
24
- # no cache of subtrees.
22
+ # Cache of deep merged values by top-level key. This is a simple hash which has keys that are the
23
+ # top-level keys of the node object, and we save the computed deep-merge for that key here. There is
24
+ # no cache of subtrees.
25
25
  attr_accessor :deep_merge_cache
26
26
 
27
27
  def initialize
@@ -31,10 +31,10 @@ class Chef
31
31
  @deep_merge_cache = {}
32
32
  end
33
33
 
34
- # Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
35
- # the entire deep_merge cache. In the case of the user doing node.default['foo']['bar']['baz']=
36
- # that eventually results in a call to reset_cache('foo') here. A node.default=hash_thing call
37
- # must invalidate the entire cache and re-deep-merge the entire node object.
34
+ # Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
35
+ # the entire deep_merge cache. In the case of the user doing node.default['foo']['bar']['baz']=
36
+ # that eventually results in a call to reset_cache('foo') here. A node.default=hash_thing call
37
+ # must invalidate the entire cache and re-deep-merge the entire node object.
38
38
  def reset_cache(path = nil)
39
39
  if path.nil?
40
40
  deep_merge_cache.clear
@@ -18,15 +18,16 @@
18
18
  require_relative "../package"
19
19
  require_relative "../../resource/chocolatey_package"
20
20
  require_relative "../../mixin/powershell_out"
21
+ require_relative "../../win32/api/command_line_helper" if ChefUtils.windows?
21
22
 
22
23
  class Chef
23
24
  class Provider
24
25
  class Package
25
26
  class Chocolatey < Chef::Provider::Package
26
27
  include Chef::Mixin::PowershellOut
28
+ include Chef::ReservedNames::Win32::API::CommandLineHelper if ChefUtils.windows?
27
29
 
28
30
  provides :chocolatey_package
29
-
30
31
  # Declare that our arguments should be arrays
31
32
  use_multipackage_api
32
33
 
@@ -209,7 +210,7 @@ class Chef
209
210
  # @param include_source [Boolean] should the source parameter be added
210
211
  # @return [String] options from new_resource or empty string
211
212
  def cmd_args(include_source: true)
212
- cmd_args = [ new_resource.options ]
213
+ cmd_args = new_resource.options.is_a?(String) ? command_line_to_argv_w_helper(new_resource.options) : Array(new_resource.options)
213
214
  cmd_args += common_options(include_source: include_source)
214
215
  cmd_args
215
216
  end
@@ -117,9 +117,9 @@ class Chef
117
117
  logger.trace("#{@new_resource} is running")
118
118
  end
119
119
  rescue Mixlib::ShellOut::ShellCommandFailed, SystemCallError
120
- # ShellOut sometimes throws different types of Exceptions than ShellCommandFailed.
121
- # Temporarily catching different types of exceptions here until we get Shellout fixed.
122
- # TODO: Remove the line before one we get the ShellOut fix.
120
+ # ShellOut sometimes throws different types of Exceptions than ShellCommandFailed.
121
+ # Temporarily catching different types of exceptions here until we get Shellout fixed.
122
+ # TODO: Remove the line before one we get the ShellOut fix.
123
123
  @status_load_success = false
124
124
  @current_resource.running false
125
125
  nil
@@ -426,7 +426,7 @@ class Chef
426
426
  when TaskScheduler::AT_LOGON
427
427
  # TODO: handle option for this trigger
428
428
  when TaskScheduler::AT_SYSTEMSTART
429
- # TODO: handle option for this trigger
429
+ # TODO: handle option for this trigger
430
430
  end
431
431
  end
432
432
 
@@ -60,7 +60,7 @@ class Chef
60
60
  when fedora_derived?
61
61
  package %w{ autoconf bison flex gcc gcc-c++ gettext kernel-devel make m4 ncurses-devel patch }
62
62
 
63
- # Ensure GCC 4 is available on older pre-6 EL
63
+ # Ensure GCC 4 is available on older pre-6 EL
64
64
  package %w{ gcc44 gcc44-c++ } if platform_family?("rhel") && node["platform_version"].to_i < 6
65
65
  when freebsd?
66
66
  package "devel/gmake"
@@ -76,20 +76,20 @@ class Chef
76
76
  property :start_calendar_interval, [Hash, Array],
77
77
  description: "A Hash (similar to crontab) that defines the calendar frequency at which a job is started or an Array.",
78
78
  coerce: proc { |type|
79
- # Coerce into an array of hashes to make validation easier
79
+ # Coerce into an array of hashes to make validation easier
80
80
  array = if type.is_a?(Array)
81
81
  type
82
82
  else
83
83
  [type]
84
84
  end
85
85
 
86
- # Check to make sure that our array only has hashes
86
+ # Check to make sure that our array only has hashes
87
87
  unless array.all? { |obj| obj.is_a?(Hash) }
88
88
  error_msg = "start_calendar_interval must be a single hash or an array of hashes!"
89
89
  raise Chef::Exceptions::ValidationFailed, error_msg
90
90
  end
91
91
 
92
- # Make sure the hashes don't have any incorrect keys/values
92
+ # Make sure the hashes don't have any incorrect keys/values
93
93
  array.each do |entry|
94
94
  allowed_keys = %w{Minute Hour Day Weekday Month}
95
95
  unless entry.keys.all? { |key| allowed_keys.include?(key) }
@@ -105,7 +105,7 @@ class Chef
105
105
  end
106
106
  end
107
107
 
108
- # Don't return array if we only have one entry
108
+ # Don't return array if we only have one entry
109
109
  if array.size == 1
110
110
  array.first
111
111
  else
@@ -61,9 +61,9 @@ class Chef
61
61
  desired_state: false,
62
62
  skip_docs: true
63
63
 
64
- # coerce various ways of representing a boolean into either 0 (false) or 1 (true)
65
- # which is what the defaults CLI expects. Why? Well defaults itself accepts a few
66
- # different formats, but when you do a read command it all comes back as 1 or 0.
64
+ # coerce various ways of representing a boolean into either 0 (false) or 1 (true)
65
+ # which is what the defaults CLI expects. Why? Well defaults itself accepts a few
66
+ # different formats, but when you do a read command it all comes back as 1 or 0.
67
67
  def coerce_booleans(val)
68
68
  return 1 if [true, "TRUE", "1", "true", "YES", "yes"].include?(val)
69
69
  return 0 if [false, "FALSE", "0", "false", "NO", "no"].include?(val)
@@ -41,7 +41,7 @@ class Chef
41
41
  description: "The local address the firewall rule applies to."
42
42
 
43
43
  property :local_port, [String, Integer, Array],
44
- # split various formats of comma separated lists and provide a sorted array of strings to match PS output
44
+ # split various formats of comma separated lists and provide a sorted array of strings to match PS output
45
45
  coerce: proc { |d| d.is_a?(String) ? d.split(/\s*,\s*/).sort : Array(d).sort.map(&:to_s) },
46
46
  description: "The local port the firewall rule applies to."
47
47
 
@@ -49,7 +49,7 @@ class Chef
49
49
  description: "The remote address the firewall rule applies to."
50
50
 
51
51
  property :remote_port, [String, Integer, Array],
52
- # split various formats of comma separated lists and provide a sorted array of strings to match PS output
52
+ # split various formats of comma separated lists and provide a sorted array of strings to match PS output
53
53
  coerce: proc { |d| d.is_a?(String) ? d.split(/\s*,\s*/).sort : Array(d).sort.map(&:to_s) },
54
54
  description: "The remote port the firewall rule applies to."
55
55
 
@@ -72,7 +72,7 @@ class Chef
72
72
  description: "The profile the firewall rule applies to.",
73
73
  coerce: proc { |p| Array(p).map(&:downcase).map(&:to_sym).sort },
74
74
  callbacks: {
75
- "contains values not in :public, :private :domain, :any or :notapplicable" => lambda { |p|
75
+ "contains values not in :public, :private, :domain, :any or :notapplicable" => lambda { |p|
76
76
  p.all? { |e| %i{public private domain any notapplicable}.include?(e) }
77
77
  },
78
78
  }
@@ -106,6 +106,10 @@ class Chef
106
106
  else
107
107
  state = Chef::JSONCompat.from_json(output.stdout)
108
108
  end
109
+
110
+ # Need to reverse `$rule.Profile.ToString()` in powershell command
111
+ current_profiles = state["profile"].split(", ").map(&:to_sym)
112
+
109
113
  local_address state["local_address"]
110
114
  local_port Array(state["local_port"]).sort
111
115
  remote_address state["remote_address"]
@@ -113,7 +117,7 @@ class Chef
113
117
  direction state["direction"]
114
118
  protocol state["protocol"]
115
119
  firewall_action state["firewall_action"]
116
- profile state["profile"]
120
+ profile current_profiles
117
121
  program state["program"]
118
122
  service state["service"]
119
123
  interface_type state["interface_type"]
@@ -149,8 +149,8 @@ class Chef
149
149
  raise "The windows_share resource relies on PowerShell cmdlets not present in Windows releases prior to 8/2012. Cannot continue!" if node["platform_version"].to_f < 6.3
150
150
  end
151
151
 
152
- # given the string output of Get-SmbShareAccess parse out
153
- # arrays of full access users, change users, and read only users
152
+ # given the string output of Get-SmbShareAccess parse out
153
+ # arrays of full access users, change users, and read only users
154
154
  def parse_permissions(results_string)
155
155
  json_results = Chef::JSONCompat.from_json(results_string)
156
156
  json_results = [json_results] unless json_results.is_a?(Array) # single result is not an array
@@ -171,8 +171,8 @@ class Chef
171
171
  [f_users, c_users, r_users]
172
172
  end
173
173
 
174
- # local names are returned from Get-SmbShareAccess in the full format MACHINE\\NAME
175
- # but users of this resource would simply say NAME so we need to strip the values for comparison
174
+ # local names are returned from Get-SmbShareAccess in the full format MACHINE\\NAME
175
+ # but users of this resource would simply say NAME so we need to strip the values for comparison
176
176
  def stripped_account(name)
177
177
  name.slice!("#{node["hostname"]}\\")
178
178
  name
@@ -159,16 +159,16 @@ class Chef
159
159
 
160
160
  private
161
161
 
162
- ## Resource is not idempotent when day, start_day is not provided with frequency :weekly
163
- ## we set start_day when not given by user as current date based on which we set the day property for current current date day is monday ..
164
- ## we set the monday as the day so at next run when new_resource.day is nil and current_resource day is monday due to which udpate gets called
162
+ ## Resource is not idempotent when day, start_day is not provided with frequency :weekly
163
+ ## we set start_day when not given by user as current date based on which we set the day property for current current date day is monday ..
164
+ ## we set the monday as the day so at next run when new_resource.day is nil and current_resource day is monday due to which udpate gets called
165
165
  def idempotency_warning_for_frequency_weekly(day, start_day)
166
166
  if start_day.nil? && day.nil?
167
167
  logger.warn "To maintain idempotency for frequency :weekly provide start_day, start_time and day."
168
168
  end
169
169
  end
170
170
 
171
- # Validate the passed value is numeric values only if it is a string
171
+ # Validate the passed value is numeric values only if it is a string
172
172
  def numeric_value_in_string?(val)
173
173
  return true if Integer(val)
174
174
  rescue ArgumentError
@@ -194,7 +194,7 @@ class Chef
194
194
  end
195
195
  end
196
196
 
197
- # returns true if frequency_modifer has values First, second, third, fourth, last, lastday
197
+ # returns true if frequency_modifer has values First, second, third, fourth, last, lastday
198
198
  def frequency_modifier_includes_days_of_weeks?(frequency_modifier)
199
199
  frequency_modifier = frequency_modifier.to_s.split(",")
200
200
  frequency_modifier.map! { |value| value.strip.upcase }
@@ -209,7 +209,7 @@ class Chef
209
209
  raise ArgumentError, "Invalid value passed for `random_delay`. Please pass seconds as an Integer (e.g. 60) or a String with numeric values only (e.g. '60')." unless numeric_value_in_string?(random_delay)
210
210
  end
211
211
 
212
- # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~f
212
+ # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~f
213
213
  def validate_start_day(start_day, frequency)
214
214
  if start_day && frequency == :none
215
215
  raise ArgumentError, "`start_day` property is not supported with frequency: #{frequency}"
@@ -221,7 +221,7 @@ class Chef
221
221
  end
222
222
  end
223
223
 
224
- # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~
224
+ # @todo when we drop ruby 2.3 support this should be converted to .match?() instead of =~
225
225
  def validate_start_time(start_time, frequency)
226
226
  if start_time
227
227
  raise ArgumentError, "`start_time` property is not supported with `frequency :none`" if frequency == :none
@@ -321,7 +321,7 @@ class Chef
321
321
  end
322
322
  end
323
323
 
324
- # This method returns true if day has values from 1-31 which is a days of moths and used with frequency :monthly
324
+ # This method returns true if day has values from 1-31 which is a days of moths and used with frequency :monthly
325
325
  def days_includes_days_of_months?(days)
326
326
  days.map! { |day| day.to_s.strip.downcase }
327
327
  (days - VALID_DAYS_OF_MONTH).empty?
@@ -339,11 +339,11 @@ class Chef
339
339
  end
340
340
  end
341
341
 
342
- # Converts the number of seconds to an ISO8601 duration format and returns it.
343
- # Ref : https://github.com/arnau/ISO8601/blob/master/lib/iso8601/duration.rb#L18-L23
344
- # e.g.
345
- # ISO8601::Duration.new(65707200).to_s
346
- # returns 'PT65707200S'
342
+ # Converts the number of seconds to an ISO8601 duration format and returns it.
343
+ # Ref : https://github.com/arnau/ISO8601/blob/master/lib/iso8601/duration.rb#L18-L23
344
+ # e.g.
345
+ # ISO8601::Duration.new(65707200).to_s
346
+ # returns 'PT65707200S'
347
347
  def sec_to_dur(seconds)
348
348
  ISO8601::Duration.new(seconds.to_i).to_s
349
349
  end
@@ -68,8 +68,8 @@ module ResourceInspector
68
68
  dir, name = File.split(path)
69
69
  Chef::Cookbook::FileVendor.fetch_from_disk(path)
70
70
  loader = Chef::CookbookLoader.new(dir)
71
- cookbooks = loader.load_cookbooks
72
- resources = cookbooks[name].files_for(:resources)
71
+ cookbook = loader.load_cookbook(name)
72
+ resources = cookbook.files_for(:resources)
73
73
 
74
74
  resources.each_with_object({}) do |r, res|
75
75
  pth = r["full_path"]
@@ -82,13 +82,14 @@ module ResourceInspector
82
82
  # otherwise, if we have a path then extract all the resources from the cookbook
83
83
  # or else do a list of built in resources
84
84
  #
85
+ # @param arguments [Array, String] One of more paths to a cookbook or a resource file to inspect
85
86
  # @param complete [TrueClass, FalseClass] Whether to show properties defined in the base Resource class
86
87
  # @return [String] JSON formatting of all resources
87
88
  def self.inspect(arguments = [], complete: false)
88
89
  output = if arguments.empty?
89
90
  ObjectSpace.each_object(Class).select { |k| k < Chef::Resource }.each_with_object({}) { |klass, acc| acc[klass.resource_name] = extract_resource(klass) }
90
91
  else
91
- arguments.each_with_object({}) do |arg, acc|
92
+ Array(arguments).each_with_object({}) do |arg, acc|
92
93
  if File.directory?(arg)
93
94
  extract_cookbook(arg, complete).each { |k, v| acc[k] = v }
94
95
  else
@@ -160,9 +160,9 @@ class Chef
160
160
 
161
161
  def self.parse_line(line)
162
162
  if match = line.match(/^.*?:.*?:\s*LCM:\s*\[(.*?)\](.*)/)
163
- # If the line looks like
164
- # What If: [machinename]: LCM: [op_action op_type] message
165
- # extract op_action, op_type, and message
163
+ # If the line looks like
164
+ # What If: [machinename]: LCM: [op_action op_type] message
165
+ # extract op_action, op_type, and message
166
166
  operation, info = match.captures
167
167
  op_action, op_type = operation.strip.split(" ").map { |m| m.downcase.to_sym }
168
168
  else
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("../..", __FILE__)
26
- VERSION = Chef::VersionString.new("15.10.12")
26
+ VERSION = Chef::VersionString.new("15.11.3")
27
27
  end
28
28
 
29
29
  #
@@ -0,0 +1,89 @@
1
+ #
2
+ # Author:: Kapil Chouhan <kapil.chouhan@msystechnologies.com>
3
+ # Copyright:: Copyright 2013-2020, Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "../api"
20
+
21
+ class Chef
22
+ module ReservedNames::Win32
23
+ module API
24
+ module CommandLineHelper
25
+ # extend Chef::ReservedNames::Win32
26
+ extend Chef::ReservedNames::Win32::API
27
+
28
+ ###############################################
29
+ # Win32 API Bindings
30
+ ###############################################
31
+
32
+ ffi_lib "Shell32"
33
+
34
+ =begin
35
+ LPWSTR * CommandLineToArgvW(
36
+ LPCWSTR lpCmdLine,
37
+ int *pNumArgs
38
+ );
39
+ =end
40
+
41
+ safe_attach_function :command_line_to_argv_w, :CommandLineToArgvW, %i{pointer pointer}, :pointer
42
+
43
+ ffi_lib "Kernel32"
44
+
45
+ =begin
46
+ LPSTR GetCommandLineA();
47
+ =end
48
+
49
+ safe_attach_function :get_command_line, :GetCommandLineA, [], :pointer
50
+
51
+ =begin
52
+ HLOCAL LocalFree(
53
+ _Frees_ptr_opt_ HLOCAL hMem
54
+ );
55
+ =end
56
+
57
+ safe_attach_function :local_free, :LocalFree, [:pointer], :pointer
58
+
59
+ ###############################################
60
+ # Helpers
61
+ ###############################################
62
+
63
+ # It takes the supplied string and splits it into an array.
64
+ def command_line_to_argv_w_helper(args)
65
+ arguments_list = []
66
+ argv = args.to_wstring
67
+ result = get_command_line
68
+ argc = FFI::MemoryPointer.new(:int)
69
+
70
+ # Parses a Unicode command line string
71
+ # It is return an array of pointers to the command line arguments.
72
+ # Along with a count of such arguments
73
+ result = command_line_to_argv_w(argv, argc)
74
+ str_ptr = result.read_pointer
75
+ offset = 0
76
+ number_of_agrs = argc.read_int
77
+ number_of_agrs.times do
78
+ new_str_pointer = str_ptr.+(offset)
79
+ argument = new_str_pointer.read_wstring
80
+ arguments_list << argument
81
+ offset = offset + argument.length * 2 + 2
82
+ end
83
+ local_free(result)
84
+ arguments_list
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end