www.YoYoBrain.com - Accelerators for Memory and Learning Questions for Capistrano

Category: Basics - (21 questions) Command for installing capistrano when gem install capistrano RubyGems package management is installed

Capistrano's expectations about your servers that must be met to use Capistrano accessed via SSH have a POSIX-compatible shell installed called "sh" that resides in the default system path. If using passwords to access your servers, all must have the same password. (Because this is not generally a good idea, the preferred way of accessing your servers is with a public key. Make sure you've got a good passphrase on your key.)

Does Capistrano support telnet and ftp no

Capistrano prerequites skills Comfort with command line enough to navigate directories and excute commands Familiar/comfortable with Ruby

Files that provide Capistrano with its capfile - similar to makefile or rakefile instructions concept

Where do you tell Capistrano about the capfile servers you want to connect to and what tasks you want to perform on your servers

What is a capfile in terms of programming It is a custom Domain Specific Language on instructions/language top of Ruby put more simply, its a Ruby script augmented with helper syntax that makes it easy to define server roles and tasks.

Editor that must be used to write capfiles any capfile file extension none. just capfile

What's happening in this example? defines a single task, called "search_libs", that task runs the shell command in task :search_libs, :hosts => "www.capify.org" quotes do run "ls -x1 /usr/lib | grep -i xml"end says that it should be executed only on the "www.capify.org" host.

When executed, it will display all files and subdirectories in /usr/lib that include the text "xml" in their name. Where does "run" display all output by the console default how do you specify that a task should run on pass an array of role names to the :roles servers in multiple roles option

What is the lmit to the number of tasks you none can define in a capfile

Purpose of "roles" allows you to drop the :hosts=> option in your tasks and define groups of servers to run tasks on

By default, what roles are tasks run on all servers/all roles defined with role

Capistrano's default log in is Whatever user you are as currently logged in to your local machine

How do you tell capistrano about a gateway server you may be using to get behind a set :gateway, "www.capify.org"role :libs, firewall "crimson.capify.org"

Syntax for adding multiple servers to a role role :libs, "crimson.capify.org", "magenta.capify.org"

What happens with tasks when run on a role command will be executed in parallel on both with multiple servers servers, with the output aggregated into a single stream and displayed on your console. How do you specifiy the server roles on add :roles constraints to each task, which a task should run specifying which role each is associated with.

task :count_libs, :roles => :libs do run "ls -x1 /usr/lib | wc -l"end

Preferred way of accessing your with a public key with a good good servers...and why passphrase ...otherwise all servers need the same username and password installed

Category: Syntax - (63 questions) Do transactions track and revert your no, you have to register on_rollback handlers changes? appropriately, that take the necessary steps to undo the changes that the task has made.

What is going on this code block in terms of the transaction first task, "deploy" wraps a transaction around its invocations of "update_code" and task :deploy do transaction do "symlink". update_code symlink endendtask If error happens within that transaction, the :update_code do on_rollback { run "rm -rf "on_rollback" handlers that have been #{release_path}" } declared are all executed, in reverse order. source.checkout(release_path)endtask :symlink do on_rollback { run "rm #{current_path}; ln -s #{previous_release} #{current_path}" } run "rm #{current_path}; ln -s #{release_path} #{current_path}"end purpose of on_rollback handlers run if a transaction fails command to load files load "files" how do you add a directory to capistrano's load path load_paths << "config/stages" how do you specify files load from the -f switch command line cap -f libs libs:search purpose of -F switch loads default capfile syntax to execute a task defined in a capfile cap search_libs (assuming you are in the directory where the capfile is located) command to get a list of tasks cap -T syntax for adding a description that show in cap -t desc "Search /usr/lib for files named xml." which tasks are shown in cap -t those with "desc" defined desc "Search /usr/lib for files named xml."task :search_libs, :roles => :libs do run "ls -x1 /usr/lib | grep -i xml"end syntax to declare a role role :libs, "www.capify.org"

What part of desc is shown by cap -T description shown is all text up to the first "." character (or up to the first 30 characters, whichever comes first

Command to show all of description cap -t -e (its the -e switch "explain") and pass the name of the tasks you want to describe

2 ways How do you log in as a different user encode that username in the server definition, "[email protected]".Alternatively, you can set the :user variable to the username you want to use.

How do you define multiple server roles role :libs, "crimson.capify.org", "magenta.capify.org"role :files, "fuchsia.capify.org"

What is the purpose of the invoke task lets you execute a single command on your remote servers, without having to write a task for it syntax for invoke specify the command you want to invoke via the COMMAND variable:

cap invoke COMMAND="df -h"

What does the following command do execute "df -h" on all defined servers, in all roles. cap invoke COMMAND="df -h"

How do you restrict a command called from specifying the role names as a invoke to a certain set of roles comma-delimited list, using the ROLES variable:

cap invoke COMMAND="df -h" ROLES=libs how do you execute commands via invoke using the HOSTS variable on servers that have not been previously defined cap invoke COMMAND="df -h" HOSTS=mauve.capify.org command to get full documentation for the cap -e invoke invoke task

Main draw back of the invoke command every time you invoke a command, it has to reestablish connections to the servers purpose and benefit of cap shell interactive prompt from which you can enter adhoc commands execute tasks.... all connections that are established during the duration of the shell session are cached and reused How do you get help from within cap shell type "help"

Purpose of a namespace allows you to group a set of tasks (or even other namespaces) and give them a name. Syntax for creating a namespace namespace :libs do task :search, :roles => :libs do run "ls -x1 /usr/lib | grep -i xml" end task :count, :roles => :libs do run "ls -x1 /usr/lib | wc -l" endendnamespace :disk do task :free, :roles => :files do run "df -h /" endend syntax to peform the search task defined cap libs:search below namespace :libs do task :search, :roles => :libs do run "ls -x1 /usr/lib | grep -i xml" end task :count, :roles => :libs do run "ls -x1 /usr/lib | wc -l" endend

Can you have tasks with the same name in yes different namespaces?

What happens with a task in a namespace it is run if you type cap name space named :default so cap libs runs the default task below

namespace :libs do task :default, :roles => :libs do run "ls -x1 /usr/lib | grep -i xml" end task :count, :roles => :libs do run "ls -x1 /usr/lib | wc -l" endend how do you add variables into your tasks - #{} syntax: for example to search task :search, :roles => :libs do run "ls -x1 /usr/lib | grep -i #{term}"end

How would the user set the term variable below set :term, "xml" task :search, :roles => :libs do run "ls -x1 /usr/lib | grep -i #{term}"end The helper below

Capistrano::CLI.ui.ask "Gimme a search code to send a prompt to the user and grab term: " replaces what block of code he responseset(:term) do print "Gimme a search term: " STDOUT.flush STDIN.gets.chompend Syntax to introduce a transaction task :deploy do transaction do update_code symlink endendtask :update_code do on_rollback { run "rm -rf #{release_path}" } source.checkout(release_path)endtask :symlink do on_rollback { run "rm #{current_path}; ln -s #{previous_release} #{current_path}" } run "rm #{current_path}; ln -s #{release_path} #{current_path}"end helper that prompts the user to enter a variable Capistrano::CLI.ui.ask

Variables that you get with ".ask" are cached Cached . user is prompted for first, answer is or prompted each time? cached fr subsequent requests purpose of :default_environment for specifying environment variables that should be set for every command purpose of :ssh_options variable for setting things like agent forwarding and specifying an alternative port number, purpose of :logger variable holds a reference to the logger instance being used by Capistrano. purpose of -s switch used to set variables from the command-line, "-s" (lower-case) switch will set the variable after all recipe files have been loaded purpose of -S switch set variables from the command-line before any recipe files hae been loaded purpose of -S switch set variables from the command-line before any recipe files hae been loaded when is it useful to set a variable after all if you need to override variables that have recipe files have loaded been set by the recipe files themselves

When is it useful to set variables before a if the recipes themselves depend on a recipe file has loaded variable being set while they are loading (for instance, if they are doing conditional creation of tasks and so forth).

How do you set an environment variable from the command line cap COMMAND="df -h" invoke

That will set an environment variable named COMMAND, which you could access in your tasks using Ruby's ENV hash of environment variables

Most popular capistrano use case deploying web applications show_tasks The show_tasks task never does any work on any remote servers. All it does is inspect the existing tasks and display them to standard out in alphabetical order, along with their descriptions. This will include both the standard tasks (described here), as well as your own custom tasks. default command to view deployment tasks

show_deploy_tasks how will the setup task behave on servers It is non-destructive, though, and may safely that have been previously set up be executed against an existing production system. purpose of rollback task k task will roll your application back to the previously deployed version. It does this by first calling the update_code task, and then invoking restart to get your FastCGI listeners looking at the right version. does the rollback task address migrations no, only code. rollback_code task primarily used as a single component of the rollback task, but it may occassionally be useful on its own. All it does determine what the previous release was (if one exists), update the current symlink to point to that, and then delete the latest release. It affects all servers. purpose of the spinner task The spinner task may be used to start the spinner process for your application (as described in chapter 3). It assumes that you have a file script/spin in your application, that describes the process for starting the spinner. Also, by default the spinner will be started as the app user. If you wish to start it as a different user, set the :spinner_user variable to something else. (This only works if you are using sudo to start the spinner. If you can't use sudo, or don't want to use sudo, set the :use_sudo variable to false, and the spinner will always be started as you.) migrate task he migrate task exists to help you run ActiveRecord migrations against your production database. It assumes that:

your database servers are in the :db role, and your primary database server has :primary => true associated with it.

The migrate task will only be executed for the :db server with :primary => true. how does the migrate task work The migrate task will only be executed for the :db server with :primary => true. By default, all this task does is change to the directory of your current release (as indicated by the current symlink), and run rake RAILS_ENV=production migrate. You can specify that it should run against the latest release (regardless of what the current release is) by setting the migrate_target variable to :latest before invoking this task. Likewise, if you want to specify additional environment variables (beside RAILS_ENV) you can set the migrate_env variable to the space-delimited list of name=value pairs to use. syntax for using invoke with rake rake remote_exec ACTION=invoke \ COMMAND="svn up /u/apps/flipper/current/app/views" \ ROLES=app purpose of disable_web There are times when you want to temporarily disable web access to your application, such as when you are doing database maintenance, or upgrading your Ruby installation. The disable_web task may be used in this instance to put up a static maintenance page that is displayed to visitors, instead of your application. assumptions made by disable_web ou are using Apache to front your applications. Your web servers are all in the :web role. There is a system symlink in your application's public directory that points to a #{shared_path}/system directory. You have an rewrite rule set up that redirects all requests to /system/maintenance.html if that file exists. syntax for running disable_web command rake remote_exec ACTION=disable_web. if any one of the three preconditions are not met, how must disable_web be handled You are using Apache to front your applications. Your web servers are all in the :web role. There is a system symlink in your application's public directory that points to a #{shared_path}/system directory. You have an rewrite rule set up that redirects all requests to /system/maintenance.html if that file exists. how do you build custom Capistrano task the author of a task library, you simply write libraries your tasks as you normally would, but then you wrap them in a block so that Capistrano can load them into the currently executing configuration: A task library [ruby]

Capistrano.configuration(:must_exist).load do task :my_funky_task, :roles => :app do ... end task :another_funky_task do ... end end

The :must_exist parameter simply guards against your file being loaded outside of a Capistrano recipe file. If it is, an exception will be raised indicating that was the case. Then, you package the file up (let's call it "custom-tasks.rb") and distribute it, either via , or with a "setup.rb"http://i.loveruby.net/en/projects/set up/ file. once you've installed a custom library of in your deploy.rb, require the file like you tasks, how do you make its tasks available to would any other ruby file: you? Using a task library [ruby]

require 'custom-tasks'

verify it with cap show_tasks How can you extend lower level capistrano extension methods commands " when you'll write methods that you want multiple tasks to share. The methods themselves aren't tasks, they are simply lower-level operations, like the run or put or delete methods that Capistrano itself provides. Capistrano allows you to easily distribute and share libraries of these extension methods, as well as tasks. Simply put your extension methods in a module, register the module with Capistrano, and then package it up and ship it. People can then use your extension methods simply by requiring the file, the same as with task libraries. Sample extension library [ruby]

require 'capistrano' module MyReportingMethods def display(options={}) ... run(...) ... put(...) ... end end Capistrano.plugin :report, MyReportingMethods

Category: Rails - (48 questions) Assumption made in regard to logging in via You have configured a public key to use for ssh when using rails and capistrano SSH access to your target host. first step to enable capistrano for a rails create a capfile project (use the capify command - see related flashcard) Rails convention regarding configuration all put under the config directory information How does Capistrano handle rails preference it puts a skeleton capfile in the root project of having all configuration info under the directory which loads config/deploy.rb config directory while handling its preference of having its files in the current directory?

Where does rails related deployment config/deploy.rb information live? what does 'capify' do stubs out skeleton capfile in the root project directory, and config/deploy.rb purpose of cap -T listing of all tasks available to you what does the statement below do -explain switch will explain the deploy:pending:diff task cap -e deploy:pending:diff

Things to modify for rails /capistrano in the congif/deploy.rb file that is generated by the Application name capify command deploy_to (modify as needed)(?roles) repository variable deployment target for the :app, :web, and :db roles: (set to your server) how do you set the repository to be used in a rails capistrano deployment there is a repository variable, use the set commandset :repository, "http://svn.sourcecode.com/project/trunk" Purpose of the "roles" concept in Capistrano helps specialize the behavior of certain tasks regarding certain kinds of machines.

Most complicated part of first time fire up the "listeners". These are the FastCGI deployments or processes that drive your application.

Mongrel configuration requires requests to they are forwarded to your pool of listeners be handled how? REcommended method for telling capistrano how to start pool of listeners create a spin script and put it in the script directory. sample might look like this

/path/current/script/process/spawner -p 11000 -i 3

What happens when type cap deploy:setup Capistrano will log into your server and try to set up a simple directory hierarchy, which cap deploy:setup will use to support your application's deployment. Every Capistrano deployment will use this same basic layout for directory hierarchy it #{deploy_to}/#{deploy_to}/releases sets up when you type cap deploy:setup #{deploy_to}/shared ...what is it #{deploy_to}/shared/log #{deploy_to}/shared/system #{deploy_to}/shared/pids

What happens each time the application is a new directory is created under the deployed "releases" directory, and then a symlink is created at "#{deploy_to}/current" that points at the new release. This "current" symlink should be considered the root directory of the currently active release.

What should be considered the root directory It will be the last directory created under the of the currently active release in capistrano? "releases" directory when the application was last deployed....Capistrano creates a symlink to this directory called "current"

Purpose of Checks the configuration on deployment: cap -q deploy:check outputs an "ok" message or a list of dependancies that could not be found (i.e. if you didn't have subversion installed on a remote host) Common cause for subversion showing up SVN installed to non-standard location. as a missing dependancy even though it is Tell Capistrano specifically where the "svn" installed on the target host - and how you do command is located by adding this you firx somewhere in "config/deploy.rb" file:

set :scm_command, "/opt/local/bin/svn"

(set the value to be the actual path to the "svn" executable for your own environment.) You are ready to deploy only when this deploy:check reports that all the occurs dependencies are found on all servers What is the idea of "The Cold Deploy" Usually, when you deploy, your application will already be running, so the deploy simply pushes the code out, updates that "current" symlink, and then restarts your app. The first time, though, your app is not already running. Things are "cold

What provision is made in Capistrano for the "deploy:cold" task: "cold deployment" use case will push the code out to your servers and update the symlink, just like deploy does. However, it will also run any migrations that need to be run (letting you to get your database schema set up) and will then start your application's listeners.

Common failure point for cap deploy:cold starting the various event listeners like task mongrel for example What steps need to be taken if deploy:cold you have log in and do it manually. fails to start event listeners command to deploy that is used after cap deploy deploy:cold (i.e. any deployment after initial set up)

What does cap deploy do? push the new code, symlink it, and then restart your application so that it uses the new code purpose of roll your application back to the previous release cap deploy:rollback Capistrano handles rollbacks how? because it deploys each new release into it's own directory, it simply updates the "current" symlink to point to the previous release and then restarts your application again

How do you handle scaling up in Capistrano SET ROLES - st tell Capistrano about each in terms of providing information on your server, and what role each play, using role infrastructure and getting it set up :role_name SET GATEWAYS AS NEEDED any gateways set with set :gateway "gateway url" SET UP SERVERS..set up each server with cap deploy:setup DEPLOY then deploy or deploy:cold as necessary Command that goes one step farther than capify, and reads information for cap --apply-to /path/to/my/app deployment.rb MyApplicationName According to the authors, Deployment recipe rakefile is to Capistrano as what is to rake? The repository variable in the full path to repository (not just the server) config/deployment.rb refers to default capitstrano tasks expect what roles to web be defined? app db What roles can ou define in deployment.rb - none...define what you want. what constraints are there What variables are required for rails application capistrano deployment recipes repository Where does the deployment recipe live? config/deployment.rb deploy_to represents the root of your deployment path Command to execute setup of your application using rake rake remote:exec ACTION=setup What command transfers files from the the put helper machine where you launching capistrano commands to one or more servers syntax for put helper to use put, just pass two parameters-a string containing the data to transfer, and the name of the file to receive the data on each remote host. Optionally, you can also specify :mode => value to set the mode of the value. (Note, this will overwrite the file on the remote host!)

put(File.read('templates/database.yml'), "#{release_path}/config/database.yml", :mode => 0444) purpose of the sudo command; how does it The sudo command is exactly like the run work? command, except that it executes the command via sudo. This assumes that sudo is in a standard path on the remote host, and that the user you used to log into the server has permission to use sudo for the requested operation. If a password is requested, the password used to log into the server will be used. sudo example [ruby]

sudo "apachectl graceful"

helper that executes a string as a command run run "ls" run "cd /home/" run "gem install rails"

etc etc how do you deal with prompts when using the run command run "sudo ls -la" do |channel, stream, data| if data =~ /^Password:/ logger.info "#{channel[:host]} asked for password" channel.send_data "mypass\n" end end how does the run command work he run helper takes a single string identifying the command to execute. This command can be any valid shell command, or even multiple commands chained together by &&. This command (or commands) will be executed on all servers associated with the current task, in parallel. If the executed command fails (returns non-zero) on any server, run will raise an exception. how can you pass a block to run you can pass a block to run. The block will be invoked every time the command produces output (stderr or stdout). The block should accept three parameters: the channel (an object representing the underlying SSH channel being used to communicate with the server), the stream (a symbol, either :err or :out), and the data itself. What is the purpose of the channel object The channel object allows you to send data back to the process, on it's stdin stream, by calling send_data on the channel. Also, you can access the name of the host that produced the output via channel[:host]. How can you extend Capistrano's capbilities write a task library Category: Tips and Tidbits - (2 questions) Recommended method for handling asset:packager plug in with rails deployment

Add a task to after_update_code so it gets run before the symlink is updated and the listeners are bounced namespace :deploy do desc "Create asset packages for production" task :after_update_code, :roles => [:web] do run <<-EOF cd #{release_path} && rake RAILS_ENV=production asset:packager:build_all EOF endend test test