chef 0.8.16 → 0.9.0.a3

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 (185) hide show
  1. data/bin/shef +1 -0
  2. data/distro/common/man/man1/chef-server-webui.1 +106 -0
  3. data/distro/common/man/man1/chef-server.1 +0 -1
  4. data/distro/common/man/man1/chef-solr-indexer.1 +55 -0
  5. data/distro/common/man/man1/chef-solr.1 +55 -0
  6. data/distro/common/man/man8/chef-client.8 +4 -2
  7. data/distro/common/man/man8/chef-solo.8 +1 -2
  8. data/distro/common/man/man8/chef-solr-rebuild.8 +37 -0
  9. data/distro/common/man/man8/knife.8 +668 -266
  10. data/distro/common/man/man8/shef.8 +45 -0
  11. data/distro/common/markdown/README +3 -0
  12. data/distro/common/markdown/knife.mkd +520 -0
  13. data/distro/debian/etc/default/chef-client +4 -0
  14. data/distro/debian/etc/default/chef-server +6 -0
  15. data/distro/debian/etc/default/chef-server-webui +6 -0
  16. data/distro/debian/etc/default/chef-solr +4 -0
  17. data/distro/debian/etc/default/chef-solr-indexer +4 -0
  18. data/distro/debian/etc/init.d/chef-client +41 -41
  19. data/distro/debian/etc/init.d/chef-server +10 -10
  20. data/distro/debian/etc/init.d/chef-server-webui +121 -0
  21. data/distro/debian/etc/init.d/chef-solr +177 -0
  22. data/distro/debian/etc/init.d/chef-solr-indexer +176 -0
  23. data/distro/redhat/etc/init.d/chef-client +76 -48
  24. data/distro/redhat/etc/init.d/chef-server +85 -51
  25. data/distro/redhat/etc/init.d/chef-server-webui +85 -51
  26. data/distro/redhat/etc/init.d/chef-solr +77 -49
  27. data/distro/redhat/etc/init.d/chef-solr-indexer +77 -48
  28. data/distro/redhat/etc/logrotate.d/chef-client +8 -0
  29. data/distro/redhat/etc/logrotate.d/chef-server +8 -0
  30. data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
  31. data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
  32. data/distro/redhat/etc/logrotate.d/chef-solr-indexer +8 -0
  33. data/distro/redhat/etc/sysconfig/chef-client +9 -4
  34. data/distro/redhat/etc/sysconfig/chef-server +10 -6
  35. data/distro/redhat/etc/sysconfig/chef-server-webui +10 -6
  36. data/distro/redhat/etc/sysconfig/chef-solr +3 -4
  37. data/distro/redhat/etc/sysconfig/chef-solr-indexer +3 -3
  38. data/lib/chef.rb +16 -5
  39. data/lib/chef/application/knife.rb +2 -2
  40. data/lib/chef/application/solo.rb +1 -7
  41. data/lib/chef/cache/checksum.rb +12 -5
  42. data/lib/chef/cache/file_cache_by_checksum.rb +52 -0
  43. data/lib/chef/checksum.rb +115 -0
  44. data/lib/chef/client.rb +193 -185
  45. data/lib/chef/config.rb +9 -1
  46. data/lib/chef/cookbook/cookbook_collection.rb +43 -0
  47. data/lib/chef/cookbook/file_system_file_vendor.rb +53 -0
  48. data/lib/chef/cookbook/file_vendor.rb +47 -0
  49. data/lib/chef/cookbook/metadata.rb +34 -35
  50. data/lib/chef/cookbook/metadata/version.rb +1 -1
  51. data/lib/chef/cookbook_loader.rb +70 -45
  52. data/lib/chef/cookbook_version.rb +760 -0
  53. data/lib/chef/couchdb.rb +8 -5
  54. data/lib/chef/data_bag_item.rb +5 -5
  55. data/lib/chef/exceptions.rb +10 -0
  56. data/lib/chef/file_access_control.rb +134 -0
  57. data/lib/chef/handler.rb +62 -0
  58. data/lib/chef/handler/json_file.rb +47 -0
  59. data/lib/chef/knife.rb +14 -2
  60. data/lib/chef/knife/bootstrap.rb +126 -0
  61. data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
  62. data/lib/chef/knife/cookbook_delete.rb +4 -4
  63. data/lib/chef/knife/cookbook_download.rb +57 -26
  64. data/lib/chef/knife/cookbook_metadata.rb +2 -2
  65. data/lib/chef/knife/cookbook_show.rb +30 -11
  66. data/lib/chef/knife/cookbook_upload.rb +113 -86
  67. data/lib/chef/knife/ec2_server_create.rb +146 -0
  68. data/lib/chef/knife/ec2_server_delete.rb +84 -0
  69. data/lib/chef/knife/ec2_server_list.rb +82 -0
  70. data/lib/chef/knife/status.rb +51 -0
  71. data/lib/chef/mixin/language_include_attribute.rb +16 -11
  72. data/lib/chef/mixin/language_include_recipe.rb +15 -16
  73. data/lib/chef/mixin/recipe_definition_dsl_core.rb +17 -20
  74. data/lib/chef/mixin/shell_out.rb +38 -0
  75. data/lib/chef/mixins.rb +1 -1
  76. data/lib/chef/node.rb +190 -63
  77. data/lib/chef/node/attribute.rb +92 -78
  78. data/lib/chef/platform.rb +24 -4
  79. data/lib/chef/provider.rb +28 -10
  80. data/lib/chef/provider/breakpoint.rb +2 -2
  81. data/lib/chef/provider/cookbook_file.rb +96 -0
  82. data/lib/chef/provider/cron.rb +2 -2
  83. data/lib/chef/provider/deploy.rb +12 -10
  84. data/lib/chef/provider/env.rb +152 -0
  85. data/lib/chef/provider/env/windows.rb +75 -0
  86. data/lib/chef/provider/file.rb +10 -14
  87. data/lib/chef/provider/group.rb +15 -2
  88. data/lib/chef/provider/group/dscl.rb +17 -25
  89. data/lib/chef/provider/group/gpasswd.rb +6 -3
  90. data/lib/chef/provider/group/pw.rb +3 -7
  91. data/lib/chef/provider/group/windows.rb +79 -0
  92. data/lib/chef/provider/link.rb +4 -5
  93. data/lib/chef/provider/mdadm.rb +25 -18
  94. data/lib/chef/provider/mount/mount.rb +28 -27
  95. data/lib/chef/provider/package.rb +35 -35
  96. data/lib/chef/provider/package/dpkg.rb +13 -10
  97. data/lib/chef/provider/package/easy_install.rb +6 -6
  98. data/lib/chef/provider/package/freebsd.rb +17 -51
  99. data/lib/chef/provider/package/rpm.rb +1 -1
  100. data/lib/chef/provider/package/rubygems.rb +391 -74
  101. data/lib/chef/provider/package/yum.rb +2 -2
  102. data/lib/chef/provider/package/zypper.rb +2 -1
  103. data/lib/chef/provider/remote_directory.rb +60 -83
  104. data/lib/chef/provider/remote_file.rb +17 -66
  105. data/lib/chef/provider/script.rb +20 -9
  106. data/lib/chef/provider/service.rb +23 -30
  107. data/lib/chef/provider/service/arch.rb +3 -3
  108. data/lib/chef/provider/service/debian.rb +22 -17
  109. data/lib/chef/provider/service/freebsd.rb +4 -4
  110. data/lib/chef/provider/service/init.rb +2 -2
  111. data/lib/chef/provider/service/redhat.rb +14 -16
  112. data/lib/chef/provider/service/simple.rb +7 -3
  113. data/lib/chef/provider/service/solaris.rb +85 -0
  114. data/lib/chef/provider/service/upstart.rb +12 -7
  115. data/lib/chef/provider/service/windows.rb +2 -2
  116. data/lib/chef/provider/template.rb +133 -118
  117. data/lib/chef/provider/user.rb +34 -17
  118. data/lib/chef/provider/user/dscl.rb +117 -114
  119. data/lib/chef/provider/user/windows.rb +124 -0
  120. data/lib/chef/providers.rb +7 -0
  121. data/lib/chef/recipe.rb +39 -20
  122. data/lib/chef/resource.rb +47 -52
  123. data/lib/chef/resource/apt_package.rb +4 -4
  124. data/lib/chef/resource/bash.rb +4 -4
  125. data/lib/chef/resource/cookbook_file.rb +45 -0
  126. data/lib/chef/resource/cron.rb +3 -3
  127. data/lib/chef/resource/csh.rb +4 -4
  128. data/lib/chef/resource/deploy.rb +3 -3
  129. data/lib/chef/resource/directory.rb +4 -4
  130. data/lib/chef/resource/dpkg_package.rb +4 -4
  131. data/lib/chef/resource/easy_install_package.rb +3 -3
  132. data/lib/chef/resource/env.rb +58 -0
  133. data/lib/chef/resource/erl_call.rb +3 -3
  134. data/lib/chef/resource/execute.rb +3 -3
  135. data/lib/chef/resource/file.rb +3 -3
  136. data/lib/chef/resource/freebsd_package.rb +3 -3
  137. data/lib/chef/resource/gem_package.rb +17 -9
  138. data/lib/chef/resource/git.rb +3 -3
  139. data/lib/chef/resource/group.rb +3 -3
  140. data/lib/chef/resource/http_request.rb +4 -4
  141. data/lib/chef/resource/ifconfig.rb +3 -3
  142. data/lib/chef/resource/link.rb +3 -3
  143. data/lib/chef/resource/log.rb +2 -2
  144. data/lib/chef/resource/macports_package.rb +2 -2
  145. data/lib/chef/resource/mdadm.rb +3 -3
  146. data/lib/chef/resource/mount.rb +2 -2
  147. data/lib/chef/resource/package.rb +4 -4
  148. data/lib/chef/resource/pacman_package.rb +4 -4
  149. data/lib/chef/resource/perl.rb +4 -4
  150. data/lib/chef/resource/portage_package.rb +4 -4
  151. data/lib/chef/resource/python.rb +4 -4
  152. data/lib/chef/resource/remote_directory.rb +3 -3
  153. data/lib/chef/resource/remote_file.rb +26 -3
  154. data/lib/chef/resource/route.rb +3 -3
  155. data/lib/chef/resource/ruby.rb +3 -3
  156. data/lib/chef/resource/ruby_block.rb +3 -2
  157. data/lib/chef/resource/scm.rb +7 -5
  158. data/lib/chef/resource/script.rb +4 -4
  159. data/lib/chef/resource/service.rb +3 -3
  160. data/lib/chef/resource/subversion.rb +4 -2
  161. data/lib/chef/resource/template.rb +3 -3
  162. data/lib/chef/resource/user.rb +3 -3
  163. data/lib/chef/resource/yum_package.rb +3 -3
  164. data/lib/chef/resource_collection.rb +9 -5
  165. data/lib/chef/resources.rb +2 -0
  166. data/lib/chef/rest.rb +4 -0
  167. data/lib/chef/role.rb +2 -0
  168. data/lib/chef/run_context.rb +108 -0
  169. data/lib/chef/run_list.rb +75 -98
  170. data/lib/chef/run_list/run_list_expansion.rb +156 -0
  171. data/lib/chef/run_list/run_list_item.rb +71 -0
  172. data/lib/chef/runner.rb +58 -61
  173. data/lib/chef/sandbox.rb +147 -0
  174. data/lib/chef/shef.rb +4 -3
  175. data/lib/chef/shef/ext.rb +12 -4
  176. data/lib/chef/shef/shef_session.rb +27 -23
  177. data/lib/chef/shell_out.rb +375 -0
  178. data/lib/chef/util/windows.rb +56 -0
  179. data/lib/chef/util/windows/net_group.rb +101 -0
  180. data/lib/chef/util/windows/net_user.rb +198 -0
  181. data/lib/chef/version.rb +20 -0
  182. metadata +112 -22
  183. data/lib/chef/compile.rb +0 -158
  184. data/lib/chef/cookbook.rb +0 -201
  185. data/lib/chef/mixin/generate_url.rb +0 -58
@@ -21,9 +21,9 @@ require 'chef/resource/file'
21
21
  class Chef
22
22
  class Resource
23
23
  class RemoteFile < Chef::Resource::File
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :remote_file
28
28
  @action = "create"
29
29
  @source = ::File.basename(name)
@@ -54,6 +54,29 @@ class Chef
54
54
  )
55
55
  end
56
56
 
57
+ # The provider that should be used for this resource.
58
+ # === Returns:
59
+ # Chef::Provider::RemoteFile when the source is an absolute URI, like
60
+ # http://www.google.com/robots.txt
61
+ # Chef::Provider::CookbookFile when the source is a relative URI, like
62
+ # 'myscript.pl', 'dir/config.conf'
63
+ def provider
64
+ if absolute_uri?(source)
65
+ Chef::Provider::RemoteFile
66
+ else
67
+ # contentious...
68
+ Chef::Log.warn("remote_file is deprecated for fetching files from cookbooks. Use cookbook_file instead")
69
+ Chef::Provider::CookbookFile
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def absolute_uri?(source)
76
+ URI.parse(source).absolute?
77
+ rescue URI::InvalidURIError
78
+ false
79
+ end
57
80
 
58
81
  end
59
82
  end
@@ -21,9 +21,9 @@ require 'chef/resource'
21
21
  class Chef
22
22
  class Resource
23
23
  class Route < Chef::Resource
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :route
28
28
  @target = name
29
29
  @action = :add
@@ -21,9 +21,9 @@ require 'chef/resource/script'
21
21
  class Chef
22
22
  class Resource
23
23
  class Ruby < Chef::Resource::Script
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :ruby
28
28
  @interpreter = "ruby"
29
29
  end
@@ -20,8 +20,9 @@
20
20
  class Chef
21
21
  class Resource
22
22
  class RubyBlock < Chef::Resource
23
- def initialize(name, collection=nil, node=nil)
24
- super(name, collection, node)
23
+
24
+ def initialize(name, run_context=nil)
25
+ super
25
26
  @resource_name = :ruby_block
26
27
  @action = "create"
27
28
  @allowed_actions.push(:create)
@@ -22,9 +22,9 @@ require 'chef/resource'
22
22
  class Chef
23
23
  class Resource
24
24
  class Scm < Chef::Resource
25
-
26
- def initialize(name, collection=nil, node=nil)
27
- super(name, collection, node)
25
+
26
+ def initialize(name, run_context=nil)
27
+ super
28
28
  @destination = name
29
29
  @resource_name = :scm
30
30
  @enable_submodules = false
@@ -92,6 +92,7 @@ class Chef
92
92
  end
93
93
 
94
94
  def svn_arguments(arg=nil)
95
+ @svn_arguments, arg = nil, nil if arg == false
95
96
  set_or_return(
96
97
  :svn_arguments,
97
98
  arg,
@@ -100,8 +101,9 @@ class Chef
100
101
  end
101
102
 
102
103
  def svn_info_args(arg=nil)
104
+ @svn_info_args, arg = nil, nil if arg == false
103
105
  set_or_return(
104
- :svn_arguments,
106
+ :svn_info_args,
105
107
  arg,
106
108
  :kind_of => String)
107
109
  end
@@ -141,4 +143,4 @@ class Chef
141
143
 
142
144
  end
143
145
  end
144
- end
146
+ end
@@ -21,9 +21,9 @@ require 'chef/resource/execute'
21
21
  class Chef
22
22
  class Resource
23
23
  class Script < Chef::Resource::Execute
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :script
28
28
  @command = name
29
29
  @code = nil
@@ -48,4 +48,4 @@ class Chef
48
48
 
49
49
  end
50
50
  end
51
- end
51
+ end
@@ -21,9 +21,9 @@ require 'chef/resource'
21
21
  class Chef
22
22
  class Resource
23
23
  class Service < Chef::Resource
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :service
28
28
  @service_name = name
29
29
  @enabled = nil
@@ -22,8 +22,10 @@ class Chef
22
22
  class Resource
23
23
  class Subversion < Chef::Resource::Scm
24
24
 
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
25
+ def initialize(name, run_context=nil)
26
+ super
27
+ @svn_arguments = '--no-auth-cache'
28
+ @svn_info_args = '--no-auth-cache'
27
29
  @resource_name = :subversion
28
30
  @provider = Chef::Provider::Subversion
29
31
  allowed_actions << :force_export
@@ -21,9 +21,9 @@ require 'chef/resource/file'
21
21
  class Chef
22
22
  class Resource
23
23
  class Template < Chef::Resource::File
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :template
28
28
  @action = "create"
29
29
  @source = "#{::File.basename(name)}.erb"
@@ -21,9 +21,9 @@ require 'chef/resource'
21
21
  class Chef
22
22
  class Resource
23
23
  class User < Chef::Resource
24
-
25
- def initialize(name, collection=nil, node=nil)
26
- super(name, collection, node)
24
+
25
+ def initialize(name, run_context=nil)
26
+ super
27
27
  @resource_name = :user
28
28
  @username = name
29
29
  @comment = nil
@@ -22,9 +22,9 @@ require 'chef/provider/package/yum'
22
22
  class Chef
23
23
  class Resource
24
24
  class YumPackage < Chef::Resource::Package
25
-
26
- def initialize(name, collection=nil, node=nil)
27
- super(name, collection, node)
25
+
26
+ def initialize(name, run_context=nil)
27
+ super
28
28
  @resource_name = :yum_package
29
29
  @provider = Chef::Provider::Package::Yum
30
30
  end
@@ -120,16 +120,16 @@ class Chef
120
120
  # Find existing resources by searching the list of existing resources. Possible
121
121
  # forms are:
122
122
  #
123
- # resources(:file => "foobar")
124
- # resources(:file => [ "foobar", "baz" ])
125
- # resources("file[foobar]", "file[baz]")
126
- # resources("file[foobar,baz]")
123
+ # find(:file => "foobar")
124
+ # find(:file => [ "foobar", "baz" ])
125
+ # find("file[foobar]", "file[baz]")
126
+ # find("file[foobar,baz]")
127
127
  #
128
128
  # Returns the matching resource, or an Array of matching resources.
129
129
  #
130
130
  # Raises an ArgumentError if you feed it bad lookup information
131
131
  # Raises a Runtime Error if it can't find the resources you are looking for.
132
- def resources(*args)
132
+ def find(*args)
133
133
  results = Array.new
134
134
  args.each do |arg|
135
135
  case arg
@@ -145,6 +145,10 @@ class Chef
145
145
  flat_results.length == 1 ? flat_results[0] : flat_results
146
146
  end
147
147
 
148
+ # resources is a poorly named, but we have to maintain it for back
149
+ # compat.
150
+ alias_method :resources, :find
151
+
148
152
  # Serialize this object as a hash
149
153
  def to_json(*a)
150
154
  instance_vars = Hash.new
@@ -19,6 +19,7 @@
19
19
  require 'chef/resource/apt_package'
20
20
  require 'chef/resource/bash'
21
21
  require 'chef/resource/breakpoint'
22
+ require 'chef/resource/cookbook_file'
22
23
  require 'chef/resource/cron'
23
24
  require 'chef/resource/csh'
24
25
  require 'chef/resource/deploy'
@@ -26,6 +27,7 @@ require 'chef/resource/deploy_revision'
26
27
  require 'chef/resource/directory'
27
28
  require 'chef/resource/dpkg_package'
28
29
  require 'chef/resource/easy_install_package'
30
+ require 'chef/resource/env'
29
31
  require 'chef/resource/erl_call'
30
32
  require 'chef/resource/execute'
31
33
  require 'chef/resource/file'
@@ -339,12 +339,16 @@ class Chef
339
339
  headers = @default_headers.merge(headers)
340
340
  headers['Accept'] = "application/json" unless raw
341
341
  headers["Content-Type"] = 'application/json' if json_body
342
+ headers['Content-Length'] = json_body.bytesize.to_s if json_body
342
343
  headers.merge!(authentication_headers(method, url, json_body)) if sign_requests?
343
344
  headers
344
345
  end
345
346
 
346
347
  def stream_to_tempfile(url, response)
347
348
  tf = Tempfile.open("chef-rest")
349
+ if RUBY_PLATFORM =~ /mswin|mingw32|windows/
350
+ tf.binmode #required for binary files on Windows platforms
351
+ end
348
352
  Chef::Log.debug("Streaming download from #{url.to_s} to tempfile #{tf.path}")
349
353
  # Stolen from http://www.ruby-forum.com/topic/166423
350
354
  # Kudos to _why!
@@ -275,6 +275,8 @@ class Chef
275
275
  role.name(name)
276
276
  role.from_file(rb_file)
277
277
  role
278
+ else
279
+ raise Chef::Exceptions::RoleNotFound, "Role '#{name}' could not be loaded from disk"
278
280
  end
279
281
  end
280
282
 
@@ -0,0 +1,108 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
4
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008-2010 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ require 'chef/resource_collection'
21
+ require 'chef/node'
22
+ require 'chef/role'
23
+ require 'chef/log'
24
+ require 'chef/mixin/language_include_recipe'
25
+
26
+ # Value object that loads and tracks the context of a Chef run
27
+ class Chef
28
+ class RunContext
29
+
30
+ # Used to load the node's recipes after expanding its run list
31
+ include Chef::Mixin::LanguageIncludeRecipe
32
+
33
+ attr_reader :node, :cookbook_collection, :definitions
34
+
35
+ # Needs to be settable so deploy can run a resource_collection independent
36
+ # of any cookbooks.
37
+ attr_accessor :resource_collection
38
+
39
+ # Creates a new Chef::RunContext object and populates its fields. This object gets
40
+ # used by the Chef Server to generate a fully compiled recipe list for a node.
41
+ #
42
+ # === Returns
43
+ # object<Chef::RunContext>:: Duh. :)
44
+ def initialize(node, cookbook_collection)
45
+ @node = node
46
+ @cookbook_collection = cookbook_collection
47
+ @resource_collection = Chef::ResourceCollection.new
48
+ @definitions = Hash.new
49
+
50
+ # TODO: 5/18/2010 cw/timh - See note on Chef::Node's
51
+ # cookbook_collection attr_accessor
52
+ node.cookbook_collection = cookbook_collection
53
+
54
+ load
55
+ end
56
+
57
+ def load
58
+ foreach_cookbook_load_segment(:libraries) do |cookbook_name, filename|
59
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s library file: #{filename}")
60
+ require filename
61
+ end
62
+
63
+ foreach_cookbook_load_segment(:providers) do |cookbook_name, filename|
64
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s providers from #{filename}")
65
+ Chef::Provider.build_from_file(cookbook_name, filename)
66
+ end
67
+
68
+ foreach_cookbook_load_segment(:resources) do |cookbook_name, filename|
69
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s resources from #{filename}")
70
+ Chef::Resource.build_from_file(cookbook_name, filename)
71
+ end
72
+
73
+ node.load_attributes
74
+
75
+ foreach_cookbook_load_segment(:definitions) do |cookbook_name, filename|
76
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s definitions from #{filename}")
77
+ resourcelist = Chef::ResourceDefinitionList.new
78
+ resourcelist.from_file(filename)
79
+ definitions.merge!(resourcelist.defines) do |key, oldval, newval|
80
+ Chef::Log.info("Overriding duplicate definition #{key}, new found in #{filename}")
81
+ newval
82
+ end
83
+ end
84
+
85
+ # Retrieve the fully expanded list of recipes for the node by
86
+ # resolving roles; this step also merges attributes into the
87
+ # node from the roles/recipes included.
88
+ recipe_names = node.expand_node!
89
+ recipe_names.each do |recipe_name|
90
+ # TODO: timh/cw, 5-14-2010: It's distasteful to be including
91
+ # the DSL in a class outside the context of the DSL
92
+ include_recipe(recipe_name)
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def foreach_cookbook_load_segment(segment, &block)
99
+ cookbook_collection.each do |cookbook_name, cookbook|
100
+ segment_filenames = cookbook.segment_filenames(segment)
101
+ segment_filenames.each do |segment_filename|
102
+ block.call(cookbook_name, segment_filename)
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
@@ -1,100 +1,109 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
3
+ # Author:: Nuo Yan (<nuoyan@opscode.com>)
4
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
5
+ # Author:: Christopher Walters (<cw@opscode.com>)
6
+ # Copyright:: Copyright (c) 2008-2010 Opscode, Inc.
4
7
  # License:: Apache License, Version 2.0
5
8
  #
6
9
  # Licensed under the Apache License, Version 2.0 (the "License");
7
10
  # you may not use this file except in compliance with the License.
8
11
  # You may obtain a copy of the License at
9
- #
12
+ #
10
13
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
14
+ #
12
15
  # Unless required by applicable law or agreed to in writing, software
13
16
  # distributed under the License is distributed on an "AS IS" BASIS,
14
17
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
18
  # See the License for the specific language governing permissions and
16
19
  # limitations under the License.
17
20
 
18
- require 'chef/mixin/deep_merge'
21
+ require 'chef/run_list/run_list_item'
22
+ require 'chef/run_list/run_list_expansion'
19
23
 
20
24
  class Chef
21
25
  class RunList
22
26
  include Enumerable
23
27
 
24
- attr_reader :recipes, :roles, :run_list
28
+ # @run_list_items is an array of RunListItems that describe the items to
29
+ # execute in order. RunListItems can load from and convert to the string
30
+ # forms users set on roles and nodes.
31
+ # For example:
32
+ # @run_list_items = ['recipe[foo::bar]', 'role[webserver]']
33
+ # Thus,
34
+ # self.role_names would return ['webserver']
35
+ # self.recipe_names would return ['foo::bar']
36
+ attr_reader :run_list_items
37
+
38
+ # For backwards compat
39
+ alias :run_list :run_list_items
25
40
 
26
41
  def initialize
27
- @run_list = Array.new
28
- @recipes = Array.new
29
- @roles = Array.new
30
- @seen_roles = Array.new
31
- end
32
-
33
- def <<(item)
34
- type, entry, fentry = parse_entry(item)
35
- case type
36
- when 'recipe'
37
- @recipes << entry unless @recipes.include?(entry)
38
- when 'role'
39
- @roles << entry unless @roles.include?(entry)
40
- end
41
- @run_list << fentry unless @run_list.include?(fentry)
42
+ @run_list_items = Array.new
43
+ end
44
+
45
+ def role_names
46
+ @run_list_items.inject([]){|memo, run_list_item| memo << run_list_item.name if run_list_item.role? ; memo}
47
+ end
48
+
49
+ alias :roles :role_names
50
+
51
+ def recipe_names
52
+ @run_list_items.inject([]){|memo, run_list_item| memo << run_list_item.name if run_list_item.recipe? ; memo}
53
+ end
54
+
55
+ alias :recipes :recipe_names
56
+
57
+ # Add an item of the form "recipe[foo::bar]" or "role[webserver]";
58
+ # takes a String or a RunListItem
59
+ def <<(run_list_item)
60
+ run_list_item = run_list_item.kind_of?(RunListItem) ? run_list_item : parse_entry(run_list_item)
61
+ @run_list_items << run_list_item unless @run_list_items.include?(run_list_item)
42
62
  self
43
63
  end
44
64
 
45
- def ==(*isequal)
46
- check_array = nil
47
- if isequal[0].kind_of?(Chef::RunList)
48
- check_array = isequal[0].run_list
65
+ def ==(other)
66
+ if other.kind_of?(Chef::RunList)
67
+ other.run_list_items == @run_list_items
49
68
  else
50
- check_array = isequal.flatten
51
- end
52
-
53
- return false if check_array.length != @run_list.length
69
+ other_run_list_items = other
70
+ return false unless other_run_list_items.size == @run_list_items.size
54
71
 
55
- check_array.each_index do |i|
56
- to_check = check_array[i]
57
- type, name, fname = parse_entry(to_check)
58
- return false if @run_list[i] != fname
72
+ other_run_list_items.map! { |item| item.kind_of?(RunListItem) ? item : RunListItem.new(item) }
73
+ other_run_list_items == @run_list_items
59
74
  end
60
-
61
- true
62
75
  end
63
76
 
64
77
  def to_s
65
- @run_list.join(", ")
78
+ @run_list_items.join(", ")
66
79
  end
67
80
 
68
81
  def empty?
69
- @run_list.length == 0 ? true : false
82
+ @run_list_items.length == 0 ? true : false
70
83
  end
71
84
 
72
85
  def [](pos)
73
- @run_list[pos]
86
+ @run_list_items[pos]
74
87
  end
75
88
 
76
89
  def []=(pos, item)
77
- type, entry, fentry = parse_entry(item)
78
- @run_list[pos] = fentry
90
+ @run_list_items[pos] = parse_entry(item)
79
91
  end
80
92
 
81
93
  def each(&block)
82
- @run_list.each { |i| block.call(i) }
94
+ @run_list_items.each { |i| block.call(i) }
83
95
  end
84
96
 
85
97
  def each_index(&block)
86
- @run_list.each_index { |i| block.call(i) }
98
+ @run_list_items.each_index { |i| block.call(i) }
87
99
  end
88
100
 
89
101
  def include?(item)
90
- type, entry, fentry = parse_entry(item)
91
- @run_list.include?(fentry)
102
+ @run_list_items.include?(parse_entry(item))
92
103
  end
93
104
 
94
105
  def reset!(*args)
95
- @run_list = Array.new
96
- @recipes = Array.new
97
- @roles = Array.new
106
+ @run_list_items.clear
98
107
  args.flatten.each do |item|
99
108
  if item.kind_of?(Chef::RunList)
100
109
  item.each { |r| self << r }
@@ -106,65 +115,33 @@ class Chef
106
115
  end
107
116
 
108
117
  def remove(item)
109
- type, entry, fentry = parse_entry(item)
110
- @run_list.delete_if { |i| i == fentry }
111
- if type == "recipe"
112
- @recipes.delete_if { |i| i == entry }
113
- elsif type == "role"
114
- @roles.delete_if { |i| i == entry }
115
- end
118
+ @run_list_items.delete_if{|i| i == item}
116
119
  self
117
120
  end
118
121
 
119
- def expand(from='server', couchdb=nil, rest=nil)
122
+ def expand(data_source='server', couchdb=nil, rest=nil)
120
123
  couchdb = couchdb ? couchdb : Chef::CouchDB.new
121
- recipes = Array.new
122
- default_attrs = Mash.new
123
- override_attrs = Mash.new
124
-
125
- @run_list.each do |entry|
126
- type, name, fname = parse_entry(entry)
127
- case type
128
- when 'recipe'
129
- recipes << name unless recipes.include?(name)
130
- when 'role'
131
- role = begin
132
- next if @seen_roles.include?(name)
133
- @seen_roles << name
134
- if from == 'disk' || Chef::Config[:solo]
135
- # Load the role from disk
136
- Chef::Role.from_disk("#{name}") || raise(Chef::Exceptions::RoleNotFound)
137
- elsif from == 'server'
138
- # Load the role from the server
139
- begin
140
- (rest || Chef::REST.new(Chef::Config[:role_url])).get_rest("roles/#{name}")
141
- rescue Net::HTTPServerException
142
- raise Chef::Exceptions::RoleNotFound if $!.message == '404 "Not Found"'
143
- raise
144
- end
145
- elsif from == 'couchdb'
146
- # Load the role from couchdb
147
- Chef::Role.cdb_load(name, couchdb) rescue Chef::Exceptions::CouchDBNotFound raise(Chef::Exceptions::RoleNotFound)
148
- end
149
- rescue Chef::Exceptions::RoleNotFound
150
- Chef::Log.error("Role #{name} is in the runlist but does not exist. Skipping expand.")
151
- next
152
- end
153
- rec, d, o = role.run_list.expand(from, couchdb, rest)
154
- rec.each { |r| recipes << r unless recipes.include?(r) }
155
- default_attrs = Chef::Mixin::DeepMerge.merge(default_attrs, Chef::Mixin::DeepMerge.merge(role.default_attributes,d))
156
- override_attrs = Chef::Mixin::DeepMerge.merge(override_attrs, Chef::Mixin::DeepMerge.merge(role.override_attributes, o))
157
- end
158
- end
159
- return recipes, default_attrs, override_attrs
124
+
125
+ expansion = expansion_for_data_source(data_source, :couchdb => couchdb, :rest => rest)
126
+ expansion.expand
127
+ return expansion.recipes, expansion.default_attrs, expansion.override_attrs
160
128
  end
161
129
 
130
+ # Converts a string run list entry to a RunListItem object.
131
+ # TODO: 5/27/2010 cw: this method has become nothing more than a proxy, revisit its necessity
162
132
  def parse_entry(entry)
163
- case entry
164
- when /^(.+)\[(.+)\]$/
165
- [ $1, $2, entry ]
166
- else
167
- [ 'recipe', entry, "recipe[#{entry}]" ]
133
+ RunListItem.new(entry)
134
+ end
135
+
136
+ def expansion_for_data_source(data_source, opts={})
137
+ data_source = 'disk' if Chef::Config[:solo]
138
+ case data_source.to_s
139
+ when 'disk'
140
+ RunListExpansionFromDisk.new(@run_list_items)
141
+ when 'server'
142
+ RunListExpansionFromAPI.new(@run_list_items, opts[:rest])
143
+ when 'couchdb'
144
+ RunListExpansionFromCouchDB.new(@run_list_items, opts[:couchdb])
168
145
  end
169
146
  end
170
147