docker-compose 0.3.0 → 0.3.1
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/docker-compose.gemspec +2 -0
- data/lib/docker/compose.rb +0 -1
- data/lib/docker/compose/rake_tasks.rb +1 -1
- data/lib/docker/compose/session.rb +10 -8
- data/lib/docker/compose/version.rb +1 -1
- metadata +15 -2
- data/lib/docker/compose/shell.rb +0 -210
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03253ecae7a727eaba835a5042ec07bd4af06aee
|
4
|
+
data.tar.gz: f82b24d7ade2a1621eab41bb8dc8da1188b7afef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49ae1c849beb8c5b9623faea4fd73057be4660979f1ea570e4ce013deb4d4e6807498090ae741859a530036ce420b068a587153514aa7b77b9c41072e7d72f59
|
7
|
+
data.tar.gz: 3350c7abbd3ae4fcefba35661b82abc314de369f8b7105b0430c10fd7b7031efc9e10e550d47da23898250fc00d76c9bb715d224fe8ebcf0cfbace0623f00d54
|
data/docker-compose.gemspec
CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
+
spec.add_dependency "backticks", "~> 0.1"
|
23
|
+
|
22
24
|
spec.add_development_dependency "bundler", "~> 1.10"
|
23
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
26
|
spec.add_development_dependency "rspec"
|
data/lib/docker/compose.rb
CHANGED
@@ -53,7 +53,7 @@ module Docker::Compose
|
|
53
53
|
self.extra_server_env = {}
|
54
54
|
yield self if block_given?
|
55
55
|
|
56
|
-
@shell =
|
56
|
+
@shell = Backticks::Runner.new
|
57
57
|
@session = Docker::Compose::Session.new(@shell, dir:dir, file:file)
|
58
58
|
@net_info = Docker::Compose::NetInfo.new
|
59
59
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'backticks'
|
2
|
+
|
1
3
|
module Docker::Compose
|
2
4
|
# A Ruby OOP interface to a docker-compose session. A session is bound to
|
3
5
|
# a particular directory and docker-compose file (which are set at initialize
|
@@ -13,7 +15,7 @@ module Docker::Compose
|
|
13
15
|
class Session
|
14
16
|
attr_reader :dir, :file
|
15
17
|
|
16
|
-
def initialize(shell=
|
18
|
+
def initialize(shell=Backticks::Runner.new,
|
17
19
|
dir:Dir.pwd, file:'docker-compose.yml')
|
18
20
|
@shell = shell
|
19
21
|
@dir = dir
|
@@ -89,20 +91,20 @@ module Docker::Compose
|
|
89
91
|
#
|
90
92
|
# @see Docker::Compose::Shell#command
|
91
93
|
#
|
92
|
-
# @param [Array]
|
93
|
-
#
|
94
|
+
# @param [Array] args command-line arguments in the format accepted by
|
95
|
+
# Backticks::Runner#command
|
94
96
|
# @return [String] output of the command
|
95
97
|
# @raise [RuntimeError] if command fails
|
96
|
-
def run!(*
|
98
|
+
def run!(*args)
|
97
99
|
project_opts = {
|
98
100
|
file: @file
|
99
101
|
}
|
100
102
|
|
101
103
|
Dir.chdir(@dir) do
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
104
|
+
cmd = @shell.command('docker-compose', project_opts, *args).join
|
105
|
+
status, out, err= cmd.status, cmd.captured_output, cmd.captured_error
|
106
|
+
status.success? || raise(Error.new(args.first, status, err))
|
107
|
+
out
|
106
108
|
end
|
107
109
|
end
|
108
110
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docker-compose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Spataro
|
@@ -10,6 +10,20 @@ bindir: exe
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2015-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: backticks
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.1'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,7 +92,6 @@ files:
|
|
78
92
|
- lib/docker/compose/net_info.rb
|
79
93
|
- lib/docker/compose/rake_tasks.rb
|
80
94
|
- lib/docker/compose/session.rb
|
81
|
-
- lib/docker/compose/shell.rb
|
82
95
|
- lib/docker/compose/version.rb
|
83
96
|
homepage: https://github.com/xeger/docker-compose
|
84
97
|
licenses:
|
data/lib/docker/compose/shell.rb
DELETED
@@ -1,210 +0,0 @@
|
|
1
|
-
require 'open3'
|
2
|
-
require 'pty'
|
3
|
-
|
4
|
-
module Docker::Compose
|
5
|
-
# An easy-to-use interface for invoking commands and capturing their output.
|
6
|
-
# Instances of Shell can be interactive, which prints the command's output
|
7
|
-
# to the terminal and also allows the user to interact with the command.
|
8
|
-
class Shell
|
9
|
-
# If true, commands run in the shell will have their stdio streams tied
|
10
|
-
# to the parent process so the user can view their output and send input
|
11
|
-
# to them. Commands' stdout is still captured normally when they are
|
12
|
-
# interactive.
|
13
|
-
#
|
14
|
-
# Note that interactivity doesn't work very well because we use popen,
|
15
|
-
# which uses pipes to communicate with the child process and pipes have
|
16
|
-
# a fixed buffer size; the displayed output tends to "lag" behind the
|
17
|
-
# actual program, and bytes sent to stdin may not arrive until you send
|
18
|
-
# a lot of them!
|
19
|
-
#
|
20
|
-
# @return [Boolean]
|
21
|
-
attr_accessor :interactive
|
22
|
-
|
23
|
-
# Convert Ruby keyword arguments into CLI parameters that are compatible
|
24
|
-
# with the syntax of golang's flags package.
|
25
|
-
#
|
26
|
-
# Options are translated to CLI parameters using the following convention:
|
27
|
-
# 1) Snake-case symbols are hyphenated, e.g. :no_foo => "--no-foo"
|
28
|
-
# 2) boolean values indicate a CLI flag; true includes the flag, false or nil omits it
|
29
|
-
# 3) other values indicate a CLI option that has a value.
|
30
|
-
# 4) single character values are passed as short options e.g. "-X V"
|
31
|
-
# 5) multi-character values are passed as long options e.g. "--XXX=V"
|
32
|
-
#
|
33
|
-
def self.options(**opts)
|
34
|
-
flags = []
|
35
|
-
|
36
|
-
# Transform opts into golang flags-style command line parameters;
|
37
|
-
# append them to the command.
|
38
|
-
opts.each do |kw, arg|
|
39
|
-
if kw.length == 1
|
40
|
-
if arg == true
|
41
|
-
# true: boolean flag
|
42
|
-
flags << "-#{kw}"
|
43
|
-
elsif arg
|
44
|
-
# truthey: option that has a value
|
45
|
-
flags << "-#{kw}" << arg.to_s
|
46
|
-
else
|
47
|
-
# falsey: omit boolean flag
|
48
|
-
end
|
49
|
-
else
|
50
|
-
kw = kw.to_s.gsub('_','-')
|
51
|
-
if arg == true
|
52
|
-
# true: boolean flag
|
53
|
-
flags << "--#{kw}"
|
54
|
-
elsif arg
|
55
|
-
# truthey: option that has a value
|
56
|
-
flags << "--#{kw}=#{arg}"
|
57
|
-
else
|
58
|
-
# falsey: omit boolean flag
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
flags
|
64
|
-
end
|
65
|
-
|
66
|
-
# Create an instance of Shell.
|
67
|
-
def initialize
|
68
|
-
@interactive = false
|
69
|
-
end
|
70
|
-
|
71
|
-
# Run a shell command whose arguments and flags are expressed using some
|
72
|
-
# Rubyish sugar. This method accepts an arbitrary number of positional
|
73
|
-
# parameters; each parameter can be a Hash, an array, or a simple Object.
|
74
|
-
# Arrays and simple objects are appended to argv as "bare" words; Hashes
|
75
|
-
# are translated to golang flags and then appended to argv.
|
76
|
-
#
|
77
|
-
# @return [Array] an (Integer,String,String) triple of exitstatus, stdout and stderr
|
78
|
-
#
|
79
|
-
# @example Run docker-compose with complex parameters
|
80
|
-
# command('docker-compose', {file: 'joe.yml'}, 'up', {d:true}, 'mysvc')
|
81
|
-
#
|
82
|
-
# @see #options for information on Hash-to-flag translation
|
83
|
-
def command(*cmd)
|
84
|
-
argv = []
|
85
|
-
|
86
|
-
cmd.each do |item|
|
87
|
-
case item
|
88
|
-
when Array
|
89
|
-
# list of words to append to argv
|
90
|
-
argv.concat(item.map { |e| e.to_s })
|
91
|
-
when Hash
|
92
|
-
# list of options to convert to CLI parameters
|
93
|
-
argv.concat(self.class.options(item))
|
94
|
-
else
|
95
|
-
# single word to append to argv
|
96
|
-
argv << item.to_s
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
run(argv)
|
101
|
-
end
|
102
|
-
|
103
|
-
# Run a simple command.
|
104
|
-
#
|
105
|
-
# @param [Array] argv list of command words
|
106
|
-
# @return [Array] triple of integer exitstatus, string stdout, and stderr
|
107
|
-
private def run(argv)
|
108
|
-
if self.interactive
|
109
|
-
run_interactive(argv)
|
110
|
-
else
|
111
|
-
run_noninteractive(argv)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Run a shell command. Use a pty to capture the unbuffered output.
|
116
|
-
#
|
117
|
-
# @param [Array] argv command to run; argv[0] is program name and the
|
118
|
-
# remaining elements are parameters and flags
|
119
|
-
# @return [Array] an (Integer,String,String) triple of exitstatus, stdout and (empty) stderr
|
120
|
-
private def run_interactive(argv)
|
121
|
-
stdout, stdout_w = PTY.open
|
122
|
-
stdin_r, stdin = IO.pipe
|
123
|
-
stderr, stderr_w = IO.pipe
|
124
|
-
pid = spawn(*argv, in: stdin_r, out: stdout_w, err: stderr_w)
|
125
|
-
stdin_r.close
|
126
|
-
stdout_w.close
|
127
|
-
stderr_w.close
|
128
|
-
|
129
|
-
output, error = run_inner(stdin, stdout, stderr)
|
130
|
-
|
131
|
-
Process.waitpid(pid)
|
132
|
-
|
133
|
-
[$?.exitstatus, output, error]
|
134
|
-
end
|
135
|
-
|
136
|
-
# Run a shell command. Perform no translation or substitution. Use a pipe
|
137
|
-
# to read the output, which may be buffered by the OS. Return the program's
|
138
|
-
# exit status and stdout.
|
139
|
-
#
|
140
|
-
# TODO eliminate interactive path (it can't happen anymore) and move flourishes to run_interactive
|
141
|
-
#
|
142
|
-
# @param [Array] argv command to run; argv[0] is program name and the
|
143
|
-
# remaining elements are parameters and flags
|
144
|
-
# @return [Array] an (Integer,String,String) triple of exitstatus, stdout and stderr
|
145
|
-
private def run_noninteractive(argv)
|
146
|
-
stdin, stdout, stderr, thr = Open3.popen3(*argv)
|
147
|
-
|
148
|
-
output, error = run_inner(stdin, stdout, stderr)
|
149
|
-
|
150
|
-
# This blocks until the process exits (which probably already happened,
|
151
|
-
# given that we have received EOF on its output streams).
|
152
|
-
status = thr.value.exitstatus
|
153
|
-
|
154
|
-
[status, output, error]
|
155
|
-
rescue Interrupt
|
156
|
-
# Proxy Ctrl+C to our child process
|
157
|
-
Process.kill('INT', thr.pid) rescue nil
|
158
|
-
raise
|
159
|
-
end
|
160
|
-
|
161
|
-
private def run_inner(stdin, stdout, stderr)
|
162
|
-
streams = [stdout, stderr]
|
163
|
-
|
164
|
-
if @interactive
|
165
|
-
streams << STDIN
|
166
|
-
else
|
167
|
-
stdin.close
|
168
|
-
end
|
169
|
-
|
170
|
-
output = String.new.force_encoding(Encoding::BINARY)
|
171
|
-
error = String.new.force_encoding(Encoding::BINARY)
|
172
|
-
|
173
|
-
until streams.empty? || (streams.length == 1 && streams.first == STDIN)
|
174
|
-
ready, _, _ = IO.select(streams, [], [], 1)
|
175
|
-
|
176
|
-
if ready && ready.include?(STDIN)
|
177
|
-
input = STDIN.readpartial(1_024) rescue nil
|
178
|
-
if input
|
179
|
-
stdin.write(input)
|
180
|
-
else
|
181
|
-
# our own STDIN got closed; proxy to child's stdin
|
182
|
-
stdin.close
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
if ready && ready.include?(stderr)
|
187
|
-
data = stderr.readpartial(1_024) rescue nil
|
188
|
-
if data
|
189
|
-
error << data
|
190
|
-
STDERR.write(data) if @interactive
|
191
|
-
else
|
192
|
-
streams.delete(stderr)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
if ready && ready.include?(stdout)
|
197
|
-
data = stdout.readpartial(1_024) rescue nil
|
198
|
-
if data
|
199
|
-
output << data
|
200
|
-
STDOUT.write(data) if @interactive
|
201
|
-
else
|
202
|
-
streams.delete(stdout)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
[output, error]
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|