capistrano_multiconfig_parallel 0.6.3 → 0.7.0
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 +4 -4
- data/README.md +5 -5
- data/capistrano_multiconfig_parallel.gemspec +8 -8
- data/img/parallel_demo.png +0 -0
- data/lib/capistrano_multiconfig_parallel/all.rb +1 -0
- data/lib/capistrano_multiconfig_parallel/base.rb +4 -6
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_manager.rb +46 -40
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_worker.rb +18 -16
- data/lib/capistrano_multiconfig_parallel/celluloid/child_process.rb +1 -1
- data/lib/capistrano_multiconfig_parallel/celluloid/terminal_table.rb +30 -21
- data/lib/capistrano_multiconfig_parallel/configuration.rb +8 -4
- data/lib/capistrano_multiconfig_parallel/helpers/base_manager.rb +47 -46
- data/lib/capistrano_multiconfig_parallel/helpers/multi_app_manager.rb +3 -3
- data/lib/capistrano_multiconfig_parallel/initializers/helper.rb +0 -1
- data/lib/capistrano_multiconfig_parallel/multi_app_helpers/interactive_menu.rb +1 -1
- data/lib/capistrano_multiconfig_parallel/version.rb +2 -2
- metadata +19 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f0f8c07848c290c54be6147ed565365c4f5d9b6
|
4
|
+
data.tar.gz: 6e2a75cf93aee7cb7bbe1a6f484c53f3bf003db5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf0d3c5f0d5453bece121ff9c6886e16e7f063a11772683188a396f528f88698f75cb874a08cf5f357ae1b22100dba2e5af994957eab1e46432d7c4bc48a139d
|
7
|
+
data.tar.gz: 06d957bbd180bc92b34ab03dfa0b31ec3af13f81fd4f8829d7ae750e4be9561e4bd2ad374fbe7179c374b7871b3aa2b25dee24ee70bce96155fd0dcc65ad9d37
|
data/README.md
CHANGED
@@ -183,7 +183,7 @@ bundle exec multi_cap <development_stage> <task_name> BOX=<box_name>,<box_nam
|
|
183
183
|
|
184
184
|
```
|
185
185
|
|
186
|
-
If a branch is specified using
|
186
|
+
If a branch is specified using **BRANCH=name** it will deploy same branch to all sandboxes
|
187
187
|
The branch environment variable is then passed to the capistrano task
|
188
188
|
|
189
189
|
Also the script will ask if there are any other environment variables that user might want to pass to each of the sandboxes separately.
|
@@ -195,10 +195,10 @@ Also the script will ask if there are any other environment variables that user
|
|
195
195
|
|
196
196
|
bundle exec multi_cap deploy_multi_stages STAGES=development, staging, production
|
197
197
|
```
|
198
|
-
NOTE: IF you want to execute a different command on all stages, you can specify environment variable **ACTION
|
198
|
+
NOTE: IF you want to execute a different command on all stages, you can specify environment variable **ACTION=task_name** either when you specify the STAGES, or can be done
|
199
199
|
individually for each task when prompted about additional ENV options
|
200
200
|
|
201
|
-
If a branch is specified using
|
201
|
+
If a branch is specified using **BRANCH=name** it will deploy same branch to all stages.The branch environment variable is then passed to the capistrano task
|
202
202
|
|
203
203
|
Also the script will ask if there are any other environment variables that user might want to pass to each of the stages separately.
|
204
204
|
|
@@ -256,10 +256,10 @@ Will ask user if he wants to deploy the apps "foo" and "bar" , since they appear
|
|
256
256
|
bundle exec multi_cap deploy_multi_stages STAGES=development, staging, production
|
257
257
|
```
|
258
258
|
|
259
|
-
NOTE: IF you want to execute a different command on all stages, you can specify environment variable **ACTION
|
259
|
+
NOTE: IF you want to execute a different command on all stages, you can specify environment variable **ACTION=task_name** either when you specify the STAGES, or can be done
|
260
260
|
individually for each task when prompted about additional ENV options
|
261
261
|
|
262
|
-
If a branch is specified using **BRANCH
|
262
|
+
If a branch is specified using **BRANCH=branch_name** it will deploy same branch to all stages.The branch environment variable is then passed to the capistrano task
|
263
263
|
If you want different branches , capistrano will ask for additional ENV options for each stage, and can be specified then for each stage
|
264
264
|
|
265
265
|
If you use **capistrano-gitflow**, the workers will first deploy to all the other stages
|
@@ -41,12 +41,12 @@ Gem::Specification.new do |s|
|
|
41
41
|
s.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7'
|
42
42
|
s.add_development_dependency 'rvm-tester', '~> 1.1', '>= 1.1'
|
43
43
|
|
44
|
-
s.add_development_dependency 'rubocop', '0
|
45
|
-
s.add_development_dependency 'phare', '~> 0
|
46
|
-
s.add_development_dependency 'yard', '~> 0
|
47
|
-
s.add_development_dependency 'yard-rspec', '~> 0
|
48
|
-
s.add_development_dependency 'redcarpet', '~> 3
|
49
|
-
s.add_development_dependency 'github-markup', '~> 1
|
50
|
-
s.add_development_dependency 'inch', '~> 0
|
51
|
-
s.add_development_dependency 'guard-inch', '~> 0
|
44
|
+
s.add_development_dependency 'rubocop', '~> 0', '>= 0.29'
|
45
|
+
s.add_development_dependency 'phare', '~> 0', '>= 0.6'
|
46
|
+
s.add_development_dependency 'yard', '~> 0', '>= 0.8.7'
|
47
|
+
s.add_development_dependency 'yard-rspec', '~> 0', '>= 0.1'
|
48
|
+
s.add_development_dependency 'redcarpet', '~> 3', '>= 3.2.2'
|
49
|
+
s.add_development_dependency 'github-markup', '~> 1', '>= 1.3.3'
|
50
|
+
s.add_development_dependency 'inch', '~> 0', '>= 0.5.10'
|
51
|
+
s.add_development_dependency 'guard-inch', '~> 0', '>= 0.1.0'
|
52
52
|
end
|
data/img/parallel_demo.png
CHANGED
Binary file
|
@@ -5,10 +5,10 @@ module CapistranoMulticonfigParallel
|
|
5
5
|
ENV_KEY_JOB_ID = 'multi_cap_job_id'
|
6
6
|
MULTI_KEY = 'multi'
|
7
7
|
SINGLE_KEY = 'single'
|
8
|
-
GITFLOW_TAG_STAGING_TASK =
|
8
|
+
GITFLOW_TAG_STAGING_TASK = 'gitflow:tag_staging'
|
9
9
|
GITFLOW_CALCULATE_TAG_TASK = 'gitflow:calculate_tag'
|
10
10
|
GITFLOW_VERIFY_UPTODATE_TASK = 'gitflow:verify_up_to_date'
|
11
|
-
|
11
|
+
|
12
12
|
CUSTOM_COMMANDS = {
|
13
13
|
CapistranoMulticonfigParallel::MULTI_KEY => {
|
14
14
|
stages: 'deploy_multi_stages'
|
@@ -26,11 +26,9 @@ module CapistranoMulticonfigParallel
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def ask_confirm(message, default)
|
29
|
-
begin
|
30
29
|
Ask.input message, default: default
|
31
30
|
rescue
|
32
31
|
return nil
|
33
|
-
end
|
34
32
|
end
|
35
33
|
|
36
34
|
def log_directory
|
@@ -48,7 +46,7 @@ module CapistranoMulticonfigParallel
|
|
48
46
|
def enable_logging
|
49
47
|
CapistranoMulticonfigParallel.configuration_valid?
|
50
48
|
FileUtils.mkdir_p(log_directory) unless File.directory?(log_directory)
|
51
|
-
if
|
49
|
+
if CapistranoMulticonfigParallel::CelluloidManager.debug_enabled.to_s.downcase == 'true'
|
52
50
|
FileUtils.touch(main_log_file) unless File.file?(main_log_file)
|
53
51
|
if ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
|
54
52
|
log_file = File.open(main_log_file, 'w')
|
@@ -56,7 +54,7 @@ module CapistranoMulticonfigParallel
|
|
56
54
|
end
|
57
55
|
self.logger = ::Logger.new(main_log_file)
|
58
56
|
else
|
59
|
-
self.logger =
|
57
|
+
self.logger = ::Logger.new(DevNull.new)
|
60
58
|
end
|
61
59
|
Celluloid.logger = CapistranoMulticonfigParallel.logger
|
62
60
|
Celluloid.task_class = Celluloid::TaskThread
|
@@ -79,18 +79,21 @@ module CapistranoMulticonfigParallel
|
|
79
79
|
debug("job id not found. delegating again the job #{job.inspect}") if self.class.debug_enabled?
|
80
80
|
delegate(job)
|
81
81
|
else
|
82
|
-
|
83
|
-
@job_to_worker[job['id']] = worker
|
84
|
-
@worker_to_job[worker.mailbox.address] = job
|
85
|
-
debug("worker #{worker.job_id} registed into manager") if self.class.debug_enabled?
|
86
|
-
Actor.current.link worker
|
87
|
-
worker.async.start_task unless syncronized_confirmation?
|
88
|
-
if @job_manager.jobs.size == @job_to_worker.size
|
89
|
-
@registration_complete = true
|
90
|
-
end
|
82
|
+
start_worker(job, worker)
|
91
83
|
end
|
92
84
|
end
|
93
85
|
|
86
|
+
def start_worker(job, worker)
|
87
|
+
worker.job_id = job['id'] if worker.job_id.blank?
|
88
|
+
@job_to_worker[job['id']] = worker
|
89
|
+
@worker_to_job[worker.mailbox.address] = job
|
90
|
+
debug("worker #{worker.job_id} registed into manager") if self.class.debug_enabled?
|
91
|
+
Actor.current.link worker
|
92
|
+
worker.async.start_task unless syncronized_confirmation?
|
93
|
+
return unless @job_manager.jobs.size != @job_to_worker.size
|
94
|
+
@registration_complete = true
|
95
|
+
end
|
96
|
+
|
94
97
|
def process_jobs
|
95
98
|
if syncronized_confirmation?
|
96
99
|
@job_to_worker.pmap do |_job_id, worker|
|
@@ -105,18 +108,18 @@ module CapistranoMulticonfigParallel
|
|
105
108
|
debug("all jobs have completed #{condition}") if self.class.debug_enabled?
|
106
109
|
@job_manager.condition.signal('completed') if condition
|
107
110
|
end
|
108
|
-
|
111
|
+
|
109
112
|
def apply_confirmations?
|
110
|
-
|
113
|
+
CapistranoMulticonfigParallel.configuration.task_confirmation_active.to_s.downcase == 'true'
|
111
114
|
end
|
112
|
-
|
115
|
+
|
113
116
|
def syncronized_confirmation?
|
114
|
-
|
115
|
-
|
117
|
+
(CapistranoMulticonfigParallel.configuration.syncronize_confirmation.to_s.downcase == 'true' && !@job_manager.executes_deploy_stages?) ||
|
118
|
+
(@job_manager.executes_deploy_stages? && @job_manager.confirmation_applies_to_all_workers?)
|
116
119
|
end
|
117
120
|
|
118
121
|
def apply_confirmation_for_worker(worker)
|
119
|
-
worker.alive? &&
|
122
|
+
worker.alive? && CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.include?(worker.env_name)
|
120
123
|
end
|
121
124
|
|
122
125
|
def setup_worker_conditions(worker)
|
@@ -129,7 +132,7 @@ module CapistranoMulticonfigParallel
|
|
129
132
|
end
|
130
133
|
|
131
134
|
def mark_completed_remaining_tasks(worker)
|
132
|
-
return if !apply_confirmation_for_worker(worker)
|
135
|
+
return if !apply_confirmation_for_worker(worker) || !apply_confirmations?
|
133
136
|
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, _index|
|
134
137
|
fake_result = proc { |sum| sum }
|
135
138
|
task_confirmation = @job_to_condition[worker.job_id][task]
|
@@ -141,20 +144,20 @@ module CapistranoMulticonfigParallel
|
|
141
144
|
end
|
142
145
|
|
143
146
|
def wait_task_confirmations_worker(worker)
|
144
|
-
return if !apply_confirmations? ||
|
147
|
+
return if !apply_confirmations? || !apply_confirmation_for_worker(worker) || syncronized_confirmation?
|
145
148
|
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, _index|
|
146
149
|
result = wait_condition_for_task(worker.job_id, task)
|
147
150
|
confirm_task_approval(result, task, worker) if result.present?
|
148
151
|
end
|
149
|
-
|
152
|
+
end
|
150
153
|
|
151
154
|
def wait_condition_for_task(job_id, task)
|
152
155
|
@job_to_condition[job_id][task][:condition].wait
|
153
156
|
end
|
154
157
|
|
155
158
|
def wait_task_confirmations
|
156
|
-
|
157
|
-
return
|
159
|
+
stage_apply = CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.include?(@job_manager.stage)
|
160
|
+
return if !apply_confirmations? || !stage_apply || !syncronized_confirmation?
|
158
161
|
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, _index|
|
159
162
|
results = []
|
160
163
|
@jobs.pmap do |job_id, _job|
|
@@ -167,17 +170,20 @@ module CapistranoMulticonfigParallel
|
|
167
170
|
end
|
168
171
|
end
|
169
172
|
|
173
|
+
def print_confirm_task_approvall(result, task, worker = nil)
|
174
|
+
return if result.is_a?(Proc)
|
175
|
+
message = "Do you want to continue the deployment and execute #{task.upcase}"
|
176
|
+
message += " for JOB #{worker.job_id}" if worker.present?
|
177
|
+
message += '?'
|
178
|
+
set :apps_symlink_confirmation, CapistranoMulticonfigParallel.ask_confirm(message, 'Y/N')
|
179
|
+
until fetch(:apps_symlink_confirmation).present?
|
180
|
+
sleep(0.1) # keep current thread alive
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
170
184
|
def confirm_task_approval(result, task, worker = nil)
|
171
185
|
return unless result.present?
|
172
|
-
|
173
|
-
message = "Do you want to continue the deployment and execute #{task.upcase}"
|
174
|
-
message += " for JOB #{worker.job_id}" if worker.present?
|
175
|
-
message += '?'
|
176
|
-
set :apps_symlink_confirmation, CapistranoMulticonfigParallel.ask_confirm(message, 'Y/N')
|
177
|
-
until fetch(:apps_symlink_confirmation).present?
|
178
|
-
sleep(0.1) # keep current thread alive
|
179
|
-
end
|
180
|
-
end
|
186
|
+
print_confirm_task_approvall(result, task, worker = nil)
|
181
187
|
return if fetch(:apps_symlink_confirmation).blank? || fetch(:apps_symlink_confirmation).downcase != 'y'
|
182
188
|
@jobs.pmap do |job_id, job|
|
183
189
|
worker = get_worker_for_job(job_id)
|
@@ -185,7 +191,7 @@ module CapistranoMulticonfigParallel
|
|
185
191
|
'action' => 'invoke',
|
186
192
|
'job_id' => job['id'],
|
187
193
|
'task' => task
|
188
|
-
|
194
|
+
)
|
189
195
|
end
|
190
196
|
end
|
191
197
|
|
@@ -203,17 +209,17 @@ module CapistranoMulticonfigParallel
|
|
203
209
|
end
|
204
210
|
|
205
211
|
def can_tag_staging?
|
206
|
-
|
207
|
-
|
212
|
+
@job_manager.can_tag_staging? &&
|
213
|
+
@jobs.find { |_job_id, job| job['env'] == 'production' }.blank?
|
208
214
|
end
|
209
|
-
|
215
|
+
|
210
216
|
def dispatch_new_job(job)
|
211
217
|
original_env = job['env_options']
|
212
218
|
env_opts = @job_manager.get_app_additional_env_options(job['app_name'], job['stage'])
|
213
|
-
job['env_options'] =
|
219
|
+
job['env_options'] = original_env.merge(env_opts)
|
214
220
|
async.delegate(job)
|
215
221
|
end
|
216
|
-
|
222
|
+
|
217
223
|
def process_job(job)
|
218
224
|
env_options = {}
|
219
225
|
job['env_options'].each do |key, value|
|
@@ -222,13 +228,13 @@ module CapistranoMulticonfigParallel
|
|
222
228
|
{
|
223
229
|
'job_id' => job['id'],
|
224
230
|
'app_name' => job['app'],
|
225
|
-
'env_name' =>
|
226
|
-
'action_name' =>
|
231
|
+
'env_name' => job['env'],
|
232
|
+
'action_name' => job['action'],
|
227
233
|
'env_options' => env_options,
|
228
|
-
'task_arguments' => job['task_arguments']
|
234
|
+
'task_arguments' => job['task_arguments']
|
229
235
|
}
|
230
236
|
end
|
231
|
-
|
237
|
+
|
232
238
|
# lookup status of job by asking actor running it
|
233
239
|
def get_job_status(job)
|
234
240
|
status = nil
|
@@ -244,7 +250,7 @@ module CapistranoMulticonfigParallel
|
|
244
250
|
end
|
245
251
|
status
|
246
252
|
end
|
247
|
-
|
253
|
+
|
248
254
|
def job_failed?(job)
|
249
255
|
job['worker_action'].present? && job['worker_action'] == 'worker_died'
|
250
256
|
end
|
@@ -23,9 +23,9 @@ module CapistranoMulticonfigParallel
|
|
23
23
|
class TaskFailed < StandardError; end
|
24
24
|
|
25
25
|
attr_accessor :job, :manager, :job_id, :app_name, :env_name, :action_name, :env_options, :machine, :client, :task_argv, :execute_deploy, :executed_dry_run,
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
:rake_tasks, :current_task_number, # tracking tasks
|
27
|
+
:successfull_subscription, :subscription_channel, :publisher_channel, # for subscriptions and publishing events
|
28
|
+
:job_termination_condition, :worker_state
|
29
29
|
|
30
30
|
def work(job, manager)
|
31
31
|
@job = job
|
@@ -38,7 +38,7 @@ module CapistranoMulticonfigParallel
|
|
38
38
|
@machine = CapistranoMulticonfigParallel::StateMachine.new(job, Actor.current)
|
39
39
|
manager.register_worker_for_job(job, Actor.current)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def debug_enabled?
|
43
43
|
@manager.class.debug_enabled?
|
44
44
|
end
|
@@ -88,18 +88,17 @@ module CapistranoMulticonfigParallel
|
|
88
88
|
def rake_tasks
|
89
89
|
@rake_tasks ||= []
|
90
90
|
end
|
91
|
-
|
92
|
-
|
91
|
+
|
93
92
|
def cd_working_directory
|
94
|
-
"cd #{CapistranoMulticonfigParallel.detect_root
|
93
|
+
"cd #{CapistranoMulticonfigParallel.detect_root}"
|
95
94
|
end
|
96
|
-
|
95
|
+
|
97
96
|
def generate_command
|
98
97
|
<<-CMD
|
99
98
|
#{cd_working_directory} && RAILS_ENV=#{@env_name} bundle exec multi_cap #{@task_argv.join(' ')}
|
100
99
|
CMD
|
101
100
|
end
|
102
|
-
|
101
|
+
|
103
102
|
def execute_deploy
|
104
103
|
@execute_deploy = true
|
105
104
|
debug("invocation chain #{@job_id} is : #{@rake_tasks.inspect}") if debug_enabled? && CapistranoMulticonfigParallel.show_task_progress
|
@@ -124,11 +123,14 @@ module CapistranoMulticonfigParallel
|
|
124
123
|
debug("worker #{@job_id} websocket connection closed: #{code.inspect}, #{reason.inspect}") if debug_enabled?
|
125
124
|
end
|
126
125
|
|
126
|
+
def check_gitflow
|
127
|
+
return if !@env_name == 'staging' || !@manager.can_tag_staging? || !executed_task?(CapistranoMulticonfigParallel::GITFLOW_VERIFY_UPTODATE_TASK)
|
128
|
+
@manager.dispatch_new_job(@job.merge('env' => 'production'))
|
129
|
+
end
|
130
|
+
|
127
131
|
def handle_subscription(message)
|
128
132
|
if message_is_about_a_task?(message)
|
129
|
-
|
130
|
-
@manager.dispatch_new_job(@job.merge('env' => 'production'))
|
131
|
-
end
|
133
|
+
check_gitflow
|
132
134
|
save_tasks_to_be_executed(message)
|
133
135
|
update_machine_state(message['task']) # if message['action'] == 'invoke'
|
134
136
|
debug("worker #{@job_id} state is #{@machine.state}") if debug_enabled?
|
@@ -141,8 +143,8 @@ module CapistranoMulticonfigParallel
|
|
141
143
|
def message_is_about_a_task?(message)
|
142
144
|
message.present? && message.is_a?(Hash) && message['action'].present? && message['job_id'].present? && message['task'].present?
|
143
145
|
end
|
144
|
-
|
145
|
-
def
|
146
|
+
|
147
|
+
def executed_task?(task)
|
146
148
|
@rake_tasks.present? && @rake_tasks[task].present?
|
147
149
|
end
|
148
150
|
|
@@ -203,9 +205,9 @@ module CapistranoMulticonfigParallel
|
|
203
205
|
@env_options = processed_job['env_options']
|
204
206
|
@task_arguments = processed_job['task_arguments']
|
205
207
|
end
|
206
|
-
|
208
|
+
|
207
209
|
def crashed?
|
208
|
-
@action_name == 'deploy:rollback' || @action_name == 'deploy:failed'
|
210
|
+
@action_name == 'deploy:rollback' || @action_name == 'deploy:failed' || @manager.job_failed?(@job)
|
209
211
|
end
|
210
212
|
|
211
213
|
def finish_worker
|
@@ -28,7 +28,7 @@ module CapistranoMulticonfigParallel
|
|
28
28
|
def set_worker_log
|
29
29
|
FileUtils.mkdir_p(CapistranoMulticonfigParallel.log_directory) unless File.directory?(CapistranoMulticonfigParallel.log_directory)
|
30
30
|
@filename = File.join(CapistranoMulticonfigParallel.log_directory, "worker_#{@actor.job_id}.log")
|
31
|
-
FileUtils.rm_rf(@filename) if File.file?(@filename) && !@actor.crashed? &&
|
31
|
+
FileUtils.rm_rf(@filename) if File.file?(@filename) && !@actor.crashed? && (@options[:dry_run] || @actor.executed_dry_run != true)
|
32
32
|
@worker_log = ::Logger.new(@filename)
|
33
33
|
@worker_log.level = ::Logger::Severity::DEBUG
|
34
34
|
@worker_log.formatter = proc do |severity, datetime, progname, msg|
|
@@ -50,42 +50,52 @@ module CapistranoMulticonfigParallel
|
|
50
50
|
puts "\n"
|
51
51
|
sleep(1)
|
52
52
|
end
|
53
|
-
|
54
|
-
def
|
55
|
-
job = @manager.jobs[job_id]
|
56
|
-
processed_job = @manager.process_job(job)
|
57
|
-
worker = @manager.get_worker_for_job(job_id)
|
53
|
+
|
54
|
+
def worker_state(worker)
|
58
55
|
if worker.alive?
|
59
56
|
state = worker.machine.state.to_s
|
60
|
-
|
57
|
+
worker.crashed? ? state.red : state.green
|
61
58
|
else
|
62
|
-
|
59
|
+
'dead'.upcase.red
|
63
60
|
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def worker_env_options(processed_job)
|
64
64
|
worker_optons = ''
|
65
65
|
processed_job['env_options'].each do |key, value|
|
66
66
|
worker_optons << "#{key}=#{value}\n"
|
67
67
|
end
|
68
|
-
|
69
|
-
|
68
|
+
worker_optons
|
69
|
+
end
|
70
|
+
|
71
|
+
def worker_action(processed_job)
|
72
|
+
processed_job['task_arguments'].present? ? "#{processed_job['action_name']}[#{processed_job['task_arguments'].join(',')}]" : processed_job['action_name']
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_worker_details(job_id)
|
76
|
+
job = @manager.jobs[job_id]
|
77
|
+
processed_job = @manager.process_job(job)
|
78
|
+
worker = @manager.get_worker_for_job(job_id)
|
79
|
+
|
70
80
|
{
|
71
81
|
'job_id' => job_id,
|
72
|
-
'app_name' =>processed_job['app_name'],
|
73
|
-
'env_name' =>processed_job['env_name'],
|
74
|
-
'action_name' =>
|
75
|
-
'env_options' =>
|
82
|
+
'app_name' => processed_job['app_name'],
|
83
|
+
'env_name' => processed_job['env_name'],
|
84
|
+
'action_name' => worker_action(processed_job),
|
85
|
+
'env_options' => worker_env_options(processed_job),
|
76
86
|
'task_arguments' => job['task_arguments'],
|
77
|
-
'state' =>
|
87
|
+
'state' => worker_state(worker)
|
78
88
|
}
|
79
89
|
end
|
80
|
-
|
90
|
+
|
81
91
|
def add_job_to_table(table, job_id)
|
82
92
|
details = get_worker_details(job_id)
|
83
93
|
row = [{ value: job_id.to_s },
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
94
|
+
{ value: "#{details['app_name']}\n#{details['env_name']}" },
|
95
|
+
{ value: details['action_name'] },
|
96
|
+
{ value: details['env_options'] },
|
97
|
+
{ value: "#{details['state']}" }
|
98
|
+
]
|
89
99
|
if CapistranoMulticonfigParallel.show_task_progress
|
90
100
|
row << { value: worker.rake_tasks.size }
|
91
101
|
row << { value: worker_progress(worker) }
|
@@ -98,7 +108,6 @@ module CapistranoMulticonfigParallel
|
|
98
108
|
system('cls') || system('clear') || puts("\e[H\e[2J")
|
99
109
|
end
|
100
110
|
|
101
|
-
|
102
111
|
def worker_progress(worker)
|
103
112
|
tasks = worker.rake_tasks
|
104
113
|
current_task = worker.machine.state
|
@@ -27,7 +27,7 @@ module CapistranoMulticonfigParallel
|
|
27
27
|
|
28
28
|
def default_config
|
29
29
|
@default_config ||= Configliere::Param.new
|
30
|
-
@default_config.read File.join(
|
30
|
+
@default_config.read File.join(internal_config_directory, 'default.yml')
|
31
31
|
@default_config.resolve!
|
32
32
|
end
|
33
33
|
|
@@ -35,7 +35,11 @@ module CapistranoMulticonfigParallel
|
|
35
35
|
File.join(CapistranoMulticonfigParallel.detect_root.to_s, 'config', 'multi_cap.yml')
|
36
36
|
end
|
37
37
|
|
38
|
-
|
38
|
+
def internal_config_directory
|
39
|
+
File.join(CapistranoMulticonfigParallel.root.to_s, 'capistrano_multiconfig_parallel', 'initializers')
|
40
|
+
end
|
41
|
+
|
42
|
+
def command_line_params
|
39
43
|
[
|
40
44
|
{
|
41
45
|
name: 'multi_debug',
|
@@ -122,7 +126,7 @@ module CapistranoMulticonfigParallel
|
|
122
126
|
default: default_config[:application_dependencies]
|
123
127
|
}
|
124
128
|
]
|
125
|
-
|
129
|
+
end
|
126
130
|
|
127
131
|
def capistrano_options
|
128
132
|
command_line_params.map do |param|
|
@@ -181,5 +185,5 @@ module CapistranoMulticonfigParallel
|
|
181
185
|
CapistranoMulticonfigParallel.execute_in_sequence = true if c[:multi_secvential].to_s.downcase == 'true'
|
182
186
|
end
|
183
187
|
end
|
184
|
-
end
|
188
|
+
end
|
185
189
|
end
|
@@ -5,7 +5,7 @@ module CapistranoMulticonfigParallel
|
|
5
5
|
class BaseManager
|
6
6
|
include Celluloid
|
7
7
|
include Celluloid::Logger
|
8
|
-
|
8
|
+
|
9
9
|
attr_accessor :condition, :manager, :deps, :application, :stage, :name, :args, :argv, :jobs, :job_registered_condition, :default_stage, :original_argv
|
10
10
|
|
11
11
|
def initialize(cap_app, top_level_tasks, stages)
|
@@ -40,11 +40,15 @@ module CapistranoMulticonfigParallel
|
|
40
40
|
def configuration
|
41
41
|
CapistranoMulticonfigParallel.configuration
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def start(&block)
|
45
|
-
CapistranoMulticonfigParallel.configuration_valid?
|
46
|
-
@default_stage = CapistranoMulticonfigParallel.configuration.development_stages.present? ? CapistranoMulticonfigParallel.configuration.development_stages.first : 'development'
|
47
45
|
check_before_starting
|
46
|
+
initialize_data
|
47
|
+
block.call if block_given?
|
48
|
+
run
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize_data
|
48
52
|
@application = custom_command? ? nil : @top_level_tasks.first.split(':').reverse[1]
|
49
53
|
@stage = custom_command? ? nil : @top_level_tasks.first.split(':').reverse[0]
|
50
54
|
@stage = @stage.present? ? @stage : @default_stage
|
@@ -52,21 +56,21 @@ module CapistranoMulticonfigParallel
|
|
52
56
|
@argv = @cap_app.handle_options.delete_if { |arg| arg == @stage || arg == @name || arg == @top_level_tasks.first }
|
53
57
|
@argv = multi_fetch_argv(@argv)
|
54
58
|
@original_argv = @argv.clone
|
55
|
-
block.call if block_given?
|
56
|
-
run
|
57
59
|
end
|
58
|
-
|
60
|
+
|
59
61
|
def verify_options_custom_command(options)
|
60
62
|
options[:action] = @argv['ACTION'].present? ? @argv['ACTION'] : 'deploy'
|
61
63
|
@argv = @argv['ACTION'].present? ? @argv.except('ACTION') : @argv
|
62
64
|
options
|
63
65
|
end
|
64
|
-
|
66
|
+
|
65
67
|
def check_before_starting
|
68
|
+
CapistranoMulticonfigParallel.configuration_valid?
|
69
|
+
@default_stage = CapistranoMulticonfigParallel.configuration.development_stages.present? ? CapistranoMulticonfigParallel.configuration.development_stages.first : 'development'
|
66
70
|
@condition = Celluloid::Condition.new
|
67
71
|
@manager = CapistranoMulticonfigParallel::CelluloidManager.new(Actor.current)
|
68
72
|
end
|
69
|
-
|
73
|
+
|
70
74
|
def collect_jobs(options = {}, &block)
|
71
75
|
options = prepare_options(options)
|
72
76
|
block.call(options) if block_given?
|
@@ -82,48 +86,50 @@ module CapistranoMulticonfigParallel
|
|
82
86
|
run_async_jobs
|
83
87
|
end
|
84
88
|
end
|
85
|
-
|
89
|
+
|
86
90
|
def tag_staging_exists? # check exists task from capistrano-gitflow
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
rake1 = Rake::Task[CapistranoMulticonfigParallel::GITFLOW_TAG_STAGING_TASK]
|
92
|
+
rake2 = Rake::Task[GITFLOW_CALCULATE_TAG_TASK]
|
93
|
+
rake3 = Rake::Task[GITFLOW_VERIFY_UPTODATE_TASK]
|
94
|
+
check_giflow_tasks(rake1, rake2, rake3)
|
95
|
+
rescue
|
96
|
+
return false
|
97
|
+
end
|
98
|
+
|
99
|
+
def check_giflow_tasks(rake1, rake2, rake3)
|
100
|
+
rake1.present? && rake2.present? && rake3.present? && rake2.prerequisites.present? && rake2.actions.present? && rake3.prerequisites.present?
|
95
101
|
end
|
96
102
|
|
97
103
|
def fetch_multi_stages
|
98
104
|
stages = @argv['STAGES'].blank? ? '' : @argv['STAGES']
|
99
105
|
@argv = @argv['STAGES'].present? ? @argv.except('STAGES') : @argv
|
100
106
|
stages = parse_inputted_value(value: stages).split(',').compact if stages.present?
|
101
|
-
stages.present? ? stages :
|
107
|
+
stages.present? ? stages : [@default_stage]
|
102
108
|
end
|
103
109
|
|
104
110
|
def wants_deploy_production?
|
105
|
-
|
111
|
+
(!custom_command? && @stage == 'production') || (custom_command? && fetch_multi_stages.include?('production'))
|
106
112
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
113
|
+
|
114
|
+
def can_tag_staging?
|
115
|
+
using_git? && wants_deploy_production? && tag_staging_exists?
|
116
|
+
end
|
117
|
+
|
118
|
+
def check_multi_stages(stages)
|
119
|
+
can_tag_staging? ? stages.reject { |u| u == 'production' } : stages
|
110
120
|
end
|
111
|
-
|
112
|
-
def check_multi_stages(stages)
|
113
|
-
can_tag_staging? ? stages.reject{|u| u == 'production'} : stages
|
114
|
-
end
|
115
|
-
|
121
|
+
|
116
122
|
def deploy_app(options = {})
|
117
123
|
options = options.stringify_keys
|
118
124
|
app = options['app'].is_a?(Hash) ? options['app'] : { 'app' => options['app'] }
|
119
125
|
branch = @branch_backup.present? ? @branch_backup : @argv['BRANCH'].to_s
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
126
|
+
call_task_deploy_app({
|
127
|
+
branch: branch,
|
128
|
+
app: app,
|
129
|
+
action: options['action']
|
130
|
+
}.reverse_merge(options))
|
125
131
|
end
|
126
|
-
|
132
|
+
|
127
133
|
def get_app_additional_env_options(app, app_message)
|
128
134
|
app_name = (app.is_a?(Hash) && app[:app].present?) ? app[:app].camelcase : app
|
129
135
|
app_name = app_name.present? ? app_name : 'current application'
|
@@ -133,11 +139,11 @@ module CapistranoMulticonfigParallel
|
|
133
139
|
end
|
134
140
|
|
135
141
|
def confirmation_applies_to_all_workers?
|
136
|
-
environments = @jobs.map{|job| job['env']}
|
142
|
+
environments = @jobs.map { |job| job['env'] }
|
137
143
|
CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.all? { |e| environments.include?(e) }
|
138
144
|
end
|
139
|
-
|
140
|
-
|
145
|
+
|
146
|
+
private
|
141
147
|
|
142
148
|
def call_task_deploy_app(options = {})
|
143
149
|
options = options.stringify_keys
|
@@ -183,9 +189,8 @@ module CapistranoMulticonfigParallel
|
|
183
189
|
options['env_options'] = options['env_options'].reverse_merge(env_opts.except('BOX'))
|
184
190
|
|
185
191
|
env_options = branch_name.present? ? { 'BRANCH' => branch_name }.merge(options['env_options']) : options['env_options']
|
186
|
-
job_env_options =
|
187
|
-
|
188
|
-
|
192
|
+
job_env_options = custom_command? && env_options['ACTION'].present? ? env_options.except('ACTION') : env_options
|
193
|
+
|
189
194
|
job = {
|
190
195
|
app: app,
|
191
196
|
env: options['stage'],
|
@@ -196,8 +201,6 @@ module CapistranoMulticonfigParallel
|
|
196
201
|
job = job.stringify_keys
|
197
202
|
@jobs << job
|
198
203
|
end
|
199
|
-
|
200
|
-
|
201
204
|
|
202
205
|
def prepare_options(options)
|
203
206
|
options = options.stringify_keys
|
@@ -222,13 +225,11 @@ module CapistranoMulticonfigParallel
|
|
222
225
|
return ''
|
223
226
|
end
|
224
227
|
end
|
225
|
-
|
228
|
+
|
226
229
|
def using_git?
|
227
|
-
|
230
|
+
fetch(:scm, :git).to_sym == :git
|
228
231
|
end
|
229
232
|
|
230
|
-
|
231
|
-
|
232
233
|
def fetch_app_additional_env_options
|
233
234
|
options = {}
|
234
235
|
return options if fetch(:app_additional_env_options).blank?
|
@@ -23,7 +23,7 @@ module CapistranoMulticonfigParallel
|
|
23
23
|
end
|
24
24
|
raise ArgumentError, "invalid configuration for #{wrong.inspect}" if wrong.present?
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def run
|
28
28
|
options = {}
|
29
29
|
if custom_command?
|
@@ -39,7 +39,7 @@ module CapistranoMulticonfigParallel
|
|
39
39
|
CapistranoMulticonfigParallel.interactive_menu = true
|
40
40
|
options = verify_options_custom_command(options)
|
41
41
|
action_name = @name
|
42
|
-
if
|
42
|
+
if action_name == custom_commands[:stages]
|
43
43
|
multi_stage_deploy(options)
|
44
44
|
else
|
45
45
|
raise "Custom command #{@name} not available for multi apps"
|
@@ -66,7 +66,7 @@ module CapistranoMulticonfigParallel
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
|
69
|
+
private
|
70
70
|
|
71
71
|
def multi_collect_and_run_jobs(options = {}, &block)
|
72
72
|
collect_jobs(options) do |new_options|
|
@@ -49,7 +49,7 @@ module CapistranoMulticonfigParallel
|
|
49
49
|
num = number_option.to_i
|
50
50
|
if /^[0-9]+/.match(num.to_s) && ((num.to_i > 0 && num.to_i <= applications.size))
|
51
51
|
num -= 1
|
52
|
-
msg += "#{applications[num]} was #{choices[num].present? ? 'un' : ''
|
52
|
+
msg += "#{applications[num]} was #{choices[num].present? ? 'un' : ''}checked\n"
|
53
53
|
choices[num] = choices[num].blank? ? '+' : ' '
|
54
54
|
else
|
55
55
|
msg = "Invalid option: #{num}\n"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bogdanRada
|
@@ -454,9 +454,9 @@ dependencies:
|
|
454
454
|
name: rubocop
|
455
455
|
requirement: !ruby/object:Gem::Requirement
|
456
456
|
requirements:
|
457
|
-
- -
|
457
|
+
- - "~>"
|
458
458
|
- !ruby/object:Gem::Version
|
459
|
-
version: '0
|
459
|
+
version: '0'
|
460
460
|
- - ">="
|
461
461
|
- !ruby/object:Gem::Version
|
462
462
|
version: '0.29'
|
@@ -464,9 +464,9 @@ dependencies:
|
|
464
464
|
prerelease: false
|
465
465
|
version_requirements: !ruby/object:Gem::Requirement
|
466
466
|
requirements:
|
467
|
-
- -
|
467
|
+
- - "~>"
|
468
468
|
- !ruby/object:Gem::Version
|
469
|
-
version: '0
|
469
|
+
version: '0'
|
470
470
|
- - ">="
|
471
471
|
- !ruby/object:Gem::Version
|
472
472
|
version: '0.29'
|
@@ -476,7 +476,7 @@ dependencies:
|
|
476
476
|
requirements:
|
477
477
|
- - "~>"
|
478
478
|
- !ruby/object:Gem::Version
|
479
|
-
version: '0
|
479
|
+
version: '0'
|
480
480
|
- - ">="
|
481
481
|
- !ruby/object:Gem::Version
|
482
482
|
version: '0.6'
|
@@ -486,7 +486,7 @@ dependencies:
|
|
486
486
|
requirements:
|
487
487
|
- - "~>"
|
488
488
|
- !ruby/object:Gem::Version
|
489
|
-
version: '0
|
489
|
+
version: '0'
|
490
490
|
- - ">="
|
491
491
|
- !ruby/object:Gem::Version
|
492
492
|
version: '0.6'
|
@@ -496,7 +496,7 @@ dependencies:
|
|
496
496
|
requirements:
|
497
497
|
- - "~>"
|
498
498
|
- !ruby/object:Gem::Version
|
499
|
-
version: '0
|
499
|
+
version: '0'
|
500
500
|
- - ">="
|
501
501
|
- !ruby/object:Gem::Version
|
502
502
|
version: 0.8.7
|
@@ -506,7 +506,7 @@ dependencies:
|
|
506
506
|
requirements:
|
507
507
|
- - "~>"
|
508
508
|
- !ruby/object:Gem::Version
|
509
|
-
version: '0
|
509
|
+
version: '0'
|
510
510
|
- - ">="
|
511
511
|
- !ruby/object:Gem::Version
|
512
512
|
version: 0.8.7
|
@@ -516,7 +516,7 @@ dependencies:
|
|
516
516
|
requirements:
|
517
517
|
- - "~>"
|
518
518
|
- !ruby/object:Gem::Version
|
519
|
-
version: '0
|
519
|
+
version: '0'
|
520
520
|
- - ">="
|
521
521
|
- !ruby/object:Gem::Version
|
522
522
|
version: '0.1'
|
@@ -526,7 +526,7 @@ dependencies:
|
|
526
526
|
requirements:
|
527
527
|
- - "~>"
|
528
528
|
- !ruby/object:Gem::Version
|
529
|
-
version: '0
|
529
|
+
version: '0'
|
530
530
|
- - ">="
|
531
531
|
- !ruby/object:Gem::Version
|
532
532
|
version: '0.1'
|
@@ -536,7 +536,7 @@ dependencies:
|
|
536
536
|
requirements:
|
537
537
|
- - "~>"
|
538
538
|
- !ruby/object:Gem::Version
|
539
|
-
version: '3
|
539
|
+
version: '3'
|
540
540
|
- - ">="
|
541
541
|
- !ruby/object:Gem::Version
|
542
542
|
version: 3.2.2
|
@@ -546,7 +546,7 @@ dependencies:
|
|
546
546
|
requirements:
|
547
547
|
- - "~>"
|
548
548
|
- !ruby/object:Gem::Version
|
549
|
-
version: '3
|
549
|
+
version: '3'
|
550
550
|
- - ">="
|
551
551
|
- !ruby/object:Gem::Version
|
552
552
|
version: 3.2.2
|
@@ -556,7 +556,7 @@ dependencies:
|
|
556
556
|
requirements:
|
557
557
|
- - "~>"
|
558
558
|
- !ruby/object:Gem::Version
|
559
|
-
version: '1
|
559
|
+
version: '1'
|
560
560
|
- - ">="
|
561
561
|
- !ruby/object:Gem::Version
|
562
562
|
version: 1.3.3
|
@@ -566,7 +566,7 @@ dependencies:
|
|
566
566
|
requirements:
|
567
567
|
- - "~>"
|
568
568
|
- !ruby/object:Gem::Version
|
569
|
-
version: '1
|
569
|
+
version: '1'
|
570
570
|
- - ">="
|
571
571
|
- !ruby/object:Gem::Version
|
572
572
|
version: 1.3.3
|
@@ -576,7 +576,7 @@ dependencies:
|
|
576
576
|
requirements:
|
577
577
|
- - "~>"
|
578
578
|
- !ruby/object:Gem::Version
|
579
|
-
version: '0
|
579
|
+
version: '0'
|
580
580
|
- - ">="
|
581
581
|
- !ruby/object:Gem::Version
|
582
582
|
version: 0.5.10
|
@@ -586,7 +586,7 @@ dependencies:
|
|
586
586
|
requirements:
|
587
587
|
- - "~>"
|
588
588
|
- !ruby/object:Gem::Version
|
589
|
-
version: '0
|
589
|
+
version: '0'
|
590
590
|
- - ">="
|
591
591
|
- !ruby/object:Gem::Version
|
592
592
|
version: 0.5.10
|
@@ -596,7 +596,7 @@ dependencies:
|
|
596
596
|
requirements:
|
597
597
|
- - "~>"
|
598
598
|
- !ruby/object:Gem::Version
|
599
|
-
version: '0
|
599
|
+
version: '0'
|
600
600
|
- - ">="
|
601
601
|
- !ruby/object:Gem::Version
|
602
602
|
version: 0.1.0
|
@@ -606,7 +606,7 @@ dependencies:
|
|
606
606
|
requirements:
|
607
607
|
- - "~>"
|
608
608
|
- !ruby/object:Gem::Version
|
609
|
-
version: '0
|
609
|
+
version: '0'
|
610
610
|
- - ">="
|
611
611
|
- !ruby/object:Gem::Version
|
612
612
|
version: 0.1.0
|