Skip to content

Instantly share code, notes, and snippets.

@donnoman
Created December 11, 2010 17:10
Show Gist options
  • Select an option

  • Save donnoman/737474 to your computer and use it in GitHub Desktop.

Select an option

Save donnoman/737474 to your computer and use it in GitHub Desktop.
module Capistrano
class Configuration
module Servers
# Identifies all servers that the given task should be executed on.
# The options hash accepts the same arguments as #find_servers, and any
# preexisting options there will take precedence over the options in
# the task.
def find_servers_for_task(task, options={})
find_servers(task.options.merge(options))
end
# Attempts to find all defined servers that match the given criteria.
# The options hash may include a :hosts option (which should specify
# an array of host names or ServerDefinition instances), a :roles
# option (specifying an array of roles), an :only option (specifying
# a hash of key/value pairs that any matching server must match), and
# an :exception option (like :only, but the inverse).
#
# Additionally, if the HOSTS environment variable is set, it will take
# precedence over any other options. Similarly, the ROLES environment
# variable will take precedence over other options. If both HOSTS and
# ROLES are given, HOSTS wins.
#
# Yet additionally, if the HOSTFILTER environment variable is set, it
# will limit the result to hosts found in that (comma-separated) list.
#
# Usage:
#
# # return all known servers
# servers = find_servers
#
# # find all servers in the app role that are not exempted from
# # deployment
# servers = find_servers :roles => :app,
# :except => { :no_release => true }
#
# # returns the given hosts, translated to ServerDefinition objects
# servers = find_servers :hosts => "[email protected]"
def find_servers(options={})
hosts = server_list_from(ENV['HOSTS'] || options[:hosts])
if hosts.any?
filter_server_list(hosts.uniq)
else
roles = role_list_from(ENV['ROLES'] || options[:roles] || self.roles.keys)
only = options[:only] || {}
except = options[:except] || {}
servers = roles.inject([]) { |list, role| list.concat(self.roles[role]) }
servers = servers.select { |server| only.all? { |key,value| server.options[key] == value } }
servers = servers.reject { |server| except.any? { |key,value| server.options[key] == value } }
#allows you to add the option :once to a task ie: task :my_task, :roles => :app, :once => true do ...
servers = [servers.first] if options[:once]
logger.trace "servers: #{servers.map { |s| s.host }.inspect}"
filter_server_list(servers.uniq)
end
end
end
end
end
namespace :deploy do
desc <<-DESC
Run the migrate rake task. By default, it runs this in most recently \
deployed version of the app. However, you can specify a different release \
via the migrate_target variable, which must be one of :latest (for the \
default behavior), or :current (for the release indicated by the \
`current' symlink). Strings will work for those values instead of symbols, \
too. You can also specify additional environment variables to pass to rake \
via the migrate_env variable. Finally, you can specify the full path to the \
rake executable by setting the rake variable. The defaults are:
set :rake, "rake"
set :rails_env, "production"
set :migrate_env, ""
set :migrate_target, :latest
DESC
task :migrate, :roles => :app, :once => true do
rake = fetch(:rake, "rake")
rails_env = fetch(:rails_env, "production")
migrate_env = fetch(:migrate_env, "")
migrate_target = fetch(:migrate_target, :latest)
directory = case migrate_target.to_sym
when :current then current_path
when :latest then current_release
else raise ArgumentError, "unknown migration target #{migrate_target.inspect}"
end
run "cd #{directory}; #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment