chef 0.10.10 → 10.12.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/README.rdoc +6 -0
  2. data/distro/common/html/chef-client.8.html +4 -3
  3. data/distro/common/html/chef-expander.8.html +3 -3
  4. data/distro/common/html/chef-expanderctl.8.html +3 -3
  5. data/distro/common/html/chef-server-webui.8.html +3 -3
  6. data/distro/common/html/chef-server.8.html +3 -3
  7. data/distro/common/html/chef-solo.8.html +3 -3
  8. data/distro/common/html/chef-solr.8.html +3 -3
  9. data/distro/common/html/knife-bootstrap.1.html +3 -3
  10. data/distro/common/html/knife-client.1.html +3 -3
  11. data/distro/common/html/knife-configure.1.html +3 -3
  12. data/distro/common/html/knife-cookbook-site.1.html +3 -3
  13. data/distro/common/html/knife-cookbook.1.html +3 -3
  14. data/distro/common/html/knife-data-bag.1.html +3 -3
  15. data/distro/common/html/knife-environment.1.html +3 -3
  16. data/distro/common/html/knife-exec.1.html +3 -3
  17. data/distro/common/html/knife-index.1.html +3 -3
  18. data/distro/common/html/knife-node.1.html +3 -3
  19. data/distro/common/html/knife-role.1.html +3 -3
  20. data/distro/common/html/knife-search.1.html +3 -3
  21. data/distro/common/html/knife-ssh.1.html +3 -3
  22. data/distro/common/html/knife-status.1.html +3 -3
  23. data/distro/common/html/knife-tag.1.html +3 -3
  24. data/distro/common/html/knife.1.html +3 -3
  25. data/distro/common/html/shef.1.html +3 -3
  26. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  27. data/distro/common/man/man1/knife-client.1 +1 -1
  28. data/distro/common/man/man1/knife-configure.1 +1 -1
  29. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  30. data/distro/common/man/man1/knife-cookbook.1 +1 -1
  31. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  32. data/distro/common/man/man1/knife-environment.1 +1 -1
  33. data/distro/common/man/man1/knife-exec.1 +1 -1
  34. data/distro/common/man/man1/knife-index.1 +1 -1
  35. data/distro/common/man/man1/knife-node.1 +1 -1
  36. data/distro/common/man/man1/knife-role.1 +1 -1
  37. data/distro/common/man/man1/knife-search.1 +1 -1
  38. data/distro/common/man/man1/knife-ssh.1 +1 -1
  39. data/distro/common/man/man1/knife-status.1 +1 -1
  40. data/distro/common/man/man1/knife-tag.1 +1 -1
  41. data/distro/common/man/man1/knife.1 +1 -1
  42. data/distro/common/man/man1/shef.1 +1 -1
  43. data/distro/common/man/man8/chef-client.8 +5 -1
  44. data/distro/common/man/man8/chef-expander.8 +1 -1
  45. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  46. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  47. data/distro/common/man/man8/chef-server.8 +1 -1
  48. data/distro/common/man/man8/chef-solo.8 +1 -1
  49. data/distro/common/man/man8/chef-solr.8 +1 -1
  50. data/distro/common/markdown/man8/chef-client.mkd +2 -0
  51. data/lib/chef/application/client.rb +1 -1
  52. data/lib/chef/application/solo.rb +1 -1
  53. data/lib/chef/application/windows_service.rb +1 -1
  54. data/lib/chef/config.rb +1 -1
  55. data/lib/chef/exceptions.rb +3 -0
  56. data/lib/chef/file_access_control/unix.rb +21 -6
  57. data/lib/chef/file_access_control/windows.rb +7 -7
  58. data/lib/chef/knife/ssh.rb +4 -2
  59. data/lib/chef/mixin/enforce_ownership_and_permissions.rb +1 -1
  60. data/lib/chef/provider/link.rb +49 -45
  61. data/lib/chef/provider/mdadm.rb +4 -1
  62. data/lib/chef/provider/package/rubygems.rb +2 -1
  63. data/lib/chef/provider/remote_file.rb +17 -1
  64. data/lib/chef/reserved_names.rb +9 -0
  65. data/lib/chef/resource/link.rb +1 -17
  66. data/lib/chef/resource/mdadm.rb +1 -1
  67. data/lib/chef/resource_platform_map.rb +1 -3
  68. data/lib/chef/rest.rb +48 -17
  69. data/lib/chef/version.rb +1 -1
  70. data/lib/chef/win32/api.rb +16 -1
  71. data/lib/chef/win32/api/error.rb +9 -9
  72. data/lib/chef/win32/api/file.rb +263 -17
  73. data/lib/chef/win32/api/memory.rb +12 -12
  74. data/lib/chef/win32/api/process.rb +5 -5
  75. data/lib/chef/win32/api/psapi.rb +3 -3
  76. data/lib/chef/win32/api/security.rb +41 -41
  77. data/lib/chef/win32/api/system.rb +8 -8
  78. data/lib/chef/win32/api/unicode.rb +6 -6
  79. data/lib/chef/win32/error.rb +4 -4
  80. data/lib/chef/win32/file.rb +65 -15
  81. data/lib/chef/win32/file/info.rb +7 -7
  82. data/lib/chef/win32/handle.rb +3 -3
  83. data/lib/chef/win32/memory.rb +8 -8
  84. data/lib/chef/win32/process.rb +8 -8
  85. data/lib/chef/win32/security.rb +49 -49
  86. data/lib/chef/win32/security/ace.rb +11 -11
  87. data/lib/chef/win32/security/acl.rb +10 -10
  88. data/lib/chef/win32/security/securable_object.rb +13 -13
  89. data/lib/chef/win32/security/security_descriptor.rb +12 -12
  90. data/lib/chef/win32/security/sid.rb +8 -8
  91. data/lib/chef/win32/security/token.rb +8 -8
  92. data/lib/chef/win32/unicode.rb +5 -5
  93. data/lib/chef/win32/version.rb +4 -4
  94. metadata +374 -370
@@ -22,9 +22,9 @@ require 'chef/win32/security'
22
22
  class Chef
23
23
  class FileAccessControl
24
24
  module Windows
25
- include Chef::Win32::API::Security
25
+ include Chef::ReservedNames::Win32::API::Security
26
26
 
27
- Security = Chef::Win32::Security
27
+ Security = Chef::ReservedNames::Win32::Security
28
28
  ACL = Security::ACL
29
29
  ACE = Security::ACE
30
30
  SID = Security::SID
@@ -83,9 +83,9 @@ class Chef
83
83
  def securable_object
84
84
  @securable_object ||= begin
85
85
  if file.kind_of?(String)
86
- so = Chef::Win32::Security::SecurableObject.new(file.dup)
86
+ so = Chef::ReservedNames::Win32::Security::SecurableObject.new(file.dup)
87
87
  end
88
- raise ArgumentError, "'file' must be a valid path or object of type 'Chef::Win32::Security::SecurableObject'" unless so.kind_of? Chef::Win32::Security::SecurableObject
88
+ raise ArgumentError, "'file' must be a valid path or object of type 'Chef::ReservedNames::Win32::Security::SecurableObject'" unless so.kind_of? Chef::ReservedNames::Win32::Security::SecurableObject
89
89
  so
90
90
  end
91
91
  end
@@ -223,20 +223,20 @@ class Chef
223
223
  if owner
224
224
  acls += mode_ace(owner, (mode & 0700) >> 6)
225
225
  elsif mode & 0700 != 0
226
- raise "Mode #{mode.to_s(8)} includes bits for the owner, but owner is not specified"
226
+ Chef::Log.warn("Mode #{sprintf("%03o", mode)} includes bits for the owner, but owner is not specified")
227
227
  end
228
228
 
229
229
  group = target_group
230
230
  if group
231
231
  acls += mode_ace(group, (mode & 070) >> 3)
232
232
  elsif mode & 070 != 0
233
- raise "Mode #{mode.to_s(8)} includes bits for the group, but group is not specified"
233
+ Chef::Log.warn("Mode #{sprintf("%03o", mode)} includes bits for the group, but group is not specified")
234
234
  end
235
235
 
236
236
  acls += mode_ace(SID.Everyone, (mode & 07))
237
237
  end
238
238
 
239
- acls.nil? ? nil : Chef::Win32::Security::ACL.create(acls)
239
+ acls.nil? ? nil : Chef::ReservedNames::Win32::Security::ACL.create(acls)
240
240
  end
241
241
 
242
242
  def target_group
@@ -27,9 +27,11 @@ class Chef
27
27
  require 'net/ssh/multi'
28
28
  require 'readline'
29
29
  require 'chef/search/query'
30
- require 'chef/mixin/command'
30
+ require 'chef/mixin/shell_out'
31
31
  end
32
32
 
33
+ include Chef::Mixin::ShellOut
34
+
33
35
  attr_writer :password
34
36
 
35
37
  banner "knife ssh QUERY COMMAND (options)"
@@ -294,7 +296,7 @@ class Chef
294
296
  cmd = ["tmux new-session -d -s #{tmux_name}",
295
297
  "-n '#{server.host}'", ssh_dest.call(server),
296
298
  new_window_cmds.call].join(" ")
297
- Chef::Mixin::Command.run_command(:command => cmd)
299
+ shell_out!(cmd)
298
300
  exec("tmux attach-session -t #{tmux_name}")
299
301
  rescue Chef::Exceptions::Exec
300
302
  end
@@ -31,7 +31,7 @@ class Chef
31
31
  end
32
32
  access_controls = Chef::FileAccessControl.new(new_resource, path)
33
33
  access_controls.set_all
34
- new_resource.updated_by_last_action(access_controls.modified?)
34
+ new_resource.updated_by_last_action(true) if access_controls.modified?
35
35
  end
36
36
 
37
37
  end
@@ -30,7 +30,16 @@ class Chef
30
30
  def file_class
31
31
  @host_os_file ||= if Chef::Platform.windows?
32
32
  require 'chef/win32/file'
33
- Chef::Win32::File
33
+ begin
34
+ Chef::ReservedNames::Win32::File.verify_links_supported!
35
+ rescue Chef::Exceptions::Win32APIFunctionNotImplemented => e
36
+ message = "Link resource is not supported on this version of Windows"
37
+ message << ": #{node[:kernel][:name]}" if node
38
+ message << " (#{node[:platform_version]})" if node
39
+ Chef::Log.fatal(message)
40
+ raise e
41
+ end
42
+ Chef::ReservedNames::Win32::File
34
43
  else
35
44
  ::File
36
45
  end
@@ -48,44 +57,47 @@ class Chef
48
57
  def load_current_resource
49
58
  @current_resource = Chef::Resource::Link.new(@new_resource.name)
50
59
  @current_resource.target_file(@new_resource.target_file)
51
- @current_resource.link_type(@new_resource.link_type)
52
- if @new_resource.link_type == :symbolic
53
- if ::File.exists?(@current_resource.target_file) && file_class.symlink?(@current_resource.target_file)
54
- @current_resource.to(
55
- ::File.expand_path(file_class.readlink(@current_resource.target_file))
56
- )
57
- cstats = ::File.lstat(@current_resource.target_file)
58
- @current_resource.owner(cstats.uid)
59
- @current_resource.group(cstats.gid)
60
- else
61
- @current_resource.to("")
62
- end
63
- elsif @new_resource.link_type == :hard
64
- if ::File.exists?(@current_resource.target_file) && ::File.exists?(@new_resource.to)
65
- if ::File.stat(@current_resource.target_file).ino == ::File.stat(@new_resource.to).ino
66
- @current_resource.to(@new_resource.to)
60
+ if file_class.symlink?(@current_resource.target_file)
61
+ @current_resource.link_type(:symbolic)
62
+ @current_resource.to(
63
+ canonicalize(file_class.readlink(@current_resource.target_file))
64
+ )
65
+ cstats = ::File.lstat(@current_resource.target_file)
66
+ @current_resource.owner(cstats.uid)
67
+ @current_resource.group(cstats.gid)
68
+ else
69
+ @current_resource.link_type(:hard)
70
+ if ::File.exists?(@current_resource.target_file)
71
+ if ::File.exists?(@new_resource.to) &&
72
+ file_class.stat(@current_resource.target_file).ino ==
73
+ file_class.stat(@new_resource.to).ino
74
+ @current_resource.to(canonicalize(@new_resource.to))
67
75
  else
68
76
  @current_resource.to("")
69
77
  end
70
- else
71
- @current_resource.to("")
72
78
  end
73
79
  end
74
80
  @current_resource
75
81
  end
76
82
 
83
+ def canonicalize(path)
84
+ Chef::Platform.windows? ? path.gsub('/', '\\') : path
85
+ end
86
+
77
87
  def action_create
78
- if @current_resource.to != ::File.expand_path(@new_resource.to, @new_resource.target_file)
88
+ if @current_resource.to != canonicalize(@new_resource.to) ||
89
+ @current_resource.link_type != @new_resource.link_type
79
90
  if @new_resource.link_type == :symbolic
80
- unless (file_class.symlink?(@new_resource.target_file) && file_class.readlink(@new_resource.target_file) == @new_resource.to)
81
- if file_class.symlink?(@new_resource.target_file) || ::File.exist?(@new_resource.target_file)
82
- ::File.unlink(@new_resource.target_file)
83
- end
84
- file_class.symlink(@new_resource.to,@new_resource.target_file)
85
- Chef::Log.debug("#{@new_resource} created #{@new_resource.link_type} link from #{@new_resource.to} -> #{@new_resource.target_file}")
86
- Chef::Log.info("#{@new_resource} created")
91
+ if @current_resource.to # nil if target_file does not exist
92
+ ::File.unlink(@new_resource.target_file)
87
93
  end
94
+ file_class.symlink(canonicalize(@new_resource.to),@new_resource.target_file)
95
+ Chef::Log.debug("#{@new_resource} created #{@new_resource.link_type} link from #{@new_resource.to} -> #{@new_resource.target_file}")
96
+ Chef::Log.info("#{@new_resource} created")
88
97
  elsif @new_resource.link_type == :hard
98
+ if @current_resource.to # nil if target_file does not exist
99
+ ::File.unlink(@new_resource.target_file)
100
+ end
89
101
  file_class.link(@new_resource.to, @new_resource.target_file)
90
102
  Chef::Log.debug("#{@new_resource} created #{@new_resource.link_type} link from #{@new_resource.to} -> #{@new_resource.target_file}")
91
103
  Chef::Log.info("#{@new_resource} created")
@@ -93,29 +105,21 @@ class Chef
93
105
  @new_resource.updated_by_last_action(true)
94
106
  end
95
107
  if @new_resource.link_type == :symbolic
96
- enforce_ownership_and_permissions
108
+ enforce_ownership_and_permissions @new_resource.target_file
97
109
  end
98
110
  end
99
111
 
100
112
  def action_delete
101
- if @new_resource.link_type == :symbolic
102
- if file_class.symlink?(@new_resource.target_file)
103
- ::File.delete(@new_resource.target_file)
104
- Chef::Log.info("#{@new_resource} deleted")
105
- @new_resource.updated_by_last_action(true)
106
- elsif ::File.exists?(@new_resource.target_file)
107
- raise Chef::Exceptions::Link, "Cannot delete #{@new_resource} at #{@new_resource.target_file}! Not a symbolic link."
108
- end
109
- elsif @new_resource.link_type == :hard
110
- if ::File.exists?(@new_resource.target_file)
111
- if ::File.exists?(@new_resource.to) && (file_class.stat(@current_resource.target_file).ino == file_class.stat(@new_resource.to).ino)
112
- ::File.delete(@new_resource.target_file)
113
- Chef::Log.info("#{@new_resource} deleted")
114
- @new_resource.updated_by_last_action(true)
115
- else
116
- raise Chef::Exceptions::Link, "Cannot delete #{@new_resource} at #{@new_resource.target_file}! Not a hard link."
117
- end
113
+ if @current_resource.to # Exists
114
+ if @current_resource.link_type == @new_resource.link_type
115
+ unless @current_resource.link_type == :hard && @current_resource.to == ''
116
+ ::File.delete(@new_resource.target_file)
117
+ Chef::Log.info("#{@new_resource} deleted")
118
+ @new_resource.updated_by_last_action(true)
119
+ return
120
+ end
118
121
  end
122
+ raise Chef::Exceptions::Link, "Cannot delete #{@new_resource} at #{@new_resource.target_file}! Not a #{@new_resource.link_type.to_s} link."
119
123
  end
120
124
  end
121
125
  end
@@ -51,7 +51,10 @@ class Chef
51
51
 
52
52
  def action_create
53
53
  unless @current_resource.exists
54
- command = "yes | mdadm --create #{@new_resource.raid_device} --chunk=#{@new_resource.chunk} --level #{@new_resource.level} --metadata=#{@new_resource.metadata} --bitmap=#{@new_resource.bitmap} --raid-devices #{@new_resource.devices.length} #{@new_resource.devices.join(" ")}"
54
+ command = "yes | mdadm --create #{@new_resource.raid_device} --chunk=#{@new_resource.chunk} --level #{@new_resource.level}"
55
+ command << " --metadata=#{@new_resource.metadata}"
56
+ command << " --bitmap=#{@new_resource.bitmap}" if @new_resource.bitmap
57
+ command << " --raid-devices #{@new_resource.devices.length} #{@new_resource.devices.join(" ")}"
55
58
  Chef::Log.debug("#{@new_resource} mdadm command: #{command}")
56
59
  #pid, stdin, stdout, stderr = popen4(command)
57
60
  shell_out!(command)
@@ -344,6 +344,7 @@ class Chef
344
344
  # Opscode Omnibus - The ruby that ships inside omnibus is only used for Chef
345
345
  # Default to installing somewhere more functional
346
346
  gem_location = find_gem_by_path
347
+ @new_resource.gem_binary gem_location
347
348
  @gem_env = AlternateGemEnvironment.new(gem_location)
348
349
  Chef::Log.debug("#{@new_resource} using gem '#{gem_location}'")
349
350
  else
@@ -353,7 +354,7 @@ class Chef
353
354
  end
354
355
 
355
356
  def is_omnibus?
356
- if RbConfig::CONFIG['bindir'] == "/opt/chef/embedded/bin"
357
+ if RbConfig::CONFIG['bindir'] =~ %r!/opt/(opscode|chef)/embedded/bin!
357
358
  Chef::Log.debug("#{@new_resource} detected omnibus installation in #{RbConfig::CONFIG['bindir']}")
358
359
  # Omnibus installs to a static path because of linking on unix, find it.
359
360
  true
@@ -39,7 +39,7 @@ class Chef
39
39
  if current_resource_matches_target_checksum?
40
40
  Chef::Log.debug("#{@new_resource} checksum matches target checksum (#{@new_resource.checksum}) - not updating")
41
41
  else
42
- Chef::REST.new(@new_resource.source, nil, nil).fetch(@new_resource.source) do |raw_file|
42
+ Chef::REST.new(@new_resource.source, nil, nil, http_client_opts).fetch(@new_resource.source) do |raw_file|
43
43
  if matches_current_checksum?(raw_file)
44
44
  Chef::Log.debug "#{@new_resource} target and source checksums are the same - not updating"
45
45
  else
@@ -99,6 +99,22 @@ class Chef
99
99
  end
100
100
  end
101
101
 
102
+ def http_client_opts
103
+ opts={}
104
+ # CHEF-3140
105
+ # 1. If it's already compressed, trying to compress it more will
106
+ # probably be counter-productive.
107
+ # 2. Some servers are misconfigured so that you GET $URL/file.tgz but
108
+ # they respond with content type of tar and content encoding of gzip,
109
+ # which tricks Chef::REST into decompressing the response body. In this
110
+ # case you'd end up with a tar archive (no gzip) named, e.g., foo.tgz,
111
+ # which is not what you wanted.
112
+ if @new_resource.path =~ /gz$/ or @new_resource.source =~ /gz$/
113
+ opts[:disable_gzip] = true
114
+ end
115
+ opts
116
+ end
117
+
102
118
  private
103
119
 
104
120
  def absolute_uri?(source)
@@ -0,0 +1,9 @@
1
+ class Chef
2
+
3
+ # This module exists to hide conflicting constant names from the DSL.
4
+ # Hopefully we'll have a better/prettier/more sustainable solution in the
5
+ # future, but for now this will fix a regression introduced in Chef 0.10.10
6
+ # (conflict with the Win32 namespace)
7
+ module ReservedNames
8
+ end
9
+ end
@@ -39,7 +39,7 @@ class Chef
39
39
 
40
40
  def to(arg=nil)
41
41
  set_or_return(
42
- :source_file,
42
+ :to,
43
43
  arg,
44
44
  :kind_of => String
45
45
  )
@@ -62,22 +62,6 @@ class Chef
62
62
  )
63
63
  end
64
64
 
65
- def group(arg=nil)
66
- set_or_return(
67
- :group,
68
- arg,
69
- :regex => Chef::Config[:group_valid_regex]
70
- )
71
- end
72
-
73
- def owner(arg=nil)
74
- set_or_return(
75
- :owner,
76
- arg,
77
- :regex => Chef::Config[:user_valid_regex]
78
- )
79
- end
80
-
81
65
  end
82
66
  end
83
67
  end
@@ -31,7 +31,7 @@ class Chef
31
31
  @exists = false
32
32
  @level = 1
33
33
  @metadata = "0.90"
34
- @bitmap = "none"
34
+ @bitmap = nil
35
35
  @raid_device = name
36
36
 
37
37
  @action = :create
@@ -43,7 +43,6 @@ class Chef
43
43
 
44
44
  if map.has_key?(platform_sym)
45
45
  if map[platform_sym].has_key?(version)
46
- Chef::Log.debug("Platform #{platform_sym} version #{version} found")
47
46
  if map[platform_sym].has_key?(:default)
48
47
  resource_map.merge!(map[platform_sym][:default])
49
48
  end
@@ -51,8 +50,6 @@ class Chef
51
50
  elsif map[platform_sym].has_key?(:default)
52
51
  resource_map.merge!(map[platform_sym][:default])
53
52
  end
54
- else
55
- Chef::Log.debug("Platform #{platform} not found, using all defaults. (Unsupported platform?)")
56
53
  end
57
54
  resource_map
58
55
  end
@@ -136,6 +133,7 @@ class Chef
136
133
  def platform_resource(short_name, platform, version)
137
134
  pmap = filter(platform, version)
138
135
  rtkey = short_name.kind_of?(Chef::Resource) ? short_name.resource_name.to_sym : short_name
136
+
139
137
  pmap.has_key?(rtkey) ? pmap[rtkey] : nil
140
138
  end
141
139
 
@@ -62,6 +62,8 @@ class Chef
62
62
  @sign_on_redirect, @sign_request = true, true
63
63
  @redirects_followed = 0
64
64
  @redirect_limit = 10
65
+ @disable_gzip = false
66
+ handle_options(options)
65
67
  end
66
68
 
67
69
  def signing_key_filename
@@ -267,15 +269,19 @@ class Chef
267
269
  end
268
270
 
269
271
  def decompress_body(response)
270
- case response[CONTENT_ENCODING]
271
- when GZIP
272
- Chef::Log.debug "decompressing gzip response"
273
- Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(response.body)
274
- when DEFLATE
275
- Chef::Log.debug "decompressing deflate response"
276
- Zlib::Inflate.inflate(response.body)
277
- else
272
+ if gzip_disabled?
278
273
  response.body
274
+ else
275
+ case response[CONTENT_ENCODING]
276
+ when GZIP
277
+ Chef::Log.debug "decompressing gzip response"
278
+ Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(response.body)
279
+ when DEFLATE
280
+ Chef::Log.debug "decompressing deflate response"
281
+ Zlib::Inflate.inflate(response.body)
282
+ else
283
+ response.body
284
+ end
279
285
  end
280
286
  end
281
287
 
@@ -403,7 +409,7 @@ class Chef
403
409
  headers['Accept'] = "application/json" unless raw
404
410
  headers["Content-Type"] = 'application/json' if json_body
405
411
  headers['Content-Length'] = json_body.bytesize.to_s if json_body
406
- headers[RESTRequest::ACCEPT_ENCODING] = RESTRequest::ENCODING_GZIP_DEFLATE
412
+ headers[RESTRequest::ACCEPT_ENCODING] = RESTRequest::ENCODING_GZIP_DEFLATE unless gzip_disabled?
407
413
  headers.merge!(authentication_headers(method, url, json_body)) if sign_requests?
408
414
  headers.merge!(Chef::Config[:custom_http_headers]) if Chef::Config[:custom_http_headers]
409
415
  headers
@@ -419,15 +425,19 @@ class Chef
419
425
  # Kudos to _why!
420
426
  size, total = 0, response.header['Content-Length'].to_i
421
427
 
422
- inflater = case response[CONTENT_ENCODING]
423
- when GZIP
424
- Chef::Log.debug "decompressing gzip stream"
425
- Zlib::Inflate.new(Zlib::MAX_WBITS + 16)
426
- when DEFLATE
427
- Chef::Log.debug "decompressing inflate stream"
428
- Zlib::Inflate.new
429
- else
428
+ inflater = if gzip_disabled?
430
429
  NoopInflater.new
430
+ else
431
+ case response[CONTENT_ENCODING]
432
+ when GZIP
433
+ Chef::Log.debug "decompressing gzip stream"
434
+ Zlib::Inflate.new(Zlib::MAX_WBITS + 16)
435
+ when DEFLATE
436
+ Chef::Log.debug "decompressing inflate stream"
437
+ Zlib::Inflate.new
438
+ else
439
+ NoopInflater.new
440
+ end
431
441
  end
432
442
 
433
443
  response.read_body do |chunk|
@@ -441,5 +451,26 @@ class Chef
441
451
  raise
442
452
  end
443
453
 
454
+ # gzip is disabled using the disable_gzip => true option in the
455
+ # constructor. When gzip is disabled, no 'Accept-Encoding' header will be
456
+ # set, and the response will not be decompressed, no matter what the
457
+ # Content-Encoding header of the response is. The intended use case for
458
+ # this is to work around situations where you request +file.tar.gz+, but
459
+ # the server responds with a content type of tar and a content encoding of
460
+ # gzip, tricking the client into decompressing the response so you end up
461
+ # with a tar archive (no gzip) named file.tar.gz
462
+ def gzip_disabled?
463
+ @disable_gzip
464
+ end
465
+
466
+ def handle_options(opts)
467
+ opts.each do |name, value|
468
+ case name.to_s
469
+ when 'disable_gzip'
470
+ @disable_gzip = value
471
+ end
472
+ end
473
+ end
474
+
444
475
  end
445
476
  end