capistrano-sidekiq-sic 0.4.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 +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
|
+
[](http://badge.fury.io/rb/capistrano-sidekiq)
|
2
|
+
[](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:
|