chef 0.9.8.rc.0 → 0.9.8

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.
@@ -17,13 +17,14 @@
17
17
  # See the License for the specific language governing permissions and
18
18
  # limitations under the License.
19
19
 
20
- # Notice:
21
- # This code is imported from deep_merge by Steve Midgley. deep_merge is
22
- # available under the MIT license from
23
- # http://trac.misuse.org/science/wiki/DeepMerge
24
-
25
20
  class Chef
26
21
  module Mixin
22
+ # == Chef::Mixin::DeepMerge
23
+ # Implements a deep merging algorithm for nested data structures.
24
+ # ==== Notice:
25
+ # This code is imported from deep_merge by Steve Midgley. deep_merge is
26
+ # available under the MIT license from
27
+ # http://trac.misuse.org/science/wiki/DeepMerge
27
28
  module DeepMerge
28
29
  def self.merge(first, second)
29
30
  first = Mash.new(first) unless first.kind_of?(Mash)
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Christopher Walters (<cw@opscode.com>)
4
4
  # Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
@@ -21,6 +21,7 @@ require 'chef/resource'
21
21
  require 'chef/mixin/convert_to_class_name'
22
22
  require 'chef/mixin/language'
23
23
 
24
+ #--
24
25
  # UGH. this is a circular require that will cause an uninitialized constant
25
26
  # error, but this file really does depend on Chef::Recipe. oh well.
26
27
  # require 'chef/recipe'
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Daniel DeLeo (<dan@opscode.com>)
3
3
  # Copyright:: Copyright (c) 2010 Opscode, Inc.
4
4
  # License:: Apache License, Version 2.0
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
4
  # License:: Apache License, Version 2.0
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Daniel DeLeo (<dan@opscode.com>)
3
3
  # Copyright:: Copyright (c) 2009 Opscode, Inc.
4
4
  # Copyright:: Copyright (c) 2005 Sam Ruby
@@ -16,7 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- #
19
+ #--
20
20
  # Portions of this code are adapted from Sam Ruby's xchar.rb
21
21
  # http://intertwingly.net/stories/2005/09/28/xchar.rb
22
22
  #
@@ -16,11 +16,11 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- # Adds a Dir.glob to Ruby 1.8.5, for compat
20
19
  if RUBY_VERSION < "1.8.6" || RUBY_PLATFORM =~ /mswin|mingw32|windows/
21
20
  class Dir
22
21
  class << self
23
22
  alias_method :glob_, :glob
23
+ # Adds a Dir.glob to Ruby 1.8.5, for compat
24
24
  def glob(pattern, flags=0)
25
25
  raise ArgumentError unless (
26
26
  !pattern.nil? and (
@@ -16,7 +16,8 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- # On ruby 1.9, Strings are aware of multibyte characters, so #size and length
19
+ # == String (Patch)
20
+ # On ruby 1.9, Strings are aware of multibyte characters, so +size+ and +length+
20
21
  # give the actual number of characters. In Chef::REST, we need the bytesize
21
22
  # so we can correctly set the Content-Length headers, but ruby 1.8.6 and lower
22
23
  # don't define String#bytesize. Monkey patching time!
@@ -16,11 +16,15 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ # == Tempfile (Patch)
19
20
  # Tempfile has a horrible bug where it causes an IOError: closed stream in its
20
21
  # finalizer, leading to intermittent application crashes with confusing stack
21
22
  # traces. Here we monkey patch the fix into place. You can track the bug on
22
23
  # ruby's redmine: http://redmine.ruby-lang.org/issues/show/3119
23
- class Tempfile
24
+ #
25
+ # The patch is slightly different for Ruby 1.8 and Ruby 1.9, both patches are
26
+ # included here.
27
+ class Tempfile # :nodoc:
24
28
  # Tempfile has changes between 1.8.x and 1.9.x
25
29
  # so we monkey patch separately
26
30
  if RUBY_VERSION =~ /^1\.8/
@@ -18,22 +18,34 @@
18
18
 
19
19
  require 'chef/provider/package'
20
20
  require 'chef/mixin/command'
21
+ require 'chef/mixin/shell_out'
21
22
  require 'chef/resource/package'
23
+ require 'chef/mixin/shell_out'
24
+
22
25
  class Chef
23
26
  class Provider
24
27
  class Package
25
28
  class EasyInstall < Chef::Provider::Package
26
29
 
30
+ include Chef::Mixin::ShellOut
31
+
27
32
  def install_check(name)
28
- command = "python -c \"import sys; print sys.path\""
29
33
  check = false
30
- status = popen4(command) do |pid, stdin, stdout, stderr|
31
- stdout.each do |line|
32
- if line.include? "#{name}"
33
- check = true
34
- end
34
+
35
+ begin
36
+ # first check to see if we can import it
37
+ output = shell_out!("python -c \"import #{name}\"").stderr
38
+ unless output.include? "ImportError"
39
+ check = true
40
+ end
41
+ rescue
42
+ # then check to see if its on the path
43
+ output = shell_out!("python -c \"import sys; print sys.path\"").stdout
44
+ if output.downcase.include? "#{name.downcase}"
45
+ check = true
35
46
  end
36
47
  end
48
+
37
49
  check
38
50
  end
39
51
 
@@ -50,17 +62,19 @@ class Chef
50
62
  # get the currently installed version if installed
51
63
  package_version = nil
52
64
  if install_check(@new_resource.package_name)
53
- command = "python -c \"import #{@new_resource.package_name}; print #{@new_resource.package_name}.__path__\""
54
- status = popen4(command) do |pid, stdin, stdout, stderr|
55
- install_location = stdout.readline
56
- install_location[/\S\S(.*)\/(.*)-(.*)-py(.*).egg\S/]
65
+ begin
66
+ output = shell_out!("python -c \"import #{@new_resource.package_name}; print #{@new_resource.package_name}.__version__\"").stdout
67
+ package_version = output.strip
68
+ rescue
69
+ output = shell_out!("python -c \"import #{@new_resource.package_name}; print #{@new_resource.package_name}.__path__\"").stdout
70
+ output[/\S\S(.*)\/(.*)-(.*)-py(.*).egg\S/]
57
71
  package_version = $3
58
72
  end
59
73
  end
60
74
 
61
75
  if package_version == @new_resource.version
62
76
  Chef::Log.debug("#{@new_resource.package_name} at version #{@new_resource.version}")
63
- @current_resource.version(@new_resource.version)
77
+ @current_resource.version(@new_resource.version)
64
78
  else
65
79
  Chef::Log.debug("#{@new_resource.package_name} at version #{package_version}")
66
80
  @current_resource.version(package_version)
@@ -73,16 +87,9 @@ class Chef
73
87
  return @candidate_version if @candidate_version
74
88
 
75
89
  # do a dry run to get the latest version
76
- command = "#{easy_install_binary_path} -n #{@new_resource.package_name}"
77
- status = popen4(command) do |pid, stdin, stdout, stderr|
78
- dry_run_output = ""
79
- stdout.each do |line|
80
- dry_run_output << line
81
- end
82
- dry_run_output[/(.*)Best match: (.*) (.*)\n/]
83
- @candidate_version = $3
84
- @candidate_version
85
- end
90
+ result = shell_out!("#{easy_install_binary_path} -n #{@new_resource.package_name}", :returns=>[0,1])
91
+ @candidate_version = result.stdout[/(.*)Best match: (.*) (.*)$/, 3]
92
+ @candidate_version
86
93
  end
87
94
 
88
95
  def install_package(name, version)
@@ -104,4 +111,4 @@ class Chef
104
111
  end
105
112
  end
106
113
  end
107
- end
114
+ end
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Daniel DeLeo (<dan@opscode.com>)
4
4
  # Copyright:: Copyright (c) 2008, 2010 Opscode, Inc.
@@ -22,12 +22,6 @@ require 'chef/mixin/template'
22
22
  require 'chef/mixin/checksum'
23
23
  require 'chef/file_access_control'
24
24
 
25
- #require 'chef/mixin/find_preferred_file'
26
- #require 'chef/rest'
27
- #require 'chef/file_cache'
28
- #require 'uri'
29
- #require 'tempfile'
30
-
31
25
  class Chef
32
26
  class Provider
33
27
 
@@ -35,7 +29,6 @@ class Chef
35
29
 
36
30
  include Chef::Mixin::Checksum
37
31
  include Chef::Mixin::Template
38
- #include Chef::Mixin::FindPreferredFile
39
32
 
40
33
  def load_current_resource
41
34
  super
@@ -98,45 +91,8 @@ class Chef
98
91
  @new_resource.updated = access_controls.modified?
99
92
  end
100
93
 
101
- # def locate_or_fetch_template
102
- # Chef::Log.debug("looking for template #{@new_resource.source} in cookbook #{cookbook_name.inspect}")
103
- #
104
- # cache_file_name = "cookbooks/#{cookbook_name}/templates/default/#{@new_resource.source}"
105
- # template_cache_name = "#{cookbook_name}_#{@new_resource.source}"
106
- #
107
- # if @new_resource.local
108
- # cache_file_name = @new_resource.source
109
- # elsif Chef::Config[:solo]
110
- # cache_file_name = solo_cache_file_name
111
- # else
112
- # raw_template_file = fetch_template_via_rest(cache_file_name, template_cache_name)
113
- # end
114
- #
115
- # if template_updated?
116
- # Chef::Log.debug("Updating template for #{@new_resource} in the cache")
117
- # Chef::FileCache.move_to(raw_template_file.path, cache_file_name)
118
- # end
119
- # cache_file_name
120
- # end
121
-
122
94
  private
123
95
 
124
- # def template_updated
125
- # @template_updated = true
126
- # end
127
- #
128
- # def template_not_updated
129
- # @template_updated = false
130
- # end
131
- #
132
- # def template_updated?
133
- # @template_updated
134
- # end
135
- #
136
- # def cookbook_name
137
- # @cookbook_name = (@new_resource.cookbook || @new_resource.cookbook_name)
138
- # end
139
-
140
96
  def render_with_context(template_location, &block)
141
97
  context = {}
142
98
  context.merge!(@new_resource.variables)
@@ -144,55 +100,6 @@ class Chef
144
100
  render_template(IO.read(template_location), context, &block)
145
101
  end
146
102
 
147
- # def solo_cache_file_name
148
- # filename = find_preferred_file(
149
- # cookbook_name,
150
- # :template,
151
- # @new_resource.source,
152
- # node[:fqdn],
153
- # node[:platform],
154
- # node[:platform_version]
155
- # )
156
- # Chef::Log.debug("Using local file for template:#{filename}")
157
- # Pathname.new(filename).relative_path_from(Pathname.new(Chef::Config[:file_cache_path])).to_s
158
- # end
159
- #
160
- # def fetch_template_via_rest(cache_file_name, template_cache_name)
161
- # if node.run_state[:template_cache].has_key?(template_cache_name)
162
- # Chef::Log.debug("I have already fetched the template for #{@new_resource} once this run, not checking again.")
163
- # template_not_updated
164
- # return false
165
- # end
166
- #
167
- # r = Chef::REST.new(Chef::Config[:template_url])
168
- #
169
- # current_checksum = nil
170
- #
171
- # if Chef::FileCache.has_key?(cache_file_name)
172
- # current_checksum = self.checksum(Chef::FileCache.load(cache_file_name, false))
173
- # else
174
- # Chef::Log.debug("Template #{@new_resource} is not in the template cache")
175
- # end
176
- #
177
- # template_url = generate_url(@new_resource.source, "templates", :checksum => current_checksum)
178
- #
179
- # begin
180
- # raw_template_file = r.get_rest(template_url, true)
181
- # template_updated
182
- # rescue Net::HTTPRetriableError
183
- # if e.response.kind_of?(Net::HTTPNotModified)
184
- # Chef::Log.debug("Cached template for #{@new_resource} is unchanged")
185
- # else
186
- # raise
187
- # end
188
- # end
189
- #
190
- # # We have checked the cache for this template this run
191
- # node.run_state[:template_cache][template_cache_name] = true
192
- #
193
- # raw_template_file
194
- # end
195
-
196
103
  end
197
104
  end
198
105
  end
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Christopher Walters (<cw@opscode.com>)
4
4
  # Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
@@ -26,6 +26,8 @@ require 'chef/mixin/language_include_recipe'
26
26
  require 'chef/mixin/deprecation'
27
27
 
28
28
  class Chef
29
+ # == Chef::Recipe
30
+ # A Recipe object is the context in which Chef recipes are evaluated.
29
31
  class Recipe
30
32
 
31
33
  include Chef::Mixin::FromFile
@@ -42,6 +44,8 @@ class Chef
42
44
  # For example:
43
45
  # "aws::elastic_ip" returns [:aws, "elastic_ip"]
44
46
  # "aws" returns [:aws, "default"]
47
+ #--
48
+ # TODO: Duplicates functionality of RunListItem
45
49
  def self.parse_recipe_name(recipe_name)
46
50
  rmatch = recipe_name.match(/(.+?)::(.+)/)
47
51
  if rmatch
@@ -65,10 +69,10 @@ class Chef
65
69
  run_context.node
66
70
  end
67
71
 
72
+ # Used by the DSL to look up resources when executing in the context of a
73
+ # recipe.
74
+ #--
68
75
  # what does this do? and what is args? TODO 5-14-2010.
69
- #
70
- # We believe this is used by the DSL when it's executing in the
71
- # context of a recipe in order to look up resources.
72
76
  def resources(*args)
73
77
  run_context.resource_collection.find(*args)
74
78
  end
@@ -83,9 +87,9 @@ class Chef
83
87
  #
84
88
  # === Returns
85
89
  # tags<Array>:: The contents of run_context.node[:tags]
86
- def tag(*args)
87
- if args.length > 0
88
- args.each do |tag|
90
+ def tag(*tags)
91
+ if tags.length > 0
92
+ tags.each do |tag|
89
93
  run_context.node[:tags] << tag unless run_context.node[:tags].include?(tag)
90
94
  end
91
95
  run_context.node[:tags]
@@ -94,7 +98,7 @@ class Chef
94
98
  end
95
99
  end
96
100
 
97
- # Returns true if the node is tagged with the supplied list of tags.
101
+ # Returns true if the node is tagged with *all* of the supplied +tags+.
98
102
  #
99
103
  # === Parameters
100
104
  # tags<Array>:: A list of tags
@@ -102,8 +106,8 @@ class Chef
102
106
  # === Returns
103
107
  # true<TrueClass>:: If all the parameters are present
104
108
  # false<FalseClass>:: If any of the parameters are missing
105
- def tagged?(*args)
106
- args.each do |tag|
109
+ def tagged?(*tags)
110
+ tags.each do |tag|
107
111
  return false unless run_context.node[:tags].include?(tag)
108
112
  end
109
113
  true
@@ -116,8 +120,8 @@ class Chef
116
120
  #
117
121
  # === Returns
118
122
  # tags<Array>:: The current list of run_context.node[:tags]
119
- def untag(*args)
120
- args.each do |tag|
123
+ def untag(*tags)
124
+ tags.each do |tag|
121
125
  run_context.node[:tags].delete(tag)
122
126
  end
123
127
  end
@@ -1,4 +1,4 @@
1
- #
1
+ #--
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
3
  # Author:: Thom May (<thom@clearairturbulence.org>)
4
4
  # Author:: Nuo Yan (<nuo@opscode.com>)
@@ -30,10 +30,17 @@ require 'chef/rest/rest_request'
30
30
  require 'chef/monkey_patches/string'
31
31
 
32
32
  class Chef
33
+ # == Chef::REST
34
+ # Chef's custom REST client with built-in JSON support and RSA signed header
35
+ # authentication.
33
36
  class REST
34
37
  attr_reader :auth_credentials
35
38
  attr_accessor :url, :cookies, :sign_on_redirect, :redirect_limit
36
39
 
40
+ # Create a REST client object. The supplied +url+ is used as the base for
41
+ # all subsequent requests. For example, when initialized with a base url
42
+ # http://localhost:4000, a call to +get_rest+ with 'nodes' will make an
43
+ # HTTP GET request to http://localhost:4000/nodes
37
44
  def initialize(url, client_name=Chef::Config[:node_name], signing_key_filename=Chef::Config[:client_key], options={})
38
45
  @url = url
39
46
  @cookies = CookieJar.instance
@@ -90,6 +97,8 @@ class Chef
90
97
 
91
98
  # Send an HTTP GET request to the path
92
99
  #
100
+ # Using this method to +fetch+ a file is considered deprecated.
101
+ #
93
102
  # === Parameters
94
103
  # path:: The path to GET
95
104
  # raw:: Whether you want the raw body returned, or JSON inflated. Defaults
@@ -138,6 +147,9 @@ class Chef
138
147
  auth_credentials.sign_requests? && @sign_request
139
148
  end
140
149
 
150
+ # ==== DEPRECATED
151
+ # Use +api_request+ instead
152
+ #--
141
153
  # Actually run an HTTP request. First argument is the HTTP method,
142
154
  # which should be one of :GET, :PUT, :POST or :DELETE. Next is the
143
155
  # URL, then an object to include in the body (which will be converted with
@@ -190,7 +202,7 @@ class Chef
190
202
  end
191
203
  end
192
204
 
193
- # Similar to #run_request but only supports JSON APIs. File Download not supported.
205
+ # Runs an HTTP request to a JSON API. File Download not supported.
194
206
  def api_request(method, url, headers={}, data=false)
195
207
  json_body = data ? data.to_json : nil
196
208
  headers = build_headers(method, url, headers, json_body)
@@ -219,11 +231,11 @@ class Chef
219
231
  end
220
232
  end
221
233
 
222
- # similar to #run_request but only supports streaming downloads.
223
- # Only supports GET, doesn't speak JSON
234
+ # Makes a streaming download request. <b>Doesn't speak JSON.</b>
224
235
  # Streams the response body to a tempfile. If a block is given, it's
225
- # passed to the tempfile, which means that the tempfile will automatically
236
+ # passed to Tempfile.open(), which means that the tempfile will automatically
226
237
  # be unlinked after the block is executed.
238
+ #
227
239
  # If no block is given, the tempfile is returned, which means it's up to
228
240
  # you to unlink the tempfile when you're done with it.
229
241
  def streaming_request(url, headers, &block)