capistrano-unicorn 0.1.10 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +7 -1
- data/NEWS.md +27 -0
- data/README.md +108 -22
- data/Rakefile +10 -2
- data/capistrano-unicorn.gemspec +17 -16
- data/lib/capistrano-unicorn/capistrano_integration.rb +44 -124
- data/lib/capistrano-unicorn/config.rb +52 -0
- data/lib/capistrano-unicorn/utility.rb +147 -0
- data/lib/capistrano-unicorn/version.rb +1 -1
- data/spec/capistrano_integration_spec.rb +84 -0
- data/spec/config_spec.rb +134 -0
- data/spec/spec_helper.rb +7 -0
- metadata +41 -27
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1a058f515bf172a37d40eedbd47982db1374ffb3
|
4
|
+
data.tar.gz: d9e4825ca605a00f559985fd5cbfbac9768cb958
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb193dc5a958641c7febf145c9586b3186b1727fbd59e615022283fba9d7d32f109bd6e2f249f9f8930407f5229bb30e99ee0fa5574384c4a3de16e994d77b1f
|
7
|
+
data.tar.gz: 3821b7cf00a08cc83d068881caae0fae99132b091f4ea71d07fb3eeef73ffb6b7af559bf0d57da6300ae79fcb9396a56793166cba3b742ffabec254c68a05676
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/NEWS.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Capistrano Unicorn NEWS
|
2
|
+
|
3
|
+
## 0.2.0
|
4
|
+
|
5
|
+
Significant changes since 0.1.10 are as follows. Backwards-incompatible changes are **in bold**.
|
6
|
+
|
7
|
+
* Ensured `RAILS_ENV` is set correctly.
|
8
|
+
* Embedded multistage docs directly within the [README](README.md) (the wiki page was version-specific and misleading).
|
9
|
+
* Significantly tidied up the usage and documentation of configuration variables:
|
10
|
+
* **In most cases, it should now be sufficient to simply set `rails_env` correctly,
|
11
|
+
and other variables should assume the correct value by default.**
|
12
|
+
* **Make `unicorn_env` default to `rails_env` or `'production'`.**
|
13
|
+
* **Rename `app_env` to `unicorn_rack_env` and fix default value.**
|
14
|
+
* Add `unicorn_options` variable which allows passing of arbitrary options to unicorn.
|
15
|
+
* Added `app_subdir` to support app running in a subdirectory.
|
16
|
+
* Updated documentation in [README](README.md) to fix inaccuracies and ambiguities.
|
17
|
+
* `unicorn_pid` defaults to attempting to auto-detect from unicorn config file.
|
18
|
+
This avoids having to keep two paths in sync.
|
19
|
+
https://github.com/sosedoff/capistrano-unicorn/issues/7
|
20
|
+
* Also added the `unicorn:show_vars` task to make it easier to debug
|
21
|
+
config variable values client-side.
|
22
|
+
* Defer calculation of `unicorn-roles`.
|
23
|
+
|
24
|
+
It was noticed that there are a
|
25
|
+
[huge number of unmerged forks on github](https://github.com/sosedoff/capistrano-unicorn/issues/45),
|
26
|
+
so we also updated the [README](README.md) asking the community to
|
27
|
+
contribute back any useful changes they make.
|
data/README.md
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
Capistrano plugin that integrates Unicorn tasks into capistrano deployment script.
|
4
4
|
|
5
|
-
|
5
|
+
**Developers:** Please consider contributing your forked changes, or opening an
|
6
|
+
issue if there is no existing relevant one. There are a lot of forks--we'd love
|
7
|
+
to reabsorb some of the issues/solutions the community has encountered.
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
gem install capistrano-unicorn
|
11
|
-
```
|
9
|
+
[![Build Status](https://travis-ci.org/sosedoff/capistrano-unicorn.png?branch=master)](https://travis-ci.org/sosedoff/capistrano-unicorn)
|
10
|
+
[![Gem Version](https://badge.fury.io/rb/capistrano-unicorn.png)](http://badge.fury.io/rb/capistrano-unicorn)
|
11
|
+
[![Code Climate](https://codeclimate.com/github/sosedoff/capistrano-unicorn.png)](https://codeclimate.com/github/sosedoff/capistrano-unicorn)
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
|
+
If you are upgrading from a previous version, please see the [NEWS file](NEWS.md).
|
16
|
+
|
15
17
|
### Setup
|
16
18
|
|
17
19
|
Add the library to your `Gemfile`:
|
@@ -31,15 +33,18 @@ require 'capistrano-unicorn'
|
|
31
33
|
Add unicorn restart task hook:
|
32
34
|
|
33
35
|
```ruby
|
34
|
-
after 'deploy:restart', 'unicorn:reload'
|
35
|
-
after 'deploy:restart', 'unicorn:restart'
|
36
|
+
after 'deploy:restart', 'unicorn:reload' # app IS NOT preloaded
|
37
|
+
after 'deploy:restart', 'unicorn:restart' # app preloaded
|
38
|
+
after 'deploy:restart', 'unicorn:duplicate' # before_fork hook implemented (zero downtime deployments)
|
36
39
|
```
|
37
40
|
|
38
|
-
Create a new configuration file `config/unicorn.rb` or `config/unicorn/STAGE.rb`,
|
41
|
+
Create a new configuration file `config/unicorn.rb` or `config/unicorn/STAGE.rb`,
|
42
|
+
where stage is your deployment environment.
|
39
43
|
|
40
|
-
Example config - [examples/rails3.rb](https://github.com/sosedoff/capistrano-unicorn/blob/master/examples/rails3.rb).
|
44
|
+
Example config - [examples/rails3.rb](https://github.com/sosedoff/capistrano-unicorn/blob/master/examples/rails3.rb).
|
45
|
+
Please refer to Unicorn documentation for more examples and configuration options.
|
41
46
|
|
42
|
-
###
|
47
|
+
### Deploy
|
43
48
|
|
44
49
|
First, make sure you're running the latest release:
|
45
50
|
|
@@ -57,20 +62,43 @@ cap unicorn:reload
|
|
57
62
|
|
58
63
|
## Configuration
|
59
64
|
|
60
|
-
You can modify any of the following
|
65
|
+
You can modify any of the following Capistrano variables in your `deploy.rb` config.
|
66
|
+
You can use the `unicorn:show_vars` task to check that the values you have specified
|
67
|
+
are set correctly.
|
61
68
|
|
62
|
-
|
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`.
|
66
|
-
- `unicorn_user` - Launch unicorn master as the specified user. Default to `user` variable.
|
67
|
-
- `unicorn_roles` - Define which roles to perform unicorn recpies on. Default to `:app`.
|
68
|
-
- `unicorn_config_path` - Set the directory where unicorn config files reside. Default to `current_path/config`.
|
69
|
-
- `unicorn_config_filename` - Set the filename of the unicorn config file. Not used in multistage installations. Default to `unicorn.rb`.
|
69
|
+
### Environment parameters
|
70
70
|
|
71
|
-
|
71
|
+
- `unicorn_env` - Set basename of unicorn config `.rb` file to be used loaded from `unicorn_config_path`. Defaults to `rails_env` variable if set, otherwise `production`.
|
72
|
+
- `unicorn_rack_env` - Set the value which will be passed to unicorn via [the `-E` parameter as the Rack environment](http://unicorn.bogomips.org/unicorn_1.html). Valid values are `development`, `deployment`, and `none`. Defaults to `development` if `rails_env` is `development`, otherwise `deployment`.
|
73
|
+
|
74
|
+
### Execution parameters
|
75
|
+
|
76
|
+
- `unicorn_user` - Launch unicorn master as the specified user via `sudo`. Defaults to `nil`, which means no use of `sudo`, i.e. run as the user defined by the `user` variable.
|
77
|
+
- `unicorn_roles` - Define which roles to perform unicorn recipes on. Defaults to `:app`.
|
78
|
+
- `unicorn_bundle` - Set bundler command for unicorn. Defaults to `bundle`.
|
79
|
+
- `unicorn_bin` - Set unicorn executable file. Defaults to `unicorn`.
|
80
|
+
- `unicorn_options` - Set any additional options to be passed to unicorn on startup.
|
81
|
+
- `unicorn_restart_sleep_time` - Number of seconds to wait for (old) pidfile to show up when restarting unicorn. Defaults to 2.
|
82
|
+
|
83
|
+
### Relative path parameters
|
84
|
+
|
85
|
+
- `app_subdir` - If your app lives in a subdirectory 'rails' (say) of your repository, set this to `/rails` (the leading slash is required).
|
86
|
+
- `unicorn_config_rel_path` - Set the directory path (relative to `app_path` - see below) where unicorn config files reside. Defaults to `config`.
|
87
|
+
- `unicorn_config_filename` - Set the filename of the unicorn config file loaded from `unicorn_config_path`. Should not be present in multistage installations. Defaults to `unicorn.rb`.
|
72
88
|
|
73
|
-
|
89
|
+
### Absolute path parameters
|
90
|
+
|
91
|
+
- `app_path` - Set path to app root. Defaults to `current_path + app_subdir`.
|
92
|
+
- `unicorn_pid` - Set unicorn PID file path. By default, attempts to auto-detect from unicorn config file. On failure, falls back to value in `unicorn_default_pid`
|
93
|
+
- `unicorn_default_pid` - See above. Defaults to `#{current_path}/tmp/pids/unicorn.pid`
|
94
|
+
- `bundle_gemfile` - Set path to Gemfile. Defaults to `#{app_path}/Gemfile`
|
95
|
+
- `unicorn_config_path` - Set the directory where unicorn config files reside. Defaults to `#{current_path}/config`.
|
96
|
+
|
97
|
+
### Zero Downtime Deployment Options
|
98
|
+
|
99
|
+
* `unicorn:restart`: :-1: This can sort of support it with a configurable timeout, which may not be reliable.
|
100
|
+
* `unicorn:reload`: :question: Can anyone testify to its zero-downtime support?
|
101
|
+
* `unicorn:duplicate`: :+1: If you install the Unicorn `before_fork` hook, then yes! See: https://github.com/sosedoff/capistrano-unicorn/issues/40#issuecomment-16011353
|
74
102
|
|
75
103
|
## Available Tasks
|
76
104
|
|
@@ -81,11 +109,69 @@ cap unicorn:add_worker # Add a new worker
|
|
81
109
|
cap unicorn:remove_worker # Remove amount of workers
|
82
110
|
cap unicorn:reload # Reload Unicorn
|
83
111
|
cap unicorn:restart # Restart Unicorn
|
112
|
+
cap unicorn:show_vars # Debug Unicorn variables
|
84
113
|
cap unicorn:shutdown # Immediately shutdown Unicorn
|
85
114
|
cap unicorn:start # Start Unicorn master process
|
86
115
|
cap unicorn:stop # Stop Unicorn
|
87
116
|
```
|
88
117
|
|
118
|
+
## Tests
|
119
|
+
|
120
|
+
To execute test suite run:
|
121
|
+
|
122
|
+
```
|
123
|
+
bundle exec rake test
|
124
|
+
```
|
125
|
+
|
126
|
+
### Multistage
|
127
|
+
|
128
|
+
The issue here is that capistrano loads default configuration and then
|
129
|
+
executes your staging task and overrides previously defined
|
130
|
+
variables. The default environment before executing your stage task is
|
131
|
+
set to `:production`, so it will use a wrong environment unless you
|
132
|
+
take steps to ensure that `:rails_env` and `:unicorn_env` are
|
133
|
+
set correctly.
|
134
|
+
|
135
|
+
Let's say you have a scenario involving two deployment stages: staging
|
136
|
+
and production. You’ll need to add `config/deploy/staging.rb` and
|
137
|
+
`config/deploy/production.rb` files. However, it makes sense to
|
138
|
+
adhere to DRY and avoid duplicating lines between the two files. So
|
139
|
+
it would be nicer to keep common settings in `config/deploy.rb`, and
|
140
|
+
only put stuff in each staging definition file which is really
|
141
|
+
specific to that staging environment. Fortunately this can be done
|
142
|
+
using the [lazy evaluation form of `set`](https://github.com/capistrano/capistrano/wiki/2.x-DSL-Configuration-Variables-Set).
|
143
|
+
|
144
|
+
So `config/deploy.rb` file would contain something like:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
set :stages, %w(production staging)
|
148
|
+
set :default_stage, "staging"
|
149
|
+
require 'capistrano/ext/multistage'
|
150
|
+
|
151
|
+
role(:web) { domain }
|
152
|
+
role(:app) { domain }
|
153
|
+
role(:db, :primary => true) { domain }
|
154
|
+
|
155
|
+
set(:deploy_to) { "/home/#{user}/#{application}/#{fetch :rails_env}" }
|
156
|
+
set(:current_path) { File.join(deploy_to, current_dir) }
|
157
|
+
```
|
158
|
+
|
159
|
+
Then `config/deploy/production.rb` would contain something like:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
set :domain, "app.mydomain.com"
|
163
|
+
set :rails_env, "production"
|
164
|
+
```
|
165
|
+
|
166
|
+
and `config/deploy/staging.rb` would only need to contain something like:
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
set :domain, "app.staging.mydomain.com"
|
170
|
+
set :rails_env, "staging"
|
171
|
+
```
|
172
|
+
|
173
|
+
Nice and clean!
|
174
|
+
|
89
175
|
## License
|
90
176
|
|
91
177
|
See LICENSE file for details.
|
data/Rakefile
CHANGED
data/capistrano-unicorn.gemspec
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path(
|
2
|
+
require File.expand_path("../lib/capistrano-unicorn/version", __FILE__)
|
3
3
|
|
4
|
-
Gem::Specification.new do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "capistrano-unicorn"
|
6
|
+
spec.version = CapistranoUnicorn::VERSION.dup
|
7
|
+
spec.author = "Dan Sosedoff"
|
8
|
+
spec.email = "dan.sosedoff@gmail.com"
|
9
|
+
spec.homepage = "https://github.com/sosedoff/capistrano-unicorn"
|
10
|
+
spec.summary = %q{Unicorn integration for Capistrano}
|
11
|
+
spec.description = %q{Capistrano plugin that integrates Unicorn server tasks.}
|
12
|
+
spec.license = "MIT"
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
spec.files = `git ls-files`.split("\n")
|
15
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
spec.require_paths = ["lib"]
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
spec.add_development_dependency "rake"
|
20
|
+
spec.add_development_dependency "unicorn"
|
21
|
+
spec.add_runtime_dependency "capistrano", "< 3.0"
|
21
22
|
end
|
@@ -1,6 +1,11 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
1
3
|
require 'capistrano'
|
2
4
|
require 'capistrano/version'
|
3
5
|
|
6
|
+
require 'capistrano-unicorn/config'
|
7
|
+
require 'capistrano-unicorn/utility'
|
8
|
+
|
4
9
|
module CapistranoUnicorn
|
5
10
|
class CapistranoIntegration
|
6
11
|
TASKS = [
|
@@ -11,142 +16,57 @@ module CapistranoUnicorn
|
|
11
16
|
'unicorn:reload',
|
12
17
|
'unicorn:shutdown',
|
13
18
|
'unicorn:add_worker',
|
14
|
-
'unicorn:remove_worker'
|
19
|
+
'unicorn:remove_worker',
|
20
|
+
'unicorn:show_vars',
|
15
21
|
]
|
16
22
|
|
17
23
|
def self.load_into(capistrano_config)
|
18
24
|
capistrano_config.load do
|
19
|
-
before(CapistranoIntegration::TASKS) do
|
20
|
-
_cset(:app_env) { (fetch(:rails_env) rescue 'production') }
|
21
|
-
_cset(:unicorn_pid) { "#{fetch(:current_path)}/tmp/pids/unicorn.pid" }
|
22
|
-
_cset(:unicorn_env) { fetch(:app_env) }
|
23
|
-
_cset(:unicorn_bin) { "unicorn" }
|
24
|
-
_cset(:unicorn_bundle) { fetch(:bundle_cmd) rescue 'bundle' }
|
25
|
-
_cset(:unicorn_restart_sleep_time) { 2 }
|
26
|
-
_cset(:unicorn_user) { nil }
|
27
|
-
_cset(:unicorn_config_path) { "#{fetch(:current_path)}/config" }
|
28
|
-
_cset(:unicorn_config_filename) { "unicorn.rb" }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Check if a remote process exists using its pid file
|
32
|
-
#
|
33
|
-
def remote_process_exists?(pid_file)
|
34
|
-
"[ -e #{pid_file} ] && #{try_unicorn_user} kill -0 `cat #{pid_file}` > /dev/null 2>&1"
|
35
|
-
end
|
36
|
-
|
37
|
-
# Stale Unicorn process pid file
|
38
|
-
#
|
39
|
-
def old_unicorn_pid
|
40
|
-
"#{unicorn_pid}.oldbin"
|
41
|
-
end
|
42
25
|
|
43
|
-
|
44
|
-
|
45
|
-
def unicorn_is_running?
|
46
|
-
remote_process_exists?(unicorn_pid)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Command to check if stale Unicorn is running
|
50
|
-
#
|
51
|
-
def old_unicorn_is_running?
|
52
|
-
remote_process_exists?(old_unicorn_pid)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Get unicorn master process PID (using the shell)
|
56
|
-
#
|
57
|
-
def get_unicorn_pid(pid_file=unicorn_pid)
|
58
|
-
"`cat #{pid_file}`"
|
59
|
-
end
|
60
|
-
|
61
|
-
# Get unicorn master (old) process PID
|
62
|
-
#
|
63
|
-
def get_old_unicorn_pid
|
64
|
-
get_unicorn_pid(old_unicorn_pid)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Send a signal to a unicorn master processes
|
68
|
-
#
|
69
|
-
def unicorn_send_signal(signal, pid=get_unicorn_pid)
|
70
|
-
"#{try_unicorn_user} kill -s #{signal} #{pid}"
|
71
|
-
end
|
72
|
-
|
73
|
-
# Run a command as the :unicorn_user user if :unicorn_user is a string.
|
74
|
-
# Otherwise run as default (:user) user.
|
75
|
-
#
|
76
|
-
def try_unicorn_user
|
77
|
-
"#{sudo :as => unicorn_user.to_s}" if unicorn_user.kind_of?(String)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Kill Unicorns in multiple ways O_O
|
81
|
-
#
|
82
|
-
def kill_unicorn(signal)
|
83
|
-
script = <<-END
|
84
|
-
if #{unicorn_is_running?}; then
|
85
|
-
echo "Stopping Unicorn...";
|
86
|
-
#{unicorn_send_signal(signal)};
|
87
|
-
else
|
88
|
-
echo "Unicorn is not running.";
|
89
|
-
fi;
|
90
|
-
END
|
91
|
-
|
92
|
-
script
|
93
|
-
end
|
94
|
-
|
95
|
-
# Start the Unicorn server
|
96
|
-
#
|
97
|
-
def start_unicorn
|
98
|
-
primary_config_path = "#{unicorn_config_path}/#{unicorn_config_filename}"
|
99
|
-
secondary_config_path = "#{unicorn_config_path}/unicorn/#{unicorn_env}.rb"
|
100
|
-
|
101
|
-
script = <<-END
|
102
|
-
if [ -e #{primary_config_path} ]; then
|
103
|
-
UNICORN_CONFIG_PATH=#{primary_config_path};
|
104
|
-
else
|
105
|
-
if [ -e #{secondary_config_path} ]; then
|
106
|
-
UNICORN_CONFIG_PATH=#{secondary_config_path};
|
107
|
-
else
|
108
|
-
echo "Config file for \"#{unicorn_env}\" environment was not found at either \"#{primary_config_path}\" or \"#{secondary_config_path}\"";
|
109
|
-
exit 1;
|
110
|
-
fi;
|
111
|
-
fi;
|
112
|
-
|
113
|
-
if [ -e #{unicorn_pid} ]; then
|
114
|
-
if #{try_unicorn_user} kill -0 `cat #{unicorn_pid}` > /dev/null 2>&1; then
|
115
|
-
echo "Unicorn is already running!";
|
116
|
-
exit 0;
|
117
|
-
fi;
|
118
|
-
|
119
|
-
#{try_unicorn_user} rm #{unicorn_pid};
|
120
|
-
fi;
|
121
|
-
|
122
|
-
echo "Starting Unicorn...";
|
123
|
-
cd #{current_path} && #{try_unicorn_user} BUNDLE_GEMFILE=#{current_path}/Gemfile #{unicorn_bundle} exec #{unicorn_bin} -c $UNICORN_CONFIG_PATH -E #{app_env} -D;
|
124
|
-
END
|
125
|
-
|
126
|
-
script
|
127
|
-
end
|
128
|
-
|
129
|
-
def duplicate_unicorn
|
130
|
-
script = <<-END
|
131
|
-
if #{unicorn_is_running?}; then
|
132
|
-
echo "Duplicating Unicorn...";
|
133
|
-
#{unicorn_send_signal('USR2')};
|
134
|
-
else
|
135
|
-
#{start_unicorn}
|
136
|
-
fi;
|
137
|
-
END
|
138
|
-
|
139
|
-
script
|
26
|
+
before(CapistranoIntegration::TASKS) do
|
27
|
+
Config.load(self)
|
140
28
|
end
|
141
29
|
|
142
|
-
|
143
|
-
fetch(:unicorn_roles, :app)
|
144
|
-
end
|
30
|
+
extend Utility
|
145
31
|
|
146
32
|
#
|
147
33
|
# Unicorn cap tasks
|
148
34
|
#
|
149
35
|
namespace :unicorn do
|
36
|
+
desc 'Debug Unicorn variables'
|
37
|
+
task :show_vars, :roles => :app do
|
38
|
+
puts <<-EOF.gsub(/^ +/, '')
|
39
|
+
|
40
|
+
# Environments
|
41
|
+
rails_env "#{rails_env}"
|
42
|
+
unicorn_env "#{unicorn_env}"
|
43
|
+
unicorn_rack_env "#{unicorn_rack_env}"
|
44
|
+
|
45
|
+
# Execution
|
46
|
+
unicorn_user #{unicorn_user.inspect}
|
47
|
+
unicorn_bundle "#{unicorn_bundle}"
|
48
|
+
unicorn_bin "#{unicorn_bin}"
|
49
|
+
unicorn_options "#{unicorn_options}"
|
50
|
+
unicorn_restart_sleep_time #{unicorn_restart_sleep_time}
|
51
|
+
|
52
|
+
# Relative paths
|
53
|
+
app_subdir "#{app_subdir}"
|
54
|
+
unicorn_config_rel_path "#{unicorn_config_rel_path}"
|
55
|
+
unicorn_config_filename "#{unicorn_config_filename}"
|
56
|
+
unicorn_config_rel_file_path "#{unicorn_config_rel_file_path}"
|
57
|
+
unicorn_config_stage_rel_file_path "#{unicorn_config_stage_rel_file_path}"
|
58
|
+
|
59
|
+
# Absolute paths
|
60
|
+
app_path "#{app_path}"
|
61
|
+
unicorn_pid "#{unicorn_pid}"
|
62
|
+
bundle_gemfile "#{bundle_gemfile}"
|
63
|
+
unicorn_config_path "#{unicorn_config_path}"
|
64
|
+
unicorn_config_file_path "#{unicorn_config_file_path}"
|
65
|
+
unicorn_config_stage_file_path
|
66
|
+
-> "#{unicorn_config_stage_file_path}"
|
67
|
+
EOF
|
68
|
+
end
|
69
|
+
|
150
70
|
desc 'Start Unicorn master process'
|
151
71
|
task :start, :roles => unicorn_roles, :except => {:no_release => true} do
|
152
72
|
run start_unicorn
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CapistranoUnicorn
|
2
|
+
class Config
|
3
|
+
def self.load(config)
|
4
|
+
config.instance_eval do
|
5
|
+
# Environments
|
6
|
+
_cset(:unicorn_env) { fetch(:rails_env, 'production' ) }
|
7
|
+
_cset(:unicorn_rack_env) do
|
8
|
+
# Following recommendations from http://unicorn.bogomips.org/unicorn_1.html
|
9
|
+
fetch(:rails_env) == 'development' ? 'development' : 'deployment'
|
10
|
+
end
|
11
|
+
|
12
|
+
# Execution
|
13
|
+
_cset(:unicorn_user) { nil }
|
14
|
+
_cset(:unicorn_bundle) { fetch(:bundle_cmd, "bundle") }
|
15
|
+
_cset(:unicorn_bin) { "unicorn" }
|
16
|
+
_cset(:unicorn_options) { '' }
|
17
|
+
_cset(:unicorn_restart_sleep_time) { 2 }
|
18
|
+
|
19
|
+
# Relative paths
|
20
|
+
_cset(:app_subdir) { '' }
|
21
|
+
_cset(:unicorn_config_rel_path) { "config" }
|
22
|
+
_cset(:unicorn_config_filename) { "unicorn.rb" }
|
23
|
+
_cset(:unicorn_config_rel_file_path) \
|
24
|
+
{ unicorn_config_rel_path + '/' + unicorn_config_filename }
|
25
|
+
_cset(:unicorn_config_stage_rel_file_path) \
|
26
|
+
{ [ unicorn_config_rel_path, 'unicorn',
|
27
|
+
"#{unicorn_env}.rb" ].join('/') }
|
28
|
+
|
29
|
+
# Absolute paths
|
30
|
+
# If you find the following confusing, try running 'cap unicorn:show_vars' -
|
31
|
+
# it might help :-)
|
32
|
+
_cset(:app_path) { current_path + app_subdir }
|
33
|
+
_cset(:bundle_gemfile) { app_path + '/Gemfile' }
|
34
|
+
_cset(:unicorn_config_path) { app_path + '/' + unicorn_config_rel_path }
|
35
|
+
_cset(:unicorn_config_file_path) { app_path + '/' + unicorn_config_rel_file_path }
|
36
|
+
_cset(:unicorn_config_stage_file_path) \
|
37
|
+
{ app_path + '/' + unicorn_config_stage_rel_file_path }
|
38
|
+
_cset(:unicorn_default_pid) { app_path + "/tmp/pids/unicorn.pid" }
|
39
|
+
_cset(:unicorn_pid) do
|
40
|
+
extracted_pid = extract_pid_file
|
41
|
+
if extracted_pid
|
42
|
+
extracted_pid
|
43
|
+
else
|
44
|
+
logger.important "err :: failed to auto-detect pid from #{local_unicorn_config}"
|
45
|
+
logger.important "err :: falling back to default: #{unicorn_default_pid}"
|
46
|
+
unicorn_default_pid
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module CapistranoUnicorn
|
2
|
+
module Utility
|
3
|
+
|
4
|
+
def local_unicorn_config
|
5
|
+
File.exist?(unicorn_config_rel_file_path) ?
|
6
|
+
unicorn_config_rel_file_path
|
7
|
+
: unicorn_config_stage_rel_file_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def extract_pid_file
|
11
|
+
tmp = Tempfile.new('unicorn.rb')
|
12
|
+
begin
|
13
|
+
conf = local_unicorn_config
|
14
|
+
tmp.write <<-EOF.gsub(/^ */, '')
|
15
|
+
config_file = "#{conf}"
|
16
|
+
|
17
|
+
# stub working_directory to avoid chdir failure since this will
|
18
|
+
# run client-side:
|
19
|
+
def working_directory(path); end
|
20
|
+
|
21
|
+
instance_eval(File.read(config_file), config_file) if config_file
|
22
|
+
puts set[:pid]
|
23
|
+
exit 0
|
24
|
+
EOF
|
25
|
+
tmp.close
|
26
|
+
extracted_pid = `unicorn -c "#{tmp.path}"`
|
27
|
+
$?.success? ? extracted_pid.rstrip : nil
|
28
|
+
rescue StandardError => e
|
29
|
+
return nil
|
30
|
+
ensure
|
31
|
+
tmp.close
|
32
|
+
tmp.unlink
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Check if a remote process exists using its pid file
|
37
|
+
#
|
38
|
+
def remote_process_exists?(pid_file)
|
39
|
+
"[ -e #{pid_file} ] && #{try_unicorn_user} kill -0 `cat #{pid_file}` > /dev/null 2>&1"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Stale Unicorn process pid file
|
43
|
+
#
|
44
|
+
def old_unicorn_pid
|
45
|
+
"#{unicorn_pid}.oldbin"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Command to check if Unicorn is running
|
49
|
+
#
|
50
|
+
def unicorn_is_running?
|
51
|
+
remote_process_exists?(unicorn_pid)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Command to check if stale Unicorn is running
|
55
|
+
#
|
56
|
+
def old_unicorn_is_running?
|
57
|
+
remote_process_exists?(old_unicorn_pid)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get unicorn master process PID (using the shell)
|
61
|
+
#
|
62
|
+
def get_unicorn_pid(pid_file=unicorn_pid)
|
63
|
+
"`cat #{pid_file}`"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Get unicorn master (old) process PID
|
67
|
+
#
|
68
|
+
def get_old_unicorn_pid
|
69
|
+
get_unicorn_pid(old_unicorn_pid)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Send a signal to a unicorn master processes
|
73
|
+
#
|
74
|
+
def unicorn_send_signal(signal, pid=get_unicorn_pid)
|
75
|
+
"#{try_unicorn_user} kill -s #{signal} #{pid}"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Run a command as the :unicorn_user user if :unicorn_user is a string.
|
79
|
+
# Otherwise run as default (:user) user.
|
80
|
+
#
|
81
|
+
def try_unicorn_user
|
82
|
+
"#{sudo :as => unicorn_user.to_s}" if unicorn_user.kind_of?(String)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Kill Unicorns in multiple ways O_O
|
86
|
+
#
|
87
|
+
def kill_unicorn(signal)
|
88
|
+
script = <<-END
|
89
|
+
if #{unicorn_is_running?}; then
|
90
|
+
echo "Stopping Unicorn...";
|
91
|
+
#{unicorn_send_signal(signal)};
|
92
|
+
else
|
93
|
+
echo "Unicorn is not running.";
|
94
|
+
fi;
|
95
|
+
END
|
96
|
+
|
97
|
+
script
|
98
|
+
end
|
99
|
+
|
100
|
+
# Start the Unicorn server
|
101
|
+
#
|
102
|
+
def start_unicorn
|
103
|
+
%Q%
|
104
|
+
if [ -e "#{unicorn_config_file_path}" ]; then
|
105
|
+
UNICORN_CONFIG_PATH=#{unicorn_config_file_path};
|
106
|
+
else
|
107
|
+
if [ -e "#{unicorn_config_stage_file_path}" ]; then
|
108
|
+
UNICORN_CONFIG_PATH=#{unicorn_config_stage_file_path};
|
109
|
+
else
|
110
|
+
echo "Config file for "#{unicorn_env}" environment was not found at either "#{unicorn_config_file_path}" or "#{unicorn_config_stage_file_path}"";
|
111
|
+
exit 1;
|
112
|
+
fi;
|
113
|
+
fi;
|
114
|
+
|
115
|
+
if [ -e "#{unicorn_pid}" ]; then
|
116
|
+
if #{try_unicorn_user} kill -0 `cat #{unicorn_pid}` > /dev/null 2>&1; then
|
117
|
+
echo "Unicorn is already running!";
|
118
|
+
exit 0;
|
119
|
+
fi;
|
120
|
+
|
121
|
+
#{try_unicorn_user} rm #{unicorn_pid};
|
122
|
+
fi;
|
123
|
+
|
124
|
+
echo "Starting Unicorn...";
|
125
|
+
cd #{app_path} && #{try_unicorn_user} RAILS_ENV=#{rails_env} BUNDLE_GEMFILE=#{bundle_gemfile} #{unicorn_bundle} exec #{unicorn_bin} -c $UNICORN_CONFIG_PATH -E #{unicorn_rack_env} -D #{unicorn_options};
|
126
|
+
%
|
127
|
+
end
|
128
|
+
|
129
|
+
def duplicate_unicorn
|
130
|
+
script = <<-END
|
131
|
+
if #{unicorn_is_running?}; then
|
132
|
+
echo "Duplicating Unicorn...";
|
133
|
+
#{unicorn_send_signal('USR2')};
|
134
|
+
else
|
135
|
+
#{start_unicorn}
|
136
|
+
fi;
|
137
|
+
END
|
138
|
+
|
139
|
+
script
|
140
|
+
end
|
141
|
+
|
142
|
+
def unicorn_roles
|
143
|
+
defer{ fetch(:unicorn_roles, :app) }
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CapistranoUnicorn::CapistranoIntegration, "loaded tasks into capistrano" do
|
4
|
+
before do
|
5
|
+
@configuration = Capistrano::Configuration.new
|
6
|
+
@configuration.extend(Capistrano::Spec::ConfigurationExtension)
|
7
|
+
CapistranoUnicorn::CapistranoIntegration.load_into(@configuration)
|
8
|
+
end
|
9
|
+
|
10
|
+
shared_examples_for "a task" do |task_name|
|
11
|
+
it "sets attributes in before_task hook" do
|
12
|
+
# Environments
|
13
|
+
@configuration.should_receive(:_cset).with(:unicorn_env)
|
14
|
+
@configuration.should_receive(:_cset).with(:unicorn_rack_env)
|
15
|
+
|
16
|
+
# Execution
|
17
|
+
@configuration.should_receive(:_cset).with(:unicorn_user)
|
18
|
+
@configuration.should_receive(:_cset).with(:unicorn_bundle)
|
19
|
+
@configuration.should_receive(:_cset).with(:unicorn_bin)
|
20
|
+
@configuration.should_receive(:_cset).with(:unicorn_options)
|
21
|
+
@configuration.should_receive(:_cset).with(:unicorn_restart_sleep_time)
|
22
|
+
|
23
|
+
# Relative paths
|
24
|
+
@configuration.should_receive(:_cset).with(:app_subdir)
|
25
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_rel_path)
|
26
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_filename)
|
27
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_rel_file_path)
|
28
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_stage_rel_file_path)
|
29
|
+
|
30
|
+
# Absolute paths
|
31
|
+
@configuration.should_receive(:_cset).with(:app_path)
|
32
|
+
@configuration.should_receive(:_cset).with(:unicorn_pid)
|
33
|
+
@configuration.should_receive(:_cset).with(:bundle_gemfile)
|
34
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_path)
|
35
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_file_path)
|
36
|
+
@configuration.should_receive(:_cset).with(:unicorn_config_stage_file_path)
|
37
|
+
|
38
|
+
@configuration.find_and_execute_task(task_name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "task" do
|
43
|
+
describe 'unicorn:start' do
|
44
|
+
before do
|
45
|
+
@configuration.stub(:start_unicorn)
|
46
|
+
@configuration.stub(:_cset)
|
47
|
+
end
|
48
|
+
|
49
|
+
it_behaves_like "a task", 'unicorn:start'
|
50
|
+
|
51
|
+
it "runs start_unicorn command" do
|
52
|
+
@configuration.should_receive(:start_unicorn).and_return("start unicorn command")
|
53
|
+
@configuration.find_and_execute_task('unicorn:start')
|
54
|
+
@configuration.should have_run("start unicorn command")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'unicorn:stop' do
|
59
|
+
before do
|
60
|
+
@configuration.stub(:kill_unicorn)
|
61
|
+
@configuration.stub(:_cset)
|
62
|
+
end
|
63
|
+
|
64
|
+
it_behaves_like "a task", 'unicorn:stop'
|
65
|
+
|
66
|
+
it "runs kill_unicorn command" do
|
67
|
+
@configuration.should_receive(:kill_unicorn).with('QUIT').and_return("kill unicorn command")
|
68
|
+
@configuration.find_and_execute_task('unicorn:stop')
|
69
|
+
@configuration.should have_run("kill unicorn command")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#kill_unicorn" do
|
75
|
+
before do
|
76
|
+
@configuration.stub(:unicorn_pid).and_return(999)
|
77
|
+
@configuration.stub(:unicorn_user).and_return("deploy_user")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "generates the kill unicorn command" do
|
81
|
+
@configuration.kill_unicorn('QUIT').should match /-u deploy_user kill -s QUIT `cat 999`;/
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe CapistranoUnicorn::Config, "loaded into a configuration" do
|
3
|
+
before do
|
4
|
+
@configuration = Capistrano::Configuration.new
|
5
|
+
@configuration.extend(Capistrano::Spec::ConfigurationExtension)
|
6
|
+
CapistranoUnicorn::CapistranoIntegration.load_into(@configuration)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "testing variables" do
|
10
|
+
before do
|
11
|
+
# define _cset etc. from capistrano
|
12
|
+
@configuration.load 'deploy'
|
13
|
+
|
14
|
+
# capistrano-unicorn variables are set during a 'before'
|
15
|
+
# callback, so in order to be able to test the result, we need
|
16
|
+
# to ensure the callback is triggered.
|
17
|
+
@configuration.trigger :before
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "app paths" do
|
21
|
+
cur_path = '/path/to/myapp'
|
22
|
+
|
23
|
+
before do
|
24
|
+
@configuration.set(:current_path, cur_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
shared_examples_for "an app in path" do |app_path|
|
28
|
+
let(:shell) { :` } # ` } work around confused emacs ruby-mode
|
29
|
+
|
30
|
+
specify "app_path should default to #{app_path}" do
|
31
|
+
@configuration.fetch(:app_path).should == app_path
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should default to a sensible pid file when auto-detection failed" do
|
35
|
+
@configuration.should_receive(shell).with(/unicorn -c /).and_return('') do |cmd|
|
36
|
+
`false` # Simulate failure by setting $?
|
37
|
+
end
|
38
|
+
@configuration.logger.stub(:important)
|
39
|
+
@configuration.fetch(:unicorn_pid).should == app_path + "/tmp/pids/unicorn.pid"
|
40
|
+
end
|
41
|
+
|
42
|
+
shared_examples "auto-detect pid file from unicorn config" do
|
43
|
+
|pid_file, primary_exists, config_file|
|
44
|
+
which_config = primary_exists ? 'primary' : 'stage'
|
45
|
+
it "should auto-detect pid file from #{which_config} unicorn config" do
|
46
|
+
# Tempfile.new in Ruby 1.9.2 will call File.exist?
|
47
|
+
allow(File).to receive(:exist?).with(/tmp/)
|
48
|
+
|
49
|
+
File.should_receive(:exist?).with('config/unicorn.rb').and_return(primary_exists)
|
50
|
+
tmpfile = nil
|
51
|
+
@configuration.should_receive(shell).with(/unicorn -c /) do |cmd|
|
52
|
+
(cmd =~ /^unicorn -c "(.+)"$/).should be_true
|
53
|
+
tmpfile = $~[1]
|
54
|
+
tmpfile.should include("tmp")
|
55
|
+
File.read(tmpfile).should include(%!config_file = "#{config_file}"!)
|
56
|
+
`true` # Simulate success by setting $?
|
57
|
+
pid_file
|
58
|
+
end
|
59
|
+
@configuration.fetch(:unicorn_pid).should == pid_file
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
include_examples "auto-detect pid file from unicorn config", \
|
64
|
+
'/path/to/pid/from/config/file', true, "config/unicorn.rb"
|
65
|
+
|
66
|
+
include_examples "auto-detect pid file from unicorn config", \
|
67
|
+
'/path/to/pid/from/stage/config/file', false, "config/unicorn/production.rb"
|
68
|
+
|
69
|
+
specify "Gemfile should default correctly" do
|
70
|
+
@configuration.fetch(:bundle_gemfile).should == app_path + "/Gemfile"
|
71
|
+
end
|
72
|
+
|
73
|
+
specify "config/ directory should default correctly" do
|
74
|
+
@configuration.fetch(:unicorn_config_path).should == app_path + "/config"
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "config file should default correctly" do
|
78
|
+
@configuration.fetch(:unicorn_config_file_path).should == app_path + "/config/unicorn.rb"
|
79
|
+
end
|
80
|
+
|
81
|
+
specify "per-stage config file should default correctly" do
|
82
|
+
@configuration.fetch(:unicorn_config_stage_file_path).should == app_path + "/config/unicorn/production.rb"
|
83
|
+
end
|
84
|
+
|
85
|
+
specify "per-stage config file should be set correctly for different environment" do
|
86
|
+
@configuration.set(:rails_env, 'staging')
|
87
|
+
@configuration.fetch(:unicorn_config_stage_file_path).should == app_path + "/config/unicorn/staging.rb"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "app in current_path" do
|
92
|
+
it_should_behave_like "an app in path", cur_path
|
93
|
+
end
|
94
|
+
|
95
|
+
context "app in a subdirectory" do
|
96
|
+
subdir = 'mysubdir'
|
97
|
+
|
98
|
+
before do
|
99
|
+
@configuration.set(:app_subdir, '/' + subdir)
|
100
|
+
end
|
101
|
+
|
102
|
+
it_should_behave_like "an app in path", cur_path + '/' + subdir
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "unicorn_env" do
|
107
|
+
it "should default to value of rails_env if set" do
|
108
|
+
@configuration.set(:rails_env, 'staging')
|
109
|
+
@configuration.fetch(:unicorn_env).should == \
|
110
|
+
@configuration.fetch(:rails_env)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should default to production if rails_env not set" do
|
114
|
+
@configuration.fetch(:unicorn_env).should == 'production'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "unicorn_rack_env" do
|
119
|
+
it "should default to deployment if rails_env not set" do
|
120
|
+
@configuration.fetch(:unicorn_rack_env).should == 'deployment'
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should default to development if rails_env set to development" do
|
124
|
+
@configuration.set(:rails_env, 'development')
|
125
|
+
@configuration.fetch(:unicorn_rack_env).should == 'development'
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should default to deployment if rails_env set to anything else" do
|
129
|
+
@configuration.set(:rails_env, 'staging')
|
130
|
+
@configuration.fetch(:unicorn_rack_env).should == 'deployment'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,48 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-unicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Dan Sosedoff
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-10-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
28
|
+
name: unicorn
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
|
-
type: :
|
34
|
+
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: capistrano
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - <
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - <
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
46
55
|
description: Capistrano plugin that integrates Unicorn server tasks.
|
47
56
|
email: dan.sosedoff@gmail.com
|
48
57
|
executables: []
|
@@ -50,43 +59,48 @@ extensions: []
|
|
50
59
|
extra_rdoc_files: []
|
51
60
|
files:
|
52
61
|
- .gitignore
|
62
|
+
- .rspec
|
63
|
+
- .travis.yml
|
53
64
|
- Gemfile
|
54
65
|
- LICENSE
|
66
|
+
- NEWS.md
|
55
67
|
- README.md
|
56
68
|
- Rakefile
|
57
69
|
- capistrano-unicorn.gemspec
|
58
70
|
- examples/rails3.rb
|
59
71
|
- lib/capistrano-unicorn.rb
|
60
72
|
- lib/capistrano-unicorn/capistrano_integration.rb
|
73
|
+
- lib/capistrano-unicorn/config.rb
|
74
|
+
- lib/capistrano-unicorn/utility.rb
|
61
75
|
- lib/capistrano-unicorn/version.rb
|
76
|
+
- spec/capistrano_integration_spec.rb
|
77
|
+
- spec/config_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
62
79
|
homepage: https://github.com/sosedoff/capistrano-unicorn
|
63
|
-
licenses:
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
64
83
|
post_install_message:
|
65
84
|
rdoc_options: []
|
66
85
|
require_paths:
|
67
86
|
- lib
|
68
87
|
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
-
none: false
|
70
88
|
requirements:
|
71
|
-
- -
|
89
|
+
- - '>='
|
72
90
|
- !ruby/object:Gem::Version
|
73
91
|
version: '0'
|
74
|
-
segments:
|
75
|
-
- 0
|
76
|
-
hash: 759058187647909637
|
77
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - '>='
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
|
-
segments:
|
84
|
-
- 0
|
85
|
-
hash: 759058187647909637
|
86
97
|
requirements: []
|
87
98
|
rubyforge_project:
|
88
|
-
rubygems_version:
|
99
|
+
rubygems_version: 2.0.5
|
89
100
|
signing_key:
|
90
|
-
specification_version:
|
101
|
+
specification_version: 4
|
91
102
|
summary: Unicorn integration for Capistrano
|
92
|
-
test_files:
|
103
|
+
test_files:
|
104
|
+
- spec/capistrano_integration_spec.rb
|
105
|
+
- spec/config_spec.rb
|
106
|
+
- spec/spec_helper.rb
|