docker-sync 0.0.6 → 0.0.7

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: cc40aa79fbd367b388ee77e59de18a559b859ec0
4
- data.tar.gz: 5277727751ab18be0546e84105b40f9f81d80e89
3
+ metadata.gz: 4c038d1707563cd3431430008536b86b51d54967
4
+ data.tar.gz: cca9a557c34d66c70a80fdf503722f8f5e5533e1
5
5
  SHA512:
6
- metadata.gz: 2d65defb8a672fa3c1a548c8340e486aacb9fb9772096578bdea854f11614e9e790737acc7def7b8a7d198cb652d4b24a48978357c8e2f5242303a789f7b5faf
7
- data.tar.gz: f1779efc2e0a4c3e397a377584f3e6afa2fea49daf53b28e740a5889f5b5bb02c0b8bde2d2c2dc5b5ce7551929cf77c1bc4a9c2cd314d5df3c41b012b820f7b0
6
+ metadata.gz: 902d178c8baf27b21ffef9b943123e642b2acf3f3260af96f0b75453806c5605d010a1a15720786a0186a7d3ab6db6398fb4d5e9c05bca5288e96dbf94252202
7
+ data.tar.gz: d8e7ba089970977e9ce4fd6232eabaed4503bfd180d0deb910965cb9c69540caacf02129d26caddc5c41db0715606f91571446e1fbf10df4c24f78b9ca3d03f7
@@ -42,7 +42,10 @@ module Docker_Rsync
42
42
  @config_syncs[name]['config_path'] = @config_path
43
43
  @config_syncs[name]['src'] = File.expand_path(@config_syncs[name]['src'])
44
44
  unless config.key?('verbose')
45
- @config_syncs[name]['verbose'] = @config_options['verbose'] || false
45
+ @config_syncs[name]['verbose'] = false
46
+ if @config_options.key?('verbose')
47
+ @config_syncs[name]['verbose'] = @config_options['verbose']
48
+ end
46
49
  end
47
50
  end
48
51
  end
@@ -1,9 +1,12 @@
1
1
  require 'thor/shell'
2
+ require 'preconditions'
2
3
 
3
4
  module Docker_Sync
4
5
  module SyncStrategy
5
6
  class Rsync
6
7
  include Thor::Shell
8
+ include Preconditions
9
+
7
10
  @options
8
11
  @sync_name
9
12
  @watch_thread
@@ -11,6 +14,14 @@ module Docker_Sync
11
14
  def initialize(sync_name, options)
12
15
  @sync_name = sync_name
13
16
  @options = options
17
+
18
+ begin
19
+ rsync_available
20
+ rescue Exception => e
21
+ say_status 'error', "#{@sync_name} has been configured to sync with rsync, but no rsync binary available", :red
22
+ say_status 'error', e.message, :red
23
+ exit 1
24
+ end
14
25
  end
15
26
 
16
27
  def run
@@ -29,7 +40,7 @@ module Docker_Sync
29
40
  say_status 'error', "Error starting sync, exit code #{$?.exitstatus}", :red
30
41
  say_status 'message', out
31
42
  else
32
- say_status 'success', "Synced #{@options['src']}", :green
43
+ say_status 'ok', "Synced #{@options['src']}", :white
33
44
  if @options['verbose']
34
45
  say_status 'output', out
35
46
  end
@@ -43,33 +54,61 @@ module Docker_Sync
43
54
  end
44
55
  args.push('-ap')
45
56
  args.push(@options['sync_args']) if @options.key?('sync_args')
57
+ # we do not need to user usermap/groupmap since we started our container the way that it also maps user/group like we defined
58
+ # in the config - see start_container
59
+ #args.push("--usermap='*:#{@options['sync_user']}'") if @options.key?('sync_user')
60
+ #args.push("--groupmap='*:#{@options['sync_group']}'") if @options.key?('sync_group')
46
61
  args.push("#{@options['src']}/") # add a trailing slash
47
62
  args.push("rsync://#{@options['sync_host_ip']}:#{@options['sync_host_port']}/volume")
48
63
  end
49
64
 
50
-
65
+ # starts a rsync docker container listening on the specific port
66
+ # this container exposes a named volume and is on one side used as the rsync-endpoint for the
67
+ # local rsync command, on the other side the volume is mounted into the app-container to share the code / content
51
68
  def start_container
52
69
  say_status 'ok', 'Starting rsync', :white
53
70
  running = `docker ps --filter 'status=running' --filter 'name=#{@sync_name}' | grep #{@sync_name}`
54
- if running == ''
55
- say_status 'ok', "#{@sync_name} container not running", :white
56
- exists = `docker ps --filter "status=exited" --filter "name=filesync_dw" | grep filesync_dw`
57
- if exists == ''
58
- say_status 'ok', "creating #{@sync_name} container", :white
59
- cmd = "docker run -p '#{@options['sync_host_port']}:873' -v #{@sync_name}:#{@options['dest']} -e VOLUME=#{@options['dest']} --name #{@sync_name} -d eugenmayer/rsync"
60
- else
61
- say_status 'success', "starting #{@sync_name} container", :green
71
+ if running == '' # container is yet not running
72
+ say_status 'ok', "#{@sync_name} container not running", :white if @options['verbose']
73
+ exists = `docker ps --filter "status=exited" --filter "name=#{@sync_name}" | grep #{@sync_name}`
74
+ if exists == '' # container has yet not been created
75
+ say_status 'ok', "creating #{@sync_name} container", :white if @options['verbose']
76
+
77
+ user_mapping = ''
78
+ if @options.key?('sync_user')
79
+ user_mapping = "-e OWNER=#{@options['sync_user']}"
80
+ if @options.key?('sync_userid')
81
+ user_mapping = "#{user_mapping} -e OWNERID=#{@options['sync_userid']}"
82
+ end
83
+ elsif @options.key?('sync_userid')
84
+ raise("#{@sync_name}: You have set a sync_userid but no sync_user - you need to set both")
85
+ end
86
+
87
+ group_mapping = ''
88
+ if @options.key?('sync_group')
89
+ group_mapping = "-e GROUP=#{@options['sync_group']}"
90
+ if @options.key?('sync_groupid')
91
+ group_mapping = "#{group_mapping} -e GROUPID=#{@options['sync_groupid']}"
92
+ end
93
+ elsif @options.key?('sync_groupid')
94
+ raise("#{@sync_name}: You have set a sync_groupid but no sync_group - you need to set both")
95
+ end
96
+
97
+ cmd = "docker run -p '#{@options['sync_host_port']}:873' -v #{@sync_name}:#{@options['dest']} #{user_mapping} #{group_mapping} -e VOLUME=#{@options['dest']} --name #{@sync_name} -d eugenmayer/rsync"
98
+ else # container already created, just start / reuse it
99
+ say_status 'ok', "starting #{@sync_name} container", :white if @options['verbose']
62
100
  cmd = "docker start #{@sync_name}"
63
101
  end
64
- say_status 'command', cmd, :white
102
+ say_status 'command', cmd, :white if @options['verbose']
65
103
  `#{cmd}` || raise('Start failed')
66
104
  else
67
- say_status 'ok', "#{@sync_name} container still running", :blue
105
+ say_status 'ok', "#{@sync_name} container still running", :blue if @options['verbose']
68
106
  end
69
- say_status 'success', "starting initial #{@sync_name} of src", :green
107
+ say_status 'ok', "starting initial #{@sync_name} of src", :white if @options['verbose']
70
108
  # this sleep is needed since the container could be not started
71
109
  sleep 1
72
110
  sync
111
+ say_status 'success', 'Rsync server started', :green
73
112
  end
74
113
 
75
114
  def stop_container
@@ -1,9 +1,14 @@
1
1
  require 'thor/shell'
2
+ require 'preconditions'
3
+ require 'open3'
2
4
 
3
5
  module Docker_Sync
4
6
  module SyncStrategy
5
7
  class Unison
6
8
  include Thor::Shell
9
+ include Preconditions
10
+
11
+
7
12
  @options
8
13
  @sync_name
9
14
  @watch_thread
@@ -13,6 +18,14 @@ module Docker_Sync
13
18
  def initialize(sync_name, options)
14
19
  @sync_name = sync_name
15
20
  @options = options
21
+
22
+ begin
23
+ unison_available
24
+ rescue Exception => e
25
+ say_status 'error', "#{@sync_name} has been configured to sync with unison, but no unison available", :red
26
+ say_status 'error', e.message, :red
27
+ exit 1
28
+ end
16
29
  end
17
30
 
18
31
  def run
@@ -26,12 +39,12 @@ module Docker_Sync
26
39
 
27
40
  say_status 'command', cmd, :white if @options['verbose']
28
41
 
29
- out = `#{cmd}`
42
+ Open3.popen3(cmd)
30
43
  if $?.exitstatus > 0
31
44
  say_status 'error', "Error starting sync, exit code #{$?.exitstatus}", :red
32
45
  say_status 'message', out
33
46
  else
34
- say_status 'success', "Synced #{@options['src']}", :green
47
+ say_status 'ok', "Synced #{@options['src']}", :white
35
48
  if @options['verbose']
36
49
  say_status 'output', out
37
50
  end
@@ -42,8 +55,8 @@ module Docker_Sync
42
55
  args = []
43
56
 
44
57
  unless @options['sync_excludes'].nil?
45
- # TODO: does unison support excludes as a command paramter? seems to be a config-value only
46
- say_status 'warning','Excludes are yet not implemented for unison!', :orange
58
+ # TODO: does unison support excludes as a command parameter? seems to be a config-value only
59
+ say_status 'warning','Excludes are yet not implemented for unison!', :yellow
47
60
  # args = @options['sync_excludes'].map { |pattern| "--exclude='#{pattern}'" } + args
48
61
  end
49
62
  args.push(@options['src'])
@@ -51,30 +64,34 @@ module Docker_Sync
51
64
  args.push('-batch')
52
65
  args.push(@options['sync_args']) if @options.key?('sync_args')
53
66
  args.push("socket://#{@options['sync_host_ip']}:#{@options['sync_host_port']}/")
67
+ if @options.key?('sync_user') || @options.key?('sync_group') || @options.key?('sync_groupid') || @options.key?('sync_userid')
68
+ raise('Unison does not support sync_user, sync_group, sync_groupid or sync_userid - please use rsync if you need that')
69
+ end
54
70
  end
55
71
 
56
72
  def start_container
57
- say_status 'ok', 'Starting rsync', :white
73
+ say_status 'ok', 'Starting unison', :white
58
74
  running = `docker ps --filter 'status=running' --filter 'name=#{@sync_name}' | grep #{@sync_name}`
59
75
  if running == ''
60
- say_status 'ok', "#{@sync_name} container not running", :white
61
- exists = `docker ps --filter "status=exited" --filter "name=filesync_dw" | grep filesync_dw`
76
+ say_status 'ok', "#{@sync_name} container not running", :white if @options['verbose']
77
+ exists = `docker ps --filter "status=exited" --filter "name=#{@sync_name}" | grep #{@sync_name}`
62
78
  if exists == ''
63
- say_status 'ok', "creating #{@sync_name} container", :white
79
+ say_status 'ok', "creating #{@sync_name} container", :white if @options['verbose']
64
80
  cmd = "docker run -p '#{@options['sync_host_port']}:#{UNISON_CONTAINER_PORT}' -v #{@sync_name}:#{@options['dest']} -e UNISON_VERSION=#{UNISON_VERSION} -e UNISON_WORKING_DIR=#{@options['dest']} --name #{@sync_name} -d #{UNISON_IMAGE}"
65
81
  else
66
- say_status 'success', "starting #{@sync_name} container", :green
82
+ say_status 'ok', "starting #{@sync_name} container", :ok if @options['verbose']
67
83
  cmd = "docker start #{@sync_name}"
68
84
  end
69
- say_status 'command', cmd, :white
85
+ say_status 'command', cmd, :white if @options['verbose']
70
86
  `#{cmd}` || raise('Start failed')
71
87
  else
72
88
  say_status 'ok', "#{@sync_name} container still running", :blue
73
89
  end
74
- say_status 'success', "starting initial #{@sync_name} of src", :green
90
+ say_status 'ok', "starting initial #{@sync_name} of src", :white if @options['verbose']
75
91
  # this sleep is needed since the container could be not started
76
92
  sleep 1
77
93
  sync
94
+ say_status 'success', 'Unison server started', :green
78
95
  end
79
96
 
80
97
  def stop_container
@@ -1,10 +1,14 @@
1
1
  require 'thor/shell'
2
2
  require 'execution'
3
+ require 'preconditions'
4
+
3
5
  module Docker_Sync
4
6
  module WatchStrategy
5
7
  class Fswatch
6
8
  include Thor::Shell
7
9
  include Execution
10
+ include Preconditions
11
+
8
12
  @options
9
13
  @sync_name
10
14
  @watch_thread
@@ -12,6 +16,13 @@ module Docker_Sync
12
16
  def initialize(sync_name, options)
13
17
  @sync_name = sync_name
14
18
  @options = options
19
+
20
+ begin
21
+ fswatch_available
22
+ rescue Exception => e
23
+ say_status 'error', e.message, :red
24
+ exit 1
25
+ end
15
26
  end
16
27
 
17
28
  def run
@@ -26,10 +37,11 @@ module Docker_Sync
26
37
 
27
38
  def watch
28
39
  args = watch_options
29
- say_status 'ok', "Starting to watch #{@options['src']} - Press CTRL-C to stop", :green
40
+ say_status 'success', "Starting to watch #{@options['src']} - Press CTRL-C to stop", :green
30
41
  cmd = 'fswatch ' + args.join(' ')
31
42
  say_status 'command', cmd, :white if @options['verbose']
32
43
 
44
+ # run a thread here, since it is blocking
33
45
  @watch_thread = threadexec(cmd, "Sync #{@sync_name}", :blue)
34
46
  end
35
47
 
@@ -41,7 +53,17 @@ module Docker_Sync
41
53
  args.push('-orIE')
42
54
  args.push(@options['watch_args']) if @options.key?('watch_args')
43
55
  args.push(@options['src'])
44
- args.push(" | xargs -I -n1 docker-sync sync -n #{@sync_name} --config='#{@options['config_path']}'")
56
+
57
+ sync_command = 'thor sync:sync'
58
+ begin
59
+ docker_sync_available
60
+ sync_command = 'docker-sync sync'
61
+ rescue Exception => e
62
+ say_status 'warning', 'docker-sync not available, assuming dev mode, using thor', :yellow
63
+ puts e.message
64
+ sync_command = 'thor sync:sync'
65
+ end
66
+ args.push(" | xargs -I -n1 #{sync_command} -n #{@sync_name} --config='#{@options['config_path']}'")
45
67
  end
46
68
 
47
69
  def watch_thread
data/lib/execution.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'open3'
2
- require 'colorize'
2
+ require 'thor/shell'
3
3
 
4
4
  module Execution
5
5
 
@@ -7,8 +7,9 @@ module Execution
7
7
 
8
8
  def threadexec(command, prefix = nil, color = nil)
9
9
 
10
- unless prefix.nil?
11
- prefix = "#{prefix} | "
10
+ if prefix.nil?
11
+ # TODO: probably pick the command name without args
12
+ prefix = 'unknown'
12
13
  end
13
14
 
14
15
  if color.nil?
@@ -19,11 +20,11 @@ module Execution
19
20
  Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
20
21
 
21
22
  while lineOut = stdout.gets
22
- puts prefix.nil? ? lineOut : prefix.colorize(color) + lineOut
23
+ say_status prefix, lineOut, color
23
24
  end
24
25
 
25
26
  while lineErr = stderr.gets
26
- puts prefix.nil? ? lineErr : prefix.colorize(color) + lineErr
27
+ say_status prefix, lineErr, :red
27
28
  end
28
29
 
29
30
  end
@@ -0,0 +1,46 @@
1
+ require 'mkmf'
2
+
3
+ module Preconditions
4
+ def check_all_preconditions
5
+ docker_available
6
+ docker_running
7
+ fswatch_available
8
+ end
9
+
10
+ def docker_available
11
+ if (find_executable0 'docker').nil?
12
+ raise('Could not find docker binary in path. Please install it, e.g. using "brew install docker" or install docker-for-mac')
13
+ end
14
+ end
15
+
16
+ def docker_running
17
+ `docker ps`
18
+ if $?.exitstatus > 0
19
+ raise('No docker daemon seems to be running. Did you start your docker-for-mac / docker-machine?')
20
+ end
21
+ end
22
+
23
+ def fswatch_available
24
+ if (find_executable0 'fswatch').nil?
25
+ raise('No fswatch available. Install it by "brew install fswatch"')
26
+ end
27
+ end
28
+
29
+ def docker_sync_available
30
+ if (find_executable0 'docker-sync').nil?
31
+ raise('No docker-sync available. Install it by "gem install docker-sync"')
32
+ end
33
+ end
34
+
35
+ def rsync_available
36
+ if (find_executable0 'rsync').nil?
37
+ raise('Could not find rsync binary in path. Please install it, e.g. using "brew install rsync"')
38
+ end
39
+ end
40
+
41
+ def unison_available
42
+ if (find_executable0 'unison').nil?
43
+ raise('Could not find unison binary in path. Please install it, e.g. using "brew install unison"')
44
+ end
45
+ end
46
+ end
data/tasks/sync.thor CHANGED
@@ -1,13 +1,23 @@
1
1
  require 'docker_sync/sync_manager'
2
2
  require 'config'
3
+ require 'preconditions'
3
4
 
4
5
  class Sync < Thor
5
6
  include DockerSyncConfig
7
+ include Preconditions
8
+
6
9
  class_option :config, :aliases => '-c',:default => nil, :type => :string, :desc => 'Path of the docker_sync config'
7
10
  class_option :sync_name, :aliases => '-n',:type => :string, :desc => 'If given, only this sync configuration will be references/started/synced'
8
11
 
9
12
  desc 'start', 'Start all sync configurations in this project'
10
13
  def start
14
+ begin
15
+ check_all_preconditions
16
+ rescue Exception => e
17
+ say_status 'error', e.message, :red
18
+ exit 1
19
+ end
20
+
11
21
  if options[:config]
12
22
  config_path = options[:config]
13
23
  else
@@ -24,6 +34,13 @@ class Sync < Thor
24
34
 
25
35
  desc 'sync_only', 'sync - do not start a watcher'
26
36
  def sync
37
+ begin
38
+ check_all_preconditions
39
+ rescue Exception => e
40
+ say_status 'error', e.message, :red
41
+ exit 1
42
+ end
43
+
27
44
  if options[:config]
28
45
  config_path = options[:config]
29
46
  else
@@ -40,6 +57,13 @@ class Sync < Thor
40
57
 
41
58
  desc 'clean', 'Stop and clean up all sync endpoints'
42
59
  def clean
60
+ begin
61
+ check_all_preconditions
62
+ rescue Exception => e
63
+ say_status 'error', e.message, :red
64
+ exit 1
65
+ end
66
+
43
67
  if options[:config]
44
68
  config_path = options[:config]
45
69
  else
@@ -58,6 +82,13 @@ class Sync < Thor
58
82
  desc 'list', 'List all sync-points of the project configuration path'
59
83
  method_option :verbose, :default => false, :type => :boolean, :desc => 'Verbose output'
60
84
  def list
85
+ begin
86
+ check_all_preconditions
87
+ rescue Exception => e
88
+ say_status 'error', e.message, :red
89
+ exit 1
90
+ end
91
+
61
92
  if options[:config]
62
93
  config_path = options[:config]
63
94
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eugen Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-08 00:00:00.000000000 Z
11
+ date: 2016-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: colorize
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  description: Sync your code live to docker-containers without losing any performance
42
28
  on OSX
43
29
  email: eugen.mayer@kontextwork.de
@@ -55,6 +41,7 @@ files:
55
41
  - lib/docker_sync/sync_strategy/unison.rb
56
42
  - lib/docker_sync/watch_strategy/fswatch.rb
57
43
  - lib/execution.rb
44
+ - lib/preconditions.rb
58
45
  - tasks/sync.thor
59
46
  homepage: https://github.com/EugenMayer/docker_sync
60
47
  licenses: