chef-provisioning-docker 0.8.0 → 0.9.0
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 +4 -4
- data/README.md +13 -8
- data/chef-provisioning-docker.gemspec +1 -1
- data/lib/chef/provisioning/docker_driver/docker_container_machine.rb +199 -13
- data/lib/chef/provisioning/docker_driver/docker_run_options.rb +593 -0
- data/lib/chef/provisioning/docker_driver/docker_transport.rb +120 -57
- data/lib/chef/provisioning/docker_driver/driver.rb +82 -148
- data/lib/chef/provisioning/docker_driver/version.rb +1 -1
- metadata +12 -5
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'chef/provisioning/transport'
|
2
|
+
require 'chef/provisioning/transport/ssh'
|
3
|
+
require 'chef/provisioning/docker_driver/chef_zero_http_proxy'
|
2
4
|
require 'docker'
|
3
5
|
require 'archive/tar/minitar'
|
4
6
|
require 'shellwords'
|
@@ -6,7 +8,7 @@ require 'uri'
|
|
6
8
|
require 'socket'
|
7
9
|
require 'mixlib/shellout'
|
8
10
|
require 'sys/proctable'
|
9
|
-
require '
|
11
|
+
require 'tempfile'
|
10
12
|
|
11
13
|
class Chef
|
12
14
|
module Provisioning
|
@@ -20,15 +22,15 @@ module DockerDriver
|
|
20
22
|
attr_reader :config
|
21
23
|
attr_accessor :container
|
22
24
|
|
23
|
-
def execute(command, options
|
24
|
-
Chef::Log.debug("execute '#{command}' with options #{options}")
|
25
|
-
|
25
|
+
def execute(command, timeout: nil, keep_stdin_open: nil, tty: nil, detached: nil, **options)
|
26
26
|
opts = {}
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
opts[:tty] = tty unless tty.nil?
|
28
|
+
opts[:detached] = detached unless detached.nil?
|
29
|
+
opts[:stdin] = keep_stdin_open unless keep_stdin_open.nil?
|
30
|
+
opts[:wait] = timeout unless timeout.nil?
|
30
31
|
|
31
32
|
command = Shellwords.split(command) if command.is_a?(String)
|
33
|
+
Chef::Log.debug("execute #{command.inspect} on container #{container.id} with options #{opts}'")
|
32
34
|
response = container.exec(command, opts) do |stream, chunk|
|
33
35
|
case stream
|
34
36
|
when :stdout
|
@@ -47,9 +49,11 @@ module DockerDriver
|
|
47
49
|
begin
|
48
50
|
tarfile = ''
|
49
51
|
# NOTE: this would be more efficient if we made it a stream and passed that to Minitar
|
50
|
-
container.
|
52
|
+
container.archive_out(path) do |block|
|
51
53
|
tarfile << block
|
52
54
|
end
|
55
|
+
rescue Docker::Error::NotFoundError
|
56
|
+
return nil
|
53
57
|
rescue Docker::Error::ServerError
|
54
58
|
if $!.message =~ /500/ || $!.message =~ /Could not find the file/
|
55
59
|
return nil
|
@@ -72,12 +76,12 @@ module DockerDriver
|
|
72
76
|
end
|
73
77
|
|
74
78
|
def write_file(path, content)
|
75
|
-
|
79
|
+
tar = StringIO.new(Docker::Util.create_tar(path => content))
|
80
|
+
container.archive_in_stream('/') { tar.read }
|
76
81
|
end
|
77
82
|
|
78
83
|
def download_file(path, local_path)
|
79
|
-
|
80
|
-
file = File.open(local_path, 'w')
|
84
|
+
file = File.open(local_path, 'wb')
|
81
85
|
begin
|
82
86
|
file.write(read_file(path))
|
83
87
|
file.close
|
@@ -87,71 +91,130 @@ module DockerDriver
|
|
87
91
|
end
|
88
92
|
|
89
93
|
def upload_file(local_path, path)
|
90
|
-
|
94
|
+
write_file(path, IO.read(local_path, mode: "rb"))
|
91
95
|
end
|
92
96
|
|
93
|
-
def make_url_available_to_remote(
|
94
|
-
|
95
|
-
|
96
|
-
uri.scheme
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
$1
|
113
|
-
end
|
114
|
-
|
115
|
-
if !@proxy_thread
|
116
|
-
# Listen to docker instances only, and forward to localhost
|
117
|
-
@proxy_thread = Thread.new do
|
118
|
-
Chef::Log.debug("Starting proxy thread: #{uri.host}:#{uri.port} <--> #{host}:#{uri.port}")
|
119
|
-
ChefZeroHttpProxy.new(uri.host, uri.port, host, uri.port).run
|
97
|
+
def make_url_available_to_remote(local_url)
|
98
|
+
uri = URI(local_url)
|
99
|
+
|
100
|
+
if uri.scheme == "chefzero" || is_local_machine(uri.host)
|
101
|
+
# chefzero: URLs are just http URLs with a shortcut if you are in-process.
|
102
|
+
# The remote machine is definitely not in-process.
|
103
|
+
uri.scheme = "http" if uri.scheme == "chefzero"
|
104
|
+
|
105
|
+
if docker_toolkit_transport
|
106
|
+
# Forward localhost on docker_machine -> chef-zero. The container will
|
107
|
+
# be able to access this because it was started with --net=host.
|
108
|
+
uri = docker_toolkit_transport.make_url_available_to_remote(uri.to_s)
|
109
|
+
uri = URI(uri)
|
110
|
+
@docker_toolkit_transport_thread ||= Thread.new do
|
111
|
+
begin
|
112
|
+
docker_toolkit_transport.send(:session).loop { true }
|
113
|
+
rescue
|
114
|
+
Chef::Log.error("SSH forwarding loop failed: #{$!}")
|
115
|
+
raise
|
120
116
|
end
|
117
|
+
Chef::Log.debug("Session loop completed normally")
|
121
118
|
end
|
122
|
-
Chef::Log.debug("Using Chef server URL: #{uri.to_s}")
|
123
|
-
|
124
|
-
return uri.to_s
|
125
119
|
else
|
126
|
-
|
120
|
+
# We are the host. Find the docker machine's gateway (us) and talk to that;
|
121
|
+
# and set up a little proxy that will forward the container's requests to
|
122
|
+
# chef-zero
|
123
|
+
result = execute('ip route list', :read_only => true)
|
124
|
+
|
125
|
+
Chef::Log.debug("IP route: #{result.stdout}")
|
126
|
+
|
127
|
+
if result.stdout =~ /default via (\S+)/
|
128
|
+
|
129
|
+
old_uri = uri.dup
|
130
|
+
|
131
|
+
uri.host = $1
|
132
|
+
|
133
|
+
if !@proxy_thread
|
134
|
+
# Listen to docker instances only, and forward to localhost
|
135
|
+
@proxy_thread = Thread.new do
|
136
|
+
begin
|
137
|
+
Chef::Log.debug("Starting proxy thread: #{old_uri.host}:#{old_uri.port} <--> #{uri.host}:#{uri.port}")
|
138
|
+
ChefZeroHttpProxy.new(uri.host, uri.port, old_uri.host, old_uri.port).run
|
139
|
+
rescue
|
140
|
+
Chef::Log.error("Proxy thread unable to start: #{$!}")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
else
|
145
|
+
raise "Cannot forward port: ip route ls did not show default in expected format.\nSTDOUT: #{result.stdout}"
|
146
|
+
end
|
147
|
+
|
127
148
|
end
|
128
149
|
end
|
129
|
-
|
150
|
+
|
151
|
+
uri.to_s
|
130
152
|
end
|
131
153
|
|
132
154
|
def disconnect
|
133
|
-
|
155
|
+
if @docker_toolkit_transport_thread
|
156
|
+
@docker_toolkit_transport_thread.kill
|
157
|
+
@docker_toolkit_transport_thread = nil
|
158
|
+
end
|
134
159
|
end
|
135
160
|
|
136
161
|
def available?
|
137
162
|
end
|
138
163
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
if proc.respond_to?(:cmdline)
|
146
|
-
if proc.send(:cmdline).to_s =~ /.*--comment boot2docker.*/
|
147
|
-
return true
|
148
|
-
end
|
164
|
+
def is_local_machine(host)
|
165
|
+
local_addrs = Socket.ip_address_list
|
166
|
+
host_addrs = Addrinfo.getaddrinfo(host, nil)
|
167
|
+
local_addrs.any? do |local_addr|
|
168
|
+
host_addrs.any? do |host_addr|
|
169
|
+
local_addr.ip_address == host_addr.ip_address
|
149
170
|
end
|
150
171
|
end
|
151
172
|
end
|
152
173
|
|
153
|
-
def
|
154
|
-
|
174
|
+
def docker_toolkit_transport(connection_url=nil)
|
175
|
+
if !defined?(@docker_toolkit_transport)
|
176
|
+
# Figure out which docker-machine this container is in
|
177
|
+
begin
|
178
|
+
docker_machines = `docker-machine ls --format "{{.Name}},{{.URL}}"`
|
179
|
+
rescue Errno::ENOENT
|
180
|
+
Chef::Log.debug("docker-machine ls returned ENOENT: Docker Toolkit is presumably not installed.")
|
181
|
+
@docker_toolkit_transport = nil
|
182
|
+
return
|
183
|
+
end
|
184
|
+
|
185
|
+
connection_url ||= container.connection.url
|
186
|
+
|
187
|
+
Chef::Log.debug("Found docker machines:")
|
188
|
+
docker_machine = nil
|
189
|
+
docker_machines.lines.each do |line|
|
190
|
+
machine_name, machine_url = line.chomp.split(',', 2)
|
191
|
+
Chef::Log.debug("- #{machine_name} at URL #{machine_url.inspect}")
|
192
|
+
if machine_url == connection_url
|
193
|
+
Chef::Log.debug("Docker machine #{machine_name} at URL #{machine_url} matches the container's URL #{connection_url}! Will use it for port forwarding.")
|
194
|
+
docker_machine = machine_name
|
195
|
+
end
|
196
|
+
end
|
197
|
+
if !docker_machine
|
198
|
+
Chef::Log.debug("Docker Toolkit is installed, but no Docker machine's URL matches #{connection_url.inspect}. Assuming docker must be installed as well ...")
|
199
|
+
@docker_toolkit_transport = nil
|
200
|
+
return
|
201
|
+
end
|
202
|
+
|
203
|
+
# Get the SSH information for the docker-machine
|
204
|
+
docker_toolkit_json = `docker-machine inspect #{docker_machine}`
|
205
|
+
machine_info = JSON.parse(docker_toolkit_json, create_additions: false)["Driver"]
|
206
|
+
ssh_host = machine_info["IPAddress"]
|
207
|
+
ssh_username = machine_info["SSHUser"]
|
208
|
+
ssh_options = {
|
209
|
+
# port: machine_info["SSHPort"], seems to be bad information (44930???)
|
210
|
+
keys: [ machine_info["SSHKeyPath"] ],
|
211
|
+
keys_only: true
|
212
|
+
}
|
213
|
+
|
214
|
+
Chef::Log.debug("Docker Toolkit is installed. Will use SSH transport with docker-machine #{docker_machine.inspect} to perform port forwarding.")
|
215
|
+
@docker_toolkit_transport = Chef::Provisioning::Transport::SSH.new(ssh_host, ssh_username, ssh_options, {}, Chef::Config)
|
216
|
+
end
|
217
|
+
@docker_toolkit_transport
|
155
218
|
end
|
156
219
|
|
157
220
|
class DockerResult
|
@@ -28,6 +28,10 @@ module DockerDriver
|
|
28
28
|
Driver.new(driver_url, config)
|
29
29
|
end
|
30
30
|
|
31
|
+
def driver_url
|
32
|
+
"docker:#{Docker.url}"
|
33
|
+
end
|
34
|
+
|
31
35
|
def initialize(driver_url, config)
|
32
36
|
super
|
33
37
|
url = Driver.connection_url(driver_url)
|
@@ -37,10 +41,14 @@ module DockerDriver
|
|
37
41
|
# to be set for command-line utilities
|
38
42
|
ENV['DOCKER_HOST'] = url
|
39
43
|
Chef::Log.debug("Setting Docker URL to #{url}")
|
40
|
-
Docker.url = url
|
41
44
|
end
|
42
45
|
|
43
|
-
|
46
|
+
ENV['DOCKER_HOST'] ||= url if url
|
47
|
+
Docker.logger = Chef::Log
|
48
|
+
options = Docker.options.dup || {}
|
49
|
+
options.merge!(read_timeout: 600)
|
50
|
+
options.merge!(config[:docker_connection].hash_dup) if config && config[:docker_connection]
|
51
|
+
@connection = Docker::Connection.new(url || Docker.url, options)
|
44
52
|
end
|
45
53
|
|
46
54
|
def self.canonicalize_url(driver_url, config)
|
@@ -75,6 +83,8 @@ module DockerDriver
|
|
75
83
|
action_handler,
|
76
84
|
machine_spec
|
77
85
|
)
|
86
|
+
|
87
|
+
# Grab options from existing machine (TODO seems wrong) and set the machine_spec to that
|
78
88
|
docker_options = machine_options[:docker_options]
|
79
89
|
container_id = nil
|
80
90
|
image_id = machine_options[:image_id]
|
@@ -84,7 +94,6 @@ module DockerDriver
|
|
84
94
|
image_id ||= machine_spec.reference['image_id']
|
85
95
|
docker_options ||= machine_spec.reference['docker_options']
|
86
96
|
end
|
87
|
-
|
88
97
|
container_name ||= machine_spec.name
|
89
98
|
machine_spec.reference = {
|
90
99
|
'driver_url' => driver_url,
|
@@ -93,110 +102,69 @@ module DockerDriver
|
|
93
102
|
'host_node' => action_handler.host_node,
|
94
103
|
'container_name' => container_name,
|
95
104
|
'image_id' => image_id,
|
96
|
-
'docker_options' => docker_options,
|
105
|
+
'docker_options' => stringize_keys(docker_options),
|
97
106
|
'container_id' => container_id
|
98
107
|
}
|
99
|
-
build_container(machine_spec, docker_options)
|
100
108
|
end
|
101
109
|
|
102
110
|
def ready_machine(action_handler, machine_spec, machine_options)
|
103
|
-
start_machine(action_handler, machine_spec, machine_options)
|
104
111
|
machine_for(machine_spec, machine_options)
|
105
112
|
end
|
106
113
|
|
107
|
-
def
|
114
|
+
def start_machine(action_handler, machine_spec, machine_options)
|
108
115
|
container = container_for(machine_spec)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
build_image(machine_spec, docker_options)
|
113
|
-
|
114
|
-
args = [
|
115
|
-
'docker',
|
116
|
-
'run',
|
117
|
-
'--name',
|
118
|
-
machine_spec.reference['container_name'],
|
119
|
-
'--detach'
|
120
|
-
]
|
121
|
-
|
122
|
-
if docker_options[:keep_stdin_open]
|
123
|
-
args << '-i'
|
124
|
-
end
|
125
|
-
|
126
|
-
if docker_options[:env]
|
127
|
-
docker_options[:env].each do |key, value|
|
128
|
-
args << '-e'
|
129
|
-
args << "#{key}=#{value}"
|
116
|
+
if container && !container.info['State']['Running']
|
117
|
+
action_handler.perform_action "start container #{machine_spec.name}" do
|
118
|
+
container.start!
|
130
119
|
end
|
131
120
|
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Connect to machine without acquiring it
|
124
|
+
def connect_to_machine(machine_spec, machine_options)
|
125
|
+
Chef::Log.debug('Connect to machine')
|
126
|
+
machine_for(machine_spec, machine_options)
|
127
|
+
end
|
132
128
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
def destroy_machine(action_handler, machine_spec, machine_options)
|
130
|
+
container = container_for(machine_spec)
|
131
|
+
if container
|
132
|
+
image_id = container.info['Image']
|
133
|
+
action_handler.perform_action "stop and destroy container #{machine_spec.name}" do
|
134
|
+
container.stop
|
135
|
+
container.delete
|
137
136
|
end
|
138
137
|
end
|
138
|
+
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
def stop_machine(action_handler, machine_spec, machine_options)
|
141
|
+
container = container_for(machine_spec)
|
142
|
+
if container.info['State']['Running']
|
143
|
+
action_handler.perform_action "stop container #{machine_spec.name}" do
|
144
|
+
container.stop!
|
144
145
|
end
|
145
146
|
end
|
146
|
-
|
147
|
-
args << image.id
|
148
|
-
args += Shellwords.split("/bin/sh -c 'while true;do sleep 1; done'")
|
149
|
-
|
150
|
-
cmdstr = Shellwords.join(args)
|
151
|
-
Chef::Log.debug("Executing #{cmdstr}")
|
152
|
-
|
153
|
-
cmd = Mixlib::ShellOut.new(cmdstr)
|
154
|
-
cmd.run_command
|
155
|
-
|
156
|
-
container = Docker::Container.get(machine_spec.reference['container_name'])
|
157
|
-
|
158
|
-
Chef::Log.debug("Container id: #{container.id}")
|
159
|
-
machine_spec.reference['container_id'] = container.id
|
160
|
-
container
|
161
147
|
end
|
162
148
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
source_repository = base_image[:repository]
|
167
|
-
source_tag = base_image[:tag]
|
168
|
-
|
169
|
-
target_tag = machine_spec.reference['container_name']
|
170
|
-
|
171
|
-
image = Docker::Image.create(
|
172
|
-
'fromImage' => source_name,
|
173
|
-
'repo' => source_repository,
|
174
|
-
'tag' => source_tag
|
175
|
-
)
|
176
|
-
|
177
|
-
Chef::Log.debug("Allocated #{image}")
|
178
|
-
image.tag('repo' => 'chef', 'tag' => target_tag)
|
179
|
-
Chef::Log.debug("Tagged image #{image}")
|
180
|
-
|
181
|
-
machine_spec.reference['image_id'] = image.id
|
182
|
-
image
|
183
|
-
end
|
149
|
+
#
|
150
|
+
# Images
|
151
|
+
#
|
184
152
|
|
185
153
|
def allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options)
|
154
|
+
tag_container_image(action_handler, machine_spec, image_spec)
|
155
|
+
|
186
156
|
# Set machine options on the image to match our newly created image
|
187
157
|
image_spec.reference = {
|
188
158
|
'driver_url' => driver_url,
|
189
159
|
'driver_version' => Chef::Provisioning::DockerDriver::VERSION,
|
190
160
|
'allocated_at' => Time.now.to_i,
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
:tag => image_spec.name
|
196
|
-
},
|
197
|
-
:from_image => true
|
161
|
+
'docker_options' => {
|
162
|
+
'base_image' => {
|
163
|
+
'name' => image_spec.name
|
164
|
+
}
|
198
165
|
}
|
199
166
|
}
|
167
|
+
|
200
168
|
# Workaround for chef/chef-provisioning-docker#37
|
201
169
|
machine_spec.attrs[:keep_image] = true
|
202
170
|
end
|
@@ -207,66 +175,33 @@ module DockerDriver
|
|
207
175
|
|
208
176
|
# workaround for https://github.com/chef/chef-provisioning/issues/358.
|
209
177
|
def destroy_image(action_handler, image_spec, image_options, machine_options={})
|
210
|
-
image =
|
178
|
+
image = image_for(image_spec)
|
211
179
|
image.delete unless image.nil?
|
212
180
|
end
|
213
181
|
|
214
|
-
|
215
|
-
def connect_to_machine(machine_spec, machine_options)
|
216
|
-
Chef::Log.debug('Connect to machine')
|
217
|
-
machine_for(machine_spec, machine_options)
|
218
|
-
end
|
182
|
+
private
|
219
183
|
|
220
|
-
def
|
184
|
+
def tag_container_image(action_handler, machine_spec, image_spec)
|
221
185
|
container = container_for(machine_spec)
|
222
|
-
|
223
|
-
|
224
|
-
container.
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
image = find_image(machine_spec)
|
229
|
-
Chef::Log.debug("Destroying image: chef:#{image.id}")
|
230
|
-
image.delete
|
186
|
+
existing_image = image_for(image_spec)
|
187
|
+
unless existing_image && existing_image.id == container.info['Image']
|
188
|
+
image = Docker::Image.get(container.info['Image'], {}, @connection)
|
189
|
+
action_handler.perform_action "tag image #{container.info['Image']} as chef-images/#{image_spec.name}" do
|
190
|
+
image.tag('repo' => image_spec.name, 'force' => true)
|
191
|
+
end
|
231
192
|
end
|
232
193
|
end
|
233
194
|
|
234
|
-
def
|
235
|
-
|
236
|
-
return if container.nil?
|
237
|
-
|
238
|
-
container.stop if container.info['State']['Running']
|
195
|
+
def to_camel_case(name)
|
196
|
+
name.split('_').map { |x| x.capitalize }.join("")
|
239
197
|
end
|
240
198
|
|
241
|
-
def
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
rescue Docker::Error::NotFoundError
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
if image.nil?
|
252
|
-
image_name = "chef:#{machine_spec.reference['container_name']}"
|
253
|
-
if machine_spec.from_image
|
254
|
-
base_image = base_image_for(machine_spec)
|
255
|
-
image_name = "#{base_image[:repository]}:#{base_image[:tag]}"
|
256
|
-
end
|
257
|
-
|
258
|
-
image = Docker::Image.all.select {
|
259
|
-
|i| i.info['RepoTags'].include? image_name
|
260
|
-
}.first
|
261
|
-
|
262
|
-
if machine_spec.from_image && image.nil?
|
263
|
-
raise "Unable to locate machine_image for #{image_name}"
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
machine_spec.reference['image_id'] = image.id if image
|
268
|
-
|
269
|
-
image
|
199
|
+
def to_snake_case(name)
|
200
|
+
# ExposedPorts -> _exposed_ports
|
201
|
+
name = name.gsub(/[A-Z]/) { |x| "_#{x.downcase}" }
|
202
|
+
# _exposed_ports -> exposed_ports
|
203
|
+
name = name[1..-1] if name.start_with?('_')
|
204
|
+
name
|
270
205
|
end
|
271
206
|
|
272
207
|
def from_image_from_action_handler(action_handler, machine_spec)
|
@@ -280,22 +215,11 @@ module DockerDriver
|
|
280
215
|
end
|
281
216
|
end
|
282
217
|
|
283
|
-
def driver_url
|
284
|
-
"docker:#{Docker.url}"
|
285
|
-
end
|
286
|
-
|
287
|
-
def start_machine(action_handler, machine_spec, machine_options)
|
288
|
-
container = container_for(machine_spec)
|
289
|
-
if container && !container.info['State']['Running']
|
290
|
-
container.start
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
218
|
def machine_for(machine_spec, machine_options)
|
295
219
|
Chef::Log.debug('machine_for...')
|
296
|
-
docker_options = machine_options[:docker_options] || Mash.from_hash(machine_spec.reference['docker_options'])
|
220
|
+
docker_options = machine_options[:docker_options] || Mash.from_hash(machine_spec.reference['docker_options'] || {})
|
297
221
|
|
298
|
-
container =
|
222
|
+
container = container_for(machine_spec)
|
299
223
|
|
300
224
|
if machine_spec.from_image
|
301
225
|
convergence_strategy = Chef::Provisioning::ConvergenceStrategy::NoConverge.new({}, config)
|
@@ -310,22 +234,32 @@ module DockerDriver
|
|
310
234
|
machine_spec,
|
311
235
|
transport,
|
312
236
|
convergence_strategy,
|
237
|
+
@connection,
|
313
238
|
docker_options[:command]
|
314
239
|
)
|
315
240
|
end
|
316
241
|
|
317
242
|
def container_for(machine_spec)
|
318
|
-
container_id = machine_spec.reference['container_id']
|
319
243
|
begin
|
320
|
-
|
244
|
+
Docker::Container.get(machine_spec.name, {}, @connection)
|
245
|
+
rescue Docker::Error::NotFoundError
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def image_for(image_spec)
|
250
|
+
begin
|
251
|
+
Docker::Image.get(image_spec.name, {}, @connection)
|
321
252
|
rescue Docker::Error::NotFoundError
|
322
253
|
end
|
323
254
|
end
|
324
255
|
|
325
|
-
def
|
326
|
-
|
327
|
-
|
328
|
-
|
256
|
+
def stringize_keys(hash)
|
257
|
+
if hash
|
258
|
+
hash.each_with_object({}) do |(k,v),hash|
|
259
|
+
v = stringize_keys(v) if v.is_a?(Hash)
|
260
|
+
hash[k.to_s] = v
|
261
|
+
end
|
262
|
+
end
|
329
263
|
end
|
330
264
|
end
|
331
265
|
end
|