bigrig 0.1.4 → 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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile.lock +5 -1
  4. data/README.md +1 -0
  5. data/bigrig.gemspec +1 -0
  6. data/lib/bigrig/actions/dev_action.rb +56 -1
  7. data/lib/bigrig/actions/log_action.rb +2 -33
  8. data/lib/bigrig/actions/run_action.rb +1 -1
  9. data/lib/bigrig/dependency_graph.rb +16 -2
  10. data/lib/bigrig/log_tailer.rb +56 -0
  11. data/lib/bigrig/models/container.rb +3 -2
  12. data/lib/bigrig/runner.rb +14 -12
  13. data/lib/bigrig/version.rb +1 -1
  14. data/lib/bigrig.rb +1 -0
  15. data/spec/bigrig/actions/dev_action_spec.rb +1 -1
  16. data/spec/bigrig/actions/log_action_spec.rb +5 -1
  17. data/spec/bigrig/dependency_graph_spec.rb +22 -1
  18. data/spec/bigrig/log_tailer_spec.rb +24 -0
  19. data/spec/bigrig/models/container_spec.rb +10 -1
  20. data/spec/bigrig_spec.rb +55 -4
  21. data/spec/data/scan.json +18 -0
  22. data/spec/spec_helper.rb +25 -0
  23. data/spec/support/vcr.rb +1 -0
  24. data/spec/vcr/Bigrig_LogAction/_perform/follows_the_log.yml +129 -17
  25. data/spec/vcr/bigrig/dev/spec/data/dev_json/activates_the_dev_profile.yml +270 -18
  26. data/spec/vcr/bigrig/dev/spec/data/dev_json/starts_the_containers.yml +362 -30
  27. data/spec/vcr/bigrig/dev/spec/data/scan_json/leaves_unaffected_containers_alone_when_the_scanned_file_changes.yml +527 -0
  28. data/spec/vcr/bigrig/dev/spec/data/scan_json/restarts_dependant_containers_when_the_scanned_file_changes.yml +501 -0
  29. data/spec/vcr/bigrig/dev/spec/data/scan_json/restarts_the_container_when_the_scanned_file_changes.yml +607 -0
  30. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_activates_the_dev_profile.yml +311 -113
  31. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_starts_the_containers.yml +305 -107
  32. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/scan_json_leaves_unaffected_containers_alone_when_the_scanned_file_changes.yml +2127 -0
  33. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/scan_json_restarts_dependant_containers_when_the_scanned_file_changes.yml +2127 -0
  34. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/scan_json_restarts_the_container_when_the_scanned_file_changes.yml +2863 -0
  35. metadata +25 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67c0ec6d99a335ab032bf9ca126d7175e3c4a08e
4
- data.tar.gz: 756289a5f4bf550b94f8dc6eb1cf547d4458db53
3
+ metadata.gz: c9a963f80ce0fa0894c6a8dff9c4676778a99dcf
4
+ data.tar.gz: 5905ee20eb915c1b58f095d35375f125ba887840
5
5
  SHA512:
6
- metadata.gz: 67d2524b1ad424c25886a2e7b2c196af1bb1dfb54cd7547c774a446bacb95e9a1d0a2e03dda5a10cc36e029586e26e4a2103164b5c6b0dcda18c7ea4da8a9d06
7
- data.tar.gz: ab4098ceae9911c786ca40cc72a2b2791ed8c3d213da133c4caf69925e741e21ffbb1a1e694d45da2ed69a135ef34c4dc2cc4238b9c7af2496153d3a63597562
6
+ metadata.gz: b8bfaef2b69cd7af858afdbfb33394c9c3c737c4c6d0f5929f5a1b3b996a0bfbb3f21e2b9096c2b292a9059f60938219c71e701b50d46df7e758e0abda8a745c
7
+ data.tar.gz: c2f5dcdb8d3a32127482c92d6ec5ad9b16695c5913308f0da7cb4787dd61ca067a3f0e264f77435e53abf27417a0ae738e857fef5457591f2c45c8282e305d92
data/CHANGELOG.md CHANGED
@@ -35,3 +35,7 @@ Add `volumes` attriute
35
35
  0.1.4
36
36
  =====
37
37
  * Unbreak build caching
38
+
39
+ 0.2.0
40
+ =====
41
+ * Added `scan` functionality
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bigrig (0.1.4)
4
+ bigrig (0.2.0)
5
5
  colorize (= 0.7.5)
6
6
  docker-api (= 1.20.0)
7
+ filewatcher (= 0.4.0)
7
8
  gli (= 2.12.2)
8
9
 
9
10
  GEM
@@ -23,6 +24,8 @@ GEM
23
24
  excon (>= 0.38.0)
24
25
  json
25
26
  excon (0.45.1)
27
+ filewatcher (0.4.0)
28
+ trollop (~> 2.0)
26
29
  gli (2.12.2)
27
30
  json (1.8.2)
28
31
  method_source (0.8.2)
@@ -64,6 +67,7 @@ GEM
64
67
  ruby-progressbar (1.7.0)
65
68
  safe_yaml (1.0.4)
66
69
  slop (3.6.0)
70
+ trollop (2.1.2)
67
71
  vcr (2.9.3)
68
72
  webmock (1.20.4)
69
73
  addressable (>= 2.3.6)
data/README.md CHANGED
@@ -55,6 +55,7 @@ generate a docker image.
55
55
  "ports": ["80:80"],
56
56
  "repo": "hawknewton/my-awesome-app",
57
57
  "path": ".",
58
+ "scan": "target/app.war",
58
59
  "env": {
59
60
  "USE_SSL": true,
60
61
  "CACHE_TIMEOUT": "3600"
data/bigrig.gemspec CHANGED
@@ -26,4 +26,5 @@ Gem::Specification.new do |s|
26
26
  s.add_runtime_dependency('gli', '2.12.2')
27
27
  s.add_runtime_dependency('colorize', '0.7.5')
28
28
  s.add_runtime_dependency('docker-api', '1.20.0')
29
+ s.add_runtime_dependency('filewatcher', '0.4.0')
29
30
  end
@@ -1,13 +1,21 @@
1
+ require 'filewatcher'
2
+
1
3
  module Bigrig
2
4
  class DevAction
3
5
  def initialize(active_containers)
4
6
  @active_containers = active_containers
7
+ @application = Application.from_json active_containers
8
+ @restarting = 0
5
9
  end
6
10
 
7
11
  def perform
12
+ Thread.new { watch_for_changes }
13
+
8
14
  RunAction.new(@active_containers).perform
9
15
  [:SIGTERM, :SIGINT].each { |s| Signal.trap(s) { destroy } }
10
- LogAction.new(@active_containers).perform
16
+
17
+ follow_logs
18
+ wait_for_containers
11
19
  end
12
20
 
13
21
  private
@@ -15,5 +23,52 @@ module Bigrig
15
23
  def destroy
16
24
  DestroyAction.new(@active_containers).perform
17
25
  end
26
+
27
+ def follow_logs
28
+ @tailers = @application.containers.map do |container|
29
+ LogTailer.create container.name
30
+ end
31
+ end
32
+
33
+ def kill_containers(containers)
34
+ containers.reverse.each do |c|
35
+ puts "Killing #{c.name} for restart".light_white
36
+ DockerAdapter.kill c.name
37
+ end
38
+ end
39
+
40
+ def restart(container)
41
+ @restarting += 1
42
+ containers = DependencyGraph.new(@application.containers).resolve_subtree container
43
+ kill_containers containers
44
+ Runner.new(containers).run
45
+ containers.each { |c| @tailers << LogTailer.create(c.name) }
46
+ ensure
47
+ @restarting -= 1
48
+ end
49
+
50
+ def tailers
51
+ @tailers ||= []
52
+ end
53
+
54
+ def watch_for_changes
55
+ @application.containers.select(&:scan).each do |container|
56
+ FileWatcher.new([container.scan]).watch do
57
+ begin
58
+ restart container
59
+ rescue => e
60
+ puts "Error restarting container: #{e}\n#{e.backtrace.join}".red
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def wait_for_containers
67
+ while @tailers.any? || @restarting != 0
68
+ @tailers.each(&:join)
69
+ @tailers.keep_if(&:alive?)
70
+ sleep 0.1
71
+ end
72
+ end
18
73
  end
19
74
  end
@@ -2,44 +2,13 @@ require 'colorize'
2
2
 
3
3
  module Bigrig
4
4
  class LogAction
5
- COLORS = [:green,
6
- :yellow,
7
- :light_blue,
8
- :magenta,
9
- :light_white]
10
-
11
5
  def initialize(active_containers)
12
6
  @application = Application.from_json active_containers
13
7
  end
14
8
 
15
9
  def perform
16
- threads = @application.containers.map do |container|
17
- color = next_color
18
- Thread.new do
19
- DockerAdapter.logs container.name, &print_block(container.name.send color)
20
- end
21
- end
22
-
23
- threads.each(&:join)
24
- end
25
-
26
- private
27
-
28
- def print_block(name)
29
- proc do |stream, chunk|
30
- if stream == :stderr
31
- print "#{name}: #{chunk.light_red}"
32
- else
33
- puts "#{name}: #{chunk}"
34
- end
35
- $stdout.flush
36
- end
37
- end
38
-
39
- def next_color
40
- @color ||= 0
41
- @color += 1
42
- COLORS[(@color - 1) % 5]
10
+ tailers = @application.containers.map { |c| LogTailer.create c.name }
11
+ tailers.each(&:join)
43
12
  end
44
13
  end
45
14
  end
@@ -4,7 +4,7 @@ module Bigrig
4
4
 
5
5
  def initialize(active_containers)
6
6
  application = Application.from_json active_containers
7
- @runner = Runner.new application
7
+ @runner = Runner.new application.containers
8
8
  end
9
9
 
10
10
  def perform
@@ -6,9 +6,23 @@ module Bigrig
6
6
  end
7
7
 
8
8
  def resolve
9
+ startup_order @containers
10
+ end
11
+
12
+ def resolve_subtree(container)
13
+ startup_order @containers.select { |c| resolve_deps(c, []).include? container.name }
14
+ end
15
+
16
+ private
17
+
18
+ def containers_for(names)
19
+ names.map { |n| @map[n] }
20
+ end
21
+
22
+ def startup_order(containers)
9
23
  resolved = []
10
- @containers.each { |c| resolve_deps(c, resolved) unless resolved.include? c.name }
11
- resolved.map { |n| @map[n] }
24
+ containers.each { |c| resolve_deps(c, resolved) unless resolved.include? c.name }
25
+ containers_for resolved
12
26
  end
13
27
 
14
28
  def resolve_deps(container, resolved)
@@ -0,0 +1,56 @@
1
+ require 'colorize'
2
+ require 'forwardable'
3
+
4
+ module Bigrig
5
+ class LogTailer
6
+ extend Forwardable
7
+
8
+ COLORS = [:green,
9
+ :yellow,
10
+ :light_blue,
11
+ :magenta,
12
+ :light_white]
13
+
14
+ def_delegators :@thread, :alive?, :join, :kill
15
+
16
+ class << self
17
+ def create(name)
18
+ new name, color_for(name)
19
+ end
20
+
21
+ def color_for(name)
22
+ @colors ||= {}
23
+ @colors[name] ||= next_color
24
+ end
25
+
26
+ def next_color
27
+ @color ||= 0
28
+ @color += 1
29
+ COLORS[(@color - 1) % 5]
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def initialize(name, color)
36
+ @thread = Thread.new do
37
+ begin
38
+ DockerAdapter.logs name, &print_block(name.send color)
39
+ rescue => e
40
+ puts "Error starting log tailer: #{e}\n#{e.backtrace.join "\n"}"
41
+ end
42
+ end
43
+ end
44
+
45
+ def print_block(name)
46
+ proc do |stream, chunk|
47
+ if stream == :stderr
48
+ print "#{name}: #{chunk.light_red}"
49
+ else
50
+ puts "#{name}: #{chunk}"
51
+ end
52
+ $stdout.flush
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,10 +1,11 @@
1
1
  module Bigrig
2
2
  class Container < BaseModel
3
- attr_accessor :env, :name, :path, :ports, :tag, :volumes_from, :links, :hosts, :repo, :volumes
3
+ attr_accessor :env, :name, :path, :ports, :tag, :volumes_from, :links, :hosts, :repo,
4
+ :volumes, :scan
4
5
 
5
6
  class << self
6
7
  def from_json(name, json)
7
- opts = [:env, :path, :ports, :tag, :repo].each_with_object(name: name) do |e, o|
8
+ opts = [:env, :path, :ports, :tag, :repo, :scan].each_with_object(name: name) do |e, o|
8
9
  o[e] = json.send :[], e.to_s
9
10
  end
10
11
  [:volumes_from, :links, :hosts, :volumes].each { |x| opts[x] = as_array json[x.to_s] }
data/lib/bigrig/runner.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  module Bigrig
2
2
  class Runner
3
- def initialize(application)
4
- @application = application
3
+ def self.start(container)
4
+ puts "Starting #{container.name}"
5
+ puts DockerAdapter.run docker_opts_for container
6
+ end
7
+
8
+ def initialize(containers)
9
+ @containers = containers
5
10
  end
6
11
 
7
12
  def run
@@ -10,15 +15,13 @@ module Bigrig
10
15
 
11
16
  private
12
17
 
18
+ attr_accessor :containers
19
+
13
20
  def build(path)
14
21
  puts "Building #{path}"
15
22
  DockerAdapter.build path, &OutputParser.parser_proc
16
23
  end
17
24
 
18
- def containers
19
- @application.containers
20
- end
21
-
22
25
  def depends_on_containers(container, containers)
23
26
  (containers.map(&:name) & container.dependencies).any?
24
27
  end
@@ -33,22 +36,21 @@ module Bigrig
33
36
  end
34
37
 
35
38
  def docker_opts(step)
36
- step.map do |container|
37
- docker_opts_for(container).merge image_id: image_id(container)
38
- end
39
+ step.map { |c| Runner.docker_opts_for c }
39
40
  end
40
41
 
41
- def docker_opts_for(container)
42
+ def self.docker_opts_for(container)
42
43
  { env: container.env,
43
44
  name: container.name,
44
45
  ports: container.ports,
45
46
  volumes_from: container.volumes_from,
46
47
  volumes: container.volumes,
47
48
  links: container.links,
48
- hosts: container.hosts }
49
+ hosts: container.hosts,
50
+ image_id: image_id(container) }
49
51
  end
50
52
 
51
- def image_id(container)
53
+ def self.image_id(container)
52
54
  if container.path
53
55
  build container.path
54
56
  else
@@ -1,3 +1,3 @@
1
1
  module Bigrig
2
- VERSION = '0.1.4'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/bigrig.rb CHANGED
@@ -2,6 +2,7 @@ require 'bigrig/actions'
2
2
  require 'bigrig/descriptor'
3
3
  require 'bigrig/dependency_graph'
4
4
  require 'bigrig/docker_adapter'
5
+ require 'bigrig/log_tailer'
5
6
  require 'bigrig/models'
6
7
  require 'bigrig/output_parser'
7
8
  require 'bigrig/runner'
@@ -2,7 +2,7 @@ module Bigrig
2
2
  describe DevAction do
3
3
  describe '#perform' do
4
4
  subject { described_class.new descriptor.as_json }
5
- let(:descriptor) { Descriptor.new test_file(file), profiles }
5
+ let(:descriptor) { Descriptor.read test_file(file), profiles }
6
6
 
7
7
  context 'when no profile is provided' do
8
8
  let(:profiles) { [] }
@@ -10,6 +10,10 @@ module Bigrig
10
10
  let(:container) { Docker::Container.get 'log-test' }
11
11
 
12
12
  before do
13
+ begin
14
+ Docker::Container.get('log-test').kill.delete
15
+ rescue Docker::Error::NotFoundError # rubocop:disable Lint/HandleExceptions
16
+ end
13
17
  Docker::Container.create('Image' => image.id, 'name' => 'log-test').start
14
18
  end
15
19
 
@@ -24,7 +28,7 @@ module Bigrig
24
28
  and_yield(:stdout, 'stdout message').
25
29
  and_yield(:stderr, 'stderr message')
26
30
  expect($stdout).to receive(:puts).with "\e[0;32;49mlog-test\e[0m: stdout message"
27
- expect(runner).to receive(:print).
31
+ expect_any_instance_of(LogTailer).to receive(:print).
28
32
  with "\e[0;32;49mlog-test\e[0m: \e[0;91;49mstderr message\e[0m"
29
33
  subject
30
34
  end
@@ -11,7 +11,28 @@ module Bigrig
11
11
  end
12
12
 
13
13
  it 'resolves in the correct order' do
14
- expect(subject.map(&:name)).to match_array %w(test1 test2)
14
+ expect(subject.map(&:name)).to eq %w(test1 test2)
15
+ end
16
+ end
17
+ end
18
+
19
+ describe '#resolve_subtree' do
20
+ subject { described_class.new(containers).resolve_subtree target }
21
+ context 'given three containers, two of which have a relationship' do
22
+ let(:target) do
23
+ Container.new(name: 'target')
24
+ end
25
+
26
+ let(:containers) do
27
+ [
28
+ target,
29
+ Container.new(name: 'test1', volumes_from: ['target']),
30
+ Container.new(name: 'test2')
31
+ ]
32
+ end
33
+
34
+ it 'resolves only related containers' do
35
+ expect(subject.map(&:name)).to eq %w(target test1)
15
36
  end
16
37
  end
17
38
  end
@@ -0,0 +1,24 @@
1
+ module Bigrig
2
+ describe LogTailer do
3
+
4
+ describe '#create' do
5
+ before do
6
+ LogTailer.instance_variable_set :@colors, nil
7
+ LogTailer.instance_variable_set :@color, nil
8
+ end
9
+ it 'reuses the same color for a given container' do
10
+ expect(LogTailer).to receive(:new).with('container', :green).twice
11
+ LogTailer.create 'container'
12
+ LogTailer.create 'container'
13
+ end
14
+
15
+ it 'uses new colors for new containers' do
16
+ expect(LogTailer).to receive(:new).with 'container1', :green
17
+ expect(LogTailer).to receive(:new).with 'container2', :yellow
18
+
19
+ LogTailer.create 'container1'
20
+ LogTailer.create 'container2'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -12,6 +12,8 @@ module Bigrig
12
12
  it { is_expected.to respond_to :ports= }
13
13
  it { is_expected.to respond_to :repo }
14
14
  it { is_expected.to respond_to :repo= }
15
+ it { is_expected.to respond_to :scan= }
16
+ it { is_expected.to respond_to :scan }
15
17
  it { is_expected.to respond_to :tag }
16
18
  it { is_expected.to respond_to :tag= }
17
19
  it { is_expected.to respond_to :volumes_from }
@@ -83,7 +85,6 @@ module Bigrig
83
85
 
84
86
  its(:ports) { is_expected.to be_a Array }
85
87
  its(:ports) { is_expected.to be_empty }
86
-
87
88
  end
88
89
 
89
90
  context 'given json with a path' do
@@ -94,6 +95,14 @@ module Bigrig
94
95
  end
95
96
  end
96
97
 
98
+ context 'given json with a scan' do
99
+ let(:json) { { 'scan' => '/path/to/scan' } }
100
+
101
+ it 'sets the path' do
102
+ expect(subject.scan).to eq '/path/to/scan'
103
+ end
104
+ end
105
+
97
106
  context 'given json with env params' do
98
107
  let(:json) { { 'env' => { 'NAME1' => 'VALUE1', 'NAME2' => 'VALUE2' } } }
99
108
 
data/spec/bigrig_spec.rb CHANGED
@@ -11,8 +11,61 @@ describe 'bigrig' do
11
11
  end
12
12
 
13
13
  describe 'dev' do
14
+ context 'spec/data/scan.json' do
15
+ let(:args) { ['-f', 'spec/data/scan.json', 'dev'] }
16
+ let(:command) { %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '}) }
17
+
18
+ before do
19
+ FileUtils.mkdir_p '/tmp/scan'
20
+ FileUtils.touch '/tmp/scan/scan.me'
21
+ end
22
+
23
+ it 'restarts the container when the scanned file changes', :vcr do
24
+ pid, _stdin, stdout, _stderr = Open4.popen4(command)
25
+ drain_io stdout
26
+
27
+ wait_for %w(scanning uses_scanning some_ahole)
28
+ before_image = Docker::Container.get 'scanning'
29
+ FileUtils.touch '/tmp/scan/scan.me'
30
+ sleep 3
31
+ wait_for 'scanning'
32
+ expect(before_image.id).to_not eq Docker::Container.get('scanning').id
33
+ Process.kill :SIGINT, pid
34
+ Process.wait pid
35
+ end
36
+
37
+ it 'restarts dependant containers when the scanned file changes', :vcr do
38
+ pid, _stdin, stdout, _stderr = Open4.popen4(command)
39
+ drain_io stdout
40
+ wait_for %w(scanning uses_scanning some_ahole)
41
+ before_image = Docker::Container.get 'uses_scanning'
42
+
43
+ FileUtils.touch '/tmp/scan/scan.me'
44
+ sleep 3
45
+ wait_for 'uses_scanning'
46
+ expect(before_image.id).to_not eq Docker::Container.get('uses_scanning').id
47
+ Process.kill :SIGINT, pid
48
+ Process.wait pid
49
+ end
50
+
51
+ it 'leaves unaffected containers alone when the scanned file changes', :vcr do
52
+ pid, _stdin, stdout, _stderr = Open4.popen4(command)
53
+ drain_io stdout
54
+ wait_for %w(scanning uses_scanning some_ahole)
55
+ before_image = Docker::Container.get 'some_ahole'
56
+
57
+ FileUtils.touch '/tmp/scan/scan.me'
58
+ sleep 3
59
+ wait_for %w(scanning uses_scanning)
60
+ expect(before_image.id).to eq Docker::Container.get('some_ahole').id
61
+ Process.kill :SIGINT, pid
62
+ Process.wait pid
63
+ end
64
+ end
65
+
14
66
  context 'spec/data/dev.json' do
15
67
  let(:args) { ['-f', 'spec/data/dev.json', 'dev'] }
68
+ let(:command) { %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '}) }
16
69
  let(:env) do
17
70
  url = URI.parse Docker.connection.url
18
71
  text = Net::HTTP.get URI.parse("http://#{url.host}:4568")
@@ -29,8 +82,8 @@ describe 'bigrig' do
29
82
  end
30
83
 
31
84
  it 'starts the containers', :vcr do
32
- command = %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '})
33
85
  pid = Open4.popen4(command).first
86
+ wait_for %w(dev-test dev-logs)
34
87
  sleep 2
35
88
  dev_test = Docker::Container.get('dev-test')
36
89
  dev_logs = Docker::Container.get('dev-logs')
@@ -44,7 +97,6 @@ describe 'bigrig' do
44
97
  end
45
98
 
46
99
  it 'destroys containers on exit', :vcr do
47
- command = %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '})
48
100
  pid = Open4.popen4(command).first
49
101
  Process.kill :SIGINT, pid
50
102
  Process.wait pid
@@ -61,8 +113,8 @@ describe 'bigrig' do
61
113
  end
62
114
 
63
115
  it 'activates the dev profile', :vcr do
64
- command = %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '})
65
116
  pid = Open4.popen4(command).first
117
+ wait_for 'dev-test'
66
118
  sleep 2
67
119
  begin
68
120
  expect(env).to include 'PROFILE' => 'dev'
@@ -73,7 +125,6 @@ describe 'bigrig' do
73
125
  end
74
126
 
75
127
  it 'tails the logs', :vcr do
76
- command = %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '})
77
128
  pid, output = capture_stdout command
78
129
  Process.kill :SIGINT, pid
79
130
  Process.wait pid
@@ -0,0 +1,18 @@
1
+ {
2
+ "containers": {
3
+ "scanning": {
4
+ "repo": "hawknewton/log-test",
5
+ "tag": "0.0.1",
6
+ "scan": "/tmp/scan/**"
7
+ },
8
+ "uses_scanning": {
9
+ "repo": "hawknewton/log-test",
10
+ "tag": "0.0.1",
11
+ "links": "scanning:scanning"
12
+ },
13
+ "some_ahole": {
14
+ "repo": "hawknewton/log-test",
15
+ "tag": "0.0.1"
16
+ }
17
+ }
18
+ }
data/spec/spec_helper.rb CHANGED
@@ -90,6 +90,18 @@ def capture_stdout(command)
90
90
  [pid, output]
91
91
  end
92
92
 
93
+ def drain_io(io)
94
+ Thread.new do
95
+ loop do
96
+ begin
97
+ puts io.read_nonblock 512_000
98
+ rescue IO::EAGAINWaitReadable # rubocop:disable Lint/HandleExceptions
99
+ end
100
+ sleep 0.1
101
+ end
102
+ end
103
+ end
104
+
93
105
  def read_stdout(stdout)
94
106
  output = ''
95
107
  5.times do
@@ -102,3 +114,16 @@ def read_stdout(stdout)
102
114
  end
103
115
  output
104
116
  end
117
+
118
+ def wait_for(containers)
119
+ [containers].flatten.each do |container|
120
+ Timeout.timeout(5) do
121
+ begin
122
+ Docker::Container.get container
123
+ rescue Docker::Error::NotFoundError
124
+ sleep 0.5
125
+ retry
126
+ end
127
+ end
128
+ end
129
+ end
data/spec/support/vcr.rb CHANGED
@@ -3,6 +3,7 @@ require 'webmock'
3
3
  require 'docker'
4
4
 
5
5
  VCR.configure do |c|
6
+ ENV['VCR_RECORD_ALL'] == 'true' && c.default_cassette_options = { record: :all }
6
7
  docker_host = URI.parse(Docker.url).host
7
8
  c.allow_http_connections_when_no_cassette = false
8
9
  c.filter_sensitive_data('<USERNAME>') { ENV['DOCKER_API_USER'] }