chef 0.8.16 → 0.9.0.a3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of chef might be problematic. Click here for more details.

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
@@ -103,13 +103,15 @@ class Chef
103
103
  client_registration_retries 5
104
104
  cookbook_path [ "/var/chef/cookbooks", "/var/chef/site-cookbooks" ]
105
105
  cookbook_tarball_path "/var/chef/cookbook-tarballs"
106
+ sandbox_path "/var/chef/sandboxes"
107
+ checksum_path "/var/chef/checksums"
106
108
  couchdb_database "chef"
107
109
  couchdb_url "http://localhost:5984"
108
110
  couchdb_version nil
109
111
  delay 0
110
112
  executable_path ENV['PATH'] ? ENV['PATH'].split(File::PATH_SEPARATOR) : []
111
113
  file_cache_path "/var/chef/cache"
112
- file_backup_path nil
114
+ file_backup_path "/var/chef/backup"
113
115
  group nil
114
116
  http_retry_count 5
115
117
  http_retry_delay 5
@@ -191,6 +193,12 @@ class Chef
191
193
  signing_ca_domain "opensource.opscode.com"
192
194
  signing_ca_email "opensource-cert@opscode.com"
193
195
 
196
+ # Report Handlers
197
+ report_handlers []
198
+
199
+ # Exception Handlers
200
+ exception_handlers []
201
+
194
202
  # Checksum Cache
195
203
  # Uses Moneta on the back-end
196
204
  cache_type "BasicFile"
@@ -0,0 +1,43 @@
1
+ #
2
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'extlib'
21
+
22
+ # This class is the consistent interface for a node to obtain its
23
+ # cookbooks by name.
24
+ #
25
+ # This class is basically a glorified Hash, but since there are
26
+ # several ways this cookbook information is collected,
27
+ # (e.g. CookbookLoader for solo, hash of auto-vivified Cookbook
28
+ # objects for lazily-loaded remote cookbooks), it gets transformed
29
+ # into this.
30
+ class Chef
31
+ class CookbookCollection < Mash
32
+
33
+ # The input is a mapping of cookbook name to CookbookVersion objects. We
34
+ # simply extract them
35
+ def initialize(cookbook_versions={})
36
+ super() do |hash, key|
37
+ raise Chef::Exceptions::CookbookNotFound, "Cookbook #{key} not found"
38
+ end
39
+ cookbook_versions.each{ |cookbook_name, cookbook_version| self[cookbook_name] = cookbook_version }
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ #
2
+ # Author:: Christopher Walters (<cw@opscode.com>)
3
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/cookbook/file_vendor'
21
+
22
+ # This FileVendor loads files from Chef::Config.cookbook_path. The
23
+ # thing that's sort of janky about this FileVendor implementation is
24
+ # that it basically takes only the cookbook's name from the manifest
25
+ # and throws the rest away then re-builds the list of files on the
26
+ # disk. This is due to the manifest not having the on-disk file
27
+ # locations, since in the chef-client case, that information is
28
+ # non-sensical.
29
+ class Chef
30
+ class Cookbook
31
+ class FileSystemFileVendor < FileVendor
32
+
33
+ def initialize(manifest)
34
+ @cookbook_name = manifest[:cookbook_name]
35
+ end
36
+
37
+ # Implements abstract base's requirement. It looks in the
38
+ # Chef::Config.cookbook_path file hierarchy for the requested
39
+ # file.
40
+ def get_filename(filename)
41
+ location = Array(Chef::Config.cookbook_path).inject(nil) do |memo, basepath|
42
+ candidate_location = File.join(basepath, @cookbook_name, filename)
43
+ memo = candidate_location if File.exist?(candidate_location)
44
+ memo
45
+ end
46
+ raise "File #{filename} does not exist for cookbook #{@cookbook_name}" unless location
47
+
48
+ location
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,47 @@
1
+ #
2
+ # Author:: Christopher Walters (<cw@opscode.com>)
3
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+
21
+ # This class handles fetching of cookbook files based on specificity.
22
+ class Chef
23
+ class Cookbook
24
+ class FileVendor
25
+
26
+ def self.on_create(&block)
27
+ @instance_creator = block
28
+ end
29
+
30
+ # Factory method that creates the appropriate kind of
31
+ # Cookbook::FileVendor to serve the contents of the manifest
32
+ def self.create_from_manifest(manifest)
33
+ raise "Must call Chef::Cookbook::FileVendor.on_create before calling create_from_manifest factory" unless defined?(@instance_creator)
34
+ @instance_creator.call(manifest)
35
+ end
36
+
37
+ # Gets the on-disk location for the given cookbook file.
38
+ #
39
+ # Subclasses are responsible for determining exactly how the
40
+ # files are obtained and where they are stored.
41
+ def get_filename(filename)
42
+ raise NotImplemented, "Subclasses must implement this method"
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -31,7 +31,7 @@ class Chef
31
31
  include Chef::Mixin::ParamsValidate
32
32
  include Chef::Mixin::FromFile
33
33
 
34
- attr_accessor :cookbook,
34
+ attr_reader :cookbook,
35
35
  :platforms,
36
36
  :dependencies,
37
37
  :recommendations,
@@ -74,7 +74,7 @@ class Chef
74
74
  @recipes = Mash.new
75
75
  @version = Version.new "0.0.0"
76
76
  if cookbook
77
- @recipes = cookbook.recipes.inject({}) do |r, e|
77
+ @recipes = cookbook.fully_qualified_recipe_names.inject({}) do |r, e|
78
78
  e = self.name if e =~ /::default$/
79
79
  r[e] = ""
80
80
  self.provides e
@@ -367,23 +367,23 @@ class Chef
367
367
 
368
368
  def to_json(*a)
369
369
  result = {
370
- :name => self.name,
371
- :description => self.description,
370
+ :name => self.name,
371
+ :description => self.description,
372
372
  :long_description => self.long_description,
373
- :maintainer => self.maintainer,
373
+ :maintainer => self.maintainer,
374
374
  :maintainer_email => self.maintainer_email,
375
- :license => self.license,
376
- :platforms => self.platforms,
377
- :dependencies => self.dependencies,
378
- :recommendations => self.recommendations,
379
- :suggestions => self.suggestions,
380
- :conflicting => self.conflicting,
381
- :providing => self.providing,
382
- :replacing => self.replacing,
383
- :attributes => self.attributes,
384
- :groupings => self.groupings,
385
- :recipes => self.recipes,
386
- :version => self.version
375
+ :license => self.license,
376
+ :platforms => self.platforms,
377
+ :dependencies => self.dependencies,
378
+ :recommendations => self.recommendations,
379
+ :suggestions => self.suggestions,
380
+ :conflicting => self.conflicting,
381
+ :providing => self.providing,
382
+ :replacing => self.replacing,
383
+ :attributes => self.attributes,
384
+ :groupings => self.groupings,
385
+ :recipes => self.recipes,
386
+ :version => self.version
387
387
  }
388
388
  result.to_json(*a)
389
389
  end
@@ -395,24 +395,23 @@ class Chef
395
395
  end
396
396
 
397
397
  def from_hash(o)
398
- self.name o['name'] if o.has_key?('name')
399
- self.description o['description'] if o.has_key?('description')
400
- self.long_description o['long_description'] if o.has_key?('long_description')
401
- self.maintainer o['maintainer'] if o.has_key?('maintainer')
402
- self.maintainer_email o['maintainer_email'] if o.has_key?('maintainer_email')
403
- self.license o['license'] if o.has_key?('license')
404
- self.version o['version'] if o.has_key?('version')
405
- self.platforms = o['platforms'] if o.has_key?('platforms')
406
- self.dependencies = o['dependencies'] if o.has_key?('dependencies')
407
- self.recommendations = o['recommendations'] if o.has_key?('recommendations')
408
- self.suggestions = o['suggestions'] if o.has_key?('suggestions')
409
- self.conflicting = o['conflicting'] if o.has_key?('conflicting')
410
- self.providing = o['providing'] if o.has_key?('providing')
411
- self.replacing = o['replacing'] if o.has_key?('replacing')
412
- self.attributes = o['attributes'] if o.has_key?('attributes')
413
- self.groupings = o['groupings'] if o.has_key?('groupings')
414
- self.recipes = o['recipes'] if o.has_key?('recipes')
415
- self.version = o['version'] if o.has_key?('version')
398
+ @name = o['name'] if o.has_key?('name')
399
+ @description = o['description'] if o.has_key?('description')
400
+ @long_description = o['long_description'] if o.has_key?('long_description')
401
+ @maintainer = o['maintainer'] if o.has_key?('maintainer')
402
+ @maintainer_email = o['maintainer_email'] if o.has_key?('maintainer_email')
403
+ @license = o['license'] if o.has_key?('license')
404
+ @platforms = o['platforms'] if o.has_key?('platforms')
405
+ @dependencies = o['dependencies'] if o.has_key?('dependencies')
406
+ @recommendations = o['recommendations'] if o.has_key?('recommendations')
407
+ @suggestions = o['suggestions'] if o.has_key?('suggestions')
408
+ @conflicting = o['conflicting'] if o.has_key?('conflicting')
409
+ @providing = o['providing'] if o.has_key?('providing')
410
+ @replacing = o['replacing'] if o.has_key?('replacing')
411
+ @attributes = o['attributes'] if o.has_key?('attributes')
412
+ @groupings = o['groupings'] if o.has_key?('groupings')
413
+ @recipes = o['recipes'] if o.has_key?('recipes')
414
+ @version = o['version'] if o.has_key?('version')
416
415
  self
417
416
  end
418
417
 
@@ -16,7 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'chef/cookbook'
19
+ require 'chef/cookbook_version'
20
20
  require 'chef/cookbook/metadata'
21
21
 
22
22
  class Chef::Cookbook::Metadata
@@ -19,7 +19,7 @@
19
19
  # limitations under the License.
20
20
 
21
21
  require 'chef/config'
22
- require 'chef/cookbook'
22
+ require 'chef/cookbook_version'
23
23
  require 'chef/cookbook/metadata'
24
24
 
25
25
  class Chef
@@ -30,7 +30,7 @@ class Chef
30
30
  include Enumerable
31
31
 
32
32
  def initialize()
33
- @cookbook = Hash.new
33
+ @cookbooks_by_name = Hash.new
34
34
  @metadata = Hash.new
35
35
  @ignore_regexes = Hash.new { |hsh, key| hsh[key] = Array.new }
36
36
  load_cookbooks
@@ -39,20 +39,22 @@ class Chef
39
39
  def load_cookbooks
40
40
  cookbook_settings = Hash.new
41
41
  [Chef::Config.cookbook_path].flatten.each do |cb_path|
42
+ cb_path = File.expand_path(cb_path)
42
43
  Dir[File.join(cb_path, "*")].each do |cookbook|
43
- next unless File.directory?(cookbook)
44
+ next unless File.directory?(cookbook)
44
45
  cookbook_name = File.basename(cookbook).to_sym
45
46
  unless cookbook_settings.has_key?(cookbook_name)
46
47
  cookbook_settings[cookbook_name] = {
47
- :attribute_files => Hash.new,
48
- :definition_files => Hash.new,
49
- :recipe_files => Hash.new,
50
- :template_files => Hash.new,
51
- :remote_files => Hash.new,
52
- :lib_files => Hash.new,
53
- :resource_files => Hash.new,
54
- :provider_files => Hash.new,
55
- :metadata_files => Array.new
48
+ :attribute_filenames => Hash.new,
49
+ :definition_filenames => Hash.new,
50
+ :recipe_filenames => Hash.new,
51
+ :template_filenames => Hash.new,
52
+ :file_filenames => Hash.new,
53
+ :library_filenames => Hash.new,
54
+ :resource_filenames => Hash.new,
55
+ :provider_filenames => Hash.new,
56
+ :root_filenames => Hash.new,
57
+ :metadata_filenames => Array.new
56
58
  }
57
59
  end
58
60
  ignore_regexes = load_ignore_file(File.join(cookbook, "ignore"))
@@ -60,84 +62,99 @@ class Chef
60
62
 
61
63
  load_files_unless_basename(
62
64
  File.join(cookbook, "attributes", "*.rb"),
63
- cookbook_settings[cookbook_name][:attribute_files]
65
+ cookbook_settings[cookbook_name][:attribute_filenames]
64
66
  )
65
67
  load_files_unless_basename(
66
68
  File.join(cookbook, "definitions", "*.rb"),
67
- cookbook_settings[cookbook_name][:definition_files]
69
+ cookbook_settings[cookbook_name][:definition_filenames]
68
70
  )
69
71
  load_files_unless_basename(
70
72
  File.join(cookbook, "recipes", "*.rb"),
71
- cookbook_settings[cookbook_name][:recipe_files]
73
+ cookbook_settings[cookbook_name][:recipe_filenames]
72
74
  )
73
75
  load_files_unless_basename(
74
76
  File.join(cookbook, "libraries", "*.rb"),
75
- cookbook_settings[cookbook_name][:lib_files]
77
+ cookbook_settings[cookbook_name][:library_filenames]
76
78
  )
77
79
  load_cascading_files(
78
80
  "*",
79
81
  File.join(cookbook, "templates"),
80
- cookbook_settings[cookbook_name][:template_files]
82
+ cookbook_settings[cookbook_name][:template_filenames]
81
83
  )
82
84
  load_cascading_files(
83
85
  "*",
84
86
  File.join(cookbook, "files"),
85
- cookbook_settings[cookbook_name][:remote_files]
87
+ cookbook_settings[cookbook_name][:file_filenames]
86
88
  )
87
89
  load_cascading_files(
88
90
  "*.rb",
89
91
  File.join(cookbook, "resources"),
90
- cookbook_settings[cookbook_name][:resource_files]
92
+ cookbook_settings[cookbook_name][:resource_filenames]
91
93
  )
92
94
  load_cascading_files(
93
95
  "*.rb",
94
96
  File.join(cookbook, "providers"),
95
- cookbook_settings[cookbook_name][:provider_files]
97
+ cookbook_settings[cookbook_name][:provider_filenames]
98
+ )
99
+ load_files(
100
+ "*",
101
+ cookbook,
102
+ cookbook_settings[cookbook_name][:root_filenames]
96
103
  )
97
-
98
104
  if File.exists?(File.join(cookbook, "metadata.json"))
99
- cookbook_settings[cookbook_name][:metadata_files] << File.join(cookbook, "metadata.json")
105
+ cookbook_settings[cookbook_name][:metadata_filenames] << File.join(cookbook, "metadata.json")
100
106
  end
101
107
  end
102
108
  end
103
109
  remove_ignored_files_from(cookbook_settings)
104
-
110
+
105
111
  cookbook_settings.each_key do |cookbook|
106
- @cookbook[cookbook] = Chef::Cookbook.new(cookbook)
107
- @cookbook[cookbook].attribute_files = cookbook_settings[cookbook][:attribute_files].values
108
- @cookbook[cookbook].definition_files = cookbook_settings[cookbook][:definition_files].values
109
- @cookbook[cookbook].recipe_files = cookbook_settings[cookbook][:recipe_files].values
110
- @cookbook[cookbook].template_files = cookbook_settings[cookbook][:template_files].values
111
- @cookbook[cookbook].remote_files = cookbook_settings[cookbook][:remote_files].values
112
- @cookbook[cookbook].lib_files = cookbook_settings[cookbook][:lib_files].values
113
- @cookbook[cookbook].resource_files = cookbook_settings[cookbook][:resource_files].values
114
- @cookbook[cookbook].provider_files = cookbook_settings[cookbook][:provider_files].values
115
- @metadata[cookbook] = Chef::Cookbook::Metadata.new(@cookbook[cookbook])
116
- cookbook_settings[cookbook][:metadata_files].each do |meta_json|
112
+ @cookbooks_by_name[cookbook] = Chef::CookbookVersion.new(cookbook)
113
+ @cookbooks_by_name[cookbook].attribute_filenames = cookbook_settings[cookbook][:attribute_filenames].values
114
+ @cookbooks_by_name[cookbook].definition_filenames = cookbook_settings[cookbook][:definition_filenames].values
115
+ @cookbooks_by_name[cookbook].recipe_filenames = cookbook_settings[cookbook][:recipe_filenames].values
116
+ @cookbooks_by_name[cookbook].template_filenames = cookbook_settings[cookbook][:template_filenames].values
117
+ @cookbooks_by_name[cookbook].file_filenames = cookbook_settings[cookbook][:file_filenames].values
118
+ @cookbooks_by_name[cookbook].library_filenames = cookbook_settings[cookbook][:library_filenames].values
119
+ @cookbooks_by_name[cookbook].resource_filenames = cookbook_settings[cookbook][:resource_filenames].values
120
+ @cookbooks_by_name[cookbook].provider_filenames = cookbook_settings[cookbook][:provider_filenames].values
121
+ @cookbooks_by_name[cookbook].root_filenames = cookbook_settings[cookbook][:root_filenames].values
122
+ @cookbooks_by_name[cookbook].metadata_filenames = cookbook_settings[cookbook][:metadata_filenames]
123
+ @metadata[cookbook] = Chef::Cookbook::Metadata.new(@cookbooks_by_name[cookbook])
124
+ cookbook_settings[cookbook][:metadata_filenames].each do |meta_json|
117
125
  begin
118
126
  @metadata[cookbook].from_json(IO.read(meta_json))
119
127
  rescue JSON::ParserError
120
- puts "Couldn't parse JSON in " + meta_json
128
+ Chef::Log.fatal("Couldn't parse JSON in " + meta_json)
121
129
  raise
122
130
  end
123
131
  end
132
+ @cookbooks_by_name[cookbook].metadata = @metadata[cookbook]
124
133
  end
125
134
  end
126
135
 
127
136
  def [](cookbook)
128
- if @cookbook.has_key?(cookbook.to_sym)
129
- @cookbook[cookbook.to_sym]
137
+ if @cookbooks_by_name.has_key?(cookbook.to_sym)
138
+ @cookbooks_by_name[cookbook.to_sym]
130
139
  else
131
140
  raise ArgumentError, "Cannot find a cookbook named #{cookbook.to_s}; did you forget to add metadata to a cookbook? (http://wiki.opscode.com/display/chef/Metadata)"
132
141
  end
133
142
  end
143
+
144
+ def has_key?(cookbook_name)
145
+ @cookbooks_by_name.has_key?(cookbook_name)
146
+ end
134
147
 
135
148
  def each
136
- @cookbook.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |cname|
137
- yield @cookbook[cname]
149
+ @cookbooks_by_name.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |cname|
150
+ yield(cname, @cookbooks_by_name[cname])
138
151
  end
139
152
  end
140
153
 
154
+ def values
155
+ @cookbooks_by_name.values
156
+ end
157
+
141
158
  private
142
159
 
143
160
  def load_ignore_file(ignore_file)
@@ -154,8 +171,8 @@ class Chef
154
171
  end
155
172
 
156
173
  def remove_ignored_files_from(cookbook_settings)
157
- file_types_to_inspect = [ :attribute_files, :definition_files, :recipe_files, :template_files,
158
- :remote_files, :lib_files, :resource_files, :provider_files]
174
+ file_types_to_inspect = [ :attribute_filenames, :definition_filenames, :recipe_filenames, :template_filenames,
175
+ :file_filenames, :library_filenames, :resource_filenames, :provider_filenames]
159
176
 
160
177
  @ignore_regexes.each do |cookbook_name, regexes|
161
178
  regexes.each do |regex|
@@ -166,15 +183,23 @@ class Chef
166
183
  end
167
184
  end
168
185
  end
169
-
170
- def load_cascading_files(file_glob, base_path, result_hash)
171
- rm_base_path = /^#{base_path}\/(.+)$/
186
+
187
+ def load_files(file_glob, base_path, result_hash, recursive=false)
188
+ rm_base_path = /^#{Regexp.escape(base_path)}\/(.+)$/
189
+ file_spec = [base_path]
190
+ file_spec << "**" if recursive
191
+ file_spec << file_glob
172
192
  # To handle dotfiles like .ssh
173
- Dir.glob(File.join(base_path, "**/#{file_glob}"), File::FNM_DOTMATCH).each do |file|
193
+ Dir.glob(File.join(file_spec), File::FNM_DOTMATCH).each do |file|
194
+ next if File.directory?(file)
174
195
  result_hash[rm_base_path.match(file)[1]] = file
175
196
  end
176
197
  end
177
198
 
199
+ def load_cascading_files(file_glob, base_path, result_hash)
200
+ load_files(file_glob, base_path, result_hash, true)
201
+ end
202
+
178
203
  def load_files_unless_basename(file_glob, result_hash)
179
204
  Dir[file_glob].each do |file|
180
205
  result_hash[File.basename(file)] = file