rails.rb 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #
  2. # Author:: Noah Kantrowitz <noah@opscode.com>
  3. # Cookbook Name:: application
  4. # Provider:: rails
  5. #
  6. # Copyright:: 2011, Opscode, Inc <legal@opscode.com>
  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. action :before_compile do
  21. new_resource.environment.update({
  22. "RAILS_ENV" => new_resource.environment_name,
  23. })
  24. new_resource.symlink_before_migrate.update({
  25. "database.yml" => "config/database.yml",
  26. "memcached.yml" => "config/memcached.yml",
  27. })
  28. end
  29. action :before_deploy do
  30. new_resource.environment['RAILS_ENV'] = new_resource.environment_name
  31. new_resource.gems.each do |gem, ver|
  32. gem_package gem do
  33. action :install
  34. version ver if ver && ver.length > 0
  35. end
  36. end
  37. if new_resource.database_master_role
  38. dbm = nil
  39. # If we are the database master
  40. if node['roles'].include?(new_resource.database_master_role)
  41. dbm = node
  42. else
  43. # Find the database master
  44. results = search(:node, "role:#{new_resource.database_master_role} AND chef_environment:#{node.chef_environment}", nil, 0, 1)
  45. rows = results[0]
  46. if rows.length == 1
  47. dbm = rows[0]
  48. end
  49. end
  50. # Assuming we have one...
  51. if dbm
  52. template "#{new_resource.path}/shared/database.yml" do
  53. source "database.yml.erb"
  54. cookbook "application"
  55. owner new_resource.owner
  56. group new_resource.group
  57. mode "644"
  58. variables(
  59. :host => (dbm.attribute?('cloud') ? dbm['cloud']['local_ipv4'] : dbm['ipaddress']),
  60. :database => new_resource.database,
  61. :rails_env => new_resource.environment_name
  62. )
  63. end
  64. else
  65. Chef::Log.warn("No node with role #{new_resource.database_master_role}, database.yml not rendered!")
  66. end
  67. end
  68. if new_resource.memcached_role
  69. results = search(:node, "role:#{new_resource.memcached_role} AND chef_environment:#{node.chef_environment} NOT hostname:#{node[:hostname]}")
  70. if results.length == 0
  71. if node['roles'].include?(new_resource.memcached_role)
  72. results << node
  73. end
  74. end
  75. template "#{new_resource.path}/shared/memcached.yml" do
  76. source "memcached.yml.erb"
  77. cookbook "application"
  78. owner new_resource.owner
  79. group new_resource.group
  80. mode "644"
  81. variables(
  82. :memcached_envs => new_resource.memcached,
  83. :hosts => results.sort_by { |r| r.name }
  84. )
  85. end
  86. end
  87. end
  88. action :before_migrate do
  89. gem_names = new_resource.gems.map{|gem, ver| gem}
  90. if gem_names.include?('bundler')
  91. Chef::Log.info "Running bundle install"
  92. link "#{new_resource.release_path}/vendor/bundle" do
  93. to "#{new_resource.path}/shared/vendor_bundle"
  94. end
  95. common_groups = %w{development test cucumber staging production}
  96. bundler_deployment = new_resource.bundler_deployment
  97. if bundler_deployment.nil?
  98. # Check for a Gemfile.lock
  99. bundler_deployment = ::File.exists?(::File.join(new_resource.release_path, "Gemfile.lock"))
  100. end
  101. execute "bundle install #{bundler_deployment ? "--deployment " : ""}--without #{(common_groups -([node.chef_environment])).join(' ')}" do
  102. ignore_failure true
  103. cwd new_resource.release_path
  104. end
  105. elsif gem_names.include?('bundler08')
  106. Chef::Log.info "Running gem bundle"
  107. execute "gem bundle" do
  108. ignore_failure true
  109. cwd new_resource.release_path
  110. end
  111. else
  112. # chef runs before_migrate, then symlink_before_migrate symlinks, then migrations,
  113. # yet our before_migrate needs database.yml to exist (and must complete before
  114. # migrations).
  115. #
  116. # maybe worth doing run_symlinks_before_migrate before before_migrate callbacks,
  117. # or an add'l callback.
  118. execute "(ln -s ../../../shared/database.yml config/database.yml && rake gems:install); rm config/database.yml" do
  119. ignore_failure true
  120. cwd new_resource.release_path
  121. end
  122. end
  123. if new_resource.migration_command.include?('rake') && !gem_names.include?('rake')
  124. gem_package "rake" do
  125. action :install
  126. end
  127. end
  128. end
  129. action :before_symlink do
  130. ruby_block "remove_run_migrations" do
  131. block do
  132. if node.role?("#{new_resource.id}_run_migrations")
  133. Chef::Log.info("Migrations were run, removing role[#{new_resource.id}_run_migrations]")
  134. node.run_list.remove("role[#{new_resource.id}_run_migrations]")
  135. end
  136. end
  137. end
  138. end
  139. action :before_restart do
  140. end
  141. action :after_restart do
  142. end
  143. # action :deploy do
  144. # # Alias to a variable so I can use in sub-resources
  145. # new_resource = @new_resource
  146. # # make the _default chef_environment look like the Rails production environment
  147. # rails_env = (node.chef_environment =~ /_default/ ? "production" : node.chef_environment)
  148. # node.run_state[:rails_env] = rails_env
  149. # application new_resource.id do
  150. # action :deploy
  151. # path new_resource.path
  152. # owner new_resource.owner
  153. # group new_resource.group
  154. # revision new_resource.revision
  155. # repository new_resource.repository
  156. # deploy_key new_resource.deploy_key
  157. # force new_resource.force
  158. # packages new_resource.packages
  159. # environment new_resource.environment.merge('RAILS_ENV' => rails_env)
  160. # before_deploy do
  161. # new_resource.gems.each do |gem, ver|
  162. # gem_package gem do
  163. # action :install
  164. # version ver if ver && ver.length > 0
  165. # end
  166. # end
  167. # if new_resource.database_master_role
  168. # dbm = nil
  169. # # If we are the database master
  170. # if node['roles'].include?(new_resource.database_master_role)
  171. # dbm = node
  172. # else
  173. # # Find the database master
  174. # results = search(:node, "role:#{new_resource.database_master_role} AND chef_environment:#{node.chef_environment}", nil, 0, 1)
  175. # rows = results[0]
  176. # if rows.length == 1
  177. # dbm = rows[0]
  178. # end
  179. # end
  180. # # Assuming we have one...
  181. # if dbm
  182. # template "#{new_resource.path}/shared/database.yml" do
  183. # source "database.yml.erb"
  184. # cookbook "application"
  185. # owner new_resource.owner
  186. # group new_resource.group
  187. # mode "644"
  188. # variables(
  189. # :host => (dbm.attribute?('cloud') ? dbm['cloud']['local_ipv4'] : dbm['ipaddress']),
  190. # :databases => new_resource.databases,
  191. # :rails_env => rails_env
  192. # )
  193. # end
  194. # else
  195. # Chef::Log.warn("No node with role #{new_resource.database_master_role}, database.yml not rendered!")
  196. # end
  197. # end
  198. # if new_resource.memcached_role
  199. # results = search(:node, "role:#{new_resource.memcached_role} AND chef_environment:#{node.chef_environment} NOT hostname:#{node[:hostname]}")
  200. # if results.length == 0
  201. # if node['roles'].include?(new_resource.memcached_role)
  202. # results << node
  203. # end
  204. # end
  205. # template "#{new_resource.path}/shared/memcached.yml" do
  206. # source "memcached.yml.erb"
  207. # cookbook "application"
  208. # owner new_resource.owner
  209. # group new_resource.group
  210. # mode "644"
  211. # variables(
  212. # :memcached_envs => new_resource.memcached,
  213. # :hosts => results.sort_by { |r| r.name }
  214. # )
  215. # end
  216. # end
  217. # callback(:before_deploy, new_resource.before_deploy)
  218. # end
  219. # before_migrate do
  220. # gem_names = new_resource.gems.map{|gem, ver| gem}
  221. # if gem_names.include?('bundler')
  222. # link "#{release_path}/vendor/bundle" do
  223. # to "#{new_resource.path}/shared/vendor_bundle"
  224. # end
  225. # common_groups = %w{development test cucumber staging production}
  226. # execute "bundle install --deployment --without #{(common_groups -([node.chef_environment])).join(' ')}" do
  227. # ignore_failure true
  228. # cwd release_path
  229. # end
  230. # elsif gem_names.include?('bundler08')
  231. # execute "gem bundle" do
  232. # ignore_failure true
  233. # cwd release_path
  234. # end
  235. # elsif new_resource.databases.has_key?(rails_env)
  236. # # chef runs before_migrate, then symlink_before_migrate symlinks, then migrations,
  237. # # yet our before_migrate needs database.yml to exist (and must complete before
  238. # # migrations).
  239. # #
  240. # # maybe worth doing run_symlinks_before_migrate before before_migrate callbacks,
  241. # # or an add'l callback.
  242. # execute "(ln -s ../../../shared/database.yml config/database.yml && rake gems:install); rm config/database.yml" do
  243. # ignore_failure true
  244. # cwd release_path
  245. # end
  246. # end
  247. # if new_resource.migration_command.include?('rake') && !gem_names.include?('rake')
  248. # gem_package "rake" do
  249. # action :install
  250. # end
  251. # end
  252. # end
  253. # symlink_before_migrate({
  254. # "database.yml" => "config/database.yml",
  255. # "memcached.yml" => "config/memcached.yml"
  256. # })
  257. # migrate new_resource.migrate
  258. # migration_command new_resource.migration_command
  259. # before_symlink do
  260. # ruby_block "remove_run_migrations" do
  261. # block do
  262. # if node.role?("#{new_resource.id}_run_migrations")
  263. # Chef::Log.info("Migrations were run, removing role[#{new_resource.id}_run_migrations]")
  264. # node.run_list.remove("role[#{new_resource.id}_run_migrations]")
  265. # end
  266. # end
  267. # end
  268. # end
  269. # end
  270. # end