gramos-robbie 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt ADDED
@@ -0,0 +1 @@
1
+ = robbie
@@ -0,0 +1,125 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+ module Capistrano
4
+
5
+ class Logger
6
+
7
+ def ey_log(level, message, line_prefix = nil)
8
+ EYLogger.log(level, message, line_prefix) if EYLogger.setup?
9
+ log_without_ey_logging(level, message, line_prefix)
10
+ end
11
+
12
+ unless method_defined?(:log_without_ey_logging)
13
+ alias_method :log_without_ey_logging, :log
14
+ alias_method :log, :ey_log
15
+ end
16
+
17
+ def close
18
+ device.close if @needs_close
19
+ EYLogger.close if EYLogger.setup?
20
+ end
21
+ end
22
+
23
+ class EYLogger
24
+
25
+ # Sets up the EYLogger to beging capturing capistrano's logging. You should pass the capistrno configuration
26
+ # and the deploy type as a string. The deploy type is for reporting purposes only but must be included.
27
+ def self.setup(configuration, deploy_type, options = {})
28
+ @_configuration = configuration
29
+ @_deploy_type = deploy_type.gsub(/:/, "_")
30
+ @_log_path = options[:deploy_log_path] || Dir.tmpdir
31
+ @_log_path << "/" unless @_log_path =~ /\/$/
32
+ FileUtils.mkdir_p(@_log_path)
33
+ @_setup = true
34
+ @_success = true
35
+ end
36
+
37
+ def self.log(level, message, line_prefix=nil)
38
+ return nil unless setup?
39
+ @release_name = @_configuration[:release_name] if @release_name.nil?
40
+ @_log_file_path = @_log_path + @release_name + ".log" unless @_log_file_path
41
+ @_deploy_log_file = File.open(@_log_file_path, "w") if @_deploy_log_file.nil?
42
+
43
+ indent = "%*s" % [Logger::MAX_LEVEL, "*" * (Logger::MAX_LEVEL - level)]
44
+ message.each do |line|
45
+ if line_prefix
46
+ @_deploy_log_file << "#{indent} [#{line_prefix}] #{line.strip}\n"
47
+ else
48
+ @_deploy_log_file << "#{indent} #{line.strip}\n"
49
+ end
50
+ end
51
+ end
52
+
53
+ def self.post_process
54
+ unless ::Interrupt === $!
55
+ puts "\n\nPlease wait while the log file is processed\n"
56
+ # Should dump the stack trace of an exception if there is one
57
+ error = $!
58
+ unless error.nil?
59
+ @_deploy_log_file << error.message << "\n"
60
+ @_deploy_log_file << error.backtrace.join("\n")
61
+ @_success = false
62
+ end
63
+ self.close
64
+
65
+ hooks = [:any]
66
+ hooks << self.successful? ? :success : :failure
67
+ puts "Executing Post Processing Hooks"
68
+ hooks.each do |h|
69
+ @_post_process_hooks[h].each do |key|
70
+ @_configuration.parent.find_and_execute_task(key)
71
+ end
72
+ end
73
+ puts "Finished Post Processing Hooks"
74
+ end
75
+ end
76
+
77
+ # Adds a post processing hook.
78
+ #
79
+ # Provide a task name to execute. These tasks are executed after capistrano has actually run its course.
80
+ #
81
+ # Takes a key to control when the hook is executed.'
82
+ # :any - always executed
83
+ # :success - only execute on success
84
+ # :failure - only execute on failure
85
+ #
86
+ # ==== Example
87
+ # Capistrano::EYLogger.post_process_hook( "ey_logger:upload_log_to_slice", :any)
88
+ #
89
+ def self.post_process_hook(task, key = :any)
90
+ @_post_process_hooks ||= Hash.new{|h,k| h[k] = []}
91
+ @_post_process_hooks[key] << task
92
+ end
93
+
94
+ def self.setup?
95
+ !!@_setup
96
+ end
97
+
98
+ def self.deploy_type
99
+ @_deploy_type
100
+ end
101
+
102
+ def self.successful?
103
+ !!@_success
104
+ end
105
+
106
+ def self.failure?
107
+ !@_success
108
+ end
109
+
110
+ def self.log_file_path
111
+ @_log_file_path
112
+ end
113
+
114
+ def self.remote_log_file_name
115
+ @_log_file_name ||= "#{@_configuration[:release_name]}-#{@_deploy_type}-#{self.successful? ? "SUCCESS" : "FAILURE"}.log"
116
+ end
117
+
118
+ def self.close
119
+ @_deploy_log_file.flush unless @_deploy_log_file.nil?
120
+ @_deploy_log_file.close unless @_deploy_log_file.nil?
121
+ @_setup = false
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), "ey_logger")
2
+
3
+ # These tasks are setup to use with the logger as post commit hooks.
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ namespace :ey_logger do
6
+ task :upload_log_to_slice, :except => { :no_release => true} do
7
+ logger = Capistrano::EYLogger
8
+ run "mkdir -p #{shared_path}/deploy_logs"
9
+ put File.open(logger.log_file_path).read, "#{shared_path}/deploy_logs/#{logger.remote_log_file_name}"
10
+ end
11
+ end
12
+ end
13
+
14
+ Capistrano::EYLogger.post_process_hook("ey_logger:upload_log_to_slice")
@@ -0,0 +1,59 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ ##########################################################################
4
+ # ADMIN and MONITORING
5
+
6
+ namespace :admin do
7
+
8
+ desc "tail log files"
9
+ task :tail_logs, :roles => :app do
10
+ run "tail -f #{shared_path}/log/*.log" do |channel, stream, data|
11
+ puts "\n\n"# for an extra line break before the host name
12
+ puts "#{channel[:host]}: #{data}"
13
+ break if stream == :err
14
+ end
15
+ end
16
+
17
+ desc "show server conections"
18
+ task :netstat, :roles => :app do
19
+ run "netstat -a" do |channel, stream, data|
20
+ puts "\n\n"# for an extra line break before the host name
21
+ puts "#{data}"
22
+ break if stream == :err
23
+ end
24
+ end
25
+
26
+ desc 'Pone los permisos necesarios para la carpeta de la app'
27
+ task :set_perms, :roles => :app do
28
+ sudo "chown -R #{user}:#{mongrel_group} #{deploy_to}/"
29
+ sudo "chmod 774 -R #{deploy_to}"
30
+ end
31
+
32
+ ###############################################################################
33
+ # SETUP SSH
34
+
35
+ desc "Copies contents of ssh public keys into authorized_keys file"
36
+ task :setup_ssh_keys do
37
+
38
+ unless ssh_options[:keys]
39
+ puts <<-ERROR
40
+
41
+ You need to define the name of your SSH key(s)
42
+ e.g. ssh_options[:keys] = %w(/Users/someuser/.ssh/id_dsa)
43
+
44
+ You can put this in your .caprc file in your home directory.
45
+
46
+ ERROR
47
+ exit
48
+ end
49
+
50
+ sudo "test -d ~/.ssh || mkdir ~/.ssh"
51
+ sudo "chmod 0700 ~/.ssh"
52
+ put(ssh_options[:keys].collect{|key| File.read(key+'.pub')}.join("\n"),
53
+ File.join('/home', user, '.ssh/authorized_keys'),
54
+ :mode => 0600 )
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,25 @@
1
+ Capistrano::Configuration.instance.load do
2
+
3
+ #############################################################################
4
+ # ASSETS
5
+
6
+ namespace :assets do
7
+ task :symlink, :roles => :app do
8
+ assets.create_dirs
9
+ run <<-CMD
10
+ rm -rf #{release_path}/public/uploads;
11
+ rm -rf #{release_path}/public/images/avatars;
12
+ ln -nfs #{shared_path}/uploads #{release_path}/public/uploads;
13
+ ln -nfs #{shared_path}/avatars #{release_path}/public/images/avatars;
14
+ CMD
15
+ end
16
+ task :create_dirs, :roles => :app do
17
+ %w(uploads avatars).each do |name|
18
+ run "mkdir -p #{shared_path}/#{name}; true"
19
+ end
20
+ end
21
+ end
22
+
23
+ after "deploy:update_code" , "assets:symlink"
24
+
25
+ end
@@ -0,0 +1,23 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :bdrb do
4
+ desc "After update_code you want to reindex"
5
+ task :reindex, :roles => [:app], :only => {:backgroundrb => true} do
6
+ run "/engineyard/bin/searchd #{application} reindex"
7
+ end
8
+
9
+ desc "Start Backgroundrb"
10
+ task :start, :roles => [:app], :only => {:backgroundrb => true} do
11
+ sudo "/usr/bin/monit start all -g backgroundrb_#{application}"
12
+ end
13
+ desc "Stop Backgroundrb"
14
+ task :stop, :roles => [:app], :only => {:backgroundrb => true} do
15
+ sudo "/usr/bin/monit stop all -g backgroundrb_#{application}"
16
+ end
17
+ desc "Restart Backgroundrb"
18
+ task :restart, :roles => [:app], :only => {:backgroundrb => true} do
19
+ sudo "/usr/bin/monit restart all -g backgroundrb_#{application}"
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,98 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :db do
4
+ task :backup_name, :roles => :db, :only => { :primary => true } do
5
+ now = Time.now
6
+ run "mkdir -p #{shared_path}/db_backups"
7
+ backup_time = [now.year,now.month,now.day,now.hour,now.min,now.sec].join('-')
8
+ set :backup_file, "#{shared_path}/db_backups/#{environment_database}-snapshot-#{backup_time}.sql"
9
+ end
10
+
11
+ desc "Clone Production Database to Staging Database."
12
+ task :clone_prod_to_staging, :roles => :db, :only => { :primary => true } do
13
+ backup_name
14
+ on_rollback { run "rm -f #{backup_file}" }
15
+ run("cat #{shared_path}/config/database.yml") { |channel, stream, data| @environment_info = YAML.load(data)[rails_env] }
16
+ if @environment_info['adapter'] == 'mysql'
17
+ run "mysqldump --add-drop-table -u #{dbuser} -h #{production_dbhost.gsub('-master', '-replica')} -p#{dbpass} #{production_database} > #{backup_file}"
18
+ run "mysql -u #{dbuser} -p#{dbpass} -h #{staging_dbhost} #{staging_database} < #{backup_file}"
19
+ else
20
+ run "PGPASSWORD=#{dbpass} pg_dump -c -U #{dbuser} -h #{production_dbhost} -f #{backup_file} #{production_database}"
21
+ run "PGPASSWORD=#{dbpass} psql -U #{dbuser} -h #{staging_dbhost} -f #{backup_file} #{staging_database}"
22
+ end
23
+ run "rm -f #{backup_file}"
24
+ end
25
+
26
+ desc "Backup your MySQL or PostgreSQL database to shared_path+/db_backups"
27
+ task :dump, :roles => :db, :only => {:primary => true} do
28
+ backup_name
29
+ run("cat #{shared_path}/config/database.yml") { |channel, stream, data| @environment_info = YAML.load(data)[rails_env] }
30
+ if @environment_info['adapter'] == 'mysql'
31
+ run "mysqldump --add-drop-table -u #{dbuser} -h #{environment_dbhost.gsub('-master', '-replica')} -p#{dbpass} #{environment_database} | bzip2 -c > #{backup_file}.bz2"
32
+ else
33
+ run "PGPASSWORD=#{dbpass} pg_dump -c -U #{dbuser} -h #{environment_dbhost} #{environment_database} | bzip2 -c > #{backup_file}.bz2"
34
+ end
35
+ end
36
+
37
+ desc "Sync your production database to your local workstation"
38
+ task :clone_to_local, :roles => :db, :only => {:primary => true} do
39
+ backup_name
40
+ dump
41
+ get "#{backup_file}.bz2", "/tmp/#{application}.sql.gz"
42
+ development_info = YAML.load_file("config/database.yml")['development']
43
+ if development_info['adapter'] == 'mysql'
44
+ run_str = "bzcat /tmp/#{application}.sql.gz | mysql -u #{development_info['username']} -p#{development_info['password']} -h #{development_info['host']} #{development_info['database']}"
45
+ else
46
+ run_str = "PGPASSWORD=#{development_info['password']} bzcat /tmp/#{application}.sql.gz | psql -U #{development_info['username']} -h #{development_info['host']} #{development_info['database']}"
47
+ end
48
+ %x!#{run_str}!
49
+ end
50
+ end
51
+
52
+ ###########################################################################
53
+ # DATABASE YAML
54
+
55
+ # after "deploy:setup", :db
56
+ # after "deploy:update_code", "db:symlink"
57
+
58
+ namespace :db do
59
+
60
+ desc "Create database yaml in shared path"
61
+ task :default do
62
+ db_config = ERB.new <<-EOF
63
+ base: &base
64
+ adapter: mysql
65
+ username: #{runner}
66
+ password: #{password}
67
+ host: 127.0.0.1
68
+
69
+ development:
70
+ database: #{db_name}_dev
71
+ <<: *base
72
+
73
+ test:
74
+ database: #{db_name}_test
75
+ <<: *base
76
+
77
+ production:
78
+ database: #{db_name}_prod
79
+ shooting_star:
80
+ server: #{shoot_server}:#{shoot_server_port}
81
+ shooter: druby://localhost:#{shoot_drb_port}
82
+ <<: *base
83
+ EOF
84
+
85
+ sudo "mkdir -p #{shared_path}/config"
86
+ sudo "chown -R #{user}:#{mongrel_group} #{deploy_to}/"
87
+ sudo "chmod 774 -R #{shared_path}/config"
88
+ put db_config.result, "#{shared_path}/config/database.yml"
89
+ end
90
+
91
+ desc "Make symlink for database yaml"
92
+ task :symlink do
93
+ run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,128 @@
1
+ require File.join(File.dirname(__FILE__), "..", "lib", "ey_logger.rb")
2
+ Capistrano::Configuration.instance(:must_exist).load do
3
+
4
+ namespace :deploy do
5
+ # This is here to hook into the logger for deploy and deploy:long tasks
6
+ ["deploy", "deploy:long"].each do |tsk|
7
+ before(tsk) do
8
+ Capistrano::EYLogger.setup( self, tsk )
9
+ at_exit{ Capistrano::EYLogger.post_process if Capistrano::EYLogger.setup? }
10
+ end
11
+ end
12
+
13
+ desc "Link the database.yml and mongrel_cluster.yml files into the current release path."
14
+ task :symlink_configs, :roles => :app, :except => {:no_release => true} do
15
+ run <<-CMD
16
+ cd #{latest_release} &&
17
+ ln -nfs #{shared_path}/config/database.yml #{latest_release}/config/database.yml &&
18
+ ln -nfs #{shared_path}/config/mongrel_cluster.yml #{latest_release}/config/mongrel_cluster.yml
19
+ CMD
20
+ end
21
+
22
+ desc <<-DESC
23
+ Run the migrate rake task. By default, it runs this in most recently \
24
+ deployed version of the app. However, you can specify a different release \
25
+ via the migrate_target variable, which must be one of :latest (for the \
26
+ default behavior), or :current (for the release indicated by the \
27
+ `current' symlink). Strings will work for those values instead of symbols, \
28
+ too. You can also specify additional environment variables to pass to rake \
29
+ via the migrate_env variable. Finally, you can specify the full path to the \
30
+ rake executable by setting the rake variable. The defaults are:
31
+
32
+ set :rake, "rake"
33
+ set :framework, "merb"
34
+ set :merb_env, "production"
35
+ set :migrate_env, ""
36
+ set :migrate_target, :latest
37
+ DESC
38
+ task :migrate, :roles => :db, :only => { :primary => true } do
39
+ rake = fetch(:rake, "rake")
40
+
41
+ framework = fetch(:framework, "rails")
42
+ if framework.match(/^rails$/i)
43
+ app_env = fetch(:rails_env, "production")
44
+ else
45
+ app_env = fetch("#{framework.downcase}_env".to_sym, "production")
46
+ end
47
+
48
+ migrate_env = fetch(:migrate_env, "")
49
+ migrate_target = fetch(:migrate_target, :latest)
50
+
51
+ directory = case migrate_target.to_sym
52
+ when :current then current_path
53
+ when :latest then current_release
54
+ else raise ArgumentError, "unknown migration target #{migrate_target.inspect}"
55
+ end
56
+
57
+ run "cd #{directory}; #{rake} #{framework.upcase}_ENV=#{app_env} #{migrate_env} db:migrate"
58
+ end
59
+
60
+ desc "Display the maintenance.html page while deploying with migrations. Then it restarts and enables the site again."
61
+ task :long do
62
+ transaction do
63
+ update_code
64
+ web.disable
65
+ symlink
66
+ migrate
67
+ end
68
+
69
+ restart
70
+ web.enable
71
+ end
72
+
73
+ desc "Restart the Mongrel processes on the app slices."
74
+ task :restart, :roles => :app do
75
+ mongrel.restart
76
+ end
77
+
78
+ desc "Start the Mongrel processes on the app slices."
79
+ task :spinner, :roles => :app do
80
+ mongrel.start
81
+ end
82
+
83
+ desc "Start the Mongrel processes on the app slices."
84
+ task :start, :roles => :app do
85
+ mongrel.start
86
+ end
87
+
88
+ desc "Stop the Mongrel processes on the app slices."
89
+ task :stop, :roles => :app do
90
+ mongrel.stop
91
+ end
92
+
93
+ namespace :web do
94
+ desc <<-DESC
95
+ Present a maintenance page to visitors. Disables your application's web \
96
+ interface by writing a "maintenance.html" file to each web server. The \
97
+ servers must be configured to detect the presence of this file, and if \
98
+ it is present, always display it instead of performing the request.
99
+
100
+ By default, the maintenance page will just say the site is down for \
101
+ "maintenance", and will be back "shortly", but you can customize the \
102
+ page by specifying the REASON and UNTIL environment variables:
103
+
104
+ $ cap deploy:web:disable \\
105
+ REASON="hardware upgrade" \\
106
+ UNTIL="12pm Central Time"
107
+
108
+ Further customization copy your html file to shared_path+'/system/maintenance.html.custom'.
109
+ If this file exists it will be used instead of the default capistrano ugly page
110
+ DESC
111
+ task :disable, :roles => :web, :except => { :no_release => true } do
112
+ maint_file = "#{shared_path}/system/maintenance.html"
113
+ require 'erb'
114
+ on_rollback { run "rm #{shared_path}/system/maintenance.html" }
115
+
116
+ reason = ENV['REASON']
117
+ deadline = ENV['UNTIL']
118
+
119
+ template = File.read(File.join(File.dirname(__FILE__), "templates", "maintenance.rhtml"))
120
+ result = ERB.new(template).result(binding)
121
+
122
+ put result, "#{shared_path}/system/maintenance.html.tmp", :mode => 0644
123
+ run "if [ -f #{shared_path}/system/maintenance.html.custom ]; then cp #{shared_path}/system/maintenance.html.custom #{maint_file}; else cp #{shared_path}/system/maintenance.html.tmp #{maint_file}; fi"
124
+ end
125
+ end
126
+ end
127
+
128
+ end
@@ -0,0 +1,20 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :ferret do
4
+ desc "After update_code you want to symlink the index and ferret_server.yml file into place"
5
+ task :symlink_configs, :roles => [:app], :except => {:no_release => true, :ferret => false} do
6
+ run <<-CMD
7
+ cd #{latest_release} &&
8
+ ln -nfs #{shared_path}/config/ferret_server.yml #{latest_release}/config/ferret_server.yml &&
9
+ if [ -d #{latest_release}/index ]; then mv #{latest_release}/index #{latest_release}/index.bak; fi &&
10
+ ln -nfs #{shared_path}/index #{latest_release}/index
11
+ CMD
12
+ end
13
+ [:start,:stop,:restart].each do |op|
14
+ desc "#{op} ferret server"
15
+ task op, :roles => [:app], :except => {:no_release => true, :ferret => false} do
16
+ sudo "/usr/bin/monit #{op} all -g ferret_#{application}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :juggernaut do
4
+ desc "After update_code you want to symlink the juggernaut.yml file into place"
5
+ task :symlink_configs, :roles => [:app], :except => {:no_release => true, :juggernaut => false} do
6
+ run <<-CMD
7
+ cd #{latest_release} &&
8
+ ln -nfs #{shared_path}/config/juggernaut.yml #{latest_release}/config/juggernaut.yml &&
9
+ ln -nfs #{shared_path}/config/juggernaut_hosts.yml #{latest_release}/config/juggernaut_hosts.yml
10
+ CMD
11
+ end
12
+ [:start,:stop,:restart].each do |op|
13
+ desc "#{op} juggernaut server"
14
+ task op, :roles => [:app], :except => {:no_release => true, :juggernaut => false} do
15
+ sudo "/usr/bin/monit #{op} all -g juggernaut_#{application}"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :memcached do
3
+ desc "Start memcached"
4
+ task :start, :roles => [:app], :only => {:memcached => true} do
5
+ sudo "/etc/init.d/memcached start"
6
+ end
7
+ desc "Stop memcached"
8
+ task :stop, :roles => [:app], :only => {:memcached => true} do
9
+ sudo "/etc/init.d/memcached stop"
10
+ end
11
+ desc "Restart memcached"
12
+ task :restart, :roles => [:app], :only => {:memcached => true} do
13
+ sudo "/etc/init.d/memcached restart"
14
+ end
15
+ desc "Symlink the memcached.yml file into place if it exists"
16
+ task :symlink_configs, :roles => [:app], :only => {:memcached => true }, :except => { :no_release => true } do
17
+ run "if [ -f #{shared_path}/config/memcached.yml ]; then ln -nfs #{shared_path}/config/memcached.yml #{latest_release}/config/memcached.yml; fi"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :mongrel do
3
+ desc <<-DESC
4
+ Start Mongrel processes on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
5
+ set to true.
6
+ DESC
7
+ task :start, :roles => [:app], :except => {:mongrel => false} do
8
+ sudo "/usr/bin/monit start all -g #{monit_group}"
9
+ end
10
+
11
+ desc <<-DESC
12
+ Restart the Mongrel processes on the app server by starting and stopping the cluster. This uses the :use_sudo
13
+ variable to determine whether to use sudo or not. By default, :use_sudo is set to true.
14
+ DESC
15
+ task :restart, :roles => [:app], :except => {:mongrel => false} do
16
+ sudo "/usr/bin/monit restart all -g #{monit_group}"
17
+ end
18
+
19
+ desc <<-DESC
20
+ Stop the Mongrel processes on the app server. This uses the :use_sudo
21
+ variable to determine whether to use sudo or not. By default, :use_sudo is
22
+ set to true.
23
+ DESC
24
+ task :stop, :roles => [:app], :except => {:mongrel => false} do
25
+ sudo "/usr/bin/monit stop all -g #{monit_group}"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,66 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ ##########################################################################
3
+ # monit
4
+
5
+ namespace :monit do
6
+ desc "Get the status of your mongrels"
7
+ task :status, :roles => :app do
8
+ @monit_output ||= { }
9
+ sudo "/usr/bin/monit status" do |channel, stream, data|
10
+ @monit_output[channel[:server].to_s] ||= [ ]
11
+ @monit_output[channel[:server].to_s].push(data.chomp)
12
+ end
13
+ @monit_output.each do |k,v|
14
+ puts "#{k} -> #{'*'*55}"
15
+ puts v.join("\n")
16
+ end
17
+ end
18
+
19
+
20
+
21
+
22
+ desc "reload monit server"
23
+ task :reload do
24
+ run "sudo /etc/init.d/monit force-reload"
25
+ end
26
+
27
+ desc "Create monit file in /etc/monit.d/ror-apps/"
28
+ task :default do
29
+ monit_config_str = ""
30
+ cluster_mongrel_port = mongrel_port.to_i
31
+
32
+ cluster_mongrel_port.upto(cluster_mongrel_port + mongrel_servers - 1) {|cluster_port|
33
+ monit_config_str += <<-EOF
34
+
35
+ ###############################################################################################
36
+ # #{application}
37
+
38
+ check process mongrel_#{cluster_port} with pidfile #{shared_path}/pids/mongrel.#{cluster_port}.pid
39
+ start program = "/usr/bin/mongrel_rails cluster::start -C #{mongrel_conf} --clean --only #{cluster_port}"
40
+ stop program = "/usr/bin/mongrel_rails cluster::stop -C #{mongrel_conf} --clean --only #{cluster_port}"
41
+
42
+ if failed host 127.0.0.1 port #{cluster_port} protocol http
43
+ with timeout 10 seconds
44
+ then restart
45
+
46
+ if totalmem > 100 Mb then restart
47
+ if cpu is greater than 90% for 2 cycles then alert
48
+ if cpu > 90% for 5 cycles then restart
49
+ if loadavg(5min) greater than 10 for 8 cycles then restart
50
+ if 5 restarts within 5 cycles then timeout
51
+ group mongrel-#{application}
52
+ EOF
53
+ }
54
+
55
+ monit_config = ERB.new(monit_config_str)
56
+ sudo "mkdir -p /etc/monit.d/ror-apps/"
57
+ sudo "chown -R #{user}:#{mongrel_group} /etc/monit.d/ror-apps/"
58
+ sudo "chmod 774 -R /etc/monit.d/ror-apps/"
59
+ put monit_config.result, "/etc/monit.d/ror-apps/#{application}"
60
+ end
61
+
62
+ end
63
+
64
+
65
+ end
66
+
@@ -0,0 +1,127 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ ######################################################################################
4
+ # NGINX
5
+
6
+ namespace :nginx do
7
+ desc "Start Nginx on the app slices."
8
+ task :start, :roles => :app do
9
+ sudo "/etc/init.d/nginx start"
10
+ end
11
+
12
+ desc "Restart the Nginx processes on the app slices."
13
+ task :restart , :roles => :app do
14
+ sudo "/etc/init.d/nginx restart"
15
+ end
16
+
17
+ desc "Stop the Nginx processes on the app slices."
18
+ task :stop , :roles => :app do
19
+ sudo "/etc/init.d/nginx stop"
20
+ end
21
+
22
+ desc "Tail the nginx access logs for this application"
23
+ task :tail, :roles => :app do
24
+ run "tail -f /var/log/engineyard/nginx/#{application}.access.log" do |channel, stream, data|
25
+ puts "#{channel[:server]}: #{data}" unless data =~ /^10\.[01]\.0/ # skips lb pull pages
26
+ break if stream == :err
27
+ end
28
+ end
29
+
30
+ desc "Tail the nginx error logs on the app slices"
31
+ task :tail_error, :roles => :app do
32
+ run "tail -f /var/log/engineyard/nginx/error.log" do |channel, stream, data|
33
+ puts "#{channel[:server]}: #{data}" unless data =~ /^10\.[01]\.0/ # skips lb pull pages
34
+ break if stream == :err
35
+ end
36
+ end
37
+
38
+ @nginx_path = "/etc/nginx"
39
+ @tmp = "/tmp"
40
+ @enabled_path = "#{@nginx_path}/sites-enabled"
41
+ @available_path = "#{@nginx_path}/sites-available"
42
+
43
+ desc 'Habilita un host virtual'
44
+ task :en_vhost do
45
+ sudo "test -L #{@available_path}/#{application} || sudo ln -s #{@available_path}/#{application}; true " +
46
+ "#{@enabled_path}/#{application}"
47
+ end
48
+
49
+ desc 'Deshabilita un host virtual'
50
+ task :dis_vhost do
51
+ sudo "rm -f #{@enabled_path}/#{application}"
52
+ end
53
+
54
+ desc 'Hace un reload del nginx'
55
+ task :reload do
56
+ sudo "/etc/init.d/nginx reload"
57
+ end
58
+
59
+ desc "Agrega una vhost para nginx"
60
+ task :add_vhost do
61
+ nginx_config = ERB.new <<-EOF
62
+ upstream mongrel-#{application} {
63
+ server 127.0.0.1:#{mongrel_port};
64
+ server 127.0.0.1:#{mongrel_port.to_i + 1};
65
+ }
66
+ server {
67
+ listen 80;
68
+ server_name #{nginx_server_name};
69
+ root #{deploy_to}/current/public;
70
+ index index.html index.htm;
71
+
72
+ access_log /var/log/nginx/localhost.access.log;
73
+
74
+ location / {
75
+ index index.html index.htm;
76
+ proxy_set_header X-Real-IP $remote_addr;
77
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
78
+ proxy_set_header Host $http_host;
79
+ proxy_redirect false;
80
+
81
+ # If the file exists as a static file serve it directly without
82
+ # running all the other rewite tests on it
83
+ if (-f $request_filename) {
84
+ break;
85
+ }
86
+
87
+ if (-f $request_filename/index.html) {
88
+ rewrite (.*) $1/index.html break;
89
+ }
90
+
91
+ if (-f $request_filename.html) {
92
+ rewrite (.*) $1.html break;
93
+ }
94
+
95
+ if (!-f $request_filename) {
96
+ proxy_pass http://mongrel-#{application};
97
+ break;
98
+ }
99
+
100
+ }
101
+
102
+ #error_page 404 /404.html;
103
+
104
+ # redirect server error pages to the static page /50x.html
105
+ #
106
+ error_page 500 502 503 504 /500.html;
107
+ location = /500.html {
108
+ root #{deploy_to}/current/public/;
109
+ }
110
+
111
+ }
112
+ EOF
113
+ sudo "test -d #{@nginx_path}/sites-available || mkdir #{@nginx_path}/sites-available"
114
+ sudo "test -d #{@nginx_path}/sites-enabled || mkdir #{@nginx_path}/sites-enabled"
115
+ put nginx_config.result, "#{@tmp}/#{application}"
116
+ sudo "cp #{@tmp}/#{application} #{@nginx_path}/sites-available/#{application}"
117
+ sudo "rm #{@tmp}/#{application}"
118
+ end
119
+
120
+ end
121
+
122
+ # after "nginx:add_vhost", "nginx:en_vhost"
123
+ # after "deploy:cold", "nginx:add_vhost"
124
+ # after "deploy:cold", "nginx:reload"
125
+ end
126
+
127
+
@@ -0,0 +1,49 @@
1
+ require 'erb'
2
+
3
+ Capistrano::Configuration.instance.load do
4
+
5
+ ##########################################################################
6
+ # shoot_star for CHAT system
7
+
8
+ namespace :shooting_star do
9
+
10
+ desc "start shoot_star server"
11
+ task :start do
12
+ run "cd #{latest_release} && sudo nohup shooting_star start -d"
13
+ end
14
+
15
+ desc "stop shoot_star server"
16
+ task :stop do
17
+ run "cd #{latest_release} && sudo shooting_star stop"
18
+ end
19
+
20
+ desc "restart shoot_star server"
21
+ task :restart do
22
+ stop
23
+ start
24
+ end
25
+
26
+ desc "Create shooting_star yaml in shared path"
27
+ task :default do
28
+ shoot_config = ERB.new <<-EOF
29
+ server:
30
+ host: 0.0.0.0
31
+ port: #{shoot_server_port}
32
+ shooter:
33
+ uri: druby://0.0.0.0:#{shoot_drb_port}
34
+ EOF
35
+
36
+ sudo "mkdir -p #{shared_path}/config"
37
+ sudo "chown -R #{user}:#{mongrel_group} #{deploy_to}/"
38
+ sudo "chmod 774 -R #{shared_path}/config"
39
+ put shoot_config.result, "#{shared_path}/config/shooting_star.yml"
40
+ end
41
+
42
+ desc "Make symlink for shooting star yaml"
43
+ task :symlink do
44
+ run "ln -nfs #{shared_path}/config/shooting_star.yml #{release_path}/config/shooting_star.yml"
45
+ end
46
+ end
47
+
48
+
49
+ end
@@ -0,0 +1,21 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :slice do
4
+ desc "Tail the Rails production log for this environment"
5
+ task :tail_production_logs, :roles => :app do
6
+ run "tail -f #{shared_path}/log/#{rails_env}.log" do |channel, stream, data|
7
+ puts # for an extra line break before the host name
8
+ puts "#{channel[:server]} -> #{data}"
9
+ break if stream == :err
10
+ end
11
+ end
12
+ desc "Tail the Mongrel logs this environment"
13
+ task :tail_mongrel_logs, :roles => :app do
14
+ run "tail -f #{shared_path}/log/mongrel*.log" do |channel, stream, data|
15
+ puts # for an extra line break before the host name
16
+ puts "#{channel[:server]} -> #{data}"
17
+ break if stream == :err
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :solr do
4
+ desc "After update_code you want to symlink the index and ferret_server.yml file into place"
5
+ task :symlink_configs, :roles => [:app], :except => {:no_release => true} do
6
+ run <<-CMD
7
+ cd #{latest_release} && ln -nfs #{shared_path}/config/solr.yml #{latest_release}/config/solr.yml
8
+ CMD
9
+ end
10
+
11
+ [:start,:stop,:restart].each do |op|
12
+ desc "#{op} ferret server"
13
+ task op, :roles => [:app], :only => {:solr => true} do
14
+ sudo "/usr/bin/monit #{op} all -g solr_#{application}"
15
+ end
16
+ end
17
+
18
+ namespace :tail do
19
+ desc "Tail the Solr logs this environment"
20
+ task :logs, :roles => [:app], :only => {:solr => true} do
21
+ run "tail -f /var/log/engineyard/solr/#{application}.log" do |channel, stream, data|
22
+ puts # for an extra line break before the host name
23
+ puts "#{channel[:server]} -> #{data}"
24
+ break if stream == :err
25
+ end
26
+ end
27
+ desc "Tail the Solr error logs this environment"
28
+ task :errors, :roles => [:app], :only => {:solr => true} do
29
+ run "tail -f /var/log/engineyard/solr/#{application}.err.log" do |channel, stream, data|
30
+ puts # for an extra line break before the host name
31
+ puts "#{channel[:server]} -> #{data}"
32
+ break if stream == :err
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,76 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ namespace :sphinx do
4
+ desc "After update_code you want to configure, then reindex"
5
+ task :configure, :roles => [:app], :only => {:sphinx => true}, :except => {:no_release => true} do
6
+ run "/engineyard/bin/searchd #{application} configure"
7
+ end
8
+
9
+ desc "After configure you want to reindex"
10
+ task :reindex, :roles => [:app], :only => {:sphinx => true} do
11
+ run "/engineyard/bin/searchd #{application} reindex"
12
+ end
13
+
14
+ desc "Start Sphinx Searchd"
15
+ task :start, :roles => [:app], :only => {:sphinx => true} do
16
+ sudo "/usr/bin/monit start all -g sphinx_#{application}"
17
+ end
18
+
19
+ desc "Stop Sphinx Searchd"
20
+ task :stop, :roles => [:app], :only => {:sphinx => true} do
21
+ sudo "/usr/bin/monit stop all -g sphinx_#{application}"
22
+ end
23
+
24
+ desc "Restart Sphinx Searchd"
25
+ task :restart, :roles => [:app], :only => {:sphinx => true} do
26
+ sudo "/usr/bin/monit restart all -g sphinx_#{application}"
27
+ end
28
+
29
+ task :symlink, :roles => [:app], :only => {:sphinx => true}, :except => {:no_release => true} do
30
+ run "if [ -d #{latest_release}/config/ultrasphinx ]; then mv #{latest_release}/config/ultrasphinx #{latest_release}/config/ultrasphinx.bak; fi"
31
+ run "ln -nfs #{shared_path}/config/ultrasphinx #{latest_release}/config/ultrasphinx"
32
+ end
33
+ end
34
+
35
+ namespace :acts_as_sphinx do
36
+ desc "After update_code you to to reindex"
37
+ task :reindex, :roles => [:app], :only => {:sphinx => true} do
38
+ run "/engineyard/bin/acts_as_sphinx_searchd #{application} reindex"
39
+ end
40
+ end
41
+
42
+ namespace :thinking_sphinx do
43
+ desc "After update_code you want to configure, then reindex"
44
+ task :configure, :roles => [:app], :only => {:sphinx => true}, :except => {:no_release => true} do
45
+ run "/engineyard/bin/thinking_sphinx_searchd #{application} configure"
46
+ end
47
+
48
+ desc "After configure you want to reindex"
49
+ task :reindex, :roles => [:app], :only => {:sphinx => true} do
50
+ run "/engineyard/bin/thinking_sphinx_searchd #{application} reindex"
51
+ end
52
+
53
+ task :symlink, :roles => [:app], :only => {:sphinx => true}, :except => {:no_release => true} do
54
+ run "if [ -d #{latest_release}/config/thinkingsphinx ]; then mv #{latest_release}/config/thinkingsphinx #{latest_release}/config/thinkingsphinx.bak; fi"
55
+ run "ln -nfs #{shared_path}/config/thinkingsphinx #{latest_release}/config/thinkingsphinx"
56
+ run "ln -nfs #{shared_path}/config/sphinx.yml #{latest_release}/config/sphinx.yml"
57
+ end
58
+ end
59
+
60
+ namespace :ultrasphinx do
61
+ desc "After update_code you want to configure, then reindex"
62
+ task :configure, :roles => [:app], :only => {:sphinx => true}, :except => {:no_release => true} do
63
+ run "/engineyard/bin/ultrasphinx_searchd #{application} configure"
64
+ end
65
+
66
+ desc "After configure you want to reindex"
67
+ task :reindex, :roles => [:app], :only => {:sphinx => true} do
68
+ run "/engineyard/bin/ultrasphinx_searchd #{application} reindex"
69
+ end
70
+
71
+ task :symlink, :roles => [:app], :only => {:sphinx => true}, :except => {:no_release => true} do
72
+ run "if [ -d #{latest_release}/config/ultrasphinx ]; then mv #{latest_release}/config/ultrasphinx #{latest_release}/config/ultrasphinx.bak; fi"
73
+ run "ln -nfs #{shared_path}/config/ultrasphinx #{latest_release}/config/ultrasphinx"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,53 @@
1
+
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+
7
+ <head>
8
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
9
+ <title>System down for maintenance</title>
10
+
11
+ <style type="text/css">
12
+ div.outer {
13
+ position: absolute;
14
+ left: 50%;
15
+ top: 50%;
16
+ width: 500px;
17
+ height: 300px;
18
+ margin-left: -260px;
19
+ margin-top: -150px;
20
+ }
21
+
22
+ .DialogBody {
23
+ margin: 0;
24
+ padding: 10px;
25
+ text-align: left;
26
+ border: 1px solid #ccc;
27
+ border-right: 1px solid #999;
28
+ border-bottom: 1px solid #999;
29
+ background-color: #fff;
30
+ }
31
+
32
+ body { background-color: #fff; }
33
+ </style>
34
+ </head>
35
+
36
+ <body>
37
+
38
+ <div class="outer">
39
+ <div class="DialogBody" style="text-align: center;">
40
+ <div style="text-align: center; width: 200px; margin: 0 auto;">
41
+ <p style="color: red; font-size: 16px; line-height: 20px;">
42
+ The system is down for <%= reason ? reason : "maintenance" %>
43
+ as of <%= Time.now.strftime("%H:%M %Z") %>.
44
+ </p>
45
+ <p style="color: #666;">
46
+ It'll be back <%= deadline ? deadline : "shortly" %>.
47
+ </p>
48
+ </div>
49
+ </div>
50
+ </div>
51
+
52
+ </body>
53
+ </html>
@@ -0,0 +1,16 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :tomcat do
3
+ desc "Start tomcat"
4
+ task :start, :roles => [:app], :only => {:tomcat => true} do
5
+ sudo "/etc/init.d/tomcat start"
6
+ end
7
+ desc "Stop tomcat"
8
+ task :stop, :roles => [:app], :only => {:tomcat => true} do
9
+ sudo "/etc/init.d/tomcat stop"
10
+ end
11
+ desc "Restart tomcat"
12
+ task :restart, :roles => [:app], :only => {:tomcat => true} do
13
+ sudo "/etc/init.d/tomcat restart"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ require 'robbie/lib/ey_logger'
2
+ require 'robbie/lib/ey_logger_hooks'
3
+ require 'robbie/recipes/database'
4
+ require 'robbie/recipes/assets'
5
+ require 'robbie/recipes/shooting_star'
6
+ require 'robbie/recipes/ferret'
7
+ require 'robbie/recipes/mongrel'
8
+ require 'robbie/recipes/nginx'
9
+ require 'robbie/recipes/slice'
10
+ require 'robbie/recipes/deploy'
11
+ require 'robbie/recipes/sphinx'
12
+ require 'robbie/recipes/backgroundrb'
13
+ require 'robbie/recipes/memcached'
14
+ require 'robbie/recipes/solr'
15
+ require 'robbie/recipes/monit'
16
+ require 'robbie/recipes/tomcat'
17
+ require 'robbie/recipes/juggernaut'
18
+
19
+ Capistrano::Configuration.instance(:must_exist).load do
20
+
21
+ default_run_options[:pty] = true if respond_to?(:default_run_options)
22
+ set :keep_releases, 3
23
+ set :runner, defer { user }
24
+
25
+ end
@@ -0,0 +1,10 @@
1
+ module Robbie
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ self
9
+ end
10
+ end
data/lib/robbie.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Robbie
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gramos-robbie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - "Gast\xF3n Ramos"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-06 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: capistrano
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.2.0
23
+ version:
24
+ description: A bunch of useful recipes (based on eycap) to help deployment
25
+ email: ramos.gaston@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/robbie
34
+ - lib/robbie/lib
35
+ - lib/robbie/lib/ey_logger.rb
36
+ - lib/robbie/lib/ey_logger_hooks.rb
37
+ - lib/robbie/recipes
38
+ - lib/robbie/recipes/backgroundrb.rb
39
+ - lib/robbie/recipes/database.rb
40
+ - lib/robbie/recipes/deploy.rb
41
+ - lib/robbie/recipes/ferret.rb
42
+ - lib/robbie/recipes/juggernaut.rb
43
+ - lib/robbie/recipes/memcached.rb
44
+ - lib/robbie/recipes/mongrel.rb
45
+ - lib/robbie/recipes/monit.rb
46
+ - lib/robbie/recipes/nginx.rb
47
+ - lib/robbie/recipes/slice.rb
48
+ - lib/robbie/recipes/solr.rb
49
+ - lib/robbie/recipes/sphinx.rb
50
+ - lib/robbie/recipes/templates
51
+ - lib/robbie/recipes/templates/maintenance.rhtml
52
+ - lib/robbie/recipes/tomcat.rb
53
+ - lib/robbie/recipes/shooting_star.rb
54
+ - lib/robbie/recipes/admin.rb
55
+ - lib/robbie/recipes/assets.rb
56
+ - lib/robbie/recipes.rb
57
+ - lib/robbie/version.rb
58
+ - lib/robbie.rb
59
+ - README.txt
60
+ has_rdoc: true
61
+ homepage: ""
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project: robbie
82
+ rubygems_version: 1.2.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: Capistrano tasks
86
+ test_files: []
87
+