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 +4 -4
- data/lib/docker_sync/sync_manager.rb +4 -1
- data/lib/docker_sync/sync_strategy/rsync.rb +52 -13
- data/lib/docker_sync/sync_strategy/unison.rb +28 -11
- data/lib/docker_sync/watch_strategy/fswatch.rb +24 -2
- data/lib/execution.rb +6 -5
- data/lib/preconditions.rb +46 -0
- data/tasks/sync.thor +31 -0
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c038d1707563cd3431430008536b86b51d54967
|
4
|
+
data.tar.gz: cca9a557c34d66c70a80fdf503722f8f5e5533e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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'] =
|
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 '
|
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
|
57
|
-
if exists == ''
|
58
|
-
say_status 'ok', "creating #{@sync_name} container", :white
|
59
|
-
|
60
|
-
|
61
|
-
|
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 '
|
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
|
-
|
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 '
|
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
|
46
|
-
say_status 'warning','Excludes are yet not implemented for unison!', :
|
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
|
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
|
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 '
|
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 '
|
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 '
|
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
|
-
|
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 '
|
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
|
-
|
11
|
-
|
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
|
-
|
23
|
+
say_status prefix, lineOut, color
|
23
24
|
end
|
24
25
|
|
25
26
|
while lineErr = stderr.gets
|
26
|
-
|
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.
|
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-
|
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:
|