docker-dev 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b790b0f51b1657492a1aa2ab4f6528f6b3d2ab48
4
+ data.tar.gz: a8a10e13b6483b0b41f7a8cc87f61e68807e616f
5
+ SHA512:
6
+ metadata.gz: 38f16ae99fcc1296a1768d2b6f34be5b17996e481dace95dfbdcbdc5aa5e2959c95548292c77ebad000905a23ec8a78089d35d399c1b5022016417fdb4d0b1c6
7
+ data.tar.gz: c16ed1806dc1b618c3744acba0455695a46e560b50563fb1bcfa1a44e2b0cb9a6719bae1ddb7c2d9cdb09e9add7e5c85b6d9631d53f8a00d354ed8aeb4ffbe98
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 John Hager
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ ###To Build an App
2
+ _This should be done everytime you change the Gemfile or do something
3
+ that would force you to restart the Rails Sever_
4
+ ```
5
+ rake docker:build /path/to/app
6
+ ```
7
+
8
+ ###To Run an App
9
+ _After the app has be built, you can run it with:_
10
+ ```
11
+ rake docker:run /path/to/app
12
+ ```
13
+
14
+ ###To Stop all Running Containers and then Remove all Containers
15
+ _Be careful, because this will remove all your Docker Containers,
16
+ not just the ones run from the commands above_
17
+ ```
18
+ rake docker:cleanup
19
+ ```
data/helpers.rake ADDED
@@ -0,0 +1,33 @@
1
+ require_relative 'lib/docker'
2
+
3
+ include Docker::Helpers
4
+
5
+ def get_args(num_args)
6
+ # See this link for explanation of this black magic:
7
+ # http://itshouldbeuseful.wordpress.com/2011/11/07/passing-parameters-to-a-rake-task/
8
+ args = ARGV.last(num_args)
9
+ yield(args)
10
+ args.each { |arg| task arg.to_sym {} }
11
+ end
12
+
13
+ def build_docker_app_image(type, app_path)
14
+ full_path_and_name(app_path) do |path, name|
15
+ `docker build -t jphager2/#{type}-#{name} #{path}`
16
+ end
17
+ end
18
+
19
+ # You Can't overwrite rake tasks (yet)
20
+ # Paths Can't be relative (try to source them)
21
+ namespace :docker do
22
+ desc "Stop all running docker containers and then remove them"
23
+ task :cleanup do
24
+ Docker.containers.each { |c| c.remove! }
25
+ end
26
+
27
+ desc "Remove all nameless docker images (repositories, tags)"
28
+ task :nameless do
29
+ Docker.images(:repository).select {|r| r.id == "<none>"}.each do |r|
30
+ r.remove_image!
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,114 @@
1
+ module Docker
2
+ class Container
3
+ include Docker::Equality
4
+
5
+ attr_reader :id, :removal_instructions
6
+ def initialize(id)
7
+ @id = Docker::ID(id)
8
+ end
9
+
10
+ def self.run(image, flags = "", command = "", path = nil)
11
+ path = Docker::PATH(path)
12
+ flags = "#{flags} -e DOCKER_TYPE=#{self}"
13
+ flags = "#{flags} -e LOCAL_PATH=#{path.path}" if path
14
+
15
+ id = Docker::ID(`docker run #{flags} #{image} #{command}`)
16
+
17
+ # Nasty hack to return a removed container if the --rm flag
18
+ # is passed and the container alread exited
19
+ return new(nil).disable! unless id || flags !~ /--rm/
20
+
21
+ id ||= Docker.containers(:stopped).first.id
22
+
23
+ new(id)
24
+ end
25
+
26
+ def self.load_from(container)
27
+ new(container.id) if container.from_a?(self)
28
+ end
29
+
30
+ def logs
31
+ @logs || `docker logs #{id}` # @logs given with #disable!
32
+ end
33
+
34
+ def inspekt
35
+ Docker.inspekt(id)
36
+ end
37
+
38
+ def to_klass
39
+ return self unless klass = from_klass
40
+ klass.load_from(self)
41
+ end
42
+
43
+ def from_klass
44
+ return nil unless klass = env["DOCKER_TYPE"]
45
+ Kernel.const_get(klass)
46
+ end
47
+
48
+ def path
49
+ Docker::PATH(env["LOCAL_PATH"])
50
+ end
51
+
52
+ def add_removal_instructions(&block)
53
+ @removal_instructions = Proc.new { block.call(self) }
54
+ self
55
+ end
56
+
57
+ def attach!
58
+ `docker attach --sig-proxy=false #{id}`
59
+ end
60
+
61
+ def remove!
62
+ @logs = logs
63
+ @removal_instructions.call if @removal_instructions
64
+ `docker rm -f #{id}`
65
+ disable!
66
+ id
67
+ end
68
+
69
+ def disable!
70
+ self.instance_eval {
71
+ undef :attach!
72
+ undef :remove!
73
+ undef :add_removal_instructions
74
+ }
75
+ self.instance_eval { def state; @id; end }
76
+ @id = 'REMOVED'
77
+ self
78
+ end
79
+
80
+ def from_a?(klass)
81
+ env["DOCKER_TYPE"] == klass.to_s
82
+ end
83
+
84
+ def removed?
85
+ id == "REMOVED"
86
+ end
87
+
88
+ def exists_in?(state)
89
+ Docker.containers(state).any? { |container| container == self }
90
+ end
91
+
92
+ def up?; running?; end
93
+ def ip; ip_address; end
94
+ alias_method :to_s, :id
95
+
96
+ def method_missing(method, *args, &block)
97
+ super if removed?
98
+ inspekt_methods = [:env, :state, :ports, :ip_address, :name]
99
+ state_methods = [:running? , :stopped?, :paused?]
100
+ action_methods = [:stop!, :start!, :restart!, :pause!, :unpause!]
101
+ if inspekt_methods.include?(method)
102
+ inspekt.__send__(method)
103
+ elsif state_methods.include?(method)
104
+ method = method.to_s.delete('?').to_sym
105
+ exists_in?(method)
106
+ elsif action_methods.include?(method)
107
+ method = method.to_s.delete('!').to_sym
108
+ `docker #{method} #{id}`
109
+ else
110
+ super
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,11 @@
1
+ module Docker
2
+ module Equality
3
+ def ==(other)
4
+ # this seems unconfident, but it is because I want to be able
5
+ # to create containers with shortened ID's (for now)
6
+ min = [id.length, other.id.length].min
7
+ id[0...min] == other.id[0...min]
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,12 @@
1
+ module Docker
2
+ module Helpers
3
+
4
+ def rails_image(name)
5
+ "#{USER_NAME}/rails-#{name}"
6
+ end
7
+
8
+ def rails_server(name)
9
+ "rails-server-#{name}"
10
+ end
11
+ end
12
+ end
data/lib/docker/id.rb ADDED
@@ -0,0 +1,33 @@
1
+ module Docker
2
+ class Id
3
+ def self.create(id)
4
+ id = new(id)
5
+ id.id.empty? ? nil : id
6
+ end
7
+
8
+ attr_reader :id
9
+ def initialize(id)
10
+ @id = id.to_s[0..11]
11
+ validate!
12
+ end
13
+
14
+ alias_method :to_s, :id
15
+ alias_method :to_str, :id
16
+
17
+ def validate!
18
+ valid = id.length >= 12 &&
19
+ id =~ /^[0-9a-z]+$/ && id !~ /^[^0-9a-z]$/ &&
20
+ id =~/[0-9]/ && id =~ /[a-z]/
21
+ valid ? id : (@id = '')
22
+ end
23
+
24
+ def method_missing(method, *args, &block)
25
+ if id.respond_to?(method)
26
+ id.__send__(method, *args, &block)
27
+ else
28
+ super
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,38 @@
1
+ module Docker
2
+ class Image
3
+ extend Docker::Helpers
4
+ extend Docker::Equality
5
+
6
+ attr_reader :id
7
+ def initialize(id)
8
+ @id = id[0..11]
9
+ end
10
+
11
+ def self.build(path, name)
12
+ name = "#{Docker::USER_NAME}/#{name}"
13
+ repo, tag = name.split(':')
14
+ id = `docker build -t #{name} #{path}`[-13..-2]
15
+ tag ? Tag.new(repo, tag) : Repository.new(id, repo)
16
+ end
17
+
18
+ def remove!
19
+ `docker rmi #{id}`
20
+ end
21
+
22
+ def inspekt
23
+ Docker.inspekt(id)
24
+ end
25
+
26
+ def image_id
27
+ id
28
+ end
29
+
30
+ def to_s
31
+ id
32
+ end
33
+
34
+ def repositories
35
+ Docker.images.select { |repo| repo == self }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ require 'json'
2
+
3
+ module Docker
4
+ class Inspect
5
+
6
+ attr_reader :inspekt
7
+ def initialize(id)
8
+ @id = id[0..11]
9
+ @inspekt = JSON.load(`docker inspect #{@id}`).first
10
+ end
11
+
12
+ def name
13
+ inspekt["Name"][1..-1]
14
+ end
15
+
16
+ def env
17
+ inspekt["Config"]["Env"].each_with_object({}) do |e,h|
18
+ pair = e.split('=')
19
+ h[pair.first] = pair.last
20
+ end
21
+ end
22
+
23
+ def ip_address
24
+ inspekt["NetworkSettings"]["IPAddress"]
25
+ end
26
+
27
+ def ports
28
+ inspekt["NetworkSettings"]["Ports"]
29
+ end
30
+
31
+ def state
32
+ inspekt["State"]
33
+ end
34
+
35
+ def to_s
36
+ inspekt.to_s
37
+ end
38
+ end
39
+
40
+ class NullInspect
41
+ def method_missing(*)
42
+ return nil
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ module Docker
2
+ module Interactive
3
+ extend self
4
+
5
+ def warn(command)
6
+ Kernel.warn (
7
+ "Interactive containers cannot (yet) be run within this " +
8
+ "library. Please copy the following command into a new " +
9
+ "shell:\n\n\t#{command}"
10
+ )
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module Docker
2
+ class Path
3
+
4
+ attr_reader :path, :name
5
+ def initialize(path)
6
+ raise "Bad Path: Directory Not Found" unless Dir.exist?(path)
7
+ @path = File.expand_path(path)
8
+ @name = @path.sub(/\/$/, '').sub(/.+\//, '')
9
+ end
10
+
11
+ def to_s
12
+ @path
13
+ end
14
+
15
+ def to_dpath
16
+ self
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Docker
2
+ class Postgres < Container
3
+
4
+ def self.run(name, version = '9.3.5')
5
+ pg = Docker.find_container(name: name)
6
+ if pg
7
+ pg.start! if pg.stopped?
8
+ else
9
+ pg = super("postgres:#{version}", "-d --name #{name}")
10
+ sleep 3
11
+ end
12
+ pg
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ module Docker
2
+ module Rails
3
+ class Console < Docker::Container
4
+
5
+ extend Docker::Helpers
6
+
7
+ def initialize(id)
8
+ super
9
+ end
10
+
11
+ def self.run(path, postgres)
12
+ image = "#{rails_image(path.name)}"
13
+ options = "-it --name rails-console-#{path.name} " +
14
+ "--rm -e PG_HOST=#{postgres.ip} " +
15
+ "--link db:db -v #{path}:/usr/src/app"
16
+ command = 'rails console'
17
+
18
+ docker_cmd = "docker run #{options} #{image} #{command}"
19
+ Docker::Interactive.warn(docker_cmd)
20
+ docker_cmd
21
+ end
22
+
23
+ def self.load(id, path)
24
+ run(path)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -0,0 +1,53 @@
1
+ module Docker
2
+ module Rails
3
+ class Server < Docker::Container
4
+
5
+ extend Docker::Helpers
6
+
7
+ def initialize(id)
8
+ super
9
+ end
10
+
11
+ def self.run(path, postgres)
12
+ server = existing_server(path)
13
+ return server if server
14
+ migrate_database!(path, postgres)
15
+ server = super(
16
+ "#{rails_image(path.name)}",
17
+ "-d --name #{rails_server(path.name)} --link db:db " +
18
+ "-e PG_HOST=#{postgres.ip} -v #{path}:/usr/src/app",
19
+ nil,
20
+ path
21
+ )
22
+ self.load(server.id, path)
23
+ end
24
+
25
+ def self.load_from(container)
26
+ load(container.id, container.path)
27
+ end
28
+
29
+ def self.load(id, path)
30
+ server = new(id)
31
+ Docker::Rails.add_default_instructions_to(server, path)
32
+ end
33
+
34
+ def self.migrate_database!(path, postgres)
35
+ ['create', 'migrate'].each do |cmd|
36
+ Docker.run(
37
+ "#{rails_image(path.name)}",
38
+ "--rm --link db:db -e PG_HOST=#{postgres.ip} " +
39
+ "-v #{path}:/usr/src/app",
40
+ "rake db:#{cmd}"
41
+ )
42
+ end
43
+ end
44
+
45
+ def self.existing_server(path)
46
+ server = Rails.find_server(path)
47
+ return server if server && server.up?
48
+ server.remove! if server
49
+ nil
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,54 @@
1
+ module Docker
2
+ module Rails
3
+
4
+ extend Helpers
5
+ extend Docker
6
+ extend self
7
+
8
+ def build(app_path)
9
+ path = Docker::PATH(app_path)
10
+ Image.build(path, "rails-#{path.name}")
11
+ end
12
+
13
+ def postgres
14
+ Docker::Postgres.run('db')
15
+ end
16
+
17
+ def run(app_path, options = "", command = "")
18
+ path = Docker::PATH(app_path)
19
+ image = rails_image(path.name)
20
+ options = "#{options} -v #{path}:/usr/src/app"
21
+ Docker::Container.run(image, options, command, path)
22
+ end
23
+
24
+ def run_server(app_path)
25
+ path = Docker::PATH(app_path)
26
+ Docker::Rails::Server.run(path, postgres)
27
+ end
28
+
29
+ def run_console(app_path)
30
+ path = Docker::PATH(app_path)
31
+ Docker::Rails::Console.run(path, postgres)
32
+ end
33
+
34
+ def add_default_instructions_to(server, path)
35
+ path = Docker::PATH(path)
36
+ server.add_removal_instructions do |container|
37
+ # Give all users Read/Write Access to App
38
+ Docker.run(
39
+ "#{rails_image(path.name)}",
40
+ "--rm -v #{path}:/usr/src/app",
41
+ "chmod -R a+rw /usr/src/app"
42
+ )
43
+ # Remove the tmp dir files and sub directories
44
+ `rm -rf #{path}/tmp/*`
45
+ end
46
+ end
47
+
48
+ def find_server(path)
49
+ path = Docker::PATH(path)
50
+ server = Docker.find_container(name: rails_server(path.name))
51
+ Rails::Server.load(server.id, path) if server
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,10 @@
1
+ module Docker
2
+ module Rake
3
+ extend self
4
+
5
+ def load
6
+ file = File.expand_path(__FILE__, '../../helpers.rake')
7
+ Kernel.load(file)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module Docker
2
+ class Repository < Image
3
+
4
+ attr_reader :id, :image_id
5
+ def initialize(id, name)
6
+ @id = name
7
+ @image_id = id
8
+ end
9
+
10
+ def remove!
11
+ `docker rmi #{id}`
12
+ end
13
+
14
+ def remove_image!
15
+ `docker rmi -f #{image_id}`
16
+ end
17
+
18
+ def to_s
19
+ id
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ module Docker
2
+ module Ruby
3
+
4
+ extend Helpers
5
+ extend Docker
6
+ extend self
7
+
8
+ def build(app_path)
9
+ path = Docker::PATH(app_path)
10
+ Docker.build(path, "ruby-#{path.name}")
11
+ end
12
+
13
+ def run_irb(app_path, flags = '', command = '')
14
+ path = Docker::PATH(app_path)
15
+ name = path.name
16
+
17
+ image = "jphager2/ruby-#{path.name}"
18
+ flags = "-it --name ruby-irb-#{name} -v #{path}:/usr/src/app #{flags}"
19
+
20
+ docker_cmd = "docker run #{flags} #{image} #{command}"
21
+
22
+ Docker::Interactive.warn(docker_cmd)
23
+ docker_cmd
24
+ end
25
+ end
26
+ end
27
+
data/lib/docker/tag.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Docker
2
+ class Tag < Repository
3
+
4
+ attr_reader :repo_name
5
+ def initialize(id, repo_name, name)
6
+ @id = "#{repo_name}:#{name}"
7
+ @repo_name = repo_name
8
+ @image_id = id
9
+ end
10
+ end
11
+ end
data/lib/docker-dev.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative 'docker'