chef-metal-docker 0.1.1 → 0.2
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f6ac421bc65fa8a3497942dbd04d15efb23badc
|
4
|
+
data.tar.gz: 1b23d70778b4bbece79836bb419cb3ecd462fc19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec3d7947e1e67187603842051249713a662ee9f800a8d4abd72fd10334a4e692c0005fd1f25c34a7121b01a5f6a5c3e5aea8f3f18416a2e8d5ccb882c943e3ce
|
7
|
+
data.tar.gz: a2df491bf80e944a349f256e333d6e759f2b4e2f46aab7a3ed6e7727507338a9c93dda64331ae516f50761a35b29464e70637891bb43f3dd44f8d47bb7629a72
|
@@ -3,8 +3,8 @@ require 'chef_metal/convergence_strategy/no_converge'
|
|
3
3
|
require 'chef_metal/convergence_strategy/install_cached'
|
4
4
|
require 'chef_metal_docker/helpers/container'
|
5
5
|
require 'chef_metal_docker/docker_transport'
|
6
|
-
require 'chef_metal_docker/docker_convergence_strategy'
|
7
6
|
require 'chef_metal_docker/docker_unix_machine'
|
7
|
+
require 'chef_metal/transport/ssh'
|
8
8
|
require 'docker'
|
9
9
|
|
10
10
|
module ChefMetalDocker
|
@@ -50,10 +50,12 @@ module ChefMetalDocker
|
|
50
50
|
#
|
51
51
|
# -- provisioner_url: docker:<URL of Docker API endpoint>
|
52
52
|
# -- base_image: Base image name to use, or repository_name:tag_name to use a specific tagged revision of that image
|
53
|
-
# --
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
53
|
+
# -- create_container: hash of a container to create. If present, no image will be created, just a container.
|
54
|
+
# Hash options:
|
55
|
+
# - command: command to run (if unspecified or nil, will spin up the container. If false, will not run anything and will just leave the image alone.)
|
56
|
+
# - container_options: options for container create (see http://docs.docker.io/en/latest/reference/api/docker_remote_api_v1.10/#create-a-container)
|
57
|
+
# - host_options: options for container start (see http://docs.docker.io/en/latest/reference/api/docker_remote_api_v1.10/#start-a-container)
|
58
|
+
# - ssh_options: hash of ssh options. Presence of hash indicates sshd is running in the container. Net::SSH.new(ssh_options['username'], ssh_options) will be called. Set 'sudo' to true to sudo all commands (will be detected if username != root)
|
57
59
|
#
|
58
60
|
# node['normal']['provisioner_output'] will be populated with information
|
59
61
|
# about the created machine. For lxc, it is a hash with this
|
@@ -77,29 +79,45 @@ module ChefMetalDocker
|
|
77
79
|
base_image_name = provisioner_options['base_image']
|
78
80
|
raise "base_image not specified in provisioner options!" if !base_image_name
|
79
81
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
#
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
82
|
+
if provisioner_options['create_container']
|
83
|
+
create_container(action_handler, provisioner_options, provisioner_output)
|
84
|
+
# We don't bother waiting ... our only job is to bring it up.
|
85
|
+
else # We are in image build mode. Get prepped.
|
86
|
+
# Tag the initial image. We aren't going to actually DO anything yet.
|
87
|
+
# We will start up after we converge!
|
88
|
+
base_image = Docker::Image.get(base_image_name)
|
89
|
+
begin
|
90
|
+
repository_image = Docker::Image.get("#{repository_name}:latest")
|
91
|
+
# If the current image does NOT have the base_image as an ancestor,
|
92
|
+
# we are going to have to re-tag it and rebuild.
|
93
|
+
if repository_image.history.any? { |entry| entry['Id'] == base_image.id }
|
94
|
+
tag_base_image = false
|
95
|
+
else
|
96
|
+
tag_base_image = true
|
97
|
+
end
|
98
|
+
rescue Docker::Error::NotFoundError
|
90
99
|
tag_base_image = true
|
91
100
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
action_handler.perform_action "Tag base image #{base_image_name} as #{repository_name}" do
|
97
|
-
base_image.tag('repo' => repository_name, 'force' => true)
|
101
|
+
if tag_base_image
|
102
|
+
action_handler.perform_action "Tag base image #{base_image_name} as #{repository_name}" do
|
103
|
+
base_image.tag('repo' => repository_name, 'force' => true)
|
104
|
+
end
|
98
105
|
end
|
99
106
|
end
|
100
107
|
|
101
108
|
node['normal']['provisioner_output'] = provisioner_output
|
102
109
|
|
110
|
+
if provisioner_options['create_container'] && provisioner_options['create_container']['ssh_options']
|
111
|
+
action_handler.perform_action "wait for node to start ssh" do
|
112
|
+
transport = transport_for(node)
|
113
|
+
Timeout::timeout(5*60) do
|
114
|
+
while !transport.available?
|
115
|
+
sleep(0.5)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
103
121
|
# Nothing else needs to happen until converge. We already have the image we need!
|
104
122
|
machine_for(node)
|
105
123
|
end
|
@@ -168,48 +186,87 @@ module ChefMetalDocker
|
|
168
186
|
private
|
169
187
|
|
170
188
|
def machine_for(node)
|
189
|
+
strategy = convergence_strategy_for(node)
|
171
190
|
ChefMetalDocker::DockerUnixMachine.new(node, transport_for(node), convergence_strategy_for(node))
|
172
191
|
end
|
173
192
|
|
174
193
|
def convergence_strategy_for(node)
|
175
194
|
provisioner_output = node['normal']['provisioner_output']
|
176
195
|
provisioner_options = node['normal']['provisioner_options']
|
177
|
-
strategy =
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
provisioner_options = node['normal']['provisioner_options'] || {}
|
183
|
-
options[:chef_client_timeout] = provisioner_options['chef_client_timeout'] if provisioner_options.has_key?('chef_client_timeout')
|
184
|
-
ChefMetal::ConvergenceStrategy::InstallCached.new(options)
|
185
|
-
end
|
186
|
-
container_configuration = provisioner_options['container_configuration'] || {}
|
187
|
-
if provisioner_options['command']
|
188
|
-
command = provisioner_options['command']
|
189
|
-
command = command.split(/\s+/) if command.is_a?(String)
|
190
|
-
container_configuration['Cmd'] = command
|
191
|
-
elsif provisioner_options['command'] == false
|
192
|
-
container_configuration = nil
|
193
|
-
else
|
194
|
-
# TODO how do we get things started? runit? cron? wassup here.
|
195
|
-
container_configuration['Cmd'] = %w(while 1; sleep 1000; end)
|
196
|
+
strategy = begin
|
197
|
+
options = {}
|
198
|
+
provisioner_options = node['normal']['provisioner_options'] || {}
|
199
|
+
options[:chef_client_timeout] = provisioner_options['chef_client_timeout'] if provisioner_options.has_key?('chef_client_timeout')
|
200
|
+
ChefMetal::ConvergenceStrategy::InstallCached.new(options)
|
196
201
|
end
|
197
|
-
ChefMetalDocker::DockerConvergenceStrategy.new(strategy,
|
198
|
-
provisioner_output['repository_name'],
|
199
|
-
provisioner_output['container_name'],
|
200
|
-
container_configuration,
|
201
|
-
provisioner_options['host_configuration'] || {},
|
202
|
-
credentials,
|
203
|
-
connection)
|
204
202
|
end
|
205
203
|
|
206
204
|
def transport_for(node)
|
205
|
+
provisioner_options = node['normal']['provisioner_options']
|
207
206
|
provisioner_output = node['normal']['provisioner_output']
|
208
|
-
|
209
|
-
provisioner_output['
|
210
|
-
|
211
|
-
|
212
|
-
|
207
|
+
if provisioner_options['create_container'] && provisioner_options['create_container']['ssh_options']
|
208
|
+
container = Docker::Container.get(provisioner_output['container_name'])
|
209
|
+
ssh_options = {
|
210
|
+
# TODO create a user known hosts file
|
211
|
+
# :user_known_hosts_file => vagrant_ssh_config['UserKnownHostsFile'],
|
212
|
+
# :paranoid => true,
|
213
|
+
:host_key_alias => "#{container.id}.docker"
|
214
|
+
}.merge(provisioner_options['create_container']['ssh_options'])
|
215
|
+
username = ssh_options.delete(:username)
|
216
|
+
options = {}
|
217
|
+
if ssh_options[:sudo] || (!ssh_options.has_key?(:sudo) && username != 'root')
|
218
|
+
if ssh_options[:password]
|
219
|
+
options[:prefix] = "echo #{ssh_options[:password]} | sudo -S -p '' "
|
220
|
+
else
|
221
|
+
options[:prefix] = 'sudo '
|
222
|
+
end
|
223
|
+
end
|
224
|
+
ssh_options.delete(:sudo)
|
225
|
+
ip_address = container.info['NetworkSettings']['IPAddress']
|
226
|
+
Chef::Log.debug("Container #{provisioner_output['container_name']} address is #{ip_address}")
|
227
|
+
ChefMetal::Transport::SSH.new(ip_address, username, ssh_options, options)
|
228
|
+
else
|
229
|
+
ChefMetalDocker::DockerTransport.new(
|
230
|
+
provisioner_output['repository_name'],
|
231
|
+
provisioner_output['container_name'],
|
232
|
+
credentials,
|
233
|
+
connection)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def create_container(action_handler, provisioner_options, provisioner_output)
|
238
|
+
container_name = provisioner_output['container_name']
|
239
|
+
|
240
|
+
container_configuration = provisioner_options['create_container']['container_configuration'] || {}
|
241
|
+
host_configuration = provisioner_options['create_container']['host_configuration'] || {}
|
242
|
+
command = provisioner_options['create_container']['command']
|
243
|
+
raise "Must pass create_container.command if creating a container" if !command
|
244
|
+
command = command.split(/\s+/) if command.is_a?(String)
|
245
|
+
container_configuration['Cmd'] = command
|
246
|
+
need_to_create = false
|
247
|
+
begin
|
248
|
+
# Try to get the container; if that fails, it doesn't exist and we start it.
|
249
|
+
container = Docker::Container.get(container_name)
|
250
|
+
if !container.info['State']['Running']
|
251
|
+
action_handler.perform_action "Delete old, non-running container" do
|
252
|
+
container.delete
|
253
|
+
end
|
254
|
+
need_to_create = true
|
255
|
+
end
|
256
|
+
|
257
|
+
rescue Docker::Error::NotFoundError
|
258
|
+
need_to_create = true
|
259
|
+
end
|
260
|
+
|
261
|
+
if need_to_create
|
262
|
+
action_handler.perform_action "Create new container and run container_configuration['Cmd']" do
|
263
|
+
container = Docker::Container.create({
|
264
|
+
'name' => container_name,
|
265
|
+
'Image' => provisioner_options['base_image']
|
266
|
+
}.merge(container_configuration), connection)
|
267
|
+
container.start!(host_configuration)
|
268
|
+
end
|
269
|
+
end
|
213
270
|
end
|
214
271
|
end
|
215
272
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-metal-docker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Duffield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -108,7 +108,6 @@ files:
|
|
108
108
|
- lib/chef/provider/docker_container.rb
|
109
109
|
- lib/chef/resource/docker_container.rb
|
110
110
|
- lib/chef_metal/provisioner_init/docker_init.rb
|
111
|
-
- lib/chef_metal_docker/docker_convergence_strategy.rb
|
112
111
|
- lib/chef_metal_docker/docker_provisioner.rb
|
113
112
|
- lib/chef_metal_docker/docker_transport.rb
|
114
113
|
- lib/chef_metal_docker/docker_unix_machine.rb
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'chef_metal/convergence_strategy'
|
2
|
-
require 'docker'
|
3
|
-
|
4
|
-
module ChefMetalDocker
|
5
|
-
class DockerConvergenceStrategy < ChefMetal::ConvergenceStrategy
|
6
|
-
def initialize(real_convergence_strategy, repository_name, container_name, container_configuration, host_configuration, credentials, connection)
|
7
|
-
@real_convergence_strategy = real_convergence_strategy
|
8
|
-
@repository_name = repository_name
|
9
|
-
@container_name = container_name
|
10
|
-
@container_configuration = container_configuration
|
11
|
-
@host_configuration = host_configuration
|
12
|
-
@credentials = credentials
|
13
|
-
@connection = connection
|
14
|
-
end
|
15
|
-
|
16
|
-
attr_reader :real_convergence_strategy
|
17
|
-
attr_reader :repository_name
|
18
|
-
attr_reader :container_name
|
19
|
-
attr_reader :container_configuration
|
20
|
-
attr_reader :host_configuration
|
21
|
-
attr_reader :credentials
|
22
|
-
attr_reader :connection
|
23
|
-
|
24
|
-
def setup_convergence(action_handler, machine, machine_resource)
|
25
|
-
real_convergence_strategy.setup_convergence(action_handler, machine, machine_resource)
|
26
|
-
end
|
27
|
-
|
28
|
-
def converge(action_handler, machine, chef_server)
|
29
|
-
real_convergence_strategy.converge(action_handler, machine, chef_server)
|
30
|
-
|
31
|
-
# After converge, we bring up the container command
|
32
|
-
if container_configuration
|
33
|
-
begin
|
34
|
-
container = Docker::Container.get(container_name)
|
35
|
-
action_handler.perform_action "Delete existing container" do
|
36
|
-
container.delete
|
37
|
-
end
|
38
|
-
rescue Docker::Error::NotFoundError
|
39
|
-
end
|
40
|
-
action_handler.perform_action "Create new container and run container_configuration['Cmd']" do
|
41
|
-
container = Docker::Container.create({
|
42
|
-
'name' => container_name,
|
43
|
-
'Image' => "#{repository_name}:latest"
|
44
|
-
}.merge(container_configuration), connection)
|
45
|
-
container.start!(host_configuration)
|
46
|
-
end
|
47
|
-
# We don't bother waiting ... our only job is to bring it up.
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def cleanup_convergence(action_handler, node)
|
52
|
-
real_convergence_strategy.cleanup_convergence(action_handler, node)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|