docker-compose-api 1.0.2 → 1.0.4
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/README.md +5 -0
- data/lib/docker-compose/models/compose.rb +14 -3
- data/lib/docker-compose/models/compose_container.rb +57 -21
- data/lib/docker-compose/utils/compose_utils.rb +3 -1
- data/lib/version.rb +1 -1
- data/spec/docker-compose/docker_compose_spec.rb +61 -9
- data/spec/docker-compose/fixtures/compose_1.yaml +10 -0
- data/spec/docker-compose/models/compose_container_spec.rb +19 -2
- data/spec/docker-compose/utils/compose_utils_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -61,6 +61,11 @@ compose.stop(['container1', 'container2', ...]) # stop a list of specific contai
|
|
61
61
|
compose.kill # kill all containers
|
62
62
|
compose.kill(['container1', 'container2', ...]) # kill a list of specific containers
|
63
63
|
|
64
|
+
# Deleting containers
|
65
|
+
# (ps: container dependencies will keep running)
|
66
|
+
compose.delete # delete all containers
|
67
|
+
compose.delete(['container1', 'container2', ...]) # delete a list of specific containers
|
68
|
+
|
64
69
|
# Checking if a container is running or not
|
65
70
|
a_container = compose.containers['a_container']
|
66
71
|
a_container.running?
|
@@ -58,16 +58,27 @@ class Compose
|
|
58
58
|
end
|
59
59
|
|
60
60
|
#
|
61
|
-
#
|
61
|
+
# Kill a container
|
62
62
|
#
|
63
63
|
# This method accepts an array of labels.
|
64
|
-
# If labels is informed, only those containers with label present in array will be
|
65
|
-
# Otherwise, all containers are
|
64
|
+
# If labels is informed, only those containers with label present in array will be killed.
|
65
|
+
# Otherwise, all containers are killed
|
66
66
|
#
|
67
67
|
def kill(labels = [])
|
68
68
|
call_container_method(:kill, labels)
|
69
69
|
end
|
70
70
|
|
71
|
+
#
|
72
|
+
# Delete a container
|
73
|
+
#
|
74
|
+
# This method accepts an array of labels.
|
75
|
+
# If labels is informed, only those containers with label present in array will be deleted.
|
76
|
+
# Otherwise, all containers are deleted
|
77
|
+
#
|
78
|
+
def delete(labels = [])
|
79
|
+
call_container_method(:delete, labels)
|
80
|
+
end
|
81
|
+
|
71
82
|
private
|
72
83
|
|
73
84
|
def call_container_method(method, labels = [])
|
@@ -15,7 +15,7 @@ class ComposeContainer
|
|
15
15
|
ports: prepare_ports(hash_attributes[:ports]),
|
16
16
|
volumes: hash_attributes[:volumes],
|
17
17
|
command: ComposeUtils.format_command(hash_attributes[:command]),
|
18
|
-
environment: hash_attributes[:environment]
|
18
|
+
environment: prepare_environment(hash_attributes[:environment])
|
19
19
|
}.reject{ |key, value| value.nil? }
|
20
20
|
|
21
21
|
# Docker client variables
|
@@ -49,28 +49,15 @@ class ComposeContainer
|
|
49
49
|
|
50
50
|
#
|
51
51
|
# Start a new container with parameters informed in object construction
|
52
|
-
# (TODO: start container from a Dockerfile)
|
53
52
|
#
|
54
53
|
def prepare_container
|
55
|
-
|
56
|
-
port_bindings =
|
57
|
-
links =
|
54
|
+
# Prepare attributes
|
55
|
+
port_bindings = prepare_port_bindings
|
56
|
+
links = prepare_links
|
58
57
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
exposed_ports["#{port.container_port}/tcp"] = {}
|
63
|
-
port_bindings["#{port.container_port}/tcp"] = [{
|
64
|
-
"HostIp" => port.host_ip || '',
|
65
|
-
"HostPort" => port.host_port || ''
|
66
|
-
}]
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Build link parameters
|
71
|
-
@dependencies.each do |dependency|
|
72
|
-
links << "#{dependency.stats['Id']}:#{dependency.attributes[:label]}"
|
73
|
-
end
|
58
|
+
# Exposed ports are port bindings with an empty hash as value
|
59
|
+
exposed_ports = {}
|
60
|
+
port_bindings.each {|k, v| exposed_ports[k] = {}}
|
74
61
|
|
75
62
|
container_config = {
|
76
63
|
Image: @internal_image,
|
@@ -87,6 +74,40 @@ class ComposeContainer
|
|
87
74
|
@container = Docker::Container.create(container_config)
|
88
75
|
end
|
89
76
|
|
77
|
+
#
|
78
|
+
# Prepare port binding attribute based on ports
|
79
|
+
# received from compose file
|
80
|
+
#
|
81
|
+
def prepare_port_bindings
|
82
|
+
port_bindings = {}
|
83
|
+
|
84
|
+
return port_bindings if @attributes[:ports].nil?
|
85
|
+
|
86
|
+
@attributes[:ports].each do |port|
|
87
|
+
port_bindings["#{port.container_port}/tcp"] = [{
|
88
|
+
"HostIp" => port.host_ip || '',
|
89
|
+
"HostPort" => port.host_port || ''
|
90
|
+
}]
|
91
|
+
end
|
92
|
+
|
93
|
+
port_bindings
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Prepare link entries based on
|
98
|
+
# attributes received from compose
|
99
|
+
#
|
100
|
+
def prepare_links
|
101
|
+
links = []
|
102
|
+
|
103
|
+
@dependencies.each do |dependency|
|
104
|
+
link_name = @attributes[:links][dependency.attributes[:label]]
|
105
|
+
links << "#{dependency.stats['Id']}:#{link_name}"
|
106
|
+
end
|
107
|
+
|
108
|
+
links
|
109
|
+
end
|
110
|
+
|
90
111
|
#
|
91
112
|
# Process each port entry in docker compose file and
|
92
113
|
# create structure recognized by docker client
|
@@ -105,6 +126,14 @@ class ComposeContainer
|
|
105
126
|
ports
|
106
127
|
end
|
107
128
|
|
129
|
+
#
|
130
|
+
# Forces the environment structure to use the array format.
|
131
|
+
#
|
132
|
+
def prepare_environment(env_entries)
|
133
|
+
return env_entries unless env_entries.is_a?(Hash)
|
134
|
+
env_entries.to_a.map { |x| x.join('=') }
|
135
|
+
end
|
136
|
+
|
108
137
|
#
|
109
138
|
# Check if a given image already exists in host
|
110
139
|
#
|
@@ -136,7 +165,7 @@ class ComposeContainer
|
|
136
165
|
# Stop the container
|
137
166
|
#
|
138
167
|
def stop
|
139
|
-
@container.
|
168
|
+
@container.stop unless @container.nil?
|
140
169
|
end
|
141
170
|
|
142
171
|
#
|
@@ -175,4 +204,11 @@ class ComposeContainer
|
|
175
204
|
def running?
|
176
205
|
@container.nil? ? false : self.stats['State']['Running']
|
177
206
|
end
|
207
|
+
|
208
|
+
#
|
209
|
+
# Check if the container exists or not
|
210
|
+
#
|
211
|
+
def exist?
|
212
|
+
!@container.nil?
|
213
|
+
end
|
178
214
|
end
|
@@ -62,6 +62,8 @@ module ComposeUtils
|
|
62
62
|
# Generate a pair key:hash with
|
63
63
|
# format {service:label}
|
64
64
|
#
|
65
|
+
# The label will be the conainer name if not specified.
|
66
|
+
#
|
65
67
|
def self.format_links(links_array)
|
66
68
|
links = {}
|
67
69
|
|
@@ -72,7 +74,7 @@ module ComposeUtils
|
|
72
74
|
|
73
75
|
case parts.length
|
74
76
|
when 1
|
75
|
-
links[parts[0]] =
|
77
|
+
links[parts[0]] = parts[0]
|
76
78
|
|
77
79
|
when 2
|
78
80
|
links[parts[0]] = parts[1]
|
data/lib/version.rb
CHANGED
@@ -14,7 +14,7 @@ describe DockerCompose do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should read a YAML file correctly' do
|
17
|
-
expect(@compose.containers.length).to eq(
|
17
|
+
expect(@compose.containers.length).to eq(3)
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should raise error when reading an invalid YAML file' do
|
@@ -49,13 +49,27 @@ describe DockerCompose do
|
|
49
49
|
expect(container.running?).to be false
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
it 'should start/delete all containers' do
|
54
|
+
# Start containers to test Delete
|
55
|
+
@compose.start
|
56
|
+
@compose.containers.values.each do |container|
|
57
|
+
expect(container.running?).to be true
|
58
|
+
end
|
59
|
+
|
60
|
+
# Delete containers
|
61
|
+
@compose.delete
|
62
|
+
@compose.containers.values.each do |container|
|
63
|
+
expect(container.exist?).to be false
|
64
|
+
end
|
65
|
+
end
|
52
66
|
end
|
53
67
|
|
54
68
|
context 'Single container' do
|
55
69
|
context 'Without dependencies' do
|
56
70
|
it 'should start/stop a single container' do
|
57
71
|
container1 = @compose.containers.values.first.attributes[:label]
|
58
|
-
container2 = @compose.containers.values.
|
72
|
+
container2 = @compose.containers.values[1].attributes[:label]
|
59
73
|
|
60
74
|
# Should start Redis only, since it hasn't dependencies
|
61
75
|
@compose.start([container2])
|
@@ -70,7 +84,7 @@ describe DockerCompose do
|
|
70
84
|
|
71
85
|
it 'should start/kill a single container' do
|
72
86
|
container1 = @compose.containers.values.first.attributes[:label]
|
73
|
-
container2 = @compose.containers.values.
|
87
|
+
container2 = @compose.containers.values[1].attributes[:label]
|
74
88
|
|
75
89
|
# Should start Redis only, since it hasn't dependencies
|
76
90
|
@compose.start([container2])
|
@@ -87,7 +101,7 @@ describe DockerCompose do
|
|
87
101
|
context 'With dependencies' do
|
88
102
|
it 'should start/stop a single container' do
|
89
103
|
container1 = @compose.containers.values.first.attributes[:label]
|
90
|
-
container2 = @compose.containers.values.
|
104
|
+
container2 = @compose.containers.values[1].attributes[:label]
|
91
105
|
|
92
106
|
# Should start Ubuntu and Redis, since Ubuntu depends on Redis
|
93
107
|
@compose.start([container1])
|
@@ -106,7 +120,7 @@ describe DockerCompose do
|
|
106
120
|
|
107
121
|
it 'should start/kill a single container' do
|
108
122
|
container1 = @compose.containers.values.first.attributes[:label]
|
109
|
-
container2 = @compose.containers.values.
|
123
|
+
container2 = @compose.containers.values[1].attributes[:label]
|
110
124
|
|
111
125
|
# Should start Ubuntu and Redis, since Ubuntu depends on Redis
|
112
126
|
@compose.start([container1])
|
@@ -125,7 +139,7 @@ describe DockerCompose do
|
|
125
139
|
|
126
140
|
it 'should be able to ping a dependent container' do
|
127
141
|
container1 = @compose.containers.values.first.attributes[:label]
|
128
|
-
container2 = @compose.containers.values.
|
142
|
+
container2 = @compose.containers.values[1].attributes[:label]
|
129
143
|
|
130
144
|
# Start all containers
|
131
145
|
@compose.start
|
@@ -136,6 +150,20 @@ describe DockerCompose do
|
|
136
150
|
ping_response = @compose.containers[container1].container.exec(['ping', '-c', '3', 'busybox2'])
|
137
151
|
expect(ping_response[2]).to eq(0) # Status 0 = OK
|
138
152
|
end
|
153
|
+
|
154
|
+
it 'should be able to ping a dependent aliased container' do
|
155
|
+
container2 = @compose.containers.values[1].attributes[:label]
|
156
|
+
container3 = @compose.containers.values[2].attributes[:label]
|
157
|
+
|
158
|
+
# Start all containers
|
159
|
+
@compose.start
|
160
|
+
expect(@compose.containers[container2].running?).to be true
|
161
|
+
expect(@compose.containers[container3].running?).to be true
|
162
|
+
|
163
|
+
# Ping container3 from container1
|
164
|
+
ping_response = @compose.containers[container3].container.exec(['ping', '-c', '3', 'bb2'])
|
165
|
+
expect(ping_response[2]).to eq(0) # Status 0 = OK
|
166
|
+
end
|
139
167
|
end # context 'with dependencies'
|
140
168
|
end # context 'Single container'
|
141
169
|
|
@@ -177,9 +205,33 @@ describe DockerCompose do
|
|
177
205
|
container1.stop
|
178
206
|
end
|
179
207
|
|
208
|
+
it 'supports setting environment as array' do
|
209
|
+
container1 = @compose.containers.values.first
|
210
|
+
|
211
|
+
# Start container
|
212
|
+
container1.start
|
213
|
+
|
214
|
+
env = container1.stats['Config']['Env']
|
215
|
+
expect(env).to eq(%w(MYENV1=variable1))
|
216
|
+
|
217
|
+
# Stop container
|
218
|
+
container1.stop
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'supports setting environment as hash' do
|
222
|
+
container1 = @compose.containers.values[1]
|
223
|
+
|
224
|
+
# Start container
|
225
|
+
container1.start
|
226
|
+
|
227
|
+
env = container1.stats['Config']['Env']
|
228
|
+
expect(env).to eq(%w(MYENV2=variable2))
|
229
|
+
|
230
|
+
# Stop container
|
231
|
+
container1.stop
|
232
|
+
end
|
233
|
+
|
180
234
|
after(:all) do
|
181
|
-
@compose.
|
182
|
-
entry.delete
|
183
|
-
end
|
235
|
+
@compose.delete
|
184
236
|
end
|
185
237
|
end
|
@@ -9,9 +9,19 @@ busybox1:
|
|
9
9
|
links:
|
10
10
|
- busybox2
|
11
11
|
command: ping busybox2
|
12
|
+
environment:
|
13
|
+
- MYENV1=variable1
|
12
14
|
|
13
15
|
busybox2:
|
14
16
|
image: busybox
|
15
17
|
expose:
|
16
18
|
- "6000"
|
17
19
|
command: ping localhost
|
20
|
+
environment:
|
21
|
+
MYENV2: variable2
|
22
|
+
|
23
|
+
busybox3:
|
24
|
+
image: busybox
|
25
|
+
links:
|
26
|
+
- busybox2:bb2
|
27
|
+
command: ping localhost
|
@@ -5,7 +5,7 @@ describe ComposeContainer do
|
|
5
5
|
before(:all) do
|
6
6
|
@attributes = {
|
7
7
|
image: 'busybox:latest',
|
8
|
-
links: ['
|
8
|
+
links: ['service1:label', 'service2'],
|
9
9
|
ports: ['3000', '8000:8000', '127.0.0.1:8001:8001'],
|
10
10
|
volumes: {'/tmp' => {}},
|
11
11
|
command: 'ping -c 3 localhost',
|
@@ -17,7 +17,8 @@ describe ComposeContainer do
|
|
17
17
|
|
18
18
|
it 'should prepare attributes correctly' do
|
19
19
|
expect(@entry.attributes[:image]).to eq(@attributes[:image])
|
20
|
-
expect(@entry.attributes[:links])
|
20
|
+
expect(@entry.attributes[:links])
|
21
|
+
.to eq({'service1' => 'label', 'service2' => 'service2'})
|
21
22
|
expect(@entry.attributes[:volumes]).to eq(@attributes[:volumes])
|
22
23
|
expect(@entry.attributes[:command]).to eq(@attributes[:command].split(' '))
|
23
24
|
expect(@entry.attributes[:environment]).to eq(@attributes[:environment])
|
@@ -133,4 +134,20 @@ describe ComposeContainer do
|
|
133
134
|
expect{@entry.start}.to raise_error(ArgumentError)
|
134
135
|
end
|
135
136
|
end
|
137
|
+
|
138
|
+
context 'With environment as a hash' do
|
139
|
+
before(:all) do
|
140
|
+
@attributes = {
|
141
|
+
image: 'busybox:latest',
|
142
|
+
command: 'ping -c 3 localhost',
|
143
|
+
environment: { ENVIRONMENT: 'VALUE' }
|
144
|
+
}
|
145
|
+
|
146
|
+
@entry = ComposeContainer.new(@attributes)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should prepare environment attribute correctly' do
|
150
|
+
expect(@entry.attributes[:environment]).to eq(%w(ENVIRONMENT=VALUE))
|
151
|
+
end
|
152
|
+
end
|
136
153
|
end
|
@@ -56,7 +56,7 @@ describe ComposeUtils do
|
|
56
56
|
it 'should recognize pattern "[service]"' do
|
57
57
|
links = ComposeUtils.format_links(['service'])
|
58
58
|
expect(links.key?('service')).to be true
|
59
|
-
expect(links['service']).
|
59
|
+
expect(links['service']).to eq('service')
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'should recognize pattern "[service:label]"' do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docker-compose-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: docker-api
|