marcosgz-cap-recipe 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +1 -0
- data/README.md +7 -0
- data/Rakefile +4 -0
- data/lib/capistrano/recipe.rb +4 -0
- data/lib/capistrano/recipes/application.rb +75 -0
- data/lib/capistrano/recipes/database.rb +64 -0
- data/lib/capistrano/recipes/mailer.rb +32 -0
- data/lib/capistrano/recipes/newrelic.rb +213 -0
- data/lib/capistrano/recipes/passenger.rb +72 -0
- data/lib/capistrano/recipes/settler.rb +42 -0
- data/lib/capistrano/recipes/shards.rb +51 -0
- data/lib/capistrano/recipes/thin.rb +64 -0
- data/lib/capistrano/recipes/tire.rb +33 -0
- data/lib/capistrano/recipes/unicorn.rb +116 -0
- data/lib/capistrano/recipes/uploader.rb +36 -0
- data/marcosgz-cap-recipe.gemspec +21 -0
- metadata +95 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
source "http://rubygems.org"
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
set :app_setup_defaults, %w(app:create:dirs app:create:application_server db:setup)
|
4
|
+
set :app_setup_aditional, [] unless exists?(:app_setup_aditional)
|
5
|
+
|
6
|
+
set :user, 'app' unless exists?(:user)
|
7
|
+
set :group, 'app' unless exists?(:group)
|
8
|
+
|
9
|
+
namespace :app do
|
10
|
+
task :setup, :roles => :app do
|
11
|
+
(fetch(:app_setup_defaults)+fetch(:app_setup_aditional)).each do |name|
|
12
|
+
if (t=top.find_task(name))
|
13
|
+
execute_task(t)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
namespace :create do
|
20
|
+
task :dirs, :roles => :app do
|
21
|
+
deploy.setup
|
22
|
+
commands = %w(config uploads backup bundle pids tmp/cache public/cache).map do |path|
|
23
|
+
"if [ ! -d '#{path}' ]; then mkdir -p #{path}; fi;"
|
24
|
+
end
|
25
|
+
run "cd #{shared_path}; #{commands.join(' ')}"
|
26
|
+
run "chmod 777 #{shared_path}/public/cache #{shared_path}/tmp/cache"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
task :application_server, :roles => :app do
|
31
|
+
# App Server
|
32
|
+
case fetch(:app_server, nil)
|
33
|
+
when 'passenger'
|
34
|
+
passenger.setup
|
35
|
+
when 'unicorn'
|
36
|
+
unicorn.setup
|
37
|
+
unicorn.monit.setup
|
38
|
+
when 'thin'
|
39
|
+
thin.setup
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
namespace :destroy do
|
46
|
+
desc "Remove application directory"
|
47
|
+
task :all, :roles => :app do
|
48
|
+
set(:confirmed) do
|
49
|
+
puts <<-WARN
|
50
|
+
|
51
|
+
========================================================================
|
52
|
+
|
53
|
+
WARNING: You're about to remove the application directory:
|
54
|
+
"#{ deploy_to }"
|
55
|
+
|
56
|
+
========================================================================
|
57
|
+
|
58
|
+
WARN
|
59
|
+
answer = Capistrano::CLI.ui.ask " Are you sure you want to continue? (Yn) "
|
60
|
+
if answer == 'Y' then true else false end
|
61
|
+
end
|
62
|
+
|
63
|
+
if fetch(:confirmed)
|
64
|
+
passenger.remove
|
65
|
+
run "rm -Rf #{deploy_to}"
|
66
|
+
else
|
67
|
+
abort
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# db_setup_settings:
|
5
|
+
# common:
|
6
|
+
# host: 127.0.0.1
|
7
|
+
# database: db_name
|
8
|
+
|
9
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
10
|
+
set(:database_remote_file) { File.join(shared_path, 'config/database.yml') } unless exists?(:database_remote_file)
|
11
|
+
set(:database_template, 'database.yml.erb') unless exists?(:database_template)
|
12
|
+
|
13
|
+
def database_setup_defaults
|
14
|
+
{
|
15
|
+
'common' => {
|
16
|
+
'adapter' => fetch(:database_adapter, 'mysql2'),
|
17
|
+
'encoding' => fetch(:database_encoding, 'utf8'),
|
18
|
+
'reconnect' => fetch(:database_reconnect, false),
|
19
|
+
'pool' => fetch(:database_pool, 2),
|
20
|
+
'username' => fetch(:database_username) { user },
|
21
|
+
'password' => self[:database_password],
|
22
|
+
'host' => self[:database_host]
|
23
|
+
},
|
24
|
+
'development' => {},
|
25
|
+
'staging' => {},
|
26
|
+
'production' => {},
|
27
|
+
'test' => {}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# task: `database:setup'
|
32
|
+
def database_template_settings
|
33
|
+
fetch(:db_setup_settings, {}).reverse_merge(
|
34
|
+
database_setup_defaults.keys.inject({}) {|r, e| r.merge Hash[e, Hash.new] }
|
35
|
+
).inject({}) do |r, (k,v)|
|
36
|
+
r.merge Hash[k, v.reverse_merge(database_setup_defaults[k] || {})]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Required attributes
|
41
|
+
# ===================
|
42
|
+
# *database_name* prod_db
|
43
|
+
namespace :db do
|
44
|
+
|
45
|
+
namespace :setup do
|
46
|
+
desc "Upload configs"
|
47
|
+
task :default, :roles => :db do
|
48
|
+
if exists?(:db_setup_settings)
|
49
|
+
set(:recipe_settings, database_template_settings)
|
50
|
+
put template.render(fetch(:database_template)), fetch(:database_remote_file)
|
51
|
+
else
|
52
|
+
puts "[FATAL] - Database template settings were not found"
|
53
|
+
abort
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Download configs"
|
58
|
+
task :get, :roles => :db do
|
59
|
+
download fetch(:database_remote_file), File.join(local_rails_root, 'config/database.yml')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# mailer_setup_settings:
|
5
|
+
# user_name: "email@example.com"
|
6
|
+
# password: "secret"
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
|
10
|
+
set(:mailer_remote_file) { File.join(shared_path, 'config/mailers.yml') } unless exists?(:mailer_remote_file)
|
11
|
+
set(:mailer_template, 'mailers.yml.erb') unless exists?(:mailer_template)
|
12
|
+
|
13
|
+
namespace :mailer do
|
14
|
+
namespace :setup do
|
15
|
+
desc "Upload configs"
|
16
|
+
task :default, :roles => :db do
|
17
|
+
if exists?(:mailer_setup_settings)
|
18
|
+
set :recipe_settings, fetch(:mailer_setup_settings, {})
|
19
|
+
put template.render(fetch(:mailer_template)), fetch(:mailer_remote_file)
|
20
|
+
else
|
21
|
+
puts "[FATAL] - Mailers template settings were not found"
|
22
|
+
abort
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Download configs"
|
27
|
+
task :get, :roles => :db do
|
28
|
+
download fetch(:mailer_remote_file), File.join(local_rails_root, 'config/mailers.yml')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# newrelic_setup_settings:
|
5
|
+
# common:
|
6
|
+
# app_name: AppName
|
7
|
+
# license_key: secret
|
8
|
+
# staging:
|
9
|
+
# app_name: AppName (Staging)
|
10
|
+
|
11
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
12
|
+
set(:newrelic_remote_file) { File.join(shared_path, 'config/newrelic.yml') } unless exists?(:newrelic_remote_file)
|
13
|
+
set(:newrelic_template, 'newrelic.yml.erb') unless exists?(:newrelic_template)
|
14
|
+
|
15
|
+
def newrelic_setup_defaults
|
16
|
+
{
|
17
|
+
'common' => {
|
18
|
+
# ============================== LICENSE KEY ===============================
|
19
|
+
|
20
|
+
# You must specify the license key associated with your New Relic
|
21
|
+
# account. This key binds your Agent's data to your account in the
|
22
|
+
# New Relic service.
|
23
|
+
'license_key' => self[:newrelic_license_key],
|
24
|
+
# Agent Enabled (Ruby/Rails Only)
|
25
|
+
# Use this setting to force the agent to run or not run.
|
26
|
+
# Default is 'auto' which means the agent will install and run only
|
27
|
+
# if a valid dispatcher such as Mongrel is running. This prevents
|
28
|
+
# it from running with Rake or the console. Set to false to
|
29
|
+
# completely turn the agent off regardless of the other settings.
|
30
|
+
# Valid values are true, false and auto.
|
31
|
+
# 'agent_enabled' => 'auto'
|
32
|
+
|
33
|
+
# Application Name
|
34
|
+
# Set this to be the name of your application as you'd like it show
|
35
|
+
# up in New Relic. New Relic will then auto-map instances of your application
|
36
|
+
# into a New Relic "application" on your home dashboard page. If you want
|
37
|
+
# to map this instance into multiple apps, like "AJAX Requests" and
|
38
|
+
# "All UI" then specify a semicolon-separated list of up to three
|
39
|
+
# distinct names. If you comment this out, it defaults to the
|
40
|
+
# capitalized RAILS_ENV (i.e., Production, Staging, etc)
|
41
|
+
'app_name' => fetch(:application),
|
42
|
+
|
43
|
+
# When "true", the agent collects performance data about your
|
44
|
+
# application and reports this data to the New Relic service at
|
45
|
+
# newrelic.com. This global switch is normally overridden for each
|
46
|
+
# environment below. (formerly called 'enabled')
|
47
|
+
'monitor_mode' => false,
|
48
|
+
|
49
|
+
# Developer mode should be off in every environment but
|
50
|
+
# development as it has very high overhead in memory.
|
51
|
+
'developer_mode' => false,
|
52
|
+
|
53
|
+
# The newrelic agent generates its own log file to keep its logging
|
54
|
+
# information separate from that of your application. Specify its
|
55
|
+
# log level here.
|
56
|
+
'log_level' => 'info',
|
57
|
+
|
58
|
+
# The newrelic agent communicates with the New Relic service via http by
|
59
|
+
# default. If you want to communicate via https to increase
|
60
|
+
# security, then turn on SSL by setting this value to true. Note,
|
61
|
+
# this will result in increased CPU overhead to perform the
|
62
|
+
# encryption involved in SSL communication, but this work is done
|
63
|
+
# asynchronously to the threads that process your application code,
|
64
|
+
# so it should not impact response times.
|
65
|
+
'ssl' => false,
|
66
|
+
|
67
|
+
# EXPERIMENTAL: enable verification of the SSL certificate sent by
|
68
|
+
# the server. This setting has no effect unless SSL is enabled
|
69
|
+
# above. This may block your application. Only enable it if the data
|
70
|
+
# you send us needs end-to-end verified certificates.
|
71
|
+
#
|
72
|
+
# This means we cannot cache the DNS lookup, so each request to the
|
73
|
+
# New Relic service will perform a lookup. It also means that we cannot
|
74
|
+
# use a non-blocking lookup, so in a worst case, if you have DNS
|
75
|
+
# problems, your app may block indefinitely.
|
76
|
+
# 'verify_certificate' => true,
|
77
|
+
|
78
|
+
# Proxy settings for connecting to the New Relic server.
|
79
|
+
#
|
80
|
+
# If a proxy is used, the host setting is required. Other settings
|
81
|
+
# are optional. Default port is 8080.
|
82
|
+
#
|
83
|
+
# 'proxy_host' => 'hostname'
|
84
|
+
# 'proxy_port' => 8080
|
85
|
+
# 'proxy_user' => ''
|
86
|
+
# 'proxy_pass' => ''
|
87
|
+
|
88
|
+
# Tells transaction tracer and error collector (when enabled)
|
89
|
+
# whether or not to capture HTTP params. When true, frameworks can
|
90
|
+
# exclude HTTP parameters from being captured.
|
91
|
+
# Rails: the RoR filter_parameter_logging excludes parameters
|
92
|
+
# Java: create a config setting called "ignored_params" and set it to
|
93
|
+
# a comma separated list of HTTP parameter names.
|
94
|
+
# ex: ignored_params: credit_card, ssn, password
|
95
|
+
'capture_params' => true,
|
96
|
+
|
97
|
+
# Transaction tracer captures deep information about slow
|
98
|
+
# transactions and sends this to the New Relic service once a
|
99
|
+
# minute. Included in the transaction is the exact call sequence of
|
100
|
+
# the transactions including any SQL statements issued.
|
101
|
+
'transaction_tracer' => {
|
102
|
+
# Transaction tracer is enabled by default. Set this to false to
|
103
|
+
# turn it off. This feature is only available at the Professional
|
104
|
+
# product level.
|
105
|
+
'enabled' => true,
|
106
|
+
|
107
|
+
# Threshold in seconds for when to collect a transaction
|
108
|
+
# trace. When the response time of a controller action exceeds
|
109
|
+
# this threshold, a transaction trace will be recorded and sent to
|
110
|
+
# New Relic. Valid values are any float value, or (default) "apdex_f",
|
111
|
+
# which will use the threshold for an dissatisfying Apdex
|
112
|
+
# controller action - four times the Apdex T value.
|
113
|
+
'transaction_threshold' => 'apdex_f',
|
114
|
+
|
115
|
+
# When transaction tracer is on, SQL statements can optionally be
|
116
|
+
# recorded. The recorder has three modes, "off" which sends no
|
117
|
+
# SQL, "raw" which sends the SQL statement in its original form,
|
118
|
+
# and "obfuscated", which strips out numeric and string literals.
|
119
|
+
'record_sql' => 'raw',
|
120
|
+
|
121
|
+
# Threshold in seconds for when to collect stack trace for a SQL
|
122
|
+
# call. In other words, when SQL statements exceed this threshold,
|
123
|
+
# then capture and send to New Relic the current stack trace. This is
|
124
|
+
# helpful for pinpointing where long SQL calls originate from.
|
125
|
+
'stack_trace_threshold' => 0.500
|
126
|
+
|
127
|
+
# Determines whether the agent will capture query plans for slow
|
128
|
+
# SQL queries. Only supported in mysql and postgres. Should be
|
129
|
+
# set to false when using other adapters.
|
130
|
+
# 'explain_enabled' => true
|
131
|
+
|
132
|
+
# Threshold for query execution time below which query plans will not
|
133
|
+
# not be captured. Relevant only when `explain_enabled` is true.
|
134
|
+
# 'explain_threshold' => 0.5
|
135
|
+
},
|
136
|
+
|
137
|
+
|
138
|
+
# Error collector captures information about uncaught exceptions and
|
139
|
+
# sends them to New Relic for viewing
|
140
|
+
'error_collector' => {
|
141
|
+
# Error collector is enabled by default. Set this to false to turn
|
142
|
+
# it off. This feature is only available at the Professional
|
143
|
+
# product level.
|
144
|
+
'enabled' => true,
|
145
|
+
|
146
|
+
# Rails Only - tells error collector whether or not to capture a
|
147
|
+
# source snippet around the place of the error when errors are View
|
148
|
+
# related.
|
149
|
+
'capture_source' => true,
|
150
|
+
|
151
|
+
# To stop specific errors from reporting to New Relic, set this property
|
152
|
+
# to comma-separated values. Default is to ignore routing errors,
|
153
|
+
# which are how 404's get triggered.
|
154
|
+
'ignore_errors' => 'ActionController::RoutingError'
|
155
|
+
},
|
156
|
+
|
157
|
+
# (Advanced) Uncomment this to ensure the CPU and memory samplers
|
158
|
+
# won't run. Useful when you are using the agent to monitor an
|
159
|
+
# external resource
|
160
|
+
# 'disable_samplers' => true
|
161
|
+
|
162
|
+
# If you aren't interested in visibility in these areas, you can
|
163
|
+
# disable the instrumentation to reduce overhead.
|
164
|
+
#
|
165
|
+
# 'disable_view_instrumentation' => true,
|
166
|
+
# 'disable_activerecord_instrumentation' => true,
|
167
|
+
# 'disable_memcache_instrumentation' => true,
|
168
|
+
# 'disable_dj' => true,
|
169
|
+
|
170
|
+
# Certain types of instrumentation such as GC stats will not work if
|
171
|
+
# you are running multi-threaded. Please let us know.
|
172
|
+
# 'multi_threaded' => false
|
173
|
+
},
|
174
|
+
'development' => {'developer_mode' => true},
|
175
|
+
'staging' => {'developer_mode' => true},
|
176
|
+
'test' => {},
|
177
|
+
'production' => {'monitor_mode' => true}
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
# task: `newrelic:setup'
|
182
|
+
def newrelic_template_settings
|
183
|
+
fetch(:newrelic_setup_settings, {}).reverse_merge(
|
184
|
+
newrelic_setup_defaults.keys.inject({}) {|r, e| r.merge Hash[e, Hash.new] }
|
185
|
+
).inject({}) do |r, (k,v)|
|
186
|
+
r.merge Hash[k, v.reverse_merge(newrelic_setup_defaults[k] || {})]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Required attributes
|
191
|
+
# ===================
|
192
|
+
# *license_key* 123xyz
|
193
|
+
# *app_name* Production App
|
194
|
+
namespace :newrelic do
|
195
|
+
namespace :setup do
|
196
|
+
desc "Upload configs"
|
197
|
+
task :default, :roles => :db do
|
198
|
+
if exists?(:newrelic_setup_settings)
|
199
|
+
set(:recipe_settings) { newrelic_template_settings }
|
200
|
+
put template.render(fetch(:newrelic_template)), fetch(:newrelic_remote_file)
|
201
|
+
else
|
202
|
+
puts "[FATAL] - Newrelic template settings were not found"
|
203
|
+
abort
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
desc "Download configs"
|
208
|
+
task :get, :roles => :db do
|
209
|
+
download fetch(:newrelic_remote_file), File.join(local_rails_root, 'config/newrelic.yml')
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# passenger_setup_settings:
|
5
|
+
# port: 80
|
6
|
+
# auth_user_file: '/path/to/htpasswd'
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
|
10
|
+
set(:apache_sites_available) { "/home/#{user}/configs/apache/sites-available" }
|
11
|
+
set(:apache_sites_enabled) { "/home/#{user}/configs/apache/sites-enabled" }
|
12
|
+
set(:apache_remote_file) { File.join(apache_sites_available, "#{application}.conf") } unless exists?(:apache_remote_file)
|
13
|
+
set(:apache_template, 'passenger.conf.erb') unless exists?(:apache_template)
|
14
|
+
|
15
|
+
# task: `passenger:setup'
|
16
|
+
def passenger_template_settings
|
17
|
+
fetch(:passenger_setup_settings, {}).reverse_merge({
|
18
|
+
'server_name' => fetch(:domain),
|
19
|
+
'document_root' => File.join(fetch(:current_path), 'public'),
|
20
|
+
'rails_env' => fetch(:rails_env, 'production')
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
namespace :passenger do
|
25
|
+
desc "Restart Rails app running under Phusion Passenger by touching restart.txt"
|
26
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
27
|
+
run "touch #{current_path}/tmp/restart.txt"
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Inspect Phusion Passenger's memory usage."
|
31
|
+
task :memory, :roles => :app do
|
32
|
+
run "sudo passenger-memory-stats"
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Inspect Phusion Passenger's internal status."
|
36
|
+
task :status, :roles => :app do
|
37
|
+
run "sudo passenger-status"
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Remove passenger config"
|
41
|
+
task :remove, :roles => :app, :except => { :no_release => true } do
|
42
|
+
passenger.disable
|
43
|
+
run "rm #{apache_sites_available}/#{application}.conf"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Disable passenger config"
|
47
|
+
task :disable, :roles => :app, :except => { :no_release => true } do
|
48
|
+
run "rm #{apache_sites_enabled}/#{application}.conf"
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
namespace :setup do
|
53
|
+
desc "Upload configs"
|
54
|
+
task :default, :roles => :db do
|
55
|
+
if exists?(:passenger_setup_settings)
|
56
|
+
run "mkdir -p #{apache_sites_available} #{apache_sites_enabled}"
|
57
|
+
set(:recipe_settings) { passenger_template_settings }
|
58
|
+
put template.render(fetch(:apache_template)), fetch(:apache_remote_file)
|
59
|
+
else
|
60
|
+
puts "[FATAL] - Passenger template settings were not found"
|
61
|
+
abort
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Download configs"
|
66
|
+
task :get, :roles => :db do
|
67
|
+
download fetch(:apache_remote_file), File.join(local_rails_root, "configs/#{application}.conf")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# settler_setup_settings:
|
5
|
+
# host: example.com
|
6
|
+
# partner_name: FooBar
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
set(:settler_remote_file) { File.join(shared_path, 'config/settler.yml') } unless exists?(:settler_remote_file)
|
10
|
+
set(:settler_template, 'settler.yml.erb') unless exists?(:settler_template)
|
11
|
+
|
12
|
+
# task: `settler:setup'
|
13
|
+
def settler_template_settings
|
14
|
+
fetch(:settler_setup_settings, {}).inject({}) do |r, (k,v)|
|
15
|
+
r.merge Hash[k, {'alt' => k, 'value' => v}]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Required attributes
|
21
|
+
# ===================
|
22
|
+
# *settler_name* prod_db
|
23
|
+
namespace :settler do
|
24
|
+
namespace :setup do
|
25
|
+
desc "Upload configs"
|
26
|
+
task :default, :roles => :db do
|
27
|
+
if exists?(:settler_setup_settings)
|
28
|
+
set(:recipe_settings) { settler_template_settings }
|
29
|
+
put template.render(fetch(:settler_template)), fetch(:settler_remote_file)
|
30
|
+
else
|
31
|
+
puts "[FATAL] - Settler template settings were not found"
|
32
|
+
abort
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Download configs"
|
37
|
+
task :get, :roles => :db do
|
38
|
+
download fetch(:settler_remote_file), File.join(local_rails_root, 'config/settler.yml')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# shards_setup_settings:
|
5
|
+
# databases:
|
6
|
+
# production:
|
7
|
+
# slave1: {}
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
set(:shards_remote_file) { File.join(shared_path, 'config/shards.yml') } unless exists?(:shards_remote_file)
|
10
|
+
set(:shards_template, 'shards.yml.erb') unless exists?(:shards_template)
|
11
|
+
|
12
|
+
def shards_setup_defaults
|
13
|
+
{
|
14
|
+
'replicated' => true,
|
15
|
+
'verify_connection' => true,
|
16
|
+
'environments' => %w(production),
|
17
|
+
'databases' => {}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
# task: `shards:setup'
|
22
|
+
def shards_template_settings
|
23
|
+
fetch(:shards_setup_settings, {}).reverse_merge(shards_setup_defaults)
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :shards do
|
27
|
+
namespace :setup do
|
28
|
+
desc "Upload configs"
|
29
|
+
task :default, :roles => :db do
|
30
|
+
if exists?(:shards_setup_settings)
|
31
|
+
set(:recipe_settings) do
|
32
|
+
{
|
33
|
+
'main' => database_template_settings,
|
34
|
+
'shards' => shards_template_settings
|
35
|
+
}
|
36
|
+
end
|
37
|
+
put template.render(fetch(:shards_template)), fetch(:shards_remote_file)
|
38
|
+
else
|
39
|
+
puts "[FATAL] - Shards template settings were not found"
|
40
|
+
abort
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Download configs"
|
45
|
+
task :get, :roles => :db do
|
46
|
+
download fetch(:shards_remote_file), File.join(local_rails_root, "config/shards.yml")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
set(:thin_remote_file) { File.join(shared_path, 'config/thin.yml') } unless exists?(:thin_remote_file)
|
3
|
+
set(:thin_template, 'thin.yml.erb') unless exists?(:thin_template)
|
4
|
+
|
5
|
+
|
6
|
+
# The wrapped bin to start thin
|
7
|
+
# This is necessary if you're using rvm
|
8
|
+
set :thin_bin, 'bundle exec thin' unless exists?(:thin_bin)
|
9
|
+
|
10
|
+
# The remote location of thin's config file. Used by god to fire it up
|
11
|
+
set(:thin_remote_config) { File.join(current_path, 'config', 'thin.yml') }
|
12
|
+
|
13
|
+
# task: `thin:setup'
|
14
|
+
def thin_template_settings
|
15
|
+
fetch(:thin_setup_settings, {}).reverse_merge({
|
16
|
+
'chdir' => fetch(:current_path),
|
17
|
+
'timeout' => fetch(:thin_timeout, 30),
|
18
|
+
'servers' => fetch(:thin_servers, 4),
|
19
|
+
'rails_env' => fetch(:rails_env, 'production')
|
20
|
+
})
|
21
|
+
end
|
22
|
+
|
23
|
+
def thin_cmd(action)
|
24
|
+
"cd #{current_path}; #{thin_bin} -C #{thin_remote_config} #{action}"
|
25
|
+
end
|
26
|
+
|
27
|
+
namespace :thin do
|
28
|
+
desc "Thin restart"
|
29
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
30
|
+
run thin_cmd('restart')
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Thin start"
|
34
|
+
task :start, :roles => :app, :except => { :no_release => true } do
|
35
|
+
run thin_cmd('start')
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Thin stop"
|
39
|
+
task :stop, :roles => :app, :except => { :no_release => true } do
|
40
|
+
run thin_cmd('stop')
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
namespace :setup do
|
45
|
+
desc "Upload configs"
|
46
|
+
task :default, :roles => :db do
|
47
|
+
if exists?(:thin_setup_settings)
|
48
|
+
set(:recipe_settings) { thin_template_settings }
|
49
|
+
put template.render(fetch(:thin_template)), fetch(:thin_remote_file)
|
50
|
+
else
|
51
|
+
puts "[FATAL] - Thin template settings were not found"
|
52
|
+
abort
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Download configs"
|
57
|
+
task :get, :roles => :db do
|
58
|
+
download fetch(:thin_remote_file), File.join(local_rails_root, "config/thin.yml")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# tire_setup_settings:
|
5
|
+
# url: "http://localhost:9200"
|
6
|
+
|
7
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
8
|
+
set(:tire_remote_file) { File.join(shared_path, 'config/tire.yml') } unless exists?(:tire_remote_file)
|
9
|
+
set(:tire_template, 'tire.yml.erb') unless exists?(:tire_template)
|
10
|
+
|
11
|
+
# Required attributes
|
12
|
+
# ===================
|
13
|
+
# *url* http://localhost:9200
|
14
|
+
namespace :tire do
|
15
|
+
namespace :setup do
|
16
|
+
desc "Upload configs"
|
17
|
+
task :default, :roles => :db do
|
18
|
+
if exists?(:tire_setup_settings)
|
19
|
+
set :recipe_settings, fetch(:tire_setup_settings, {})
|
20
|
+
put template.render(fetch(:tire_template)), fetch(:tire_remote_file)
|
21
|
+
else
|
22
|
+
puts "[FATAL] - Tire template settings were not found"
|
23
|
+
abort
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Download configs"
|
28
|
+
task :get, :roles => :db do
|
29
|
+
download fetch(:tire_remote_file), File.join(local_rails_root, "config/tire.yml")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# unicorn_setup_settings:
|
5
|
+
# port: 80
|
6
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
7
|
+
set(:monit_root){ "/home/#{user}/monit/metromix" }
|
8
|
+
|
9
|
+
# The wrapped bin to start unicorn
|
10
|
+
# This is necessary if you're using rvm
|
11
|
+
set :unicorn_bin, 'bundle exec unicorn' unless exists?(:unicorn_bin)
|
12
|
+
|
13
|
+
# The remote location of unicorn's config file. Used by god to fire it up
|
14
|
+
set(:unicorn_remote_config) { "#{current_path}/config/unicorn.rb" }
|
15
|
+
|
16
|
+
set(:unicorn_template, 'unicorn.rb.erb') unless exists?(:unicorn_template)
|
17
|
+
set(:unicorn_monit_template, 'unicorn_monit.erb') unless exists?(:unicorn_monit_template)
|
18
|
+
|
19
|
+
# Defines where the unicorn pid will live.
|
20
|
+
set(:unicorn_pid) { File.join(shared_path, "pids", "unicorn.pid") } unless exists?(:unicorn_pid)
|
21
|
+
|
22
|
+
# task: `unicorn:setup'
|
23
|
+
def unicorn_template_settings
|
24
|
+
fetch(:unicorn_setup_settings, {}).reverse_merge({
|
25
|
+
# Number of workers (Rule of thumb is 2 per CPU)
|
26
|
+
# Just be aware that every worker needs to cache all classes and thus eat some
|
27
|
+
# of your RAM.
|
28
|
+
'workers' => fetch(:unicorn_workers, 4),
|
29
|
+
# Workers timeout in the amount of seconds below, when the master kills it and
|
30
|
+
# forks another one.
|
31
|
+
'workers_timeout' => fetch(:unicorn_workers_timeout, 30),
|
32
|
+
# Workers are started with this user/group
|
33
|
+
# By default we get the user/group set in capistrano.
|
34
|
+
'user' => fetch(:unicorn_user) { user },
|
35
|
+
'group' => fetch(:unicorn_group) { group },
|
36
|
+
'rails_env' => fetch(:rails_env, 'production'),
|
37
|
+
# configs for the monit template
|
38
|
+
'pids_root' => fetch(:unicorn_pids_root) { File.join(shared_path, "pids") },
|
39
|
+
'application' => fetch(:application),
|
40
|
+
'current_path' => fetch(:current_path),
|
41
|
+
'remote_config' => fetch(:unicorn_remote_config)
|
42
|
+
})
|
43
|
+
end
|
44
|
+
|
45
|
+
def unicorn_start_cmd
|
46
|
+
"cd #{current_path} && #{unicorn_bin} -c #{unicorn_remote_config} -E #{rails_env} -D"
|
47
|
+
end
|
48
|
+
|
49
|
+
def unicorn_stop_cmd
|
50
|
+
"kill -QUIT `cat #{unicorn_pid}`"
|
51
|
+
end
|
52
|
+
|
53
|
+
def unicorn_restart_cmd
|
54
|
+
"kill -USR2 `cat #{unicorn_pid}`"
|
55
|
+
end
|
56
|
+
|
57
|
+
namespace :unicorn do
|
58
|
+
desc "Starts unicorn directly"
|
59
|
+
task :start, :roles => :app, :except => { :no_release => true } do
|
60
|
+
run unicorn_start_cmd
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Stops unicorn directly"
|
64
|
+
task :stop, :roles => :app, :except => { :no_release => true } do
|
65
|
+
run unicorn_stop_cmd
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Restarts unicorn directly"
|
69
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
70
|
+
run unicorn_restart_cmd
|
71
|
+
end
|
72
|
+
|
73
|
+
# Required attributes
|
74
|
+
# ===================
|
75
|
+
# *port* 80
|
76
|
+
namespace :setup do
|
77
|
+
desc "Upload configs"
|
78
|
+
task :default, :roles => :db do
|
79
|
+
if exists?(:unicorn_setup_settings)
|
80
|
+
set(:recipe_settings) { unicorn_template_settings }
|
81
|
+
put template.render(fetch(:unicorn_template)), File.join(shared_path, 'config/unicorn.rb')
|
82
|
+
else
|
83
|
+
puts "[FATAL] - Unicorn template settings were not found"
|
84
|
+
abort
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "Download configs"
|
89
|
+
task :get, :roles => :db do
|
90
|
+
download File.join(shared_path, 'config/unicorn.rb'), File.join(local_rails_root, "config/unicorn.rb")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
namespace :monit do
|
95
|
+
namespace :setup do
|
96
|
+
desc "Upload configs"
|
97
|
+
task :default, :roles => :db do
|
98
|
+
if exists?(:unicorn_setup_settings)
|
99
|
+
run "mkdir -p #{monit_root}"
|
100
|
+
set(:recipe_settings) { unicorn_template_settings }
|
101
|
+
put template.render(fetch(:unicorn_monit_template)), File.join(monit_root, application)
|
102
|
+
else
|
103
|
+
puts "[FATAL] - Unicorn/Monit template settings were not found"
|
104
|
+
abort
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
desc "Download configs"
|
109
|
+
task :get, :roles => :db do
|
110
|
+
download File.join(monit_root, application), File.join(local_rails_root, "config/#{application}-monit")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Example
|
2
|
+
# =======
|
3
|
+
#
|
4
|
+
# uploader_setup_settings:
|
5
|
+
# fog_credentials:
|
6
|
+
# provider: Rackspace
|
7
|
+
# rackspace_username: username
|
8
|
+
# rackspace_api_key: secret
|
9
|
+
# fog_directory: frontend
|
10
|
+
# fog_host: http://123.rackcdn.com
|
11
|
+
|
12
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
13
|
+
set(:uploader_remote_file) { File.join(shared_path, 'config/uploader.yml') } unless exists?(:uploader_remote_file)
|
14
|
+
set(:uploader_template, 'uploader.yml.erb') unless exists?(:uploader_template)
|
15
|
+
|
16
|
+
namespace :uploader do
|
17
|
+
namespace :setup do
|
18
|
+
desc "Upload configs"
|
19
|
+
task :default, :roles => :db do
|
20
|
+
if exists?(:uploader_setup_settings)
|
21
|
+
set :recipe_settings, fetch(:uploader_setup_settings, {})
|
22
|
+
put template.render(fetch(:uploader_template)), fetch(:uploader_remote_file)
|
23
|
+
else
|
24
|
+
puts "[FATAL] - Uploader template settings were not found"
|
25
|
+
abort
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "Download configs"
|
30
|
+
task :get, :roles => :db do
|
31
|
+
download fetch(:uploader_remote_file), File.join(local_rails_root, "config/uploader.yml")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "marcosgz-cap-recipe"
|
6
|
+
s.version = "0.0.3"
|
7
|
+
s.authors = ["Marcos G. Zimmermann"]
|
8
|
+
s.email = ["mgzmaster@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/marcosgz/capistrano-recipe"
|
10
|
+
s.summary = %q{Capistrano recipe}
|
11
|
+
|
12
|
+
s.rubyforge_project = "capistrano-recipe"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency "capistrano", "> 2.0.0"
|
20
|
+
s.add_development_dependency "pry", "~> 0.9.11.4"
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: marcosgz-cap-recipe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Marcos G. Zimmermann
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: capistrano
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>'
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>'
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.0.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: pry
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.9.11.4
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.9.11.4
|
46
|
+
description:
|
47
|
+
email:
|
48
|
+
- mgzmaster@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- lib/capistrano/recipe.rb
|
58
|
+
- lib/capistrano/recipes/application.rb
|
59
|
+
- lib/capistrano/recipes/database.rb
|
60
|
+
- lib/capistrano/recipes/mailer.rb
|
61
|
+
- lib/capistrano/recipes/newrelic.rb
|
62
|
+
- lib/capistrano/recipes/passenger.rb
|
63
|
+
- lib/capistrano/recipes/settler.rb
|
64
|
+
- lib/capistrano/recipes/shards.rb
|
65
|
+
- lib/capistrano/recipes/thin.rb
|
66
|
+
- lib/capistrano/recipes/tire.rb
|
67
|
+
- lib/capistrano/recipes/unicorn.rb
|
68
|
+
- lib/capistrano/recipes/uploader.rb
|
69
|
+
- marcosgz-cap-recipe.gemspec
|
70
|
+
homepage: https://github.com/marcosgz/capistrano-recipe
|
71
|
+
licenses: []
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project: capistrano-recipe
|
90
|
+
rubygems_version: 1.8.23
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: Capistrano recipe
|
94
|
+
test_files: []
|
95
|
+
has_rdoc:
|