capistrano-sidekiq 0.20.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +286 -0
- data/Gemfile +4 -0
- data/README.md +46 -49
- data/Rakefile +8 -0
- data/capistrano-sidekiq.gemspec +3 -3
- data/lib/capistrano/sidekiq/helpers.rb +53 -0
- data/lib/capistrano/sidekiq/monit.rb +21 -2
- data/lib/capistrano/sidekiq/systemd.rb +19 -0
- data/lib/capistrano/sidekiq/version.rb +3 -3
- data/lib/capistrano/sidekiq.rb +30 -4
- data/lib/capistrano/tasks/monit.rake +64 -78
- data/lib/capistrano/tasks/sidekiq.rake +2 -250
- data/lib/capistrano/tasks/systemd.rake +296 -0
- data/lib/generators/capistrano/sidekiq/monit/templates/sidekiq_monit.conf.erb +8 -10
- data/lib/generators/capistrano/sidekiq/systemd/templates/sidekiq.service.capistrano.erb +68 -0
- metadata +28 -12
- data/CHANGELOG +0 -28
- data/CONTRIBUTORS.md +0 -11
- data/lib/capistrano/tasks/capistrano2.rb +0 -147
@@ -1,12 +1,4 @@
|
|
1
|
-
|
2
|
-
task :defaults do
|
3
|
-
set :sidekiq_monit_conf_dir, '/etc/monit/conf.d'
|
4
|
-
set :sidekiq_monit_use_sudo, true
|
5
|
-
set :monit_bin, '/usr/bin/monit'
|
6
|
-
set :sidekiq_monit_default_hooks, true
|
7
|
-
set :sidekiq_monit_templates_path, 'config/deploy/templates'
|
8
|
-
end
|
9
|
-
end
|
1
|
+
git_plugin = self
|
10
2
|
|
11
3
|
namespace :deploy do
|
12
4
|
before :starting, :check_sidekiq_monit_hooks do
|
@@ -18,7 +10,6 @@ end
|
|
18
10
|
|
19
11
|
namespace :sidekiq do
|
20
12
|
namespace :monit do
|
21
|
-
|
22
13
|
task :add_default_hooks do
|
23
14
|
before 'deploy:updating', 'sidekiq:monit:unmonitor'
|
24
15
|
after 'deploy:published', 'sidekiq:monit:monitor'
|
@@ -26,26 +17,28 @@ namespace :sidekiq do
|
|
26
17
|
|
27
18
|
desc 'Config Sidekiq monit-service'
|
28
19
|
task :config do
|
29
|
-
on roles(fetch(:
|
20
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
30
21
|
@role = role
|
31
|
-
upload_sidekiq_template 'sidekiq_monit', "#{fetch(:tmp_dir)}/monit.conf", @role
|
22
|
+
git_plugin.upload_sidekiq_template 'sidekiq_monit', "#{fetch(:tmp_dir)}/monit.conf", @role
|
32
23
|
|
33
|
-
|
34
|
-
|
24
|
+
git_plugin.switch_user(role) do
|
25
|
+
mv_command = "mv #{fetch(:tmp_dir)}/monit.conf #{fetch(:sidekiq_monit_conf_dir)}/#{fetch(:sidekiq_monit_conf_file)}"
|
35
26
|
|
36
|
-
|
27
|
+
git_plugin.sudo_if_needed mv_command
|
28
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} reload"
|
29
|
+
end
|
37
30
|
end
|
38
31
|
end
|
39
32
|
|
40
33
|
desc 'Monitor Sidekiq monit-service'
|
41
34
|
task :monitor do
|
42
|
-
on roles(fetch(:
|
43
|
-
|
35
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
36
|
+
git_plugin.switch_user(role) do
|
44
37
|
begin
|
45
|
-
sudo_if_needed "#{fetch(:monit_bin)} monitor #{sidekiq_service_name
|
38
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} monitor #{git_plugin.sidekiq_service_name}"
|
46
39
|
rescue
|
47
40
|
invoke 'sidekiq:monit:config'
|
48
|
-
sudo_if_needed "#{fetch(:monit_bin)} monitor #{sidekiq_service_name
|
41
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} monitor #{git_plugin.sidekiq_service_name}"
|
49
42
|
end
|
50
43
|
end
|
51
44
|
end
|
@@ -53,89 +46,82 @@ namespace :sidekiq do
|
|
53
46
|
|
54
47
|
desc 'Unmonitor Sidekiq monit-service'
|
55
48
|
task :unmonitor do
|
56
|
-
on roles(fetch(:
|
57
|
-
|
49
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
50
|
+
git_plugin.switch_user(role) do
|
58
51
|
begin
|
59
|
-
sudo_if_needed "#{fetch(:monit_bin)} unmonitor #{sidekiq_service_name
|
52
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} unmonitor #{git_plugin.sidekiq_service_name}"
|
60
53
|
rescue
|
61
54
|
# no worries here
|
62
55
|
end
|
63
56
|
end
|
64
57
|
end
|
65
58
|
end
|
59
|
+
end
|
66
60
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
desc 'Stop Sidekiq monit-service'
|
77
|
-
task :stop do
|
78
|
-
on roles(fetch(:sidekiq_role)) do
|
79
|
-
fetch(:sidekiq_processes).times do |idx|
|
80
|
-
sudo_if_needed "#{fetch(:monit_bin)} stop #{sidekiq_service_name(idx)}"
|
81
|
-
end
|
61
|
+
desc 'Start Sidekiq monit-service'
|
62
|
+
task :start do
|
63
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
64
|
+
git_plugin.switch_user(role) do
|
65
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} start #{git_plugin.sidekiq_service_name}"
|
82
66
|
end
|
83
67
|
end
|
68
|
+
end
|
84
69
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
70
|
+
desc 'Stop Sidekiq monit-service'
|
71
|
+
task :stop do
|
72
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
73
|
+
git_plugin.switch_user(role) do
|
74
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} stop #{git_plugin.sidekiq_service_name}"
|
91
75
|
end
|
92
76
|
end
|
77
|
+
end
|
93
78
|
|
94
|
-
|
95
|
-
|
79
|
+
desc 'Restart Sidekiq monit-service'
|
80
|
+
task :restart do
|
81
|
+
on roles(fetch(:sidekiq_roles)) do |role|
|
82
|
+
git_plugin.sudo_if_needed "#{fetch(:monit_bin)} restart #{git_plugin.sidekiq_service_name}"
|
96
83
|
end
|
84
|
+
end
|
97
85
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
end
|
86
|
+
def sidekiq_service_name
|
87
|
+
fetch(:sidekiq_service_name, "sidekiq_#{fetch(:application)}_#{fetch(:sidekiq_env)}")
|
88
|
+
end
|
103
89
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
90
|
+
def sudo_if_needed(command)
|
91
|
+
if use_sudo?
|
92
|
+
backend.execute :sudo, command
|
93
|
+
else
|
94
|
+
backend.execute command
|
108
95
|
end
|
96
|
+
end
|
109
97
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end.join(' ')
|
114
|
-
end
|
98
|
+
def use_sudo?
|
99
|
+
fetch(:sidekiq_monit_use_sudo)
|
100
|
+
end
|
115
101
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
102
|
+
def upload_sidekiq_template(from, to, role)
|
103
|
+
template = sidekiq_template(from, role)
|
104
|
+
backend.upload!(StringIO.new(ERB.new(template).result(binding)), to)
|
105
|
+
end
|
121
106
|
|
122
|
-
|
123
|
-
|
124
|
-
"--require #{fetch(:sidekiq_require)}"
|
125
|
-
end
|
126
|
-
end
|
107
|
+
def sidekiq_template(name, role)
|
108
|
+
local_template_directory = fetch(:sidekiq_monit_templates_path)
|
127
109
|
|
128
|
-
|
129
|
-
fetch(:
|
130
|
-
|
110
|
+
search_paths = [
|
111
|
+
"#{name}-#{role.hostname}-#{fetch(:stage)}.erb",
|
112
|
+
"#{name}-#{role.hostname}.erb",
|
113
|
+
"#{name}-#{fetch(:stage)}.erb",
|
114
|
+
"#{name}.erb"
|
115
|
+
].map { |filename| File.join(local_template_directory, filename) }
|
131
116
|
|
132
|
-
|
133
|
-
|
134
|
-
|
117
|
+
global_search_path = File.expand_path(
|
118
|
+
File.join(*%w[.. .. .. generators capistrano sidekiq monit templates], "#{name}.conf.erb"),
|
119
|
+
__FILE__
|
120
|
+
)
|
135
121
|
|
136
|
-
|
137
|
-
fetch(:sidekiq_monit_use_sudo)
|
138
|
-
end
|
122
|
+
search_paths << global_search_path
|
139
123
|
|
124
|
+
template_path = search_paths.detect { |path| File.file?(path) }
|
125
|
+
File.read(template_path)
|
140
126
|
end
|
141
127
|
end
|
@@ -1,262 +1,14 @@
|
|
1
|
-
namespace :load do
|
2
|
-
task :defaults do
|
3
|
-
set :sidekiq_default_hooks, -> { true }
|
4
|
-
|
5
|
-
set :sidekiq_pid, -> { File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid') }
|
6
|
-
set :sidekiq_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
|
7
|
-
set :sidekiq_log, -> { File.join(shared_path, 'log', 'sidekiq.log') }
|
8
|
-
set :sidekiq_timeout, -> { 10 }
|
9
|
-
set :sidekiq_role, -> { :app }
|
10
|
-
set :sidekiq_processes, -> { 1 }
|
11
|
-
set :sidekiq_options_per_process, -> { nil }
|
12
|
-
set :sidekiq_user, -> { nil }
|
13
|
-
# Rbenv, Chruby, 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
|
-
set :chruby_map_bins, fetch(:chruby_map_bins).to_a.concat(%w{ sidekiq sidekiqctl })
|
17
|
-
# Bundler integration
|
18
|
-
set :bundle_bins, fetch(:bundle_bins).to_a.concat(%w(sidekiq sidekiqctl))
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
1
|
namespace :deploy do
|
23
2
|
before :starting, :check_sidekiq_hooks do
|
24
3
|
invoke 'sidekiq:add_default_hooks' if fetch(:sidekiq_default_hooks)
|
25
4
|
end
|
26
|
-
after :publishing, :restart_sidekiq do
|
27
|
-
invoke 'sidekiq:restart' if fetch(:sidekiq_default_hooks)
|
28
|
-
end
|
29
5
|
end
|
30
6
|
|
31
7
|
namespace :sidekiq do
|
32
|
-
def for_each_process(reverse = false, &block)
|
33
|
-
pids = processes_pids
|
34
|
-
pids.reverse! if reverse
|
35
|
-
pids.each_with_index do |pid_file, idx|
|
36
|
-
within release_path do
|
37
|
-
yield(pid_file, idx)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def processes_pids
|
43
|
-
pids = []
|
44
|
-
sidekiq_roles = Array(fetch(:sidekiq_role))
|
45
|
-
sidekiq_roles.each do |role|
|
46
|
-
next unless host.roles.include?(role)
|
47
|
-
processes = fetch(:"#{ role }_processes") || fetch(:sidekiq_processes)
|
48
|
-
processes.times do |idx|
|
49
|
-
pids.push fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
pids
|
54
|
-
end
|
55
|
-
|
56
|
-
def pid_process_exists?(pid_file)
|
57
|
-
pid_file_exists?(pid_file) and test(*("kill -0 $( cat #{pid_file} )").split(' '))
|
58
|
-
end
|
59
|
-
|
60
|
-
def pid_file_exists?(pid_file)
|
61
|
-
test(*("[ -f #{pid_file} ]").split(' '))
|
62
|
-
end
|
63
|
-
|
64
|
-
def stop_sidekiq(pid_file)
|
65
|
-
if fetch(:stop_sidekiq_in_background, fetch(:sidekiq_run_in_background))
|
66
|
-
if fetch(:sidekiq_use_signals)
|
67
|
-
background "kill -TERM `cat #{pid_file}`"
|
68
|
-
else
|
69
|
-
background :sidekiqctl, 'stop', "#{pid_file}", fetch(:sidekiq_timeout)
|
70
|
-
end
|
71
|
-
else
|
72
|
-
execute :sidekiqctl, 'stop', "#{pid_file}", fetch(:sidekiq_timeout)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def quiet_sidekiq(pid_file)
|
77
|
-
if fetch(:sidekiq_use_signals)
|
78
|
-
background "kill -USR1 `cat #{pid_file}`"
|
79
|
-
else
|
80
|
-
begin
|
81
|
-
execute :sidekiqctl, 'quiet', "#{pid_file}"
|
82
|
-
rescue SSHKit::Command::Failed
|
83
|
-
# If gems are not installed eq(first deploy) and sidekiq_default_hooks as active
|
84
|
-
warn 'sidekiqctl not found (ignore if this is the first deploy)'
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def start_sidekiq(pid_file, idx = 0)
|
90
|
-
args = []
|
91
|
-
args.push "--index #{idx}"
|
92
|
-
args.push "--pidfile #{pid_file}"
|
93
|
-
args.push "--environment #{fetch(:sidekiq_env)}"
|
94
|
-
args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
95
|
-
args.push "--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require)
|
96
|
-
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
97
|
-
Array(fetch(:sidekiq_queue)).each do |queue|
|
98
|
-
args.push "--queue #{queue}"
|
99
|
-
end
|
100
|
-
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
101
|
-
args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
102
|
-
if process_options = fetch(:sidekiq_options_per_process)
|
103
|
-
args.push process_options[idx]
|
104
|
-
end
|
105
|
-
# use sidekiq_options for special options
|
106
|
-
args.push fetch(:sidekiq_options) if fetch(:sidekiq_options)
|
107
|
-
|
108
|
-
if defined?(JRUBY_VERSION)
|
109
|
-
args.push '>/dev/null 2>&1 &'
|
110
|
-
warn 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.'
|
111
|
-
else
|
112
|
-
args.push '--daemon'
|
113
|
-
end
|
114
|
-
|
115
|
-
if fetch(:start_sidekiq_in_background, fetch(:sidekiq_run_in_background))
|
116
|
-
background :sidekiq, args.compact.join(' ')
|
117
|
-
else
|
118
|
-
execute :sidekiq, args.compact.join(' ')
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
8
|
task :add_default_hooks do
|
123
|
-
after 'deploy:starting', 'sidekiq:quiet'
|
9
|
+
after 'deploy:starting', 'sidekiq:quiet' if Rake::Task.task_defined?('sidekiq:quiet')
|
124
10
|
after 'deploy:updated', 'sidekiq:stop'
|
125
|
-
after 'deploy:reverted', 'sidekiq:stop'
|
126
11
|
after 'deploy:published', 'sidekiq:start'
|
127
|
-
|
128
|
-
|
129
|
-
desc 'Quiet sidekiq (stop processing new tasks)'
|
130
|
-
task :quiet do
|
131
|
-
on roles fetch(:sidekiq_role) do |role|
|
132
|
-
switch_user(role) do
|
133
|
-
if test("[ -d #{release_path} ]") # fixes #11
|
134
|
-
for_each_process(true) do |pid_file, idx|
|
135
|
-
if pid_process_exists?(pid_file)
|
136
|
-
quiet_sidekiq(pid_file)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
desc 'Stop sidekiq'
|
145
|
-
task :stop do
|
146
|
-
on roles fetch(:sidekiq_role) do |role|
|
147
|
-
switch_user(role) do
|
148
|
-
if test("[ -d #{release_path} ]")
|
149
|
-
for_each_process(true) do |pid_file, idx|
|
150
|
-
if pid_process_exists?(pid_file)
|
151
|
-
stop_sidekiq(pid_file)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
desc 'Start sidekiq'
|
160
|
-
task :start do
|
161
|
-
on roles fetch(:sidekiq_role) do |role|
|
162
|
-
switch_user(role) do
|
163
|
-
for_each_process do |pid_file, idx|
|
164
|
-
start_sidekiq(pid_file, idx) unless pid_process_exists?(pid_file)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
desc 'Restart sidekiq'
|
171
|
-
task :restart do
|
172
|
-
invoke! 'sidekiq:stop'
|
173
|
-
invoke 'sidekiq:start'
|
174
|
-
end
|
175
|
-
|
176
|
-
desc 'Rolling-restart sidekiq'
|
177
|
-
task :rolling_restart do
|
178
|
-
on roles fetch(:sidekiq_role) do |role|
|
179
|
-
switch_user(role) do
|
180
|
-
for_each_process(true) do |pid_file, idx|
|
181
|
-
if pid_process_exists?(pid_file)
|
182
|
-
stop_sidekiq(pid_file)
|
183
|
-
end
|
184
|
-
start_sidekiq(pid_file, idx)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
# Delete any pid file not in use
|
191
|
-
task :cleanup do
|
192
|
-
on roles fetch(:sidekiq_role) do |role|
|
193
|
-
switch_user(role) do
|
194
|
-
for_each_process do |pid_file, idx|
|
195
|
-
if pid_file_exists?(pid_file)
|
196
|
-
execute "rm #{pid_file}" unless pid_process_exists?(pid_file)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
# TODO : Don't start if all processes are off, raise warning.
|
204
|
-
desc 'Respawn missing sidekiq processes'
|
205
|
-
task :respawn do
|
206
|
-
invoke 'sidekiq:cleanup'
|
207
|
-
on roles fetch(:sidekiq_role) do |role|
|
208
|
-
switch_user(role) do
|
209
|
-
for_each_process do |pid_file, idx|
|
210
|
-
unless pid_file_exists?(pid_file)
|
211
|
-
start_sidekiq(pid_file, idx)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
def switch_user(role, &block)
|
219
|
-
su_user = sidekiq_user(role)
|
220
|
-
if su_user == role.user
|
221
|
-
block.call
|
222
|
-
else
|
223
|
-
as su_user do
|
224
|
-
block.call
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def sidekiq_user(role)
|
230
|
-
properties = role.properties
|
231
|
-
properties.fetch(:sidekiq_user) || # local property for sidekiq only
|
232
|
-
fetch(:sidekiq_user) ||
|
233
|
-
properties.fetch(:run_as) || # global property across multiple capistrano gems
|
234
|
-
role.user
|
235
|
-
end
|
236
|
-
|
237
|
-
def upload_sidekiq_template(from, to, role)
|
238
|
-
template = sidekiq_template(from, role)
|
239
|
-
upload!(StringIO.new(ERB.new(template).result(binding)), to)
|
240
|
-
end
|
241
|
-
|
242
|
-
def sidekiq_template(name, role)
|
243
|
-
local_template_directory = fetch(:sidekiq_monit_templates_path)
|
244
|
-
|
245
|
-
search_paths = [
|
246
|
-
"#{name}-#{role.hostname}-#{fetch(:stage)}.erb",
|
247
|
-
"#{name}-#{role.hostname}.erb",
|
248
|
-
"#{name}-#{fetch(:stage)}.erb",
|
249
|
-
"#{name}.erb"
|
250
|
-
].map { |filename| File.join(local_template_directory, filename) }
|
251
|
-
|
252
|
-
global_search_path = File.expand_path(
|
253
|
-
File.join(*%w[.. .. .. generators capistrano sidekiq monit templates], "#{name}.conf.erb"),
|
254
|
-
__FILE__
|
255
|
-
)
|
256
|
-
|
257
|
-
search_paths << global_search_path
|
258
|
-
|
259
|
-
template_path = search_paths.detect { |path| File.file?(path) }
|
260
|
-
File.read(template_path)
|
12
|
+
after 'deploy:failed', 'sidekiq:restart'
|
261
13
|
end
|
262
14
|
end
|