baha 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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