capistrano_multiconfig_parallel 0.20.9 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/capistrano_multiconfig_parallel/application.rb +6 -6
- data/lib/capistrano_multiconfig_parallel/base.rb +1 -2
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_manager.rb +41 -36
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_worker.rb +14 -17
- data/lib/capistrano_multiconfig_parallel/celluloid/child_process.rb +6 -6
- data/lib/capistrano_multiconfig_parallel/celluloid/terminal_table.rb +22 -30
- data/lib/capistrano_multiconfig_parallel/celluloid/web_server.rb +1 -1
- data/lib/capistrano_multiconfig_parallel/classes/dependency_tracker.rb +2 -2
- data/lib/capistrano_multiconfig_parallel/classes/interactive_menu.rb +1 -1
- data/lib/capistrano_multiconfig_parallel/classes/job.rb +33 -6
- data/lib/capistrano_multiconfig_parallel/classes/job_command.rb +1 -1
- data/lib/capistrano_multiconfig_parallel/classes/{rake_hook_actor.rb → rake_task_hooks.rb} +2 -2
- data/lib/capistrano_multiconfig_parallel/cli.rb +3 -2
- data/lib/capistrano_multiconfig_parallel/helpers/application_helper.rb +7 -1
- data/lib/capistrano_multiconfig_parallel/helpers/configuration.rb +1 -1
- data/lib/capistrano_multiconfig_parallel/helpers/core_helper.rb +17 -20
- data/lib/capistrano_multiconfig_parallel/initializers/rake.rb +3 -3
- data/lib/capistrano_multiconfig_parallel/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba9973965ea61da495ec59d3cd50c8465267532a
|
4
|
+
data.tar.gz: ac92a48585d8b7491120f898a38b8a5fc9439316
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee5a2f3d237b7eeca37eb51b9358f3cce6b47fec61dcfa1923fa5bf014299b65a238c0a72f03ee3a7eca1b16afb0c6c3747ccd6e00d1f885e9d14fa827f4bf77
|
7
|
+
data.tar.gz: 5c70b0cdb8b7a347babfba5fdeaad76c99128d4f66f2b22f5473d628e1c66796148ec17881b9626d21874b7c5bcd1a0cbefa21eb15361bf68eb74dee73b35423
|
@@ -17,14 +17,14 @@ module CapistranoMulticonfigParallel
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def start
|
20
|
-
verify_app_dependencies if multi_apps? &&
|
20
|
+
verify_app_dependencies if multi_apps? && configuration.application_dependencies.present?
|
21
21
|
check_before_starting
|
22
22
|
initialize_data
|
23
23
|
run
|
24
24
|
end
|
25
25
|
|
26
26
|
def verify_app_dependencies
|
27
|
-
wrong =
|
27
|
+
wrong = configuration.application_dependencies.find do |hash|
|
28
28
|
!@stage_apps.include?(hash[:app]) || (hash[:dependencies].present? && hash[:dependencies].find { |val| !@stage_apps.include?(val) })
|
29
29
|
end
|
30
30
|
raise ArgumentError, "Invalid configuration for #{wrong.inspect}".red if wrong.present?
|
@@ -93,7 +93,7 @@ module CapistranoMulticonfigParallel
|
|
93
93
|
def check_before_starting
|
94
94
|
CapistranoMulticonfigParallel.enable_logging
|
95
95
|
@dependency_tracker = CapistranoMulticonfigParallel::DependencyTracker.new(Actor.current)
|
96
|
-
@default_stage =
|
96
|
+
@default_stage = configuration.development_stages.present? ? configuration.development_stages.first : 'development'
|
97
97
|
@condition = Celluloid::Condition.new
|
98
98
|
@manager = CapistranoMulticonfigParallel::CelluloidManager.new(Actor.current)
|
99
99
|
end
|
@@ -110,7 +110,7 @@ module CapistranoMulticonfigParallel
|
|
110
110
|
def process_jobs
|
111
111
|
return unless @jobs.present?
|
112
112
|
FileUtils.rm Dir["#{log_directory}/worker_*.log"]
|
113
|
-
if
|
113
|
+
if configuration.multi_secvential.to_s.downcase == 'true'
|
114
114
|
@jobs.each(&:execute_standard_deploy)
|
115
115
|
else
|
116
116
|
run_async_jobs
|
@@ -177,7 +177,7 @@ module CapistranoMulticonfigParallel
|
|
177
177
|
options = options.stringify_keys
|
178
178
|
main_box_name = @argv['BOX'].blank? ? '' : @argv['BOX']
|
179
179
|
stage = options.fetch('stage', @default_stage)
|
180
|
-
if
|
180
|
+
if configuration.development_stages.include?(stage) && main_box_name.present? && /^[a-z0-9,]+/.match(main_box_name)
|
181
181
|
execute_on_multiple_boxes(main_box_name, options)
|
182
182
|
else
|
183
183
|
prepare_job(options)
|
@@ -198,7 +198,7 @@ module CapistranoMulticonfigParallel
|
|
198
198
|
end
|
199
199
|
|
200
200
|
def wait_jobs_termination
|
201
|
-
return if
|
201
|
+
return if configuration.multi_secvential.to_s.downcase == 'true'
|
202
202
|
result = @condition.wait
|
203
203
|
return unless result.present?
|
204
204
|
@manager.terminate
|
@@ -55,12 +55,12 @@ module CapistranoMulticonfigParallel
|
|
55
55
|
@worker_to_job[worker.mailbox.address] = job
|
56
56
|
log_to_file("worker #{worker.job_id} registed into manager")
|
57
57
|
Actor.current.link worker
|
58
|
-
worker.async.start_task
|
58
|
+
worker.async.start_task if !syncronized_confirmation? || job.failed? || job.rolling_back?
|
59
59
|
@registration_complete = true if @job_manager.jobs.size == @job_to_worker.size
|
60
60
|
end
|
61
61
|
|
62
62
|
def all_workers_finished?
|
63
|
-
@
|
63
|
+
@jobs.all? { |_job_id, job| job.finished? || job.crashed? || job.rolling_back? }
|
64
64
|
end
|
65
65
|
|
66
66
|
def process_jobs
|
@@ -80,7 +80,7 @@ module CapistranoMulticonfigParallel
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def apply_confirmations?
|
83
|
-
confirmations =
|
83
|
+
confirmations = configuration.task_confirmations
|
84
84
|
confirmations.is_a?(Array) && confirmations.present?
|
85
85
|
end
|
86
86
|
|
@@ -89,13 +89,13 @@ module CapistranoMulticonfigParallel
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def apply_confirmation_for_job(job)
|
92
|
-
|
92
|
+
configuration.apply_stage_confirmation.include?(job.stage) && apply_confirmations?
|
93
93
|
end
|
94
94
|
|
95
95
|
def setup_worker_conditions(job)
|
96
96
|
return unless apply_confirmation_for_job(job)
|
97
97
|
hash_conditions = {}
|
98
|
-
|
98
|
+
configuration.task_confirmations.each do |task|
|
99
99
|
hash_conditions[task] = { condition: Celluloid::Condition.new, status: 'unconfirmed' }
|
100
100
|
end
|
101
101
|
@job_to_condition[job.id] = hash_conditions
|
@@ -103,22 +103,21 @@ module CapistranoMulticonfigParallel
|
|
103
103
|
|
104
104
|
def mark_completed_remaining_tasks(job)
|
105
105
|
return unless apply_confirmation_for_job(job)
|
106
|
-
|
106
|
+
configuration.task_confirmations.each_with_index do |task, _index|
|
107
107
|
fake_result = proc { |sum| sum }
|
108
108
|
task_confirmation = @job_to_condition[job.id][task]
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
next unless task_confirmation[:status] != 'confirmed'
|
110
|
+
log_to_file("worker #{job.id} with action #{job.action} status #{job.status} and exit status #{job.exit_status} tries to mark fake the task #{task} with status #{task_confirmation[:status]}")
|
111
|
+
task_confirmation[:status] = 'confirmed'
|
112
|
+
task_confirmation[:condition].signal(fake_result)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
116
|
def wait_task_confirmations_worker(job)
|
117
|
-
return unless job.finished? || job.exit_status.present?
|
118
117
|
return if !apply_confirmation_for_job(job) || !syncronized_confirmation?
|
119
|
-
|
118
|
+
configuration.task_confirmations.each_with_index do |task, _index|
|
120
119
|
result = wait_condition_for_task(job.id, task)
|
121
|
-
confirm_task_approval(result, task, job)
|
120
|
+
confirm_task_approval(result, task, job)
|
122
121
|
end
|
123
122
|
end
|
124
123
|
|
@@ -127,9 +126,9 @@ module CapistranoMulticonfigParallel
|
|
127
126
|
end
|
128
127
|
|
129
128
|
def wait_task_confirmations
|
130
|
-
stage_apply =
|
129
|
+
stage_apply = configuration.apply_stage_confirmation.include?(@job_manager.stage)
|
131
130
|
return if !stage_apply || !syncronized_confirmation?
|
132
|
-
|
131
|
+
configuration.task_confirmations.each_with_index do |task, _index|
|
133
132
|
results = []
|
134
133
|
@jobs.pmap do |job_id, _job|
|
135
134
|
result = wait_condition_for_task(job_id, task)
|
@@ -146,11 +145,15 @@ module CapistranoMulticonfigParallel
|
|
146
145
|
message = "Do you want to continue the deployment and execute #{task.upcase}"
|
147
146
|
message += " for JOB #{job.id}" if job.present?
|
148
147
|
message += '?'
|
149
|
-
|
150
|
-
|
151
|
-
|
148
|
+
if Celluloid::Actor[:terminal_server].present? && Celluloid::Actor[:terminal_server].alive?
|
149
|
+
apps_symlink_confirmation = Celluloid::Actor[:terminal_server].show_confirmation(message, 'Y/N')
|
150
|
+
until apps_symlink_confirmation.present?
|
151
|
+
sleep(0.1) # keep current thread alive
|
152
|
+
end
|
153
|
+
apps_symlink_confirmation
|
154
|
+
else
|
155
|
+
'y'
|
152
156
|
end
|
153
|
-
apps_symlink_confirmation
|
154
157
|
end
|
155
158
|
|
156
159
|
def confirm_task_approval(result, task, processed_job = nil)
|
@@ -159,11 +162,13 @@ module CapistranoMulticonfigParallel
|
|
159
162
|
return unless action_confirmed?(result)
|
160
163
|
@jobs.pmap do |job_id, job|
|
161
164
|
worker = get_worker_for_job(job_id)
|
162
|
-
worker.
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
165
|
+
if worker.alive?
|
166
|
+
worker.publish_rake_event('approved' => 'yes',
|
167
|
+
'action' => 'invoke',
|
168
|
+
'job_id' => job.id,
|
169
|
+
'task' => task
|
170
|
+
)
|
171
|
+
end
|
167
172
|
end
|
168
173
|
end
|
169
174
|
|
@@ -185,10 +190,13 @@ module CapistranoMulticonfigParallel
|
|
185
190
|
end
|
186
191
|
|
187
192
|
def dispatch_new_job(job, options = {})
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
193
|
+
return unless job.is_a?(CapistranoMulticonfigParallel::Job)
|
194
|
+
options.stringify_keys! if options.present?
|
195
|
+
env_opts = options['skip_env_options'].present? ? {} : @job_manager.get_app_additional_env_options(job.app, job.stage)
|
196
|
+
new_job_options = job.options.merge('env_options' => job.env_options.merge(env_opts))
|
197
|
+
new_job = CapistranoMulticonfigParallel::Job.new(new_job_options.merge(options.except(job.job_writer_attributes)))
|
198
|
+
new_job.setup_writer_attributes(options)
|
199
|
+
async.delegate(new_job) unless job.worker_died?
|
192
200
|
end
|
193
201
|
|
194
202
|
# lookup status of job by asking actor running it
|
@@ -208,14 +216,11 @@ module CapistranoMulticonfigParallel
|
|
208
216
|
|
209
217
|
def worker_died(worker, reason)
|
210
218
|
job = @worker_to_job[worker.mailbox.address]
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
job.status = 'worker_died'
|
217
|
-
job.action = 'deploy:rollback'
|
218
|
-
dispatch_new_job(job)
|
219
|
+
return true if job.blank? || job.worker_died? || job.action != 'deploy'
|
220
|
+
mailbox = worker.mailbox
|
221
|
+
@worker_to_job.delete(mailbox.address)
|
222
|
+
log_to_file("RESTARTING: worker job #{job.inspect} with mailbox #{mailbox.inspect} and #{mailbox.address.inspect} died for reason: #{reason}")
|
223
|
+
dispatch_new_job(job, skip_env_options: true, action: 'deploy:rollback', status: 'worker_died')
|
219
224
|
end
|
220
225
|
end
|
221
226
|
end
|
@@ -43,9 +43,9 @@ module CapistranoMulticonfigParallel
|
|
43
43
|
|
44
44
|
def worker_state
|
45
45
|
if Actor.current.alive?
|
46
|
-
|
47
|
-
job.crashed? ? status.red : status.green
|
46
|
+
@machine.state.to_s.green
|
48
47
|
else
|
48
|
+
job.status = 'dead'
|
49
49
|
'dead'.upcase.red
|
50
50
|
end
|
51
51
|
end
|
@@ -76,6 +76,7 @@ module CapistranoMulticonfigParallel
|
|
76
76
|
|
77
77
|
def execute_after_succesfull_subscription
|
78
78
|
async.execute_deploy
|
79
|
+
@manager.async.wait_task_confirmations_worker(@job)
|
79
80
|
end
|
80
81
|
|
81
82
|
def rake_tasks
|
@@ -91,7 +92,6 @@ module CapistranoMulticonfigParallel
|
|
91
92
|
check_child_proces
|
92
93
|
log_to_file("worker #{@job_id} executes: #{@job.build_capistrano_task}")
|
93
94
|
@child_process.async.work(@job, @job.build_capistrano_task, actor: Actor.current, silent: true)
|
94
|
-
@manager.wait_task_confirmations_worker(@job)
|
95
95
|
end
|
96
96
|
|
97
97
|
def check_child_proces
|
@@ -110,8 +110,7 @@ module CapistranoMulticonfigParallel
|
|
110
110
|
|
111
111
|
def check_gitflow
|
112
112
|
return if @job.stage != 'staging' || !@manager.can_tag_staging? || !executed_task?(CapistranoMulticonfigParallel::GITFLOW_TAG_STAGING_TASK)
|
113
|
-
@job
|
114
|
-
@manager.dispatch_new_job(@job)
|
113
|
+
@manager.dispatch_new_job(@job, stage: 'production')
|
115
114
|
end
|
116
115
|
|
117
116
|
def handle_subscription(message)
|
@@ -143,7 +142,7 @@ module CapistranoMulticonfigParallel
|
|
143
142
|
|
144
143
|
def task_approval(message)
|
145
144
|
job_conditions = @manager.job_to_condition[@job_id]
|
146
|
-
if job_conditions.present? &&
|
145
|
+
if job_conditions.present? && configuration.task_confirmations.include?(message['task']) && message['action'] == 'invoke'
|
147
146
|
task_confirmation = job_conditions[message['task']]
|
148
147
|
task_confirmation[:status] = 'confirmed'
|
149
148
|
task_confirmation[:condition].signal(message['task'])
|
@@ -161,28 +160,26 @@ module CapistranoMulticonfigParallel
|
|
161
160
|
def update_machine_state(name)
|
162
161
|
log_to_file("worker #{@job_id} triest to transition from #{@machine.state} to #{name}")
|
163
162
|
@machine.go_to_transition(name.to_s)
|
164
|
-
|
163
|
+
error_message = "worker #{@job_id} task #{name} failed "
|
164
|
+
raise(CapistranoMulticonfigParallel::CelluloidWorker::TaskFailed.new(error_message), error_message) if job.failed? # force worker to rollback
|
165
165
|
end
|
166
166
|
|
167
167
|
def send_msg(channel, message = nil)
|
168
168
|
publish channel, message.present? && message.is_a?(Hash) ? { job_id: @job_id }.merge(message) : { job_id: @job_id, time: Time.now }
|
169
169
|
end
|
170
170
|
|
171
|
-
def finish_worker
|
171
|
+
def finish_worker(exit_status)
|
172
|
+
log_to_file("worker #{job_id} tries to terminate with exit_status #{exit_status}")
|
172
173
|
@manager.mark_completed_remaining_tasks(@job)
|
173
|
-
|
174
|
+
update_machine_state('FINISHED')
|
174
175
|
@manager.workers_terminated.signal('completed') if @manager.alive? && @manager.all_workers_finished?
|
175
176
|
end
|
176
177
|
|
177
178
|
def notify_finished(exit_status)
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
async.update_machine_state('FINISHED')
|
183
|
-
log_to_file("worker #{job_id} notifies manager has finished")
|
184
|
-
async.finish_worker
|
185
|
-
end
|
179
|
+
finish_worker(exit_status)
|
180
|
+
return if exit_status == 0
|
181
|
+
error_message = "worker #{@job_id} task failed with exit status #{exit_status.inspect} "
|
182
|
+
raise(CapistranoMulticonfigParallel::CelluloidWorker::TaskFailed.new(error_message), error_message)
|
186
183
|
end
|
187
184
|
end
|
188
185
|
end
|
@@ -7,7 +7,7 @@ module CapistranoMulticonfigParallel
|
|
7
7
|
include Celluloid::Logger
|
8
8
|
include CapistranoMulticonfigParallel::ApplicationHelper
|
9
9
|
|
10
|
-
attr_accessor :options, :actor, :job_id, :exit_status, :pid, :process
|
10
|
+
attr_accessor :options, :job, :actor, :job_id, :exit_status, :pid, :process
|
11
11
|
|
12
12
|
finalizer :process_finalizer
|
13
13
|
|
@@ -23,6 +23,7 @@ module CapistranoMulticonfigParallel
|
|
23
23
|
end
|
24
24
|
@timer = EM::PeriodicTimer.new(0.1) do
|
25
25
|
check_exit_status
|
26
|
+
@timer.cancel if @exit_status.present?
|
26
27
|
end
|
27
28
|
end
|
28
29
|
EM.error_handler do|e|
|
@@ -37,12 +38,11 @@ module CapistranoMulticonfigParallel
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def check_exit_status
|
40
|
-
log_to_file("worker #{@job_id} checking exit status #{@exit_status.inspect}") if @exit_status.present?
|
41
41
|
return if @exit_status.blank?
|
42
|
+
@timer.cancel
|
42
43
|
@job.exit_status = @exit_status
|
43
|
-
log_to_file("worker #{@job_id} startsnotify finished")
|
44
|
+
log_to_file("worker #{@job_id} startsnotify finished with exit status #{@exit_status.inspect}")
|
44
45
|
@actor.async.notify_finished(@exit_status)
|
45
|
-
@timer.cancel
|
46
46
|
end
|
47
47
|
|
48
48
|
def start_async_deploy(cmd, options)
|
@@ -76,9 +76,8 @@ module CapistranoMulticonfigParallel
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def on_exit(status)
|
79
|
+
log_to_file "Child process for worker #{@job_id} on_exit disconnected due to error #{status.inspect}"
|
79
80
|
@exit_status = status.exitstatus
|
80
|
-
log_to_file "Child process for worker #{@job_id} on_exit disconnected due to error #{status.inspect} and #{@exit_status.inspect}"
|
81
|
-
check_exit_status
|
82
81
|
end
|
83
82
|
|
84
83
|
def async_exception_handler(*data)
|
@@ -90,6 +89,7 @@ module CapistranoMulticonfigParallel
|
|
90
89
|
|
91
90
|
def watch_handler(process)
|
92
91
|
@process ||= process
|
92
|
+
check_exit_status
|
93
93
|
end
|
94
94
|
|
95
95
|
def io_callback(io, data)
|
@@ -25,19 +25,18 @@ module CapistranoMulticonfigParallel
|
|
25
25
|
# default_headings << 'Total'
|
26
26
|
# default_headings << 'Progress'
|
27
27
|
table = Terminal::Table.new(title: 'Deployment Status Table', headings: default_headings)
|
28
|
-
jobs = @manager.alive? ? @manager.jobs : []
|
28
|
+
jobs = @manager.alive? ? @manager.jobs.dup : []
|
29
29
|
if jobs.present?
|
30
30
|
count = 0
|
31
|
-
|
32
|
-
jobs.each do |_job_id, job|
|
31
|
+
jobs.pmap do |job_id, job|
|
33
32
|
count += 1
|
34
|
-
add_job_to_table(table, job, count
|
33
|
+
add_job_to_table(table, job_id, job, count)
|
35
34
|
end
|
36
35
|
end
|
37
36
|
show_terminal_screen(table)
|
38
37
|
rescue => ex
|
39
38
|
log_to_file("Terminal Table client disconnected due to error #{ex.inspect}")
|
40
|
-
|
39
|
+
log_error(ex, 'stderr')
|
41
40
|
terminate
|
42
41
|
end
|
43
42
|
|
@@ -56,7 +55,9 @@ module CapistranoMulticonfigParallel
|
|
56
55
|
@job_manager.condition.signal('completed') if @manager.all_workers_finished?
|
57
56
|
end
|
58
57
|
|
59
|
-
def worker_state(
|
58
|
+
def worker_state(job_id)
|
59
|
+
return unless @manager.alive?
|
60
|
+
worker = @manager.get_worker_for_job(job_id)
|
60
61
|
worker.alive? ? worker.worker_state : 'dead'.upcase.red
|
61
62
|
end
|
62
63
|
|
@@ -64,27 +65,24 @@ module CapistranoMulticonfigParallel
|
|
64
65
|
%w(STAGES ACTION)
|
65
66
|
end
|
66
67
|
|
67
|
-
def add_job_to_table(table,
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
row = [{ value: count.to_s },
|
72
|
-
{ value: job.id.to_s },
|
68
|
+
def add_job_to_table(table, job_id, job, index)
|
69
|
+
row = [{ value: index.to_s },
|
70
|
+
{ value: job_id.to_s },
|
73
71
|
{ value: job.job_stage },
|
74
72
|
{ value: job.capistrano_action },
|
75
73
|
{ value: job.setup_command_line_standard(filtered_keys: [CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]).join("\n") },
|
76
|
-
{ value: worker_state(
|
74
|
+
{ value: worker_state(job_id) }
|
77
75
|
]
|
78
76
|
|
79
77
|
# if worker.alive?
|
80
|
-
# row << { value:
|
81
|
-
# row << { value: worker_progress(
|
78
|
+
# row << { value: job.rake_tasks.size }
|
79
|
+
# row << { value: worker_progress(job_id, job) }
|
82
80
|
# else
|
83
81
|
# row << { value: 0 }
|
84
|
-
# row << { value: worker_state(
|
82
|
+
# row << { value: worker_state(job_id) }
|
85
83
|
# end
|
86
84
|
table.add_row(row)
|
87
|
-
table.add_separator
|
85
|
+
table.add_separator
|
88
86
|
table
|
89
87
|
end
|
90
88
|
|
@@ -92,23 +90,17 @@ module CapistranoMulticonfigParallel
|
|
92
90
|
system('cls') || system('clear') || puts("\e[H\e[2J")
|
93
91
|
end
|
94
92
|
|
95
|
-
# def worker_progress(
|
96
|
-
#
|
97
|
-
#
|
98
|
-
# current_task
|
99
|
-
# show_worker_percent(worker, tasks, current_task, processed_job)
|
93
|
+
# def worker_progress(job)
|
94
|
+
# tasks = job.rake_tasks.size
|
95
|
+
# current_task = job.status
|
96
|
+
# show_worker_percent(tasks, current_task, job)
|
100
97
|
# end
|
101
98
|
#
|
102
|
-
# def show_worker_percent(
|
103
|
-
#
|
104
|
-
# task_index = worker.alive? ? tasks.index(current_task.to_s).to_i + 1 : 0
|
99
|
+
# def show_worker_percent(tasks, current_task, job)
|
100
|
+
# task_index = tasks.index(current_task.to_s).to_i + 1
|
105
101
|
# percent = percent_of(task_index, total_tasks)
|
106
102
|
# result = "Progress [#{format('%.2f', percent)}%] (executed #{task_index} of #{total_tasks})"
|
107
|
-
#
|
108
|
-
# processed_job.crashed? ? result.red : result.green
|
109
|
-
# else
|
110
|
-
# worker_state(worker)
|
111
|
-
# end
|
103
|
+
# job.crashed? ? result.red : result.green
|
112
104
|
# end
|
113
105
|
#
|
114
106
|
# def percent_of(index, total)
|
@@ -22,7 +22,7 @@ module CapistranoMulticonfigParallel
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def fetch_application_dependencies(application, action)
|
25
|
-
return [] if
|
25
|
+
return [] if configuration.application_dependencies.blank? || application.blank?
|
26
26
|
applications = get_applications_to_deploy(action, [application.camelcase])
|
27
27
|
applications.delete_if { |hash| hash['app'] == application }
|
28
28
|
end
|
@@ -33,7 +33,7 @@ module CapistranoMulticonfigParallel
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def application_dependencies
|
36
|
-
deps =
|
36
|
+
deps = configuration.application_dependencies
|
37
37
|
value_is_array?(deps) ? deps.map(&:stringify_keys) : []
|
38
38
|
end
|
39
39
|
|
@@ -43,7 +43,7 @@ module CapistranoMulticonfigParallel
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def confirm_option_selected
|
46
|
-
print
|
46
|
+
print 'Enter a comma-separated list of option numbers or one single option number (again to uncheck, ENTER when done): '
|
47
47
|
$stdin.gets.squeeze(' ').strip
|
48
48
|
end
|
49
49
|
|
@@ -17,7 +17,20 @@ module CapistranoMulticonfigParallel
|
|
17
17
|
|
18
18
|
def initialize(options)
|
19
19
|
@options = options
|
20
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
def command
|
23
|
+
@command ||= CapistranoMulticonfigParallel::JobCommand.new(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
def job_writer_attributes
|
27
|
+
%w(status exit_status)
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_writer_attributes(options)
|
31
|
+
job_writer_attributes.each do |attribute|
|
32
|
+
send("#{attribute}=", options.fetch("#{attribute}", send(attribute)))
|
33
|
+
end
|
21
34
|
end
|
22
35
|
|
23
36
|
def id
|
@@ -44,19 +57,33 @@ module CapistranoMulticonfigParallel
|
|
44
57
|
value["#{CapistranoMulticonfigParallel::ENV_KEY_JOB_ID}"] = id if hash[:name] == 'env_options'
|
45
58
|
verify_empty_options(value)
|
46
59
|
end
|
60
|
+
# define_method "#{hash[:name]}=" do |value|
|
61
|
+
# self.send("#{hash[:name]}=", value)
|
62
|
+
# end
|
47
63
|
end
|
48
64
|
|
49
65
|
def finished?
|
50
|
-
|
66
|
+
status == 'finished'
|
67
|
+
end
|
68
|
+
|
69
|
+
def failed?
|
70
|
+
['deploy:failed'].include?(status)
|
71
|
+
end
|
72
|
+
|
73
|
+
def rolling_back?
|
74
|
+
['deploy:rollback'].include?(action)
|
51
75
|
end
|
52
76
|
|
53
77
|
def crashed?
|
54
|
-
|
55
|
-
crashing_actions.include?(action) || crashing_actions.include?(status) || failed?
|
78
|
+
failed? || dead? || worker_died? || exit_status.to_i != 0
|
56
79
|
end
|
57
80
|
|
58
|
-
def
|
59
|
-
status.present? && status == '
|
81
|
+
def dead?
|
82
|
+
status.present? && status.to_s.downcase == 'dead'
|
83
|
+
end
|
84
|
+
|
85
|
+
def worker_died?
|
86
|
+
status.present? && status.to_s.downcase == 'worker_died'
|
60
87
|
end
|
61
88
|
end
|
62
89
|
end
|
@@ -55,7 +55,7 @@ module CapistranoMulticonfigParallel
|
|
55
55
|
command = build_capistrano_task(action)
|
56
56
|
run_shell_command(command)
|
57
57
|
rescue => ex
|
58
|
-
log_error(ex)
|
58
|
+
log_error(ex, 'stderr')
|
59
59
|
execute_standard_deploy('deploy:rollback') if action.blank? && @name == 'deploy'
|
60
60
|
end
|
61
61
|
|
@@ -3,14 +3,14 @@ require_relative './input_stream'
|
|
3
3
|
require_relative './output_stream'
|
4
4
|
module CapistranoMulticonfigParallel
|
5
5
|
# class used to handle the rake worker and sets all the hooks before and after running the worker
|
6
|
-
class
|
6
|
+
class RakeTaskHooks
|
7
7
|
attr_accessor :task, :env
|
8
8
|
def initialize(env, task)
|
9
9
|
@env = env
|
10
10
|
@task = task
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def automatic_hooks(&block)
|
14
14
|
if job_id.present?
|
15
15
|
actor_start_working
|
16
16
|
actor.wait_execution until actor.task_approved
|
@@ -9,7 +9,8 @@ module CapistranoMulticonfigParallel
|
|
9
9
|
# method used to start
|
10
10
|
def start
|
11
11
|
check_terminal_tty
|
12
|
-
|
12
|
+
CapistranoMulticonfigParallel.original_args = ARGV.dup
|
13
|
+
arguments = multi_fetch_argv(original_args)
|
13
14
|
if arguments[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
|
14
15
|
run_the_application
|
15
16
|
else
|
@@ -19,7 +20,7 @@ module CapistranoMulticonfigParallel
|
|
19
20
|
|
20
21
|
def run_the_application
|
21
22
|
execute_with_rescue('stderr') do
|
22
|
-
|
23
|
+
configuration_valid?
|
23
24
|
CapistranoMulticonfigParallel::Application.new.start
|
24
25
|
end
|
25
26
|
end
|
@@ -8,6 +8,12 @@ module CapistranoMulticonfigParallel
|
|
8
8
|
include CapistranoMulticonfigParallel::CoreHelper
|
9
9
|
include CapistranoMulticonfigParallel::StagesHelper
|
10
10
|
|
11
|
+
delegate :logger,
|
12
|
+
:configuration,
|
13
|
+
:configuration_valid?,
|
14
|
+
:original_args,
|
15
|
+
to: :CapistranoMulticonfigParallel
|
16
|
+
|
11
17
|
module_function
|
12
18
|
|
13
19
|
def multi_fetch_argv(args)
|
@@ -75,7 +81,7 @@ module CapistranoMulticonfigParallel
|
|
75
81
|
return string, [] unless name
|
76
82
|
return name, [] if remaining_args.empty?
|
77
83
|
|
78
|
-
args =
|
84
|
+
args = find_remaining_args(remaining_args)
|
79
85
|
[name, args]
|
80
86
|
end
|
81
87
|
|
@@ -3,9 +3,9 @@ module CapistranoMulticonfigParallel
|
|
3
3
|
# class that holds the options that are configurable for this gem
|
4
4
|
module Configuration
|
5
5
|
extend ActiveSupport::Concern
|
6
|
-
include CapistranoMulticonfigParallel::ApplicationHelper
|
7
6
|
|
8
7
|
included do
|
8
|
+
include CapistranoMulticonfigParallel::ApplicationHelper
|
9
9
|
attr_reader :configuration
|
10
10
|
|
11
11
|
def configuration
|
@@ -4,26 +4,13 @@ module CapistranoMulticonfigParallel
|
|
4
4
|
module_function
|
5
5
|
|
6
6
|
def app_debug_enabled?
|
7
|
-
|
7
|
+
configuration.multi_debug.to_s.downcase == 'true'
|
8
8
|
end
|
9
9
|
|
10
10
|
def show_warning(message)
|
11
11
|
warn message if app_debug_enabled?
|
12
12
|
end
|
13
13
|
|
14
|
-
def app_configuration
|
15
|
-
CapistranoMulticonfigParallel.configuration
|
16
|
-
end
|
17
|
-
|
18
|
-
def app_logger
|
19
|
-
CapistranoMulticonfigParallel.logger
|
20
|
-
end
|
21
|
-
|
22
|
-
def verify_validation
|
23
|
-
CapistranoMulticonfigParallel.original_args = ARGV.dup
|
24
|
-
CapistranoMulticonfigParallel.configuration_valid?
|
25
|
-
end
|
26
|
-
|
27
14
|
def check_terminal_tty
|
28
15
|
$stdin.sync = true if $stdin.isatty
|
29
16
|
$stdout.sync = true if $stdout.isatty
|
@@ -55,8 +42,19 @@ module CapistranoMulticonfigParallel
|
|
55
42
|
result
|
56
43
|
end
|
57
44
|
|
58
|
-
def
|
59
|
-
|
45
|
+
def filtered_errors
|
46
|
+
[CapistranoMulticonfigParallel::CelluloidWorker::TaskFailed, Celluloid::DeadActorError, Celluloid::Task::TerminatedError]
|
47
|
+
end
|
48
|
+
|
49
|
+
def error_filtered?(error)
|
50
|
+
filtered_errors.find { |class_name| error.is_a?(class_name) }.present?
|
51
|
+
end
|
52
|
+
|
53
|
+
def log_error(error, output = nil)
|
54
|
+
return if error_filtered?(error)
|
55
|
+
message = format_error(error)
|
56
|
+
puts(message) if output.present?
|
57
|
+
log_to_file(message)
|
60
58
|
end
|
61
59
|
|
62
60
|
def format_error(error)
|
@@ -66,7 +64,7 @@ module CapistranoMulticonfigParallel
|
|
66
64
|
end
|
67
65
|
|
68
66
|
def log_to_file(message, job_id = nil)
|
69
|
-
worker_log = job_id.present? ? find_worker_log(job_id) :
|
67
|
+
worker_log = job_id.present? ? find_worker_log(job_id) : logger
|
70
68
|
worker_log.debug(message) if worker_log.present? && app_debug_enabled?
|
71
69
|
end
|
72
70
|
|
@@ -96,7 +94,7 @@ module CapistranoMulticonfigParallel
|
|
96
94
|
end
|
97
95
|
|
98
96
|
def websocket_server_config
|
99
|
-
|
97
|
+
configuration.fetch(:websocket_server, {}).stringify_keys
|
100
98
|
end
|
101
99
|
|
102
100
|
def websocket_config
|
@@ -112,8 +110,7 @@ module CapistranoMulticonfigParallel
|
|
112
110
|
end
|
113
111
|
|
114
112
|
def rescue_error(error, output = nil)
|
115
|
-
|
116
|
-
log_error(error)
|
113
|
+
log_error(error, output)
|
117
114
|
exit(1)
|
118
115
|
end
|
119
116
|
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require_relative '../classes/
|
1
|
+
require_relative '../classes/rake_task_hooks'
|
2
2
|
Rake::Task.class_eval do
|
3
3
|
alias_method :original_execute, :execute
|
4
4
|
|
5
5
|
def execute(*args)
|
6
|
-
rake = CapistranoMulticonfigParallel::
|
7
|
-
rake.
|
6
|
+
rake = CapistranoMulticonfigParallel::RakeTaskHooks.new(ENV, self)
|
7
|
+
rake.automatic_hooks do
|
8
8
|
original_execute(*args)
|
9
9
|
end
|
10
10
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano_multiconfig_parallel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bogdanRada
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: celluloid-pmap
|
@@ -634,7 +634,7 @@ files:
|
|
634
634
|
- lib/capistrano_multiconfig_parallel/classes/job.rb
|
635
635
|
- lib/capistrano_multiconfig_parallel/classes/job_command.rb
|
636
636
|
- lib/capistrano_multiconfig_parallel/classes/output_stream.rb
|
637
|
-
- lib/capistrano_multiconfig_parallel/classes/
|
637
|
+
- lib/capistrano_multiconfig_parallel/classes/rake_task_hooks.rb
|
638
638
|
- lib/capistrano_multiconfig_parallel/cli.rb
|
639
639
|
- lib/capistrano_multiconfig_parallel/configuration/default.yml
|
640
640
|
- lib/capistrano_multiconfig_parallel/helpers/application_helper.rb
|