Skip to content

Instantly share code, notes, and snippets.

@eric
Created June 10, 2010 01:31
Show Gist options
  • Save eric/432446 to your computer and use it in GitHub Desktop.
Save eric/432446 to your computer and use it in GitHub Desktop.
Using Moonshine and Capistrano with multiple roles
# manifests/capistrano_role/app.rb
module CapistranoRole
module App
def app_stack
recipe :memcached
end
end
end
require "#{File.dirname(__FILE__)}/../../vendor/plugins/moonshine/lib/moonshine.rb"
# Let us require other files
$LOAD_PATH << File.expand_path('..', __FILE__)
require 'capistrano_role'
class ApplicationManifest < Moonshine::Manifest
# Include role-specific modules
include CapistranoRole
# ...
end
# manifests/capistrano_role.rb
module CapistranoRole
def self.included(base)
Dir[File.join(File.expand_path('..', __FILE__), 'capistrano_role', '*.rb')].each { |f| require f }
ENV['CAPISTRANO_ROLES'].to_s.split(',').each do |role|
# Only include the modules we need
if CapistranoRole.constants.include?(role.camelize)
base.send(:include, CapistranoRole.const_get(role.camelize))
end
# Only include the recipe for the stack if we can find it
stack_name = "#{role}_stack".to_sym
if base.method_defined?(stack_name)
base.recipe stack_name
else
puts " *** No stack found for '#{role}'"
end
end
end
end
::Capistrano::Command.class_eval do
def replace_placeholders(command, channel)
command.gsub(/\$CAPISTRANO:HOST\$/, channel[:host])
command.gsub(/\$CAPISTRANO:ROLES\$/, channel[:server].roles.join(','))
end
end
::Capistrano::ServerDefinition.class_eval do
attr_accessor :roles
end
::Capistrano::Configuration.class_eval do
def find_servers_with_role_attr(*args)
servers = find_servers_without_role_attr(*args)
servers.each do |server|
server.roles = self.roles.select { |name, server_list| server_list.include?(server) }.map { |name, _| name }
end
servers
end
alias_method :find_servers_without_role_attr, :find_servers
alias_method :find_servers, :find_servers_with_role_attr
end
namespace :moonshine do
desc 'Apply the Moonshine manifest for this application'
task :apply, :except => { :no_release => true } do
moonshine_manifest = fetch(:moonshine_manifest, 'application_manifest')
sudo "env RAILS_ROOT=#{latest_release} RAILS_ENV=#{fetch(:rails_env)} CAPISTRANO_ROLES=$CAPISTRANO:ROLES$ shadow_puppet #{latest_release}/app/manifests/#{moonshine_manifest}.rb"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment