Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-2 of 2 total  RSS 

execute a task serially on different hosts, not in parallel

// This code will let you define a task, using the same conventions as Capistrano's "task", that executes serially on the hosts defined by its role rather than in parallel. This is useful if you are deploying to multiple live servers behind a load balancer, the deployment process takes down the server, and you want only one server down at a given time.

This efinitely uses magic. we're not sure if this will work in future versions of Capistrano, but changing it should be relatively simple.

def serial_task(name, options = {}, &block)
  servers = self.roles[options[:roles]].collect {|server| server.host}
  task_syms = []
  servers.each do |hostname|
    role_sym = "_serial_task_#{name.to_s}_#{hostname}".to_sym
    task_sym = "_do_task_#{name.to_s}_#{hostname}".to_sym
    task_syms << task_sym
    role role_sym, hostname
    task task_sym, :roles => role_sym, &block
  end
  task name do
    task_syms.each do |t|
      self.send t
    end
  end
end


Here is an example. Note the syntax is just the same as Capistrano's "task".
serial_task :pwd, :roles => web do
  run "pwd"
end

Deploy script for rails applications under version control

#!/usr/bin/env ruby

require 'yaml'
require 'rubygems'
require_gem 'net-ssh'

$stdout.sync = true

def help
  puts <<-USAGE
This tool allows you to conviniently deploy your projects on production
or staging servers.

  Useage:
    deploy <target>
    Please specify configuration in ~/.deployrc
    
  Example:  
    
    example ~/.deployrc:   
    
      hieraki:
        server: linux
        get: svn export svn://myserver/hieraki/trunk
        directory: /var/www/applications/hieraki
        test: RAILS_ENV=production rake

        after_test:
          - chmod 777 log/
          - chmod 666 log/*

        after_commit:
          - sudo /etc/init.d/apache reload    

  Note: 
  
    server, get and directory are required
    
    available hooks are
      - after_connect
      - after_deploy
      - after_test
      - after_commit
        
  USAGE
  exit
end

def do_exec(cmd)
  print "\n\n  #{cmd}\n    "
  
  stderr = ""
  $session.process.open( cmd ) do |cmd|
    cmd.on_exit do |p, status|
      if status == 0
        print "[done]\n" 
      else
        puts "    #{stderr}"        
        print "[failed]\n" 
        exit
      end
    end
    
    cmd.on_stderr do |p, data|
      stderr << data.gsub(/\n/, "\n    ")
    end    
    cmd.on_stdout do |p, data|
      STDOUT << data.gsub(/\n/, "\n    ")
    end                
  end  
end

# Batch jobs

def deploy
  puts      "\ndeploying"  

  print     "  creating dirs"
  do_exec   "mkdir -p #{$config['directory']}" 

  print     "  get"
  do_exec   "#{$config['get']} #{$config['deploy']}"
end

def test
  puts      "\ntesting"  
  do_exec   "cd #{$config['deploy']}; #{$config['test']}"
end

def commit
  puts      "\ncomitting"
  print     "  creating new link"
  do_exec   "ln -nfs #{$config['deploy']}/ #{$config['target']}"
end

def run_tasks(tasks)
  $config[tasks].to_a.each do |task|    
    do_exec "cd #{$config['deploy']}; #{task}" 
  end
end


app_name = ARGV[0] || help
$config = YAML::load(File.open(File.expand_path("~/.deployrc")))[app_name]

# compute deploy directory 
$config['deploy'] = $config['directory'] + "/#{Time.now.strftime("%Y%m%d-%H%M")}"
# compute target directory 
$config['target'] = $config['directory'] + "/latest"

puts "deploying #{app_name} to #{$config["server"]}"

$session = Net::SSH.start( $config["server"] )

run_tasks("after_connect")  
deploy
run_tasks("after_deploy")
test
run_tasks("after_test")
commit
run_tasks("after_commit")
puts ""
puts "success!"
« Newer Snippets
Older Snippets »
Showing 1-2 of 2 total  RSS