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 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
- Add the gem to your ```Gemfile```:
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
- Add unicorn plugin into your deploy.rb file.
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
- This should add a unicorn server start task after ```deploy:restart```.
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
- Unicorn configuration file should be placed under ```config/unicorn/YOUR_ENV.rb```
42
+ ### Test
32
43
 
33
- To test if it works type:
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
- **NOTE:** This plugin uses bundler.
58
+ ## Configuration
42
59
 
43
- ## Configuration options
60
+ You can modify any of the following options in your `deploy.rb` config.
44
61
 
45
- - ```unicorn_env``` - Set unicorn environment. Default to ```rails_env``` variable.
46
- - ```unicorn_pid``` - Set unicorn PID file path. Default to ```current_path/tmp/pids/unicorn.pid```
47
- - ```unicorn_bin``` - Set unicorn executable file. Default to ```unicorn```.
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
- ## License
67
+ ## Available Tasks
50
68
 
51
- Copyright (c) 2011-2012 Dan Sosedoff.
69
+ To get a list of all capistrano tasks, run `cap -T`:
52
70
 
53
- 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:
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
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
81
+ ## License
56
82
 
57
- 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.
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.6.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 file exists
26
+ # Check if a remote process exists using its pid file
9
27
  #
10
- def remote_file_exists?(full_path)
11
- 'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
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
- # Check if process is running
31
+
32
+ # Stale Unicorn process pid file
15
33
  #
16
- def process_exists?(pid_file)
17
- capture("ps -p $(cat #{pid_file}) ; true").strip.split("\n").size == 2
34
+ def old_unicorn_pid
35
+ "#{unicorn_pid}.oldbin"
18
36
  end
19
37
 
20
- # Set unicorn vars
38
+ # Command to check if Unicorn is running
21
39
  #
22
- _cset(:unicorn_pid, "#{fetch(:current_path)}/tmp/pids/unicorn.pid")
23
- _cset(:app_env, (fetch(:rails_env) rescue 'production'))
24
- _cset(:unicorn_env, (fetch(:app_env)))
25
- _cset(:unicorn_env_variables, (fetch(:app_env_variables) rescue ''))
26
- _cset(:unicorn_bin, "unicorn")
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
- if remote_file_exists?(unicorn_pid)
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
- if remote_file_exists?(unicorn_pid)
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 'Unicorn graceful shutdown'
65
- task :graceful_stop, :roles => :app, :except => {:no_release => true} do
66
- if remote_file_exists?(unicorn_pid)
67
- if process_exists?(unicorn_pid)
68
- logger.important("Stopping...", "Unicorn")
69
- run "#{try_sudo} kill -s QUIT `cat #{unicorn_pid}`"
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
- run "rm #{unicorn_pid}"
72
- logger.important("Unicorn is not running.", "Unicorn")
73
- end
74
- else
75
- logger.important("No PIDs found. Check if unicorn is running.", "Unicorn")
76
- end
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
- if remote_file_exists?(unicorn_pid)
82
- logger.important("Stopping...", "Unicorn")
83
- run "#{try_sudo} kill -s USR2 `cat #{unicorn_pid}`"
84
- else
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
- logger.important("Config file for \"#{unicorn_env}\" environment was not found at \"#{config_path}\"", "Unicorn")
91
- end
92
- end
161
+ #{start_unicorn}
162
+ fi;
163
+ END
93
164
  end
94
- end
95
165
 
96
- after "deploy:restart", "unicorn:reload"
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
- hash: 93
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 1
9
- - 6
10
- - 1
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-21 00:00:00 Z
17
+ date: 2012-11-20 00:00:00 -05:00
18
+ default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- name: capistrano
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: :runtime
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.8.24
88
+ rubygems_version: 1.3.6
82
89
  signing_key:
83
90
  specification_version: 3
84
91
  summary: Unicorn integration for Capistrano