capistrano-sidekiq-sic 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +5 -0
- data/README.md +103 -0
- data/Rakefile +1 -0
- data/capistrano-sidekiq.gemspec +22 -0
- data/lib/capistrano-sidekiq.rb +0 -0
- data/lib/capistrano/sidekiq.rb +5 -0
- data/lib/capistrano/sidekiq/monit.rb +2 -0
- data/lib/capistrano/sidekiq/version.rb +5 -0
- data/lib/capistrano/tasks/capistrano2.rb +107 -0
- data/lib/capistrano/tasks/monit.cap +127 -0
- data/lib/capistrano/tasks/sidekiq.cap +256 -0
- data/lib/generators/capistrano/sidekiq/monit/template_generator.rb +24 -0
- data/lib/generators/capistrano/sidekiq/monit/templates/sidekiq_monit.conf.erb +10 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fb62d16c47fa1006eb673e713680ac6ccff5cace
|
4
|
+
data.tar.gz: 10f77269e3488d9a10833e15601d4a5fde8bd889
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f1a7c7247cd08c3805ba80933027abadd27e55920a8d8876e2f206234ce892499c9e7d01cf52a29c79363b9feb86af86d47fb3bd2f1743465884ccf4703168ad
|
7
|
+
data.tar.gz: 40d763d18d9376fa776ce4256f74b12e8344d487af274e873ac74b748a6603fc66027688a67e04e79e334faf8d6449a7ac140bb86d1f02699e163314009fe681
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/capistrano-sidekiq.svg)](http://badge.fury.io/rb/capistrano-sidekiq)
|
2
|
+
[![Dependency Status](https://gemnasium.com/seuros/capistrano-sidekiq.svg)](https://gemnasium.com/seuros/capistrano-sidekiq)
|
3
|
+
|
4
|
+
# Capistrano::Sidekiq
|
5
|
+
|
6
|
+
Sidekiq integration for Capistrano
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'capistrano-sidekiq', github: 'seuros/capistrano-sidekiq'
|
13
|
+
|
14
|
+
or:
|
15
|
+
|
16
|
+
gem 'capistrano-sidekiq', group: :development
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
```ruby
|
25
|
+
# Capfile
|
26
|
+
|
27
|
+
require 'capistrano/sidekiq'
|
28
|
+
require 'capistrano/sidekiq/monit' #to require monit tasks # Only for capistrano3
|
29
|
+
```
|
30
|
+
|
31
|
+
|
32
|
+
Configurable options, shown here with defaults:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
:sidekiq_default_hooks => true
|
36
|
+
:sidekiq_pid => File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid')
|
37
|
+
:sidekiq_env => fetch(:rack_env, fetch(:rails_env, fetch(:stage)))
|
38
|
+
:sidekiq_log => File.join(shared_path, 'log', 'sidekiq.log')
|
39
|
+
:sidekiq_options => nil
|
40
|
+
:sidekiq_require => nil
|
41
|
+
:sidekiq_tag => nil
|
42
|
+
:sidekiq_config => nil
|
43
|
+
:sidekiq_queue => nil
|
44
|
+
:sidekiq_timeout => 10
|
45
|
+
:sidekiq_role => :app
|
46
|
+
:sidekiq_processes => 1
|
47
|
+
:sidekiq_concurrency => nil
|
48
|
+
:sidekiq_monit_templates_path => 'config/deploy/templates'
|
49
|
+
:sidekiq_cmd => "#{fetch(:bundle_cmd, "bundle")} exec sidekiq" # Only for capistrano2.5
|
50
|
+
:sidekiqctl_cmd => "#{fetch(:bundle_cmd, "bundle")} exec sidekiqctl" # Only for capistrano2.5
|
51
|
+
```
|
52
|
+
|
53
|
+
There is a known bug that prevents sidekiq from starting when pty is true
|
54
|
+
```ruby
|
55
|
+
set :pty, false
|
56
|
+
```
|
57
|
+
|
58
|
+
## Customizing the monit sidekiq templates
|
59
|
+
|
60
|
+
If you need change some config in redactor, you can
|
61
|
+
|
62
|
+
```
|
63
|
+
bundle exec rails generate capistrano:sidekiq:monit:template
|
64
|
+
|
65
|
+
```
|
66
|
+
|
67
|
+
## Changelog
|
68
|
+
- 0.3.9: Restore daemon flag from Monit template
|
69
|
+
- 0.3.8:
|
70
|
+
* Update monit template: use su instead of sudo / permit all Sidekiq options @bensie
|
71
|
+
* Unmonitor monit while deploy @Saicheg
|
72
|
+
- 0.3.7:
|
73
|
+
* fix capistrano2 task @tribble
|
74
|
+
* Run Sidekiq as daemon from Monit @dpaluy
|
75
|
+
- 0.3.5: Added :sidekiq_tag for capistrano2 @OscarBarrett
|
76
|
+
- 0.3.4: fix bug in sidekiq:start for capistrano 2 task
|
77
|
+
- 0.3.3: sidekiq:restart after deploy:restart added to default hooks
|
78
|
+
- 0.3.2: :sidekiq_queue accept an array
|
79
|
+
- 0.3.1: Fix logs @rottman, add concurrency option support @ungsophy
|
80
|
+
- 0.3.0: Fix monit task @andreygerasimchuk
|
81
|
+
- 0.2.9: Check if current directory exist @alexdunae
|
82
|
+
- 0.2.8: Added :sidekiq_queue & :sidekiq_config
|
83
|
+
- 0.2.7: Signal usage @penso
|
84
|
+
- 0.2.6: sidekiq:start check if sidekiq is running
|
85
|
+
- 0.2.5: bug fixes
|
86
|
+
- 0.2.4: Fast deploy with :sidekiq_run_in_background
|
87
|
+
- 0.2.3: Added monit tasks (alpha)
|
88
|
+
- 0.2.0: Added sidekiq:rolling_restart - @jlecour
|
89
|
+
|
90
|
+
## Contributors
|
91
|
+
|
92
|
+
- [Jérémy Lecour] (https://github.com/jlecour)
|
93
|
+
- [Fabien Penso] (https://github.com/penso)
|
94
|
+
- [Alex Dunae] (https://github.com/alexdunae)
|
95
|
+
- [andreygerasimchuk] (https://github.com/andreygerasimchuk)
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
1. Fork it
|
100
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
101
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
102
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
103
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'capistrano/sidekiq/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'capistrano-sidekiq-sic'
|
8
|
+
spec.version = Capistrano::Sidekiq::VERSION
|
9
|
+
spec.authors = ['Abdelkader Boudih', 'Florian Schwab']
|
10
|
+
spec.email = ['terminale@gmail.com', 'me@ydkn.de']
|
11
|
+
spec.summary = %q{Sidekiq integration for Capistrano}
|
12
|
+
spec.description = %q{Sidekiq integration for Capistrano}
|
13
|
+
spec.homepage = 'https://github.com/seuros/capistrano-sidekiq'
|
14
|
+
spec.license = 'LGPL-3.0'
|
15
|
+
|
16
|
+
spec.required_ruby_version = '>= 1.9.3'
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_dependency 'capistrano'
|
21
|
+
spec.add_dependency 'sidekiq'
|
22
|
+
end
|
File without changes
|
@@ -0,0 +1,107 @@
|
|
1
|
+
Capistrano::Configuration.instance.load do
|
2
|
+
|
3
|
+
_cset(:sidekiq_default_hooks) { true }
|
4
|
+
|
5
|
+
_cset(:sidekiq_pid) { File.join(shared_path, 'pids', 'sidekiq.pid') }
|
6
|
+
_cset(:sidekiq_env) { fetch(:rack_env, fetch(:rails_env, 'production')) }
|
7
|
+
_cset(:sidekiq_tag) { nil }
|
8
|
+
_cset(:sidekiq_log) { File.join(shared_path, 'log', 'sidekiq.log') }
|
9
|
+
|
10
|
+
_cset(:sidekiq_config) { "#{current_path}/config/sidekiq.yml" }
|
11
|
+
_cset(:sidekiq_options) { nil }
|
12
|
+
_cset(:sidekiq_queue) { nil }
|
13
|
+
|
14
|
+
_cset(:sidekiq_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec sidekiq" }
|
15
|
+
_cset(:sidekiqctl_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec sidekiqctl" }
|
16
|
+
|
17
|
+
_cset(:sidekiq_timeout) { 10 }
|
18
|
+
_cset(:sidekiq_role) { :app }
|
19
|
+
_cset(:sidekiq_processes) { 1 }
|
20
|
+
|
21
|
+
if fetch(:sidekiq_default_hooks)
|
22
|
+
before 'deploy:update_code', 'sidekiq:quiet'
|
23
|
+
after 'deploy:stop', 'sidekiq:stop'
|
24
|
+
after 'deploy:start', 'sidekiq:start'
|
25
|
+
before 'deploy:restart', 'sidekiq:restart'
|
26
|
+
end
|
27
|
+
|
28
|
+
namespace :sidekiq do
|
29
|
+
def for_each_process(&block)
|
30
|
+
fetch(:sidekiq_processes).times do |idx|
|
31
|
+
if idx.zero? && fetch(:sidekiq_processes) <= 1
|
32
|
+
pid_file = fetch(:sidekiq_pid)
|
33
|
+
else
|
34
|
+
pid_file = fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid")
|
35
|
+
end
|
36
|
+
yield(pid_file, idx)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def quiet_process(pid_file, idx)
|
41
|
+
run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} quiet #{pid_file} ; else echo 'Sidekiq is not running'; fi"
|
42
|
+
end
|
43
|
+
|
44
|
+
def stop_process(pid_file, idx)
|
45
|
+
run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} stop #{pid_file} #{fetch :sidekiq_timeout} ; else echo 'Sidekiq is not running' && if [ -f #{pid_file} ] ; then rm #{pid_file} ; fi ; fi"
|
46
|
+
end
|
47
|
+
|
48
|
+
def start_process(pid_file, idx)
|
49
|
+
args = []
|
50
|
+
args.push "--index #{idx}"
|
51
|
+
args.push "--pidfile #{pid_file}"
|
52
|
+
args.push "--environment #{fetch(:sidekiq_env)}"
|
53
|
+
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
54
|
+
args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
55
|
+
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
56
|
+
fetch(:sidekiq_queue).each do |queue|
|
57
|
+
args.push "--queue #{queue}"
|
58
|
+
end if fetch(:sidekiq_queue)
|
59
|
+
args.push fetch(:sidekiq_options)
|
60
|
+
|
61
|
+
if defined?(JRUBY_VERSION)
|
62
|
+
args.push '>/dev/null 2>&1 &'
|
63
|
+
logger.info 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.'
|
64
|
+
else
|
65
|
+
args.push '--daemon'
|
66
|
+
end
|
67
|
+
|
68
|
+
run "if [ -d #{current_path} ] && [ ! -f #{pid_file} ] || ! kill -0 `cat #{pid_file}` > /dev/null 2>&1; then cd #{current_path} ; #{fetch(:sidekiq_cmd)} #{args.compact.join(' ')} ; else echo 'Sidekiq is already running'; fi", pty: false
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'Quiet sidekiq (stop accepting new work)'
|
72
|
+
task :quiet, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
73
|
+
for_each_process do |pid_file, idx|
|
74
|
+
quiet_process(pid_file, idx)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'Stop sidekiq'
|
79
|
+
task :stop, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
80
|
+
for_each_process do |pid_file, idx|
|
81
|
+
stop_process(pid_file, idx)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
desc 'Start sidekiq'
|
86
|
+
task :start, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
87
|
+
for_each_process do |pid_file, idx|
|
88
|
+
start_process(pid_file, idx)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc 'Rolling-restart sidekiq'
|
93
|
+
task :rolling_restart, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
94
|
+
for_each_process do |pid_file, idx|
|
95
|
+
stop_process(pid_file, idx)
|
96
|
+
start_process(pid_file, idx)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
desc 'Restart sidekiq'
|
101
|
+
task :restart, roles: lambda { fetch(:sidekiq_role) }, on_no_matching_servers: :continue do
|
102
|
+
stop
|
103
|
+
start
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :sidekiq_monit_conf_dir, -> { '/etc/monit/conf.d' }
|
4
|
+
set :monit_bin, -> { '/usr/bin/monit' }
|
5
|
+
set :sidekiq_monit_default_hooks, -> { true }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
namespace :deploy do
|
10
|
+
before :starting, :check_sidekiq_monit_hooks do
|
11
|
+
if fetch(:sidekiq_default_hooks) && fetch(:sidekiq_monit_default_hooks)
|
12
|
+
invoke 'sidekiq:monit:add_default_hooks'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
namespace :sidekiq do
|
18
|
+
namespace :monit do
|
19
|
+
|
20
|
+
task :add_default_hooks do
|
21
|
+
before 'deploy:updating', 'sidekiq:monit:unmonitor'
|
22
|
+
after 'deploy:published', 'sidekiq:monit:monitor'
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Config Sidekiq monit-service'
|
26
|
+
task :config do
|
27
|
+
on roles(fetch(:sidekiq_role)) do |role|
|
28
|
+
@role = role
|
29
|
+
template_sidekiq 'sidekiq_monit', "#{fetch(:tmp_dir)}/monit.conf", @role
|
30
|
+
|
31
|
+
mv_command = "mv #{fetch(:tmp_dir)}/monit.conf #{fetch(:sidekiq_monit_conf_dir)}/#{sidekiq_service_name}.conf"
|
32
|
+
|
33
|
+
# Try execute in case the deploy user doesn't have sudo to mv
|
34
|
+
begin
|
35
|
+
execute mv_command
|
36
|
+
rescue
|
37
|
+
sudo mv_command
|
38
|
+
end
|
39
|
+
|
40
|
+
sudo "#{fetch(:monit_bin)} reload"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'Monitor Sidekiq monit-service'
|
45
|
+
task :monitor do
|
46
|
+
on roles(fetch(:sidekiq_role)) do
|
47
|
+
fetch(:sidekiq_processes).times do |idx|
|
48
|
+
begin
|
49
|
+
sudo "#{fetch(:monit_bin)} monitor #{sidekiq_service_name(idx)}"
|
50
|
+
rescue
|
51
|
+
invoke 'sidekiq:monit:config'
|
52
|
+
sudo "#{fetch(:monit_bin)} monitor #{sidekiq_service_name(idx)}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Unmonitor Sidekiq monit-service'
|
59
|
+
task :unmonitor do
|
60
|
+
on roles(fetch(:sidekiq_role)) do
|
61
|
+
fetch(:sidekiq_processes).times do |idx|
|
62
|
+
begin
|
63
|
+
sudo "#{fetch(:monit_bin)} unmonitor #{sidekiq_service_name(idx)}"
|
64
|
+
rescue
|
65
|
+
# no worries here
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'Start Sidekiq monit-service'
|
72
|
+
task :start do
|
73
|
+
on roles(fetch(:sidekiq_role)) do
|
74
|
+
fetch(:sidekiq_processes).times do |idx|
|
75
|
+
sudo "#{fetch(:monit_bin)} start #{sidekiq_service_name(idx)}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
desc 'Stop Sidekiq monit-service'
|
81
|
+
task :stop do
|
82
|
+
on roles(fetch(:sidekiq_role)) do
|
83
|
+
fetch(:sidekiq_processes).times do |idx|
|
84
|
+
sudo "#{fetch(:monit_bin)} stop #{sidekiq_service_name(idx)}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'Restart Sidekiq monit-service'
|
90
|
+
task :restart do
|
91
|
+
on roles(fetch(:sidekiq_role)) do
|
92
|
+
fetch(:sidekiq_processes).times do |idx|
|
93
|
+
sudo "#{fetch(:monit_bin)} restart #{sidekiq_service_name(idx)}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def sidekiq_service_name(index=nil)
|
99
|
+
fetch(:sidekiq_service_name, "sidekiq_#{fetch(:application)}_#{fetch(:sidekiq_env)}") + index.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
def sidekiq_config
|
103
|
+
if fetch(:sidekiq_config)
|
104
|
+
"--config #{fetch(:sidekiq_config)}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def sidekiq_concurrency
|
109
|
+
if fetch(:sidekiq_concurrency)
|
110
|
+
"--concurrency #{fetch(:sidekiq_concurrency)}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def sidekiq_queues
|
115
|
+
Array(fetch(:sidekiq_queue)).map do |queue|
|
116
|
+
"--queue #{queue}"
|
117
|
+
end.join(' ')
|
118
|
+
end
|
119
|
+
|
120
|
+
def sidekiq_logfile
|
121
|
+
if fetch(:sidekiq_log)
|
122
|
+
"--logfile #{fetch(:sidekiq_log)}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :sidekiq_default_hooks, -> { true }
|
4
|
+
|
5
|
+
set :sidekiq_cmd, -> { 'sidekiq' }
|
6
|
+
set :sidekiqctl_cmd, -> { 'sidekiqctl' }
|
7
|
+
set :sidekiq_pid, -> { File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid') }
|
8
|
+
set :sidekiq_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
|
9
|
+
set :sidekiq_log, -> { File.join(shared_path, 'log', 'sidekiq.log') }
|
10
|
+
set :sidekiq_timeout, -> { 10 }
|
11
|
+
set :sidekiq_role, -> { :app }
|
12
|
+
set :sidekiq_processes, -> { 1 }
|
13
|
+
# Rbenv and RVM integration
|
14
|
+
set :rbenv_map_bins, fetch(:rbenv_map_bins).to_a.concat(%w(sidekiq sidekiqctl))
|
15
|
+
set :rvm_map_bins, fetch(:rvm_map_bins).to_a.concat(%w(sidekiq sidekiqctl))
|
16
|
+
|
17
|
+
set :sidekiq_monit_templates_path, -> { 'config/deploy/templates' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
namespace :deploy do
|
23
|
+
before :starting, :check_sidekiq_hooks do
|
24
|
+
invoke 'sidekiq:add_default_hooks' if fetch(:sidekiq_default_hooks)
|
25
|
+
end
|
26
|
+
after :publishing, :restart_sidekiq do
|
27
|
+
invoke 'sidekiq:restart' if fetch(:sidekiq_default_hooks)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
namespace :sidekiq do
|
32
|
+
def sidekiq_cmd
|
33
|
+
fetch(:sidekiq_cmd).split(/\s+/)
|
34
|
+
end
|
35
|
+
|
36
|
+
def sidekiqctl_cmd
|
37
|
+
fetch(:sidekiqctl_cmd).split(/\s+/)
|
38
|
+
end
|
39
|
+
|
40
|
+
def sidekiq_execute(*args)
|
41
|
+
options = args.extract_options!
|
42
|
+
|
43
|
+
run_in_background = options.delete(:background)
|
44
|
+
|
45
|
+
cmd = []
|
46
|
+
command = "bash -l -c \"#{args.join(' ')}\""
|
47
|
+
|
48
|
+
puts fetch(:sidekiq_user).inspect
|
49
|
+
|
50
|
+
if sidekiq_user = fetch(:sidekiq_user)
|
51
|
+
cmd += [:sudo, '-u', sidekiq_user, command]
|
52
|
+
else
|
53
|
+
cmd += args
|
54
|
+
end
|
55
|
+
|
56
|
+
within fetch(:app_path) do
|
57
|
+
with rails_env: fetch(:rails_env), bundle_gemfile: fetch(:bundle_gemfile) do
|
58
|
+
if run_in_background
|
59
|
+
background *cmd, options
|
60
|
+
else
|
61
|
+
execute *cmd, options
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def for_each_process(reverse = false, &block)
|
68
|
+
pids = processes_pids
|
69
|
+
pids.reverse! if reverse
|
70
|
+
pids.each_with_index do |pid_file, idx|
|
71
|
+
within release_path do
|
72
|
+
yield(pid_file, idx)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def processes_pids
|
78
|
+
pids = []
|
79
|
+
fetch(:sidekiq_processes).times do |idx|
|
80
|
+
pids.push (idx.zero? && fetch(:sidekiq_processes) <= 1) ?
|
81
|
+
fetch(:sidekiq_pid) :
|
82
|
+
fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid")
|
83
|
+
|
84
|
+
end
|
85
|
+
pids
|
86
|
+
end
|
87
|
+
|
88
|
+
def pid_process_exists?(pid_file)
|
89
|
+
pid_file_exists?(pid_file) and sidekiq_execute(:kill, '-0', "`cat #{pid_file}`", '> /dev/null 2>&1', raise_on_non_zero_exit: false)
|
90
|
+
end
|
91
|
+
|
92
|
+
def pid_file_exists?(pid_file)
|
93
|
+
test(*("[ -f #{pid_file} ]").split(' '))
|
94
|
+
end
|
95
|
+
|
96
|
+
def stop_sidekiq(pid_file)
|
97
|
+
if fetch(:stop_sidekiq_in_background, fetch(:sidekiq_run_in_background))
|
98
|
+
if fetch(:sidekiq_use_signals)
|
99
|
+
sidekiq_execute "kill -TERM `cat #{pid_file}`", background: true
|
100
|
+
else
|
101
|
+
sidekiq_execute *sidekiqctl_cmd, 'stop', "#{pid_file}", fetch(:sidekiq_timeout), background: true
|
102
|
+
end
|
103
|
+
else
|
104
|
+
sidekiq_execute *sidekiqctl_cmd, 'stop', "#{pid_file}", fetch(:sidekiq_timeout)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def quiet_sidekiq(pid_file)
|
109
|
+
if fetch(:sidekiq_use_signals)
|
110
|
+
sidekiq_execute "kill -USR1 `cat #{pid_file}`", background: true
|
111
|
+
else
|
112
|
+
begin
|
113
|
+
sidekiq_execute *sidekiqctl_cmd, 'quiet', "#{pid_file}"
|
114
|
+
rescue SSHKit::Command::Failed
|
115
|
+
# If gems are not installed eq(first deploy) and sidekiq_default_hooks as active
|
116
|
+
warn 'sidekiqctl not found (ignore if this is the first deploy)'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def start_sidekiq(pid_file, idx = 0)
|
122
|
+
args = []
|
123
|
+
args.push "--index #{idx}"
|
124
|
+
args.push "--pidfile #{pid_file}"
|
125
|
+
args.push "--environment #{fetch(:sidekiq_env)}"
|
126
|
+
args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
127
|
+
args.push "--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require)
|
128
|
+
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
129
|
+
Array(fetch(:sidekiq_queue)).each do |queue|
|
130
|
+
args.push "--queue #{queue}"
|
131
|
+
end
|
132
|
+
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
133
|
+
args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
134
|
+
# use sidekiq_options for special options
|
135
|
+
args.push fetch(:sidekiq_options) if fetch(:sidekiq_options)
|
136
|
+
|
137
|
+
if defined?(JRUBY_VERSION)
|
138
|
+
args.push '>/dev/null 2>&1 &'
|
139
|
+
warn 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.'
|
140
|
+
else
|
141
|
+
args.push '--daemon'
|
142
|
+
end
|
143
|
+
|
144
|
+
if fetch(:start_sidekiq_in_background, fetch(:sidekiq_run_in_background))
|
145
|
+
sidekiq_execute *sidekiq_cmd, args.compact.join(' '), background: true
|
146
|
+
else
|
147
|
+
sidekiq_execute *sidekiq_cmd, args.compact.join(' ')
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
task :add_default_hooks do
|
152
|
+
after 'deploy:starting', 'sidekiq:quiet'
|
153
|
+
after 'deploy:updated', 'sidekiq:stop'
|
154
|
+
after 'deploy:reverted', 'sidekiq:stop'
|
155
|
+
after 'deploy:published', 'sidekiq:start'
|
156
|
+
end
|
157
|
+
|
158
|
+
desc 'Quiet sidekiq (stop processing new tasks)'
|
159
|
+
task :quiet do
|
160
|
+
on roles fetch(:sidekiq_role) do
|
161
|
+
if test("[ -d #{release_path} ]") # fixes #11
|
162
|
+
for_each_process(true) do |pid_file, idx|
|
163
|
+
if pid_process_exists?(pid_file)
|
164
|
+
quiet_sidekiq(pid_file)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
desc 'Stop sidekiq'
|
172
|
+
task :stop do
|
173
|
+
on roles fetch(:sidekiq_role) do
|
174
|
+
if test("[ -d #{release_path} ]")
|
175
|
+
for_each_process(true) do |pid_file, idx|
|
176
|
+
if pid_process_exists?(pid_file)
|
177
|
+
stop_sidekiq(pid_file)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
desc 'Start sidekiq'
|
185
|
+
task :start do
|
186
|
+
on roles fetch(:sidekiq_role) do
|
187
|
+
for_each_process do |pid_file, idx|
|
188
|
+
start_sidekiq(pid_file, idx) unless pid_process_exists?(pid_file)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
desc 'Restart sidekiq'
|
194
|
+
task :restart do
|
195
|
+
invoke 'sidekiq:stop'
|
196
|
+
invoke 'sidekiq:start'
|
197
|
+
end
|
198
|
+
|
199
|
+
desc 'Rolling-restart sidekiq'
|
200
|
+
task :rolling_restart do
|
201
|
+
on roles fetch(:sidekiq_role) do
|
202
|
+
for_each_process(true) do |pid_file, idx|
|
203
|
+
if pid_process_exists?(pid_file)
|
204
|
+
stop_sidekiq(pid_file)
|
205
|
+
end
|
206
|
+
start_sidekiq(pid_file, idx)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Delete any pid file not in use
|
212
|
+
task :cleanup do
|
213
|
+
on roles fetch(:sidekiq_role) do
|
214
|
+
for_each_process do |pid_file, idx|
|
215
|
+
if pid_file_exists?(pid_file)
|
216
|
+
sidekiq_execute "rm #{pid_file}" unless pid_process_exists?(pid_file)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# TODO : Don't start if all processes are off, raise warning.
|
223
|
+
desc 'Respawn missing sidekiq processes'
|
224
|
+
task :respawn do
|
225
|
+
invoke 'sidekiq:cleanup'
|
226
|
+
on roles fetch(:sidekiq_role) do
|
227
|
+
for_each_process do |pid_file, idx|
|
228
|
+
unless pid_file_exists?(pid_file)
|
229
|
+
start_sidekiq(pid_file, idx)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def template_sidekiq(from, to, role)
|
236
|
+
[
|
237
|
+
"#{fetch(:sidekiq_monit_templates_path)}/#{from}.erb",
|
238
|
+
File.join('lib', 'capistrano', 'templates', "#{from}-#{role.hostname}-#{fetch(:stage)}.conf.rb"),
|
239
|
+
File.join('lib', 'capistrano', 'templates', "#{from}-#{role.hostname}-#{fetch(:stage)}.conf.rb"),
|
240
|
+
File.join('lib', 'capistrano', 'templates', "#{from}-#{role.hostname}.conf.rb"),
|
241
|
+
File.join('lib', 'capistrano', 'templates', "#{from}-#{fetch(:stage)}.conf.rb"),
|
242
|
+
File.join('lib', 'capistrano', 'templates', "#{from}.conf.rb.erb"),
|
243
|
+
File.join('lib', 'capistrano', 'templates', "#{from}.conf.rb"),
|
244
|
+
File.join('lib', 'capistrano', 'templates', "#{from}.conf.erb"),
|
245
|
+
File.expand_path("../../../generators/capistrano/sidekiq/monit/templates/#{from}.conf.rb.erb", __FILE__),
|
246
|
+
File.expand_path("../../../generators/capistrano/sidekiq/monit/templates/#{from}.conf.erb", __FILE__)
|
247
|
+
].each do |path|
|
248
|
+
if File.file?(path)
|
249
|
+
erb = File.read(path)
|
250
|
+
upload! StringIO.new(ERB.new(erb).result(binding)), to
|
251
|
+
break
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Capistrano
|
4
|
+
module Sidekiq
|
5
|
+
module Monit
|
6
|
+
module Generators
|
7
|
+
class TemplateGenerator < Rails::Generators::Base
|
8
|
+
|
9
|
+
namespace "capistrano:sidekiq:monit:template"
|
10
|
+
desc "Create local monitrc.erb, and erb files for monitored processes for customization"
|
11
|
+
source_root File.expand_path('../templates', __FILE__)
|
12
|
+
argument :templates_path, type: :string,
|
13
|
+
default: "config/deploy/templates",
|
14
|
+
banner: "path to templates"
|
15
|
+
|
16
|
+
def copy_template
|
17
|
+
copy_file "sidekiq_monit.conf.erb", "#{templates_path}/sidekiq_monit.erb"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Monit configuration for Sidekiq : <%= fetch(:application) %>
|
2
|
+
<% processes_pids.each_with_index do |pid_file, idx| %>
|
3
|
+
check process <%= sidekiq_service_name(idx) %>
|
4
|
+
with pidfile "<%= pid_file %>"
|
5
|
+
start program = "/bin/su - <%= @role.user %> -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:bundle] %> exec sidekiq <%= sidekiq_config %> --index <%= idx %> --pidfile <%= pid_file %> --environment <%= fetch(:sidekiq_env) %> <%= sidekiq_concurrency %> <%= sidekiq_logfile %> <%= sidekiq_queues %> -d'" with timeout 30 seconds
|
6
|
+
|
7
|
+
stop program = "/bin/su - <%= @role.user %> -c 'cd <%= current_path %> && <%= SSHKit.config.command_map[:bundle] %> exec sidekiqctl stop <%= pid_file %>'" with timeout <%= fetch(:sidekiq_timeout).to_i + 10 %> seconds
|
8
|
+
group <%= fetch(:sidekiq_monit_group, fetch(:application)) %>-sidekiq
|
9
|
+
|
10
|
+
<% end %>
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-sidekiq-sic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Abdelkader Boudih
|
8
|
+
- Florian Schwab
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-03-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: capistrano
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: sidekiq
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
description: Sidekiq integration for Capistrano
|
43
|
+
email:
|
44
|
+
- terminale@gmail.com
|
45
|
+
- me@ydkn.de
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- ".gitignore"
|
51
|
+
- Gemfile
|
52
|
+
- LICENSE.txt
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- capistrano-sidekiq.gemspec
|
56
|
+
- lib/capistrano-sidekiq.rb
|
57
|
+
- lib/capistrano/sidekiq.rb
|
58
|
+
- lib/capistrano/sidekiq/monit.rb
|
59
|
+
- lib/capistrano/sidekiq/version.rb
|
60
|
+
- lib/capistrano/tasks/capistrano2.rb
|
61
|
+
- lib/capistrano/tasks/monit.cap
|
62
|
+
- lib/capistrano/tasks/sidekiq.cap
|
63
|
+
- lib/generators/capistrano/sidekiq/monit/template_generator.rb
|
64
|
+
- lib/generators/capistrano/sidekiq/monit/templates/sidekiq_monit.conf.erb
|
65
|
+
homepage: https://github.com/seuros/capistrano-sidekiq
|
66
|
+
licenses:
|
67
|
+
- LGPL-3.0
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.9.3
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.4.5
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Sidekiq integration for Capistrano
|
89
|
+
test_files: []
|
90
|
+
has_rdoc:
|