baha 0.0.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.
Files changed (61) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +156 -0
  7. data/Rakefile +21 -0
  8. data/baha.gemspec +31 -0
  9. data/bin/baha +5 -0
  10. data/example/.gitignore +1 -0
  11. data/example/base/init.sh.erb +11 -0
  12. data/example/base/test-template.erb +22 -0
  13. data/example/example.yml +54 -0
  14. data/example/rvm/image.yml +33 -0
  15. data/example/rvm/init.sh.erb +12 -0
  16. data/lib/baha/builder.rb +130 -0
  17. data/lib/baha/cli.rb +69 -0
  18. data/lib/baha/config.rb +142 -0
  19. data/lib/baha/container_options/cmd.rb +33 -0
  20. data/lib/baha/container_options/entrypoint.rb +10 -0
  21. data/lib/baha/container_options/env.rb +21 -0
  22. data/lib/baha/container_options/exposed_ports.rb +35 -0
  23. data/lib/baha/container_options/invalid_option_error.rb +15 -0
  24. data/lib/baha/container_options/option.rb +59 -0
  25. data/lib/baha/container_options/volumes.rb +24 -0
  26. data/lib/baha/container_options.rb +38 -0
  27. data/lib/baha/image.rb +154 -0
  28. data/lib/baha/log.rb +80 -0
  29. data/lib/baha/pre_build/command.rb +51 -0
  30. data/lib/baha/pre_build/download.rb +28 -0
  31. data/lib/baha/pre_build/template.rb +48 -0
  32. data/lib/baha/pre_build.rb +47 -0
  33. data/lib/baha/version.rb +3 -0
  34. data/lib/baha/workspace.rb +13 -0
  35. data/lib/baha.rb +5 -0
  36. data/spec/builder_spec.rb +103 -0
  37. data/spec/config_spec.rb +93 -0
  38. data/spec/container_options/cmd_spec.rb +46 -0
  39. data/spec/container_options/entrypoint_spec.rb +32 -0
  40. data/spec/container_options/env_spec.rb +26 -0
  41. data/spec/container_options/exposed_ports_spec.rb +32 -0
  42. data/spec/container_options/option_spec.rb +43 -0
  43. data/spec/container_options/volumes_spec.rb +25 -0
  44. data/spec/fixtures/base_image.yml +5 -0
  45. data/spec/fixtures/config_build.yml +12 -0
  46. data/spec/fixtures/config_build_image.yml +10 -0
  47. data/spec/fixtures/config_eachimage.yml +12 -0
  48. data/spec/fixtures/config_embedded.yml +11 -0
  49. data/spec/fixtures/config_include.yml +7 -0
  50. data/spec/fixtures/config_ssl.yml +13 -0
  51. data/spec/fixtures/config_sslpath.yml +11 -0
  52. data/spec/helpers/docker_helpers.rb +31 -0
  53. data/spec/image_spec.rb +167 -0
  54. data/spec/log_spec.rb +89 -0
  55. data/spec/options_spec.rb +52 -0
  56. data/spec/pre_build/command_spec.rb +69 -0
  57. data/spec/pre_build/download_spec.rb +43 -0
  58. data/spec/pre_build/template_spec.rb +55 -0
  59. data/spec/pre_build_spec.rb +29 -0
  60. data/spec/spec_helper.rb +39 -0
  61. metadata +255 -0
@@ -0,0 +1,48 @@
1
+ require 'baha/pre_build'
2
+ require 'erb'
3
+ require 'ostruct'
4
+
5
+ class Baha::PreBuild::Module::Template
6
+ LOG = Baha::Log.for_name("Module::Template")
7
+
8
+ class ErbBinding < OpenStruct
9
+ def initialize(hash,config)
10
+ super(hash)
11
+ @config = config
12
+ end
13
+ def get_binding
14
+ binding()
15
+ end
16
+ def render(file)
17
+ rfile = @config.resolve_file(file) || @config.resolve_file(File.join(name,file))
18
+ if rfile
19
+ ERB.new(File.read(rfile),0,'-').result(binding)
20
+ else
21
+ raise ArgumentError.new("Template unable to render #{file}: not found")
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.execute(mod)
27
+ LOG.debug("template(#{mod.args.inspect})")
28
+
29
+ template = mod.args['template']
30
+ src = mod.config.resolve_file(mod.args['template'])
31
+ dest = mod.image.workspace + mod.args['dest']
32
+ raise ArgumentError.new("Unable to find template file #{template}") if src.nil?
33
+ LOG.info { "Loading template #{src}" }
34
+ template_str = File.read(src)
35
+ erb = ERB.new(template_str,0,'-')
36
+ environment = mod.image.env
37
+ environment.merge!(Hash[mod.args.map{|k,v| [k.to_sym, v]}])
38
+ LOG.debug { "template environment: #{environment.inspect}" }
39
+ LOG.info { "Writing to #{dest}" }
40
+ File.open(dest,"w") do |f|
41
+ f.write(erb.result(ErbBinding.new(environment,mod.config).get_binding))
42
+ end
43
+ end
44
+ end
45
+
46
+ Baha::PreBuild::Module.register(:template) do |mod|
47
+ Baha::PreBuild::Module::Template.execute(mod)
48
+ end
@@ -0,0 +1,47 @@
1
+ module Baha::PreBuild
2
+ LOG = Baha::Log.for_name(self.class.name)
3
+ class ModuleNotFoundError < StandardError
4
+ attr_reader :task
5
+ def initialize(task)
6
+ super("Could not find a module that could parse #{task.inspect}")
7
+ @task = task
8
+ end
9
+ end
10
+ class Module
11
+ class << self
12
+ @@modules = []
13
+
14
+ def register(name, options = {}, &block)
15
+ LOG.debug { "register module #{name} (#{options.inspect})" }
16
+ @@modules << name
17
+ name = name.intern
18
+ send(:define_singleton_method,"module_#{name}",&block)
19
+ end
20
+
21
+ def execute(task)
22
+ @@modules.each do |mod|
23
+ if task.has_key?(mod.to_s)
24
+ LOG.info { "Executing module #{mod}" }
25
+ method = "module_#{mod}".intern
26
+ self.send(method, Module.new(task))
27
+ return
28
+ end
29
+ end
30
+ raise ModuleNotFoundError.new(task)
31
+ end
32
+ end
33
+
34
+ attr_reader :config, :image, :args
35
+
36
+ def initialize(task)
37
+ @config = task.delete(:config)
38
+ @image = task.delete(:image)
39
+ @args = task
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ require 'baha/pre_build/download'
46
+ require 'baha/pre_build/template'
47
+ require 'baha/pre_build/command'
@@ -0,0 +1,3 @@
1
+ module Baha
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'docker'
2
+ module Baha
3
+ class Workspace
4
+
5
+ attr_reader :directory
6
+
7
+ def initialize(options)
8
+ @options = {}
9
+ @options.merge!(options)
10
+ @directory = @options['directory'] || Dir.pwd
11
+ end
12
+ end
13
+ end
data/lib/baha.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'baha/version'
2
+ require 'baha/container_options'
3
+ require 'baha/image'
4
+ require 'baha/config'
5
+ require 'baha/log'
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+ require 'baha/config'
3
+ require 'baha/builder'
4
+ require 'fileutils'
5
+
6
+ describe Baha::Builder do
7
+ let(:config) do
8
+ Baha::Config.load(fixture('config_build.yml'))
9
+ end
10
+ subject { described_class.new(config) }
11
+
12
+ describe "#new" do
13
+ it 'loads config file from filename' do
14
+ expect { described_class.new(fixture('config_build.yml')) }.not_to raise_error
15
+ end
16
+ end
17
+
18
+ describe "#inspect" do
19
+ its(:inspect) { should match(/^Baha::Builder<(@[a-z0-9_]+=.*)+>$/) }
20
+ end
21
+
22
+ describe "#build!" do
23
+ before do
24
+ allow_any_instance_of(Baha::Config).to receive(:init_docker!)
25
+ allow(Baha::PreBuild::Module).to receive(:execute)
26
+ allow(FileUtils).to receive(:mkdir_p)
27
+ end
28
+ context "when no update needed" do
29
+ before do
30
+ allow_any_instance_of(Baha::Image).to receive(:needs_update?).and_return(false)
31
+ subject.build!
32
+ end
33
+ it 'does not execute pre_build' do
34
+ expect(Baha::PreBuild::Module).not_to have_received(:execute)
35
+ end
36
+ end
37
+ context "when update needed" do
38
+ let(:container) {
39
+ double('container')
40
+ }
41
+ let(:image) {
42
+ double('image')
43
+ }
44
+ let(:image2) {
45
+ double('image2')
46
+ }
47
+ before do
48
+ allow_any_instance_of(Baha::Image).to receive(:needs_update?).and_return(true)
49
+ allow_any_instance_of(Baha::Image).to receive(:parent_id).and_return('AAAA')
50
+ allow(Docker::Container).to receive(:create).and_return(container)
51
+ allow(container).to receive(:start)
52
+ allow(container).to receive(:stop)
53
+ allow(container).to receive(:streaming_logs).with({"stdout"=>true, "stderr"=>true, "follow"=>true, "timestamps"=>false}).and_yield(:stdout,"console message").and_yield(:stderr,"error line")
54
+ allow(container).to receive(:wait).with(1200).and_return({'StatusCode' => 0})
55
+ allow(container).to receive(:commit).and_return(image)
56
+ allow(image).to receive(:id).and_return('BBBB')
57
+ allow(Docker::Image).to receive(:get).with('BBBB').and_return(image)
58
+ allow(image).to receive(:tag)
59
+ allow(container).to receive(:remove)
60
+ end
61
+ it 'executes pre_build step' do
62
+ subject.build!
63
+ expect(Baha::PreBuild::Module).to have_received(:execute).twice.with(hash_including('download' => "http://www.google.com"))
64
+ end
65
+ it 'creates containers' do
66
+ subject.build!
67
+ expect(Docker::Container).to have_received(:create).twice.with({"Image"=>"AAAA", "Cmd"=>["/bin/bash", "./init.sh"], "Workingdir"=>"/.baha"})
68
+ end
69
+ it 'starts containers' do
70
+ subject.build!
71
+ expect(container).to have_received(:start).twice
72
+ end
73
+ it 'commits containers' do
74
+ subject.build!
75
+ expect(container).to have_received(:commit).with({"run"=>{"ExposedPorts"=>{"8080/tcp"=>{}}}}).ordered
76
+ expect(container).to have_received(:commit).with({'run' => {}}).ordered
77
+ end
78
+ it 'tags image' do
79
+ subject.build!
80
+ expect(image).to have_received(:tag).with({:repo=>"docker.example.com/baha/base", :tag=>"1.0.0"})
81
+ expect(image).to have_received(:tag).with({:repo=>"docker.example.com/baha/base", :tag=>"latest"})
82
+ expect(image).to have_received(:tag).with({:repo=>"base", :tag=>"1.0.0"})
83
+ expect(image).to have_received(:tag).with({:repo=>"base", :tag=>"latest"})
84
+ expect(image).to have_received(:tag).with({:repo=>"docker.example.com/baha/derived", :tag=>"1.0.0"})
85
+ expect(image).to have_received(:tag).with({:repo=>"docker.example.com/baha/derived", :tag=>"latest"})
86
+ expect(image).to have_received(:tag).with({:repo=>"derived", :tag=>"1.0.0"})
87
+ expect(image).to have_received(:tag).with({:repo=>"derived", :tag=>"latest"})
88
+ end
89
+ context "when error building image" do
90
+ before do
91
+ allow(container).to receive(:wait).with(1200).and_return({'StatusCode' => 1})
92
+ end
93
+ it { expect { subject.build! }.to raise_error(Baha::Builder::BuildError) }
94
+ end
95
+ context "when exception building image" do
96
+ before do
97
+ allow(container).to receive(:wait).with(1200).and_raise(Exception)
98
+ end
99
+ it { expect { subject.build! }.to raise_error(Baha::Builder::BuildError) }
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+ require 'baha/config'
3
+
4
+ describe Baha::Config do
5
+ before do
6
+ ENV['DOCKER_CERT_PATH'] = nil
7
+ ENV['DOCKER_TLS_VERIFY'] = nil
8
+ end
9
+ describe "#load" do
10
+ context "with embedded images" do
11
+ subject { Baha::Config.load(fixture('config_embedded.yml')) }
12
+ its(:defaults) { should eq(
13
+ {
14
+ :parent=>"ubuntu:14.04.1",
15
+ :bind=>"/.baha",
16
+ :repository=>'docker.example.com/baha',
17
+ :maintainer => "Ishmael <ishmael@example.com>",
18
+ :command => ['/bin/bash','./init.sh'],
19
+ :timeout => 1200
20
+ })
21
+ }
22
+ its(:options) { should eq({}) }
23
+ its(:configdir) { should eq(fixture_path) }
24
+ its(:workspace) { should eq(fixture_path + 'workspace') }
25
+ end
26
+ context "with included image files" do
27
+ subject { Baha::Config.load(fixture('config_include.yml')) }
28
+ its(:defaults) { should eq(
29
+ {
30
+ :parent=>"ubuntu:14.04.1",
31
+ :bind=>"/.baha",
32
+ :repository=>'docker.example.com/baha',
33
+ :maintainer => "Ishmael <ishmael@example.com>",
34
+ :command => ['/bin/bash','./init.sh'],
35
+ :timeout => 1200
36
+ })
37
+ }
38
+ its(:options) { should eq({}) }
39
+ its(:configdir) { should eq(fixture_path) }
40
+ its(:workspace) { should eq(fixture_path + 'workspace') }
41
+ end
42
+ context "with DOCKER_CERT_PATH set" do
43
+ subject { Baha::Config.load(fixture('config_embedded.yml')) }
44
+ before do
45
+ ENV['DOCKER_CERT_PATH'] = '/tmp'
46
+ ENV['DOCKER_TLS_VERIFY'] = nil
47
+ end
48
+ its(:options) { should eq({:client_cert=>"/tmp/cert.pem", :client_key=>"/tmp/key.pem", :ssl_ca_file=>"/tmp/ca.pem", :ssl_verify_peer=>false}) }
49
+ its(:secure) { should eq(true) }
50
+ context "with DOCKER_TLS_VERIFY=1" do
51
+ before do
52
+ ENV['DOCKER_CERT_PATH'] = '/tmp'
53
+ ENV['DOCKER_TLS_VERIFY'] = '1'
54
+ end
55
+ its(:options) { should eq({:client_cert=>"/tmp/cert.pem", :client_key=>"/tmp/key.pem", :ssl_ca_file=>"/tmp/ca.pem", :ssl_verify_peer=>true}) }
56
+ end
57
+ end
58
+ context "with ssl in config" do
59
+ subject { Baha::Config.load(fixture('config_ssl.yml')) }
60
+ its(:options) { should eq({:client_cert=>"cert.pem", :client_key=>"key.pem", :ssl_ca_file=>"ca.pem", :ssl_verify_peer=>true}) }
61
+ its(:secure) { should eq(true) }
62
+ end
63
+ context "with ssl cert_path" do
64
+ subject { Baha::Config.load(fixture('config_sslpath.yml')) }
65
+ its(:options) { should eq({:client_cert=>"/ssl/cert.pem", :client_key=>"/ssl/key.pem", :ssl_ca_file=>"/ssl/ca.pem", :ssl_verify_peer=>true}) }
66
+ its(:secure) { should eq(true) }
67
+ end
68
+ end
69
+ describe "#init_docker!" do
70
+ subject { Baha::Config.load(fixture('config_ssl.yml')) }
71
+ before do
72
+ allow(Docker).to receive(:validate_version!)
73
+ subject.init_docker!
74
+ end
75
+ it { expect(Docker).to have_received(:validate_version!) }
76
+ it { expect(Docker.url).to eq('https://127.0.1.1:2375') }
77
+ it { expect(Docker.options).to eq({:client_cert=>"cert.pem", :client_key=>"key.pem", :ssl_ca_file=>"ca.pem", :ssl_verify_peer=>true}) }
78
+ end
79
+ describe "#inspect" do
80
+ subject { Baha::Config.load(fixture('config_embedded.yml')) }
81
+ its(:inspect) { should match(/^Baha::Config<(@[a-z0-9_]+=.*)+>$/) }
82
+ end
83
+ describe "#each_image" do
84
+ subject { Baha::Config.load(fixture('config_eachimage.yml')) }
85
+ it 'loads images it can find' do
86
+ images = []
87
+ subject.each_image do |image|
88
+ images << image
89
+ end
90
+ expect(images.size).to eq(2)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'baha/container_options'
3
+
4
+ describe Baha::ContainerOptions::Cmd do
5
+ subject(:option) { described_class.new(["/bin/bash","-l"]) }
6
+ subject(:option2) { described_class.new('/bin/bash -l') }
7
+ describe 'validate!' do
8
+ subject(:invalid) { described_class.new(123) }
9
+ it 'validates on array values' do
10
+ expect { option.validate! }.to_not raise_error
11
+ end
12
+ it 'validates on string values' do
13
+ expect { option2.validate! }.to_not raise_error
14
+ end
15
+ it 'does not validate other values' do
16
+ expect { invalid.validate! }.to raise_error(Baha::ContainerOptions::InvalidOptionError)
17
+ end
18
+ end
19
+ describe 'apply' do
20
+ let(:expected) { { 'Cmd' => ["/bin/bash","-l"] } }
21
+ it 'applies array command' do
22
+ conf = {}
23
+ option.apply(conf)
24
+ expect(conf).to eq(expected)
25
+ end
26
+ it 'applies string command' do
27
+ conf = {}
28
+ option2.apply(conf)
29
+ expect(conf).to eq(expected)
30
+ end
31
+ end
32
+ describe 'split_command' do
33
+ it 'splits on spaces' do
34
+ expect(described_class.split_command('/bin/bash -l')).to eq(['/bin/bash','-l'])
35
+ end
36
+ it 'splits on multiple spaces' do
37
+ expect(described_class.split_command('/bin/bash -l')).to eq(['/bin/bash','-l'])
38
+ end
39
+ it 'does not split quotes' do
40
+ expect(described_class.split_command('/bin/bash -l echo "Hello, World!"')).to eq(['/bin/bash','-l','echo','Hello, World!'])
41
+ end
42
+ it 'does not squash escaped quotes' do
43
+ expect(described_class.split_command('/bin/bash -l echo "Hello, ""World!"')).to eq(['/bin/bash','-l','echo','Hello, "World!'])
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'baha/container_options'
3
+
4
+ describe Baha::ContainerOptions::Entrypoint do
5
+ subject(:option) { described_class.new(["/bin/bash","-l"]) }
6
+ subject(:option2) { described_class.new('/bin/bash -l') }
7
+ describe 'validate!' do
8
+ subject(:invalid) { described_class.new(123) }
9
+ it 'validates on array values' do
10
+ expect { option.validate! }.to_not raise_error
11
+ end
12
+ it 'validates on string values' do
13
+ expect { option2.validate! }.to_not raise_error
14
+ end
15
+ it 'does not validate other values' do
16
+ expect { invalid.validate! }.to raise_error(Baha::ContainerOptions::InvalidOptionError)
17
+ end
18
+ end
19
+ describe 'apply' do
20
+ let(:expected) { { 'Entrypoint' => ["/bin/bash","-l"] } }
21
+ it 'applies array command' do
22
+ conf = {}
23
+ option.apply(conf)
24
+ expect(conf).to eq(expected)
25
+ end
26
+ it 'applies string command' do
27
+ conf = {}
28
+ option2.apply(conf)
29
+ expect(conf).to eq(expected)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'baha/container_options'
3
+
4
+ describe Baha::ContainerOptions::Env do
5
+ subject(:option) { described_class.new({'KEY' => 'value'}) }
6
+
7
+ describe 'validate!' do
8
+ let(:invalid) { described_class.new('value') }
9
+
10
+ it 'validates on hash values' do
11
+ expect { option.validate! }.to_not raise_error
12
+ end
13
+ it 'does not validate non-hash values' do
14
+ expect { invalid.validate! }.to raise_error(Baha::ContainerOptions::InvalidOptionError)
15
+ end
16
+ end
17
+
18
+ describe 'apply' do
19
+ let(:expected) { { 'Env' => ['KEY=value'] } }
20
+ it 'applies its key=value pair' do
21
+ conf = {}
22
+ option.apply(conf)
23
+ expect(conf).to eq(expected)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'baha/container_options'
3
+
4
+ describe Baha::ContainerOptions::ExposedPorts do
5
+ subject(:option) { described_class.new([8080]) }
6
+ subject(:option2) { described_class.new(['8080/tcp']) }
7
+ describe 'validate!' do
8
+ subject(:invalid) { described_class.new(['wtf']) }
9
+ it 'validates on num values' do
10
+ expect { option.validate! }.to_not raise_error
11
+ end
12
+ it 'validates on string values' do
13
+ expect { option2.validate! }.to_not raise_error
14
+ end
15
+ it 'does not validate other values' do
16
+ expect { invalid.validate! }.to raise_error(Baha::ContainerOptions::InvalidOptionError)
17
+ end
18
+ end
19
+ describe 'apply' do
20
+ let(:expected) { { 'ExposedPorts' => { '8080/tcp' => {} } } }
21
+ it 'applies array command' do
22
+ conf = {}
23
+ option.apply(conf)
24
+ expect(conf).to eq(expected)
25
+ end
26
+ it 'applies string command' do
27
+ conf = {}
28
+ option2.apply(conf)
29
+ expect(conf).to eq(expected)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'baha/container_options'
3
+
4
+ describe Baha::ContainerOptions::Option do
5
+ subject(:option) { described_class.new('hostname','value') }
6
+ let(:other) { described_class.new("hostname","value") }
7
+ let(:otherkey) { described_class.new("user","value") }
8
+
9
+ describe '#eql?' do
10
+ it 'is equal to same key' do
11
+ expect(option.eql?(other)).to eq(true)
12
+ end
13
+ it 'is not equal to other key' do
14
+ expect(option.eql?(otherkey)).to eq(false)
15
+ end
16
+ end
17
+
18
+ describe '#validate!' do
19
+ it 'always validates' do
20
+ expect(option.validate!).to eq(true)
21
+ end
22
+ end
23
+
24
+ describe '#apply' do
25
+ it 'applies its key/value pair' do
26
+ conf = {}
27
+ option.apply(conf)
28
+ expect(conf['Hostname']).to eq('value')
29
+ end
30
+ end
31
+
32
+ describe '#inspect' do
33
+ its(:inspect) { should match(/Baha::ContainerOptions::Option<(@[a-z0-9_]+=.*)+>/) }
34
+ end
35
+
36
+ it 'has a sym key' do
37
+ expect(option.key).to be_a(Symbol)
38
+ end
39
+
40
+ it 'has a value' do
41
+ expect(option.value).to eq('value')
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'baha/container_options'
3
+
4
+ describe Baha::ContainerOptions::Volumes do
5
+ subject(:option) { described_class.new(["/mnt/data","/mnt/logs"]) }
6
+
7
+ describe 'validate!' do
8
+ subject(:invalid) { described_class.new("value") }
9
+ it 'validates on hash values' do
10
+ expect { option.validate! }.to_not raise_error
11
+ end
12
+ it 'does not validate non-hash values' do
13
+ expect { invalid.validate! }.to raise_error(Baha::ContainerOptions::InvalidOptionError)
14
+ end
15
+ end
16
+
17
+ describe 'apply' do
18
+ let(:expected) { { 'Volumes' => {'/mnt/data' => {}, '/mnt/logs' => {} } } }
19
+ it 'applies volume config' do
20
+ conf = {}
21
+ option.apply(conf)
22
+ expect(conf).to eq(expected)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ parent: 'ubuntu:14.04.1'
3
+ name: base
4
+ tag: 1.0.0
5
+ maintainer: '"Captain Ahab" <ahab@example.com>'
@@ -0,0 +1,12 @@
1
+ ---
2
+ defaults:
3
+ parent: ubuntu:14.04.1
4
+ repository: docker.example.com/baha
5
+ maintainer: Ishmael <ishmael@example.com>
6
+ images:
7
+ - include: config_build_image.yml
8
+ - parent: 'base:1.0.0'
9
+ name: derived
10
+ tag: 1.0.0
11
+ pre_build:
12
+ - { download: 'http://www.google.com', file: 'myfile.txt' }
@@ -0,0 +1,10 @@
1
+ ---
2
+ parent: 'ubuntu:14.04.1'
3
+ name: base
4
+ tag: 1.0.0
5
+ maintainer: '"Captain Ahab" <ahab@example.com>'
6
+ pre_build:
7
+ - { download: 'http://www.google.com', file: 'myfile.txt' }
8
+ config:
9
+ exposedports:
10
+ - 8080
@@ -0,0 +1,12 @@
1
+ ---
2
+ defaults:
3
+ parent: ubuntu:14.04.1
4
+ repository: docker.example.com/baha
5
+ maintainer: Ishmael <ishmael@example.com>
6
+ images:
7
+ - include: base_image.yml
8
+ - include: no_such_file_exists.yml
9
+ - parent: 'ubuntu:14.04.1'
10
+ name: base
11
+ tag: 1.0.0
12
+ maintainer: '"Captain Ahab" <ahab@example.com>'
@@ -0,0 +1,11 @@
1
+ ---
2
+ docker_url: unix:///var/run/docker.sock
3
+ defaults:
4
+ parent: ubuntu:14.04.1
5
+ repository: docker.example.com/baha
6
+ maintainer: Ishmael <ishmael@example.com>
7
+ images:
8
+ - parent: 'ubuntu:14.04.1'
9
+ name: base
10
+ tag: 1.0.0
11
+ maintainer: '"Captain Ahab" <ahab@example.com>'
@@ -0,0 +1,7 @@
1
+ ---
2
+ defaults:
3
+ parent: ubuntu:14.04.1
4
+ repository: docker.example.com/baha
5
+ maintainer: Ishmael <ishmael@example.com>
6
+ images:
7
+ - include: base_image.yml
@@ -0,0 +1,13 @@
1
+ ---
2
+ docker_url: tcp://127.0.1.1:2375
3
+ defaults:
4
+ parent: ubuntu:14.04.1
5
+ repository: docker.example.com/baha
6
+ maintainer: Ishmael <ishmael@example.com>
7
+ ssl:
8
+ key: key.pem
9
+ cert: cert.pem
10
+ ca: ca.pem
11
+ verify: true
12
+ images:
13
+ - include: base_image.yml
@@ -0,0 +1,11 @@
1
+ ---
2
+ docker_url: tcp://127.0.1.1:2375
3
+ defaults:
4
+ parent: ubuntu:14.04.1
5
+ repository: docker.example.com/baha
6
+ maintainer: Ishmael <ishmael@example.com>
7
+ ssl:
8
+ cert_path: '/ssl'
9
+ verify: true
10
+ images:
11
+ - include: base_image.yml
@@ -0,0 +1,31 @@
1
+ module DockerHelpers
2
+ require 'docker'
3
+ def mock_registry(images)
4
+ allow(Docker::Image).to receive(:create).and_raise(RuntimeError)
5
+ allow(Docker::Image).to receive(:get).and_raise(RuntimeError)
6
+ images.each do |image|
7
+ i = double("image-#{image[:id]}")
8
+ allow(i).to receive(:id) { image[:id] }
9
+ allow(i).to receive(:info) do
10
+ { 'Parent' => image[:parent] }
11
+ end
12
+ allow(i).to receive(:history) do
13
+ [{'Tags' => image[:tags] }]
14
+ end
15
+ name = "#{image[:name]}:#{image[:tag]}"
16
+ if image[:pulled]
17
+ allow(Docker::Image).to receive(:get).with(name).and_return(i)
18
+ else
19
+ allow(Docker::Image).to receive(:get).with(name).and_raise(RuntimeError)
20
+ allow(Docker::Image).to receive(:create).with('fromImage'=>image[:name], 'tag' =>image[:tag]).and_raise(RuntimeError)
21
+ end
22
+ allow(Docker::Image).to receive(:get).with(image[:id]).and_return(i)
23
+ if image[:tags]
24
+ image[:tags].each do |tag|
25
+ t = tag.split(':')
26
+ allow(Docker::Image).to receive(:create).with('fromImage'=>t[0], 'tag' =>t[1]).and_return(i)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end