docker-sync 0.7.0 → 1.0.0
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/VERSION +1 -1
- data/lib/docker-sync/command.rb +126 -0
- data/lib/docker-sync/compose.rb +1 -2
- data/lib/docker-sync/dependencies/docker_driver.rb +5 -1
- data/lib/docker-sync/dependencies/unox.rb +2 -2
- data/lib/docker-sync/docker_compose_session.rb +44 -0
- data/lib/docker-sync/sync_strategy/native_osx.rb +1 -5
- data/lib/docker-sync/sync_strategy/rsync.rb +7 -3
- data/lib/docker-sync/sync_strategy/unison.rb +12 -9
- data/lib/docker-sync/update_check.rb +0 -2
- data/lib/docker-sync/upgrade_check.rb +0 -1
- data/tasks/stack/stack.thor +0 -1
- metadata +33 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1938ef0a123f6f1a0af089e55086717e8e94f2f013c40c3d29f61743d0cda08e
|
4
|
+
data.tar.gz: bd46e6944225bd9f52cc66ce4a45f1ff11a954e4c9b5bb441f249b20f0c0dfa1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aba2408b6a8370e0fc534b0fffa27e9d048705c227247c6552b637747cf0913362dcd76f4dad9ce906df5a395e125b134a29d88c53f471fec8bc5aed43abe1ce
|
7
|
+
data.tar.gz: aa5eb3883ece787df7c6398e0ad7cd967dee35be9b9e0f60cfc0812855e95904dc49b58f25e47ee1973da60fc8e72c08c0ea75c232bef3bea621f080ac558ace
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
@@ -0,0 +1,126 @@
|
|
1
|
+
begin
|
2
|
+
require 'pty'
|
3
|
+
rescue LoadError
|
4
|
+
# for Windows support, tolerate a missing PTY module
|
5
|
+
end
|
6
|
+
|
7
|
+
module DockerSync
|
8
|
+
# based on `Backticks::Command` from `Backticks` gem
|
9
|
+
class Command
|
10
|
+
FOREVER = 86_400 * 365
|
11
|
+
CHUNK = 1_024
|
12
|
+
|
13
|
+
# @return [Integer] child process ID
|
14
|
+
attr_reader :pid
|
15
|
+
|
16
|
+
# @return [nil,Process::Status] result of command if it has ended; nil if still running
|
17
|
+
attr_reader :status
|
18
|
+
|
19
|
+
# @return [String] all input that has been captured so far
|
20
|
+
attr_reader :captured_input
|
21
|
+
|
22
|
+
# @return [String] all output that has been captured so far
|
23
|
+
attr_reader :captured_output
|
24
|
+
|
25
|
+
# @return [String] all output to stderr that has been captured so far
|
26
|
+
attr_reader :captured_error
|
27
|
+
|
28
|
+
# Run a command. The parameters are same as `Kernel#spawn`.
|
29
|
+
#
|
30
|
+
# Usage:
|
31
|
+
# run('docker-compose', '--file=joe.yml', 'up', '-d', 'mysvc')
|
32
|
+
def self.run(*argv, dir: nil)
|
33
|
+
nopty = !defined?(PTY)
|
34
|
+
|
35
|
+
stdin_r, stdin = nopty ? IO.pipe : PTY.open
|
36
|
+
stdout, stdout_w = nopty ? IO.pipe : PTY.open
|
37
|
+
stderr, stderr_w = IO.pipe
|
38
|
+
|
39
|
+
chdir = dir || Dir.pwd
|
40
|
+
pid = spawn(*argv, in: stdin_r, out: stdout_w, err: stderr_w, chdir: chdir)
|
41
|
+
|
42
|
+
stdin_r.close
|
43
|
+
stdout_w.close
|
44
|
+
stderr_w.close
|
45
|
+
|
46
|
+
self.new(pid, stdin, stdout, stderr)
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(pid, stdin, stdout, stderr)
|
50
|
+
@pid = pid
|
51
|
+
@stdin = stdin
|
52
|
+
@stdout = stdout
|
53
|
+
@stderr = stderr
|
54
|
+
@status = nil
|
55
|
+
|
56
|
+
@captured_input = String.new(encoding: Encoding::BINARY)
|
57
|
+
@captured_output = String.new(encoding: Encoding::BINARY)
|
58
|
+
@captured_error = String.new(encoding: Encoding::BINARY)
|
59
|
+
end
|
60
|
+
|
61
|
+
def success?
|
62
|
+
status.success?
|
63
|
+
end
|
64
|
+
|
65
|
+
def join(limit = FOREVER)
|
66
|
+
return self if @status
|
67
|
+
|
68
|
+
tf = Time.now + limit
|
69
|
+
until (t = Time.now) >= tf
|
70
|
+
capture(tf - t)
|
71
|
+
res = Process.waitpid(@pid, Process::WNOHANG)
|
72
|
+
if res
|
73
|
+
@status = $?
|
74
|
+
return self
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def capture(limit)
|
84
|
+
streams = [@stdout, @stderr]
|
85
|
+
streams << STDIN if STDIN.tty?
|
86
|
+
|
87
|
+
ready, = IO.select(streams, [], [], limit)
|
88
|
+
|
89
|
+
# proxy STDIN to child's stdin
|
90
|
+
if ready && ready.include?(STDIN)
|
91
|
+
data = STDIN.readpartial(CHUNK) rescue nil
|
92
|
+
if data
|
93
|
+
@captured_input << data
|
94
|
+
@stdin.write(data)
|
95
|
+
else
|
96
|
+
# our own STDIN got closed; proxy this fact to the child
|
97
|
+
@stdin.close unless @stdin.closed?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# capture child's stdout and maybe proxy to STDOUT
|
102
|
+
if ready && ready.include?(@stdout)
|
103
|
+
data = @stdout.readpartial(CHUNK) rescue nil
|
104
|
+
if data
|
105
|
+
@captured_output << data
|
106
|
+
STDOUT.write(data)
|
107
|
+
fresh_output = data
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# capture child's stderr and maybe proxy to STDERR
|
112
|
+
if ready && ready.include?(@stderr)
|
113
|
+
data = @stderr.readpartial(CHUNK) rescue nil
|
114
|
+
if data
|
115
|
+
@captured_error << data
|
116
|
+
STDERR.write(data)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
fresh_output
|
120
|
+
rescue Interrupt
|
121
|
+
# Proxy Ctrl+C to the child
|
122
|
+
Process.kill('INT', @pid) rescue nil
|
123
|
+
raise
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/docker-sync/compose.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'docker/compose'
|
2
1
|
require 'pp'
|
3
2
|
class ComposeManager
|
4
3
|
include Thor::Shell
|
@@ -30,7 +29,7 @@ class ComposeManager
|
|
30
29
|
compose_files.push compose_dev_path
|
31
30
|
end
|
32
31
|
end
|
33
|
-
@compose_session =
|
32
|
+
@compose_session = DockerSync::DockerComposeSession.new(dir: './', files: compose_files)
|
34
33
|
end
|
35
34
|
|
36
35
|
def run
|
@@ -5,7 +5,11 @@ module DockerSync
|
|
5
5
|
def self.docker_for_mac?
|
6
6
|
return false unless Environment.mac?
|
7
7
|
return @docker_for_mac if defined? @docker_for_mac
|
8
|
-
|
8
|
+
|
9
|
+
# com.docker.hyperkit for old virtualization engine
|
10
|
+
# com.docker.virtualization for new virtualization engine
|
11
|
+
# see https://docs.docker.com/desktop/mac/#enable-the-new-apple-virtualization-framework
|
12
|
+
@docker_for_mac = Environment.system('pgrep -q com.docker.hyperkit') || Environment.system('pgrep -q com.docker.virtualization')
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.docker_toolbox?
|
@@ -14,7 +14,7 @@ module DockerSync
|
|
14
14
|
|
15
15
|
def self.available?
|
16
16
|
# should never have been called anyway - fix the call that it should check for the OS
|
17
|
-
raise 'Unox cannot be available for other
|
17
|
+
raise 'Unox cannot be available for platforms other than MacOS' unless Environment.mac?
|
18
18
|
|
19
19
|
return true if brew_package_installed?('unox')
|
20
20
|
return false unless brew_package_installed?('unison-fsmonitor')
|
@@ -26,7 +26,7 @@ module DockerSync
|
|
26
26
|
|
27
27
|
def self.ensure!
|
28
28
|
return if available?
|
29
|
-
raise 'Unox cannot be installed on other
|
29
|
+
raise 'Unox cannot be installed on platforms other than MacOS' unless Environment.mac?
|
30
30
|
|
31
31
|
cleanup_non_brew_version!
|
32
32
|
PackageManager.install_package('eugenmayer/dockersync/unox')
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module DockerSync
|
2
|
+
# based on `Docker::Compose::Compose` from `docker-compose` gem
|
3
|
+
class DockerComposeSession
|
4
|
+
def initialize(dir: nil, files: nil)
|
5
|
+
@dir = dir
|
6
|
+
@files = files || [] # Array[String]
|
7
|
+
@last_command = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def up(build: false)
|
11
|
+
args = []
|
12
|
+
args << '--build' if build
|
13
|
+
|
14
|
+
run!('up', *args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop
|
18
|
+
run!('stop')
|
19
|
+
end
|
20
|
+
|
21
|
+
def down
|
22
|
+
run!('down')
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def run!(*args)
|
28
|
+
# file_args and args should be Array of String
|
29
|
+
file_args = @files.map { |file| "--file=#{file}" }
|
30
|
+
|
31
|
+
@last_command = Command.run('docker-compose', *file_args, *args, dir: @dir).join
|
32
|
+
status = @last_command.status
|
33
|
+
out = @last_command.captured_output
|
34
|
+
err = @last_command.captured_error
|
35
|
+
unless status.success?
|
36
|
+
desc = (out + err).strip.lines.first || '(no output)'
|
37
|
+
message = format("'%s' failed with status %s: %s", args.first, status.to_s, desc)
|
38
|
+
raise message
|
39
|
+
end
|
40
|
+
|
41
|
+
out
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -20,11 +20,7 @@ module DockerSync
|
|
20
20
|
@options = options
|
21
21
|
@sync_name = sync_name
|
22
22
|
# if a custom image is set, apply it
|
23
|
-
|
24
|
-
@docker_image = @options['image']
|
25
|
-
else
|
26
|
-
@docker_image = 'eugenmayer/unison:2.51.3-4.12.0-AMD64'
|
27
|
-
end
|
23
|
+
@docker_image = @options.key?('image') ? @options['image'] : 'ghcr.io/eugenmayer/unison:2.52.1-4.12.0'
|
28
24
|
|
29
25
|
begin
|
30
26
|
Dependencies::Docker.ensure!
|
@@ -42,12 +42,16 @@ module DockerSync
|
|
42
42
|
|
43
43
|
out = `#{cmd}`
|
44
44
|
if $?.exitstatus > 0
|
45
|
-
|
45
|
+
error_msg = "Error starting sync, exit code #{$?.exitstatus}"
|
46
|
+
say_status 'error', error_msg, :red
|
46
47
|
say_status 'message', out
|
47
|
-
else
|
48
48
|
TerminalNotifier.notify(
|
49
|
-
"
|
49
|
+
"#{error_msg}", :title => @sync_name, :subtitle => @options['src'], group: 'docker-sync'
|
50
50
|
) if @options['notify_terminal']
|
51
|
+
else
|
52
|
+
TerminalNotifier.notify(
|
53
|
+
"Synced #{@options['src']}", :title => @sync_name, group: 'docker-sync'
|
54
|
+
) if @options['notify_terminal'] && @options['notify_terminal'] != 'errors_only'
|
51
55
|
say_status 'ok', "Synced #{@options['src']}", :white
|
52
56
|
if @options['verbose']
|
53
57
|
say_status 'output', out
|
@@ -19,11 +19,7 @@ module DockerSync
|
|
19
19
|
@options = options
|
20
20
|
@sync_name = sync_name
|
21
21
|
# if a custom image is set, apply it
|
22
|
-
@docker_image =
|
23
|
-
@options['image']
|
24
|
-
else
|
25
|
-
'eugenmayer/unison:2.51.3-4.12.0-AMD64'
|
26
|
-
end
|
22
|
+
@docker_image = @options.key?('image') ? @options['image'] : 'ghcr.io/eugenmayer/unison:2.52.1-4.12.0'
|
27
23
|
begin
|
28
24
|
Dependencies::Unison.ensure!
|
29
25
|
Dependencies::Unox.ensure! if Environment.mac?
|
@@ -78,13 +74,20 @@ module DockerSync
|
|
78
74
|
|
79
75
|
stdout, stderr, exit_status = Open3.capture3(cmd)
|
80
76
|
if !exit_status.success?
|
81
|
-
|
77
|
+
error_msg = "Error starting sync, exit code #{$?.exitstatus}"
|
78
|
+
say_status 'error', error_msg, :red
|
82
79
|
say_status 'message', stdout
|
83
80
|
say_status 'message', stderr
|
84
|
-
|
81
|
+
|
85
82
|
if @options['notify_terminal']
|
86
83
|
TerminalNotifier.notify(
|
87
|
-
"
|
84
|
+
"#{error_msg}", :title => @sync_name, :subtitle => @options['src'], group: 'docker-sync'
|
85
|
+
)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
if @options['notify_terminal'] && @options['notify_terminal'] != 'errors_only'
|
89
|
+
TerminalNotifier.notify(
|
90
|
+
"Synced #{@options['src']}", title: @sync_name, group: 'docker-sync'
|
88
91
|
)
|
89
92
|
end
|
90
93
|
say_status 'ok', "Synced #{@options['src']}", :white
|
@@ -205,7 +208,7 @@ module DockerSync
|
|
205
208
|
say_status 'ok', "starting initial sync of #{container_name}", :white if @options['verbose']
|
206
209
|
# wait until container is started, then sync:
|
207
210
|
sync_host_port = get_host_port(get_container_name, UNISON_CONTAINER_PORT)
|
208
|
-
cmd = "unison -testserver #{@options['src']} \"socket://#{@options['sync_host_ip']}:#{sync_host_port}\""
|
211
|
+
cmd = "unison -testserver \"#{@options['src']}\" \"socket://#{@options['sync_host_ip']}:#{sync_host_port}\""
|
209
212
|
say_status 'command', cmd, :white if @options['verbose']
|
210
213
|
attempt = 0
|
211
214
|
max_attempt = @options['max_attempt'] || 5
|
data/tasks/stack/stack.thor
CHANGED
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.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eugen Mayer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.2'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
22
|
+
version: 1.2.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '1.
|
29
|
+
version: '1.2'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.
|
32
|
+
version: 1.2.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: gem_update_checker
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,26 +50,6 @@ dependencies:
|
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 0.2.0
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: docker-compose
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - "~>"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '1.1'
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 1.1.7
|
63
|
-
type: :runtime
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - "~>"
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '1.1'
|
70
|
-
- - ">="
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: 1.1.7
|
73
53
|
- !ruby/object:Gem::Dependency
|
74
54
|
name: terminal-notifier
|
75
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,54 +70,54 @@ dependencies:
|
|
90
70
|
requirements:
|
91
71
|
- - "~>"
|
92
72
|
- !ruby/object:Gem::Version
|
93
|
-
version: '2.
|
73
|
+
version: '2.8'
|
94
74
|
- - ">="
|
95
75
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
76
|
+
version: 2.8.1
|
97
77
|
type: :runtime
|
98
78
|
prerelease: false
|
99
79
|
version_requirements: !ruby/object:Gem::Requirement
|
100
80
|
requirements:
|
101
81
|
- - "~>"
|
102
82
|
- !ruby/object:Gem::Version
|
103
|
-
version: '2.
|
83
|
+
version: '2.8'
|
104
84
|
- - ">="
|
105
85
|
- !ruby/object:Gem::Version
|
106
|
-
version: 2.
|
86
|
+
version: 2.8.1
|
107
87
|
- !ruby/object:Gem::Dependency
|
108
88
|
name: daemons
|
109
89
|
requirement: !ruby/object:Gem::Requirement
|
110
90
|
requirements:
|
111
91
|
- - "~>"
|
112
92
|
- !ruby/object:Gem::Version
|
113
|
-
version: '1.
|
93
|
+
version: '1.4'
|
114
94
|
- - ">="
|
115
95
|
- !ruby/object:Gem::Version
|
116
|
-
version: 1.
|
96
|
+
version: 1.4.1
|
117
97
|
type: :runtime
|
118
98
|
prerelease: false
|
119
99
|
version_requirements: !ruby/object:Gem::Requirement
|
120
100
|
requirements:
|
121
101
|
- - "~>"
|
122
102
|
- !ruby/object:Gem::Version
|
123
|
-
version: '1.
|
103
|
+
version: '1.4'
|
124
104
|
- - ">="
|
125
105
|
- !ruby/object:Gem::Version
|
126
|
-
version: 1.
|
106
|
+
version: 1.4.1
|
127
107
|
- !ruby/object:Gem::Dependency
|
128
108
|
name: os
|
129
109
|
requirement: !ruby/object:Gem::Requirement
|
130
110
|
requirements:
|
131
111
|
- - ">="
|
132
112
|
- !ruby/object:Gem::Version
|
133
|
-
version:
|
113
|
+
version: 1.0.0
|
134
114
|
type: :runtime
|
135
115
|
prerelease: false
|
136
116
|
version_requirements: !ruby/object:Gem::Requirement
|
137
117
|
requirements:
|
138
118
|
- - ">="
|
139
119
|
- !ruby/object:Gem::Version
|
140
|
-
version:
|
120
|
+
version: 1.0.0
|
141
121
|
- !ruby/object:Gem::Dependency
|
142
122
|
name: pry
|
143
123
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,6 +132,20 @@ dependencies:
|
|
152
132
|
- - ">="
|
153
133
|
- !ruby/object:Gem::Version
|
154
134
|
version: '0'
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: rdoc
|
137
|
+
requirement: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - "<="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 6.3.2
|
142
|
+
type: :development
|
143
|
+
prerelease: false
|
144
|
+
version_requirements: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - "<="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 6.3.2
|
155
149
|
description: Sync your code live to docker-containers without losing any performance
|
156
150
|
on OSX
|
157
151
|
email: eugen.mayer@kontextwork.de
|
@@ -169,6 +163,7 @@ files:
|
|
169
163
|
- bin/docker-sync-daemon
|
170
164
|
- bin/docker-sync-stack
|
171
165
|
- lib/docker-sync.rb
|
166
|
+
- lib/docker-sync/command.rb
|
172
167
|
- lib/docker-sync/compose.rb
|
173
168
|
- lib/docker-sync/config/config_locator.rb
|
174
169
|
- lib/docker-sync/config/config_serializer.rb
|
@@ -188,6 +183,7 @@ files:
|
|
188
183
|
- lib/docker-sync/dependencies/rsync.rb
|
189
184
|
- lib/docker-sync/dependencies/unison.rb
|
190
185
|
- lib/docker-sync/dependencies/unox.rb
|
186
|
+
- lib/docker-sync/docker_compose_session.rb
|
191
187
|
- lib/docker-sync/environment.rb
|
192
188
|
- lib/docker-sync/execution.rb
|
193
189
|
- lib/docker-sync/sync_manager.rb
|
@@ -224,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
220
|
- !ruby/object:Gem::Version
|
225
221
|
version: '0'
|
226
222
|
requirements: []
|
227
|
-
rubygems_version: 3.1.
|
223
|
+
rubygems_version: 3.1.6
|
228
224
|
signing_key:
|
229
225
|
specification_version: 4
|
230
226
|
summary: Docker Sync - Fast and efficient way to sync code to docker-containers
|