docker-sync 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|