capistrano-unicorn-pleary 0.1.6.1 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +7 -0
- data/README.md +44 -18
- data/capistrano-unicorn-pleary.gemspec +3 -2
- data/lib/capistrano-unicorn/capistrano_integration.rb +159 -66
- metadata +22 -15
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2011-2012 Dan Sosedoff.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -4,33 +4,50 @@ Capistrano plugin that integrates Unicorn tasks into capistrano deployment scrip
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
+
Install library from rubygems:
|
8
|
+
|
7
9
|
```
|
8
10
|
gem install capistrano-unicorn
|
9
11
|
```
|
10
12
|
|
11
13
|
## Usage
|
12
14
|
|
13
|
-
|
15
|
+
### Setup
|
16
|
+
|
17
|
+
Add the library to your `Gemfile`:
|
14
18
|
|
15
19
|
```ruby
|
16
20
|
group :development do
|
17
|
-
gem 'capistrano-unicorn'
|
21
|
+
gem 'capistrano-unicorn', :require => false
|
18
22
|
end
|
19
23
|
```
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
**NOTE:** Should be placed after all hooks
|
25
|
+
And load it into your deployment script `config/deploy.rb`:
|
24
26
|
|
25
27
|
```ruby
|
26
28
|
require 'capistrano-unicorn'
|
27
29
|
```
|
28
30
|
|
29
|
-
|
31
|
+
Add unicorn restart task hook:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
after 'deploy:restart', 'unicorn:restart' # app IS NOT preloaded
|
35
|
+
after 'deploy:restart', 'unicorn:reload' # app preloaded
|
36
|
+
```
|
37
|
+
|
38
|
+
Create a new configuration file `config/unicorn/unicorn.rb` or `config/unicorn/STAGE.rb`, where stage is your deployment environment.
|
39
|
+
|
40
|
+
Example config - [examples/rails3.rb](https://github.com/sosedoff/capistrano-unicorn/blob/master/examples/rails3.rb). Please refer to unicorn documentation for more examples and configuration options.
|
30
41
|
|
31
|
-
|
42
|
+
### Test
|
32
43
|
|
33
|
-
|
44
|
+
First, make sure you're running the latest release:
|
45
|
+
|
46
|
+
```
|
47
|
+
cap deploy
|
48
|
+
```
|
49
|
+
|
50
|
+
Then you can test each individual task:
|
34
51
|
|
35
52
|
```
|
36
53
|
cap unicorn:start
|
@@ -38,20 +55,29 @@ cap unicorn:stop
|
|
38
55
|
cap unicorn:reload
|
39
56
|
```
|
40
57
|
|
41
|
-
|
58
|
+
## Configuration
|
42
59
|
|
43
|
-
|
60
|
+
You can modify any of the following options in your `deploy.rb` config.
|
44
61
|
|
45
|
-
-
|
46
|
-
-
|
47
|
-
-
|
62
|
+
- `unicorn_env` - Set unicorn environment. Default to `rails_env` variable.
|
63
|
+
- `unicorn_pid` - Set unicorn PID file path. Default to `current_path/tmp/pids/unicorn.pid`
|
64
|
+
- `unicorn_bin` - Set unicorn executable file. Default to `unicorn`.
|
65
|
+
- `unicorn_bundle` - Set bundler command for unicorn. Default to `bundle`.
|
48
66
|
|
49
|
-
##
|
67
|
+
## Available Tasks
|
50
68
|
|
51
|
-
|
69
|
+
To get a list of all capistrano tasks, run `cap -T`:
|
52
70
|
|
53
|
-
|
71
|
+
```
|
72
|
+
cap unicorn:add_worker # Add a new worker
|
73
|
+
cap unicorn:remove_worker # Remove amount of workers
|
74
|
+
cap unicorn:reload # Reload Unicorn
|
75
|
+
cap unicorn:restart # Restart Unicorn
|
76
|
+
cap unicorn:shutdown # Immediately shutdown Unicorn
|
77
|
+
cap unicorn:start # Start Unicorn master process
|
78
|
+
cap unicorn:stop # Stop Unicorn
|
79
|
+
```
|
54
80
|
|
55
|
-
|
81
|
+
## License
|
56
82
|
|
57
|
-
|
83
|
+
See LICENSE file for details.
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
2
|
Gem::Specification.new do |gem|
|
4
3
|
gem.name = 'capistrano-unicorn-pleary'
|
5
|
-
gem.version = '0.1.
|
4
|
+
gem.version = '0.1.7'
|
6
5
|
gem.author = 'Dan Sosedoff; Patrick Leary'
|
7
6
|
gem.email = 'dan.sosedoff@gmail.com; pleary@mbl.edu'
|
8
7
|
gem.homepage = 'https://github.com/pleary/capistrano-unicorn'
|
@@ -13,6 +12,8 @@ Gem::Specification.new do |gem|
|
|
13
12
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
13
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
|
15
14
|
gem.require_paths = ['lib']
|
15
|
+
|
16
|
+
gem.add_development_dependency 'rake'
|
16
17
|
|
17
18
|
gem.add_runtime_dependency 'capistrano'
|
18
19
|
end
|
@@ -1,99 +1,192 @@
|
|
1
1
|
require 'capistrano'
|
2
|
+
require 'capistrano/version'
|
2
3
|
|
3
4
|
module CapistranoUnicorn
|
4
5
|
class CapistranoIntegration
|
6
|
+
TASKS = [
|
7
|
+
'unicorn:start',
|
8
|
+
'unicorn:stop',
|
9
|
+
'unicorn:restart',
|
10
|
+
'unicorn:reload',
|
11
|
+
'unicorn:shutdown',
|
12
|
+
'unicorn:add_worker',
|
13
|
+
'unicorn:remove_worker'
|
14
|
+
]
|
15
|
+
|
5
16
|
def self.load_into(capistrano_config)
|
6
17
|
capistrano_config.load do
|
18
|
+
before(CapistranoIntegration::TASKS) do
|
19
|
+
_cset(:app_env) { (fetch(:rails_env) rescue 'production') }
|
20
|
+
_cset(:unicorn_pid) { "#{fetch(:current_path)}/tmp/pids/unicorn.pid" }
|
21
|
+
_cset(:unicorn_env) { fetch(:app_env) }
|
22
|
+
_cset(:unicorn_bin) { "unicorn" }
|
23
|
+
_cset(:unicorn_bundle) { fetch(:bundle_cmd) rescue 'bundle' }
|
24
|
+
end
|
7
25
|
|
8
|
-
# Check if remote
|
26
|
+
# Check if a remote process exists using its pid file
|
9
27
|
#
|
10
|
-
def
|
11
|
-
|
28
|
+
def remote_process_exists?(pid_file)
|
29
|
+
"[ -e #{pid_file} ] && kill -0 `cat #{pid_file}` > /dev/null 2>&1"
|
12
30
|
end
|
13
|
-
|
14
|
-
#
|
31
|
+
|
32
|
+
# Stale Unicorn process pid file
|
15
33
|
#
|
16
|
-
def
|
17
|
-
|
34
|
+
def old_unicorn_pid
|
35
|
+
"#{unicorn_pid}.oldbin"
|
18
36
|
end
|
19
37
|
|
20
|
-
#
|
38
|
+
# Command to check if Unicorn is running
|
21
39
|
#
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
40
|
+
def unicorn_is_running?
|
41
|
+
remote_process_exists?(unicorn_pid)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Command to check if stale Unicorn is running
|
45
|
+
#
|
46
|
+
def old_unicorn_is_running?
|
47
|
+
remote_process_exists?(old_unicorn_pid)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get unicorn master process PID (using the shell)
|
51
|
+
#
|
52
|
+
def get_unicorn_pid(pid_file=unicorn_pid)
|
53
|
+
"`cat #{pid_file}`"
|
54
|
+
end
|
55
|
+
|
56
|
+
# Get unicorn master (old) process PID
|
57
|
+
#
|
58
|
+
def get_old_unicorn_pid
|
59
|
+
get_unicorn_pid(old_unicorn_pid)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Send a signal to a unicorn master processes
|
63
|
+
#
|
64
|
+
def unicorn_send_signal(signal, pid=get_unicorn_pid)
|
65
|
+
"#{try_sudo} kill -s #{signal} #{pid}"
|
66
|
+
end
|
67
|
+
|
68
|
+
# Kill Unicorns in multiple ways O_O
|
69
|
+
#
|
70
|
+
def kill_unicorn(signal)
|
71
|
+
script = <<-END
|
72
|
+
if #{unicorn_is_running?}; then
|
73
|
+
echo "Stopping Unicorn...";
|
74
|
+
#{unicorn_send_signal(signal)};
|
75
|
+
else
|
76
|
+
echo "Unicorn is not running.";
|
77
|
+
fi;
|
78
|
+
END
|
79
|
+
|
80
|
+
script
|
81
|
+
end
|
82
|
+
|
83
|
+
# Start the Unicorn server
|
84
|
+
#
|
85
|
+
def start_unicorn
|
86
|
+
primary_config_path = "#{current_path}/config/unicorn.rb"
|
87
|
+
secondary_config_path = "#{current_path}/config/unicorn/#{unicorn_env}.rb"
|
88
|
+
|
89
|
+
script = <<-END
|
90
|
+
if [ -e #{primary_config_path} ]; then
|
91
|
+
UNICORN_CONFIG_PATH=#{primary_config_path};
|
92
|
+
else
|
93
|
+
if [ -e #{secondary_config_path} ]; then
|
94
|
+
UNICORN_CONFIG_PATH=#{secondary_config_path};
|
95
|
+
else
|
96
|
+
echo "Config file for \"#{unicorn_env}\" environment was not found at either \"#{primary_config_path}\" or \"#{secondary_config_path}\"";
|
97
|
+
exit 1;
|
98
|
+
fi;
|
99
|
+
fi;
|
100
|
+
|
101
|
+
if [ -e #{unicorn_pid} ]; then
|
102
|
+
if kill -0 `cat #{unicorn_pid}` > /dev/null 2>&1; then
|
103
|
+
echo "Unicorn is already running!";
|
104
|
+
exit 0;
|
105
|
+
fi;
|
106
|
+
|
107
|
+
rm #{unicorn_pid};
|
108
|
+
fi;
|
109
|
+
|
110
|
+
echo "Starting Unicorn...";
|
111
|
+
cd #{current_path} && BUNDLE_GEMFILE=#{current_path}/Gemfile #{unicorn_bundle} exec #{unicorn_bin} -c $UNICORN_CONFIG_PATH -E #{app_env} -D;
|
112
|
+
END
|
27
113
|
|
114
|
+
script
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Unicorn cap tasks
|
119
|
+
#
|
28
120
|
namespace :unicorn do
|
29
|
-
desc 'Start Unicorn'
|
121
|
+
desc 'Start Unicorn master process'
|
30
122
|
task :start, :roles => :app, :except => {:no_release => true} do
|
31
|
-
|
32
|
-
if process_exists?(unicorn_pid)
|
33
|
-
logger.important("Unicorn is already running!", "Unicorn")
|
34
|
-
next
|
35
|
-
else
|
36
|
-
run "rm #{unicorn_pid}"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
config_path = "#{current_path}/config/unicorn/#{unicorn_env}.rb"
|
41
|
-
if remote_file_exists?(config_path)
|
42
|
-
logger.important("Starting...", "Unicorn")
|
43
|
-
run "cd #{current_path} && #{unicorn_env_variables} BUNDLE_GEMFILE=#{current_path}/Gemfile bundle exec #{unicorn_bin} -c #{config_path} -E #{app_env} -D"
|
44
|
-
else
|
45
|
-
logger.important("Config file for \"#{unicorn_env}\" environment was not found at \"#{config_path}\"", "Unicorn")
|
46
|
-
end
|
123
|
+
run start_unicorn
|
47
124
|
end
|
48
125
|
|
49
126
|
desc 'Stop Unicorn'
|
50
127
|
task :stop, :roles => :app, :except => {:no_release => true} do
|
51
|
-
|
52
|
-
if process_exists?(unicorn_pid)
|
53
|
-
logger.important("Stopping...", "Unicorn")
|
54
|
-
run "#{try_sudo} kill `cat #{unicorn_pid}`"
|
55
|
-
else
|
56
|
-
run "rm #{unicorn_pid}"
|
57
|
-
logger.important("Unicorn is not running.", "Unicorn")
|
58
|
-
end
|
59
|
-
else
|
60
|
-
logger.important("No PIDs found. Check if unicorn is running.", "Unicorn")
|
61
|
-
end
|
128
|
+
run kill_unicorn('QUIT')
|
62
129
|
end
|
63
130
|
|
64
|
-
desc '
|
65
|
-
task :
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
131
|
+
desc 'Immediately shutdown Unicorn'
|
132
|
+
task :shutdown, :roles => :app, :except => {:no_release => true} do
|
133
|
+
run kill_unicorn('TERM')
|
134
|
+
end
|
135
|
+
|
136
|
+
desc 'Restart Unicorn'
|
137
|
+
task :restart, :roles => :app, :except => {:no_release => true} do
|
138
|
+
run <<-END
|
139
|
+
if #{unicorn_is_running?}; then
|
140
|
+
echo "Restarting Unicorn...";
|
141
|
+
#{unicorn_send_signal('USR2')};
|
70
142
|
else
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
143
|
+
#{start_unicorn}
|
144
|
+
fi;
|
145
|
+
|
146
|
+
sleep 2; # in order to wait for the (old) pidfile to show up
|
147
|
+
|
148
|
+
if #{old_unicorn_is_running?}; then
|
149
|
+
#{unicorn_send_signal('QUIT', get_old_unicorn_pid)};
|
150
|
+
fi;
|
151
|
+
END
|
77
152
|
end
|
78
153
|
|
79
154
|
desc 'Reload Unicorn'
|
80
155
|
task :reload, :roles => :app, :except => {:no_release => true} do
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
logger.important("No PIDs found. Starting Unicorn server...", "Unicorn")
|
86
|
-
config_path = "#{current_path}/config/unicorn/#{unicorn_env}.rb"
|
87
|
-
if remote_file_exists?(config_path)
|
88
|
-
run "cd #{current_path} && #{unicorn_env_variables} BUNDLE_GEMFILE=#{current_path}/Gemfile bundle exec #{unicorn_bin} -c #{config_path} -E #{app_env} -D"
|
156
|
+
run <<-END
|
157
|
+
if #{unicorn_is_running?}; then
|
158
|
+
echo "Reloading Unicorn...";
|
159
|
+
#{unicorn_send_signal('HUP')};
|
89
160
|
else
|
90
|
-
|
91
|
-
|
92
|
-
|
161
|
+
#{start_unicorn}
|
162
|
+
fi;
|
163
|
+
END
|
93
164
|
end
|
94
|
-
end
|
95
165
|
|
96
|
-
|
166
|
+
desc 'Add a new worker'
|
167
|
+
task :add_worker, :roles => :app, :except => {:no_release => true} do
|
168
|
+
run <<-END
|
169
|
+
if #{unicorn_is_running?}; then
|
170
|
+
echo "Adding a new Unicorn worker...";
|
171
|
+
#{unicorn_send_signal('TTIN')};
|
172
|
+
else
|
173
|
+
echo "Unicorn is not running.";
|
174
|
+
fi;
|
175
|
+
END
|
176
|
+
end
|
177
|
+
|
178
|
+
desc 'Remove amount of workers'
|
179
|
+
task :remove_worker, :roles => :app, :except => {:no_release => true} do
|
180
|
+
run <<-END
|
181
|
+
if #{unicorn_is_running?}; then
|
182
|
+
echo "Removing a Unicorn worker...";
|
183
|
+
#{unicorn_send_signal('TTOU')};
|
184
|
+
else
|
185
|
+
echo "Unicorn is not running.";
|
186
|
+
fi;
|
187
|
+
END
|
188
|
+
end
|
189
|
+
end
|
97
190
|
end
|
98
191
|
end
|
99
192
|
end
|
metadata
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-unicorn-pleary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 1
|
9
|
-
-
|
10
|
-
|
11
|
-
version: 0.1.6.1
|
8
|
+
- 7
|
9
|
+
version: 0.1.7
|
12
10
|
platform: ruby
|
13
11
|
authors:
|
14
12
|
- Dan Sosedoff; Patrick Leary
|
@@ -16,22 +14,33 @@ autorequire:
|
|
16
14
|
bindir: bin
|
17
15
|
cert_chain: []
|
18
16
|
|
19
|
-
date: 2012-11-
|
17
|
+
date: 2012-11-20 00:00:00 -05:00
|
18
|
+
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
21
|
+
name: rake
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
25
|
- - ">="
|
28
26
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
27
|
segments:
|
31
28
|
- 0
|
32
29
|
version: "0"
|
33
|
-
type: :
|
30
|
+
type: :development
|
34
31
|
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: capistrano
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :runtime
|
43
|
+
version_requirements: *id002
|
35
44
|
description: Capistrano plugin that integrates Unicorn server tasks.
|
36
45
|
email: dan.sosedoff@gmail.com; pleary@mbl.edu
|
37
46
|
executables: []
|
@@ -43,12 +52,14 @@ extra_rdoc_files: []
|
|
43
52
|
files:
|
44
53
|
- .gitignore
|
45
54
|
- Gemfile
|
55
|
+
- LICENSE
|
46
56
|
- README.md
|
47
57
|
- Rakefile
|
48
58
|
- capistrano-unicorn-pleary.gemspec
|
49
59
|
- examples/rails3.rb
|
50
60
|
- lib/capistrano-unicorn.rb
|
51
61
|
- lib/capistrano-unicorn/capistrano_integration.rb
|
62
|
+
has_rdoc: true
|
52
63
|
homepage: https://github.com/pleary/capistrano-unicorn
|
53
64
|
licenses: []
|
54
65
|
|
@@ -58,27 +69,23 @@ rdoc_options: []
|
|
58
69
|
require_paths:
|
59
70
|
- lib
|
60
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
72
|
requirements:
|
63
73
|
- - ">="
|
64
74
|
- !ruby/object:Gem::Version
|
65
|
-
hash: 3
|
66
75
|
segments:
|
67
76
|
- 0
|
68
77
|
version: "0"
|
69
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
-
none: false
|
71
79
|
requirements:
|
72
80
|
- - ">="
|
73
81
|
- !ruby/object:Gem::Version
|
74
|
-
hash: 3
|
75
82
|
segments:
|
76
83
|
- 0
|
77
84
|
version: "0"
|
78
85
|
requirements: []
|
79
86
|
|
80
87
|
rubyforge_project:
|
81
|
-
rubygems_version: 1.
|
88
|
+
rubygems_version: 1.3.6
|
82
89
|
signing_key:
|
83
90
|
specification_version: 3
|
84
91
|
summary: Unicorn integration for Capistrano
|