capistrano_multiconfig_parallel 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69b1623c9bafea21ddff2b588f08bee7b214408a
4
- data.tar.gz: 2e9cb754af33f0f6808b9821b97b2e96d65998ad
3
+ metadata.gz: 3ccbcbb8b3f6f253696e7c0f5c4da3a6c86406e9
4
+ data.tar.gz: 42654d0b3a82c272c861d9db8ec1a06ed8cddedd
5
5
  SHA512:
6
- metadata.gz: d492ad626da0730b60f0dd1214ed43e64872d3237fcdf9195290608834e009de3c36989fbfe7d128af13ddb13de6d0ac4a5d13bd20bd50e9bb661b13c67c8975
7
- data.tar.gz: cea9979e1f32025ebf7a9bd2692085a5060670a1ca5bbd530d45d4add7d618ef8a959f0c65b1fd73386039f9aebeee6e2f0e7e421bf4afd84b52f324e15cbb39
6
+ metadata.gz: c16fa1a27b1f804f35b16384a99a98137a70d1624d3d862c426b0f2ee812e9e8c9da9f7dcd0b49cddc7cd614b859df3f13d9c2e5cd2908e6c1627e99c2e7bd3e
7
+ data.tar.gz: 7174e0d08f121447676b29423e990331ac5cd72e169de126d5511552331499c34d60d0e06c97f99769e4cee26c86b97ce7847768d796a07b9799e71a9642710d
@@ -25,10 +25,20 @@ module CapistranoMulticonfigParallel
25
25
  File.expand_path(File.dirname(__dir__))
26
26
  end
27
27
 
28
+ def check_terminal_tty
29
+ $stdin.sync = true if $stdin.isatty
30
+ $stdout.sync = true if $stdout.isatty
31
+ end
32
+
28
33
  def ask_confirm(message, default)
29
- Ask.input message, default: default
30
- rescue
31
- return nil
34
+ `stty -raw echo`
35
+ check_terminal_tty
36
+ result = Ask.input message, default: default
37
+ $stdout.flush
38
+ `stty -raw echo`
39
+ return result
40
+ rescue
41
+ return nil
32
42
  end
33
43
 
34
44
  def log_directory
@@ -111,12 +111,13 @@ module CapistranoMulticonfigParallel
111
111
  def apply_confirmations?
112
112
  CapistranoMulticonfigParallel.configuration.task_confirmation_active.to_s.downcase == 'true'
113
113
  end
114
+
114
115
  def syncronization_required?
115
116
  CapistranoMulticonfigParallel.configuration.syncronize_confirmation.to_s.downcase == 'true'
116
117
  end
117
-
118
+
118
119
  def syncronized_confirmation?
119
- ( syncronization_required? && !@job_manager.executes_deploy_stages?) ||
120
+ (syncronization_required? && !@job_manager.executes_deploy_stages?) ||
120
121
  (syncronization_required? && @job_manager.executes_deploy_stages? && !@job_manager.can_tag_staging? && @job_manager.confirmation_applies_to_all_workers?)
121
122
  end
122
123
 
@@ -223,9 +224,9 @@ module CapistranoMulticonfigParallel
223
224
  end
224
225
 
225
226
  def filtered_env_keys
226
- ["STAGES", "ACTION"]
227
+ %w(STAGES ACTION)
227
228
  end
228
-
229
+
229
230
  def process_job(job)
230
231
  env_options = {}
231
232
  job['env_options'].each do |key, value|
@@ -55,6 +55,10 @@ module CapistranoMulticonfigParallel
55
55
  @client.publish(rake_actor_id(data), data)
56
56
  end
57
57
 
58
+ def publish_io_event(data)
59
+ @client.publish("rake_io_#{@job_id}", 'approved' => 'yes', 'action' => 'stdin', 'job_id' => @job_id, 'result' => data)
60
+ end
61
+
58
62
  def rake_actor_id(data)
59
63
  data['action'].present? && data['action'] == 'count' ? "rake_worker_#{@job_id}_count" : "rake_worker_#{@job_id}"
60
64
  end
@@ -189,6 +193,7 @@ module CapistranoMulticonfigParallel
189
193
  array_options << "#{key}=#{value}" if value.present?
190
194
  end
191
195
  array_options << '--trace' if debug_enabled?
196
+ array_options << '--multi_debug=true' if debug_enabled?
192
197
  setup_command_line(*array_options)
193
198
  end
194
199
 
@@ -94,8 +94,31 @@ module CapistranoMulticonfigParallel
94
94
  @process ||= process
95
95
  end
96
96
 
97
+ def get_question_details(data)
98
+ question = ''
99
+ default = nil
100
+ if data =~ /(.*)\?+\s*\:*\s*(\([^)]*\))*/m
101
+ question = Regexp.last_match(1)
102
+ default = Regexp.last_match(2)
103
+ end
104
+ question.present? ? [question, default] : nil
105
+ end
106
+
107
+ def printing_question?(data)
108
+ get_question_details(data).present?
109
+ end
110
+
111
+ def user_prompt_needed?(data)
112
+ return unless printing_question?(data)
113
+ details = get_question_details(data)
114
+ default = details.second.present? ? details.second : nil
115
+ result = CapistranoMulticonfigParallel.ask_confirm(details.first, default)
116
+ @actor.publish_io_event(result)
117
+ end
118
+
97
119
  def io_callback(io, data)
98
120
  @worker_log.debug("#{io.upcase} ---- #{data}")
121
+ # user_prompt_needed?(data)
99
122
  end
100
123
  end
101
124
  end
@@ -4,45 +4,70 @@ module CapistranoMulticonfigParallel
4
4
  include Celluloid
5
5
  include Celluloid::Logger
6
6
 
7
- attr_accessor :env, :client, :job_id, :action, :task, :task_approved, :successfull_subscription, :subscription_channel, :publisher_channel
7
+ attr_accessor :env, :client, :job_id, :action, :task, :task_approved, :successfull_subscription, :subscription_channel, :publisher_channel, :stdin_result
8
8
 
9
- def work(env, task, options = {})
9
+ def work(env, options = {})
10
10
  @options = options.stringify_keys
11
11
  @env = env
12
- @job_id = find_job_id
13
- @subscription_channel = @options['rake_actor_id']
14
- @publisher_channel = "worker_#{find_job_id}"
15
- @action = @options['rake_actor_id'].include?('_count') ? 'count' : 'invoke'
16
- @task = task
12
+ default_settings
13
+ custom_attributes
14
+ initialize_subscription
15
+ end
16
+
17
+ def custom_attributes
18
+ @publisher_channel = "worker_#{@job_id}"
19
+ @action = @options['actor_id'].include?('_count') ? 'count' : 'invoke'
20
+ @task = @options['task']
21
+ end
22
+
23
+ def wait_execution(name = task_name, time = 0.1)
24
+ info "Before waiting #{name}"
25
+ Actor.current.wait_for(name, time)
26
+ info "After waiting #{name}"
27
+ end
28
+
29
+ def wait_for(name, time)
30
+ info "waiting for #{time} seconds on #{name}"
31
+ sleep time
32
+ info "done waiting on #{name} "
33
+ end
34
+
35
+ def default_settings
36
+ @stdin_result = nil
37
+ @job_id = @options['job_id']
38
+ @subscription_channel = @options['actor_id']
17
39
  @task_approved = false
18
40
  @successfull_subscription = false
19
- @client = CelluloidPubsub::Client.connect(actor: Actor.current, enable_debug: CapistranoMulticonfigParallel::CelluloidManager.debug_websocket?) do |ws|
41
+ end
42
+
43
+ def initialize_subscription
44
+ @client = CelluloidPubsub::Client.connect(actor: Actor.current, enable_debug: debug_enabled?) do |ws|
20
45
  ws.subscribe(@subscription_channel)
21
46
  end if !defined?(@client) || @client.nil?
22
47
  end
23
48
 
24
49
  def debug_enabled?
25
- @client.debug_enabled?
50
+ CapistranoMulticonfigParallel::CelluloidManager.debug_websocket?
26
51
  end
27
52
 
28
53
  def task_name
29
54
  @task.name
30
55
  end
31
56
 
32
- def find_job_id
33
- @env[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
34
- end
35
-
36
57
  def task_data
37
58
  {
38
59
  action: @action,
39
60
  task: task_name,
40
- job_id: find_job_id
61
+ job_id: @job_id
41
62
  }
42
63
  end
43
64
 
44
- def publish_new_work(env, task)
45
- work(env, task, rake_actor_id: @options['rake_actor_id'])
65
+ def publish_new_work(env, new_options = {})
66
+ work(env, @options.merge(new_options))
67
+ after_publishing_new_work
68
+ end
69
+
70
+ def after_publishing_new_work
46
71
  publish_to_worker(task_data)
47
72
  end
48
73
 
@@ -51,7 +76,7 @@ module CapistranoMulticonfigParallel
51
76
  end
52
77
 
53
78
  def on_message(message)
54
- debug("Rake worker #{find_job_id} received after parse #{message}") if debug_enabled?
79
+ debug("Rake worker #{@job_id} received after parse #{message}") if debug_enabled?
55
80
  if @client.succesfull_subscription?(message)
56
81
  publish_subscription_successfull
57
82
  elsif message.present? && message['client_action'].blank?
@@ -61,12 +86,24 @@ module CapistranoMulticonfigParallel
61
86
  end
62
87
  end
63
88
 
89
+ def msg_for_stdin?(message)
90
+ message['action'] == 'stdin'
91
+ end
92
+
64
93
  def publish_subscription_successfull
65
- debug("Rake worker #{find_job_id} received parse #{message}") if debug_enabled?
94
+ debug("Rake worker #{@job_id} received parse #{message}") if debug_enabled?
66
95
  publish_to_worker(task_data)
67
96
  @successfull_subscription = true
68
97
  end
69
98
 
99
+ def stdin_approval(message)
100
+ if @job_id.to_i == message['job_id'].to_i && message['approved'] == 'yes'
101
+ @stdin_result = message
102
+ else
103
+ warn "unknown invocation #{message.inspect}" if debug_enabled?
104
+ end
105
+ end
106
+
70
107
  def task_approval(message)
71
108
  if @job_id.to_i == message['job_id'].to_i && message['task'] == task_name && message['approved'] == 'yes'
72
109
  @task_approved = true
@@ -72,6 +72,10 @@ module CapistranoMulticonfigParallel
72
72
  processed_job['task_arguments'].present? ? "#{processed_job['action_name']}[#{processed_job['task_arguments'].join(',')}]" : processed_job['action_name']
73
73
  end
74
74
 
75
+ def worker_stage(processed_job)
76
+ processed_job['app_name'].present? ? "#{processed_job['app_name']}\n#{processed_job['env_name']}" : "#{processed_job['env_name']}"
77
+ end
78
+
75
79
  def get_worker_details(job_id)
76
80
  job = @manager.jobs[job_id]
77
81
  processed_job = @manager.process_job(job)
@@ -81,6 +85,7 @@ module CapistranoMulticonfigParallel
81
85
  'job_id' => job_id,
82
86
  'app_name' => processed_job['app_name'],
83
87
  'env_name' => processed_job['env_name'],
88
+ 'full_stage' => worker_stage(processed_job),
84
89
  'action_name' => worker_action(processed_job),
85
90
  'env_options' => worker_env_options(processed_job),
86
91
  'task_arguments' => job['task_arguments'],
@@ -91,7 +96,7 @@ module CapistranoMulticonfigParallel
91
96
  def add_job_to_table(table, job_id)
92
97
  details = get_worker_details(job_id)
93
98
  row = [{ value: job_id.to_s },
94
- { value: "#{details['app_name']}\n#{details['env_name']}" },
99
+ { value: details['full_stage'] },
95
100
  { value: details['action_name'] },
96
101
  { value: details['env_options'] },
97
102
  { value: "#{details['state']}" }
@@ -4,20 +4,15 @@ module CapistranoMulticonfigParallel
4
4
  # this is the class that will be invoked from terminal , and willl use the invoke task as the primary function.
5
5
  class CLI
6
6
  def self.start
7
- if $stdin.isatty
8
- $stdin.sync = true
9
- end
10
- if $stdout.isatty
11
- $stdout.sync = true
12
- end
7
+ CapistranoMulticonfigParallel.check_terminal_tty
13
8
  CapistranoMulticonfigParallel.original_args = ARGV.dup
14
9
  CapistranoMulticonfigParallel::Application.new.run
15
- rescue Interrupt
16
- `stty icanon echo`
17
- $stderr.puts 'Command cancelled.'
18
- rescue => error
19
- $stderr.puts error
20
- exit(1)
10
+ rescue Interrupt
11
+ `stty icanon echo`
12
+ $stderr.puts 'Command cancelled.'
13
+ rescue => error
14
+ $stderr.puts error
15
+ exit(1)
21
16
  end
22
17
  end
23
18
  end
@@ -35,11 +35,11 @@ module CapistranoMulticonfigParallel
35
35
  File.join(CapistranoMulticonfigParallel.detect_root.to_s, 'config', 'multi_cap.yml')
36
36
  end
37
37
 
38
- def internal_config_directory
39
- File.join(CapistranoMulticonfigParallel.root.to_s, 'capistrano_multiconfig_parallel', 'initializers')
40
- end
41
-
42
- def command_line_params
38
+ def internal_config_directory
39
+ File.join(CapistranoMulticonfigParallel.root.to_s, 'capistrano_multiconfig_parallel', 'initializers')
40
+ end
41
+
42
+ def command_line_params
43
43
  [
44
44
  {
45
45
  name: 'multi_debug',
@@ -126,7 +126,7 @@ module CapistranoMulticonfigParallel
126
126
  default: default_config[:application_dependencies]
127
127
  }
128
128
  ]
129
- end
129
+ end
130
130
 
131
131
  def capistrano_options
132
132
  command_line_params.map do |param|
@@ -1,28 +1,14 @@
1
+ require_relative '../helpers/extension_helper'
1
2
  Rake::Task.class_eval do
2
3
  alias_method :original_execute, :execute
3
4
 
4
5
  def execute(args = nil)
5
- job_id = ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
6
- if job_id.present?
7
- run_the_actor(job_id) do
6
+ if CapistranoMulticonfigParallel::ExtensionHelper.inside_job?
7
+ CapistranoMulticonfigParallel::ExtensionHelper.run_the_actor(self) do
8
8
  original_execute(*args)
9
9
  end
10
10
  else
11
11
  original_execute(*args)
12
12
  end
13
13
  end
14
-
15
- def run_the_actor(job_id)
16
- rake_actor_id = ENV['count_rake'].present? ? "rake_worker_#{job_id}_count" : "rake_worker_#{job_id}"
17
- if Celluloid::Actor[rake_actor_id].blank?
18
- CapistranoMulticonfigParallel::RakeWorker.supervise_as rake_actor_id
19
- Celluloid::Actor[rake_actor_id].work(ENV, self, rake_actor_id: rake_actor_id)
20
- else
21
- Celluloid::Actor[rake_actor_id].publish_new_work(ENV, self)
22
- end
23
- until Celluloid::Actor[rake_actor_id].task_approved
24
- sleep(0.1) # keep current thread alive
25
- end
26
- yield if Celluloid::Actor[rake_actor_id].task_approved
27
- end
28
14
  end
@@ -1,4 +1,5 @@
1
1
  require_relative './standard_deploy'
2
+ require_relative '../celluloid/celluloid_manager'
2
3
  module CapistranoMulticonfigParallel
3
4
  # finds app dependencies, shows menu and delegates jobs to celluloid manager
4
5
  # rubocop:disable ClassLength
@@ -88,8 +89,8 @@ module CapistranoMulticonfigParallel
88
89
 
89
90
  def tag_staging_exists? # check exists task from capistrano-gitflow
90
91
  check_giflow_tasks(
91
- CapistranoMulticonfigParallel::GITFLOW_TAG_STAGING_TASK,
92
- CapistranoMulticonfigParallel::GITFLOW_CALCULATE_TAG_TASK,
92
+ CapistranoMulticonfigParallel::GITFLOW_TAG_STAGING_TASK,
93
+ CapistranoMulticonfigParallel::GITFLOW_CALCULATE_TAG_TASK,
93
94
  CapistranoMulticonfigParallel::GITFLOW_VERIFY_UPTODATE_TASK
94
95
  )
95
96
  rescue
@@ -97,14 +98,14 @@ module CapistranoMulticonfigParallel
97
98
  end
98
99
 
99
100
  def check_giflow_tasks(*tasks)
100
- tasks.all? {|t| Rake::Task[t].present? }
101
+ tasks.all? { |t| Rake::Task[t].present? }
101
102
  end
102
103
 
103
104
  def fetch_multi_stages
104
105
  stages = @argv['STAGES'].blank? ? '' : @argv['STAGES']
105
- stages = parse_inputted_value(value: stages).split(',').compact if stages.present?
106
- stages = stages.present? ? stages : [@default_stage]
107
- return stages
106
+ stages = parse_inputted_value('value' => stages).split(',').compact if stages.present?
107
+ stages = stages.present? ? stages : [@default_stage]
108
+ stages
108
109
  end
109
110
 
110
111
  def wants_deploy_production?
@@ -139,7 +140,7 @@ module CapistranoMulticonfigParallel
139
140
  end
140
141
 
141
142
  def worker_environments
142
- @jobs.map { |job| job['env'] }
143
+ @jobs.map { |job| job['env'] }
143
144
  end
144
145
 
145
146
  def confirmation_applies_to_all_workers?
@@ -189,7 +190,7 @@ module CapistranoMulticonfigParallel
189
190
  message = box.present? ? "BOX #{box}:" : "stage #{options['stage']}:"
190
191
  env_opts = get_app_additional_env_options(app, message)
191
192
 
192
- options['env_options'] = options['env_options'].reverse_merge(env_opts.except('BOX'))
193
+ options['env_options'] = options['env_options'].reverse_merge(env_opts)
193
194
 
194
195
  env_options = branch_name.present? ? { 'BRANCH' => branch_name }.merge(options['env_options']) : options['env_options']
195
196
  job_env_options = custom_command? && env_options['ACTION'].present? ? env_options.except('ACTION') : env_options
@@ -197,7 +198,7 @@ module CapistranoMulticonfigParallel
197
198
  job = {
198
199
  app: app,
199
200
  env: options['stage'],
200
- action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
201
+ action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
201
202
  task_arguments: options['task_arguments'],
202
203
  env_options: job_env_options
203
204
  }
@@ -236,7 +237,7 @@ module CapistranoMulticonfigParallel
236
237
  def fetch_app_additional_env_options
237
238
  options = {}
238
239
  return options if fetch(:app_additional_env_options).blank?
239
- env_options = parse_inputted_value(key: :app_additional_env_options)
240
+ env_options = parse_inputted_value('key' => :app_additional_env_options)
240
241
  env_options = env_options.split(' ')
241
242
  options = multi_fetch_argv(env_options)
242
243
  options.stringify_keys!
@@ -254,7 +255,7 @@ module CapistranoMulticonfigParallel
254
255
  end
255
256
 
256
257
  def execute_on_multiple_boxes(main_box_name, options)
257
- boxes = parse_inputted_value(value: main_box_name).split(',').compact
258
+ boxes = parse_inputted_value('value' => main_box_name).split(',').compact
258
259
  boxes.each do |box_name|
259
260
  options['env_options']['BOX'] = box_name
260
261
  prepare_job(options)
@@ -0,0 +1,41 @@
1
+ module CapistranoMulticonfigParallel
2
+ class ExtensionHelper
3
+ class << self
4
+ def inside_job?
5
+ job_id.present?
6
+ end
7
+
8
+ def job_id
9
+ ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
10
+ end
11
+
12
+ def rake_actor_id
13
+ ENV['count_rake'].present? ? "rake_worker_#{job_id}_count" : "rake_worker_#{job_id}"
14
+ end
15
+
16
+ def stdin_result
17
+ Celluloid::Actor[rake_actor_id].stdin_result
18
+ end
19
+
20
+ def run_stdin_actor
21
+ Celluloid::Actor[rake_actor_id].wait_execution('stdin') until stdin_result
22
+ output = stdin_result.dup
23
+ Celluloid::Actor[rake_actor_id].stdin_result = nil
24
+ output
25
+ end
26
+
27
+ def run_the_actor(task)
28
+ if Celluloid::Actor[rake_actor_id].blank?
29
+ CapistranoMulticonfigParallel::RakeWorker.supervise_as rake_actor_id
30
+ Celluloid::Actor[rake_actor_id].work(ENV, actor_id: rake_actor_id, job_id: job_id, task: task)
31
+ else
32
+ Celluloid::Actor[rake_actor_id].publish_new_work(ENV, task: task)
33
+ end
34
+ until Celluloid::Actor[rake_actor_id].task_approved
35
+ Celluloid::Actor[rake_actor_id].wait_execution
36
+ end
37
+ yield if Celluloid::Actor[rake_actor_id].task_approved
38
+ end
39
+ end
40
+ end
41
+ end
@@ -19,7 +19,6 @@ module CapistranoMulticonfigParallel
19
19
  applications << 'all_frameworks'
20
20
  interactive_menu = CapistranoMulticonfigParallel::InteractiveMenu.new
21
21
  applications_selected = interactive_menu.show_all_websites_interactive_menu(applications)
22
-
23
22
  applications_selected = applications_selected.gsub("\r\n", '') if applications_selected.present?
24
23
  applications_selected = applications_selected.gsub("\n", '') if applications_selected.present?
25
24
  applications_selected = applications_selected.split(',') if applications_selected.present?
@@ -69,7 +68,7 @@ module CapistranoMulticonfigParallel
69
68
  end
70
69
 
71
70
  def show_frameworks_used(applications_to_deploy, all_frameworks, action)
72
- return [] if applications_to_deploy.blank? || applications_to_deploy.size <= 1
71
+ return [] if applications_to_deploy.blank? || applications_to_deploy.size < 1
73
72
  puts 'The following frameworks will be used:'
74
73
  app_names = []
75
74
  if all_frameworks.present?
@@ -7,8 +7,8 @@ module CapistranoMulticonfigParallel
7
7
  # module used for generating the version
8
8
  module VERSION
9
9
  MAJOR = 0
10
- MINOR = 7
11
- TINY = 7
10
+ MINOR = 8
11
+ TINY = 0
12
12
  PRE = nil
13
13
 
14
14
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
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.7.7
4
+ version: 0.8.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-07-06 00:00:00.000000000 Z
11
+ date: 2015-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid-pmap
@@ -648,6 +648,7 @@ files:
648
648
  - lib/capistrano_multiconfig_parallel/configuration.rb
649
649
  - lib/capistrano_multiconfig_parallel/extensions/rake.rb
650
650
  - lib/capistrano_multiconfig_parallel/helpers/base_manager.rb
651
+ - lib/capistrano_multiconfig_parallel/helpers/extension_helper.rb
651
652
  - lib/capistrano_multiconfig_parallel/helpers/multi_app_manager.rb
652
653
  - lib/capistrano_multiconfig_parallel/helpers/single_app_manager.rb
653
654
  - lib/capistrano_multiconfig_parallel/helpers/standard_deploy.rb