dc 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/dc +4 -0
  3. data/lib/dc.rb +200 -0
  4. metadata +59 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a1778827651668547f6a5ea1e41c8c29ad99f9675e8ecb0982f16e7fe41838e3
4
+ data.tar.gz: aaca72cc50e107ebfd0f6ba6517c1562d8b492217dfef2812048aef658e1c12b
5
+ SHA512:
6
+ metadata.gz: b540e943a2b221b098565ab653a9dc98ad240cc31b9076bb4736c4273ecd271dc301c47eb41d315f81a7caa3cacc05fdee5f97220c736b3e0ecc673b83202c0c
7
+ data.tar.gz: fc98f1883b3a9daae99d646f75fd593124d547ad024590e1979078b5f0aef241cecac9198855e072239fb6adef2096406a51208b0cffce5ca407368c3da2d377
data/bin/dc ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dc'
4
+ DC::CLI.run
@@ -0,0 +1,200 @@
1
+ module DC
2
+ require 'forwardable'
3
+ require 'yaml'
4
+ require 'docker'
5
+
6
+ class Container
7
+ def initialize name, ports: []
8
+ @name = name
9
+ @container = if ports.empty?
10
+ Docker::Container.create name: name, Image: name
11
+ else
12
+ port_maps = ports.map do |port|
13
+ if port.is_a? PortMap
14
+ port
15
+ else
16
+ to, from = port.split ':'
17
+ PortMap.new from: from, to: to
18
+ end
19
+ end
20
+
21
+ Docker::Container.create(
22
+ name: name, Image: name,
23
+ ExposedPorts: port_maps.map do |map|
24
+ ["#{map.internal_port}/tcp", {}]
25
+ end.to_h,
26
+ HostConfig: {
27
+ PortBindings: port_maps.map do |map|
28
+ array = [{ HostPort: map.external_port, HostIp: map.external_ip }]
29
+ ["#{map.internal_port}/tcp", array]
30
+ end.to_h
31
+ }
32
+ )
33
+ end
34
+ end
35
+
36
+ attr_reader :name
37
+
38
+ def internal_container
39
+ @container
40
+ end
41
+
42
+ extend Forwardable
43
+ delegate [:id, :start, :kill!, :remove] => :internal_container
44
+
45
+ def destroy
46
+ kill!.remove
47
+ end
48
+
49
+ class PortMap
50
+ def initialize from:, to:, external_ip: '0.0.0.0'
51
+ @internal_port = from.to_s
52
+ @external_port = to.to_s
53
+ @external_ip = external_ip
54
+ end
55
+
56
+ attr_reader :internal_port, :external_port, :external_ip
57
+ end
58
+ end
59
+
60
+ class Image
61
+ class << self
62
+ def all
63
+ @all ||= {}
64
+ end
65
+
66
+ def [] name
67
+ all[name]
68
+ end
69
+
70
+ def []= name, image
71
+ all[name] = image
72
+ end
73
+ end
74
+
75
+ def initialize name, directory: name
76
+ @name = name
77
+ @directory = directory
78
+ self.class[name] = self
79
+ end
80
+
81
+ attr_reader :name
82
+
83
+ def exist?
84
+ Docker::Image.exist? @name
85
+ end
86
+
87
+ def build
88
+ build_parent_image_if_available
89
+ image = Docker::Image.build_from_dir @directory do |json|
90
+ puts JSON.parse json
91
+ end
92
+ image.tag repo: @name
93
+ image
94
+ end
95
+
96
+ private
97
+ def build_parent_image_if_available
98
+ dockerfile = IO.read "#{@directory}/Dockerfile"
99
+ from, image_name = dockerfile.each_line.first.split ' '
100
+ fail from unless from == 'FROM'
101
+
102
+ if image = self.class[image_name]
103
+ unless image.exist?
104
+ puts "Building parent image #{image.name}."
105
+ image.build
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ class Network
112
+ def initialize name = 'common'
113
+ @network = prepare_network_with_name name
114
+ end
115
+
116
+ def internal_network
117
+ @network
118
+ end
119
+
120
+ extend Forwardable
121
+ delegate [:id, :connect] => :internal_network
122
+
123
+ def name
124
+ @network.info['Name']
125
+ end
126
+
127
+ private
128
+ def prepare_network_with_name name
129
+ Docker::Network.get name
130
+ rescue Docker::Error::NotFoundError
131
+ Docker::Network.create name
132
+ end
133
+ end
134
+
135
+ class Project
136
+ def initialize directory: '.', docker_socket: 'tcp://127.0.0.1:2375'
137
+ check_if_docker_is_available_at docker_socket
138
+
139
+ @directory = File.expand_path directory
140
+ @images_directory = "#{@directory}/.docker/images"
141
+ @services_file = "#{@directory}/.docker/services.yml"
142
+ end
143
+
144
+ attr_reader :containers
145
+
146
+ def run
147
+ prepare_images
148
+ prepare_services
149
+ end
150
+
151
+ private
152
+ def check_if_docker_is_available_at docker_socket
153
+ Docker.url = docker_socket
154
+ Docker.version
155
+ #rescue Excon::Error::Socket
156
+ end
157
+
158
+ def prepare_images
159
+ if Dir.exist? @images_directory
160
+ images = (Dir.entries(@images_directory) - ['.', '..']).map do |name|
161
+ Image.new name, directory: "#{@images_directory}/#{name}"
162
+ end
163
+
164
+ images.each do |image|
165
+ image.build unless image.exist?
166
+ end
167
+ end
168
+ end
169
+
170
+ def prepare_services
171
+ if File.exist? @services_file
172
+ hash = YAML.load_file @services_file
173
+
174
+ images = hash.keys.map do |name|
175
+ Image.new name, directory: "#{@directory}/#{name}"
176
+ end
177
+
178
+ images.each do |image|
179
+ image.build unless image.exist?
180
+ end
181
+
182
+ @containers = hash.map do |name, value|
183
+ ports = if value.is_a?(Hash) && value['ports'].is_a?(Array)
184
+ value['ports']
185
+ else
186
+ []
187
+ end
188
+
189
+ Container.new name, ports: ports
190
+ end
191
+
192
+ network = Network.new
193
+ @containers.each { |container| network.connect container.id }
194
+
195
+ @containers.each &:start
196
+ at_exit { @containers.each &:destroy }
197
+ end
198
+ end
199
+ end
200
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Anatoly Chernow
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: docker-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email:
29
+ executables:
30
+ - dc
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/dc
35
+ - lib/dc.rb
36
+ homepage:
37
+ licenses: []
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.7.6
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Manage projects with Docker conveniently.
59
+ test_files: []