amqp-daemon-kit 0.1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. data/.gitignore +5 -0
  2. data/Configuration.txt +110 -0
  3. data/Deployment.txt +113 -0
  4. data/History.txt +131 -0
  5. data/Logging.txt +96 -0
  6. data/PostInstall.txt +6 -0
  7. data/README.rdoc +132 -0
  8. data/Rakefile +29 -0
  9. data/RuoteParticipants.txt +113 -0
  10. data/TODO.txt +27 -0
  11. data/bin/daemon-kit +18 -0
  12. data/config/website.yml +2 -0
  13. data/daemon-kit.gemspec +265 -0
  14. data/lib/daemon_kit.rb +60 -0
  15. data/lib/daemon_kit/abstract_logger.rb +249 -0
  16. data/lib/daemon_kit/application.rb +230 -0
  17. data/lib/daemon_kit/arguments.rb +165 -0
  18. data/lib/daemon_kit/commands/console.rb +38 -0
  19. data/lib/daemon_kit/commands/destroy.rb +10 -0
  20. data/lib/daemon_kit/commands/generate.rb +10 -0
  21. data/lib/daemon_kit/config.rb +113 -0
  22. data/lib/daemon_kit/console_daemon.rb +2 -0
  23. data/lib/daemon_kit/core_ext.rb +1 -0
  24. data/lib/daemon_kit/core_ext/configurable.rb +96 -0
  25. data/lib/daemon_kit/core_ext/string.rb +22 -0
  26. data/lib/daemon_kit/cron.rb +67 -0
  27. data/lib/daemon_kit/cucumber/world.rb +38 -0
  28. data/lib/daemon_kit/deployment/capistrano.rb +516 -0
  29. data/lib/daemon_kit/dk_amqp.rb +39 -0
  30. data/lib/daemon_kit/em.rb +43 -0
  31. data/lib/daemon_kit/error_handlers/base.rb +32 -0
  32. data/lib/daemon_kit/error_handlers/hoptoad.rb +180 -0
  33. data/lib/daemon_kit/exceptions.rb +15 -0
  34. data/lib/daemon_kit/generators.rb +67 -0
  35. data/lib/daemon_kit/generators/base.rb +60 -0
  36. data/lib/daemon_kit/initializer.rb +449 -0
  37. data/lib/daemon_kit/jabber.rb +171 -0
  38. data/lib/daemon_kit/nanite.rb +7 -0
  39. data/lib/daemon_kit/nanite/agent.rb +77 -0
  40. data/lib/daemon_kit/pid_file.rb +61 -0
  41. data/lib/daemon_kit/ruote_participants.rb +125 -0
  42. data/lib/daemon_kit/ruote_pseudo_participant.rb +68 -0
  43. data/lib/daemon_kit/ruote_workitem.rb +187 -0
  44. data/lib/daemon_kit/safety.rb +84 -0
  45. data/lib/daemon_kit/tasks.rb +2 -0
  46. data/lib/daemon_kit/tasks/environment.rake +11 -0
  47. data/lib/daemon_kit/tasks/framework.rake +123 -0
  48. data/lib/daemon_kit/tasks/god.rake +62 -0
  49. data/lib/daemon_kit/tasks/log.rake +8 -0
  50. data/lib/daemon_kit/tasks/monit.rake +29 -0
  51. data/lib/daemon_kit/vendor/thor-0.13.6/CHANGELOG.rdoc +89 -0
  52. data/lib/daemon_kit/vendor/thor-0.13.6/LICENSE +20 -0
  53. data/lib/daemon_kit/vendor/thor-0.13.6/README.rdoc +297 -0
  54. data/lib/daemon_kit/vendor/thor-0.13.6/Thorfile +69 -0
  55. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor.rb +244 -0
  56. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions.rb +296 -0
  57. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/create_file.rb +103 -0
  58. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/directory.rb +91 -0
  59. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/empty_directory.rb +134 -0
  60. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/file_manipulation.rb +223 -0
  61. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/inject_into_file.rb +104 -0
  62. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/base.rb +540 -0
  63. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/core_ext/file_binary_read.rb +9 -0
  64. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  65. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/core_ext/ordered_hash.rb +100 -0
  66. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/error.rb +30 -0
  67. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/group.rb +271 -0
  68. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/invocation.rb +180 -0
  69. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser.rb +4 -0
  70. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/argument.rb +67 -0
  71. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/arguments.rb +150 -0
  72. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/option.rb +128 -0
  73. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/options.rb +169 -0
  74. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/rake_compat.rb +66 -0
  75. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/runner.rb +314 -0
  76. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/shell.rb +83 -0
  77. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/shell/basic.rb +239 -0
  78. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/shell/color.rb +108 -0
  79. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/task.rb +102 -0
  80. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/util.rb +224 -0
  81. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/version.rb +3 -0
  82. data/lib/daemon_kit/xmpp.rb +100 -0
  83. data/lib/generators/daemon_kit/amqp/USAGE +5 -0
  84. data/lib/generators/daemon_kit/amqp/amqp_generator.rb +24 -0
  85. data/lib/generators/daemon_kit/amqp/templates/config/amqp.yml +28 -0
  86. data/lib/generators/daemon_kit/amqp/templates/config/pre-daemonize/amqp.rb +7 -0
  87. data/lib/generators/daemon_kit/amqp/templates/libexec/%app_name%-daemon.rb +37 -0
  88. data/lib/generators/daemon_kit/app/USAGE +7 -0
  89. data/lib/generators/daemon_kit/app/app_generator.rb +140 -0
  90. data/lib/generators/daemon_kit/app/templates/Gemfile +12 -0
  91. data/lib/generators/daemon_kit/app/templates/README.tt +58 -0
  92. data/lib/generators/daemon_kit/app/templates/Rakefile +6 -0
  93. data/lib/generators/daemon_kit/app/templates/bin/daemon.tt +7 -0
  94. data/lib/generators/daemon_kit/app/templates/config/arguments.rb +12 -0
  95. data/lib/generators/daemon_kit/app/templates/config/boot.rb +70 -0
  96. data/lib/generators/daemon_kit/app/templates/config/environment.rb.tt +26 -0
  97. data/lib/generators/daemon_kit/app/templates/config/environments/development.rb +2 -0
  98. data/lib/generators/daemon_kit/app/templates/config/environments/production.rb +5 -0
  99. data/lib/generators/daemon_kit/app/templates/config/environments/test.rb +2 -0
  100. data/lib/generators/daemon_kit/app/templates/config/post-daemonize/readme +5 -0
  101. data/lib/generators/daemon_kit/app/templates/config/pre-daemonize/readme +12 -0
  102. data/lib/generators/daemon_kit/app/templates/lib/%app_name%.rb +2 -0
  103. data/lib/generators/daemon_kit/app/templates/libexec/%app_name%-daemon.rb +18 -0
  104. data/lib/generators/daemon_kit/app/templates/script/console +3 -0
  105. data/lib/generators/daemon_kit/app/templates/script/destroy +3 -0
  106. data/lib/generators/daemon_kit/app/templates/script/generate +3 -0
  107. data/lib/generators/daemon_kit/capistrano/capistrano_generator.rb +26 -0
  108. data/lib/generators/daemon_kit/capistrano/templates/Capfile +10 -0
  109. data/lib/generators/daemon_kit/capistrano/templates/USAGE +10 -0
  110. data/lib/generators/daemon_kit/capistrano/templates/config/deploy.rb.tt +67 -0
  111. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/logrotate.erb +13 -0
  112. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/production.rb.tt +6 -0
  113. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/staging.rb.tt +6 -0
  114. data/lib/generators/daemon_kit/capistrano/templates/config/environments/staging.rb +0 -0
  115. data/lib/generators/daemon_kit/cron/USAGE +5 -0
  116. data/lib/generators/daemon_kit/cron/cron_generator.rb +24 -0
  117. data/lib/generators/daemon_kit/cron/templates/config/pre-daemonize/cron.rb +11 -0
  118. data/lib/generators/daemon_kit/cron/templates/libexec/%app_name%-daemon.rb +48 -0
  119. data/lib/generators/daemon_kit/cucumber/USAGE +11 -0
  120. data/lib/generators/daemon_kit/cucumber/cucumber_generator.rb +45 -0
  121. data/lib/generators/daemon_kit/cucumber/templates/config/environments/cucumber.rb +2 -0
  122. data/lib/generators/daemon_kit/cucumber/templates/features/step_definitions/.empty_directory +0 -0
  123. data/lib/generators/daemon_kit/cucumber/templates/features/support/env.rb +7 -0
  124. data/lib/generators/daemon_kit/cucumber/templates/script/cucumber +7 -0
  125. data/lib/generators/daemon_kit/cucumber/templates/tasks/cucumber.rake +13 -0
  126. data/lib/generators/daemon_kit/nanite_agent/USAGE +5 -0
  127. data/lib/generators/daemon_kit/nanite_agent/nanite_agent_generator.rb +29 -0
  128. data/lib/generators/daemon_kit/nanite_agent/templates/config/nanite.yml +35 -0
  129. data/lib/generators/daemon_kit/nanite_agent/templates/config/pre-daemonize/nanite_agent.rb +6 -0
  130. data/lib/generators/daemon_kit/nanite_agent/templates/lib/actors/sample.rb +11 -0
  131. data/lib/generators/daemon_kit/nanite_agent/templates/libexec/%app_name%-daemon.rb +31 -0
  132. data/lib/generators/daemon_kit/rspec/USAGE +5 -0
  133. data/lib/generators/daemon_kit/rspec/rspec_generator.rb +20 -0
  134. data/lib/generators/daemon_kit/rspec/templates/spec/%app_name%_spec.rb +11 -0
  135. data/lib/generators/daemon_kit/rspec/templates/spec/spec.opts +1 -0
  136. data/lib/generators/daemon_kit/rspec/templates/spec/spec_helper.rb +23 -0
  137. data/lib/generators/daemon_kit/rspec/templates/tasks/rspec.rake +21 -0
  138. data/lib/generators/daemon_kit/ruote/USAGE +5 -0
  139. data/lib/generators/daemon_kit/ruote/ruote_generator.rb +29 -0
  140. data/lib/generators/daemon_kit/ruote/templates/config/amqp.yml +30 -0
  141. data/lib/generators/daemon_kit/ruote/templates/config/pre-daemonize/ruote.rb +13 -0
  142. data/lib/generators/daemon_kit/ruote/templates/config/ruote.yml +23 -0
  143. data/lib/generators/daemon_kit/ruote/templates/lib/%app_name%.rb +4 -0
  144. data/lib/generators/daemon_kit/ruote/templates/lib/sample.rb +26 -0
  145. data/lib/generators/daemon_kit/ruote/templates/libexec/%app_name%-daemon.rb +33 -0
  146. data/lib/generators/daemon_kit/test_unit/USAGE +5 -0
  147. data/lib/generators/daemon_kit/test_unit/templates/tasks/test_unit.rake +7 -0
  148. data/lib/generators/daemon_kit/test_unit/templates/test/%app_name%_test.rb.tt +9 -0
  149. data/lib/generators/daemon_kit/test_unit/templates/test/test_helper.rb +6 -0
  150. data/lib/generators/daemon_kit/test_unit/test_unit_generator.rb +20 -0
  151. data/lib/generators/daemon_kit/xmpp/templates/config/pre-daemonize/xmpp.rb +6 -0
  152. data/lib/generators/daemon_kit/xmpp/templates/config/xmpp.yml +29 -0
  153. data/lib/generators/daemon_kit/xmpp/templates/libexec/%app_name%-daemon.rb +27 -0
  154. data/lib/generators/daemon_kit/xmpp/xmpp_generator.rb +24 -0
  155. data/script/console +10 -0
  156. data/script/destroy +14 -0
  157. data/script/generate +14 -0
  158. data/script/txt2html +71 -0
  159. data/spec/abstract_logger_spec.rb +126 -0
  160. data/spec/argument_spec.rb +70 -0
  161. data/spec/config_spec.rb +83 -0
  162. data/spec/configurable_spec.rb +56 -0
  163. data/spec/daemon_kit_spec.rb +7 -0
  164. data/spec/error_handlers_spec.rb +23 -0
  165. data/spec/fixtures/env.yml +15 -0
  166. data/spec/fixtures/noenv.yml +4 -0
  167. data/spec/initializer_spec.rb +26 -0
  168. data/spec/spec.opts +1 -0
  169. data/spec/spec_helper.rb +27 -0
  170. data/tasks/cucumber.rake +13 -0
  171. data/tasks/rspec.rake +20 -0
  172. data/tasks/tests.rake +6 -0
  173. data/templates/god/god.erb +69 -0
  174. data/templates/monit/monit.erb +14 -0
  175. data/test/test_amqp_generator.rb +48 -0
  176. data/test/test_cron_generator.rb +45 -0
  177. data/test/test_daemon-kit_generator.rb +84 -0
  178. data/test/test_daemon_kit_config.rb +28 -0
  179. data/test/test_deploy_capistrano_generator.rb +48 -0
  180. data/test/test_generator_helper.rb +29 -0
  181. data/test/test_helper.rb +7 -0
  182. data/test/test_nanite_agent_generator.rb +49 -0
  183. data/test/test_ruote_generator.rb +51 -0
  184. data/test/test_test_unit_generator.rb +46 -0
  185. metadata +302 -0
@@ -0,0 +1,67 @@
1
+ module DaemonKit
2
+
3
+ # Thin wrapper around rufus-scheduler gem, specifically designed to ease
4
+ # configuration of a scheduler and provide some added simplicity. It also
5
+ # logs any exceptions that occur inside the scheduled blocks, ensuring your
6
+ # code isn't running blind.
7
+ #
8
+ # For more information on rufus-scheduler, please visit the RDoc's
9
+ # at http://rufus.rubyforge.org/rufus-scheduler/
10
+ #
11
+ # To use the evented scheduler, call #DaemonKit::EM.run prior to
12
+ # setting up your first schedule.
13
+ class Cron
14
+
15
+ @instance = nil
16
+ @exception_handler = nil
17
+
18
+ attr_reader :scheduler
19
+ attr_accessor :exception_handler
20
+
21
+ class << self
22
+
23
+ def instance
24
+ @instance ||= new
25
+ end
26
+
27
+ # Access to the scheduler instance
28
+ def scheduler
29
+ instance.scheduler
30
+ end
31
+
32
+ # Define a block for receiving exceptions from inside the scheduler
33
+ def handle_exception( &block )
34
+ instance.exception_handler = block
35
+ end
36
+
37
+ private :new
38
+
39
+ # Once the scheduler has been configured, call #run to block the
40
+ # current thread and keep the process alive for the scheduled
41
+ # tasks to run
42
+ def run
43
+ DaemonKit.logger.info "Starting rufus-scheduler"
44
+
45
+ if instance.is_a?( Rufus::Scheduler::PlainScheduler )
46
+ instance.scheduler.join
47
+ else
48
+ Thread.stop
49
+ end
50
+ end
51
+ end
52
+
53
+ def initialize
54
+ @scheduler = Rufus::Scheduler.start_new
55
+
56
+ def @scheduler.handle_exception( job, exception )
57
+ DaemonKit::Cron.instance.handle_exception( job, exception )
58
+ end
59
+ end
60
+
61
+ def handle_exception( job, exception )
62
+ DaemonKit.logger.error( "Cron: job #{job.job_id} caught exception: '#{exception}'" )
63
+ DaemonKit.logger.exception( exception )
64
+ @exception_handler.call( job, exception ) unless @exception_handler.nil?
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Based on code from Brian Takita, Yurii Rashkovskii, Ben Mabey and Aslak Hellesøy
3
+ # Adapted by Kenneth Kalmer for daemon-kit
4
+
5
+ begin
6
+ require 'test/unit/testresult'
7
+ rescue LoadError => e
8
+ e.message << "\nYou must gem install test-unit. For more info see https://rspec.lighthouseapp.com/projects/16211/tickets/292"
9
+ raise e
10
+ end
11
+
12
+ # So that Test::Unit doesn't launch at the end - makes it think it has already been run.
13
+ Test::Unit.run = true if Test::Unit.respond_to?(:run=)
14
+
15
+ $__cucumber_toplevel = self
16
+
17
+ module DaemonKit
18
+ module Cucumber
19
+ # All scenarios will execute in the context of a new instance of World.
20
+ class World
21
+ def initialize #:nodoc:
22
+ @_result = Test::Unit::TestResult.new
23
+ end
24
+ end
25
+
26
+ $__cucumber_toplevel.Before do
27
+ # Placeholder
28
+ end
29
+
30
+ $__cucumber_toplevel.After do
31
+ # Placeholder
32
+ end
33
+ end
34
+ end
35
+
36
+ World do
37
+ DaemonKit::Cucumber::World.new
38
+ end
@@ -0,0 +1,516 @@
1
+ require 'yaml'
2
+ require 'capistrano/recipes/deploy/scm'
3
+ require 'capistrano/recipes/deploy/strategy'
4
+
5
+ def _cset(name, *args, &block)
6
+ unless exists?(name)
7
+ set(name, *args, &block)
8
+ end
9
+ end
10
+
11
+ # =========================================================================
12
+ # These variables MUST be set in the client capfiles. If they are not set,
13
+ # the deploy will fail with an error.
14
+ # =========================================================================
15
+
16
+ _cset(:application) { abort "Please specify the name of your application, set :application, 'foo'" }
17
+ _cset(:repository) { abort "Please specify the repository that houses your application's code, set :repository, 'foo'" }
18
+
19
+ # =========================================================================
20
+ # These variables may be set in the client capfile if their default values
21
+ # are not sufficient.
22
+ # =========================================================================
23
+
24
+ _cset :scm, :subversion
25
+ _cset :deploy_via, :checkout
26
+
27
+ _cset(:deploy_to) { "/u/apps/#{application}" }
28
+ _cset(:revision) { source.head }
29
+
30
+ # =========================================================================
31
+ # These variables should NOT be changed unless you are very confident in
32
+ # what you are doing. Make sure you understand all the implications of your
33
+ # changes if you do decide to muck with these!
34
+ # =========================================================================
35
+
36
+ _cset(:source) { Capistrano::Deploy::SCM.new(scm, self) }
37
+ _cset(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }
38
+
39
+ _cset(:strategy) { Capistrano::Deploy::Strategy.new(deploy_via, self) }
40
+
41
+ _cset(:release_name) { set :deploy_timestamped, true; Time.now.utc.strftime("%Y%m%d%H%M%S") }
42
+
43
+ _cset :version_dir, "releases"
44
+ _cset :shared_dir, "shared"
45
+ _cset :shared_children, %w(log tmp)
46
+ _cset :current_dir, "current"
47
+
48
+ _cset(:releases_path) { File.join(deploy_to, version_dir) }
49
+ _cset(:shared_path) { File.join(deploy_to, shared_dir) }
50
+ _cset(:current_path) { File.join(deploy_to, current_dir) }
51
+ _cset(:release_path) { File.join(releases_path, release_name) }
52
+
53
+ _cset(:releases) { capture("ls -xt #{releases_path}").split.reverse }
54
+ _cset(:current_release) { File.join(releases_path, releases.last) }
55
+ _cset(:previous_release) { releases.length > 1 ? File.join(releases_path, releases[-2]) : nil }
56
+
57
+ _cset(:current_revision) { capture("cat #{current_path}/REVISION").chomp }
58
+ _cset(:latest_revision) { capture("cat #{current_release}/REVISION").chomp }
59
+ _cset(:previous_revision) { capture("cat #{previous_release}/REVISION").chomp }
60
+
61
+ _cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
62
+
63
+ # some tasks, like symlink, need to always point at the latest release, but
64
+ # they can also (occassionally) be called standalone. In the standalone case,
65
+ # the timestamped release_path will be inaccurate, since the directory won't
66
+ # actually exist. This variable lets tasks like symlink work either in the
67
+ # standalone case, or during deployment.
68
+ _cset(:latest_release) { exists?(:deploy_timestamped) ? release_path : current_release }
69
+
70
+ # =========================================================================
71
+ # Variables for bundler
72
+ # =========================================================================
73
+ _cset(:use_bundler, true)
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
+ # logs the command then executes it locally.
99
+ # returns the command output as a string
100
+ def run_locally(cmd)
101
+ logger.trace "executing locally: #{cmd.inspect}" if logger
102
+ `#{cmd}`
103
+ end
104
+
105
+ # If a command is given, this will try to execute the given command, as
106
+ # described below. Otherwise, it will return a string for use in embedding in
107
+ # another command, for executing that command as described below.
108
+ #
109
+ # If :run_method is :sudo (or :use_sudo is true), this executes the given command
110
+ # via +sudo+. Otherwise is uses +run+. If :as is given as a key, it will be
111
+ # passed as the user to sudo as, if using sudo. If the :as key is not given,
112
+ # it will default to whatever the value of the :admin_runner variable is,
113
+ # which (by default) is unset.
114
+ #
115
+ # THUS, if you want to try to run something via sudo, and what to use the
116
+ # root user, you'd just to try_sudo('something'). If you wanted to try_sudo as
117
+ # someone else, you'd just do try_sudo('something', :as => "bob"). If you
118
+ # always wanted sudo to run as a particular user, you could do
119
+ # set(:admin_runner, "bob").
120
+ def try_sudo(*args)
121
+ options = args.last.is_a?(Hash) ? args.pop : {}
122
+ command = args.shift
123
+ raise ArgumentError, "too many arguments" if args.any?
124
+
125
+ as = options.fetch(:as, fetch(:admin_runner, nil))
126
+ via = fetch(:run_method, :sudo)
127
+ if command
128
+ invoke_command(command, :via => via, :as => as)
129
+ elsif via == :sudo
130
+ sudo(:as => as)
131
+ else
132
+ ""
133
+ end
134
+ end
135
+
136
+ # Same as sudo, but tries sudo with :as set to the value of the :runner
137
+ # variable (which defaults to "app").
138
+ def try_runner(*args)
139
+ options = args.last.is_a?(Hash) ? args.pop : {}
140
+ args << options.merge(:as => fetch(:runner, "app"))
141
+ try_sudo(*args)
142
+ end
143
+
144
+ # =========================================================================
145
+ # These are the tasks that are available to help with deploying web apps,
146
+ # and specifically, Rails applications. You can have cap give you a summary
147
+ # of them with `cap -T'.
148
+ # =========================================================================
149
+
150
+ namespace :deploy do
151
+ desc <<-DESC
152
+ Deploys your project. This calls both `update' and `restart'. Note that \
153
+ this will generally only work for applications that have already been deployed \
154
+ once. For a "cold" deploy, you'll want to take a look at the `deploy:cold' \
155
+ task, which handles the cold start specifically.
156
+ DESC
157
+ task :default do
158
+ update
159
+ restart
160
+ end
161
+
162
+ desc <<-DESC
163
+ Prepares one or more servers for deployment. Before you can use any \
164
+ of the Capistrano deployment tasks with your project, you will need to \
165
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
166
+ you add a new server to your cluster, you can easily run the setup task \
167
+ on just that server by specifying the HOSTS environment variable:
168
+
169
+ $ cap HOSTS=new.server.com deploy:setup
170
+
171
+ It is safe to run this task on servers that have already been set up; it \
172
+ will not destroy any deployed revisions or data.
173
+ DESC
174
+ task :setup, :except => { :no_release => true } do
175
+ dirs = [deploy_to, releases_path, shared_path]
176
+ dirs += shared_children.map { |d| File.join(shared_path, d) }
177
+ run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
178
+ end
179
+
180
+ desc <<-DESC
181
+ Copies your project and updates the symlink. It does this in a \
182
+ transaction, so that if either `update_code' or `symlink' fail, all \
183
+ changes made to the remote servers will be rolled back, leaving your \
184
+ system in the same state it was in before `update' was invoked. Usually, \
185
+ you will want to call `deploy' instead of `update', but `update' can be \
186
+ handy if you want to deploy, but not immediately restart your application.
187
+ DESC
188
+ task :update do
189
+ transaction do
190
+ update_code
191
+ symlink
192
+ end
193
+ end
194
+
195
+ desc <<-DESC
196
+ Copies your project to the remote servers. This is the first stage \
197
+ of any deployment; moving your updated code and assets to the deployment \
198
+ servers. You will rarely call this task directly, however; instead, you \
199
+ should call the `deploy' task (to do a complete deploy) or the `update' \
200
+ task (if you want to perform the `restart' task separately).
201
+
202
+ You will need to make sure you set the :scm variable to the source \
203
+ control software you are using (it defaults to :subversion), and the \
204
+ :deploy_via variable to the strategy you want to use to deploy (it \
205
+ defaults to :checkout).
206
+
207
+ Your bundles will also be installed/updated as part of this step. \
208
+ You can disable bundler on remote reployments with the :user_bundler \
209
+ variable.
210
+ DESC
211
+ task :update_code, :except => { :no_release => true } do
212
+ on_rollback { run "rm -rf #{release_path}; true" }
213
+ strategy.deploy!
214
+ finalize_update
215
+ bundler.bundle_new_release if fetch(:use_bundler, true)
216
+ end
217
+
218
+ desc <<-DESC
219
+ [internal] Touches up the released code. This is called by update_code \
220
+ after the basic deploy finishes. It assumes a Rails project was deployed, \
221
+ so if you are deploying something else, you may want to override this \
222
+ task with your own environment's requirements.
223
+
224
+ This task will make the release group-writable (if the :group_writable \
225
+ variable is set to true, which is the default). It will then set up \
226
+ symlinks to the shared directory for the :shared_children \
227
+ directories, and will lastly touch all assets in public/images, \
228
+ public/stylesheets, and public/javascripts so that the times are \
229
+ consistent (so that asset timestamping works). This touch process \
230
+ is only carried out if the :normalize_asset_timestamps variable is \
231
+ set to true, which is the default.
232
+ DESC
233
+ task :finalize_update, :except => { :no_release => true } do
234
+ run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
235
+
236
+ # mkdir -p is making sure that the directories are there for some SCM's that don't
237
+ # save empty folders
238
+ dirs = fetch(:shared_children, [])
239
+ cmd = dirs.inject([]) do |c,d|
240
+ c.push "rm -rf #{latest_release}/#{d}"
241
+ c.push "ln -s #{shared_path}/#{d} #{latest_release}/#{d}"
242
+ c
243
+ end
244
+
245
+ run cmd.join( ' && ' )
246
+
247
+ if fetch(:normalize_asset_timestamps, false)
248
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
249
+ asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
250
+ run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
251
+ end
252
+
253
+ copy_configs
254
+ end
255
+
256
+ desc <<-DESC
257
+ Copies any shared configuration files from :deploy_to/config into \
258
+ the current release's config directory. Original files, if present, \
259
+ are renamed to the same name with .orig appended.
260
+
261
+ Specify a list of files by setting :config_files to an array in your \
262
+ deployment configuration.
263
+ DESC
264
+ task :copy_configs do
265
+ fetch(:config_files, []).each do |f|
266
+ run "[ -f #{release_path}/config/#{f} ]; mv #{release_path}/config/#{f} #{release_path}/config/#{f}.orig"
267
+ run "[ -f #{deploy_to}/config/#{f} ]; cp #{deploy_to}/config/#{f} #{release_path}/config/#{f}"
268
+ end
269
+ end
270
+
271
+ desc <<-DESC
272
+ Updates the symlink to the most recently deployed version. Capistrano works \
273
+ by putting each new release of your application in its own directory. When \
274
+ you deploy a new version, this task's job is to update the `current' symlink \
275
+ to point at the new version. You will rarely need to call this task \
276
+ directly; instead, use the `deploy' task (which performs a complete \
277
+ deploy, including `restart') or the 'update' task (which does everything \
278
+ except `restart').
279
+ DESC
280
+ task :symlink, :except => { :no_release => true } do
281
+ on_rollback do
282
+ if previous_release
283
+ run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true"
284
+ else
285
+ logger.important "no previous release to rollback to, rollback of symlink skipped"
286
+ end
287
+ end
288
+
289
+ run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
290
+ end
291
+
292
+ desc <<-DESC
293
+ Copy files to the currently deployed version. This is useful for updating \
294
+ files piecemeal, such as when you need to quickly deploy only a single \
295
+ file. Some files, such as updated templates, images, or stylesheets, \
296
+ might not require a full deploy, and especially in emergency situations \
297
+ it can be handy to just push the updates to production, quickly.
298
+
299
+ To use this task, specify the files and directories you want to copy as a \
300
+ comma-delimited list in the FILES environment variable. All directories \
301
+ will be processed recursively, with all files being pushed to the \
302
+ deployment servers.
303
+
304
+ $ cap deploy:upload FILES=templates,controller.rb
305
+
306
+ Dir globs are also supported:
307
+
308
+ $ cap deploy:upload FILES='config/apache/*.conf'
309
+ DESC
310
+ task :upload, :except => { :no_release => true } do
311
+ files = (ENV["FILES"] || "").split(",").map { |f| Dir[f.strip] }.flatten
312
+ abort "Please specify at least one file or directory to update (via the FILES environment variable)" if files.empty?
313
+
314
+ files.each { |file| top.upload(file, File.join(current_path, file)) }
315
+ end
316
+
317
+ desc <<-DESC
318
+ Restarts your application. This works by calling 'stop' task, \
319
+ followed by the 'start' task.
320
+
321
+ See the descriptions for the 'start' and 'stop' tasks for any \
322
+ additional info.
323
+ DESC
324
+ task :restart, :except => { :no_release => true } do
325
+ stop
326
+ start
327
+ end
328
+
329
+ namespace :rollback do
330
+ desc <<-DESC
331
+ [internal] Points the current symlink at the previous revision.
332
+ This is called by the rollback sequence, and should rarely (if
333
+ ever) need to be called directly.
334
+ DESC
335
+ task :revision, :except => { :no_release => true } do
336
+ if previous_release
337
+ run "rm #{current_path}; ln -s #{previous_release} #{current_path}"
338
+ else
339
+ abort "could not rollback the code because there is no prior release"
340
+ end
341
+ end
342
+
343
+ desc <<-DESC
344
+ [internal] Removes the most recently deployed release.
345
+ This is called by the rollback sequence, and should rarely
346
+ (if ever) need to be called directly.
347
+ DESC
348
+ task :cleanup, :except => { :no_release => true } do
349
+ run "if [ `readlink #{current_path}` != #{current_release} ]; then rm -rf #{current_release}; fi"
350
+ end
351
+
352
+ desc <<-DESC
353
+ Rolls back to the previously deployed version. The `current' symlink will \
354
+ be updated to point at the previously deployed version, and then the \
355
+ current release will be removed from the servers. You'll generally want \
356
+ to call `rollback' instead, as it performs a `restart' as well.
357
+ DESC
358
+ task :code, :except => { :no_release => true } do
359
+ revision
360
+ cleanup
361
+ end
362
+
363
+ desc <<-DESC
364
+ Rolls back to a previous version and restarts. This is handy if you ever \
365
+ discover that you've deployed a lemon; `cap rollback' and you're right \
366
+ back where you were, on the previously deployed version.
367
+ DESC
368
+ task :default do
369
+ revision
370
+ restart
371
+ cleanup
372
+ end
373
+ end
374
+
375
+ desc <<-DESC
376
+ Clean up old releases. By default, the last 5 releases are kept on each \
377
+ server (though you can change this with the keep_releases variable). All \
378
+ other deployed revisions are removed from the servers. By default, this \
379
+ will use sudo to clean up the old releases, but if sudo is not available \
380
+ for your environment, set the :use_sudo variable to false instead.
381
+ DESC
382
+ task :cleanup, :except => { :no_release => true } do
383
+ count = fetch(:keep_releases, 5).to_i
384
+ if count >= releases.length
385
+ logger.important "no old releases to clean up"
386
+ else
387
+ logger.info "keeping #{count} of #{releases.length} deployed releases"
388
+
389
+ directories = (releases - releases.last(count)).map { |release|
390
+ File.join(releases_path, release) }.join(" ")
391
+
392
+ try_sudo "rm -rf #{directories}"
393
+ end
394
+ end
395
+
396
+ desc <<-DESC
397
+ Test deployment dependencies. Checks things like directory permissions, \
398
+ necessary utilities, and so forth, reporting on the things that appear to \
399
+ be incorrect or missing. This is good for making sure a deploy has a \
400
+ chance of working before you actually run `cap deploy'.
401
+
402
+ You can define your own dependencies, as well, using the `depend' method:
403
+
404
+ depend :remote, :gem, "tzinfo", ">=0.3.3"
405
+ depend :local, :command, "svn"
406
+ depend :remote, :directory, "/u/depot/files"
407
+ DESC
408
+ task :check, :except => { :no_release => true } do
409
+ dependencies = strategy.check!
410
+
411
+ depend( :remote, :gem, "bundler", ">= 0.9.26" ) if fetch(:use_bundler, true)
412
+
413
+ other = fetch(:dependencies, {})
414
+ other.each do |location, types|
415
+ types.each do |type, calls|
416
+ if type == :gem
417
+ dependencies.send(location).command(fetch(:gem_command, "gem")).or("`gem' command could not be found. Try setting :gem_command")
418
+ end
419
+
420
+ calls.each do |args|
421
+ dependencies.send(location).send(type, *args)
422
+ end
423
+ end
424
+ end
425
+
426
+ if dependencies.pass?
427
+ puts "You appear to have all necessary dependencies installed"
428
+ else
429
+ puts "The following dependencies failed. Please check them and try again:"
430
+ dependencies.reject { |d| d.pass? }.each do |d|
431
+ puts "--> #{d.message}"
432
+ end
433
+ abort
434
+ end
435
+ end
436
+
437
+ desc <<-DESC
438
+ Deploys and starts a `cold' application. This is useful if you have not \
439
+ deployed your application before, or if your application is (for some \
440
+ other reason) not currently running. It will deploy the code, and then \
441
+ instead of invoking `deploy:restart', it will invoke `deploy:start' to \
442
+ fire up the application servers.
443
+ DESC
444
+ task :cold do
445
+ update
446
+ start
447
+ end
448
+
449
+ desc <<-DESC
450
+ Start the daemon processes. This will attempt to invoke a script \
451
+ in your application called `bin/:application', with the 'start' parameter.
452
+
453
+ By default, the script will be executed via sudo as the `app' user. If \
454
+ you wish to run it as a different user, set the :runner variable to \
455
+ that user. If you are in an environment where you can't use sudo, set \
456
+ the :use_sudo variable to false.
457
+ DESC
458
+ task :start do
459
+ try_runner "/usr/bin/env DAEMON_ENV=#{fetch(:daemon_env)} #{current_path}/bin/#{application} start"
460
+ end
461
+
462
+ desc <<-DESC
463
+ Stop the daemon processes. This will call 'bin/:application stop'.
464
+
465
+ By default, the script will be executed via sudo as the `app' user. If \
466
+ you wish to run it as a different user, set the :runner variable to \
467
+ that user. If you are in an environment where you can't use sudo, set \
468
+ the :use_sudo variable to false.
469
+ DESC
470
+ task :stop do
471
+ try_runner "/usr/bin/env DAEMON_ENV=#{fetch(:daemon_env)} #{current_path}/bin/#{application} stop"
472
+ end
473
+
474
+ namespace :pending do
475
+ desc <<-DESC
476
+ Displays the `diff' since your last deploy. This is useful if you want \
477
+ to examine what changes are about to be deployed. Note that this might \
478
+ not be supported on all SCM's.
479
+ DESC
480
+ task :diff, :except => { :no_release => true } do
481
+ system(source.local.diff(current_revision))
482
+ end
483
+
484
+ desc <<-DESC
485
+ Displays the commits since your last deploy. This is good for a summary \
486
+ of the changes that have occurred since the last deploy. Note that this \
487
+ might not be supported on all SCM's.
488
+ DESC
489
+ task :default, :except => { :no_release => true } do
490
+ from = source.next_revision(current_revision)
491
+ system(source.local.log(from))
492
+ end
493
+ end
494
+ end
495
+
496
+ namespace :bundler do
497
+ task :create_symlink, :roles => :app do
498
+ shared_dir = File.join(shared_path, 'bundle')
499
+ release_dir = File.join(current_release, '.bundle')
500
+ run("mkdir -p #{shared_dir} && ln -s #{shared_dir} #{release_dir}")
501
+ end
502
+
503
+ task :bundle_new_release, :roles => :app do
504
+ bundler.create_symlink
505
+ run "cd #{release_path} && bundle install .bundle --without test"
506
+ end
507
+
508
+ task :lock, :roles => :app do
509
+ run "cd #{current_release} && bundle lock;"
510
+ end
511
+
512
+ task :unlock, :roles => :app do
513
+ run "cd #{current_release} && bundle unlock;"
514
+ end
515
+ end
516
+