chef 0.10.8 → 0.10.10.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. data/distro/arch/etc/rc.d/chef-client +15 -1
  2. data/distro/common/html/chef-client.8.html +4 -4
  3. data/distro/common/html/chef-expander.8.html +4 -4
  4. data/distro/common/html/chef-expanderctl.8.html +4 -4
  5. data/distro/common/html/chef-server-webui.8.html +4 -4
  6. data/distro/common/html/chef-server.8.html +4 -4
  7. data/distro/common/html/chef-solo.8.html +4 -4
  8. data/distro/common/html/chef-solr.8.html +4 -4
  9. data/distro/common/html/knife-bootstrap.1.html +6 -10
  10. data/distro/common/html/knife-client.1.html +4 -4
  11. data/distro/common/html/knife-configure.1.html +4 -4
  12. data/distro/common/html/knife-cookbook-site.1.html +6 -6
  13. data/distro/common/html/knife-cookbook.1.html +4 -4
  14. data/distro/common/html/knife-data-bag.1.html +4 -4
  15. data/distro/common/html/knife-environment.1.html +4 -4
  16. data/distro/common/html/knife-exec.1.html +4 -4
  17. data/distro/common/html/knife-index.1.html +4 -4
  18. data/distro/common/html/knife-node.1.html +5 -5
  19. data/distro/common/html/knife-role.1.html +4 -4
  20. data/distro/common/html/knife-search.1.html +4 -4
  21. data/distro/common/html/knife-ssh.1.html +5 -6
  22. data/distro/common/html/knife-status.1.html +4 -4
  23. data/distro/common/html/knife-tag.1.html +4 -4
  24. data/distro/common/html/knife.1.html +7 -8
  25. data/distro/common/html/shef.1.html +4 -4
  26. data/distro/common/man/man1/knife-bootstrap.1 +4 -4
  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 +4 -4
  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 +2 -2
  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 +3 -7
  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 +5 -9
  42. data/distro/common/man/man1/shef.1 +1 -1
  43. data/distro/common/man/man8/chef-client.8 +1 -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/man1/knife-bootstrap.mkd +3 -7
  51. data/distro/common/markdown/man1/knife-cookbook-site.mkd +3 -3
  52. data/distro/common/markdown/man1/knife-node.mkd +2 -2
  53. data/distro/common/markdown/man1/knife-ssh.mkd +2 -5
  54. data/distro/common/markdown/man1/knife.mkd +7 -9
  55. data/distro/debian/etc/init.d/chef-client +22 -1
  56. data/distro/redhat/etc/init.d/chef-client +12 -1
  57. data/distro/windows/service_manager.rb +164 -0
  58. data/lib/chef/application.rb +12 -6
  59. data/lib/chef/application/client.rb +4 -3
  60. data/lib/chef/application/knife.rb +7 -12
  61. data/lib/chef/application/solo.rb +2 -1
  62. data/lib/chef/application/windows_service.rb +224 -0
  63. data/lib/chef/checksum_cache.rb +1 -0
  64. data/lib/chef/client.rb +3 -16
  65. data/lib/chef/config.rb +42 -13
  66. data/lib/chef/cookbook/metadata.rb +1 -1
  67. data/lib/chef/cookbook/syntax_check.rb +2 -2
  68. data/lib/chef/cookbook_version.rb +5 -0
  69. data/lib/chef/daemon.rb +1 -1
  70. data/lib/chef/exceptions.rb +7 -1
  71. data/lib/chef/file_access_control.rb +13 -87
  72. data/lib/chef/file_access_control/unix.rb +119 -0
  73. data/lib/chef/file_access_control/windows.rb +257 -0
  74. data/lib/chef/handler/json_file.rb +7 -1
  75. data/lib/chef/knife.rb +10 -16
  76. data/lib/chef/knife/bootstrap.rb +15 -8
  77. data/lib/chef/knife/bootstrap/centos5-gems.erb +1 -1
  78. data/lib/chef/knife/bootstrap/chef-full.erb +59 -0
  79. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +1 -0
  80. data/lib/chef/knife/configure.rb +2 -2
  81. data/lib/chef/knife/cookbook_site_download.rb +60 -21
  82. data/lib/chef/knife/cookbook_site_install.rb +16 -21
  83. data/lib/chef/knife/cookbook_upload.rb +77 -48
  84. data/lib/chef/knife/core/bootstrap_context.rb +3 -1
  85. data/lib/chef/knife/core/cookbook_scm_repo.rb +1 -1
  86. data/lib/chef/knife/core/node_editor.rb +1 -1
  87. data/lib/chef/knife/core/subcommand_loader.rb +1 -1
  88. data/lib/chef/knife/core/ui.rb +3 -2
  89. data/lib/chef/knife/help_topics.rb +1 -1
  90. data/lib/chef/knife/node_run_list_add.rb +14 -6
  91. data/lib/chef/knife/node_run_list_remove.rb +3 -3
  92. data/lib/chef/knife/ssh.rb +32 -13
  93. data/lib/chef/mash.rb +14 -0
  94. data/lib/chef/mixin/command.rb +1 -0
  95. data/lib/chef/mixin/command/unix.rb +5 -0
  96. data/lib/chef/mixin/convert_to_class_name.rb +2 -0
  97. data/lib/chef/mixin/deep_merge.rb +40 -18
  98. data/lib/chef/mixin/enforce_ownership_and_permissions.rb +39 -0
  99. data/lib/chef/mixin/language.rb +89 -3
  100. data/lib/chef/mixin/language_include_recipe.rb +8 -4
  101. data/lib/chef/mixin/path_sanity.rb +67 -0
  102. data/lib/chef/mixin/recipe_definition_dsl_core.rb +19 -11
  103. data/lib/chef/mixin/securable.rb +152 -0
  104. data/lib/chef/mixin/shell_out.rb +1 -1
  105. data/lib/chef/mixin/template.rb +8 -3
  106. data/lib/chef/mixins.rb +3 -0
  107. data/lib/chef/monkey_patches/moneta.rb +50 -0
  108. data/lib/chef/monkey_patches/string.rb +1 -1
  109. data/lib/chef/node.rb +2 -1
  110. data/lib/chef/platform.rb +34 -0
  111. data/lib/chef/provider.rb +23 -21
  112. data/lib/chef/provider/cron.rb +17 -12
  113. data/lib/chef/provider/cron/solaris.rb +6 -18
  114. data/lib/chef/provider/deploy.rb +14 -15
  115. data/lib/chef/provider/deploy/timestamped.rb +0 -1
  116. data/lib/chef/provider/directory.rb +1 -3
  117. data/lib/chef/provider/execute.rb +2 -2
  118. data/lib/chef/provider/file.rb +1 -75
  119. data/lib/chef/provider/git.rb +11 -9
  120. data/lib/chef/provider/group/gpasswd.rb +14 -9
  121. data/lib/chef/provider/link.rb +28 -59
  122. data/lib/chef/provider/mdadm.rb +2 -2
  123. data/lib/chef/provider/mount/mount.rb +1 -1
  124. data/lib/chef/provider/package.rb +10 -6
  125. data/lib/chef/provider/package/apt.rb +3 -1
  126. data/lib/chef/provider/package/dpkg.rb +1 -1
  127. data/lib/chef/provider/package/portage.rb +6 -3
  128. data/lib/chef/provider/package/rubygems.rb +75 -6
  129. data/lib/chef/provider/package/smartos.rb +84 -0
  130. data/lib/chef/provider/package/yum-dump.py +3 -2
  131. data/lib/chef/provider/package/yum.rb +51 -10
  132. data/lib/chef/provider/remote_directory.rb +24 -3
  133. data/lib/chef/provider/remote_file.rb +0 -6
  134. data/lib/chef/provider/route.rb +3 -3
  135. data/lib/chef/provider/service/debian.rb +2 -2
  136. data/lib/chef/provider/service/freebsd.rb +1 -1
  137. data/lib/chef/provider/service/macosx.rb +125 -0
  138. data/lib/chef/provider/service/windows.rb +5 -1
  139. data/lib/chef/provider/subversion.rb +10 -7
  140. data/lib/chef/providers.rb +3 -0
  141. data/lib/chef/resource.rb +181 -87
  142. data/lib/chef/resource/apt_package.rb +10 -1
  143. data/lib/chef/resource/chef_gem.rb +53 -0
  144. data/lib/chef/resource/conditional.rb +3 -0
  145. data/lib/chef/resource/cookbook_file.rb +12 -6
  146. data/lib/chef/resource/cron.rb +9 -0
  147. data/lib/chef/resource/directory.rb +14 -31
  148. data/lib/chef/resource/execute.rb +11 -9
  149. data/lib/chef/resource/file.rb +9 -33
  150. data/lib/chef/resource/link.rb +13 -8
  151. data/lib/chef/resource/mdadm.rb +10 -1
  152. data/lib/chef/resource/remote_directory.rb +13 -2
  153. data/lib/chef/resource/remote_file.rb +14 -7
  154. data/lib/chef/resource/smartos_package.rb +36 -0
  155. data/lib/chef/resource/template.rb +12 -5
  156. data/lib/chef/resource_platform_map.rb +153 -0
  157. data/lib/chef/resources.rb +2 -0
  158. data/lib/chef/rest.rb +55 -10
  159. data/lib/chef/rest/auth_credentials.rb +1 -0
  160. data/lib/chef/rest/rest_request.rb +24 -8
  161. data/lib/chef/role.rb +8 -2
  162. data/lib/chef/run_list.rb +1 -1
  163. data/lib/chef/run_list/run_list_expansion.rb +2 -2
  164. data/lib/chef/run_list/run_list_item.rb +7 -0
  165. data/lib/chef/runner.rb +4 -0
  166. data/lib/chef/shef.rb +2 -2
  167. data/lib/chef/shef/shef_session.rb +4 -5
  168. data/lib/chef/shell_out.rb +2 -245
  169. data/lib/chef/util/file_edit.rb +99 -89
  170. data/lib/chef/version.rb +1 -1
  171. data/lib/chef/win32/api.rb +349 -0
  172. data/lib/chef/win32/api/error.rb +921 -0
  173. data/lib/chef/win32/api/file.rb +289 -0
  174. data/lib/chef/win32/api/memory.rb +105 -0
  175. data/lib/chef/win32/api/process.rb +40 -0
  176. data/lib/chef/win32/api/psapi.rb +51 -0
  177. data/lib/chef/win32/api/security.rb +341 -0
  178. data/lib/chef/win32/api/system.rb +192 -0
  179. data/lib/chef/win32/api/unicode.rb +178 -0
  180. data/lib/chef/win32/error.rb +73 -0
  181. data/lib/chef/win32/file.rb +117 -0
  182. data/lib/chef/win32/file/info.rb +100 -0
  183. data/lib/chef/win32/handle.rb +48 -0
  184. data/lib/chef/win32/memory.rb +101 -0
  185. data/lib/chef/win32/process.rb +84 -0
  186. data/lib/chef/win32/security.rb +489 -0
  187. data/lib/chef/win32/security/ace.rb +125 -0
  188. data/lib/chef/win32/security/acl.rb +101 -0
  189. data/lib/chef/win32/security/securable_object.rb +109 -0
  190. data/lib/chef/win32/security/security_descriptor.rb +93 -0
  191. data/lib/chef/win32/security/sid.rb +199 -0
  192. data/lib/chef/win32/security/token.rb +64 -0
  193. data/lib/chef/win32/unicode.rb +43 -0
  194. data/lib/chef/win32/version.rb +119 -0
  195. metadata +104 -158
  196. data/lib/chef/shell_out/unix.rb +0 -223
  197. data/lib/chef/shell_out/windows.rb +0 -588
@@ -21,6 +21,7 @@
21
21
  # limitations under the License.
22
22
  #
23
23
  require 'chef/exceptions'
24
+ require 'chef/log'
24
25
  require 'mixlib/authentication/signedheaderauth'
25
26
 
26
27
  class Chef
@@ -44,6 +44,21 @@ class Chef
44
44
  UA_COMMON = "/#{::Chef::VERSION} (#{engine}-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}; ohai-#{Ohai::VERSION}; #{RUBY_PLATFORM}; +http://opscode.com)"
45
45
  DEFAULT_UA = "Chef Client" << UA_COMMON
46
46
 
47
+ USER_AGENT = "User-Agent".freeze
48
+
49
+ ACCEPT_ENCODING = "Accept-Encoding".freeze
50
+ ENCODING_GZIP_DEFLATE = "gzip;q=1.0,deflate;q=0.6,identity;q=0.3".freeze
51
+
52
+ GET = "get".freeze
53
+ PUT = "put".freeze
54
+ POST = "post".freeze
55
+ DELETE = "delete".freeze
56
+ HEAD = "head".freeze
57
+
58
+ HTTPS = "https".freeze
59
+
60
+ SLASH = "/".freeze
61
+
47
62
  def self.user_agent=(ua)
48
63
  @user_agent = ua
49
64
  end
@@ -76,7 +91,7 @@ class Chef
76
91
  end
77
92
 
78
93
  def path
79
- @url.path.empty? ? "/" : @url.path
94
+ @url.path.empty? ? SLASH : @url.path
80
95
  end
81
96
 
82
97
  def call
@@ -121,6 +136,7 @@ class Chef
121
136
  # TODO: need to set accept somewhere else
122
137
  # headers.merge!('Accept' => "application/json") unless raw
123
138
  @headers['X-Chef-Version'] = ::Chef::VERSION
139
+ @headers[ACCEPT_ENCODING] = ENCODING_GZIP_DEFLATE
124
140
 
125
141
  if @cookies.has_key?("#{host}:#{port}")
126
142
  @headers['Cookie'] = @cookies["#{host}:#{port}"]
@@ -146,7 +162,7 @@ class Chef
146
162
  pass = Chef::Config["#{url.scheme}_proxy_pass"]
147
163
  @http_client = Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass).new(host, port)
148
164
  end
149
- if url.scheme == "https"
165
+ if url.scheme == HTTPS
150
166
  @http_client.use_ssl = true
151
167
  if config[:ssl_verify_mode] == :verify_none
152
168
  @http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
@@ -188,15 +204,15 @@ class Chef
188
204
  req_path << "?#{query}" if query
189
205
 
190
206
  @http_request = case method.to_s.downcase
191
- when "get"
207
+ when GET
192
208
  Net::HTTP::Get.new(req_path, headers)
193
- when "post"
209
+ when POST
194
210
  Net::HTTP::Post.new(req_path, headers)
195
- when "put"
211
+ when PUT
196
212
  Net::HTTP::Put.new(req_path, headers)
197
- when "delete"
213
+ when DELETE
198
214
  Net::HTTP::Delete.new(req_path, headers)
199
- when "head"
215
+ when HEAD
200
216
  Net::HTTP::Head.new(req_path, headers)
201
217
  else
202
218
  raise ArgumentError, "You must provide :GET, :PUT, :POST, :DELETE or :HEAD as the method"
@@ -205,7 +221,7 @@ class Chef
205
221
  @http_request.body = request_body if (request_body && @http_request.request_body_permitted?)
206
222
  # Optionally handle HTTP Basic Authentication
207
223
  @http_request.basic_auth(url.user, url.password) if url.user
208
- @http_request['User-Agent'] = self.class.user_agent
224
+ @http_request[USER_AGENT] = self.class.user_agent
209
225
  end
210
226
 
211
227
  end
@@ -168,8 +168,14 @@ class Chef
168
168
  "default_attributes" => @default_attributes,
169
169
  "override_attributes" => @override_attributes,
170
170
  "chef_type" => "role",
171
- "run_list" => run_list,
172
- "env_run_lists" => env_run_lists_without_default
171
+
172
+ #Render to_json correctly for run_list items (both run_list and evn_run_lists)
173
+ #so malformed json does not result
174
+ "run_list" => run_list.run_list.map { |item| item.to_s },
175
+ "env_run_lists" => env_run_lists_without_default.inject({}) do |accumulator, (k, v)|
176
+ accumulator[k] = v.map { |x| x.to_s }
177
+ accumulator
178
+ end
173
179
  }
174
180
  result["_rev"] = couchdb_rev if couchdb_rev
175
181
  result
@@ -85,7 +85,7 @@ class Chef
85
85
  end
86
86
 
87
87
  def to_json(*args)
88
- to_a.to_json(*args)
88
+ to_a.map { |item| item.to_s}.to_json(*args)
89
89
  end
90
90
 
91
91
  def empty?
@@ -90,8 +90,8 @@ class Chef
90
90
  end
91
91
 
92
92
  def apply_role_attributes(role)
93
- @default_attrs = Chef::Mixin::DeepMerge.merge(@default_attrs, role.default_attributes)
94
- @override_attrs = Chef::Mixin::DeepMerge.merge(@override_attrs, role.override_attributes)
93
+ @default_attrs = Chef::Mixin::DeepMerge.role_merge(@default_attrs, role.default_attributes)
94
+ @override_attrs = Chef::Mixin::DeepMerge.role_merge(@override_attrs, role.override_attributes)
95
95
  end
96
96
 
97
97
  def applied_role?(role_name)
@@ -21,6 +21,7 @@ class Chef
21
21
  QUALIFIED_RECIPE = %r{^recipe\[([^\]@]+)(@([0-9]+(\.[0-9]+){1,2}))?\]$}
22
22
  QUALIFIED_ROLE = %r{^role\[([^\]]+)\]$}
23
23
  VERSIONED_UNQUALIFIED_RECIPE = %r{^([^@]+)(@([0-9]+(\.[0-9]+){1,2}))$}
24
+ FALSE_FRIEND = %r{[\[\]]}
24
25
 
25
26
  attr_reader :name, :type, :version
26
27
 
@@ -51,6 +52,12 @@ class Chef
51
52
  @type = :recipe
52
53
  @name = match[1]
53
54
  @version = match[3] if match[3]
55
+ elsif match = FALSE_FRIEND.match(item)
56
+ # Recipe[recipe_name]
57
+ # roles[role_name]
58
+ name = match[1]
59
+ raise ArgumentError, "Unable to create #{self.class} from #{item.class}:#{item.inspect}: must be recipe[#{name}] or role[#{name}]"
60
+
54
61
  else
55
62
  # recipe_name
56
63
  @type = :recipe
@@ -42,6 +42,10 @@ class Chef
42
42
  # Determine the appropriate provider for the given resource, then
43
43
  # execute it.
44
44
  def run_action(resource, action)
45
+ # Try to resolve lazy/forward references in notifications again to handle
46
+ # the case where the resource was defined lazily (ie. in a ruby_block)
47
+ resource.resolve_notification_references
48
+
45
49
  resource.run_action(action)
46
50
 
47
51
  # Execute any immediate and queue up any delayed notifications
@@ -144,7 +144,7 @@ module Shef
144
144
 
145
145
  def self.greeting
146
146
  " #{Etc.getlogin}@#{Shef.session.node.fqdn}"
147
- rescue NameError
147
+ rescue NameError, ArgumentError
148
148
  ""
149
149
  end
150
150
 
@@ -303,7 +303,7 @@ FOOTER
303
303
  def config_file_for_shef_mode(environment)
304
304
  if config[:config_file]
305
305
  config[:config_file]
306
- elsif environment
306
+ elsif environment && ENV['HOME']
307
307
  Shef.env = environment
308
308
  config_file_to_try = ::File.join(ENV['HOME'], '.chef', environment, 'shef.rb')
309
309
  unless ::File.exist?(config_file_to_try)
@@ -229,13 +229,13 @@ module Shef
229
229
  # attributes, and does not save updates to the server
230
230
  def build_node
231
231
  Chef::Log.debug("Building node object for #{@node_name}")
232
-
233
232
  @node = Chef::Node.find_or_create(node_name)
234
-
235
233
  ohai_data = @ohai.data.merge(@node.automatic_attrs)
236
-
237
234
  @node.consume_external_attrs(ohai_data,nil)
238
-
235
+ @run_list_expansion = @node.expand!('server')
236
+ @expanded_run_list_with_versions = @run_list_expansion.recipes.with_version_constraints_strings
237
+ Chef::Log.info("Run List is [#{@node.run_list}]")
238
+ Chef::Log.info("Run List expands to [#{@expanded_run_list_with_versions.join(', ')}]")
239
239
  @node
240
240
  end
241
241
 
@@ -276,7 +276,6 @@ module Shef
276
276
  @client.run_ohai
277
277
  @client.register
278
278
  @client.build_node
279
-
280
279
  @client.sync_cookbooks
281
280
  end
282
281
 
@@ -1,249 +1,6 @@
1
- #--
2
- # Author:: Daniel DeLeo (<dan@opscode.com>)
3
- # Copyright:: Copyright (c) 2010 Opscode, 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 'etc'
20
- require 'tmpdir'
21
- require 'chef/log'
22
- require 'fcntl'
23
- require 'chef/exceptions'
1
+ require 'mixlib/shellout'
24
2
 
25
3
  class Chef
26
-
27
- # == Chef::ShellOut
28
- # Provides a simplified interface to shelling out yet still collecting both
29
- # standard out and standard error and providing full control over environment,
30
- # working directory, uid, gid, etc.
31
- #
32
- # No means for passing input to the subprocess is provided, nor is there any
33
- # way to inspect the output of the command as it is being read. If you need
34
- # to do that, you have to use popen4 (in Chef::Mixin::Command)
35
- #
36
- # === Platform Support
37
- # Chef::ShellOut uses Kernel.fork() and is therefore unsuitable for Windows
38
- # or jruby.
39
- class ShellOut
40
- READ_WAIT_TIME = 0.01
41
- READ_SIZE = 4096
42
- DEFAULT_READ_TIMEOUT = 600
43
- DEFAULT_ENVIRONMENT = {'LC_ALL' => 'C'}
44
-
45
- if RUBY_PLATFORM =~ /mswin|mingw32|windows/
46
- require 'chef/shell_out/windows'
47
- include ShellOut::Windows
48
- else
49
- require 'chef/shell_out/unix'
50
- include ShellOut::Unix
51
- end
52
-
53
- attr_accessor :user
54
- attr_accessor :group
55
- attr_accessor :cwd
56
- attr_accessor :valid_exit_codes
57
- attr_accessor :live_stream
58
- attr_accessor :command_log_level
59
- attr_accessor :command_log_prepend
60
-
61
- attr_reader :command, :umask, :environment
62
- attr_writer :timeout
63
- attr_reader :execution_time
64
-
65
- attr_reader :stdout, :stderr, :status
66
-
67
- attr_reader :stdin_pipe, :stdout_pipe, :stderr_pipe, :process_status_pipe
68
-
69
- # === Arguments:
70
- # Takes a single command, or a list of command fragments. These are used
71
- # as arguments to Kernel.exec. See the Kernel.exec documentation for more
72
- # explanation of how arguments are evaluated. The last argument can be an
73
- # options Hash.
74
- # === Options:
75
- # If the last argument is a Hash, it is removed from the list of args passed
76
- # to exec and used as an options hash. The following options are available:
77
- # * +user+: the user the commmand should run as. if an integer is given, it is
78
- # used as a uid. A string is treated as a username and resolved to a uid
79
- # with Etc.getpwnam
80
- # * +group+: the group the command should run as. works similarly to +user+
81
- # * +cwd+: the directory to chdir to before running the command
82
- # * +umask+: a umask to set before running the command. If given as an Integer,
83
- # be sure to use two leading zeros so it's parsed as Octal. A string will
84
- # be treated as an octal integer
85
- # * +returns+: one or more Integer values to use as valid exit codes for the
86
- # subprocess. This only has an effect if you call +error!+ after
87
- # +run_command+.
88
- # * +environment+: a Hash of environment variables to set before the command
89
- # is run. By default, the environment will *always* be set to 'LC_ALL' => 'C'
90
- # to prevent issues with multibyte characters in Ruby 1.8. To avoid this,
91
- # use :environment => nil for *no* extra environment settings, or
92
- # :environment => {'LC_ALL'=>nil, ...} to set other environment settings
93
- # without changing the locale.
94
- # * +timeout+: a Numeric value for the number of seconds to wait on the
95
- # child process before raising an Exception. This is calculated as the
96
- # total amount of time that ShellOut waited on the child process without
97
- # receiving any output (i.e., IO.select returned nil). Default is 60
98
- # seconds. Note: the stdlib Timeout library is not used.
99
- # === Examples:
100
- # Invoke find(1) to search for .rb files:
101
- # find = Chef::ShellOut.new("find . -name '*.rb'")
102
- # find.run_command
103
- # # If all went well, the results are on +stdout+
104
- # puts find.stdout
105
- # # find(1) prints diagnostic info to STDERR:
106
- # puts "error messages" + find.stderr
107
- # # Raise an exception if it didn't exit with 0
108
- # find.error!
109
- # Run a command as the +www+ user with no extra ENV settings from +/tmp+
110
- # cmd = Chef::ShellOut.new("apachectl", "start", :user => 'www', :env => nil, :cwd => '/tmp')
111
- # cmd.run_command # etc.
112
- def initialize(*command_args)
113
- @stdout, @stderr = '', ''
114
- @live_stream = nil
115
- @command_log_level = :debug
116
- @command_log_prepend = nil
117
- @environment = DEFAULT_ENVIRONMENT
118
- @cwd = nil
119
- @valid_exit_codes = [0]
120
-
121
- if command_args.last.is_a?(Hash)
122
- parse_options(command_args.pop)
123
- end
124
-
125
- @command = command_args.size == 1 ? command_args.first : command_args
126
- end
127
-
128
- def umask=(new_umask)
129
- @umask = (new_umask.respond_to?(:oct) ? new_umask.oct : new_umask.to_i) & 007777
130
- end
131
-
132
- def uid
133
- return nil unless user
134
- user.kind_of?(Integer) ? user : Etc.getpwnam(user.to_s).uid
135
- end
136
-
137
- def gid
138
- return nil unless group
139
- group.kind_of?(Integer) ? group : Etc.getgrnam(group.to_s).gid
140
- end
141
-
142
- def timeout
143
- @timeout || DEFAULT_READ_TIMEOUT
144
- end
145
-
146
- # Creates a String showing the output of the command, including a banner
147
- # showing the exact command executed. Used by +invalid!+ to show command
148
- # results when the command exited with an unexpected status.
149
- def format_for_exception
150
- msg = ""
151
- msg << "---- Begin output of #{command} ----\n"
152
- msg << "STDOUT: #{stdout.strip}\n"
153
- msg << "STDERR: #{stderr.strip}\n"
154
- msg << "---- End output of #{command} ----\n"
155
- msg << "Ran #{command} returned #{status.exitstatus}" if status
156
- msg
157
- end
158
-
159
- def exitstatus
160
- @status && @status.exitstatus
161
- end
162
-
163
- # Run the command, writing the command's standard out and standard error
164
- # to +stdout+ and +stderr+, and saving its exit status object to +status+
165
- # === Returns
166
- # returns +self+; +stdout+, +stderr+, +status+, and +exitstatus+ will be
167
- # populated with results of the command
168
- # === Raises
169
- # * Errno::EACCES when you are not privileged to execute the command
170
- # * Errno::ENOENT when the command is not available on the system (or not
171
- # in the current $PATH)
172
- # * Chef::Exceptions::CommandTimeout when the command does not complete
173
- # within +timeout+ seconds (default: 60s)
174
- def run_command
175
- if command_log_prepend
176
- Chef::Log.send(command_log_level, "#{command_log_prepend} sh(#{@command})")
177
- else
178
- Chef::Log.send(command_log_level, "sh(#{@command})")
179
- end
180
- super
181
- end
182
-
183
- # Checks the +exitstatus+ against the set of +valid_exit_codes+. If
184
- # +exitstatus+ is not in the list of +valid_exit_codes+, calls +invalid!+,
185
- # which raises an Exception.
186
- # === Returns
187
- # nil::: always returns nil when it does not raise
188
- # === Raises
189
- # Chef::Exceptions::ShellCommandFailed::: via +invalid!+
190
- def error!
191
- unless Array(valid_exit_codes).include?(exitstatus)
192
- invalid!("Expected process to exit with #{valid_exit_codes.inspect}, but received '#{exitstatus}'")
193
- end
194
- end
195
-
196
- # Raises a Chef::Exceptions::ShellCommandFailed exception, appending the
197
- # command's stdout, stderr, and exitstatus to the exception message.
198
- # === Arguments
199
- # +msg+: A String to use as the basis of the exception message. The
200
- # default explanation is very generic, providing a more informative message
201
- # is highly encouraged.
202
- # === Raises
203
- # Chef::Exceptions::ShellCommandFailed always
204
- def invalid!(msg=nil)
205
- msg ||= "Command produced unexpected results"
206
- raise Chef::Exceptions::ShellCommandFailed, msg + "\n" + format_for_exception
207
- end
208
-
209
- def inspect
210
- "<#{self.class.name}##{object_id}: command: '#@command' process_status: #{@status.inspect} " +
211
- "stdout: '#{stdout.strip}' stderr: '#{stderr.strip}' child_pid: #{@child_pid.inspect} " +
212
- "environment: #{@environment.inspect} timeout: #{timeout} user: #@user group: #@group working_dir: #@cwd >"
213
- end
214
-
215
- private
216
-
217
- def parse_options(opts)
218
- opts.each do |option, setting|
219
- case option.to_s
220
- when 'cwd'
221
- self.cwd = setting
222
- when 'user'
223
- self.user = setting
224
- when 'group'
225
- self.group = setting
226
- when 'umask'
227
- self.umask = setting
228
- when 'timeout'
229
- self.timeout = setting
230
- when 'returns'
231
- self.valid_exit_codes = Array(setting)
232
- when 'live_stream'
233
- self.live_stream = setting
234
- when 'command_log_level'
235
- self.command_log_level = setting
236
- when 'command_log_prepend'
237
- self.command_log_prepend = setting
238
- when 'environment', 'env'
239
- # passing :environment => nil means don't set any new ENV vars
240
- @environment = setting.nil? ? {} : @environment.dup.merge!(setting)
241
- else
242
- raise Chef::Exceptions::InvalidCommandOption, "option '#{option.inspect}' is not a valid option for #{self.class.name}"
243
- end
244
- end
245
- end
246
-
247
-
4
+ class ShellOut < Mixlib::ShellOut
248
5
  end
249
6
  end