Guest User

Untitled

a guest
Mar 12th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.78 KB | None | 0 0
  1. ## Capfile
  2.  
  3. # Yes this is mostly copy/paste to get basic SCM/Stragegy extracted from
  4. # cap w/o standard deployment recipes for web services, etc.
  5.  
  6. require 'capistrano/recipes/deploy/scm'
  7. require 'capistrano/recipes/deploy/strategy'
  8. require 'yaml'
  9.  
  10.  
  11. def _cset(name, *args, &block)
  12. unless exists?(name)
  13. set(name, *args, &block)
  14. end
  15. end
  16.  
  17. # =========================================================================
  18. # These variables MUST be set in the client capfiles. If they are not set,
  19. # the deploy will fail with an error.
  20. # =========================================================================
  21.  
  22. _cset(:application) { abort "Please specify the name of your application, set :application, 'foo'" }
  23. _cset(:repository) { abort "Please specify the repository that houses your application's code, set :repository, 'foo'" }
  24.  
  25. # =========================================================================
  26. # These variables may be set in the client capfile if their default values
  27. # are not sufficient.
  28. # =========================================================================
  29.  
  30. _cset :scm, :subversion
  31. _cset :deploy_via, :checkout
  32.  
  33. _cset(:deploy_to) { "/u/apps/#{application}" }
  34. _cset(:revision) { source.head }
  35.  
  36. # =========================================================================
  37. # These variables should NOT be changed unless you are very confident in
  38. # what you are doing. Make sure you understand all the implications of your
  39. # changes if you do decide to muck with these!
  40. # =========================================================================
  41.  
  42. _cset(:source) { Capistrano::Deploy::SCM.new(scm, self) }
  43. _cset(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { `#{cmd}` } } }
  44.  
  45. _cset(:strategy) { Capistrano::Deploy::Strategy.new(deploy_via, self) }
  46.  
  47. _cset(:release_name) { set :deploy_timestamped, true; Time.now.utc.strftime("%Y%m%d%H%M%S") }
  48.  
  49. _cset :version_dir, "releases"
  50. _cset :shared_dir, "shared"
  51. _cset :current_dir, "current"
  52.  
  53. _cset(:releases_path) { File.join(deploy_to, version_dir) }
  54. _cset(:shared_path) { File.join(deploy_to, shared_dir) }
  55. _cset(:current_path) { File.join(deploy_to, current_dir) }
  56. _cset(:release_path) { File.join(releases_path, release_name) }
  57.  
  58. _cset(:releases) { capture("ls -x #{releases_path}").split.sort }
  59. _cset(:current_release) { File.join(releases_path, releases.last) }
  60. _cset(:previous_release) { File.join(releases_path, releases[-2]) }
  61.  
  62. _cset(:current_revision) { capture("cat #{current_path}/REVISION").chomp }
  63. _cset(:latest_revision) { capture("cat #{current_release}/REVISION").chomp }
  64. _cset(:previous_revision) { capture("cat #{previous_release}/REVISION").chomp }
  65.  
  66. _cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
  67.  
  68. # some tasks, like symlink, need to always point at the latest release, but
  69. # they can also (occassionally) be called standalone. In the standalone case,
  70. # the timestamped release_path will be inaccurate, since the directory won't
  71. # actually exist. This variable lets tasks like symlink work either in the
  72. # standalone case, or during deployment.
  73. _cset(:latest_release) { exists?(:deploy_timestamped) ? release_path : current_release }
  74.  
  75. # =========================================================================
  76. # These are helper methods that will be available to your recipes.
  77. # =========================================================================
  78.  
  79. # Auxiliary helper method for the `deploy:check' task. Lets you set up your
  80. # own dependencies.
  81. def depend(location, type, *args)
  82. deps = fetch(:dependencies, {})
  83. deps[location] ||= {}
  84. deps[location][type] ||= []
  85. deps[location][type] << args
  86. set :dependencies, deps
  87. end
  88.  
  89. # Temporarily sets an environment variable, yields to a block, and restores
  90. # the value when it is done.
  91. def with_env(name, value)
  92. saved, ENV[name] = ENV[name], value
  93. yield
  94. ensure
  95. ENV[name] = saved
  96. end
  97.  
  98. load 'config/deploy'
  99.  
  100.  
  101. ## config/deploy
  102. # Again this is a hacked up version of ONLY SCM/STRAGEY CAPISTRANO GOODNESS with custom deployment stuff.
  103. set :application, "aggregator"
  104. set :repository, "svn://your.site.com/aggregator/trunk"
  105. set :scm, :subversion
  106. set :deploy_via, :export
  107. set :deploy_to, "/var/lib/aggregator"
  108. set :shared_path, "#{deploy_to}/shared"
  109. set :current_path, "#{deploy_to}/current"
  110.  
  111. set :environment, "production"
  112.  
  113. set :user, "deploy"
  114. set :group, "deploy"
  115.  
  116. role :app, "your.aggregator.com"
  117.  
  118.  
  119. # = DEPLOYMENT TASKS ================================================================
  120. namespace :deploy do
  121.  
  122. desc 'Deploys latest (HEAD) version of the aggregator and restarts it cleanly'
  123. task :default do
  124. update
  125. end
  126.  
  127. desc <<-DESC
  128. Copies your project and updates the symlink. It does this in a \
  129. transaction, so that if either `update_code' or `symlink' fail, all \
  130. changes made to the remote servers will be rolled back, leaving your \
  131. system in the same state it was in before `update' was invoked. Usually, \
  132. you will want to call `deploy' instead of `update', but `update' can be \
  133. handy if you want to deploy, but not immediately restart your application.
  134. DESC
  135. task :update do
  136. transaction do
  137. update_code
  138. symlink
  139. end
  140. end
  141.  
  142. desc <<-DESC
  143. Copies your project to the remote servers. This is the first stage \
  144. of any deployment; moving your updated code and assets to the deployment \
  145. servers. You will rarely call this task directly, however; instead, you \
  146. should call the `deploy' task (to do a complete deploy) or the `update' \
  147. task (if you want to perform the `restart' task separately).
  148.  
  149. You will need to make sure you set the :scm variable to the source \
  150. control software you are using (it defaults to :subversion), and the \
  151. :deploy_via variable to the strategy you want to use to deploy (it \
  152. defaults to :checkout).
  153. DESC
  154. task :update_code, :except => { :no_release => true } do
  155. on_rollback { run "rm -rf #{release_path}; true" }
  156. strategy.deploy!
  157. finalize_update
  158. end
  159.  
  160. desc <<-DESC
  161. Copies your project to the remote servers. This is the first stage \
  162. of any deployment; moving your updated code and assets to the deployment \
  163. servers. You will rarely call this task directly, however; instead, you \
  164. should call the `deploy' task (to do a complete deploy) or the `update' \
  165. task (if you want to perform the `restart' task separately).
  166.  
  167. You will need to make sure you set the :scm variable to the source \
  168. control software you are using (it defaults to :subversion), and the \
  169. :deploy_via variable to the strategy you want to use to deploy (it \
  170. defaults to :checkout).
  171. DESC
  172. task :update_code, :except => { :no_release => true } do
  173. on_rollback { run "rm -rf #{release_path}; true" }
  174. strategy.deploy!
  175. finalize_update
  176. end
  177.  
  178. desc <<-DESC
  179. [internal] Touches up the released code. This is called by update_code \
  180. after the basic deploy finishes. It will then set up symlinks to the shared directories.
  181. DESC
  182. task :finalize_update, :except => { :no_release => true } do
  183. run <<-CMD
  184. rm -rf #{latest_release}/log #{latest_release}/tmp &&
  185. ln -s #{shared_path}/log #{latest_release}/log &&
  186. ln -s #{shared_path}/tmp #{latest_release}/tmp
  187. CMD
  188. end
  189.  
  190. desc <<-DESC
  191. Updates the symlink to the most recently deployed version. Capistrano works \
  192. by putting each new release of your application in its own directory. When \
  193. you deploy a new version, this task's job is to update the `current' symlink \
  194. to point at the new version. You will rarely need to call this task \
  195. directly; instead, use the `deploy' task (which performs a complete \
  196. deploy, including `restart') or the 'update' task (which does everything \
  197. except `restart').
  198. DESC
  199. task :symlink, :except => { :no_release => true } do
  200. on_rollback { run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true" }
  201. run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
  202. end
  203.  
  204. desc <<-DESC
  205. Rolls back to the previously deployed version. The `current' symlink will \
  206. be updated to point at the previously deployed version, and then the \
  207. current release will be removed from the servers. You'll generally want \
  208. to call `rollback' instead, as it performs a `restart' as well.
  209. DESC
  210. task :rollback_code, :except => { :no_release => true } do
  211. if releases.length < 2
  212. abort "could not rollback the code because there is no prior release"
  213. else
  214. run "rm #{current_path}; ln -s #{previous_release} #{current_path} && rm -rf #{current_release}"
  215. end
  216. end
  217.  
  218. desc <<-DESC
  219. Rolls back to a previous version and restarts. This is handy if you ever \
  220. discover that you've deployed a lemon; `cap rollback' and you're right \
  221. back where you were, on the previously deployed version.
  222. DESC
  223. task :rollback do
  224. rollback_code
  225. restart
  226. end
  227.  
  228. desc <<-DESC
  229. Clean up old releases. By default, the last 5 releases are kept on each \
  230. server (though you can change this with the keep_releases variable). All \
  231. other deployed revisions are removed from the servers. By default, this \
  232. will use sudo to clean up the old releases, but if sudo is not available \
  233. for your environment, set the :use_sudo variable to false instead.
  234. DESC
  235. task :cleanup, :except => { :no_release => true } do
  236. count = fetch(:keep_releases, 5).to_i
  237. if count >= releases.length
  238. logger.important "no old releases to clean up"
  239. else
  240. logger.info "keeping #{count} of #{releases.length} deployed releases"
  241.  
  242. directories = (releases - releases.last(count)).map { |release|
  243. File.join(releases_path, release) }.join(" ")
  244.  
  245. invoke_command "rm -rf #{directories}", :via => run_method
  246. end
  247. end
  248. end
  249.  
  250. # Some hooks to set things up properly after fresh deploy
  251. after 'deploy', 'config:localize'
  252. after 'deploy', 'aggregator:restart'
  253. after 'deploy', 'deploy:cleanup'
  254.  
  255.  
  256. # = VERSIONING SYSTEM TASKS ====================================================================
  257. namespace :pending do
  258. desc <<-DESC
  259. Displays the `diff' since your last deploy. This is useful if you want \
  260. to examine what changes are about to be deployed. Note that this might \
  261. not be supported on all SCM's.
  262. DESC
  263. task :diff, :except => { :no_release => true } do
  264. system(source.local.diff(current_revision))
  265. end
  266.  
  267. desc <<-DESC
  268. Displays the commits since your last deploy. This is good for a summary \
  269. of the changes that have occurred since the last deploy. Note that this \
  270. might not be supported on all SCM's.
  271. DESC
  272. task :default, :except => { :no_release => true } do
  273. from = source.next_revision(current_revision)
  274. system(source.local.log(from))
  275. end
  276. end
  277.  
  278. # = AGGREGATOR SPECIFIC TASKS ==================================================================
  279. namespace :aggregator do
  280. desc 'Stop running aggregator'
  281. task :stop do
  282. run "cd #{current_path} && APP_ENV=#{environment} ./script/schedule stop"
  283. end
  284.  
  285. desc 'Start aggregator'
  286. task :start do
  287. run "cd #{current_path} && APP_ENV=#{environment} ./script/schedule start"
  288. end
  289.  
  290. desc 'Restart aggregator'
  291. task :restart do
  292. stop
  293. start
  294. end
  295. end
  296.  
  297. # = INITAL SETUP TASKS =================================================================
  298. namespace :init do
  299. desc 'Create remote deployment structure'
  300. task :setup, :roles => [:app] do
  301. sudo "mkdir -p #{deploy_to}"
  302. sudo "chown #{user}:#{group} #{deploy_to}"
  303. run "mkdir -p #{shared_path}"
  304. ['tmp','log','config'].each do |path|
  305. run "mkdir -p #{shared_path}/#{path}"
  306. end
  307. run "mkdir -p #{deploy_to}/releases"
  308. end
  309. end
  310.  
  311. # = CONFIGURATION TASKS ================================================================
  312. namespace :config do
  313. desc "Create or update database configuration"
  314. task :database do
  315. set :db_host, Capistrano::CLI.ui.ask("database host: ")
  316. set :db_user, Capistrano::CLI.ui.ask("database user: ")
  317. set :db_pass, Capistrano::CLI.password_prompt("database password: ")
  318. database_configuration = <<-EOF
  319. production:
  320. adapter: mysql
  321. database: #{application}
  322. host: #{db_host}
  323. username: #{db_user}
  324. password: #{db_pass}
  325. EOF
  326. run "mkdir -p #{shared_path}/config"
  327. put database_configuration, "#{shared_path}/config/database.yml"
  328. end
  329.  
  330. desc "Symlink shared configurations to current release"
  331. task :localize, :roles => [:app] do
  332. %w[database.yml geokit.yml amazon_s3.yml schedule.yml].each do |f|
  333. run "ln -nsf #{shared_path}/config/#{f} #{current_path}/config/#{f}"
  334. end
  335. end
  336. end
Add Comment
Please, Sign In to add comment