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.
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'