capistrano-unicorn-sic 0.3.1
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/.gitignore +41 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +9 -0
- data/LICENSE +18 -0
- data/NEWS.md +27 -0
- data/README.md +178 -0
- data/Rakefile +10 -0
- data/capistrano-unicorn.gemspec +22 -0
- data/examples/rails3.rb +45 -0
- data/lib/capistrano-unicorn.rb +0 -0
- data/lib/capistrano/tasks/unicorn.cap +155 -0
- data/lib/capistrano/unicorn.rb +1 -0
- data/lib/capistrano/unicorn/utility.rb +149 -0
- data/lib/capistrano/unicorn/version.rb +5 -0
- data/lib/unicorn.rb +0 -0
- data/spec/capistrano_integration_spec.rb +84 -0
- data/spec/config_spec.rb +134 -0
- data/spec/spec_helper.rb +7 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8091b3b6283213655531467af348b2559f93a0fa
|
4
|
+
data.tar.gz: 2cf9717de5125c0c81af464b93fe7a4bd78dfa0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fa9cde766ec7c9eef970fcd877489d5c63a69ba85f05bad4ce816f86f1ad37054ff804b5ea53b9a970b2a9b37c5338170a920540a0ad623b97df003d9d5b1c30
|
7
|
+
data.tar.gz: c66ff4d5b531c2768b92f1627fa06b027ee5ed4db1cb0255cc2761842574c82cf3f174aeb969b8bb0a3316e3848fd398b69082c10b86c8f00c847ab326cb58ca
|
data/.gitignore
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
!.gitignore
|
2
|
+
*.gem
|
3
|
+
*.rbc
|
4
|
+
*.sw[a-p]
|
5
|
+
*.tmproj
|
6
|
+
*.tmproject
|
7
|
+
*.un~
|
8
|
+
*~
|
9
|
+
.DS_Store
|
10
|
+
.Spotlight-V100
|
11
|
+
.Trashes
|
12
|
+
._*
|
13
|
+
.bundle
|
14
|
+
.config
|
15
|
+
.directory
|
16
|
+
.elc
|
17
|
+
.redcar
|
18
|
+
.yardoc
|
19
|
+
/.emacs.desktop
|
20
|
+
/.emacs.desktop.lock
|
21
|
+
Desktop.ini
|
22
|
+
Gemfile.lock
|
23
|
+
Icon?
|
24
|
+
InstalledFiles
|
25
|
+
Session.vim
|
26
|
+
Thumbs.db
|
27
|
+
\#*\#
|
28
|
+
_yardoc
|
29
|
+
auto-save-list
|
30
|
+
coverage
|
31
|
+
doc/
|
32
|
+
lib/bundler/man
|
33
|
+
pkg
|
34
|
+
pkg/*
|
35
|
+
rdoc
|
36
|
+
spec/reports
|
37
|
+
test/tmp
|
38
|
+
test/version_tmp
|
39
|
+
tmp
|
40
|
+
tmtags
|
41
|
+
tramp
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2011-2013 Dan Sosedoff.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to
|
8
|
+
do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
14
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
15
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
16
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
17
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
18
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
# Capistrano Unicorn
|
2
|
+
|
3
|
+
Capistrano 3.x plugin that integrates Unicorn tasks into capistrano deployment script.
|
4
|
+
Taken from https://github.com/sosedoff/capistrano-unicorn and adapted to work with Capistrano 3.x.
|
5
|
+
|
6
|
+
**Note: this code is not well tested, if anything fails, please report it. Use at your own risk.**
|
7
|
+
|
8
|
+
**Developers:** Please consider contributing your forked changes, or opening an
|
9
|
+
issue if there is no existing relevant one. There are a lot of forks--we'd love
|
10
|
+
to reabsorb some of the issues/solutions the community has encountered.
|
11
|
+
|
12
|
+
[](http://badge.fury.io/rb/sepastian-capistrano3-unicorn)
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
If you are upgrading from a previous version, please see the [NEWS file](NEWS.md).
|
17
|
+
|
18
|
+
### Setup
|
19
|
+
|
20
|
+
Add the library to your `Gemfile`:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
group :development do
|
24
|
+
gem 'sepastian-capistrano3-unicorn', :require => false
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
And load it into your deployment script `config/deploy.rb`:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'capistrano/unicorn'
|
32
|
+
```
|
33
|
+
|
34
|
+
Add unicorn restart task hook:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
after 'deploy:restart', 'unicorn:reload' # app IS NOT preloaded
|
38
|
+
after 'deploy:restart', 'unicorn:restart' # app preloaded
|
39
|
+
after 'deploy:restart', 'unicorn:duplicate' # before_fork hook implemented (zero downtime deployments)
|
40
|
+
```
|
41
|
+
|
42
|
+
Create a new configuration file `config/unicorn.rb` or `config/unicorn/STAGE.rb`,
|
43
|
+
where stage is your deployment environment.
|
44
|
+
|
45
|
+
Example config - [examples/rails3.rb](https://github.com/sosedoff/capistrano-unicorn/blob/master/examples/rails3.rb).
|
46
|
+
Please refer to Unicorn documentation for more examples and configuration options.
|
47
|
+
|
48
|
+
### Deploy
|
49
|
+
|
50
|
+
First, make sure you're running the latest release:
|
51
|
+
|
52
|
+
```
|
53
|
+
cap deploy
|
54
|
+
```
|
55
|
+
|
56
|
+
Then you can test each individual task:
|
57
|
+
|
58
|
+
```
|
59
|
+
cap unicorn:start
|
60
|
+
cap unicorn:stop
|
61
|
+
cap unicorn:reload
|
62
|
+
```
|
63
|
+
|
64
|
+
## Configuration
|
65
|
+
|
66
|
+
You can modify any of the following Capistrano variables in your `deploy.rb` config.
|
67
|
+
You can use the `unicorn:show_vars` task to check that the values you have specified
|
68
|
+
are set correctly.
|
69
|
+
|
70
|
+
### Environment parameters
|
71
|
+
|
72
|
+
- `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`.
|
73
|
+
- `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`.
|
74
|
+
|
75
|
+
### Execution parameters
|
76
|
+
|
77
|
+
- `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.
|
78
|
+
- `unicorn_roles` - Define which roles to perform unicorn recipes on. Defaults to `:app`.
|
79
|
+
- `unicorn_bundle` - Set bundler command for unicorn. Defaults to `bundle`.
|
80
|
+
- `unicorn_bin` - Set unicorn executable file. Defaults to `unicorn`.
|
81
|
+
- `unicorn_options` - Set any additional options to be passed to unicorn on startup.
|
82
|
+
- `unicorn_restart_sleep_time` - Number of seconds to wait for (old) pidfile to show up when restarting unicorn. Defaults to 2.
|
83
|
+
|
84
|
+
### Relative path parameters
|
85
|
+
|
86
|
+
- `app_subdir` - If your app lives in a subdirectory 'rails' (say) of your repository, set this to `/rails` (the leading slash is required).
|
87
|
+
- `unicorn_config_rel_path` - Set the directory path (relative to `app_path` - see below) where unicorn config files reside. Defaults to `config`.
|
88
|
+
- `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`.
|
89
|
+
|
90
|
+
### Absolute path parameters
|
91
|
+
|
92
|
+
- `app_path` - Set path to app root. Defaults to `current_path + app_subdir`.
|
93
|
+
- `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`
|
94
|
+
- `unicorn_default_pid` - See above. Defaults to `#{current_path}/tmp/pids/unicorn.pid`
|
95
|
+
- `bundle_gemfile` - Set path to Gemfile. Defaults to `#{app_path}/Gemfile`
|
96
|
+
- `unicorn_config_path` - Set the directory where unicorn config files reside. Defaults to `#{current_path}/config`.
|
97
|
+
|
98
|
+
### Zero Downtime Deployment Options
|
99
|
+
|
100
|
+
* `unicorn:restart`: :-1: This can sort of support it with a configurable timeout, which may not be reliable.
|
101
|
+
* `unicorn:reload`: :question: Can anyone testify to its zero-downtime support?
|
102
|
+
* `unicorn:duplicate`: :+1: If you install the Unicorn `before_fork` hook, then yes! See: https://github.com/sosedoff/capistrano-unicorn/issues/40#issuecomment-16011353
|
103
|
+
|
104
|
+
## Available Tasks
|
105
|
+
|
106
|
+
To get a list of all capistrano tasks, run `cap -T`:
|
107
|
+
|
108
|
+
```
|
109
|
+
cap unicorn:add_worker # Add a new worker
|
110
|
+
cap unicorn:remove_worker # Remove amount of workers
|
111
|
+
cap unicorn:reload # Reload Unicorn
|
112
|
+
cap unicorn:restart # Restart Unicorn
|
113
|
+
cap unicorn:show_vars # Debug Unicorn variables
|
114
|
+
cap unicorn:shutdown # Immediately shutdown Unicorn
|
115
|
+
cap unicorn:start # Start Unicorn master process
|
116
|
+
cap unicorn:stop # Stop Unicorn
|
117
|
+
```
|
118
|
+
|
119
|
+
## Tests
|
120
|
+
|
121
|
+
To execute test suite run:
|
122
|
+
|
123
|
+
```
|
124
|
+
bundle exec rake test
|
125
|
+
```
|
126
|
+
|
127
|
+
### Multistage
|
128
|
+
|
129
|
+
The issue here is that capistrano loads default configuration and then
|
130
|
+
executes your staging task and overrides previously defined
|
131
|
+
variables. The default environment before executing your stage task is
|
132
|
+
set to `:production`, so it will use a wrong environment unless you
|
133
|
+
take steps to ensure that `:rails_env` and `:unicorn_env` are
|
134
|
+
set correctly.
|
135
|
+
|
136
|
+
Let's say you have a scenario involving two deployment stages: staging
|
137
|
+
and production. You’ll need to add `config/deploy/staging.rb` and
|
138
|
+
`config/deploy/production.rb` files. However, it makes sense to
|
139
|
+
adhere to DRY and avoid duplicating lines between the two files. So
|
140
|
+
it would be nicer to keep common settings in `config/deploy.rb`, and
|
141
|
+
only put stuff in each staging definition file which is really
|
142
|
+
specific to that staging environment. Fortunately this can be done
|
143
|
+
using the [lazy evaluation form of `set`](https://github.com/capistrano/capistrano/wiki/2.x-DSL-Configuration-Variables-Set).
|
144
|
+
|
145
|
+
So `config/deploy.rb` file would contain something like:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
set :stages, %w(production staging)
|
149
|
+
set :default_stage, "staging"
|
150
|
+
require 'capistrano/ext/multistage'
|
151
|
+
|
152
|
+
role(:web) { domain }
|
153
|
+
role(:app) { domain }
|
154
|
+
role(:db, :primary => true) { domain }
|
155
|
+
|
156
|
+
set(:deploy_to) { "/home/#{user}/#{application}/#{fetch :rails_env}" }
|
157
|
+
set(:current_path) { File.join(deploy_to, current_dir) }
|
158
|
+
```
|
159
|
+
|
160
|
+
Then `config/deploy/production.rb` would contain something like:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
set :domain, "app.mydomain.com"
|
164
|
+
set :rails_env, "production"
|
165
|
+
```
|
166
|
+
|
167
|
+
and `config/deploy/staging.rb` would only need to contain something like:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
set :domain, "app.staging.mydomain.com"
|
171
|
+
set :rails_env, "staging"
|
172
|
+
```
|
173
|
+
|
174
|
+
Nice and clean!
|
175
|
+
|
176
|
+
## License
|
177
|
+
|
178
|
+
See LICENSE file for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/capistrano/unicorn/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "capistrano-unicorn-sic"
|
6
|
+
spec.version = CapistranoUnicorn::VERSION.dup
|
7
|
+
spec.author = "Sebastian Gassner, Dan Sosedoff, Florian Schwab"
|
8
|
+
spec.email = "sebastian.gassner@gmail.com"
|
9
|
+
spec.homepage = "https://github.com/SICSoftwareGmbH/capistrano-unicorn"
|
10
|
+
spec.summary = %q{Unicorn integration for Capistrano 3.x}
|
11
|
+
spec.description = %q{Capistrano 3.x plugin that integrates Unicorn server tasks.}
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
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"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "rake"
|
20
|
+
spec.add_development_dependency "unicorn"
|
21
|
+
spec.add_runtime_dependency "capistrano", "~> 3.0.0"
|
22
|
+
end
|
data/examples/rails3.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# ------------------------------------------------------------------------------
|
2
|
+
# Sample rails 3 config
|
3
|
+
# ------------------------------------------------------------------------------
|
4
|
+
|
5
|
+
# Set your full path to application.
|
6
|
+
app_path = "/path/to/app"
|
7
|
+
|
8
|
+
# Set unicorn options
|
9
|
+
worker_processes 1
|
10
|
+
preload_app true
|
11
|
+
timeout 180
|
12
|
+
listen "127.0.0.1:9000"
|
13
|
+
|
14
|
+
# Spawn unicorn master worker for user apps (group: apps)
|
15
|
+
user 'apps', 'apps'
|
16
|
+
|
17
|
+
# Fill path to your app
|
18
|
+
working_directory app_path
|
19
|
+
|
20
|
+
# Should be 'production' by default, otherwise use other env
|
21
|
+
rails_env = ENV['RAILS_ENV'] || 'production'
|
22
|
+
|
23
|
+
# Log everything to one file
|
24
|
+
stderr_path "log/unicorn.log"
|
25
|
+
stdout_path "log/unicorn.log"
|
26
|
+
|
27
|
+
# Set master PID location
|
28
|
+
pid "#{app_path}/tmp/pids/unicorn.pid"
|
29
|
+
|
30
|
+
before_fork do |server, worker|
|
31
|
+
ActiveRecord::Base.connection.disconnect!
|
32
|
+
|
33
|
+
old_pid = "#{server.config[:pid]}.oldbin"
|
34
|
+
if File.exists?(old_pid) && server.pid != old_pid
|
35
|
+
begin
|
36
|
+
Process.kill("QUIT", File.read(old_pid).to_i)
|
37
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
38
|
+
# someone else did our job for us
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
after_fork do |server, worker|
|
44
|
+
ActiveRecord::Base.establish_connection
|
45
|
+
end
|
File without changes
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'capistrano/unicorn/utility'
|
2
|
+
|
3
|
+
include CapistranoUnicorn::Utility
|
4
|
+
|
5
|
+
# Load default values the capistrano 3.x way.
|
6
|
+
# See https://github.com/capistrano/capistrano/pull/605
|
7
|
+
namespace :load do
|
8
|
+
task :defaults do
|
9
|
+
|
10
|
+
# Environments
|
11
|
+
set :unicorn_env , Proc.new{ fetch(:rails_env, 'production') }
|
12
|
+
# Following recommendations from http://unicorn.bogomips.org/unicorn_1.html
|
13
|
+
set :unicorn_rack_env, Proc.new{ fetch(:rails_env) == 'development' ? 'development' : 'deployment' }
|
14
|
+
|
15
|
+
# Execution
|
16
|
+
set :unicorn_user , nil
|
17
|
+
set :unicorn_bundle , Proc.new{ fetch(:bundle_cmd, "bundle") }
|
18
|
+
set :unicorn_bin , "unicorn"
|
19
|
+
set :unicorn_options , ''
|
20
|
+
set :unicorn_restart_sleep_time, 2
|
21
|
+
|
22
|
+
# Relative paths
|
23
|
+
set :app_subdir , ''
|
24
|
+
set :unicorn_config_rel_path , "config"
|
25
|
+
set :unicorn_config_filename , "unicorn.rb"
|
26
|
+
set :unicorn_config_rel_file_path , Proc.new{ File.join(fetch(:unicorn_config_rel_path), fetch(:unicorn_config_filename)) }
|
27
|
+
set :unicorn_config_stage_rel_file_path, Proc.new{ File.join(fetch(:unicorn_config_rel_path), 'unicorn', "#{fetch(:unicorn_env)}.rb") }
|
28
|
+
|
29
|
+
# Absolute paths
|
30
|
+
# If you find the following confusing, try running 'cap unicorn:show_vars' -
|
31
|
+
# it might help :-)
|
32
|
+
set :app_path , Proc.new{ File.join(current_path, fetch(:app_subdir)) }
|
33
|
+
set :unicorn_config_path , Proc.new{ File.join(fetch(:app_path), fetch(:unicorn_config_rel_path)) }
|
34
|
+
set :unicorn_config_file_path , Proc.new{ File.join(fetch(:app_path), fetch(:unicorn_config_rel_file_path)) }
|
35
|
+
set :unicorn_config_stage_file_path, Proc.new{ File.join(fetch(:app_path), fetch(:unicorn_config_stage_rel_file_path)) }
|
36
|
+
set :unicorn_default_pid , Proc.new{ File.join(fetch(:app_path), 'tmp', 'pids', 'unicorn.pid') }
|
37
|
+
set :unicorn_pid, Proc.new{
|
38
|
+
extracted_pid = extract_pid_file
|
39
|
+
if extracted_pid
|
40
|
+
extracted_pid
|
41
|
+
else
|
42
|
+
# TODO logger is not defined
|
43
|
+
#logger.important "err :: failed to auto-detect pid from #{local_unicorn_config}"
|
44
|
+
#logger.important "err :: falling back to default: #{unicorn_default_pid}"
|
45
|
+
fetch :unicorn_default_pid
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
namespace :unicorn do
|
52
|
+
desc 'Debug Unicorn variables'
|
53
|
+
task :show_vars do
|
54
|
+
on roles :app do
|
55
|
+
puts <<-EOF.gsub(/^ +/, '')
|
56
|
+
# Environments
|
57
|
+
rails_env #{fetch :rails_env}
|
58
|
+
unicorn_env #{fetch :unicorn_env}
|
59
|
+
unicorn_rack_env #{fetch :unicorn_rack_env}
|
60
|
+
|
61
|
+
# Execution
|
62
|
+
unicorn_user #{fetch(:unicorn_user).inspect}
|
63
|
+
unicorn_bundle #{fetch :unicorn_bundle}
|
64
|
+
unicorn_bin #{fetch :unicorn_bin}
|
65
|
+
unicorn_options #{fetch :unicorn_options}
|
66
|
+
unicorn_restart_sleep_time #{fetch :unicorn_restart_sleep_time}
|
67
|
+
|
68
|
+
# Relative paths
|
69
|
+
app_subdir #{fetch :app_subdir}
|
70
|
+
unicorn_config_rel_path #{fetch :unicorn_config_rel_path}
|
71
|
+
unicorn_config_filename #{fetch :unicorn_config_filename}
|
72
|
+
unicorn_config_rel_file_path #{fetch :unicorn_config_rel_file_path}
|
73
|
+
unicorn_config_stage_rel_file_path #{fetch :unicorn_config_stage_rel_file_path}
|
74
|
+
|
75
|
+
# Absolute paths
|
76
|
+
app_path #{fetch :app_path}
|
77
|
+
unicorn_pid #{fetch :unicorn_pid}
|
78
|
+
#bundle_gemfile #{fetch :bundle_gemfile}
|
79
|
+
unicorn_config_path #{fetch :unicorn_config_path}
|
80
|
+
unicorn_config_file_path #{fetch :unicorn_config_file_path}
|
81
|
+
unicorn_config_stage_file_path
|
82
|
+
-> "#{fetch :unicorn_config_stage_file_path}
|
83
|
+
EOF
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
desc 'Start Unicorn master process'
|
88
|
+
task :start do
|
89
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
90
|
+
execute start_unicorn
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'Stop Unicorn'
|
95
|
+
task :stop do
|
96
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
97
|
+
execute kill_unicorn('QUIT')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'Immediately shutdown Unicorn'
|
102
|
+
task :shutdown do
|
103
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
104
|
+
execute kill_unicorn('TERM')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'Restart Unicorn'
|
109
|
+
task :restart do
|
110
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
111
|
+
duplicate_unicorn
|
112
|
+
execute :sleep, fetch(:unicorn_restart_sleep_time)
|
113
|
+
|
114
|
+
if old_unicorn_is_running?
|
115
|
+
unicorn_send_signal('QUIT', get_old_unicorn_pid)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
desc 'Duplicate Unicorn'
|
121
|
+
task :duplicate do
|
122
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
123
|
+
duplicate_unicorn
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc 'Reload Unicorn'
|
128
|
+
task :reload do
|
129
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
130
|
+
if unicorn_is_running?
|
131
|
+
unicorn_send_signal('HUP')
|
132
|
+
else
|
133
|
+
start_unicorn
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Add a new worker'
|
139
|
+
task :add_worker do
|
140
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
141
|
+
if unicorn_is_running?
|
142
|
+
unicorn_send_signal('TTIN')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
desc 'Remove amount of workers'
|
148
|
+
task :remove_worker do
|
149
|
+
on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
|
150
|
+
if unicorn_is_running?
|
151
|
+
unicorn_send_signal('TTOU')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path(File.join('..', 'tasks', 'unicorn.cap'), __FILE__)
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module CapistranoUnicorn
|
4
|
+
module Utility
|
5
|
+
# In Capistrano 3, shell scripts must be invoked with SSHKit's execute, instead of run.
|
6
|
+
def local_unicorn_config
|
7
|
+
if File.exist? fetch(:unicorn_config_rel_file_path)
|
8
|
+
fetch(:unicorn_config_rel_file_path)
|
9
|
+
else
|
10
|
+
fetch(:unicorn_config_stage_rel_file_path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def extract_pid_file
|
15
|
+
tmp = Tempfile.new('unicorn.rb')
|
16
|
+
begin
|
17
|
+
conf = local_unicorn_config
|
18
|
+
tmp.write <<-EOF.gsub(/^ */, '')
|
19
|
+
config_file = "#{conf}"
|
20
|
+
|
21
|
+
# stub working_directory to avoid chdir failure since this will
|
22
|
+
# run client-side:
|
23
|
+
def working_directory(path); end
|
24
|
+
|
25
|
+
instance_eval(File.read(config_file), config_file) if config_file
|
26
|
+
puts set[:pid]
|
27
|
+
exit 0
|
28
|
+
EOF
|
29
|
+
tmp.close
|
30
|
+
extracted_pid = `unicorn -c "#{tmp.path}"`
|
31
|
+
$?.success? ? extracted_pid.rstrip : nil
|
32
|
+
rescue StandardError => e
|
33
|
+
return nil
|
34
|
+
ensure
|
35
|
+
tmp.close
|
36
|
+
tmp.unlink
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check if a remote process exists using its pid file
|
41
|
+
#
|
42
|
+
def remote_process_exists?(pid_file)
|
43
|
+
test("[ -e #{pid_file} ]") && unicorn_execute(:kill, '-0', "`cat #{pid_file}`", '> /dev/null 2>&1', raise_on_non_zero_exit: false)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Stale Unicorn process pid file
|
47
|
+
#
|
48
|
+
def old_unicorn_pid
|
49
|
+
"#{fetch :unicorn_pid}.oldbin"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Command to check if Unicorn is running
|
53
|
+
#
|
54
|
+
def unicorn_is_running?
|
55
|
+
remote_process_exists?(fetch(:unicorn_pid))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Command to check if stale Unicorn is running
|
59
|
+
#
|
60
|
+
def old_unicorn_is_running?
|
61
|
+
remote_process_exists?(old_unicorn_pid)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get unicorn master process PID (using the shell)
|
65
|
+
#
|
66
|
+
def get_unicorn_pid(pid_file=fetch(:unicorn_pid))
|
67
|
+
capture "cat #{pid_file}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get unicorn master (old) process PID
|
71
|
+
#
|
72
|
+
def get_old_unicorn_pid
|
73
|
+
get_unicorn_pid(old_unicorn_pid)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Send a signal to a unicorn master processes
|
77
|
+
#
|
78
|
+
def unicorn_send_signal(signal, pid=get_unicorn_pid)
|
79
|
+
unicorn_execute 'kill', '-s', signal, pid
|
80
|
+
end
|
81
|
+
|
82
|
+
# Run a unicorn command with or without sudo
|
83
|
+
# Run a command as the :unicorn_user user if :unicorn_user is a string.
|
84
|
+
# Otherwise run as default (:user) user.
|
85
|
+
#
|
86
|
+
def unicorn_execute(*args)
|
87
|
+
options = args.extract_options!
|
88
|
+
|
89
|
+
command = "bash -l -c \"#{args.join(' ')}\""
|
90
|
+
if unicorn_user = fetch(:unicorn_user)
|
91
|
+
execute :sudo, '-u', unicorn_user, command, options
|
92
|
+
else
|
93
|
+
execute command, options
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Kill Unicorns in multiple ways O_O
|
98
|
+
#
|
99
|
+
def kill_unicorn(signal)
|
100
|
+
if unicorn_is_running?
|
101
|
+
puts 'Stopping unicorn...'
|
102
|
+
unicorn_send_signal(signal)
|
103
|
+
else
|
104
|
+
puts 'Unicorn is not running'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Start the Unicorn server
|
109
|
+
#
|
110
|
+
def start_unicorn
|
111
|
+
if test("[ -e #{fetch(:unicorn_config_file_path)} ]")
|
112
|
+
unicorn_config_file_path = fetch(:unicorn_config_file_path)
|
113
|
+
elsif test("[ -e #{fetch(:unicorn_config_stage_file_path)} ]")
|
114
|
+
unicorn_config_file_path = fetch(:unicorn_config_stage_file_path)
|
115
|
+
else
|
116
|
+
fail "Config file for \"#{fetch(:unicorn_env)}\" environment was not found at either \"#{fetch(:unicorn_config_file_path)}\" or \"#{fetch(:unicorn_config_stage_file_path)}\""
|
117
|
+
end
|
118
|
+
|
119
|
+
if test("[ -e #{fetch(:unicorn_pid)} ]")
|
120
|
+
if unicorn_is_running?
|
121
|
+
puts 'Unicorn is already running!'
|
122
|
+
return
|
123
|
+
else
|
124
|
+
unicorn_execute :rm, fetch(:unicorn_pid)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
puts 'Starting unicorn...'
|
129
|
+
|
130
|
+
within fetch(:app_path) do
|
131
|
+
with rails_env: fetch(:rails_env), bundle_gemfile: fetch(:bundle_gemfile) do
|
132
|
+
unicorn_execute fetch(:unicorn_bin), '-c', unicorn_config_file_path, '-E', fetch(:unicorn_rack_env), '-D', fetch(:unicorn_options)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def duplicate_unicorn
|
138
|
+
if unicorn_is_running?
|
139
|
+
unicorn_send_signal('USR2')
|
140
|
+
else
|
141
|
+
start_unicorn
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def unicorn_roles
|
146
|
+
fetch(:unicorn_roles, :app)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/unicorn.rb
ADDED
File without changes
|
@@ -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
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-unicorn-sic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sebastian Gassner, Dan Sosedoff, Florian Schwab
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: unicorn
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
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.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.0
|
55
|
+
description: Capistrano 3.x plugin that integrates Unicorn server tasks.
|
56
|
+
email: sebastian.gassner@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ".gitignore"
|
62
|
+
- ".rspec"
|
63
|
+
- ".travis.yml"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE
|
66
|
+
- NEWS.md
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- capistrano-unicorn.gemspec
|
70
|
+
- examples/rails3.rb
|
71
|
+
- lib/capistrano-unicorn.rb
|
72
|
+
- lib/capistrano/tasks/unicorn.cap
|
73
|
+
- lib/capistrano/unicorn.rb
|
74
|
+
- lib/capistrano/unicorn/utility.rb
|
75
|
+
- lib/capistrano/unicorn/version.rb
|
76
|
+
- lib/unicorn.rb
|
77
|
+
- spec/capistrano_integration_spec.rb
|
78
|
+
- spec/config_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
homepage: https://github.com/SICSoftwareGmbH/capistrano-unicorn
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.2.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Unicorn integration for Capistrano 3.x
|
104
|
+
test_files:
|
105
|
+
- spec/capistrano_integration_spec.rb
|
106
|
+
- spec/config_spec.rb
|
107
|
+
- spec/spec_helper.rb
|