chef 12.14.89-universal-mingw32 → 12.15.19-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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +76 -51
  3. data/Gemfile +1 -1
  4. data/README.md +9 -7
  5. data/Rakefile +1 -1
  6. data/VERSION +1 -1
  7. data/acceptance/Gemfile +3 -0
  8. data/acceptance/Gemfile.lock +19 -18
  9. data/acceptance/fips/.kitchen.yml +1 -1
  10. data/lib/chef/application/exit_code.rb +9 -0
  11. data/lib/chef/cookbook/file_system_file_vendor.rb +7 -8
  12. data/lib/chef/cookbook/metadata.rb +8 -0
  13. data/lib/chef/exceptions.rb +5 -0
  14. data/lib/chef/knife.rb +14 -15
  15. data/lib/chef/knife/ssh.rb +1 -0
  16. data/lib/chef/node/attribute.rb +1 -3
  17. data/lib/chef/node/attribute_collections.rb +20 -0
  18. data/lib/chef/provider/apt_repository.rb +1 -1
  19. data/lib/chef/provider/apt_update.rb +1 -1
  20. data/lib/chef/provider/group/groupadd.rb +2 -1
  21. data/lib/chef/provider/package/cab.rb +150 -0
  22. data/lib/chef/provider/package/rubygems.rb +0 -1
  23. data/lib/chef/provider/registry_key.rb +26 -2
  24. data/lib/chef/provider/remote_file/content.rb +1 -1
  25. data/lib/chef/provider/user.rb +10 -0
  26. data/lib/chef/provider/user/dscl.rb +2 -2
  27. data/lib/chef/provider/user/linux.rb +4 -14
  28. data/lib/chef/provider/user/pw.rb +2 -2
  29. data/lib/chef/provider/user/solaris.rb +15 -0
  30. data/lib/chef/provider/user/useradd.rb +1 -5
  31. data/lib/chef/providers.rb +1 -0
  32. data/lib/chef/resource/cab_package.rb +44 -0
  33. data/lib/chef/resource/registry_key.rb +3 -3
  34. data/lib/chef/resource/yum_repository.rb +1 -1
  35. data/lib/chef/resources.rb +1 -0
  36. data/lib/chef/server_api.rb +1 -1
  37. data/lib/chef/util/dsc/local_configuration_manager.rb +1 -1
  38. data/lib/chef/version.rb +1 -1
  39. data/spec/data/templates/chef-seattle20160930-4388-1crv7ef.txt +1 -0
  40. data/spec/data/templates/chef-seattle20160930-4388-jjfoae.txt +1 -0
  41. data/spec/data/templates/chef-seattle20160930-4388-umeq2c.txt +1 -0
  42. data/spec/functional/knife/cookbook_delete_spec.rb +48 -59
  43. data/spec/functional/resource/ifconfig_spec.rb +6 -0
  44. data/spec/functional/resource/registry_spec.rb +110 -4
  45. data/spec/unit/application/exit_code_spec.rb +10 -0
  46. data/spec/unit/cookbook/file_vendor_spec.rb +15 -0
  47. data/spec/unit/cookbook/metadata_spec.rb +19 -0
  48. data/spec/unit/exceptions_spec.rb +2 -0
  49. data/spec/unit/node/attribute_spec.rb +23 -1
  50. data/spec/unit/node/vivid_mash_spec.rb +27 -0
  51. data/spec/unit/provider/group/groupadd_spec.rb +118 -99
  52. data/spec/unit/provider/package/cab_spec.rb +218 -0
  53. data/spec/unit/provider/package/rubygems_spec.rb +2 -4
  54. data/spec/unit/provider/registry_key_spec.rb +94 -0
  55. data/spec/unit/provider/remote_file/content_spec.rb +1 -0
  56. data/spec/unit/provider/user/solaris_spec.rb +52 -40
  57. data/spec/unit/resource/apt_update_spec.rb +25 -17
  58. data/spec/unit/resource/cab_package_spec.rb +38 -0
  59. data/spec/unit/resource/registry_key_spec.rb +26 -10
  60. data/spec/unit/server_api_spec.rb +50 -0
  61. data/spec/unit/util/dsc/local_configuration_manager_spec.rb +10 -4
  62. metadata +13 -5
@@ -722,6 +722,14 @@ class Chef
722
722
  end
723
723
  end
724
724
 
725
+ def method_missing(method, *args, &block)
726
+ if block_given?
727
+ super
728
+ else
729
+ Chef::Log.debug "ignoring method #{method} on cookbook with name #{name}, possible typo or future metadata?"
730
+ end
731
+ end
732
+
725
733
  private
726
734
 
727
735
  # Helper to match a gem style version (ohai_version/chef_version) against a set of
@@ -79,6 +79,7 @@ class Chef
79
79
  class Reboot < Exception; end
80
80
  class RebootPending < Exception; end
81
81
  class RebootFailed < Mixlib::ShellOut::ShellCommandFailed; end
82
+ class ClientUpgraded < Exception; end
82
83
  class PrivateKeyMissing < RuntimeError; end
83
84
  class CannotWritePrivateKey < RuntimeError; end
84
85
  class RoleNotFound < RuntimeError; end
@@ -245,6 +246,10 @@ class Chef
245
246
  class Win32RegBadValueSize < ArgumentError; end
246
247
  class Win32RegTypesMismatch < ArgumentError; end
247
248
 
249
+ # incorrect input for registry_key create action throws following error
250
+ class RegKeyValuesTypeMissing < ArgumentError; end
251
+ class RegKeyValuesDataMissing < ArgumentError; end
252
+
248
253
  class InvalidEnvironmentPath < ArgumentError; end
249
254
  class EnvironmentNotFound < RuntimeError; end
250
255
 
@@ -236,6 +236,20 @@ class Chef
236
236
  OFFICIAL_PLUGINS = %w{ec2 rackspace windows openstack terremark bluebox}
237
237
 
238
238
  class << self
239
+ def list_commands(preferred_category = nil)
240
+ category_desc = preferred_category ? preferred_category + " " : ""
241
+ msg "Available #{category_desc}subcommands: (for details, knife SUB-COMMAND --help)\n\n"
242
+ subcommand_loader.list_commands(preferred_category).sort.each do |category, commands|
243
+ next if category =~ /deprecated/i
244
+ msg "** #{category.upcase} COMMANDS **"
245
+ commands.sort.each do |command|
246
+ subcommand_loader.load_command(command)
247
+ msg subcommands[command].banner if subcommands[command]
248
+ end
249
+ msg
250
+ end
251
+ end
252
+
239
253
  private
240
254
 
241
255
  # @api private
@@ -269,21 +283,6 @@ class Chef
269
283
  exit 10
270
284
  end
271
285
 
272
- # @api private
273
- def list_commands(preferred_category = nil)
274
- category_desc = preferred_category ? preferred_category + " " : ""
275
- msg "Available #{category_desc}subcommands: (for details, knife SUB-COMMAND --help)\n\n"
276
- subcommand_loader.list_commands(preferred_category).sort.each do |category, commands|
277
- next if category =~ /deprecated/i
278
- msg "** #{category.upcase} COMMANDS **"
279
- commands.sort.each do |command|
280
- subcommand_loader.load_command(command)
281
- msg subcommands[command].banner if subcommands[command]
282
- end
283
- msg
284
- end
285
- end
286
-
287
286
  # @api private
288
287
  def reset_config_path!
289
288
  @@chef_config_dir = nil
@@ -541,6 +541,7 @@ class Chef
541
541
 
542
542
  configure_user
543
543
  configure_password
544
+ @password = config[:ssh_password] if config[:ssh_password]
544
545
  configure_ssh_identity_file
545
546
  configure_gateway
546
547
  configure_session
@@ -452,9 +452,7 @@ class Chef
452
452
  #
453
453
 
454
454
  def merged_attributes(*path)
455
- # immutablize(
456
- merge_all(path)
457
- # )
455
+ immutablize(merge_all(path))
458
456
  end
459
457
 
460
458
  def combined_override(*path)
@@ -73,6 +73,7 @@ class Chef
73
73
  def initialize(root, data)
74
74
  @root = root
75
75
  super(data)
76
+ map! { |e| convert_value(e) }
76
77
  end
77
78
 
78
79
  # For elements like Fixnums, true, nil...
@@ -86,6 +87,23 @@ class Chef
86
87
  Array.new(map { |e| safe_dup(e) })
87
88
  end
88
89
 
90
+ private
91
+
92
+ def convert_value(value)
93
+ case value
94
+ when VividMash
95
+ value
96
+ when AttrArray
97
+ value
98
+ when Hash
99
+ VividMash.new(root, value)
100
+ when Array
101
+ AttrArray.new(root, value)
102
+ else
103
+ value
104
+ end
105
+ end
106
+
89
107
  end
90
108
 
91
109
  # == VividMash
@@ -184,6 +202,8 @@ class Chef
184
202
  case value
185
203
  when VividMash
186
204
  value
205
+ when AttrArray
206
+ value
187
207
  when Hash
188
208
  VividMash.new(root, value)
189
209
  when Array
@@ -153,7 +153,7 @@ class Chef
153
153
  end
154
154
 
155
155
  def install_key_from_uri
156
- key_name = new_resource.key.split(%r{\/}).last
156
+ key_name = new_resource.key.gsub(/[^0-9A-Za-z\-]/, "_")
157
157
  cached_keyfile = ::File.join(Chef::Config[:file_cache_path], key_name)
158
158
  type = if new_resource.key.start_with?("http")
159
159
  :remote_file
@@ -73,7 +73,7 @@ class Chef
73
73
  end
74
74
 
75
75
  declare_resource(:file, "#{APT_CONF_DIR}/15update-stamp") do
76
- content "APT::Update::Post-Invoke-Success {\"touch #{STAMP_DIR}/update-success-stamp 2>/dev/null || true\";};"
76
+ content "APT::Update::Post-Invoke-Success {\"touch #{STAMP_DIR}/update-success-stamp 2>/dev/null || true\";};\n"
77
77
  action :create_if_missing
78
78
  end
79
79
 
@@ -126,7 +126,8 @@ class Chef
126
126
 
127
127
  def groupadd_options
128
128
  opts = ""
129
- opts << " -r" if @new_resource.system
129
+ # Solaris doesn't support system groups.
130
+ opts << " -r" if @new_resource.system && !node.platform?("solaris2")
130
131
  opts << " -o" if @new_resource.non_unique
131
132
  opts
132
133
  end
@@ -0,0 +1,150 @@
1
+ #
2
+ # Author:: Vasundhara Jagdale (<vasundhara.jagdale@msystechnologies.com>)
3
+ # Copyright:: Copyright 2015-2016, 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 "chef/provider/package"
20
+ require "chef/resource/cab_package"
21
+ require "chef/mixin/shell_out"
22
+
23
+ class Chef
24
+ class Provider
25
+ class Package
26
+ class Cab < Chef::Provider::Package
27
+ include Chef::Mixin::ShellOut
28
+
29
+ provides :cab_package, os: "windows"
30
+
31
+ def load_current_resource
32
+ @current_resource = Chef::Resource::CabPackage.new(new_resource.name)
33
+ current_resource.source(new_resource.source)
34
+ new_resource.version(package_version)
35
+ current_resource.version(installed_version)
36
+ current_resource
37
+ end
38
+
39
+ def install_package(name, version)
40
+ dism_command("/Add-Package /PackagePath:\"#{@new_resource.source}\"")
41
+ end
42
+
43
+ def remove_package(name, version)
44
+ dism_command("/Remove-Package /PackagePath:\"#{@new_resource.source}\"")
45
+ end
46
+
47
+ def dism_command(command)
48
+ shellout = Mixlib::ShellOut.new("dism.exe /Online #{command} /NoRestart", { :timeout => @new_resource.timeout })
49
+ with_os_architecture(nil) do
50
+ shellout.run_command
51
+ end
52
+ end
53
+
54
+ def installed_version
55
+ stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
56
+ package_info = parse_dism_get_package_info(stdout)
57
+ # e.g. Package_for_KB2975719~31bf3856ad364e35~amd64~~6.3.1.8
58
+ package = split_package_identity(package_info["package_information"]["package_identity"])
59
+ # Search for just the package name to catch a different version being installed
60
+ Chef::Log.debug("#{@new_resource} searching for installed package #{package['name']}")
61
+ found_packages = installed_packages.select { |p| p["package_identity"] =~ /^#{package['name']}~/ }
62
+ if found_packages.length == 0
63
+ nil
64
+ elsif found_packages.length == 1
65
+ stdout = dism_command("/Get-PackageInfo /PackageName:\"#{found_packages.first["package_identity"]}\"").stdout
66
+ find_version(stdout)
67
+ else
68
+ # Presuming this won't happen, otherwise we need to handle it
69
+ raise Chef::Exceptions::Package, "Found multiple packages installed matching name #{package['name']}, found: #{found_packages.length} matches"
70
+ end
71
+ end
72
+
73
+ def package_version
74
+ Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
75
+ stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
76
+ find_version(stdout)
77
+ end
78
+
79
+ def find_version(stdout)
80
+ package_info = parse_dism_get_package_info(stdout)
81
+ package = split_package_identity(package_info["package_information"]["package_identity"])
82
+ package["version"]
83
+ end
84
+
85
+ # returns a hash of package state information given the output of dism /get-packages
86
+ # expected keys: package_identity
87
+ def parse_dism_get_packages(text)
88
+ packages = Array.new
89
+ text.each_line do |line|
90
+ key, value = line.split(":") if line.start_with?("Package Identity")
91
+ unless key.nil? || value.nil?
92
+ package = Hash.new
93
+ package[key.downcase.strip.tr(" ", "_")] = value.strip.chomp
94
+ packages << package
95
+ end
96
+ end
97
+ packages
98
+ end
99
+
100
+ # returns a hash of package information given the output of dism /get-packageinfo
101
+ def parse_dism_get_package_info(text)
102
+ package_data = Hash.new
103
+ errors = Array.new
104
+ in_section = false
105
+ section_headers = [ "Package information", "Custom Properties", "Features" ]
106
+ text.each_line do |line|
107
+ if line =~ /Error: (.*)/
108
+ errors << $1.strip
109
+ elsif section_headers.any? { |header| line =~ /^(#{header})/ }
110
+ in_section = $1.downcase.tr(" ", "_")
111
+ elsif line =~ /(.*) ?: (.*)/
112
+ v = $2 # has to be first or the gsub below replaces this variable
113
+ k = $1.downcase.strip.tr(" ", "_")
114
+ if in_section
115
+ package_data[in_section] = Hash.new unless package_data[in_section]
116
+ package_data[in_section][k] = v
117
+ else
118
+ package_data[k] = v
119
+ end
120
+ end
121
+ end
122
+ unless errors.empty?
123
+ if errors.include?("0x80070003") || errors.include?("0x80070002")
124
+ raise Chef::Exceptions::Package, "DISM: The system cannot find the path or file specified."
125
+ elsif errors.include?("740")
126
+ raise Chef::Exceptions::Package, "DISM: Error 740: Elevated permissions are required to run DISM."
127
+ else
128
+ raise Chef::Exceptions::Package, "Unknown errors encountered parsing DISM output: #{errors}"
129
+ end
130
+ end
131
+ package_data
132
+ end
133
+
134
+ def split_package_identity(identity)
135
+ data = Hash.new
136
+ data["name"], data["publisher"], data["arch"], data["resource_id"], data["version"] = identity.split("~")
137
+ data
138
+ end
139
+
140
+ def installed_packages
141
+ @packages ||= begin
142
+ output = dism_command("/Get-Packages").stdout
143
+ packages = parse_dism_get_packages(output)
144
+ packages
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -536,7 +536,6 @@ class Chef
536
536
  def install_via_gem_command(name, version)
537
537
  if @new_resource.source =~ /\.gem$/i
538
538
  name = @new_resource.source
539
- src = " --local" unless source_is_remote?
540
539
  elsif @new_resource.clear_sources
541
540
  src = " --clear-sources"
542
541
  src << (@new_resource.source && " --source=#{@new_resource.source}" || "")
@@ -70,27 +70,51 @@ class Chef
70
70
  end
71
71
  end
72
72
 
73
+ def key_missing?(values, name)
74
+ values.each do |v|
75
+ return true unless v.has_key?(name)
76
+ end
77
+ false
78
+ end
79
+
73
80
  def define_resource_requirements
74
81
  requirements.assert(:create, :create_if_missing, :delete, :delete_key) do |a|
75
82
  a.assertion { registry.hive_exists?(@new_resource.key) }
76
83
  a.failure_message(Chef::Exceptions::Win32RegHiveMissing, "Hive #{@new_resource.key.split("\\").shift} does not exist")
77
84
  end
85
+
78
86
  requirements.assert(:create) do |a|
79
87
  a.assertion { registry.key_exists?(@new_resource.key) }
80
88
  a.whyrun("Key #{@new_resource.key} does not exist. Unless it would have been created before, attempt to modify its values would fail.")
81
89
  end
90
+
82
91
  requirements.assert(:create, :create_if_missing) do |a|
83
- #If keys missing in the path and recursive == false
92
+ # If keys missing in the path and recursive == false
84
93
  a.assertion { !registry.keys_missing?(@current_resource.key) || @new_resource.recursive }
85
94
  a.failure_message(Chef::Exceptions::Win32RegNoRecursive, "Intermediate keys missing but recursive is set to false")
86
95
  a.whyrun("Intermediate keys in #{@new_resource.key} do not exist. Unless they would have been created earlier, attempt to modify them would fail.")
87
96
  end
97
+
88
98
  requirements.assert(:delete_key) do |a|
89
- #If key to be deleted has subkeys but recurssive == false
99
+ # If key to be deleted has subkeys but recurssive == false
90
100
  a.assertion { !registry.key_exists?(@new_resource.key) || !registry.has_subkeys?(@new_resource.key) || @new_resource.recursive }
91
101
  a.failure_message(Chef::Exceptions::Win32RegNoRecursive, "#{@new_resource.key} has subkeys but recursive is set to false.")
92
102
  a.whyrun("#{@current_resource.key} has subkeys, but recursive is set to false. attempt to delete would fails unless subkeys were deleted prior to this action.")
93
103
  end
104
+
105
+ requirements.assert(:create, :create_if_missing) do |a|
106
+ # If type key missing in the RegistryKey values hash
107
+ a.assertion { !key_missing?(@new_resource.values, :type) }
108
+ a.failure_message(Chef::Exceptions::RegKeyValuesTypeMissing, "Missing type key in RegistryKey values hash")
109
+ a.whyrun("Type key does not exist. Attempt would fail unless the complete values hash containing all the keys does not exist for registry_key resource's create action.")
110
+ end
111
+
112
+ requirements.assert(:create, :create_if_missing) do |a|
113
+ # If data key missing in the RegistryKey values hash
114
+ a.assertion { !key_missing?(@new_resource.values, :data) }
115
+ a.failure_message(Chef::Exceptions::RegKeyValuesDataMissing, "Missing data key in RegistryKey values hash")
116
+ a.whyrun("Data key does not exist. Attempt would fail unless the complete values hash containing all the keys does not exist for registry_key resource's create action.")
117
+ end
94
118
  end
95
119
 
96
120
  def action_create
@@ -54,7 +54,7 @@ class Chef
54
54
  as_uri(source)
55
55
  end
56
56
  raw_file = grab_file_from_uri(uri)
57
- rescue SocketError, Errno::ECONNREFUSED, Errno::ENOENT, Errno::EACCES, Timeout::Error, Net::HTTPServerException, Net::HTTPFatalError, Net::FTPError => e
57
+ rescue SocketError, Errno::ECONNREFUSED, Errno::ENOENT, Errno::EACCES, Timeout::Error, Net::HTTPServerException, Net::HTTPFatalError, Net::FTPError, Errno::ETIMEDOUT => e
58
58
  Chef::Log.warn("#{@new_resource} cannot be downloaded from #{source}: #{e}")
59
59
  if source = sources.shift
60
60
  Chef::Log.info("#{@new_resource} trying to download from another mirror")
@@ -210,6 +210,16 @@ class Chef
210
210
  def check_lock
211
211
  raise NotImplementedError
212
212
  end
213
+
214
+ def non_unique?
215
+ # XXX: THIS GOES AWAY IN CHEF-13 AND BECOMES JUST new_resource.non_unique
216
+ new_resource.non_unique || new_resource.supports[:non_unique]
217
+ end
218
+
219
+ def managing_home_dir?
220
+ # XXX: THIS GOES AWAY IN CHEF-13 AND BECOMES JUST new_resource.manage_home
221
+ new_resource.manage_home || new_resource.supports[:manage_home]
222
+ end
213
223
  end
214
224
  end
215
225
  end
@@ -292,7 +292,7 @@ user password using shadow hash.")
292
292
  return
293
293
  end
294
294
 
295
- if new_resource.supports[:manage_home]
295
+ if managing_home_dir?
296
296
  validate_home_dir_specification!
297
297
 
298
298
  if (current_resource.home == new_resource.home) && !new_home_exists?
@@ -438,7 +438,7 @@ user password using shadow hash.")
438
438
  # and deleting home directory if needed.
439
439
  #
440
440
  def remove_user
441
- if new_resource.supports[:manage_home]
441
+ if managing_home_dir?
442
442
  # Remove home directory
443
443
  FileUtils.rm_rf(current_resource.home)
444
444
  end
@@ -52,14 +52,14 @@ class Chef
52
52
  opts << "-s" << new_resource.shell if should_set?(:shell)
53
53
  opts << "-u" << new_resource.uid if should_set?(:uid)
54
54
  opts << "-d" << new_resource.home if updating_home?
55
- opts << "-o" if non_unique
55
+ opts << "-o" if non_unique?
56
56
  opts
57
57
  end
58
58
 
59
59
  def usermod_options
60
60
  opts = []
61
61
  if updating_home?
62
- if manage_home
62
+ if managing_home_dir?
63
63
  opts << "-m"
64
64
  end
65
65
  end
@@ -69,7 +69,7 @@ class Chef
69
69
  def useradd_options
70
70
  opts = []
71
71
  opts << "-r" if new_resource.system
72
- if manage_home
72
+ if managing_home_dir?
73
73
  opts << "-m"
74
74
  else
75
75
  opts << "-M"
@@ -79,7 +79,7 @@ class Chef
79
79
 
80
80
  def userdel_options
81
81
  opts = []
82
- opts << "-r" if manage_home
82
+ opts << "-r" if managing_home_dir?
83
83
  opts << "-f" if new_resource.force
84
84
  opts
85
85
  end
@@ -122,16 +122,6 @@ class Chef
122
122
  # FIXME: should probably go on the current_resource
123
123
  @locked
124
124
  end
125
-
126
- def non_unique
127
- # XXX: THIS GOES AWAY IN CHEF-13 AND BECOMES JUST new_resource.non_unique
128
- new_resource.non_unique || new_resource.supports[:non_unique]
129
- end
130
-
131
- def manage_home
132
- # XXX: THIS GOES AWAY IN CHEF-13 AND BECOMES JUST new_resource.manage_home
133
- new_resource.manage_home || new_resource.supports[:manage_home]
134
- end
135
125
  end
136
126
  end
137
127
  end