runa-chef 0.8.0.1

Sign up to get free protection for your applications and to get access to all the features.
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