Skip to content

Commit

Permalink
First step for a Capistrano-Multistage deployment into Joyent Acceler…
Browse files Browse the repository at this point in the history
…ators (work in progress)

git-svn-id: http://svn.joyent.com/opensource/connector/source/trunk@536 7a7ed7af-43cf-e7d3-831c-e7cc5cc1171a
  • Loading branch information
pedro@joyent.com committed Nov 14, 2007
1 parent 63a09a1 commit 25392f0
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 130 deletions.
2 changes: 2 additions & 0 deletions Capfile
@@ -0,0 +1,2 @@
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
load 'config/deploy'
96 changes: 96 additions & 0 deletions config/accelerator/accelerator_tasks.rb
@@ -0,0 +1,96 @@
=begin #(fold)
++
Copyright 2004-2007 Joyent Inc.
Redistribution and/or modification of this code is
governed by the GPLv2.
Report issues and contribute at http://dev.joyent.com/
$Id$
--
=end #(end)

Capistrano::Configuration.instance(:must_exist).load do
namespace :accelerator do

desc "Adds a SMF for the application"
task :create_smf, :roles => :app do
puts "set variables"
service_name = application
working_directory = current_path

template = File.read("config/accelerator/smf_template.erb")
buffer = ERB.new(template).result(binding)

put buffer, "#{shared_path}/#{application}-smf.xml"

sudo "svccfg import #{shared_path}/#{application}-smf.xml"
end

desc "Creates an Apache 2.2 compatible virtual host configuration file"
task :create_vhost, :roles => :web do
public_ip = ""
run "#{getip}" do |ch, st, data|
public_ip = data.gsub(/[\r\n]/, "")
end

cluster_info = YAML.load(File.read('config/mongrel_cluster.yml'))

start_port = cluster_info['port'].to_i
end_port = start_port + cluster_info['servers'].to_i - 1
public_path = "#{current_path}/public"

template = File.read("config/accelerator/apache_vhost.erb")
buffer = ERB.new(template).result(binding)

put buffer, "#{shared_path}/#{application}-apache-vhost.conf"
sudo "cp #{shared_path}/#{application}-apache-vhost.conf /opt/csw/apache2/etc/virtualhosts/#{application}.conf"

restart_apache
end

desc "Restart apache"
task :restart_apache, :roles => :web do
sudo "svcadm refresh svc:/network/http:cswapache2"
end

desc "Stops the application"
task :smf_stop, :roles => :app do
sudo "svcadm disable /network/mongrel/#{application}-production"
end

desc "Starts the application"
task :smf_start, :roles => :app do
sudo "svcadm enable -r /network/mongrel/#{application}-production"
end

desc "Restarts the application"
task :smf_restart do
smf_stop
smf_start
end

desc "Deletes the configuration"
task :smf_delete, :roles => :app do
sudo "svccfg delete /network/mongrel/#{application}-production"
end

desc "Shows all Services"
task :svcs, :roles => :app do
run "svcs -a" do |ch, st, data|
puts data
end
end

desc "After setup, creates Solaris SMF config file and adds Apache vhost"
task :setup_smf_and_vhost do
create_smf
create_vhost
end

end

after 'deploy:setup', 'accelerator:setup_smf_and_vhost'

end
23 changes: 23 additions & 0 deletions config/accelerator/apache_vhost.erb
@@ -0,0 +1,23 @@
<VirtualHost <%= public_ip %>:80>
ServerName <%= server_name %>
ServerAlias <%= server_alias %>
DocumentRoot <%= public_path %>

<Directory "<%= public_path %>/">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>

<Proxy balancer://<%= application %>-mongrels><% start_port.upto(end_port) do |port| %>
BalancerMember http://127.0.0.1:<%= port %><% end %>
</Proxy>

ProxyPass /images !
ProxyPass /javascripts !
ProxyPass /stylesheets !
ProxyPass / balancer://<%= application %>-mongrels/
ProxyPassReverse / balancer://<%= application %>-mongrels/
ProxyPreserveHost On
</VirtualHost>
30 changes: 30 additions & 0 deletions config/accelerator/smf_template.erb
@@ -0,0 +1,30 @@
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest' name='mongrel/<%= service_name %>-production'>
<service name='network/mongrel/<%= service_name %>-production' type='service' version='0'>
<create_default_instance enabled='true'/>
<single_instance/>
<dependency name='fs' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/system/filesystem/local'/>
</dependency>
<dependency name='net' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/network/loopback'/>
<!-- uncomment the following line if you are on an L+ Accelerator since /home is mounted through nfs -->
<!--<service_fmri value='svc:/network/nfs/client'/>-->
</dependency>
<dependent name='mongrel_multi-user' restart_on='none' grouping='optional_all'>
<service_fmri value='svc:/milestone/multi-user'/>
</dependent>
<exec_method name='start' type='method' exec='/opt/csw/bin/mongrel_rails cluster::start' timeout_seconds='60'>
<method_context working_directory='<%= working_directory %>'>
<method_credential user='<%= user %>' group='<%= group %>' />
<method_environment>
<envvar name='PATH' value='/usr/bin:/bin:/opt/csw/bin' />
</method_environment>
</method_context>
</exec_method>
<exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'>
<method_context/>
</exec_method>
</service>
</service_bundle>
187 changes: 57 additions & 130 deletions config/deploy.rb
Expand Up @@ -11,139 +11,66 @@
-- --
=end #(end) =end #(end)


require 'mongrel_cluster/recipes' require 'erb'

require 'config/accelerator/accelerator_tasks'
# SOME THINGS I HAD TO DO TO GET THINGS STARTED ON A NEW ZONE: require 'config/recipes/joyent'
# * checked out from svn then removed it (as to get my password on there)
# * change /etc/passwd so that /bin/bash is the default shell
# * added "PermitUserEnvironment yes" to /etc/ssh/sshd_config
# * svcadm restart ssh
# * created /.ssh/environment
# -- PATH=/opt/csw/bin:/usr/bin:/usr/sbin
#
# cap setup
#
# * Make any changes to the files in shared
# * create db
#
# cap deploy
#
# COMMANDS I HAVE CHECKED OUT
# cap <command>
# commands: setup, start, stop, restart, deploy, rollback, deploy_with_migrations

# =============================================================================
# REQUIRED VARIABLES
# =============================================================================
set :application, "connector" set :application, "connector"
set :repository, "http://svn.joyent.com/joyent/connector-merge" set :repository, "http://svn.joyent.com/opensource/connector/source/trunk"


role :web, "webhostname" # If you aren't deploying to /u/apps/#{application} on the target
role :app, "apphostname" # servers (which is the default), you can specify the actual location
role :db, "dbhostname", :primary => true # via the :deploy_to variable:

set :deploy_to, "/opt/joyent/#{application}" # I like this location
#set :rails_env, :development

# If you aren't using Subversion to manage your source code, specify

# your SCM below:
# ============================================================================= set :scm, :subversion
# OPTIONAL VARIABLES set :sudo, "/opt/csw/bin/sudo"
# =============================================================================
set :deploy_to, "/opt/joyent/#{application}" # Do not run the sudo command through sh
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml" # default_run_options[:shell] = false


set :user, "root" # We are going to get role based servers and other details from the stage files
set :svn, "/opt/csw/bin/svn" # give a look to the config/deploy/ directory for specific stages
set :sudo, "/opt/csw/bin/sudo" set :stages, %w(staging production testing)

set :default_stage, "testing"

require 'capistrano/ext/multistage'
# =============================================================================
# TASKS
# ============================================================================= # Example dependancies
task :after_setup do depend :remote, :command, :gem, :roles => :app
put (File.read('lib/joyent_config.rb'), "#{shared_path}/joyent_config.rb", :mode => 0644) depend :remote, :command, :ggrep, :roles => :app # This is due to the way we're getting the IP Address into accelerator_tasks.rb
put (File.read('config/database.yml'), "#{shared_path}/database.yml", :mode => 0644) depend :remote, :gem, :rcov, '>=0.8.0', :roles => :app
put (File.read('config/environments/production.rb'), "#{shared_path}/production.rb", :mode => 0644) depend :remote, :gem, :mongrel, '>=1.0.1',:roles => :app
end depend :remote, :gem, :hpricot, '>=0.6.0', :roles => :app

depend :remote, :gem, :rake, '>=0.7.3', :roles => :app
task :after_update_code do depend :remote, :gem, :tzinfo, '>=0.3.3', :roles => :app
run "rm #{release_path}/lib/joyent_config.rb" depend :remote, :gem, :ezcrypto, '>=0.7.0', :roles => :app
run "cp #{shared_path}/joyent_config.rb #{release_path}/lib/joyent_config.rb" depend :remote, :gem, :gettext, '=1.9.0', :roles => :app

depend :remote, :gem, :mongrel_cluster, '>=1.0.4', :roles => :app
# Copy in the database.yml file
run "rm #{release_path}/config/database.yml" deploy.task :restart do
run "cp #{shared_path}/database.yml #{release_path}/config/database.yml" accelerator.smf_restart

accelerator.restart_apache
# Copy in a stubbed out production
run "rm #{release_path}/config/environments/production.rb"
run "cp #{shared_path}/production.rb #{release_path}/config/environments/production.rb"
end

task :before_symlink do
run "if [[ -d #{current_path} ]]; then rm #{current_path}; fi"
end

task :start_mongrel_cluster , :roles => :app do
set_mongrel_conf
run "cd #{current_path}; mongrel_rails cluster::start -C #{mongrel_conf}"
end

task :stop_mongrel_cluster , :roles => :app do
set_mongrel_conf
run "cd #{current_path}; mongrel_rails cluster::stop -C #{mongrel_conf}"
end

task :restart, :roles => :app do
stop
start
end

task :stop, :roles => :app do
stop_mongrel_cluster
stop_imap_worker
stop_joyent_job
end end


task :start, :roles => :app do deploy.task :start do
start_mongrel_cluster accelerator.smf_start
start_imap_worker accelerator.restart_apache
start_joyent_job
end

task :start_imap_worker, :roles => :app do
run <<-CMD
export RAILS_ENV=#{rails_env};
nohup #{current_path}/script/imap_worker start;
sleep 5
CMD
end end


task :stop_imap_worker, :roles => :app do deploy.task :stop do
run <<-CMD accelerator.smf_stop
export RAILS_ENV=#{rails_env}; accelerator.restart_apache
#{current_path}/script/imap_worker stop;
sleep 1
CMD
end

task :start_joyent_job, :roles => :app do
run <<-CMD
export RAILS_ENV=#{rails_env};
nohup ruby #{current_path}/script/joyent_job start;
sleep 5;
export RAILS_ENV=#{rails_env};
nohup ruby #{current_path}/script/joyent_job start_worker 5;
sleep 5
CMD
end end


task :stop_joyent_job, :roles => :app do # Override the default deploy:cold to include the schema load
run "ruby #{current_path}/script/joyent_job stop" deploy.task :cold do
end update

run "cd #{current_path}; rake RAILS_ENV=production db:schema:load"
task :before_rollback_code, :except => { :no_release => true } do migrate
if releases.length < 2 start
raise "could not rollback the code because there is no prior release"
else
run "rm #{current_path}"
end
end end

after :deploy, 'deploy:cleanup'
4 changes: 4 additions & 0 deletions config/deploy/production.rb
@@ -0,0 +1,4 @@
# We have to config this properly!!

# Fill this with the real production servers.
# Give a look to deploy/testing.rb
19 changes: 19 additions & 0 deletions config/deploy/staging.rb
@@ -0,0 +1,19 @@
# We have to config this properly!!

set :user, 'foo'

# Connector stagging servers
# Give a look to deploy/testing.rb

# This is the public IP address provided with the Accelerator passwords
# You may try by running this at the command line, after you checked
# that have ggrep installed into the Accelerator:
set :getip, "ifconfig -a | ggrep -A1 e1000g0 | grep inet | awk '{print $2}'"

set :domain, 'domain.com'

role :app, domain
role :web, domain
role :db, domain, :primary => true

set :server_name, "domain.com"

0 comments on commit 25392f0

Please sign in to comment.