Skip to content

Commit

Permalink
Merge branch 'release/0.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdanRada committed Jul 3, 2015
2 parents 78984d6 + e98d2c8 commit 4d55a70
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 149 deletions.
16 changes: 8 additions & 8 deletions capistrano_multiconfig_parallel.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ Gem::Specification.new do |s|
s.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7'
s.add_development_dependency 'rvm-tester', '~> 1.1', '>= 1.1'

s.add_development_dependency 'rubocop', '0.29', '>= 0.29'
s.add_development_dependency 'phare', '~> 0.6', '>= 0.6'
s.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7'
s.add_development_dependency 'yard-rspec', '~> 0.1', '>= 0.1'
s.add_development_dependency 'redcarpet', '~> 3.2', '>= 3.2.2'
s.add_development_dependency 'github-markup', '~> 1.3', '>= 1.3.3'
s.add_development_dependency 'inch', '~> 0.5', '>= 0.5.10'
s.add_development_dependency 'guard-inch', '~> 0.1', '>= 0.1.0'
s.add_development_dependency 'rubocop', '>=0.29', '>= 0.29'
s.add_development_dependency 'phare', '>= 0.6', '>= 0.6'
s.add_development_dependency 'yard', '>= 0.8', '>= 0.8.7'
s.add_development_dependency 'yard-rspec', '>= 0.1', '>= 0.1'
s.add_development_dependency 'redcarpet', '>= 3.2', '>= 3.2.2'
s.add_development_dependency 'github-markup', '>= 1.3', '>= 1.3.3'
s.add_development_dependency 'inch', '>= 0.5', '>= 0.5.10'
s.add_development_dependency 'guard-inch', '>= 0.1', '>= 0.1.0'
end
1 change: 1 addition & 0 deletions lib/capistrano_multiconfig_parallel/all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
require 'pp'
require 'devnull'
require 'inquirer'
require 'yaml'
# fix error with not files that can not be found
Gem.find_files('composable_state_machine/**/*.rb').each { |path| require path }

Expand Down
10 changes: 4 additions & 6 deletions lib/capistrano_multiconfig_parallel/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ module CapistranoMulticonfigParallel
ENV_KEY_JOB_ID = 'multi_cap_job_id'
MULTI_KEY = 'multi'
SINGLE_KEY = 'single'
GITFLOW_TAG_STAGING_TASK = "gitflow:tag_staging"
GITFLOW_TAG_STAGING_TASK = 'gitflow:tag_staging'
GITFLOW_CALCULATE_TAG_TASK = 'gitflow:calculate_tag'
GITFLOW_VERIFY_UPTODATE_TASK = 'gitflow:verify_up_to_date'

CUSTOM_COMMANDS = {
CapistranoMulticonfigParallel::MULTI_KEY => {
stages: 'deploy_multi_stages'
Expand All @@ -26,11 +26,9 @@ def root
end

def ask_confirm(message, default)
begin
Ask.input message, default: default
rescue
return nil
end
end

def log_directory
Expand All @@ -48,15 +46,15 @@ def websokect_log_file
def enable_logging
CapistranoMulticonfigParallel.configuration_valid?
FileUtils.mkdir_p(log_directory) unless File.directory?(log_directory)
if CapistranoMulticonfigParallel::CelluloidManager.debug_enabled.to_s.downcase == 'true'
if CapistranoMulticonfigParallel::CelluloidManager.debug_enabled.to_s.downcase == 'true'
FileUtils.touch(main_log_file) unless File.file?(main_log_file)
if ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
log_file = File.open(main_log_file, 'w')
log_file.sync = true
end
self.logger = ::Logger.new(main_log_file)
else
self.logger = ::Logger.new(DevNull.new)
self.logger = ::Logger.new(DevNull.new)
end
Celluloid.logger = CapistranoMulticonfigParallel.logger
Celluloid.task_class = Celluloid::TaskThread
Expand Down
86 changes: 46 additions & 40 deletions lib/capistrano_multiconfig_parallel/celluloid/celluloid_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,21 @@ def register_worker_for_job(job, worker)
debug("job id not found. delegating again the job #{job.inspect}") if self.class.debug_enabled?
delegate(job)
else
worker.job_id = job['id'] if worker.job_id.blank?
@job_to_worker[job['id']] = worker
@worker_to_job[worker.mailbox.address] = job
debug("worker #{worker.job_id} registed into manager") if self.class.debug_enabled?
Actor.current.link worker
worker.async.start_task unless syncronized_confirmation?
if @job_manager.jobs.size == @job_to_worker.size
@registration_complete = true
end
start_worker(job, worker)
end
end

def start_worker(job, worker)
worker.job_id = job['id'] if worker.job_id.blank?
@job_to_worker[job['id']] = worker
@worker_to_job[worker.mailbox.address] = job
debug("worker #{worker.job_id} registed into manager") if self.class.debug_enabled?
Actor.current.link worker
worker.async.start_task unless syncronized_confirmation?
return unless @job_manager.jobs.size != @job_to_worker.size
@registration_complete = true
end

def process_jobs
if syncronized_confirmation?
@job_to_worker.pmap do |_job_id, worker|
Expand All @@ -105,18 +108,18 @@ def process_jobs
debug("all jobs have completed #{condition}") if self.class.debug_enabled?
@job_manager.condition.signal('completed') if condition
end

def apply_confirmations?
CapistranoMulticonfigParallel.configuration.task_confirmation_active.to_s.downcase == 'true'
CapistranoMulticonfigParallel.configuration.task_confirmation_active.to_s.downcase == 'true'
end

def syncronized_confirmation?
(CapistranoMulticonfigParallel.configuration.syncronize_confirmation.to_s.downcase == 'true' && !@job_manager.executes_deploy_stages? ) ||
(@job_manager.executes_deploy_stages? && @job_manager.confirmation_applies_to_all_workers?)
(CapistranoMulticonfigParallel.configuration.syncronize_confirmation.to_s.downcase == 'true' && !@job_manager.executes_deploy_stages?) ||
(@job_manager.executes_deploy_stages? && @job_manager.confirmation_applies_to_all_workers?)
end

def apply_confirmation_for_worker(worker)
worker.alive? && CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.include?(worker.env_name)
worker.alive? && CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.include?(worker.env_name)
end

def setup_worker_conditions(worker)
Expand All @@ -129,7 +132,7 @@ def setup_worker_conditions(worker)
end

def mark_completed_remaining_tasks(worker)
return if !apply_confirmation_for_worker(worker) || !apply_confirmations?
return if !apply_confirmation_for_worker(worker) || !apply_confirmations?
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, _index|
fake_result = proc { |sum| sum }
task_confirmation = @job_to_condition[worker.job_id][task]
Expand All @@ -141,20 +144,20 @@ def mark_completed_remaining_tasks(worker)
end

def wait_task_confirmations_worker(worker)
return if !apply_confirmations? || !apply_confirmation_for_worker(worker) || syncronized_confirmation?
return if !apply_confirmations? || !apply_confirmation_for_worker(worker) || syncronized_confirmation?
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, _index|
result = wait_condition_for_task(worker.job_id, task)
confirm_task_approval(result, task, worker) if result.present?
end
end
end

def wait_condition_for_task(job_id, task)
@job_to_condition[job_id][task][:condition].wait
end

def wait_task_confirmations
stage_apply = CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.include?(@job_manager.stage)
return if !apply_confirmations? || !stage_apply || !syncronized_confirmation?
stage_apply = CapistranoMulticonfigParallel.configuration.apply_stage_confirmation.include?(@job_manager.stage)
return if !apply_confirmations? || !stage_apply || !syncronized_confirmation?
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, _index|
results = []
@jobs.pmap do |job_id, _job|
Expand All @@ -167,25 +170,28 @@ def wait_task_confirmations
end
end

def print_confirm_task_approvall(result, task, worker = nil)
return if result.is_a?(Proc)
message = "Do you want to continue the deployment and execute #{task.upcase}"
message += " for JOB #{worker.job_id}" if worker.present?
message += '?'
set :apps_symlink_confirmation, CapistranoMulticonfigParallel.ask_confirm(message, 'Y/N')
until fetch(:apps_symlink_confirmation).present?
sleep(0.1) # keep current thread alive
end
end

def confirm_task_approval(result, task, worker = nil)
return unless result.present?
unless result.is_a?(Proc)
message = "Do you want to continue the deployment and execute #{task.upcase}"
message += " for JOB #{worker.job_id}" if worker.present?
message += '?'
set :apps_symlink_confirmation, CapistranoMulticonfigParallel.ask_confirm(message, 'Y/N')
until fetch(:apps_symlink_confirmation).present?
sleep(0.1) # keep current thread alive
end
end
print_confirm_task_approvall(result, task, worker = nil)
return if fetch(:apps_symlink_confirmation).blank? || fetch(:apps_symlink_confirmation).downcase != 'y'
@jobs.pmap do |job_id, job|
worker = get_worker_for_job(job_id)
worker.publish_rake_event('approved' => 'yes',
'action' => 'invoke',
'job_id' => job['id'],
'task' => task
)
)
end
end

Expand All @@ -203,17 +209,17 @@ def get_worker_for_job(job)
end

def can_tag_staging?
@job_manager.can_tag_staging? &&
@jobs.detect{|job_id, job| job['env'] == 'production'}.blank?
@job_manager.can_tag_staging? &&
@jobs.find { |_job_id, job| job['env'] == 'production' }.blank?
end

def dispatch_new_job(job)
original_env = job['env_options']
env_opts = @job_manager.get_app_additional_env_options(job['app_name'], job['stage'])
job['env_options'] = original_env.merge(env_opts)
job['env_options'] = original_env.merge(env_opts)
async.delegate(job)
end

def process_job(job)
env_options = {}
job['env_options'].each do |key, value|
Expand All @@ -222,13 +228,13 @@ def process_job(job)
{
'job_id' => job['id'],
'app_name' => job['app'],
'env_name' => job['env'],
'action_name' => job['action'],
'env_name' => job['env'],
'action_name' => job['action'],
'env_options' => env_options,
'task_arguments' => job['task_arguments'],
'task_arguments' => job['task_arguments']
}
end

# lookup status of job by asking actor running it
def get_job_status(job)
status = nil
Expand All @@ -244,7 +250,7 @@ def get_job_status(job)
end
status
end

def job_failed?(job)
job['worker_action'].present? && job['worker_action'] == 'worker_died'
end
Expand Down
34 changes: 18 additions & 16 deletions lib/capistrano_multiconfig_parallel/celluloid/celluloid_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class CelluloidWorker
class TaskFailed < StandardError; end

attr_accessor :job, :manager, :job_id, :app_name, :env_name, :action_name, :env_options, :machine, :client, :task_argv, :execute_deploy, :executed_dry_run,
:rake_tasks, :current_task_number, # tracking tasks
:successfull_subscription, :subscription_channel, :publisher_channel, # for subscriptions and publishing events
:job_termination_condition, :worker_state
:rake_tasks, :current_task_number, # tracking tasks
:successfull_subscription, :subscription_channel, :publisher_channel, # for subscriptions and publishing events
:job_termination_condition, :worker_state

def work(job, manager)
@job = job
Expand All @@ -38,7 +38,7 @@ def work(job, manager)
@machine = CapistranoMulticonfigParallel::StateMachine.new(job, Actor.current)
manager.register_worker_for_job(job, Actor.current)
end

def debug_enabled?
@manager.class.debug_enabled?
end
Expand Down Expand Up @@ -88,18 +88,17 @@ def execute_after_succesfull_subscription
def rake_tasks
@rake_tasks ||= []
end



def cd_working_directory
"cd #{CapistranoMulticonfigParallel.detect_root.to_s}"
"cd #{CapistranoMulticonfigParallel.detect_root}"
end

def generate_command
<<-CMD
#{cd_working_directory} && RAILS_ENV=#{@env_name} bundle exec multi_cap #{@task_argv.join(' ')}
CMD
end

def execute_deploy
@execute_deploy = true
debug("invocation chain #{@job_id} is : #{@rake_tasks.inspect}") if debug_enabled? && CapistranoMulticonfigParallel.show_task_progress
Expand All @@ -124,11 +123,14 @@ def on_close(code, reason)
debug("worker #{@job_id} websocket connection closed: #{code.inspect}, #{reason.inspect}") if debug_enabled?
end

def check_gitflow
return if !@env_name == 'staging' || !@manager.can_tag_staging? || !executed_task?(CapistranoMulticonfigParallel::GITFLOW_VERIFY_UPTODATE_TASK)
@manager.dispatch_new_job(@job.merge('env' => 'production'))
end

def handle_subscription(message)
if message_is_about_a_task?(message)
if @env_name == 'staging' && @manager.can_tag_staging? && has_executed_task?(CapistranoMulticonfigParallel::GITFLOW_VERIFY_UPTODATE_TASK)
@manager.dispatch_new_job(@job.merge('env' => 'production'))
end
check_gitflow
save_tasks_to_be_executed(message)
update_machine_state(message['task']) # if message['action'] == 'invoke'
debug("worker #{@job_id} state is #{@machine.state}") if debug_enabled?
Expand All @@ -141,8 +143,8 @@ def handle_subscription(message)
def message_is_about_a_task?(message)
message.present? && message.is_a?(Hash) && message['action'].present? && message['job_id'].present? && message['task'].present?
end
def has_executed_task?(task)

def executed_task?(task)
@rake_tasks.present? && @rake_tasks[task].present?
end

Expand Down Expand Up @@ -203,9 +205,9 @@ def process_job(job)
@env_options = processed_job['env_options']
@task_arguments = processed_job['task_arguments']
end

def crashed?
@action_name == 'deploy:rollback' || @action_name == 'deploy:failed' || @manager.job_failed?(@job)
@action_name == 'deploy:rollback' || @action_name == 'deploy:failed' || @manager.job_failed?(@job)
end

def finish_worker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def work(cmd, options = {})
def set_worker_log
FileUtils.mkdir_p(CapistranoMulticonfigParallel.log_directory) unless File.directory?(CapistranoMulticonfigParallel.log_directory)
@filename = File.join(CapistranoMulticonfigParallel.log_directory, "worker_#{@actor.job_id}.log")
FileUtils.rm_rf(@filename) if File.file?(@filename) && !@actor.crashed? && (@options[:dry_run] || @actor.executed_dry_run != true)
FileUtils.rm_rf(@filename) if File.file?(@filename) && !@actor.crashed? && (@options[:dry_run] || @actor.executed_dry_run != true)
@worker_log = ::Logger.new(@filename)
@worker_log.level = ::Logger::Severity::DEBUG
@worker_log.formatter = proc do |severity, datetime, progname, msg|
Expand Down
Loading

0 comments on commit 4d55a70

Please sign in to comment.