docker-dev 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.
data/lib/docker.rb ADDED
@@ -0,0 +1,124 @@
1
+ require_relative 'docker/rake'
2
+ require_relative 'docker/helpers'
3
+ require_relative 'docker/interactive'
4
+ require_relative 'docker/equality'
5
+ require_relative 'docker/path'
6
+ require_relative 'docker/id'
7
+
8
+ require_relative 'docker/image'
9
+ require_relative 'docker/repository'
10
+ require_relative 'docker/tag'
11
+ require_relative 'docker/container'
12
+ require_relative 'docker/inspect'
13
+
14
+ require_relative 'docker/rails'
15
+ require_relative 'docker/rails/server'
16
+ require_relative 'docker/rails/console'
17
+ require_relative 'docker/ruby'
18
+ require_relative 'docker/postgres'
19
+
20
+ module Docker
21
+
22
+ extend Helpers
23
+ extend self
24
+
25
+ USER_NAME = 'jphager2'
26
+
27
+ def ID(input)
28
+ case input
29
+ when String
30
+ Id.create(input)
31
+ when ->(obj){obj.respond_to?(:id)}
32
+ Id.create(input.id)
33
+ end
34
+ end
35
+
36
+ def PATH(input)
37
+ case input
38
+ when String
39
+ Path.new(input)
40
+ when Path
41
+ input
42
+ end
43
+ end
44
+
45
+ # delegate to Image
46
+ def build(app_path, image_tag = nil)
47
+ path = PATH(app_path)
48
+ image_tag ||= path.name
49
+ Image.build(path, image_tag)
50
+ end
51
+
52
+ # delegate to Container
53
+ def run(image, options = "", command = "")
54
+ Container.run(image.to_s, options, command)
55
+ end
56
+
57
+ def images(response_type = :image)
58
+ images = `docker images`.split("\n")[1..-1]
59
+ images.map do |image|
60
+ id = image.match(/^[^\s]+\s+[^\s]+\s+([^\s]+)/)[1]
61
+ repo = image.match(/^[a-zA-Z0-9\/\-_\.<>]+/)[0]
62
+ tag = image.match(/^[^\s]+\s+([^\s]+)/)[1]
63
+ case response_type
64
+ when :repository
65
+ Repository.new(id, repo)
66
+ when :tag
67
+ Tag.new(id, repo, tag)
68
+ when :image
69
+ Image.new(id)
70
+ end
71
+ end
72
+ end
73
+
74
+ def inspekt(id)
75
+ inspekt = Inspect.new(id.to_s)
76
+ inspekt.inspekt ? inspekt : NullInspect.new
77
+ end
78
+
79
+ def find_container(options = {})
80
+ containers.find do |container|
81
+ found = true
82
+ options.each do |option,value|
83
+ found = false unless container.send(option) == value
84
+ end
85
+ found
86
+ end
87
+ end
88
+
89
+ def find_containers(options = {})
90
+ klass = options.delete(:klass)
91
+ kontainers = containers
92
+ kontainers.map! { |container| klass.load_from(container) } if klass
93
+ kontainers.select { |container|
94
+ found = true
95
+ options.each do |option, value|
96
+ found = false unless container.send(option) === value
97
+ end
98
+ found
99
+ }.compact
100
+ end
101
+
102
+ def containers(mode = :all)
103
+ containers = case mode
104
+ when :all
105
+ all_containers
106
+ when :stopped
107
+ all_containers.select { |container| container =~ /Exited/ }
108
+ when :paused
109
+ all_containers.select { |container| container =~ /(Paused)/ }
110
+ when :running
111
+ `docker ps`.split("\n")[1..-1]
112
+ .select { |container| container !~ /(Paused)/}
113
+ else
114
+ raise ArgumentError, "Bad Argument: #{mode}"
115
+ end
116
+ containers.map do |container|
117
+ Container.new(container[0..11]).to_klass
118
+ end
119
+ end
120
+
121
+ def all_containers
122
+ `docker ps -a`.split("\n")[1..-1]
123
+ end
124
+ end
data/rakefile ADDED
@@ -0,0 +1,6 @@
1
+ load 'helpers.rake'
2
+
3
+ desc 'Run all docker tests'
4
+ task :tests do
5
+ Dir['test/docker*_test.rb'].each { |file| puts `ruby #{file}` }
6
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'test_helper'
2
+
3
+ class CleanupTest < Minitest::Test
4
+
5
+ def setup
6
+ Docker::App.run(TEST_APP_PATH)
7
+ Docker::App.cleanup!
8
+ @running = `docker ps`
9
+ @stopped = `docker ps -s`
10
+ end
11
+
12
+ def test_app_is_stopped
13
+ refute_match /rails-server-app/, @running
14
+ end
15
+
16
+ def test_postgres_is_stopped
17
+ refute_match /\sdb\s/, @running
18
+ end
19
+
20
+ def test_app_is_removed
21
+ refute_match /rails-server-app/, @stopped
22
+ end
23
+
24
+ def test_postgres_is_removed
25
+ refute_match /\sdb\s/, @stopped
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ require_relative 'test_helper'
2
+ require 'stringio'
3
+
4
+ class AppRunTest < Minitest::Test
5
+
6
+ def test_can_run_a_rails_app
7
+ assert Docker::App.run(TEST_APP_PATH),
8
+ 'Docker::App.run should return something truthy'
9
+ end
10
+
11
+ def test_a_running_app_prints_out_the_rails_app_ip
12
+ skip
13
+ out, $stdout = $stdout, StringIO.new
14
+ Docker::App.run(TEST_APP_PATH)
15
+ out.rewind
16
+ assert_match /\s\d+\.\d+\.\d+\.\d+\.:\d+\s/, out.read
17
+ $stdout = out
18
+ end
19
+
20
+ def test_a_running_app_results_in_a_running_docker_container
21
+ Docker::App.run(TEST_APP_PATH)
22
+ containers = `docker ps`
23
+ assert_match /rails-server-app/, containers
24
+ end
25
+
26
+ def test_a_running_app_starts_a_postgres_container
27
+ Docker::App.run(TEST_APP_PATH)
28
+ containers = `docker ps`
29
+ assert_match /postgres/, containers
30
+ assert_match /\sdb/, containers
31
+ end
32
+
33
+ def teardown
34
+ TestHelper.remove_containers
35
+ `docker run --rm -v /home/john/projects/docker/rails/app:/usr/src/app jphager2/rails-app chmod -R a+rw /usr/src/app`
36
+ `rm -rf #{TEST_APP_PATH}/tmp/*`
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'test_helper'
2
+
3
+
4
+ class AppStopTest < Minitest::Test
5
+
6
+ def setup
7
+ Docker::App.run(TEST_APP_PATH)
8
+ Docker::App.stop(TEST_APP_PATH)
9
+ @running = `docker ps`
10
+ @stopped = `docker ps -s`
11
+ end
12
+
13
+ def test_app_is_stopped
14
+ refute_match /rails-server-app/, @running
15
+ end
16
+
17
+ def test_app_is_removed
18
+ refute_match /rails-server-app/, @stopped
19
+ end
20
+
21
+ def test_postgres_is_still_running
22
+ assert_match /\spostgres/, @running
23
+ end
24
+
25
+ def test_tmp_directory_is_empty
26
+ assert_empty Dir["#{TEST_APP_PATH}/tmp/*"]
27
+ end
28
+
29
+ def teardown
30
+ TestHelper.remove_containers
31
+ end
32
+ end
33
+
34
+
@@ -0,0 +1,28 @@
1
+ require_relative 'test_helper'
2
+
3
+ class BuildTest < MiniTest::Unit::TestCase
4
+
5
+ def self.before_suite
6
+ end
7
+
8
+ def self.after_suite
9
+ end
10
+
11
+ def setup
12
+ if `docker images` =~ /#{Docker::USER_NAME}\/app/
13
+ `docker rmi #{Docker::USER_NAME}/app`
14
+ end
15
+ end
16
+
17
+ def test_can_build_a_rails_app
18
+ assert_kind_of Docker::Image, Docker.build(TEST_APP_PATH)
19
+ end
20
+
21
+ def test_building_app_results_in_a_docker_image
22
+ Docker.build(TEST_APP_PATH)
23
+ images = `docker images`
24
+ assert_match(/#{Docker::USER_NAME}\/app/, images)
25
+ end
26
+ end
27
+
28
+
@@ -0,0 +1,115 @@
1
+ require_relative 'test_helper'
2
+
3
+ class ContainerTest < MiniTest::Unit::TestCase
4
+
5
+ def self.before_suite
6
+ @@name = 'posty-post'
7
+ @@container = TestHelper.setup_posty(@@name)
8
+ end
9
+
10
+ def self.after_suite
11
+ TestHelper.teardown_posty(@@name)
12
+ end
13
+
14
+ def test_a_container_that_exits_has_an_id
15
+ container = Docker.run('ubuntu:14.04',nil,'/bin/bash')
16
+ assert_match /[a-z0-9]+/, container.id
17
+ refute_match /[^a-z0-9]/, container.id
18
+ container.remove!
19
+ end
20
+
21
+ def test_a_container_run_with_rm_flag_that_exits_returns_removed
22
+ container = Docker.run('ubuntu:14.04', '--rm', '/bin/bash')
23
+ assert_equal "REMOVED", container.id
24
+ end
25
+
26
+ def test_a_container_that_echos_to_stdout_has_an_id
27
+ container = Docker.run('ubuntu:14.04',nil,'echo "hello"')
28
+ assert_match /[a-z0-9]+/, container.id
29
+ refute_match /[^a-z0-9]/, container.id
30
+ container.remove!
31
+ end
32
+
33
+ def test_container_has_an_id
34
+ assert_match /[a-z0-9]+/, @@container.id
35
+ refute_match /[^a-z0-9]/, @@container.id
36
+ assert_equal 12, @@container.id.length
37
+ end
38
+
39
+ def test_stopped_container_is_stopped
40
+ @@container.stop!
41
+ assert @@container.stopped?
42
+ `docker start #{@@name}`
43
+ end
44
+
45
+ def test_container_is_up
46
+ assert @@container.up?
47
+ end
48
+
49
+ def test_container_is_not_up_when_stopped
50
+ @@container.stop!
51
+ refute @@container.up?
52
+ `docker start #{@@name}`
53
+ end
54
+
55
+ def test_container_is_not_up_when_paused
56
+ @@container.pause!
57
+ refute @@container.up?
58
+ `docker unpause #{@@name}`
59
+ end
60
+
61
+ def test_container_is_paused
62
+ @@container.pause!
63
+ assert @@container.paused?
64
+ `docker unpause #{@@name}`
65
+ end
66
+
67
+ def test_stopped_container_starts
68
+ @@container.stop!
69
+ @@container.start!
70
+ assert @@container.up?
71
+ end
72
+
73
+ def test_running_container_restarts
74
+ @@container.restart!
75
+ assert @@container.up?
76
+ end
77
+
78
+ def test_container_unpauses
79
+ @@container.pause!
80
+ @@container.unpause!
81
+ assert @@container.up?
82
+ end
83
+
84
+ def test_docker_inspect_returns_inspect_object
85
+ assert_instance_of Docker::Inspect, @@container.inspekt
86
+ end
87
+
88
+ def test_container_remove_removes_the_container
89
+ shorty = TestHelper.setup_posty('shorty')
90
+ shorty.remove!
91
+ refute Docker.containers.any? { |container| container == shorty }
92
+ end
93
+
94
+ def test_container_can_add_removal_instructions
95
+ shorty = TestHelper.setup_posty('shorty')
96
+ shorty.add_removal_instructions do |container|
97
+ ENV["SHORTY_IP"] = container.ip
98
+ end
99
+ assert shorty.removal_instructions,
100
+ 'Shorty should have removal instructions'
101
+ shorty.remove!
102
+ assert ENV["SHORTY_IP"], 'ENV["SHORTY_IP"] should by truthy'
103
+ end
104
+
105
+ def test_removed_container_has_methods_disabled
106
+ shorty = TestHelper.setup_posty('shorty')
107
+ shorty.remove!
108
+ [:stop!, :start!, :restart!, :pause!, :unpause!, :remove!]
109
+ .each do |method|
110
+ assert_raises(NoMethodError) do
111
+ shorty.send(method)
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'test_helper'
2
+
3
+ class ImageTest < MiniTest::Unit::TestCase
4
+
5
+ def self.before_suite
6
+ @@images = Docker.images
7
+ end
8
+
9
+ def self.after_suite
10
+ end
11
+
12
+ def test_image_has_id
13
+ @@images.each do |image|
14
+ refute_match /[\W\.\s\/\|:]/, image.id
15
+ refute_match /[A-Z]/, image.id
16
+ end
17
+ end
18
+
19
+ def test_image_can_be_removed
20
+ image = Docker.build(TEST_APP_PATH)
21
+ id = image.id
22
+ image.remove!
23
+ images = `docker images`
24
+ refute_match /#{id}/, images
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'test_helper'
2
+
3
+ class InspectTest < MiniTest::Unit::TestCase
4
+
5
+ def self.before_suite
6
+ @@name = 'posty-post'
7
+ @@container = TestHelper.setup_posty(@@name)
8
+ @@inspect = Docker.inspekt(@@container.id)
9
+ end
10
+
11
+ def self.after_suite
12
+ TestHelper.teardown_posty(@@name)
13
+ end
14
+
15
+ def test_inspect_gives_container_ip
16
+ assert_match /\d+\.\d+\.\d\.\d/, @@inspect.ip_address
17
+ end
18
+
19
+ def test_inspect_gives_ports
20
+ ports = @@inspect.ports
21
+ assert_instance_of Hash, ports
22
+ refute_empty ports
23
+ end
24
+
25
+ def test_inspect_gives_name
26
+ assert_match /#{@@name}/, @@inspect.name
27
+ end
28
+
29
+ def test_inspect_gives_state
30
+ assert @@inspect.state["Running"]
31
+ end
32
+
33
+ def test_inspect_gives_state_of_stopped_container
34
+ @@container.stop!
35
+ inspect = Docker.inspekt(@@container.id)
36
+ refute inspect.state["Running"]
37
+ @@container.start!
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'test_helper'
2
+
3
+ class PostgresTest < MiniTest::Unit::TestCase
4
+
5
+ def self.before_suite
6
+ @@posty = Docker::Postgres.run('posty')
7
+ end
8
+
9
+ def self.after_suite
10
+ @@posty.remove!
11
+ end
12
+
13
+ def test_can_run_a_postgres_container
14
+ assert @@posty.up?
15
+ end
16
+
17
+ def test_gets_current_postgres_contianer_if_one_exists
18
+ posty2 = Docker::Postgres.run('posty')
19
+ assert_equal @@posty, posty2
20
+ # Do not need to remove posty2 here because posty2 == posty
21
+ end
22
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'test_helper'
2
+ require 'stringio'
3
+
4
+ class RailsTest < MiniTest::Unit::TestCase
5
+ def self.before_suite
6
+ Docker::Rails.build(TEST_APP_PATH)
7
+ @@app_name = TEST_APP_PATH.match(/(\/(\w+))?$/)[2]
8
+ @@server_name = "rails-server-#{@@app_name}"
9
+ @@container = Docker::Rails.run_server(TEST_APP_PATH)
10
+ end
11
+
12
+ def self.after_suite
13
+ # @@container.remove!
14
+ end
15
+
16
+ def test_docker_can_build_a_rails_app_image
17
+ assert_match /jphager2\/rails-#{@@app_name}/, `docker images`
18
+ end
19
+
20
+ def test_docker_can_start_a_rails_app_container
21
+ assert_equal @@server_name, @@container.name
22
+ assert_includes Docker.containers(:running), @@container
23
+ end
24
+
25
+ def test_docker_run_rails_app_starts_postgres
26
+ assert Docker.containers(:running).any? { |c| c.name == 'db' }
27
+ end
28
+
29
+ def test_docker_can_start_a_rails_console_session
30
+ TestHelper.assert_match_stderr(/rails-console-app/, self) do
31
+ Docker::Rails.run_console(TEST_APP_PATH)
32
+ end
33
+ end
34
+
35
+ def test_docker_can_run_a_command_in_a_rails_app
36
+ container = Docker::Rails.run(TEST_APP_PATH, "", "ls")
37
+ assert_match /Gemfile/, container.logs
38
+ container.remove!
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'test_helper'
2
+ require 'stringio'
3
+
4
+ class RubyTest < MiniTest::Unit::TestCase
5
+ def self.before_suite
6
+ Docker::Ruby.build(RUBY_APP_PATH)
7
+ @@app_name = RUBY_APP_PATH.match(/(\/(\w+))?$/)[2]
8
+ @@container_name = "ruby-irb-#{@@app_name}"
9
+ end
10
+
11
+ def self.after_suite
12
+ #@@container.remove!
13
+ end
14
+
15
+ def test_docker_can_build_a_ruby_app_image
16
+ assert_match /jphager2\/ruby-#{@@app_name}/, `docker images`
17
+ end
18
+
19
+ def test_docker_can_start_a_ruby_app_container
20
+ TestHelper.assert_match_stderr(/ruby-irb-#{@@app_name}/, self) do
21
+ Docker::Ruby.run_irb(RUBY_APP_PATH)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,119 @@
1
+ require_relative 'test_helper'
2
+
3
+ class ImagesTest < MiniTest::Unit::TestCase
4
+ def self.before_suite
5
+ end
6
+
7
+ def self.after_suite
8
+ end
9
+
10
+ def test_images_returns_a_collection_of_images
11
+ Docker.images.each do |image|
12
+ assert_instance_of Docker::Image, image
13
+ end
14
+ end
15
+
16
+ def test_images_returns_a_collection_of_tags
17
+ Docker.images(:tag).each do |tag|
18
+ assert_instance_of Docker::Tag, tag
19
+ end
20
+ end
21
+
22
+ def test_images_returns_a_collection_of_repos
23
+ Docker.images(:repository).each do |repo|
24
+ assert_instance_of Docker::Repository, repo
25
+ end
26
+ end
27
+ end
28
+
29
+ class ContainersTest < MiniTest::Unit::TestCase
30
+
31
+ def self.before_suite
32
+ TestHelper.setup_postgres_containers
33
+ @@rails_server = Docker::Rails.run_server(TEST_APP_PATH)
34
+ #@@rails_console = Docker::Rails.run_console(TEST_APP_PATH)
35
+ #@@ruby_irb = Docker::Ruby.run_irb(RUBY_APP_PATH)
36
+ @@postgres = Docker::Postgres.run('posty-5')
37
+ @@gem_server = Docker.run('ruby:2.1.2', '-d', 'gem server')
38
+
39
+ @@all = `docker ps -a`
40
+ @@running = `docker ps`
41
+ @@stopped = `docker ps -a | grep "Exited"`
42
+ @@paused = `docker ps | grep "(Paused)"`
43
+ end
44
+
45
+ def self.after_suite
46
+ TestHelper.teardown_postgres_containers
47
+ @@rails_server.remove!
48
+ #@@rails_console.remove!
49
+ #@@ruby_irb.remove!
50
+ @@postgres.remove!
51
+ @@gem_server.remove!
52
+ end
53
+
54
+ def test_containers_is_not_empty
55
+ refute_empty Docker.containers
56
+ end
57
+
58
+ def test_containers_returns_a_collection_of_containers
59
+ Docker.containers.each do |container|
60
+ assert_kind_of Docker::Container, container
61
+ end
62
+ end
63
+
64
+ def test_containers_returns_a_collection_of_all_containers
65
+ Docker.containers.each do |container|
66
+ assert_match /#{container.id}/, @@all
67
+ end
68
+ end
69
+
70
+ def test_containers_with_option_running_returns_only_running
71
+ Docker.containers(:running).each do |container|
72
+ assert_match /#{container.id}/, @@running
73
+ refute_match /#{container.id}/, @@stopped
74
+ end
75
+ end
76
+
77
+ def test_containers_with_option_stopped_returns_stopped_containers
78
+ Docker.containers(:stopped).each do |container|
79
+ refute_match /#{container.id}/, @@running
80
+ assert_match /#{container.id}/, @@stopped
81
+ end
82
+ end
83
+
84
+ def test_containers_with_option_paused_returns_paused_containers
85
+ Docker.containers(:paused).each do |container|
86
+ assert_match /#{container.id}/, @@paused
87
+ end
88
+ end
89
+
90
+ def test_running_not_equal_to_paused
91
+ refute_equal Docker.containers(:paused),
92
+ Docker.containers(:running)
93
+ end
94
+
95
+ def test_containers_accepts_the_all_argument
96
+ assert Docker.containers(:all),
97
+ 'Docker.containers(:all) should return something truthy'
98
+ end
99
+
100
+ def test_containers_raises_exception_for_other_arguments
101
+ words = %w{ the red fox jumped over the redhat }
102
+ assert_raises(ArgumentError) do
103
+ Docker.containers(words.take.to_sym)
104
+ end
105
+ end
106
+
107
+ def test_can_get_a_collection_of_containers_based_on_class
108
+ klasses = [
109
+ Docker::Rails::Server, Docker::Postgres, Docker::Container
110
+ ]
111
+ klasses.each do |klass|
112
+ servers = Docker.find_containers(klass: klass)
113
+ refute_empty servers
114
+ servers.each do |server|
115
+ assert_instance_of klass, server
116
+ end
117
+ end
118
+ end
119
+ end