chef-provisioning-docker 0.11.0 → 1.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +3 -0
- data/README.md +51 -62
- data/chef-provisioning-docker.gemspec +4 -4
- data/lib/chef/provisioning/docker_driver/docker_container_machine.rb +13 -199
- data/lib/chef/provisioning/docker_driver/docker_transport.rb +21 -43
- data/lib/chef/provisioning/docker_driver/driver.rb +167 -76
- data/lib/chef/provisioning/docker_driver/version.rb +1 -1
- data/lib/chef/provisioning/driver_init/docker.rb +1 -1
- metadata +14 -27
- data/lib/chef/provisioning/docker_driver/chef_zero_http_proxy.rb +0 -95
- data/lib/chef/provisioning/docker_driver/docker_run_options.rb +0 -593
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a24a00feb49b30d7a76c5f0d2c6441114b961264
|
4
|
+
data.tar.gz: 4c24b6bd38a87d0afd01127e9266610e5efe1624
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c86add037f7fcb734e8884ab2116d2b13cc5eb9cbb2cd0c976e58f7e37313bde3ba82979aa950c6313c84d3ca5b048201d0b1ab7a067a378508d897773e7eeb2
|
7
|
+
data.tar.gz: ea5067b1773a9ec1eb218989de89d5023723a5fdfb3bdca40aa07d417f31e36f3ebe283847ca26d39f790c96eaac3b32b4b250633fe6bfe74f39562bb1cf172b
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# chef-provisioning-docker
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/chef/chef-provisioning-docker.svg?branch=master)](https://travis-ci.org/chef/chef-provisioning-docker) [![Gem Version](https://badge.fury.io/rb/chef-provisioning-docker.svg)](http://badge.fury.io/rb/chef-provisioning-docker)
|
4
|
-
|
5
3
|
How to use:
|
6
4
|
|
7
|
-
First you need to ensure that Docker is running. This can be done on a Linux host using Docker's installers or on OSX using boot2docker. Once you have that, you can install the dependencies with Bundler and then use the Docker
|
5
|
+
First you need to ensure that Docker is running. This can be done on a Linux host using Docker's installers or on OSX using boot2docker. Once you have that, you can install the dependencies with Bundler and then use the Docker like the following:
|
8
6
|
|
9
7
|
```
|
10
8
|
CHEF_DRIVER=docker bundle exec chef-client -z docker_ubuntu_image.rb
|
@@ -18,66 +16,58 @@ Using this , you can then define a machine similar to the following example:
|
|
18
16
|
|
19
17
|
```ruby
|
20
18
|
require 'chef/provisioning/docker_driver'
|
21
|
-
with_driver 'docker'
|
22
19
|
|
23
20
|
machine 'wario' do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
:command => '/usr/sbin/sshd -p 8022 -D',
|
34
|
-
|
35
|
-
#ENV (Environment Variables)
|
36
|
-
#Set any env var in the container by using one or more -e flags, even overriding those already defined by the developer with a Dockerfile ENV
|
37
|
-
:env => {
|
38
|
-
"deep" => 'purple',
|
39
|
-
"led" => 'zeppelin'
|
40
|
-
},
|
41
|
-
|
42
|
-
# Ports can be one of two forms:
|
43
|
-
# src_port (string or integer) is a pass-through, i.e 8022 or "9933"
|
44
|
-
# src:dst (string) is a map from src to dst, i.e "8022:8023" maps 8022 externally to 8023 in the container
|
45
|
-
|
46
|
-
# Example (multiple):
|
47
|
-
:ports => [8022, "8023:9000", "9500"],
|
48
|
-
|
49
|
-
# Examples (single):
|
50
|
-
:ports => 1234,
|
51
|
-
:ports => "2345:6789",
|
52
|
-
|
53
|
-
# Volumes can be one of three forms:
|
54
|
-
# src_volume (string) is volume to add to container, i.e. creates new volume inside container at "/tmp"
|
55
|
-
# src:dst (string) mounts host's directory src to container's dst, i.e "/tmp:/tmp1" mounts host's directory /tmp to container's /tmp1
|
56
|
-
# src:dst:mode (string) mounts host's directory src to container's dst with the specified mount option, i.e "/:/rootfs:ro" mounts read-only host's root (/) folder to container's /rootfs
|
57
|
-
# See more details on Docker volumes at https://github.com/docker/docker/blob/master/docs/sources/userguide/dockervolumes.md .
|
58
|
-
|
59
|
-
# Example (single):
|
60
|
-
:volumes => "/tmp",
|
61
|
-
|
62
|
-
# Example (multiple):
|
63
|
-
:volumes => ["/tmp:/tmp", "/:/rootfs:ro"],
|
64
|
-
|
65
|
-
# if you need to keep stdin open (i.e docker run -i)
|
66
|
-
# :keep_stdin_open => true
|
21
|
+
recipe 'openssh::default'
|
22
|
+
|
23
|
+
machine_options :docker_options => {
|
24
|
+
:base_image => {
|
25
|
+
:name => 'ubuntu',
|
26
|
+
:repository => 'ubuntu',
|
27
|
+
:tag => '14.04'
|
28
|
+
},
|
29
|
+
:command => '/usr/sbin/sshd -p 8022 -D',
|
67
30
|
|
31
|
+
#ENV (Environment Variables)
|
32
|
+
#Set any env var in the container by using one or more -e flags, even overriding those already defined by the developer with a Dockerfile ENV
|
33
|
+
:env => {
|
34
|
+
"deep" => 'purple',
|
35
|
+
"led" => 'zeppelin'
|
68
36
|
},
|
69
|
-
# optional, default timeout is 600
|
70
|
-
docker_connection: {
|
71
|
-
:read_timeout => 1000,
|
72
|
-
}
|
73
|
-
)
|
74
37
|
|
38
|
+
# Ports can be one of two forms:
|
39
|
+
# src_port (string or integer) is a pass-through, i.e 8022 or "9933"
|
40
|
+
# src:dst (string) is a map from src to dst, i.e "8022:8023" maps 8022 externally to 8023 in the container
|
41
|
+
|
42
|
+
# Example (multiple):
|
43
|
+
:ports => [8022, "8023:9000", "9500"],
|
44
|
+
|
45
|
+
# Examples (single):
|
46
|
+
:ports => 1234,
|
47
|
+
:ports => "2345:6789",
|
48
|
+
|
49
|
+
# Volumes can be one of three forms:
|
50
|
+
# src_volume (string) is volume to add to container, i.e. creates new volume inside container at "/tmp"
|
51
|
+
# src:dst (string) mounts host's directory src to container's dst, i.e "/tmp:/tmp1" mounts host's directory /tmp to container's /tmp1
|
52
|
+
# src:dst:mode (string) mounts host's directory src to container's dst with the specified mount option, i.e "/:/rootfs:ro" mounts read-only host's root (/) folder to container's /rootfs
|
53
|
+
# See more details on Docker volumes at https://github.com/docker/docker/blob/master/docs/sources/userguide/dockervolumes.md .
|
54
|
+
|
55
|
+
# Example (single):
|
56
|
+
:volumes => "/tmp",
|
57
|
+
|
58
|
+
# Example (multiple):
|
59
|
+
:volumes => ["/tmp:/tmp", "/:/rootfs:ro"],
|
60
|
+
|
61
|
+
# if you need to keep stdin open (i.e docker run -i)
|
62
|
+
# :keep_stdin_open => true
|
63
|
+
|
64
|
+
}
|
75
65
|
end
|
76
66
|
```
|
77
67
|
|
78
68
|
## Machine images
|
79
69
|
|
80
|
-
This
|
70
|
+
This supports the new machine image paradigm; with Docker you can build a base image, save that and use it to create a new container. Here is an example of this:
|
81
71
|
|
82
72
|
```ruby
|
83
73
|
require 'chef/provisioning/docker_driver'
|
@@ -85,27 +75,26 @@ require 'chef/provisioning/docker_driver'
|
|
85
75
|
machine_image 'ssh_server' do
|
86
76
|
recipe 'openssh'
|
87
77
|
|
88
|
-
machine_options
|
89
|
-
:docker_options => {
|
78
|
+
machine_options :docker_options => {
|
90
79
|
:base_image => {
|
91
80
|
:name => 'ubuntu',
|
92
81
|
:repository => 'ubuntu',
|
93
82
|
:tag => '14.04'
|
94
83
|
}
|
95
|
-
|
96
|
-
)
|
84
|
+
}
|
97
85
|
end
|
98
86
|
|
99
87
|
machine 'ssh00' do
|
100
88
|
from_image 'ssh_server'
|
101
89
|
|
102
|
-
machine_options
|
103
|
-
:docker_options => {
|
90
|
+
machine_options :docker_options => {
|
104
91
|
:command => '/usr/sbin/sshd -D -o UsePAM=no -o UsePrivilegeSeparation=no -o PidFile=/tmp/sshd.pid',
|
105
92
|
:ports => [22]
|
106
|
-
|
107
|
-
)
|
93
|
+
}
|
108
94
|
end
|
109
95
|
```
|
110
96
|
|
111
|
-
This will create a docker container based on Ubuntu 14.04 and
|
97
|
+
This will create a docker container based on Ubuntu 14.04 and
|
98
|
+
then execute the Apache recipe and run the /usr/sbin/httpd command
|
99
|
+
as the container's run command.
|
100
|
+
|
@@ -9,12 +9,12 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.summary = 'Provisioner for creating Docker containers in Chef Provisioning.'
|
10
10
|
s.description = s.summary
|
11
11
|
s.author = 'Tom Duffield'
|
12
|
-
s.email = 'tom@
|
13
|
-
s.homepage = 'https://github.com/
|
12
|
+
s.email = 'tom@getchef.com'
|
13
|
+
s.homepage = 'https://github.com/opscode/chef-provisioning-docker'
|
14
14
|
|
15
15
|
s.add_dependency 'chef'
|
16
|
-
s.add_dependency 'chef-provisioning', '
|
17
|
-
s.add_dependency 'docker-api', '~> 1.
|
16
|
+
s.add_dependency 'chef-provisioning', '~> 1.0'
|
17
|
+
s.add_dependency 'docker-api', '~> 1.25'
|
18
18
|
s.add_dependency 'minitar'
|
19
19
|
s.add_dependency 'sys-proctable'
|
20
20
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'chef/provisioning/machine/unix_machine'
|
2
|
-
require 'chef/provisioning/docker_driver/docker_run_options'
|
3
2
|
|
4
3
|
class Chef
|
5
4
|
module Provisioning
|
@@ -10,214 +9,29 @@ module DockerDriver
|
|
10
9
|
# Options is expected to contain the optional keys
|
11
10
|
# :command => the final command to execute
|
12
11
|
# :ports => a list of port numbers to listen on
|
13
|
-
def initialize(machine_spec, transport, convergence_strategy,
|
12
|
+
def initialize(machine_spec, transport, convergence_strategy, command = nil)
|
14
13
|
super(machine_spec, transport, convergence_strategy)
|
15
14
|
@command = command
|
16
15
|
@transport = transport
|
17
|
-
@connection = connection
|
18
|
-
end
|
19
|
-
|
20
|
-
def setup_convergence(action_handler)
|
21
|
-
# Build a converge container to converge in
|
22
|
-
transport.container = build_converge_container(action_handler)
|
23
|
-
unless transport.container.info['State']['Running']
|
24
|
-
action_handler.perform_action "start converge container chef-converge.#{machine_spec.name}" do
|
25
|
-
transport.container.start!
|
26
|
-
end
|
27
|
-
end
|
28
|
-
super(action_handler)
|
29
|
-
# Commit after convergence setup (such as the install of Chef)
|
30
|
-
# to break up the cost of the commit and avoid read timeouts
|
31
|
-
transport.container.commit
|
32
16
|
end
|
33
17
|
|
34
18
|
def converge(action_handler)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
unless transport.container.info['State']['Running']
|
41
|
-
action_handler.perform_action "start converge container chef-converge.#{machine_spec.name}" do
|
42
|
-
transport.container.start!
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Then, converge ...
|
47
|
-
super(action_handler)
|
48
|
-
|
49
|
-
# Save the converged image ...
|
50
|
-
converged_image = commit_converged_image(action_handler, machine_spec, transport.container)
|
51
|
-
|
52
|
-
# Build the new container
|
53
|
-
transport.container = create_container(action_handler, machine_spec, converged_image)
|
54
|
-
|
55
|
-
# Finally, start it!
|
56
|
-
action_handler.perform_action "start container #{machine_spec.name}" do
|
57
|
-
transport.container.start!
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def container_config(action_handler, machine_spec)
|
64
|
-
docker_options = machine_spec.reference['docker_options'] || {}
|
65
|
-
|
66
|
-
# We're going to delete things to make it easier on ourselves, back it up
|
67
|
-
docker_options = docker_options.dup
|
68
|
-
|
69
|
-
# Bring in from_image
|
70
|
-
if machine_spec.from_image
|
71
|
-
docker_options['base_image'] ||= {}
|
72
|
-
docker_options['base_image']['name'] = machine_spec.from_image
|
73
|
-
end
|
74
|
-
|
75
|
-
# Respect :container_config
|
76
|
-
config = stringize_keys(docker_options.delete('container_config') || {})
|
77
|
-
|
78
|
-
# Respect :base_image
|
79
|
-
image = base_image(action_handler, docker_options.delete('base_image'))
|
80
|
-
config['Image'] = image if image
|
81
|
-
|
82
|
-
# Respect everything else
|
83
|
-
DockerRunOptions.include_command_line_options_in_container_config(config, docker_options)
|
84
|
-
end
|
85
|
-
|
86
|
-
# Get the converge container for this machine
|
87
|
-
def converge_container_for(machine_spec)
|
88
|
-
begin
|
89
|
-
Docker::Container.get("chef-converge.#{machine_spec.name}", {}, @connection)
|
90
|
-
rescue Docker::Error::NotFoundError
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def container_for(machine_spec)
|
95
|
-
begin
|
96
|
-
Docker::Container.get(machine_spec.name, {}, @connection)
|
97
|
-
rescue Docker::Error::NotFoundError
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Builds a container that has the same properties as the final container,
|
102
|
-
# but with a couple of tweaks to allow processes to run and converge the
|
103
|
-
# container.
|
104
|
-
def build_converge_container(action_handler)
|
105
|
-
# If a converge container already exists, do nothing. TODO check if it's different!!!
|
106
|
-
converge_container = converge_container_for(machine_spec)
|
107
|
-
if converge_container
|
108
|
-
return converge_container
|
109
|
-
end
|
110
|
-
|
111
|
-
# Create a chef-capable container (just like the final one, but with --net=host
|
112
|
-
# and a command that keeps it open). Base it on the image.
|
113
|
-
config = container_config(action_handler, machine_spec)
|
114
|
-
config.merge!(
|
115
|
-
'name' => "chef-converge.#{machine_spec.reference['container_name']}",
|
116
|
-
'Cmd' => [ "/bin/sh", "-c", "while true;do sleep 1000; done" ],
|
19
|
+
super action_handler
|
20
|
+
Chef::Log.debug("DockerContainerMachine converge complete, executing #{@command} in #{@container_name}")
|
21
|
+
image = transport.container.commit(
|
22
|
+
'repo' => 'chef',
|
23
|
+
'tag' => machine_spec.reference['container_name']
|
117
24
|
)
|
118
|
-
|
119
|
-
# so we can open up the port we need. Don't force it in other cases, though.
|
120
|
-
if transport.is_local_machine(URI(transport.config[:chef_server_url]).host) &&
|
121
|
-
transport.docker_toolkit_transport(@connection.url)
|
122
|
-
config['HostConfig'] ||= {}
|
123
|
-
config['HostConfig'].merge!('NetworkMode' => 'host')
|
124
|
-
# These are incompatible with NetworkMode: host
|
125
|
-
config['HostConfig'].delete('Links')
|
126
|
-
config['HostConfig'].delete('ExtraHosts')
|
127
|
-
config.delete('NetworkSettings')
|
128
|
-
end
|
129
|
-
# Don't use any resources that need to be shared (such as exposed ports)
|
130
|
-
config.delete('ExposedPorts')
|
131
|
-
|
132
|
-
Chef::Log.debug("Creating converge container with config #{config} ...")
|
133
|
-
action_handler.perform_action "create container to converge #{machine_spec.name}" do
|
134
|
-
# create deletes the name :(
|
135
|
-
Docker::Container.create(config.dup, @connection)
|
136
|
-
converge_container = Docker::Container.get(config['name'], {}, @connection)
|
137
|
-
Chef::Log.debug("Created converge container #{converge_container.id}")
|
138
|
-
end
|
139
|
-
converge_container
|
140
|
-
end
|
141
|
-
|
142
|
-
# Commit the converged container to an image. Called by converge.
|
143
|
-
def commit_converged_image(action_handler, machine_spec, converge_container)
|
144
|
-
# Commit the converged container to an image
|
145
|
-
converged_image = nil
|
146
|
-
action_handler.perform_action "commit and delete converged container for #{machine_spec.name}" do
|
147
|
-
converged_image = converge_container.commit
|
148
|
-
converge_container.stop!
|
149
|
-
converge_container.delete
|
150
|
-
end
|
151
|
-
converged_image
|
152
|
-
end
|
153
|
-
|
154
|
-
# Create the final container from the converged image
|
155
|
-
def create_container(action_handler, machine_spec, converged_image)
|
156
|
-
# Check if the container already exists.
|
157
|
-
container = container_for(machine_spec)
|
158
|
-
if container
|
159
|
-
# If it's the same image, just return; don't stop and start.
|
160
|
-
if container.info['Image'] == converged_image.id
|
161
|
-
return container
|
162
|
-
else
|
163
|
-
# If the container exists but is based on an old image, destroy it.
|
164
|
-
action_handler.perform_action "stop and delete running container for #{machine_spec.name}" do
|
165
|
-
container.stop!
|
166
|
-
container.delete
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
25
|
+
machine_spec.reference['image_id'] = image.id
|
170
26
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
'Image' => converged_image.id
|
176
|
-
)
|
177
|
-
action_handler.perform_action "create final container for #{machine_spec.name}" do
|
178
|
-
container = Docker::Container.create(config, @connection)
|
27
|
+
if @command && transport.container.info['Config']['Cmd'].join(' ') != @command
|
28
|
+
transport.container.delete(:force => true)
|
29
|
+
container = image.run(Shellwords.split(@command))
|
30
|
+
container.rename(machine_spec.reference['container_name'])
|
179
31
|
machine_spec.reference['container_id'] = container.id
|
180
|
-
|
181
|
-
end
|
182
|
-
container
|
183
|
-
end
|
184
|
-
|
185
|
-
def stringize_keys(hash)
|
186
|
-
hash.each_with_object({}) do |(k,v),hash|
|
187
|
-
v = stringize_keys(v) if v.is_a?(Hash)
|
188
|
-
hash[k.to_s] = v
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def base_image(action_handler, base_image_value)
|
193
|
-
case base_image_value
|
194
|
-
when Hash
|
195
|
-
params = base_image_value.dup
|
196
|
-
if !params['fromImage']
|
197
|
-
params['fromImage'] = params.delete('name')
|
198
|
-
params['fromImage'] = "#{params['fromImage']}:#{params.delete('tag')}" if params['tag']
|
199
|
-
end
|
200
|
-
when String
|
201
|
-
params = { 'fromImage' => base_image_value }
|
202
|
-
when nil
|
203
|
-
return nil
|
204
|
-
else
|
205
|
-
raise "Unexpected type #{base_image_value.class} for docker_options[:base_image]!"
|
206
|
-
end
|
207
|
-
|
208
|
-
image_name = params['fromImage']
|
209
|
-
repo, image_name = params['fromImage'].split('/', 2) if params['fromImage'].include?('/')
|
210
|
-
|
211
|
-
begin
|
212
|
-
image = Docker::Image.get(image_name, {}, @connection)
|
213
|
-
rescue Docker::Error::NotFoundError
|
214
|
-
# If it's not found, pull it.
|
215
|
-
action_handler.perform_action "pull #{params}" do
|
216
|
-
image = Docker::Image.create(params, @connection)
|
217
|
-
end
|
32
|
+
transport.container = container
|
218
33
|
end
|
219
|
-
|
220
|
-
image.id
|
34
|
+
machine_spec.save(action_handler)
|
221
35
|
end
|
222
36
|
end
|
223
37
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'chef/provisioning/transport'
|
2
2
|
require 'chef/provisioning/transport/ssh'
|
3
|
-
require 'chef/provisioning/docker_driver/chef_zero_http_proxy'
|
4
3
|
require 'docker'
|
5
4
|
require 'archive/tar/minitar'
|
6
5
|
require 'shellwords'
|
@@ -22,12 +21,11 @@ module DockerDriver
|
|
22
21
|
attr_reader :config
|
23
22
|
attr_accessor :container
|
24
23
|
|
25
|
-
def execute(command,
|
24
|
+
def execute(command, options={})
|
26
25
|
opts = {}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
opts[:wait] = timeout unless timeout.nil?
|
26
|
+
if options[:keep_stdin_open]
|
27
|
+
opts[:stdin] = true
|
28
|
+
end
|
31
29
|
|
32
30
|
command = Shellwords.split(command) if command.is_a?(String)
|
33
31
|
Chef::Log.debug("execute #{command.inspect} on container #{container.id} with options #{opts}'")
|
@@ -81,7 +79,7 @@ module DockerDriver
|
|
81
79
|
end
|
82
80
|
|
83
81
|
def download_file(path, local_path)
|
84
|
-
file = File.open(local_path, '
|
82
|
+
file = File.open(local_path, 'w')
|
85
83
|
begin
|
86
84
|
file.write(read_file(path))
|
87
85
|
file.close
|
@@ -91,7 +89,7 @@ module DockerDriver
|
|
91
89
|
end
|
92
90
|
|
93
91
|
def upload_file(local_path, path)
|
94
|
-
write_file(path, IO.read(local_path
|
92
|
+
write_file(path, IO.read(local_path))
|
95
93
|
end
|
96
94
|
|
97
95
|
def make_url_available_to_remote(local_url)
|
@@ -117,35 +115,16 @@ module DockerDriver
|
|
117
115
|
Chef::Log.debug("Session loop completed normally")
|
118
116
|
end
|
119
117
|
else
|
120
|
-
# We are the host.
|
121
|
-
#
|
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 = ENV["PROXY_HOST_OVERRIDE"] ? ENV["PROXY_HOST_OVERRIDE"] : $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
|
-
|
118
|
+
# We are the host. The docker machine was run with --net=host, so it
|
119
|
+
# will be able to talk to us automatically.
|
148
120
|
end
|
121
|
+
else
|
122
|
+
old_uri = uri.dup
|
123
|
+
# Find out our external network address of the URL and report it
|
124
|
+
# to the container in case it has no DNS (often the case).
|
125
|
+
uri.scheme = 'http' if 'chefzero' == uri.scheme && uri.host == 'localhost'
|
126
|
+
uri.host = Socket.getaddrinfo(uri.host, uri.scheme, nil, :STREAM)[0][3]
|
127
|
+
Chef::Log.debug("Looked up IP address of #{old_uri} and modified URL to point at it: #{uri}")
|
149
128
|
end
|
150
129
|
|
151
130
|
uri.to_s
|
@@ -161,6 +140,8 @@ module DockerDriver
|
|
161
140
|
def available?
|
162
141
|
end
|
163
142
|
|
143
|
+
private
|
144
|
+
|
164
145
|
def is_local_machine(host)
|
165
146
|
local_addrs = Socket.ip_address_list
|
166
147
|
host_addrs = Addrinfo.getaddrinfo(host, nil)
|
@@ -171,7 +152,7 @@ module DockerDriver
|
|
171
152
|
end
|
172
153
|
end
|
173
154
|
|
174
|
-
def docker_toolkit_transport
|
155
|
+
def docker_toolkit_transport
|
175
156
|
if !defined?(@docker_toolkit_transport)
|
176
157
|
# Figure out which docker-machine this container is in
|
177
158
|
begin
|
@@ -181,21 +162,18 @@ module DockerDriver
|
|
181
162
|
@docker_toolkit_transport = nil
|
182
163
|
return
|
183
164
|
end
|
184
|
-
|
185
|
-
connection_url ||= container.connection.url
|
186
|
-
|
187
165
|
Chef::Log.debug("Found docker machines:")
|
188
166
|
docker_machine = nil
|
189
167
|
docker_machines.lines.each do |line|
|
190
168
|
machine_name, machine_url = line.chomp.split(',', 2)
|
191
169
|
Chef::Log.debug("- #{machine_name} at URL #{machine_url.inspect}")
|
192
|
-
if machine_url ==
|
193
|
-
Chef::Log.debug("Docker machine #{machine_name} at URL #{machine_url} matches the container's URL #{
|
170
|
+
if machine_url == container.connection.url
|
171
|
+
Chef::Log.debug("Docker machine #{machine_name} at URL #{machine_url} matches the container's URL #{container.connection.url}! Will use it for port forwarding.")
|
194
172
|
docker_machine = machine_name
|
195
173
|
end
|
196
174
|
end
|
197
175
|
if !docker_machine
|
198
|
-
Chef::Log.debug("Docker Toolkit is installed, but no Docker machine's URL matches #{
|
176
|
+
Chef::Log.debug("Docker Toolkit is installed, but no Docker machine's URL matches #{container.connection.url.inspect}. Assuming docker must be installed as well ...")
|
199
177
|
@docker_toolkit_transport = nil
|
200
178
|
return
|
201
179
|
end
|