runa-chef 0.8.0.1

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 (216) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +136 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +26 -0
  5. data/bin/knife +27 -0
  6. data/bin/shef +45 -0
  7. data/distro/README +2 -0
  8. data/distro/common/man/man1/chef-indexer.1 +42 -0
  9. data/distro/common/man/man1/chef-server.1 +108 -0
  10. data/distro/common/man/man8/chef-client.8 +61 -0
  11. data/distro/common/man/man8/chef-solo.8 +58 -0
  12. data/distro/common/man/man8/knife.8 +359 -0
  13. data/distro/debian/etc/init.d/chef-client +175 -0
  14. data/distro/debian/etc/init.d/chef-indexer +175 -0
  15. data/distro/debian/etc/init.d/chef-server +120 -0
  16. data/distro/redhat/etc/init.d/chef-client +78 -0
  17. data/distro/redhat/etc/init.d/chef-indexer +76 -0
  18. data/distro/redhat/etc/init.d/chef-server +78 -0
  19. data/distro/redhat/etc/sysconfig/chef-client +10 -0
  20. data/distro/redhat/etc/sysconfig/chef-indexer +8 -0
  21. data/distro/redhat/etc/sysconfig/chef-server +10 -0
  22. data/distro/suse/etc/init.d/chef-client +121 -0
  23. data/lib/chef.rb +49 -0
  24. data/lib/chef/api_client.rb +269 -0
  25. data/lib/chef/application.rb +98 -0
  26. data/lib/chef/application/agent.rb +18 -0
  27. data/lib/chef/application/client.rb +214 -0
  28. data/lib/chef/application/knife.rb +138 -0
  29. data/lib/chef/application/server.rb +19 -0
  30. data/lib/chef/application/solo.rb +214 -0
  31. data/lib/chef/cache.rb +61 -0
  32. data/lib/chef/cache/checksum.rb +70 -0
  33. data/lib/chef/certificate.rb +154 -0
  34. data/lib/chef/client.rb +323 -0
  35. data/lib/chef/compile.rb +158 -0
  36. data/lib/chef/config.rb +195 -0
  37. data/lib/chef/cookbook.rb +198 -0
  38. data/lib/chef/cookbook/metadata.rb +487 -0
  39. data/lib/chef/cookbook/metadata/version.rb +87 -0
  40. data/lib/chef/cookbook_loader.rb +180 -0
  41. data/lib/chef/couchdb.rb +273 -0
  42. data/lib/chef/daemon.rb +170 -0
  43. data/lib/chef/data_bag.rb +216 -0
  44. data/lib/chef/data_bag_item.rb +227 -0
  45. data/lib/chef/exceptions.rb +39 -0
  46. data/lib/chef/file_cache.rb +205 -0
  47. data/lib/chef/knife.rb +300 -0
  48. data/lib/chef/knife/client_bulk_delete.rb +41 -0
  49. data/lib/chef/knife/client_create.rb +55 -0
  50. data/lib/chef/knife/client_delete.rb +37 -0
  51. data/lib/chef/knife/client_edit.rb +37 -0
  52. data/lib/chef/knife/client_list.rb +40 -0
  53. data/lib/chef/knife/client_reregister.rb +48 -0
  54. data/lib/chef/knife/client_show.rb +42 -0
  55. data/lib/chef/knife/configure.rb +84 -0
  56. data/lib/chef/knife/cookbook_bulk_delete.rb +47 -0
  57. data/lib/chef/knife/cookbook_delete.rb +41 -0
  58. data/lib/chef/knife/cookbook_download.rb +57 -0
  59. data/lib/chef/knife/cookbook_list.rb +41 -0
  60. data/lib/chef/knife/cookbook_metadata.rb +87 -0
  61. data/lib/chef/knife/cookbook_show.rb +75 -0
  62. data/lib/chef/knife/cookbook_upload.rb +173 -0
  63. data/lib/chef/knife/data_bag_create.rb +43 -0
  64. data/lib/chef/knife/data_bag_delete.rb +43 -0
  65. data/lib/chef/knife/data_bag_edit.rb +49 -0
  66. data/lib/chef/knife/data_bag_list.rb +42 -0
  67. data/lib/chef/knife/data_bag_show.rb +40 -0
  68. data/lib/chef/knife/ec2_instance_data.rb +46 -0
  69. data/lib/chef/knife/node_bulk_delete.rb +44 -0
  70. data/lib/chef/knife/node_create.rb +39 -0
  71. data/lib/chef/knife/node_delete.rb +36 -0
  72. data/lib/chef/knife/node_edit.rb +36 -0
  73. data/lib/chef/knife/node_from_file.rb +42 -0
  74. data/lib/chef/knife/node_list.rb +41 -0
  75. data/lib/chef/knife/node_run_list_add.rb +64 -0
  76. data/lib/chef/knife/node_run_list_remove.rb +45 -0
  77. data/lib/chef/knife/node_show.rb +46 -0
  78. data/lib/chef/knife/role_bulk_delete.rb +45 -0
  79. data/lib/chef/knife/role_create.rb +44 -0
  80. data/lib/chef/knife/role_delete.rb +36 -0
  81. data/lib/chef/knife/role_edit.rb +37 -0
  82. data/lib/chef/knife/role_from_file.rb +46 -0
  83. data/lib/chef/knife/role_list.rb +40 -0
  84. data/lib/chef/knife/role_show.rb +43 -0
  85. data/lib/chef/knife/search.rb +94 -0
  86. data/lib/chef/log.rb +39 -0
  87. data/lib/chef/mixin/check_helper.rb +31 -0
  88. data/lib/chef/mixin/checksum.rb +32 -0
  89. data/lib/chef/mixin/command.rb +390 -0
  90. data/lib/chef/mixin/convert_to_class_name.rb +57 -0
  91. data/lib/chef/mixin/create_path.rb +56 -0
  92. data/lib/chef/mixin/deep_merge.rb +33 -0
  93. data/lib/chef/mixin/find_preferred_file.rb +92 -0
  94. data/lib/chef/mixin/from_file.rb +50 -0
  95. data/lib/chef/mixin/generate_url.rb +58 -0
  96. data/lib/chef/mixin/language.rb +107 -0
  97. data/lib/chef/mixin/language_include_attribute.rb +56 -0
  98. data/lib/chef/mixin/language_include_recipe.rb +53 -0
  99. data/lib/chef/mixin/params_validate.rb +197 -0
  100. data/lib/chef/mixin/recipe_definition_dsl_core.rb +79 -0
  101. data/lib/chef/mixin/template.rb +94 -0
  102. data/lib/chef/nanite.rb +100 -0
  103. data/lib/chef/node.rb +463 -0
  104. data/lib/chef/node/attribute.rb +412 -0
  105. data/lib/chef/openid_registration.rb +181 -0
  106. data/lib/chef/platform.rb +268 -0
  107. data/lib/chef/provider.rb +101 -0
  108. data/lib/chef/provider/breakpoint.rb +36 -0
  109. data/lib/chef/provider/cron.rb +184 -0
  110. data/lib/chef/provider/deploy.rb +314 -0
  111. data/lib/chef/provider/deploy/revision.rb +70 -0
  112. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  113. data/lib/chef/provider/directory.rb +72 -0
  114. data/lib/chef/provider/erl_call.rb +72 -0
  115. data/lib/chef/provider/execute.rb +58 -0
  116. data/lib/chef/provider/file.rb +195 -0
  117. data/lib/chef/provider/git.rb +203 -0
  118. data/lib/chef/provider/group.rb +120 -0
  119. data/lib/chef/provider/group/dscl.rb +128 -0
  120. data/lib/chef/provider/group/gpasswd.rb +50 -0
  121. data/lib/chef/provider/group/groupadd.rb +78 -0
  122. data/lib/chef/provider/group/pw.rb +88 -0
  123. data/lib/chef/provider/group/usermod.rb +57 -0
  124. data/lib/chef/provider/http_request.rb +106 -0
  125. data/lib/chef/provider/ifconfig.rb +131 -0
  126. data/lib/chef/provider/link.rb +157 -0
  127. data/lib/chef/provider/mdadm.rb +88 -0
  128. data/lib/chef/provider/mount.rb +117 -0
  129. data/lib/chef/provider/mount/mount.rb +208 -0
  130. data/lib/chef/provider/package.rb +160 -0
  131. data/lib/chef/provider/package/apt.rb +110 -0
  132. data/lib/chef/provider/package/dpkg.rb +109 -0
  133. data/lib/chef/provider/package/easy_install.rb +106 -0
  134. data/lib/chef/provider/package/freebsd.rb +153 -0
  135. data/lib/chef/provider/package/macports.rb +105 -0
  136. data/lib/chef/provider/package/portage.rb +124 -0
  137. data/lib/chef/provider/package/rpm.rb +99 -0
  138. data/lib/chef/provider/package/rubygems.rb +136 -0
  139. data/lib/chef/provider/package/yum-dump.py +125 -0
  140. data/lib/chef/provider/package/yum.rb +175 -0
  141. data/lib/chef/provider/package/zypper.rb +132 -0
  142. data/lib/chef/provider/remote_directory.rb +126 -0
  143. data/lib/chef/provider/remote_file.rb +141 -0
  144. data/lib/chef/provider/route.rb +118 -0
  145. data/lib/chef/provider/ruby_block.rb +33 -0
  146. data/lib/chef/provider/script.rb +42 -0
  147. data/lib/chef/provider/service.rb +135 -0
  148. data/lib/chef/provider/service/debian.rb +64 -0
  149. data/lib/chef/provider/service/freebsd.rb +156 -0
  150. data/lib/chef/provider/service/gentoo.rb +54 -0
  151. data/lib/chef/provider/service/init.rb +71 -0
  152. data/lib/chef/provider/service/redhat.rb +62 -0
  153. data/lib/chef/provider/service/simple.rb +114 -0
  154. data/lib/chef/provider/subversion.rb +156 -0
  155. data/lib/chef/provider/template.rb +175 -0
  156. data/lib/chef/provider/user.rb +170 -0
  157. data/lib/chef/provider/user/dscl.rb +280 -0
  158. data/lib/chef/provider/user/pw.rb +113 -0
  159. data/lib/chef/provider/user/useradd.rb +108 -0
  160. data/lib/chef/recipe.rb +105 -0
  161. data/lib/chef/resource.rb +380 -0
  162. data/lib/chef/resource/apt_package.rb +34 -0
  163. data/lib/chef/resource/bash.rb +33 -0
  164. data/lib/chef/resource/breakpoint.rb +35 -0
  165. data/lib/chef/resource/cron.rb +179 -0
  166. data/lib/chef/resource/csh.rb +33 -0
  167. data/lib/chef/resource/deploy.rb +359 -0
  168. data/lib/chef/resource/deploy_revision.rb +35 -0
  169. data/lib/chef/resource/directory.rb +76 -0
  170. data/lib/chef/resource/dpkg_package.rb +34 -0
  171. data/lib/chef/resource/easy_install_package.rb +41 -0
  172. data/lib/chef/resource/erl_call.rb +83 -0
  173. data/lib/chef/resource/execute.rb +127 -0
  174. data/lib/chef/resource/file.rb +84 -0
  175. data/lib/chef/resource/gem_package.rb +41 -0
  176. data/lib/chef/resource/git.rb +36 -0
  177. data/lib/chef/resource/group.rb +70 -0
  178. data/lib/chef/resource/http_request.rb +52 -0
  179. data/lib/chef/resource/ifconfig.rb +134 -0
  180. data/lib/chef/resource/link.rb +78 -0
  181. data/lib/chef/resource/macports_package.rb +29 -0
  182. data/lib/chef/resource/mdadm.rb +82 -0
  183. data/lib/chef/resource/mount.rb +135 -0
  184. data/lib/chef/resource/package.rb +80 -0
  185. data/lib/chef/resource/perl.rb +33 -0
  186. data/lib/chef/resource/portage_package.rb +33 -0
  187. data/lib/chef/resource/python.rb +33 -0
  188. data/lib/chef/resource/remote_directory.rb +91 -0
  189. data/lib/chef/resource/remote_file.rb +60 -0
  190. data/lib/chef/resource/route.rb +135 -0
  191. data/lib/chef/resource/ruby.rb +33 -0
  192. data/lib/chef/resource/ruby_block.rb +39 -0
  193. data/lib/chef/resource/scm.rb +137 -0
  194. data/lib/chef/resource/script.rb +51 -0
  195. data/lib/chef/resource/service.rb +134 -0
  196. data/lib/chef/resource/subversion.rb +34 -0
  197. data/lib/chef/resource/template.rb +60 -0
  198. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  199. data/lib/chef/resource/user.rb +101 -0
  200. data/lib/chef/resource_collection.rb +212 -0
  201. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  202. data/lib/chef/resource_definition.rb +67 -0
  203. data/lib/chef/rest.rb +298 -0
  204. data/lib/chef/role.rb +301 -0
  205. data/lib/chef/run_list.rb +164 -0
  206. data/lib/chef/runner.rb +130 -0
  207. data/lib/chef/search/query.rb +71 -0
  208. data/lib/chef/shef.rb +220 -0
  209. data/lib/chef/shef/ext.rb +297 -0
  210. data/lib/chef/shef/shef_session.rb +175 -0
  211. data/lib/chef/streaming_cookbook_uploader.rb +185 -0
  212. data/lib/chef/tasks/chef_repo.rake +245 -0
  213. data/lib/chef/util/file_edit.rb +125 -0
  214. data/lib/chef/util/fileedit.rb +121 -0
  215. data/lib/chef/webui_user.rb +231 -0
  216. metadata +398 -0
@@ -0,0 +1,195 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Brown (<cb@opscode.com>)
4
+ # Author:: AJ Christensen (<aj@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008 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/log'
21
+ require 'mixlib/config'
22
+
23
+ class Chef
24
+ class Config
25
+
26
+ extend Mixlib::Config
27
+
28
+ # Manages the chef secret session key
29
+ # === Returns
30
+ # <newkey>:: A new or retrieved session key
31
+ #
32
+ def self.manage_secret_key
33
+ newkey = nil
34
+ if Chef::FileCache.has_key?("chef_server_cookie_id")
35
+ newkey = Chef::FileCache.load("chef_server_cookie_id")
36
+ else
37
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
38
+ newkey = ""
39
+ 40.times { |i| newkey << chars[rand(chars.size-1)] }
40
+ Chef::FileCache.store("chef_server_cookie_id", newkey)
41
+ end
42
+ newkey
43
+ end
44
+
45
+
46
+ # Override the config dispatch to set the value of multiple server options simultaneously
47
+ #
48
+ # === Parameters
49
+ # url<String>:: String to be set for all of the chef-server-api URL's
50
+ #
51
+ config_attr_writer :chef_server_url do |url|
52
+ configure do |c|
53
+ [ :registration_url,
54
+ :openid_url,
55
+ :template_url,
56
+ :remotefile_url,
57
+ :search_url,
58
+ :chef_server_url,
59
+ :role_url ].each do |u|
60
+ c[u] = url
61
+ end
62
+ end
63
+ url
64
+ end
65
+
66
+ # When you are using ActiveSupport, they monkey-patch 'daemonize' into Kernel.
67
+ # So while this is basically identical to what method_missing would do, we pull
68
+ # it up here and get a real method written so that things get dispatched
69
+ # properly.
70
+ config_attr_writer :daemonize do |v|
71
+ configure do |c|
72
+ c[:daemonize] = v
73
+ end
74
+ end
75
+
76
+ # Override the config dispatch to set the value of log_location configuration option
77
+ #
78
+ # === Parameters
79
+ # location<IO||String>:: Logging location as either an IO stream or string representing log file path
80
+ #
81
+ config_attr_writer :log_location do |location|
82
+ if location.respond_to? :sync=
83
+ location
84
+ elsif location.respond_to? :to_str
85
+ File.new(location.to_str, "a")
86
+ end
87
+ end
88
+
89
+ # Override the config dispatch to set the value of authorized_openid_providers when openid_providers (deprecated) is used
90
+ #
91
+ # === Parameters
92
+ # providers<Array>:: An array of openid providers that are authorized to login to the chef server
93
+ #
94
+ config_attr_writer :openid_providers do |providers|
95
+ configure { |c| c[:authorized_openid_providers] = providers }
96
+ providers
97
+ end
98
+
99
+ authorized_openid_identifiers nil
100
+ authorized_openid_providers nil
101
+ cookbook_path [ "/var/chef/cookbooks", "/var/chef/site-cookbooks" ]
102
+ cookbook_tarball_path "/var/chef/cookbook-tarballs"
103
+ couchdb_database "chef"
104
+ couchdb_url "http://localhost:5984"
105
+ couchdb_version nil
106
+ delay 0
107
+ executable_path ENV['PATH'] ? ENV['PATH'].split(File::PATH_SEPARATOR) : []
108
+ file_cache_path "/var/chef/cache"
109
+ file_backup_path nil
110
+ group nil
111
+ http_retry_count 5
112
+ http_retry_delay 5
113
+ interval nil
114
+ json_attribs nil
115
+ log_level :info
116
+ log_location STDOUT
117
+ node_name nil
118
+ node_path "/var/chef/node"
119
+ openid_cstore_couchdb false
120
+ openid_cstore_path "/var/chef/openid/cstore"
121
+ openid_providers nil
122
+ openid_store_couchdb false
123
+ openid_store_path "/var/chef/openid/db"
124
+ openid_url "http://localhost:4001"
125
+ pid_file nil
126
+ queue_host "localhost"
127
+ queue_password ""
128
+ queue_port 61613
129
+ queue_retry_count 5
130
+ queue_retry_delay 5
131
+ queue_user ""
132
+ chef_server_url "http://localhost:4000"
133
+ registration_url "http://localhost:4000"
134
+ client_url "http://localhost:4042"
135
+ remotefile_url "http://localhost:4000"
136
+ rest_timeout 60
137
+ run_command_stderr_timeout 120
138
+ run_command_stdout_timeout 120
139
+ search_index_path "/var/chef/search_index"
140
+ search_url "http://localhost:4000"
141
+ solo false
142
+ splay nil
143
+ ssl_client_cert ""
144
+ ssl_client_key ""
145
+ ssl_verify_mode :verify_none
146
+ ssl_ca_path nil
147
+ ssl_ca_file nil
148
+ template_url "http://localhost:4000"
149
+ umask 0022
150
+ user nil
151
+ validation_token nil
152
+ role_path "/var/chef/roles"
153
+ role_url "http://localhost:4000"
154
+ recipe_url nil
155
+ solr_url "http://localhost:8983"
156
+ solr_jetty_path "/var/chef/solr-jetty"
157
+ solr_data_path "/var/chef/solr/data"
158
+ solr_home_path "/var/chef/solr"
159
+ solr_heap_size "256M"
160
+ solr_java_opts nil
161
+ nanite_host '0.0.0.0'
162
+ nanite_port '5672'
163
+ nanite_user 'nanite'
164
+ nanite_pass 'testing'
165
+ nanite_vhost '/nanite'
166
+ nanite_identity nil
167
+ nanite_persistent_mapper false
168
+
169
+ client_key "/etc/chef/client.pem"
170
+ validation_key "/etc/chef/validation.pem"
171
+ validation_client_name "chef-validator"
172
+ web_ui_client_name "chef-webui"
173
+ web_ui_key "/etc/chef/webui.pem"
174
+ web_ui_admin_user_name "admin"
175
+ web_ui_admin_default_password "p@ssw0rd1"
176
+
177
+ # Server Signing CA
178
+ #
179
+ # In truth, these don't even have to change
180
+ signing_ca_cert "/var/chef/ca/cert.pem"
181
+ signing_ca_key "/var/chef/ca/key.pem"
182
+ signing_ca_country "US"
183
+ signing_ca_state "Washington"
184
+ signing_ca_location "Seattle"
185
+ signing_ca_org "Chef User"
186
+ signing_ca_domain "opensource.opscode.com"
187
+ signing_ca_email "opensource-cert@opscode.com"
188
+
189
+ # Checksum Cache
190
+ # Uses Moneta on the back-end
191
+ cache_type "BasicFile"
192
+ cache_options({ :path => "/var/chef/cache/checksums", :skip_expires => true })
193
+
194
+ end
195
+ end
@@ -0,0 +1,198 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Nuo Yan (<nuo@opscode.com>)
4
+ # Author:: Christopher Walters (<cw@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008 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/log'
21
+ require 'chef/node'
22
+ require 'chef/resource_definition'
23
+ require 'chef/recipe'
24
+ require 'chef/mixin/convert_to_class_name'
25
+
26
+ class Chef
27
+ class Cookbook
28
+ include Chef::Mixin::ConvertToClassName
29
+
30
+ attr_accessor :definition_files, :template_files, :remote_files,
31
+ :lib_files, :resource_files, :provider_files, :name
32
+ attr_reader :recipe_files, :attribute_files
33
+
34
+ # Creates a new Chef::Cookbook object.
35
+ #
36
+ # === Returns
37
+ # object<Chef::Cookbook>:: Duh. :)
38
+ def initialize(name)
39
+ @name = name
40
+ @attribute_files = Array.new
41
+ @attribute_names = Hash.new
42
+ @definition_files = Array.new
43
+ @template_files = Array.new
44
+ @remote_files = Array.new
45
+ @recipe_files = Array.new
46
+ @recipe_names = Hash.new
47
+ @lib_files = Array.new
48
+ @resource_files = Array.new
49
+ @provider_files = Array.new
50
+ end
51
+
52
+ # Loads all the library files in this cookbook via require.
53
+ #
54
+ # === Returns
55
+ # true:: Always returns true
56
+ def load_libraries
57
+ @lib_files.each do |file|
58
+ Chef::Log.debug("Loading cookbook #{name} library file: #{file}")
59
+ require file
60
+ end
61
+ true
62
+ end
63
+
64
+ # Loads all the attribute files in this cookbook within a particular <Chef::Node>.
65
+ #
66
+ # === Parameters
67
+ # node<Chef::Node>:: The Chef::Node to apply the attributes to
68
+ #
69
+ # === Returns
70
+ # node<Chef::Node>:: The updated Chef::Node object
71
+ #
72
+ # === Raises
73
+ # <ArgumentError>:: If the argument is not a kind_of? <Chef::Node>
74
+ def load_attributes(node)
75
+ @attribute_files.each do |file|
76
+ load_attribute_file(file, node)
77
+ end
78
+ node
79
+ end
80
+
81
+ def load_attribute_file(file, node)
82
+ Chef::Log.debug("Loading attributes from #{file}")
83
+ node.from_file(file)
84
+ end
85
+
86
+ def load_attribute(name, node)
87
+ attr_name = shorten_name(name)
88
+ file = @attribute_files[@attribute_names[attr_name]]
89
+ load_attribute_file(file, node)
90
+ node
91
+ end
92
+
93
+ # Loads all the resource definitions in this cookbook.
94
+ #
95
+ # === Returns
96
+ # definitions<Hash>: A hash of <Chef::ResourceDefinition> objects, keyed by name.
97
+ def load_definitions
98
+ results = Hash.new
99
+ @definition_files.each do |file|
100
+ Chef::Log.debug("Loading cookbook #{name}'s definitions from #{file}")
101
+ resourcedef = Chef::ResourceDefinition.new
102
+ resourcedef.from_file(file)
103
+ results[resourcedef.name] = resourcedef
104
+ end
105
+ results
106
+ end
107
+
108
+ # Loads all the resources in this cookbook.
109
+ #
110
+ # === Returns
111
+ # true:: Always returns true
112
+ def load_resources
113
+ @resource_files.each do |file|
114
+ Chef::Log.debug("Loading cookbook #{name}'s resources from #{file}")
115
+ Chef::Resource.build_from_file(name, file)
116
+ end
117
+ end
118
+
119
+ # Loads all the providers in this cookbook.
120
+ #
121
+ # === Returns
122
+ # true:: Always returns true
123
+ def load_providers
124
+ @provider_files.each do |file|
125
+ Chef::Log.debug("Loading cookbook #{name}'s providers from #{file}")
126
+ Chef::Provider.build_from_file(name, file)
127
+ end
128
+ end
129
+
130
+ def recipe_files=(*args)
131
+ @recipe_files, @recipe_names = set_with_names(args.flatten)
132
+ @recipe_files
133
+ end
134
+
135
+ def attribute_files=(*args)
136
+ @attribute_files, @attribute_names = set_with_names(args.flatten)
137
+ @attribute_files
138
+ end
139
+
140
+ def recipe?(name)
141
+ lookup_name = name
142
+ if name =~ /(.+)::(.+)/
143
+ cookbook_name = $1
144
+ lookup_name = $2
145
+ return false unless cookbook_name == @name
146
+ end
147
+ @recipe_names.has_key?(lookup_name)
148
+ end
149
+
150
+ def recipes
151
+ results = Array.new
152
+ @recipe_names.each_key do |rname|
153
+ results << "#{@name}::#{rname}"
154
+ end
155
+ results
156
+ end
157
+
158
+ def load_recipe(name, node, collection=nil, definitions=nil, cookbook_loader=nil)
159
+ cookbook_name = @name
160
+ recipe_name = shorten_name(name)
161
+
162
+ unless @recipe_names.has_key?(recipe_name)
163
+ raise ArgumentError, "Cannot find a recipe matching #{recipe_name} in cookbook #{@name}"
164
+ end
165
+ Chef::Log.debug("Found recipe #{recipe_name} in cookbook #{cookbook_name}") if Chef::Log.debug?
166
+ recipe = Chef::Recipe.new(cookbook_name, recipe_name, node,
167
+ collection, definitions, cookbook_loader)
168
+ recipe.from_file(@recipe_files[@recipe_names[recipe_name]])
169
+ recipe
170
+ end
171
+
172
+ private
173
+
174
+ def shorten_name(name)
175
+ short_name = nil
176
+ nmatch = name.match(/^(.+?)::(.+)$/)
177
+ short_name = nmatch ? nmatch[2] : name
178
+ end
179
+
180
+ def set_with_names(file_list)
181
+ files = file_list
182
+ names = Hash.new
183
+ files.each_index do |i|
184
+ file = files[i]
185
+ case file
186
+ when /(.+\/)(.+).rb$/
187
+ names[$2] = i
188
+ when /(.+).rb$/
189
+ names[$1] = i
190
+ else
191
+ names[file] = i
192
+ end
193
+ end
194
+ [ files, names ]
195
+ end
196
+
197
+ end
198
+ end
@@ -0,0 +1,487 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: AJ Christensen (<aj@opscode.com>)
4
+ # Copyright:: Copyright (c) 2008 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/mixin/from_file'
21
+ require 'chef/mixin/params_validate'
22
+ require 'chef/mixin/check_helper'
23
+ require 'chef/log'
24
+ require 'chef/cookbook/metadata/version'
25
+
26
+ class Chef
27
+ class Cookbook
28
+ class Metadata
29
+
30
+ include Chef::Mixin::CheckHelper
31
+ include Chef::Mixin::ParamsValidate
32
+ include Chef::Mixin::FromFile
33
+
34
+ attr_accessor :cookbook,
35
+ :platforms,
36
+ :dependencies,
37
+ :recommendations,
38
+ :suggestions,
39
+ :conflicting,
40
+ :providing,
41
+ :replacing,
42
+ :attributes,
43
+ :groupings,
44
+ :recipes,
45
+ :version
46
+
47
+ # Builds a new Chef::Cookbook::Metadata object.
48
+ #
49
+ # === Parameters
50
+ # cookbook<String>:: An optional cookbook object
51
+ # maintainer<String>:: An optional maintainer
52
+ # maintainer_email<String>:: An optional maintainer email
53
+ # license<String>::An optional license. Default is Apache v2.0
54
+ #
55
+ # === Returns
56
+ # metadata<Chef::Cookbook::Metadata>
57
+ def initialize(cookbook=nil, maintainer='Your Name', maintainer_email='youremail@example.com', license='Apache v2.0')
58
+ @cookbook = cookbook
59
+ @name = cookbook ? cookbook.name : ""
60
+ @long_description = ""
61
+ self.maintainer(maintainer)
62
+ self.maintainer_email(maintainer_email)
63
+ self.license(license)
64
+ self.description('A fabulous new cookbook')
65
+ @platforms = Mash.new
66
+ @dependencies = Mash.new
67
+ @recommendations = Mash.new
68
+ @suggestions = Mash.new
69
+ @conflicting = Mash.new
70
+ @providing = Mash.new
71
+ @replacing = Mash.new
72
+ @attributes = Mash.new
73
+ @groupings = Mash.new
74
+ @recipes = Mash.new
75
+ @version = Version.new "0.0.0"
76
+ if cookbook
77
+ @recipes = cookbook.recipes.inject({}) do |r, e|
78
+ e = self.name if e =~ /::default$/
79
+ r[e] = ""
80
+ self.provides e
81
+ r
82
+ end
83
+ end
84
+ end
85
+
86
+ # Sets the cookbooks maintainer, or returns it.
87
+ #
88
+ # === Parameters
89
+ # maintainer<String>:: The maintainers name
90
+ #
91
+ # === Returns
92
+ # maintainer<String>:: Returns the current maintainer.
93
+ def maintainer(arg=nil)
94
+ set_or_return(
95
+ :maintainer,
96
+ arg,
97
+ :kind_of => [ String ]
98
+ )
99
+ end
100
+
101
+ # Sets the maintainers email address, or returns it.
102
+ #
103
+ # === Parameters
104
+ # maintainer_email<String>:: The maintainers email address
105
+ #
106
+ # === Returns
107
+ # maintainer_email<String>:: Returns the current maintainer email.
108
+ def maintainer_email(arg=nil)
109
+ set_or_return(
110
+ :maintainer_email,
111
+ arg,
112
+ :kind_of => [ String ]
113
+ )
114
+ end
115
+
116
+ # Sets the current license, or returns it.
117
+ #
118
+ # === Parameters
119
+ # license<String>:: The current license.
120
+ #
121
+ # === Returns
122
+ # license<String>:: Returns the current license
123
+ def license(arg=nil)
124
+ set_or_return(
125
+ :license,
126
+ arg,
127
+ :kind_of => [ String ]
128
+ )
129
+ end
130
+
131
+ # Sets the current description, or returns it. Should be short - one line only!
132
+ #
133
+ # === Parameters
134
+ # description<String>:: The new description
135
+ #
136
+ # === Returns
137
+ # description<String>:: Returns the description
138
+ def description(arg=nil)
139
+ set_or_return(
140
+ :description,
141
+ arg,
142
+ :kind_of => [ String ]
143
+ )
144
+ end
145
+
146
+ # Sets the current long description, or returns it. Might come from a README, say.
147
+ #
148
+ # === Parameters
149
+ # long_description<String>:: The new long description
150
+ #
151
+ # === Returns
152
+ # long_description<String>:: Returns the long description
153
+ def long_description(arg=nil)
154
+ set_or_return(
155
+ :long_description,
156
+ arg,
157
+ :kind_of => [ String ]
158
+ )
159
+ end
160
+
161
+ # Sets the current cookbook version, or returns it. Can be two or three digits, seperated
162
+ # by dots. ie: '2.1', '1.5.4' or '0.9'.
163
+ #
164
+ # === Parameters
165
+ # version<String>:: The curent version, as a string
166
+ #
167
+ # === Returns
168
+ # version<String>:: Returns the current version
169
+ def version(arg=nil)
170
+ if arg
171
+ @version = Version.new(arg)
172
+ end
173
+
174
+ @version.to_s
175
+ end
176
+
177
+ # Sets the name of the cookbook, or returns it.
178
+ #
179
+ # === Parameters
180
+ # name<String>:: The curent cookbook name.
181
+ #
182
+ # === Returns
183
+ # name<String>:: Returns the current cookbook name.
184
+ def name(arg=nil)
185
+ set_or_return(
186
+ :name,
187
+ arg,
188
+ :kind_of => [ String ]
189
+ )
190
+ end
191
+
192
+ # Adds a supported platform, with version checking strings.
193
+ #
194
+ # === Parameters
195
+ # platform<String>,<Symbol>:: The platform (like :ubuntu or :mac_os_x)
196
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
197
+ #
198
+ # === Returns
199
+ # versions<Array>:: Returns the list of versions for the platform
200
+ def supports(platform, *versions)
201
+ versions.each { |v| _check_version_expression(v) }
202
+ @platforms[platform] = versions
203
+ @platforms[platform]
204
+ end
205
+
206
+ # Adds a dependency on another cookbook, with version checking strings.
207
+ #
208
+ # === Parameters
209
+ # cookbook<String>:: The cookbook
210
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
211
+ #
212
+ # === Returns
213
+ # versions<Array>:: Returns the list of versions for the platform
214
+ def depends(cookbook, *versions)
215
+ versions.each { |v| _check_version_expression(v) }
216
+ @dependencies[cookbook] = versions
217
+ @dependencies[cookbook]
218
+ end
219
+
220
+ # Adds a recommendation for another cookbook, with version checking strings.
221
+ #
222
+ # === Parameters
223
+ # cookbook<String>:: The cookbook
224
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
225
+ #
226
+ # === Returns
227
+ # versions<Array>:: Returns the list of versions for the platform
228
+ def recommends(cookbook, *versions)
229
+ versions.each { |v| _check_version_expression(v) }
230
+ @recommendations[cookbook] = versions
231
+ @recommendations[cookbook]
232
+ end
233
+
234
+ # Adds a suggestion for another cookbook, with version checking strings.
235
+ #
236
+ # === Parameters
237
+ # cookbook<String>:: The cookbook
238
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
239
+ #
240
+ # === Returns
241
+ # versions<Array>:: Returns the list of versions for the platform
242
+ def suggests(cookbook, *versions)
243
+ versions.each { |v| _check_version_expression(v) }
244
+ @suggestions[cookbook] = versions
245
+ @suggestions[cookbook]
246
+ end
247
+
248
+ # Adds a conflict for another cookbook, with version checking strings.
249
+ #
250
+ # === Parameters
251
+ # cookbook<String>:: The cookbook
252
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
253
+ #
254
+ # === Returns
255
+ # versions<Array>:: Returns the list of versions for the platform
256
+ def conflicts(cookbook, *versions)
257
+ versions.each { |v| _check_version_expression(v) }
258
+ @conflicting[cookbook] = versions
259
+ @conflicting[cookbook]
260
+ end
261
+
262
+ # Adds a recipe, definition, or resource provided by this cookbook.
263
+ #
264
+ # Recipes are specified as normal
265
+ # Definitions are followed by (), and can include :params for prototyping
266
+ # Resources are the stringified version (service[apache2])
267
+ #
268
+ # === Parameters
269
+ # recipe, definition, resource<String>:: The thing we provide
270
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
271
+ #
272
+ # === Returns
273
+ # versions<Array>:: Returns the list of versions for the platform
274
+ def provides(cookbook, *versions)
275
+ versions.each { |v| _check_version_expression(v) }
276
+ @providing[cookbook] = versions
277
+ @providing[cookbook]
278
+ end
279
+
280
+ # Adds a cookbook that is replaced by this one, with version checking strings.
281
+ #
282
+ # === Parameters
283
+ # cookbook<String>:: The cookbook we replace
284
+ # *versions<String>:: A list of versions matching << <= = >= >> followed by a version.
285
+ #
286
+ # === Returns
287
+ # versions<Array>:: Returns the list of versions for the platform
288
+ def replaces(cookbook, *versions)
289
+ versions.each { |v| _check_version_expression(v) }
290
+ @replacing[cookbook] = versions
291
+ @replacing[cookbook]
292
+ end
293
+
294
+ # Adds a description for a recipe.
295
+ #
296
+ # === Parameters
297
+ # recipe<String>:: The recipe
298
+ # description<String>:: The description of the recipe
299
+ #
300
+ # === Returns
301
+ # description<String>:: Returns the current description
302
+ def recipe(name, description)
303
+ @recipes[name] = description
304
+ end
305
+
306
+ # Adds an attribute that a user needs to configure for this cookbook. Takes
307
+ # a name (with the / notation for a nested attribute), followed by any of
308
+ # these options
309
+ #
310
+ # display_name<String>:: What a UI should show for this attribute
311
+ # description<String>:: A hint as to what this attr is for
312
+ # choice<Array>:: An array of choices to present to the user.
313
+ # calculated<Boolean>:: If true, the default value is calculated by the recipe and cannot be displayed.
314
+ # type<String>:: "string" or "array" - default is "string" ("hash" is supported for backwards compatibility)
315
+ # required<String>:: Whether this attr is 'required', 'recommended' or 'optional' - default 'optional' (true/false values also supported for backwards compatibility)
316
+ # recipes<Array>:: An array of recipes which need this attr set.
317
+ # default<String>,<Array>,<Hash>:: The default value
318
+ #
319
+ # === Parameters
320
+ # name<String>:: The name of the attribute ('foo', or 'apache2/log_dir')
321
+ # options<Hash>:: The description of the options
322
+ #
323
+ # === Returns
324
+ # options<Hash>:: Returns the current options hash
325
+ def attribute(name, options)
326
+ validate(
327
+ options,
328
+ {
329
+ :display_name => { :kind_of => String },
330
+ :description => { :kind_of => String },
331
+ :choice => { :kind_of => [ Array ], :default => [] },
332
+ :calculated => { :equal_to => [ true, false ], :default => false },
333
+ :type => { :equal_to => [ "string", "array", "hash" ], :default => "string" },
334
+ :required => { :equal_to => [ "required", "recommended", "optional", true, false ], :default => "optional" },
335
+ :recipes => { :kind_of => [ Array ], :default => [] },
336
+ :default => { :kind_of => [ String, Array, Hash ] }
337
+ }
338
+ )
339
+ options[:required] = remap_required_attribute(options[:required]) unless options[:required].nil?
340
+ validate_string_array(options[:choice])
341
+ validate_calculated_default_rule(options)
342
+ validate_choice_default_rule(options)
343
+
344
+ @attributes[name] = options
345
+ @attributes[name]
346
+ end
347
+
348
+ def grouping(name, options)
349
+ validate(
350
+ options,
351
+ {
352
+ :title => { :kind_of => String },
353
+ :description => { :kind_of => String }
354
+ }
355
+ )
356
+ @groupings[name] = options
357
+ @groupings[name]
358
+ end
359
+
360
+ def _check_version_expression(version_string)
361
+ if version_string =~ /^(>>|>=|=|<=|<<) (.+)$/
362
+ [ $1, $2 ]
363
+ else
364
+ raise ArgumentError, "Version expression #{version_string} is invalid!"
365
+ end
366
+ end
367
+
368
+ def to_json(*a)
369
+ result = {
370
+ :name => self.name,
371
+ :description => self.description,
372
+ :long_description => self.long_description,
373
+ :maintainer => self.maintainer,
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
387
+ }
388
+ result.to_json(*a)
389
+ end
390
+
391
+ def self.from_hash(o)
392
+ cm = self.new()
393
+ cm.from_hash(o)
394
+ cm
395
+ end
396
+
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')
416
+ self
417
+ end
418
+
419
+ def self.from_json(string)
420
+ o = JSON.parse(string)
421
+ self.from_hash(o)
422
+ end
423
+
424
+ def from_json(string)
425
+ o = JSON.parse(string)
426
+ from_hash(o)
427
+ end
428
+
429
+ private
430
+
431
+ # Verify that the given array is an array of strings
432
+ #
433
+ # Raise an exception if the members of the array are not Strings
434
+ #
435
+ # === Parameters
436
+ # arry<Array>:: An array to be validated
437
+ def validate_string_array(arry)
438
+ if arry.kind_of?(Array)
439
+ arry.each do |choice|
440
+ validate( {:choice => choice}, {:choice => {:kind_of => String}} )
441
+ end
442
+ end
443
+ end
444
+
445
+ # For backwards compatibility, remap Boolean values to String
446
+ # true is mapped to "required"
447
+ # false is mapped to "optional"
448
+ #
449
+ # === Parameters
450
+ # required_attr<String><Boolean>:: The value of options[:required]
451
+ #
452
+ # === Returns
453
+ # required_attr<String>:: "required", "recommended", or "optional"
454
+ def remap_required_attribute(value)
455
+ case value
456
+ when true
457
+ value = "required"
458
+ when false
459
+ value = "optional"
460
+ end
461
+ value
462
+ end
463
+
464
+ def validate_calculated_default_rule(options)
465
+ calculated_conflict = ((options[:default].is_a?(Array) && !options[:default].empty?) ||
466
+ (options[:default].is_a?(String) && !options[:default] != "")) &&
467
+ options[:calculated] == true
468
+ raise ArgumentError, "Default cannot be specified if calculated is true!" if calculated_conflict
469
+ end
470
+
471
+ def validate_choice_default_rule(options)
472
+ return if !options[:choice].is_a?(Array) || options[:choice].empty?
473
+
474
+ if options[:default].is_a?(String) && options[:default] != ""
475
+ raise ArgumentError, "Default must be one of your choice values!" if options[:choice].index(options[:default]) == nil
476
+ end
477
+
478
+ if options[:default].is_a?(Array) && !options[:default].empty?
479
+ options[:default].each do |val|
480
+ raise ArgumentError, "Default values must be a subset of your choice values!" if options[:choice].index(val) == nil
481
+ end
482
+ end
483
+ end
484
+
485
+ end
486
+ end
487
+ end