docker-compose 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a06d21989982bb658ca42414f0a20e6e511263f6
4
- data.tar.gz: 94d12b911c12197da022fe880548d68f80225182
3
+ metadata.gz: b952c56ce5427a6d9ce38a1ad58ace5c5cf15d79
4
+ data.tar.gz: 0863c488fa6a6f6a46e6cd7c153c28339be08d24
5
5
  SHA512:
6
- metadata.gz: 400d618d335ebb064edccbb21f074c66d1b5e82ba4b6f5a93b69ac1227cab19438df7e23ea94529f40f5598405fcd4834234881ffdc011a7c00f0d00d0467919
7
- data.tar.gz: 180aac4998d6a1ed559f006a617a987e0ea61aa0904c9030de8ba9698f23f254b08ee907aa613b12ca79f1863a61e761668388f1e4f6d8efa816bf6b13d7b6d9
6
+ metadata.gz: b533ef0d4fa4cdfa2672228fbf28da9dfa4495b666dd4ef356a79839d2c94fabbb106d05f0044d852ccd630a43092d1a12f30b671e02b23714ea781d93f1e594
7
+ data.tar.gz: 9cd0fd736c824ec0ebbebe9d9b22ae16f941f6ad1c6c0a3f372c124b1054c32e14f027016e0035e67c0f420b7ad35f5a7b7f0f7c430a022b1658e841dab05e90
@@ -1,4 +1,5 @@
1
1
  require_relative 'compose/version'
2
+ require_relative 'compose/error'
2
3
  require_relative 'compose/shell'
3
4
  require_relative 'compose/session'
4
5
  require_relative 'compose/net_info'
@@ -6,7 +7,7 @@ require_relative 'compose/mapper'
6
7
 
7
8
  module Docker
8
9
  module Compose
9
- # Create a new session.
10
+ # Create a new session with default options.
10
11
  def self.new
11
12
  Session.new
12
13
  end
@@ -0,0 +1,16 @@
1
+ module Docker::Compose
2
+ class Error < RuntimeError
3
+ attr_reader :status, :detail
4
+
5
+ # @param [String] cmd
6
+ # @param [Integer] status
7
+ # @param [String] detail
8
+ def initialize(cmd, status, detail)
9
+ @status = status
10
+ @detail = detail
11
+ brief = detail.split("\n").first || '(no output)'
12
+ message = format("'%s' failed with status %d: %s", cmd, status, brief)
13
+ super(message)
14
+ end
15
+ end
16
+ end
@@ -48,10 +48,10 @@ module Docker::Compose::Future
48
48
  project: File.basename(@dir)
49
49
  }
50
50
 
51
- result, output =
51
+ result, output, error =
52
52
  @shell.command('docker-compose', project_opts, *cmd)
53
- (result == 0) || raise(RuntimeError,
54
- "#{cmd.first} failed with status #{result}")
53
+ (result == 0) ||
54
+ raise(Docker::Compose::Error.new(cmd.first, result, error))
55
55
  output
56
56
  end
57
57
  ensure
@@ -12,6 +12,25 @@ module Docker::Compose
12
12
  BadSubstitution = Class.new(StandardError)
13
13
  NoService = Class.new(RuntimeError)
14
14
 
15
+ # Instantiate a mapper; map some environment variables; yield to caller for
16
+ # additional processing.
17
+ #
18
+ # @param [Boolean] strict
19
+ # @param [Session] session
20
+ # @param [NetInfo] net_info
21
+ # @yield yields with each substituted (key, value) pair
22
+ def self.map(env, strict:true, session:Session.new, net_info:NetInfo.new)
23
+ mapper = self.new(session, net_info.host_routable_ip, strict:strict)
24
+ env.each_pair do |k, v|
25
+ begin
26
+ v = mapper.map(v)
27
+ yield(k, v)
28
+ rescue NoService
29
+ yield(k, nil)
30
+ end
31
+ end
32
+ end
33
+
15
34
  # Create an instance of Mapper
16
35
  # @param [Docker::Compose::Session] session
17
36
  # @param [String] host_ip IPv4 address of the host that is publishing
@@ -24,18 +24,18 @@ module Docker::Compose
24
24
  # services running inside containers.
25
25
  #
26
26
  # @see Docker::Compose::Mapper for information about the substitution syntax
27
- attr_accessor :env
27
+ attr_accessor :server_env
28
28
 
29
29
  # Extra environment variables that should be set before invoking the command
30
- # specified for docker:compose:server. These are set _in addition_ to env
31
- # (and should be disjoint from env), and do not necessarily need to map the
32
- # location of a container; they can be simple extra env values that are
30
+ # specified for docker:compose:server. These are set _in addition_ to server_env
31
+ # (and should be disjoint from server_env), and do not necessarily need to map the
32
+ # location of a container; they are simply extra environment values that are
33
33
  # useful to change the server's behavior when it runs in cooperation
34
34
  # with containers.
35
35
  #
36
- # If there is overlap between env and server_env, then keys of server_env
37
- # will "win"; they are set last.
38
- attr_accessor :server_env
36
+ # If there is overlap between server_env and extra_server_env, then keys
37
+ # of extra_server_env will "win"; they are set last.
38
+ attr_accessor :extra_server_env
39
39
 
40
40
  # Command to exec on the _host_ when someone invokes docker:compose:server.
41
41
  # This is used to start up all containers and then run a server that
@@ -44,18 +44,20 @@ module Docker::Compose
44
44
 
45
45
  # Construct Rake wrapper tasks for docker-compose. If a block is given,
46
46
  # yield self to the block before defining any tasks so their behavior
47
- # can be configured by calling #env=, #file= and so forth.
47
+ # can be configured by calling #server_env=, #file= and so forth.
48
48
  def initialize
49
49
  self.dir = Rake.application.original_dir
50
50
  self.file = 'docker-compose.yml'
51
- self.env = {}
52
51
  self.server_env = {}
52
+ self.extra_server_env = {}
53
53
  yield self if block_given?
54
54
 
55
55
  @shell = Docker::Compose::Shell.new
56
56
  @session = Docker::Compose::Session.new(@shell, dir:dir, file:file)
57
57
  @net_info = Docker::Compose::NetInfo.new
58
58
 
59
+ @shell.interactive = true
60
+
59
61
  define
60
62
  end
61
63
 
@@ -67,25 +69,25 @@ module Docker::Compose
67
69
  @shell.interactive = false # suppress useless 'port' output
68
70
 
69
71
  if Rake.application.top_level_tasks.include? 'docker:compose:env'
70
- # This task is being run as top-level; print some bash export
71
- # statements or usage information depending on whether STDOUT
72
- # is a tty.
73
- if STDOUT.tty?
74
- print_usage
75
- else
76
- export_env(print:true)
77
- end
72
+ # This task is being run as top-level task; set process
73
+ # environment _and_ print bash export commands to stdout.
74
+ # Also print usage hints if user invoked rake directly vs.
75
+ # eval'ing it's output
76
+ print_usage
77
+ export_env(print:true)
78
78
  else
79
79
  # This task is a dependency of something else; just export the
80
80
  # environment variables for use in-process by other Rake tasks.
81
81
  export_env(print:false)
82
82
  end
83
+
84
+ @shell.interactive = true
83
85
  end
84
86
 
85
- desc 'Launch services needed to run this application'
87
+ desc 'Launch services (ONLY=a,b,...)'
86
88
  task :up do
87
- @shell.interactive = true # let user see what's happening
88
- @session.up(detached:true)
89
+ only = (ENV['ONLY'] || '').split(',').compact.uniq
90
+ @session.up(*only, detached:true)
89
91
  end
90
92
 
91
93
  desc 'Tail logs of all running services'
@@ -93,7 +95,7 @@ module Docker::Compose
93
95
  @session.logs
94
96
  end
95
97
 
96
- desc 'Stop services needed to run this application'
98
+ desc 'Stop services'
97
99
  task :stop do
98
100
  @session.stop
99
101
  end
@@ -110,28 +112,17 @@ module Docker::Compose
110
112
  # published by docker-compose services. Optionally also print bash export
111
113
  # statements so this information can be made available to a user's shell.
112
114
  private def export_env(print:)
113
- # First, do env substitutions in strict mode; don't catch BadSubstitution
114
- # so the caller knows when he has a bogus value
115
- mapper = Docker::Compose::Mapper.new(@session,
116
- @net_info.docker_routable_ip)
117
- self.env.each_pair do |k, v|
118
- begin
119
- v = mapper.map(v)
120
- ENV[k] = v
121
- print_env(k, v) if print
122
- rescue Docker::Compose::Mapper::NoService
123
- ENV[k] = nil
124
- print_env(k, nil) if print
125
- end
115
+ Docker::Compose::Mapper.map(self.server_env,
116
+ session:@session,
117
+ net_info:@net_info) do |k, v|
118
+ ENV[k] = v
119
+ print_env(k, v) if print
126
120
  end
127
121
 
128
- # Next, do server substitutions in non-strict mode since server_env
129
- # can contain arbitrary values.
130
- mapper = Docker::Compose::Mapper.new(@session,
131
- @net_info.docker_routable_ip,
132
- strict:false)
133
- self.server_env.each_pair do |k, v|
134
- v = mapper.map(v)
122
+ Docker::Compose::Mapper.map(self.extra_server_env,
123
+ strict:false,
124
+ session:@session,
125
+ net_info:@net_info) do |k, v|
135
126
  ENV[k] = v
136
127
  print_env(k, v) if print
137
128
  end
@@ -148,11 +139,8 @@ module Docker::Compose
148
139
 
149
140
  private def print_usage
150
141
  be = 'bundle exec ' if defined?(Bundler)
151
- puts "# To export container network locations to your environment:"
152
- puts %Q{eval "$(#{be}rake docker:compose:env)"}
153
- puts
154
- puts '# To learn which environment variables we will export:'
155
- puts %Q{echo "$(#{be}rake docker:compose:env)"}
142
+ puts %Q{# To export these variables to your shell, run:}
143
+ puts %Q{# eval "$(#{be}rake docker:compose:env)"}
156
144
  end
157
145
  end
158
146
  end
@@ -13,6 +13,8 @@ module Docker::Compose
13
13
  # allowed by the docker-compose CLI, and that options are sometimes renamed
14
14
  # for clarity, e.g. the "-d" flag always becomes the "detached:" kwarg.
15
15
  class Session
16
+ attr_reader :dir, :file
17
+
16
18
  def initialize(shell=Docker::Compose::Shell.new,
17
19
  dir:Dir.pwd, file:'docker-compose.yml')
18
20
  @shell = shell
@@ -99,10 +101,9 @@ module Docker::Compose
99
101
  }
100
102
 
101
103
  Dir.chdir(@dir) do
102
- result, output =
104
+ result, output, error =
103
105
  @shell.command('docker-compose', project_opts, *cmd)
104
- (result == 0) || raise(RuntimeError,
105
- "#{cmd.first} failed with status #{result}")
106
+ (result == 0) || raise(Error.new(cmd.first, result, error))
106
107
  output
107
108
  end
108
109
  end
@@ -75,6 +75,8 @@ module Docker::Compose
75
75
  # Arrays and simple objects are appended to argv as "bare" words; Hashes
76
76
  # are translated to golang flags and then appended to argv.
77
77
  #
78
+ # @return [Array] an (Integer,String,String) triple of exitstatus, stdout and stderr
79
+ #
78
80
  # @example Run docker-compose with complex parameters
79
81
  # command('docker-compose', {file: 'joe.yml'}, 'up', {d:true}, 'mysvc')
80
82
  #
@@ -104,7 +106,7 @@ module Docker::Compose
104
106
  #
105
107
  # @param [Array] argv command to run; argv[0] is program name and the
106
108
  # remaining elements are parameters and flags
107
- # @return [Array] a pair of Integer exitstatus and String output
109
+ # @return [Array] an (Integer,String,String) triple of exitstatus, stdout and stderr
108
110
  private def run(argv)
109
111
  stdin, stdout, stderr, thr = Open3.popen3(*argv)
110
112
 
@@ -117,6 +119,7 @@ module Docker::Compose
117
119
  end
118
120
 
119
121
  output = String.new.force_encoding(Encoding::BINARY)
122
+ error = String.new.force_encoding(Encoding::BINARY)
120
123
 
121
124
  until streams.empty? || (streams.length == 1 && streams.first == STDIN)
122
125
  ready, _, _ = IO.select(streams, [], [], 1)
@@ -134,6 +137,7 @@ module Docker::Compose
134
137
  if ready && ready.include?(stderr)
135
138
  data = stderr.readpartial(1_024) rescue nil
136
139
  if data
140
+ error << data
137
141
  STDERR.write(data) if @interactive
138
142
  else
139
143
  streams.delete(stderr)
@@ -155,7 +159,7 @@ module Docker::Compose
155
159
  # given that we have received EOF on its output streams).
156
160
  status = thr.value.exitstatus
157
161
 
158
- [status, output]
162
+ [status, output, error]
159
163
  rescue Interrupt
160
164
  # Proxy Ctrl+C to our child process
161
165
  Process.kill('INT', thr.pid) rescue nil
@@ -1,5 +1,5 @@
1
1
  module Docker
2
2
  module Compose
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Spataro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-08 00:00:00.000000000 Z
11
+ date: 2015-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,6 +73,7 @@ files:
73
73
  - bin/setup
74
74
  - docker-compose.gemspec
75
75
  - lib/docker/compose.rb
76
+ - lib/docker/compose/error.rb
76
77
  - lib/docker/compose/future/session.rb
77
78
  - lib/docker/compose/mapper.rb
78
79
  - lib/docker/compose/net_info.rb