Skip to content

Commit

Permalink
Merge pull request #229 from masterful/use-sync-point-for-app-name
Browse files Browse the repository at this point in the history
Add daemonize option to 'docker-sync start', closes #51, replaces #65
  • Loading branch information
EugenMayer authored Feb 14, 2017
2 parents e5d26d2 + b71c4eb commit 0e17efa
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 69 deletions.
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ PATH
remote: .
specs:
docker-sync (0.1.5)
daemons (~> 1.2, >= 1.2.3)
docker-compose (~> 1.0, >= 1.0.2)
dotenv (~> 2.1, >= 2.1.1)
gem_update_checker (~> 0.2.0, >= 0.2.0)
Expand All @@ -12,6 +13,7 @@ GEM
remote: https://rubygems.org/
specs:
backticks (1.0.0)
daemons (1.2.4)
docker-compose (1.0.3)
backticks (~> 1.0)
dotenv (2.1.1)
Expand Down
1 change: 1 addition & 0 deletions docker-sync.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'docker-compose', '~> 1.0', '>= 1.0.2'
s.add_runtime_dependency 'terminal-notifier', '1.6.3'
s.add_runtime_dependency 'dotenv', '~> 2.1', '>= 2.1.1'
s.add_runtime_dependency 'daemons', '~> 1.2', '>= 1.2.3'
end
8 changes: 8 additions & 0 deletions lib/docker-sync/sync_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def validate_sync_config(name, sync_config)
end

def init_sync_processes(sync_name = nil)
return if @sync_processes.size != 0
if sync_name.nil?
@config_syncs.each { |name, sync_configuration|
@sync_processes.push(create_sync(name, sync_configuration))
Expand Down Expand Up @@ -124,6 +125,13 @@ def sync(sync_name = nil)
}
end

def start_container(sync_name = nil)
init_sync_processes(sync_name)
@sync_processes.each { |sync_process|
sync_process.start_container
}
end

def run(sync_name = nil)
init_sync_processes(sync_name)

Expand Down
4 changes: 4 additions & 0 deletions lib/docker-sync/sync_process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ def sync
@sync_strategy.sync
end

def start_container
@sync_strategy.start_container
end

def watch
@watch_strategy.run
end
Expand Down
156 changes: 87 additions & 69 deletions tasks/sync/sync.thor
Original file line number Diff line number Diff line change
Expand Up @@ -3,83 +3,67 @@ require 'docker-sync/config'
require 'docker-sync/preconditions'
require 'docker-sync/update_check'
require 'docker-sync/upgrade_check'
require 'daemons'
require 'fileutils'

class Sync < Thor

class_option :config, :aliases => '-c',:default => nil, :type => :string, :desc => 'Path of the docker_sync config'
class_option :sync_name, :aliases => '-n',:type => :string, :desc => 'If given, only this sync configuration will be references/started/synced'

desc 'start', 'Start all sync configurations in this project'
method_option :daemon, :aliases => '-d', :default => false, :type => :boolean, :desc => 'Run in the background'
method_option :app_name, :aliases => '--name', :default => 'daemon', :type => :string, :desc => 'App name used in PID and OUTPUT file name for Daemon'
method_option :dir, :aliases => '--dir', :default => './.docker-sync', :type => :string, :desc => 'Path to PID and OUTPUT file Directory'
method_option :logd, :aliases => '--logd', :default => true, :type => :boolean, :desc => 'To log OUPUT to file on Daemon or not'
def start
# do run update check in the start command only
updates = UpdateChecker.new
updates.run
upgrades = UpgradeChecker.new
upgrades.run
begin
Preconditions::check_all_preconditions
rescue Exception => e
say_status 'error', e.message, :red
exit 1
UpdateChecker.new().run
UpgradeChecker.new().run

config_path = config_preconditions # Preconditions and Define config_path from shared method
@sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)

start_dir = Dir.pwd # Set start_dir variable to be equal to pre-daemonized folder, since daemonizing will change dir to '/'
daemonize if options['daemon']

Dir.chdir(start_dir) do # We want run these in pre-daemonized folder/directory since provided config_path might not be full_path
@sync_manager.run(options[:sync_name])
@sync_manager.join_threads
end
end

if options[:config]
config_path = options[:config]
else
begin
config_path = DockerSyncConfig::project_config_path
rescue Exception => e
say_status 'error', e.message, :red
return
end
desc 'stop', 'Stop docker-sync daemon'
method_option :app_name, :aliases => '--name', :default => 'daemon', :type => :string, :desc => 'App name used in PID and OUTPUT file name for Daemon'
method_option :dir, :aliases => '--dir', :default => './.docker-sync', :type => :string, :desc => 'Path to PID and OUTPUT file Directory'
def stop
config_path = config_preconditions
sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)

begin
pid = File.read("#{options['dir']}/#{options['app_name']}.pid") # Read PID from PIDFILE created by Daemons
Process.kill(:INT, -(Process.getpgid(pid.to_i))) # Send INT signal to group PID, which means INT will be sent to all sub-processes and Threads spawned by docker-sync
say_status 'shutdown', 'Background dsync has been stopped'
rescue Errno::ESRCH, Errno::ENOENT => e
say_status 'error', e.message, :red # Rescue incase PIDFILE does not exist or there is no process with such PID
say_status(
'error', 'Check if your PIDFILE and process with such PID exists', :red
)
end
@sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)
@sync_manager.run(options[:sync_name])
@sync_manager.join_threads
end

desc 'sync', 'sync - do not start a watcher'
def sync
begin
Preconditions::check_all_preconditions
rescue Exception => e
say_status 'error', e.message, :red
exit 1
end
config_path = config_preconditions # Preconditions and Define config_path from shared method

if options[:config]
config_path = options[:config]
else
begin
config_path = DockerSyncConfig::project_config_path
rescue Exception => e
say_status 'error', e.message, :red
return
end
end
@sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)
@sync_manager.sync(options[:sync_name])
end

desc 'clean', 'Stop and clean up all sync endpoints'
def clean
begin
Preconditions::check_all_preconditions
rescue Exception => e
say_status 'error', e.message, :red
exit 1
end
config_path = config_preconditions # Preconditions and Define config_path from shared method

if options[:config]
config_path = options[:config]
else
begin
config_path = DockerSyncConfig::project_config_path
rescue Exception => e
say_status 'error', e.message, :red
return
end
end
@sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)
@sync_manager.clean(options[:sync_name])
say_status 'success', 'Finished cleanup. Removed stopped, removed sync container and removed their volumes', :green
Expand All @@ -88,30 +72,64 @@ class Sync < Thor
desc 'list', 'List all sync-points of the project configuration path'
method_option :verbose, :default => false, :type => :boolean, :desc => 'Verbose output'
def list
begin
Preconditions::check_all_preconditions
rescue Exception => e
say_status 'error', e.message, :red
exit 1
config_path = config_preconditions # Preconditions and Define config_path from shared method

say_status 'ok',"Found configuration at #{config_path}"
@sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)
@sync_manager.get_sync_points.each do |name, config|
say_status name, "On address #{config['sync_host_ip']}:#{config['sync_host_port']}",:white unless options['verbose']
puts "\n---------------[#{name}] #{config['sync_host_ip']}:#{config['sync_host_port']} ---------------\n" if options['verbose']
print_table(config) if options['verbose']
end
end

if options[:config]
config_path = options[:config]
else
no_tasks do
def config_preconditions # Moved shared preconditions block into separate method to have less/cleaner code
begin
config_path = DockerSyncConfig::project_config_path
Preconditions::check_all_preconditions
rescue Exception => e
say_status 'error', e.message, :red
return
exit 1
end

return options[:config] if options[:config]

begin
DockerSyncConfig::project_config_path
rescue Exception => e
say_status 'error', e.message, :red
exit 1
end
end

say_status 'ok',"Found configuration at #{config_path}"
@sync_manager = Docker_sync::SyncManager.new(:config_path => config_path)
@sync_manager.get_sync_points.each do |name, config|
say_status name, "On address #{config['sync_host_ip']}:#{config['sync_host_port']}",:white unless options['verbose']
puts "\n---------------[#{name}] #{config['sync_host_ip']}:#{config['sync_host_port']} ---------------\n" if options['verbose']
print_table(config) if options['verbose']
def daemonize
# Create the directory for the logs/pid if it doesn't already exist:
FileUtils.mkpath(options['dir'])

# Check to see if we're already running:
pid_file = Daemons::PidFile.find_files(options['dir'], options['app_name']).first || ''
if File.file?(pid_file)
if Daemons::Pid.running?(File.read(pid_file).to_i)
say_status 'error', "docker-sync already started for this configuration", :red
exit 1
end
end

# If we're daemonizing, run a sync first to ensure the containers exist so that a docker-compose up won't fail:
@sync_manager.start_container(options[:sync_name])
# the existing strategies' start_container will also sync, but just in case a strategy doesn't, sync now:
@sync_manager.sync(options[:sync_name])

dopts = {
app_name: options['app_name'],
dir_mode: :normal,
dir: options['dir'],
log_output: options['logd']
} # List of options accepted by Daemonize, can be customized pretty nicely with provided CLI options

say_status 'success', 'Starting Docker-Sync in the background', :green
Daemons.daemonize(dopts)
end
end

end

0 comments on commit 0e17efa

Please sign in to comment.