PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/chef/resource/deploy.rb

https://github.com/evanphx/chef
Ruby | 403 lines | 279 code | 46 blank | 78 comment | 3 complexity | 7ec6553934e67d79b9c32645159840f0 MD5 | raw file
Possible License(s): Apache-2.0
  1. #
  2. # Author:: Daniel DeLeo (<dan@kallistec.com>)
  3. # Author:: Tyler Cloke (<tyler@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. # EX:
  20. # deploy "/my/deploy/dir" do
  21. # repo "git@github.com/whoami/project"
  22. # revision "abc123" # or "HEAD" or "TAG_for_1.0" or (subversion) "1234"
  23. # user "deploy_ninja"
  24. # enable_submodules true
  25. # migrate true
  26. # migration_command "rake db:migrate"
  27. # environment "RAILS_ENV" => "production", "OTHER_ENV" => "foo"
  28. # shallow_clone true
  29. # action :deploy # or :rollback
  30. # restart_command "touch tmp/restart.txt"
  31. # git_ssh_wrapper "wrap-ssh4git.sh"
  32. # scm_provider Chef::Provider::Git # is the default, for svn: Chef::Provider::Subversion
  33. # svn_username "whoami"
  34. # svn_password "supersecret"
  35. # end
  36. require "chef/resource/scm"
  37. class Chef
  38. class Resource
  39. # Deploy: Deploy apps from a source control repository.
  40. #
  41. # Callbacks:
  42. # Callbacks can be a block or a string. If given a block, the code
  43. # is evaluated as an embedded recipe, and run at the specified
  44. # point in the deploy process. If given a string, the string is taken as
  45. # a path to a callback file/recipe. Paths are evaluated relative to the
  46. # release directory. Callback files can contain chef code (resources, etc.)
  47. #
  48. class Deploy < Chef::Resource
  49. provider_base Chef::Provider::Deploy
  50. identity_attr :repository
  51. state_attrs :deploy_to, :revision
  52. def initialize(name, run_context=nil)
  53. super
  54. @resource_name = :deploy
  55. @deploy_to = name
  56. @environment = nil
  57. @repository_cache = 'cached-copy'
  58. @copy_exclude = []
  59. @purge_before_symlink = %w{log tmp/pids public/system}
  60. @create_dirs_before_symlink = %w{tmp public config}
  61. @symlink_before_migrate = {"config/database.yml" => "config/database.yml"}
  62. @symlinks = {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"}
  63. @revision = 'HEAD'
  64. @action = :deploy
  65. @migrate = false
  66. @rollback_on_error = false
  67. @remote = "origin"
  68. @enable_submodules = false
  69. @shallow_clone = false
  70. @scm_provider = Chef::Provider::Git
  71. @svn_force_export = false
  72. @provider = Chef::Provider::Deploy::Timestamped
  73. @allowed_actions.push(:force_deploy, :deploy, :rollback)
  74. @additional_remotes = Hash[]
  75. @keep_releases = 5
  76. end
  77. # where the checked out/cloned code goes
  78. def destination
  79. @destination ||= shared_path + "/#{@repository_cache}"
  80. end
  81. # where shared stuff goes, i.e., logs, tmp, etc. goes here
  82. def shared_path
  83. @shared_path ||= @deploy_to + "/shared"
  84. end
  85. # where the deployed version of your code goes
  86. def current_path
  87. @current_path ||= @deploy_to + "/current"
  88. end
  89. def depth
  90. @shallow_clone ? "5" : nil
  91. end
  92. # note: deploy_to is your application "meta-root."
  93. def deploy_to(arg=nil)
  94. set_or_return(
  95. :deploy_to,
  96. arg,
  97. :kind_of => [ String ]
  98. )
  99. end
  100. def repo(arg=nil)
  101. set_or_return(
  102. :repo,
  103. arg,
  104. :kind_of => [ String ]
  105. )
  106. end
  107. alias :repository :repo
  108. def remote(arg=nil)
  109. set_or_return(
  110. :remote,
  111. arg,
  112. :kind_of => [ String ]
  113. )
  114. end
  115. def role(arg=nil)
  116. set_or_return(
  117. :role,
  118. arg,
  119. :kind_of => [ String ]
  120. )
  121. end
  122. def restart_command(arg=nil, &block)
  123. arg ||= block
  124. set_or_return(
  125. :restart_command,
  126. arg,
  127. :kind_of => [ String, Proc ]
  128. )
  129. end
  130. alias :restart :restart_command
  131. def migrate(arg=nil)
  132. set_or_return(
  133. :migrate,
  134. arg,
  135. :kind_of => [ TrueClass, FalseClass ]
  136. )
  137. end
  138. def migration_command(arg=nil)
  139. set_or_return(
  140. :migration_command,
  141. arg,
  142. :kind_of => [ String ]
  143. )
  144. end
  145. def rollback_on_error(arg=nil)
  146. set_or_return(
  147. :rollback_on_error,
  148. arg,
  149. :kind_of => [ TrueClass, FalseClass ]
  150. )
  151. end
  152. def user(arg=nil)
  153. set_or_return(
  154. :user,
  155. arg,
  156. :kind_of => [ String ]
  157. )
  158. end
  159. def group(arg=nil)
  160. set_or_return(
  161. :group,
  162. arg,
  163. :kind_of => [ String ]
  164. )
  165. end
  166. def enable_submodules(arg=nil)
  167. set_or_return(
  168. :enable_submodules,
  169. arg,
  170. :kind_of => [ TrueClass, FalseClass ]
  171. )
  172. end
  173. def shallow_clone(arg=nil)
  174. set_or_return(
  175. :shallow_clone,
  176. arg,
  177. :kind_of => [ TrueClass, FalseClass ]
  178. )
  179. end
  180. def repository_cache(arg=nil)
  181. set_or_return(
  182. :repository_cache,
  183. arg,
  184. :kind_of => [ String ]
  185. )
  186. end
  187. def copy_exclude(arg=nil)
  188. set_or_return(
  189. :copy_exclude,
  190. arg,
  191. :kind_of => [ String ]
  192. )
  193. end
  194. def revision(arg=nil)
  195. set_or_return(
  196. :revision,
  197. arg,
  198. :kind_of => [ String ]
  199. )
  200. end
  201. alias :branch :revision
  202. def git_ssh_wrapper(arg=nil)
  203. set_or_return(
  204. :git_ssh_wrapper,
  205. arg,
  206. :kind_of => [ String ]
  207. )
  208. end
  209. alias :ssh_wrapper :git_ssh_wrapper
  210. def svn_username(arg=nil)
  211. set_or_return(
  212. :svn_username,
  213. arg,
  214. :kind_of => [ String ]
  215. )
  216. end
  217. def svn_password(arg=nil)
  218. set_or_return(
  219. :svn_password,
  220. arg,
  221. :kind_of => [ String ]
  222. )
  223. end
  224. def svn_arguments(arg=nil)
  225. set_or_return(
  226. :svn_arguments,
  227. arg,
  228. :kind_of => [ String ]
  229. )
  230. end
  231. def svn_info_args(arg=nil)
  232. set_or_return(
  233. :svn_arguments,
  234. arg,
  235. :kind_of => [ String ])
  236. end
  237. def scm_provider(arg=nil)
  238. klass = if arg.kind_of?(String) || arg.kind_of?(Symbol)
  239. lookup_provider_constant(arg)
  240. else
  241. arg
  242. end
  243. set_or_return(
  244. :scm_provider,
  245. klass,
  246. :kind_of => [ Class ]
  247. )
  248. end
  249. def svn_force_export(arg=nil)
  250. set_or_return(
  251. :svn_force_export,
  252. arg,
  253. :kind_of => [ TrueClass, FalseClass ]
  254. )
  255. end
  256. def environment(arg=nil)
  257. if arg.is_a?(String)
  258. Chef::Log.debug "Setting RAILS_ENV, RACK_ENV, and MERB_ENV to `#{arg}'"
  259. Chef::Log.warn "[DEPRECATED] please modify your deploy recipe or attributes to set the environment using a hash"
  260. arg = {"RAILS_ENV"=>arg,"MERB_ENV"=>arg,"RACK_ENV"=>arg}
  261. end
  262. set_or_return(
  263. :environment,
  264. arg,
  265. :kind_of => [ Hash ]
  266. )
  267. end
  268. # The number of old release directories to keep around after cleanup
  269. def keep_releases(arg=nil)
  270. [set_or_return(
  271. :keep_releases,
  272. arg,
  273. :kind_of => [ Integer ]), 1].max
  274. end
  275. # An array of paths, relative to your app's root, to be purged from a
  276. # SCM clone/checkout before symlinking. Use this to get rid of files and
  277. # directories you want to be shared between releases.
  278. # Default: ["log", "tmp/pids", "public/system"]
  279. def purge_before_symlink(arg=nil)
  280. set_or_return(
  281. :purge_before_symlink,
  282. arg,
  283. :kind_of => Array
  284. )
  285. end
  286. # An array of paths, relative to your app's root, where you expect dirs to
  287. # exist before symlinking. This runs after #purge_before_symlink, so you
  288. # can use this to recreate dirs that you had previously purged.
  289. # For example, if you plan to use a shared directory for pids, and you
  290. # want it to be located in $APP_ROOT/tmp/pids, you could purge tmp,
  291. # then specify tmp here so that the tmp directory will exist when you
  292. # symlink the pids directory in to the current release.
  293. # Default: ["tmp", "public", "config"]
  294. def create_dirs_before_symlink(arg=nil)
  295. set_or_return(
  296. :create_dirs_before_symlink,
  297. arg,
  298. :kind_of => Array
  299. )
  300. end
  301. # A Hash of shared/dir/path => release/dir/path. This attribute determines
  302. # which files and dirs in the shared directory get symlinked to the current
  303. # release directory, and where they go. If you have a directory
  304. # $shared/pids that you would like to symlink as $current_release/tmp/pids
  305. # you specify it as "pids" => "tmp/pids"
  306. # Default {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"}
  307. def symlinks(arg=nil)
  308. set_or_return(
  309. :symlinks,
  310. arg,
  311. :kind_of => Hash
  312. )
  313. end
  314. # A Hash of shared/dir/path => release/dir/path. This attribute determines
  315. # which files in the shared directory get symlinked to the current release
  316. # directory and where they go. Unlike map_shared_files, these are symlinked
  317. # *before* any migration is run.
  318. # For a rails/merb app, this is used to link in a known good database.yml
  319. # (with the production db password) before running migrate.
  320. # Default {"config/database.yml" => "config/database.yml"}
  321. def symlink_before_migrate(arg=nil)
  322. set_or_return(
  323. :symlink_before_migrate,
  324. arg,
  325. :kind_of => Hash
  326. )
  327. end
  328. # Callback fires before migration is run.
  329. def before_migrate(arg=nil, &block)
  330. arg ||= block
  331. set_or_return(:before_migrate, arg, :kind_of => [Proc, String])
  332. end
  333. # Callback fires before symlinking
  334. def before_symlink(arg=nil, &block)
  335. arg ||= block
  336. set_or_return(:before_symlink, arg, :kind_of => [Proc, String])
  337. end
  338. # Callback fires before restart
  339. def before_restart(arg=nil, &block)
  340. arg ||= block
  341. set_or_return(:before_restart, arg, :kind_of => [Proc, String])
  342. end
  343. # Callback fires after restart
  344. def after_restart(arg=nil, &block)
  345. arg ||= block
  346. set_or_return(:after_restart, arg, :kind_of => [Proc, String])
  347. end
  348. def additional_remotes(arg=nil)
  349. set_or_return(
  350. :additional_remotes,
  351. arg,
  352. :kind_of => Hash
  353. )
  354. end
  355. end
  356. end
  357. end