capistrano 1.4.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/CHANGELOG +140 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README +22 -14
  4. data/bin/cap +1 -8
  5. data/bin/capify +77 -0
  6. data/examples/sample.rb +10 -109
  7. data/lib/capistrano.rb +1 -0
  8. data/lib/capistrano/callback.rb +41 -0
  9. data/lib/capistrano/cli.rb +17 -317
  10. data/lib/capistrano/cli/execute.rb +82 -0
  11. data/lib/capistrano/cli/help.rb +102 -0
  12. data/lib/capistrano/cli/help.txt +53 -0
  13. data/lib/capistrano/cli/options.rb +183 -0
  14. data/lib/capistrano/cli/ui.rb +28 -0
  15. data/lib/capistrano/command.rb +62 -29
  16. data/lib/capistrano/configuration.rb +25 -226
  17. data/lib/capistrano/configuration/actions/file_transfer.rb +35 -0
  18. data/lib/capistrano/configuration/actions/inspect.rb +46 -0
  19. data/lib/capistrano/configuration/actions/invocation.rb +127 -0
  20. data/lib/capistrano/configuration/callbacks.rb +148 -0
  21. data/lib/capistrano/configuration/connections.rb +159 -0
  22. data/lib/capistrano/configuration/execution.rb +126 -0
  23. data/lib/capistrano/configuration/loading.rb +112 -0
  24. data/lib/capistrano/configuration/namespaces.rb +190 -0
  25. data/lib/capistrano/configuration/roles.rb +51 -0
  26. data/lib/capistrano/configuration/servers.rb +75 -0
  27. data/lib/capistrano/configuration/variables.rb +127 -0
  28. data/lib/capistrano/errors.rb +15 -0
  29. data/lib/capistrano/extensions.rb +27 -8
  30. data/lib/capistrano/gateway.rb +54 -29
  31. data/lib/capistrano/logger.rb +11 -11
  32. data/lib/capistrano/recipes/compat.rb +32 -0
  33. data/lib/capistrano/recipes/deploy.rb +483 -0
  34. data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
  35. data/lib/capistrano/recipes/deploy/local_dependency.rb +46 -0
  36. data/lib/capistrano/recipes/deploy/remote_dependency.rb +65 -0
  37. data/lib/capistrano/recipes/deploy/scm.rb +19 -0
  38. data/lib/capistrano/recipes/deploy/scm/base.rb +180 -0
  39. data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
  40. data/lib/capistrano/recipes/deploy/scm/cvs.rb +151 -0
  41. data/lib/capistrano/recipes/deploy/scm/darcs.rb +85 -0
  42. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +129 -0
  43. data/lib/capistrano/recipes/deploy/scm/perforce.rb +126 -0
  44. data/lib/capistrano/recipes/deploy/scm/subversion.rb +103 -0
  45. data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
  46. data/lib/capistrano/recipes/deploy/strategy/base.rb +64 -0
  47. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
  48. data/lib/capistrano/recipes/deploy/strategy/copy.rb +143 -0
  49. data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
  50. data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
  51. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +47 -0
  52. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +53 -0
  53. data/lib/capistrano/recipes/standard.rb +26 -276
  54. data/lib/capistrano/recipes/templates/maintenance.rhtml +1 -1
  55. data/lib/capistrano/recipes/upgrade.rb +33 -0
  56. data/lib/capistrano/server_definition.rb +51 -0
  57. data/lib/capistrano/shell.rb +125 -81
  58. data/lib/capistrano/ssh.rb +80 -36
  59. data/lib/capistrano/task_definition.rb +69 -0
  60. data/lib/capistrano/upload.rb +146 -0
  61. data/lib/capistrano/version.rb +13 -17
  62. data/test/cli/execute_test.rb +132 -0
  63. data/test/cli/help_test.rb +139 -0
  64. data/test/cli/options_test.rb +226 -0
  65. data/test/cli/ui_test.rb +28 -0
  66. data/test/cli_test.rb +17 -0
  67. data/test/command_test.rb +284 -25
  68. data/test/configuration/actions/file_transfer_test.rb +40 -0
  69. data/test/configuration/actions/inspect_test.rb +62 -0
  70. data/test/configuration/actions/invocation_test.rb +195 -0
  71. data/test/configuration/callbacks_test.rb +206 -0
  72. data/test/configuration/connections_test.rb +288 -0
  73. data/test/configuration/execution_test.rb +159 -0
  74. data/test/configuration/loading_test.rb +119 -0
  75. data/test/configuration/namespace_dsl_test.rb +283 -0
  76. data/test/configuration/roles_test.rb +47 -0
  77. data/test/configuration/servers_test.rb +90 -0
  78. data/test/configuration/variables_test.rb +180 -0
  79. data/test/configuration_test.rb +60 -212
  80. data/test/deploy/scm/base_test.rb +55 -0
  81. data/test/deploy/strategy/copy_test.rb +146 -0
  82. data/test/extensions_test.rb +69 -0
  83. data/test/fixtures/cli_integration.rb +5 -0
  84. data/test/fixtures/custom.rb +2 -2
  85. data/test/gateway_test.rb +167 -0
  86. data/test/logger_test.rb +123 -0
  87. data/test/server_definition_test.rb +108 -0
  88. data/test/shell_test.rb +64 -0
  89. data/test/ssh_test.rb +67 -154
  90. data/test/task_definition_test.rb +101 -0
  91. data/test/upload_test.rb +131 -0
  92. data/test/utils.rb +31 -39
  93. data/test/version_test.rb +24 -0
  94. metadata +145 -98
  95. data/THANKS +0 -4
  96. data/lib/capistrano/actor.rb +0 -567
  97. data/lib/capistrano/generators/rails/deployment/deployment_generator.rb +0 -25
  98. data/lib/capistrano/generators/rails/deployment/templates/capistrano.rake +0 -49
  99. data/lib/capistrano/generators/rails/deployment/templates/deploy.rb +0 -122
  100. data/lib/capistrano/generators/rails/loader.rb +0 -20
  101. data/lib/capistrano/scm/base.rb +0 -61
  102. data/lib/capistrano/scm/baz.rb +0 -118
  103. data/lib/capistrano/scm/bzr.rb +0 -70
  104. data/lib/capistrano/scm/cvs.rb +0 -129
  105. data/lib/capistrano/scm/darcs.rb +0 -27
  106. data/lib/capistrano/scm/mercurial.rb +0 -83
  107. data/lib/capistrano/scm/perforce.rb +0 -139
  108. data/lib/capistrano/scm/subversion.rb +0 -128
  109. data/lib/capistrano/transfer.rb +0 -97
  110. data/lib/capistrano/utils.rb +0 -26
  111. data/test/actor_test.rb +0 -402
  112. data/test/scm/cvs_test.rb +0 -196
  113. data/test/scm/subversion_test.rb +0 -145
data/CHANGELOG CHANGED
@@ -1,13 +1,149 @@
1
- *unreleased*
1
+ *2.0.0* July 21, 2007
2
2
 
3
- * Add an explicit dependency on Net::SSH and Net::SFTP versions less than 1.99.0 so that cap1 can coexist with net-ssh v2 [Jamis Buck]
3
+ * Make the "no matching servers" error more sane [halorgium]
4
4
 
5
- * Don't send no-auth-cache if no auth credentials are given [Jonathan Younger]
5
+ * Make sure the invoke task gives a sane error when the COMMAND value is omitted [halorgium]
6
+
7
+ * Make sure variables are conditionally set in the deploy recipes, so as not to clobber values set elsewhere [Jamis Buck]
8
+
9
+ * Fix "input stream is empty" errors from HighLine on prompt [Jamis Buck]
10
+
11
+ * Added "synchronous_connect" setting to try and work around SFTP hangs for certain users [Jamis Buck]
12
+
13
+ * Auto-require the SSH shell service, to avoid race conditions [Jamis Buck]
14
+
15
+ * Add a millisecond sleep in upload to reduce CPU impact [Jamis Buck]
16
+
17
+ * Allow the logger to be set via Configuration#logger= [Jamis Buck]
18
+
19
+ * Allow $CAPISTRANO:HOST$ to be used in filenames to the put command [Jamis Buck]
20
+
21
+ * Allow execute_on_servers to be called without a current task again [Jamis Buck]
22
+
23
+ * Put $stdout in sync mode, so that Net::SSH prompts are displayed [Jamis Buck]
24
+
25
+ * Make sure deploy:check aborts if it fails [Jamis Buck]
26
+
27
+ * Spelling corrections in docs [Tim Carey-Smith, Giles Bowkett]
28
+
29
+
30
+ *1.99.3 (2.0 Preview 4)* June 28, 2007
31
+
32
+ * Don't break task descriptions on a period that appears in the middle of a sentence [Jamis Buck]
33
+
34
+ * Added support for :on_error => :continue in task definitions, allowing tasks to effectively ignore connection and execution errors that occur as they run [Rob Holland]
35
+
36
+ * Use correct parameters for Logger constructor in the SCM and Strategy base initializers [Jamis Buck]
37
+
38
+ * Set LC_ALL=C before querying the revision, to make sure the output is in a predictable locale and can be parsed predictably [via Leandro Nunes dos Santos]
39
+
40
+ * Add :copy_remote_dir variable for the :copy strategy, to indicate where the archive should be copied to on the remote servers [Jamis Buck]
41
+
42
+ * Make the awk use in the dependencies code work with POSIX awk [mcornick]
43
+
44
+ * Make variable accesses thread safe [via Adrian Danieli]
45
+
46
+ * Make user input for yes/no prompts work correctly in the Mercurial module [Matthew Elder]
47
+
48
+ * Use single quotes to escape semicolon in find command, instead of a backslash [via michael.italia@gmail.com]
49
+
50
+ * Better quoting of reserved characters in commands [Jamis Buck]
51
+
52
+ * Make sure Net::SSH versions prior to 1.1.0 still work [Jamis Buck]
53
+
54
+ * Allow the :hosts and :roles keys to accept lambdas, which will be evaluated lazily to allow runtime selection of hosts and roles in tasks [Jamis Buck]
55
+
56
+ * Use `which' to test whether a command exists in the remote path, instead of `test -p' [Jamis Buck]
57
+
58
+ * Make sure the connection factory is established synchronously, to avoid multiple gateway instances being spawned [Jamis Buck]
59
+
60
+ * Make sure symlink and finalize_update tasks reference the most recent release when called by themselves [Jamis Buck]
61
+
62
+
63
+ *1.99.2 (2.0 Preview 3)* June 15, 2007
64
+
65
+ * CVS SCM module [Brian Phillips]
66
+
67
+ * Fix typo in Perforce SCM module [Chris Bailey]
68
+
69
+ * ssh_options < server options when connecting [Jamis Buck]
70
+
71
+ * Logger defaults to $stderr instead of STDERR [lhartley]
72
+
73
+ * Use cp -RPp instead of -a in the remote cache strategy
74
+
75
+ * Make the UploadError exception include an array of the hosts that failed [rob@inversepath.com]
76
+
77
+ * Allow "empty" roles to be declared [Jamis Buck]
78
+
79
+ * Mercurial SCM module [Tobias Luetke, Matthew Elder]
80
+
81
+ * Invoke all commands via sh (customizable via :default_shell) [Jamis Buck]
82
+
83
+ * Make sure all directories exist on each deploy which are necessary for subsequent commands to succeed, since some SCM's won't save empty directories [Matthew Elder]
84
+
85
+ * Add :default_environment variable, which is applied to every command
86
+
87
+
88
+ *1.99.1 (2.0 Preview 2)* May 10, 2007
89
+
90
+ * Fix some documentation typos [eventualbuddha]
91
+
92
+ * Don't retry failed connections if an explicit auth_methods list is given [Chris Farms]
93
+
94
+ * Added support for load and exit callbacks, which get invoked when all recipes have been loaded and when all requested tasks have been executed [Jamis Buck]
95
+
96
+ * Added support for start and finish callbacks, which get invoked when any task is called via the command-line [Jamis Buck]
97
+
98
+ * Make `capify' understand simple command-line switches [Jamis Buck]
99
+
100
+ * Make the server definition itself available to SSH channels, rather than just the host name [Jamis Buck]
101
+
102
+ * Identify servers by their complete credentials in logs, rather than simply by hostname [Jamis Buck]
103
+
104
+ * Uniquely identify servers based on hostname, port, and username, instead of merely on hostname [Jamis Buck]
105
+
106
+ * Allow (e.g.) scm_command and local_scm_command to be set in the event of different paths to the scm command on local vs. remote hosts. [Jamis Buck]
107
+
108
+ * Kill the "deploy:app" namespace and move those tasks into deploy, directly. [Jamis Buck]
109
+
110
+ * Make sure 'desc' applies to the next defined task, in any namespace. [Jamis Buck]
111
+
112
+ * Fix shell so that servers for a task are correctly discovered. [Jamis Buck]
113
+
114
+ * Added before(), after(), and on() callback creation methods. [Jamis Buck]
115
+
116
+ * Fix broken check! method for some deployment strategies. [Jamis Buck]
117
+
118
+ * deploy:cold should also run migrations before starting the app [Jamis Buck]
119
+
120
+ * Make the copy strategy check out to a temporary directory [Jamis Buck]
121
+
122
+
123
+ *1.99.0 (2.0 Preview 1)* April 24, 2007
124
+
125
+ * Add `capify' script to make it easier to prepare a project for deployment using cap [Jamis Buck]
126
+
127
+ * Make sure the sudo helper understands the SuSE dialect of the sudo password prompt [Steven Wisener]
128
+
129
+ * Fix synchronization issue with Gateway initialization [Doug Barth]
130
+
131
+ * Added opt-in "compat" and "upgrade" recipes for tasks to aid in the upgrade process to Capistrano 2 [Jamis Buck]
132
+
133
+ * The deployment recipes are now opt-in. Just do 'load "deploy"' in your recipe script. [Jamis Buck]
134
+
135
+ * Added $CAPISTRANO:HOST$ placeholder in commands, which will be replaced with the name of the host on which the command is executing [Jamis Buck]
136
+
137
+ * Added -e switch to explain specific task. Added -X to extend -x. Made -h much briefer. Added -T to list known tasks. [Jamis Buck]
138
+
139
+ * Added namespaces for tasks [Jamis Buck]
140
+
141
+ * Merged the Configuration and Actor classes, performed various other massive refactorings of the code [Jamis Buck]
6
142
 
7
143
 
8
144
  *1.4.1* (February 24, 2007)
9
145
 
10
- * Use the no-auth-cache option with subversion so that username/password tokens do not get cached by capistrano usage [Jonathan Younger]
146
+ * Use the no-auth-cache option with subversion so that username/password tokens do not get cached by capistrano usage [jonathan]
11
147
 
12
148
  * Deprecated upper-cased variables [Jamis Buck]
13
149
 
@@ -1,4 +1,4 @@
1
- Copyright (c) 2005,2006 Jamis Buck
1
+ Copyright (c) 2005-2007 Jamis Buck <jamis@37signals.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README CHANGED
@@ -2,34 +2,42 @@
2
2
 
3
3
  Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake, http://rake.rubyforge.org/) that allows you to define _tasks_, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN's and firewalls.
4
4
 
5
- Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and so it comes with many tasks predefined for that ("update_code" and "deploy", for instance).
5
+ Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and originally came bundled with a set of tasks designed for deploying Rails applications. The deployment tasks are now (as of Capistrano 2.0) opt-in and require clients to explicitly put
6
+ "load 'deploy'" in their recipes.
6
7
 
7
8
  == Dependencies
8
9
 
9
- Capistrano depends upon the Net::SSH library by Jamis Buck (http://net-ssh.rubyforge.org). Net::SSH itself depends on the Needle library (http://needle.rubyforge.org), also by Jamis Buck.
10
+ * Net::SSH and Net::SFTP (http://net-ssh.rubyforge.org)
11
+ * Needle (via Net::SSH)
12
+ * HighLine (http://highline.rubyforge.org)
13
+
14
+ If you want to run the tests, you'll also need to have the following dependencies installed:
15
+
16
+ * Mocha (http://mocha.rubyforge.org)
10
17
 
11
18
  == Assumptions
12
19
 
13
- In keeping with Rails' "convention over configuration", Capistrano makes several assumptions about how you will use it (most, if not all, of which may be explicitly overridden):
20
+ Capistrano is "opinionated software", which means it has very firm ideas about how things ought to be done, and tries to force those ideas on you. Some of the assumptions behind these opinions are:
14
21
 
15
- * You are writing web applications and want to use Capistrano to deploy them.
16
- * You are using Ruby on Rails (http://www.rubyonrails.com) to build your apps.
17
- * You are using Subversion (http://subversion.tigris.org/) to manage your source code.
18
- * You are running your apps using FastCGI, together with Rails' spinner/reaper utilities.
22
+ * You are using SSH to access the remote servers.
23
+ * You either have the same password to all target machines, or you have public keys in place to allow passwordless access to them.
19
24
 
20
- As with the rest of Rails, if you can abide by these assumptions, you can use Capistrano "out of the box". If any of these assumptions do not hold, you'll need to make some adjustments to your deployment recipe files.
25
+ Do not expect these assumptions to change.
21
26
 
22
27
  == Usage
23
28
 
24
- More documentation is always pending, but you'll want to see the user manual for detailed usage instructions. (The manual is online at http://manuals.rubyonrails.org/read/book/17).
25
-
26
29
  In general, you'll use Capistrano as follows:
27
30
 
28
- * Create a deployment recipe ("deploy.rb") for your application. You can use the sample recipe in examples/sample.rb as a starting point.
29
- * Use the +cap+ script to execute your recipe (see below).
31
+ * Create a recipe file ("capfile" or "Capfile").
32
+ * Use the +cap+ script to execute your recipe.
30
33
 
31
34
  Use the +cap+ script as follows:
32
35
 
33
- cap -vvv someaction
36
+ cap sometask
37
+
38
+ By default, the script will look for a file called one of +capfile+ or +Capfile+. The +someaction+ text indicates which task to execute. You can do "cap -h" to see all the available options and "cap -T" to see all the available tasks.
39
+
40
+ == KNOWN ISSUES
34
41
 
35
- By default, the script will look for a file called one of <tt>config/deploy</tt>, <tt>config/deploy.rb</tt>, <tt>capistrano</tt>, or <tt>capistrano.rb</tt>. You can the <tt>-v</tt> switch multiple times (as shown) to increase the verbosity of the output. The +someaction+ text indicates which action to execute.
42
+ * Using "put" to upload a file to two or more hosts when a gateway is in effect has a good chance of crashing with a "corrupt mac detected" error. This is due to a bug in Net::SSH.
43
+ * Running commands may rarely hang inexplicably. This appears to be specific only to certain platforms. Most people will never see this behavior.
data/bin/cap CHANGED
@@ -1,11 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- begin
4
- require 'rubygems'
5
- rescue LoadError
6
- # no rubygems to load, so we fail silently
7
- end
8
-
9
3
  require 'capistrano/cli'
10
-
11
- Capistrano::CLI.execute!
4
+ Capistrano::CLI.execute
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ OptionParser.new do |opts|
6
+ opts.banner = "Usage: #{File.basename($0)} [path]"
7
+
8
+ opts.on("-h", "--help", "Displays this help info") do
9
+ puts opts
10
+ exit 0
11
+ end
12
+
13
+ begin
14
+ opts.parse!(ARGV)
15
+ rescue OptionParser::ParseError => e
16
+ warn e.message
17
+ puts opts
18
+ exit 1
19
+ end
20
+ end
21
+
22
+ if ARGV.empty?
23
+ abort "Please specify the directory to capify, e.g. `#{File.basename($0)} .'"
24
+ elsif !File.exists?(ARGV.first)
25
+ abort "`#{ARGV.first}' does not exist."
26
+ elsif !File.directory?(ARGV.first)
27
+ abort "`#{ARGV.first}' is not a directory."
28
+ elsif ARGV.length > 1
29
+ abort "Too many arguments; please specify only the directory to capify."
30
+ end
31
+
32
+ def unindent(string)
33
+ indentation = string[/\A\s*/]
34
+ string.strip.gsub(/^#{indentation}/, "")
35
+ end
36
+
37
+ files = {
38
+ "Capfile" => unindent(<<-FILE),
39
+ load 'deploy' if respond_to?(:namespace) # cap2 differentiator
40
+ load 'config/deploy'
41
+ FILE
42
+
43
+ "config/deploy.rb" => unindent(<<-FILE),
44
+ set :application, "set your application name here"
45
+ set :repository, "set your repository location here"
46
+
47
+ # If you aren't deploying to /u/apps/\#{application} on the target
48
+ # servers (which is the default), you can specify the actual location
49
+ # via the :deploy_to variable:
50
+ # set :deploy_to, "/var/www/\#{application}"
51
+
52
+ # If you aren't using Subversion to manage your source code, specify
53
+ # your SCM below:
54
+ # set :scm, :subversion
55
+
56
+ role :app, "your app-server here"
57
+ role :web, "your web-server here"
58
+ role :db, "your db-server here", :primary => true
59
+ FILE
60
+ }
61
+
62
+ base = ARGV.shift
63
+ files.each do |file, content|
64
+ file = File.join(base, file)
65
+ if File.exists?(file)
66
+ warn "[skip] `#{file}' already exists"
67
+ elsif File.exists?(file.downcase)
68
+ warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
69
+ elsif !File.exists?(File.dirname(file))
70
+ warn "[skip] directory `#{File.dirname(file)}' does not exist"
71
+ else
72
+ puts "[add] writing `#{file}'"
73
+ File.open(file, "w") { |f| f.write(content) }
74
+ end
75
+ end
76
+
77
+ puts "[done] capified!"
@@ -1,113 +1,14 @@
1
- # You must always specify the application and repository for every recipe. The
2
- # repository must be the URL of the repository you want this recipe to
3
- # correspond to. The deploy_to path must be the path on each machine that will
4
- # form the root of the application path.
1
+ # set :user, "flippy"
2
+ # set :password, "hello-flippy"
3
+ # set :gateway, "gateway.example.com"
5
4
 
6
- set :application, "sample"
7
- set :repository, "http://svn.example.com/#{application}/trunk"
5
+ role :web, "web1.example.com"
6
+ role :app, "app1.example.com", "app2.example.com"
8
7
 
9
- # The deploy_to path is optional, defaulting to "/u/apps/#{application}".
10
-
11
- set :deploy_to, "/path/to/app/root"
12
-
13
- # The user value is optional, defaulting to user-name of the current user. This
14
- # is the user name that will be used when logging into the deployment boxes.
15
-
16
- set :user, "flippy"
17
-
18
- # By default, the source control module (scm) is set to "subversion". You can
19
- # set it to any supported scm:
20
-
21
- set :scm, :subversion
22
-
23
- # gateway is optional, but allows you to specify the address of a computer that
24
- # will be used to tunnel other requests through, such as when your machines are
25
- # all behind a VPN or something
26
-
27
- set :gateway, "gateway.example.com"
28
-
29
- # You can define any number of roles, each of which contains any number of
30
- # machines. Roles might include such things as :web, or :app, or :db, defining
31
- # what the purpose of each machine is. You can also specify options that can
32
- # be used to single out a specific subset of boxes in a particular role, like
33
- # :primary => true.
34
-
35
- role :web, "www01.example.com", "www02.example.com"
36
- role :app, "app01.example.com", "app02.example.com", "app03.example.com"
37
- role :db, "db01.example.com", :primary => true
38
- role :db, "db02.example.com", "db03.example.com"
39
-
40
- # Define tasks that run on all (or only some) of the machines. You can specify
41
- # a role (or set of roles) that each task should be executed on. You can also
42
- # narrow the set of servers to a subset of a role by specifying options, which
43
- # must match the options given for the servers to select (like :primary => true)
44
-
45
- desc <<DESC
46
- An imaginary backup task. (Execute the 'show_tasks' task to display all
47
- available tasks.)
8
+ desc <<-DESC
9
+ This is a sample task. It is only intended to be used as a demonstration of \
10
+ how you can define your own tasks.
48
11
  DESC
49
-
50
- task :backup, :roles => :db, :only => { :primary => true } do
51
- # the on_rollback handler is only executed if this task is executed within
52
- # a transaction (see below), AND it or a subsequent task fails.
53
- on_rollback { delete "/tmp/dump.sql" }
54
-
55
- run "mysqldump -u theuser -p thedatabase > /tmp/dump.sql" do |ch, stream, out|
56
- ch.send_data "thepassword\n" if out =~ /^Enter password:/
57
- end
58
- end
59
-
60
- # Tasks may take advantage of several different helper methods to interact
61
- # with the remote server(s). These are:
62
- #
63
- # * run(command, options={}, &block): execute the given command on all servers
64
- # associated with the current task, in parallel. The block, if given, should
65
- # accept three parameters: the communication channel, a symbol identifying the
66
- # type of stream (:err or :out), and the data. The block is invoked for all
67
- # output from the command, allowing you to inspect output and act
68
- # accordingly.
69
- # * sudo(command, options={}, &block): same as run, but it executes the command
70
- # via sudo.
71
- # * delete(path, options={}): deletes the given file or directory from all
72
- # associated servers. If :recursive => true is given in the options, the
73
- # delete uses "rm -rf" instead of "rm -f".
74
- # * put(buffer, path, options={}): creates or overwrites a file at "path" on
75
- # all associated servers, populating it with the contents of "buffer". You
76
- # can specify :mode as an integer value, which will be used to set the mode
77
- # on the file.
78
- # * render(template, options={}) or render(options={}): renders the given
79
- # template and returns a string. Alternatively, if the :template key is given,
80
- # it will be treated as the contents of the template to render. Any other keys
81
- # are treated as local variables, which are made available to the (ERb)
82
- # template.
83
-
84
- desc "Demonstrates the various helper methods available to recipes."
85
- task :helper_demo do
86
- # "setup" is a standard task which sets up the directory structure on the
87
- # remote servers. It is a good idea to run the "setup" task at least once
88
- # at the beginning of your app's lifetime (it is non-destructive).
89
- setup
90
-
91
- buffer = render("maintenance.rhtml", :deadline => ENV['UNTIL'])
92
- put buffer, "#{shared_path}/system/maintenance.html", :mode => 0644
93
- sudo "killall -USR1 dispatch.fcgi"
94
- run "#{release_path}/script/spin"
95
- delete "#{shared_path}/system/maintenance.html"
96
- end
97
-
98
- # You can use "transaction" to indicate that if any of the tasks within it fail,
99
- # all should be rolled back (for each task that specifies an on_rollback
100
- # handler).
101
-
102
- desc "A task demonstrating the use of transactions."
103
- task :long_deploy do
104
- transaction do
105
- update_code
106
- disable_web
107
- symlink
108
- migrate
109
- end
110
-
111
- restart
112
- enable_web
12
+ task :sample_task, :roles => :app do
13
+ run "ls -l"
113
14
  end
@@ -1 +1,2 @@
1
1
  require 'capistrano/configuration'
2
+ require 'capistrano/extensions'
@@ -0,0 +1,41 @@
1
+ module Capistrano
2
+ class Callback
3
+ attr_reader :source, :options, :only, :except
4
+
5
+ def initialize(source, options={})
6
+ @source = source
7
+ @options = options
8
+ @only = Array(options[:only]).map { |v| v.to_s }
9
+ @except = Array(options[:except]).map { |v| v.to_s }
10
+ end
11
+
12
+ def applies_to?(task)
13
+ if task && only.any?
14
+ return only.include?(task.fully_qualified_name)
15
+ elsif task && except.any?
16
+ return !except.include?(task.fully_qualified_name)
17
+ else
18
+ return true
19
+ end
20
+ end
21
+ end
22
+
23
+ class ProcCallback < Callback
24
+ def call
25
+ source.call
26
+ end
27
+ end
28
+
29
+ class TaskCallback < Callback
30
+ attr_reader :config
31
+
32
+ def initialize(config, source, options={})
33
+ super(source, options)
34
+ @config = config
35
+ end
36
+
37
+ def call
38
+ config.find_and_execute_task(source)
39
+ end
40
+ end
41
+ end