capistrano-unicorn 0.1.10 → 0.2.0
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.
- 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
|
+
[](https://travis-ci.org/sosedoff/capistrano-unicorn)
|
10
|
+
[](http://badge.fury.io/rb/capistrano-unicorn)
|
11
|
+
[](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
|