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,323 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@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
+ require 'chef/config'
20
+ require 'chef/mixin/params_validate'
21
+ require 'chef/mixin/generate_url'
22
+ require 'chef/mixin/checksum'
23
+ require 'chef/log'
24
+ require 'chef/rest'
25
+ require 'chef/platform'
26
+ require 'chef/node'
27
+ require 'chef/role'
28
+ require 'chef/file_cache'
29
+ require 'chef/compile'
30
+ require 'chef/runner'
31
+ require 'ohai'
32
+
33
+ class Chef
34
+ class Client
35
+
36
+ include Chef::Mixin::GenerateURL
37
+ include Chef::Mixin::Checksum
38
+
39
+ attr_accessor :node, :registration, :safe_name, :json_attribs, :validation_token, :node_name, :ohai
40
+
41
+ # Creates a new Chef::Client.
42
+ def initialize()
43
+ @node = nil
44
+ @safe_name = nil
45
+ @validation_token = nil
46
+ @registration = nil
47
+ @json_attribs = nil
48
+ @node_name = nil
49
+ @node_exists = true
50
+ Mixlib::Authentication::Log.logger = Ohai::Log.logger = Chef::Log.logger
51
+ @ohai = Ohai::System.new
52
+ @ohai_has_run = false
53
+ if File.exists?(Chef::Config[:client_key])
54
+ @rest = Chef::REST.new(Chef::Config[:chef_server_url])
55
+ else
56
+ @rest = Chef::REST.new(Chef::Config[:chef_server_url], nil, nil)
57
+ end
58
+ end
59
+
60
+ # Do a full run for this Chef::Client. Calls:
61
+ #
62
+ # * build_node - Get the last known state, merge with local changes
63
+ # * register - Make sure we have an openid
64
+ # * authenticate - Authenticate with our openid
65
+ # * sync_library_files - Populate the local cache with all the library files
66
+ # * sync_provider_files - Populate the local cache with all the provider files
67
+ # * sync_resource_files - Populate the local cache with all the resource files
68
+ # * sync_attribute_files - Populate the local cache with all the attribute files
69
+ # * sync_definitions - Populate the local cache with all the definitions
70
+ # * sync_recipes - Populate the local cache with all the recipes
71
+ # * do_attribute_files - Populate the local cache with all attributes, and execute them
72
+ # * save_node - Store the new node configuration
73
+ # * converge - Bring this system up to date, based on the local cache
74
+ # * save_node - Store the node again, in case convergence altered future state
75
+ #
76
+ # === Returns
77
+ # true:: Always returns true.
78
+ def run
79
+ start_time = Time.now
80
+ Chef::Log.info("Starting Chef Run")
81
+
82
+ determine_node_name
83
+ register
84
+ build_node(@node_name)
85
+ save_node
86
+ sync_cookbooks
87
+ save_node
88
+ converge
89
+ save_node
90
+
91
+ end_time = Time.now
92
+ Chef::Log.info("Chef Run complete in #{end_time - start_time} seconds")
93
+ true
94
+ end
95
+
96
+ # Similar to Chef::Client#run, but instead of talking to the Chef server,
97
+ # simply runs in a standalone ("solo") mode.
98
+ #
99
+ # Someday, we'll have chef_chewbacca.
100
+ #
101
+ # === Returns
102
+ # true:: Always returns true.
103
+ def run_solo
104
+ start_time = Time.now
105
+ Chef::Log.info("Starting Chef Solo Run")
106
+
107
+ determine_node_name
108
+ build_node(@node_name, true)
109
+ converge(true)
110
+
111
+ end_time = Time.now
112
+ Chef::Log.info("Chef Run complete in #{end_time - start_time} seconds")
113
+ true
114
+ end
115
+
116
+ def run_ohai
117
+ if ohai.keys
118
+ ohai.refresh_plugins
119
+ else
120
+ ohai.all_plugins
121
+ end
122
+ end
123
+
124
+ def determine_node_name
125
+ run_ohai
126
+ unless safe_name && node_name
127
+ if Chef::Config[:node_name]
128
+ @node_name = Chef::Config[:node_name]
129
+ else
130
+ @node_name ||= ohai[:fqdn] ? ohai[:fqdn] : ohai[:hostname]
131
+ Chef::Config[:node_name] = @node_name
132
+ end
133
+ @safe_name = @node_name.gsub(/\./, '_')
134
+ end
135
+ @node_name
136
+ end
137
+
138
+ # Builds a new node object for this client. Starts with querying for the FQDN of the current
139
+ # host (unless it is supplied), then merges in the facts from Ohai.
140
+ #
141
+ # === Parameters
142
+ # node_name<String>:: The name of the node to build - defaults to nil
143
+ #
144
+ # === Returns
145
+ # node<Chef::Node>:: Returns the created node object, also stored in @node
146
+ def build_node(node_name=nil, solo=false)
147
+ node_name ||= determine_node_name
148
+ raise RuntimeError, "Unable to determine node name from ohai" unless node_name
149
+ Chef::Log.debug("Building node object for #{@safe_name}")
150
+ unless solo
151
+ begin
152
+ @node = @rest.get_rest("nodes/#{@safe_name}")
153
+ rescue Net::HTTPServerException => e
154
+ unless e.message =~ /^404/
155
+ raise e
156
+ end
157
+ end
158
+ end
159
+ unless @node
160
+ @node_exists = false
161
+ @node ||= Chef::Node.new
162
+ @node.name(node_name)
163
+ end
164
+
165
+ @node.consume_attributes(@json_attribs)
166
+
167
+ ohai.each do |field, value|
168
+ Chef::Log.debug("Ohai Attribute: #{field} - #{value.inspect}")
169
+ @node[field] = value
170
+ end
171
+ platform, version = Chef::Platform.find_platform_and_version(@node)
172
+ Chef::Log.debug("Platform is #{platform} version #{version}")
173
+ @node[:platform] = platform
174
+ @node[:platform_version] = version
175
+ @node
176
+ end
177
+
178
+ #
179
+ # === Returns
180
+ # rest<Chef::REST>:: returns Chef::REST connection object
181
+ def register
182
+ if File.exists?(Chef::Config[:client_key])
183
+ Chef::Log.debug("Client key #{Chef::Config[:client_key]} is present - skipping registration")
184
+ else
185
+ Chef::Log.info("Client key #{Chef::Config[:client_key]} is not present - registering")
186
+ @vr = Chef::REST.new(Chef::Config[:client_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key])
187
+ @vr.register(@node_name, Chef::Config[:client_key])
188
+ end
189
+ # We now have the client key, and should use it from now on.
190
+ @rest = Chef::REST.new(Chef::Config[:chef_server_url])
191
+ end
192
+
193
+ # Update the file caches for a given cache segment. Takes a segment name
194
+ # and a hash that matches one of the cookbooks/_attribute_files style
195
+ # remote file listings.
196
+ #
197
+ # === Parameters
198
+ # segment<String>:: The cache segment to update
199
+ # remote_list<Hash>:: A cookbooks/_attribute_files style remote file listing
200
+ def update_file_cache(cookbook_name, parts)
201
+ Chef::Log.debug("Synchronizing cookbook #{cookbook_name}")
202
+
203
+ file_canonical = Hash.new
204
+
205
+ [ "recipes", "attributes", "definitions", "libraries", "resources", "providers" ].each do |segment|
206
+ remote_list = parts.has_key?(segment) ? parts[segment] : []
207
+
208
+ # segement = cookbook segment
209
+ # remote_list = list of file hashes
210
+ #
211
+ # We need the list of known good attribute files, so we can delete any that are
212
+ # just laying about.
213
+
214
+ remote_list.each do |rf|
215
+ cache_file = File.join("cookbooks", cookbook_name, segment, rf['name'])
216
+ file_canonical[cache_file] = true
217
+
218
+ # For back-compat between older clients and new chef servers
219
+ rf['checksum'] ||= nil
220
+
221
+ current_checksum = nil
222
+ if Chef::FileCache.has_key?(cache_file)
223
+ current_checksum = checksum(Chef::FileCache.load(cache_file, false))
224
+ end
225
+
226
+ if current_checksum != rf['checksum']
227
+ rf_url = generate_cookbook_url(
228
+ rf['name'],
229
+ cookbook_name,
230
+ segment,
231
+ @node,
232
+ current_checksum ? { 'checksum' => current_checksum } : nil
233
+ )
234
+
235
+ changed = true
236
+ begin
237
+ raw_file = @rest.get_rest(rf_url, true)
238
+ rescue Net::HTTPRetriableError => e
239
+ if e.response.kind_of?(Net::HTTPNotModified)
240
+ changed = false
241
+ Chef::Log.debug("Cache file #{cache_file} is unchanged")
242
+ else
243
+ raise e
244
+ end
245
+ end
246
+
247
+ if changed
248
+ Chef::Log.info("Storing updated #{cache_file} in the cache.")
249
+ Chef::FileCache.move_to(raw_file.path, cache_file)
250
+ end
251
+ end
252
+ end
253
+
254
+ end
255
+
256
+ Chef::FileCache.list.each do |cache_file|
257
+ if cache_file =~ /^cookbooks\/#{cookbook_name}\/(recipes|attributes|definitions|libraries|resources|providers)\//
258
+ unless file_canonical[cache_file]
259
+ Chef::Log.info("Removing #{cache_file} from the cache; it is no longer on the server.")
260
+ Chef::FileCache.delete(cache_file)
261
+ end
262
+ end
263
+ end
264
+
265
+ end
266
+
267
+ # Synchronizes all the cookbooks from the chef-server.
268
+ #
269
+ # === Returns
270
+ # true:: Always returns true
271
+ def sync_cookbooks
272
+ Chef::Log.debug("Synchronizing cookbooks")
273
+ cookbook_hash = @rest.get_rest("nodes/#{@safe_name}/cookbooks")
274
+ Chef::Log.debug("Cookbooks to load: #{cookbook_hash.inspect}")
275
+ Chef::FileCache.list.each do |cache_file|
276
+ if cache_file =~ /^cookbooks\/(.+?)\//
277
+ unless cookbook_hash.has_key?($1)
278
+ Chef::Log.info("Removing #{cache_file} from the cache; it's cookbook is no longer needed on this client.")
279
+ Chef::FileCache.delete(cache_file)
280
+ end
281
+ end
282
+ end
283
+ cookbook_hash.each do |cookbook_name, parts|
284
+ update_file_cache(cookbook_name, parts)
285
+ end
286
+ end
287
+
288
+ # Updates the current node configuration on the server.
289
+ #
290
+ # === Returns
291
+ # true:: Always returns true
292
+ def save_node
293
+ Chef::Log.debug("Saving the current state of node #{@safe_name}")
294
+ if @node_exists
295
+ @node = @rest.put_rest("nodes/#{@safe_name}", @node)
296
+ else
297
+ result = @rest.post_rest("nodes", @node)
298
+ @node = @rest.get_rest(result['uri'])
299
+ @node_exists = true
300
+ end
301
+ true
302
+ end
303
+
304
+ # Compiles the full list of recipes for the server, and passes it to an instance of
305
+ # Chef::Runner.converge.
306
+ #
307
+ # === Returns
308
+ # true:: Always returns true
309
+ def converge(solo=false)
310
+ Chef::Log.debug("Compiling recipes for node #{@safe_name}")
311
+ unless solo
312
+ Chef::Config[:cookbook_path] = File.join(Chef::Config[:file_cache_path], "cookbooks")
313
+ end
314
+ compile = Chef::Compile.new(@node)
315
+
316
+ Chef::Log.debug("Converging node #{@safe_name}")
317
+ cr = Chef::Runner.new(@node, compile.collection, compile.definitions, compile.cookbook_loader)
318
+ cr.converge
319
+ true
320
+ end
321
+
322
+ end
323
+ end
@@ -0,0 +1,158 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@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
+ require 'chef/cookbook_loader'
20
+ require 'chef/resource_collection'
21
+ require 'chef/node'
22
+ require 'chef/role'
23
+ require 'chef/log'
24
+ require 'chef/mixin/deep_merge'
25
+ require 'chef/mixin/language_include_recipe'
26
+
27
+ class Chef
28
+ class Compile
29
+
30
+ attr_accessor :node, :cookbook_loader, :collection, :definitions
31
+
32
+ include Chef::Mixin::LanguageIncludeRecipe
33
+
34
+ # Creates a new Chef::Compile object and populates its fields. This object gets
35
+ # used by the Chef Server to generate a fully compiled recipe list for a node.
36
+ #
37
+ # === Returns
38
+ # object<Chef::Compile>:: Duh. :)
39
+ def initialize(node=nil)
40
+ @node = node
41
+ @cookbook_loader = Chef::CookbookLoader.new
42
+ @node.cookbook_loader = @cookbook_loader
43
+ @collection = Chef::ResourceCollection.new
44
+ @definitions = Hash.new
45
+ @recipes = Array.new
46
+ @default_attributes = Array.new
47
+ @override_attributes = Array.new
48
+
49
+ load_libraries
50
+ load_providers
51
+ load_resources
52
+ load_attributes
53
+ load_definitions
54
+ load_recipes
55
+ end
56
+
57
+ # Looks up the node via the "name" argument, first from CouchDB, then by calling
58
+ # Chef::Node.find_file(name)
59
+ #
60
+ # The first step in compiling the catalog. Results available via the node accessor.
61
+ #
62
+ # === Returns
63
+ # node<Chef::Node>:: The loaded Chef Node
64
+ def load_node(name)
65
+ Chef::Log.debug("Loading Chef Node #{name} from CouchDB")
66
+ @node = Chef::Node.load(name)
67
+ Chef::Log.debug("Loading Recipe for Chef Node #{name}")
68
+ @node.find_file(name)
69
+ @node
70
+ end
71
+
72
+ # Load all the attributes, from every cookbook
73
+ #
74
+ # === Returns
75
+ # true:: Always returns true
76
+ def load_attributes()
77
+ @cookbook_loader.each do |cookbook|
78
+ cookbook.load_attributes(@node)
79
+ end
80
+
81
+ true
82
+ end
83
+
84
+ # Load all the definitions, from every cookbook, so they are available when we process
85
+ # the recipes.
86
+ #
87
+ # Results available via the definitions accessor.
88
+ #
89
+ # === Returns
90
+ # true:: Always returns true
91
+ def load_definitions()
92
+ @cookbook_loader.each do |cookbook|
93
+ hash = cookbook.load_definitions
94
+ @definitions.merge!(hash)
95
+ end
96
+ true
97
+ end
98
+
99
+ # Load all the libraries, from every cookbook, so they are available when we process
100
+ # the recipes.
101
+ #
102
+ # === Returns
103
+ # true:: Always returns true
104
+ def load_libraries()
105
+ @cookbook_loader.each do |cookbook|
106
+ cookbook.load_libraries
107
+ end
108
+ true
109
+ end
110
+
111
+ # Load all the providers, from every cookbook, so they are available when we process
112
+ # the recipes.
113
+ #
114
+ # === Returns
115
+ # true:: Always returns true
116
+ def load_providers()
117
+ @cookbook_loader.each do |cookbook|
118
+ cookbook.load_providers
119
+ end
120
+ true
121
+ end
122
+
123
+ # Load all the resources, from every cookbook, so they are available when we process
124
+ # the recipes.
125
+ #
126
+ # === Returns
127
+ # true:: Always returns true
128
+ def load_resources()
129
+ @cookbook_loader.each do |cookbook|
130
+ cookbook.load_resources
131
+ end
132
+ true
133
+ end
134
+
135
+ # Load all the recipes specified in the node data (loaded via load_node, above.)
136
+ #
137
+ # The results are available via the collection accessor (which returns a Chef::ResourceCollection
138
+ # object)
139
+ #
140
+ # === Returns
141
+ # true:: Always returns true
142
+ def load_recipes
143
+ expand_node
144
+ @recipes.each do |recipe|
145
+ include_recipe(recipe)
146
+ end
147
+ true
148
+ end
149
+
150
+ def expand_node
151
+ @recipes, @default_attributes, @override_attributes = @node.run_list.expand
152
+ @node.default_attrs = @default_attributes
153
+ @node.override_attrs = @override_attributes
154
+ return @recipes, @default_attributes, @override_attributes
155
+ end
156
+
157
+ end
158
+ end