chef-provisioning-docker 0.7 → 0.8.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/Gemfile +5 -0
- data/README.md +6 -5
- data/Rakefile +9 -0
- data/chef-provisioning-docker.gemspec +31 -0
- data/lib/chef/provisioning/docker_driver/docker_container_machine.rb +16 -15
- data/lib/chef/provisioning/docker_driver/docker_transport.rb +20 -161
- data/lib/chef/provisioning/docker_driver/driver.rb +172 -111
- data/lib/chef/provisioning/docker_driver/version.rb +1 -1
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb7082e943ebcd274d30997976c1049a8eda063c
|
4
|
+
data.tar.gz: e453939b728683c8d9c0a74a313413a83496ec08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4852d7f066c734ecf52dc2cbe2b2121f40327d82078503c1ef98ac2ed3e2565a43c33e916fac11ac8fdaa5c726270b7c1bd805355ba8120d734e8e9d6282f40
|
7
|
+
data.tar.gz: c6c7f6e92b01b9451fafb5f46db02b28f92944394aab21cc08f556d694e481f874ad95692e31a84cba4d14d0dc4756dad52036288b2955c0b645191d3661454f
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -72,8 +72,8 @@ This supports the new machine image paradigm; with Docker you can build a base
|
|
72
72
|
```ruby
|
73
73
|
require 'chef/provisioning/docker_driver'
|
74
74
|
|
75
|
-
machine_image '
|
76
|
-
recipe '
|
75
|
+
machine_image 'ssh_server' do
|
76
|
+
recipe 'openssh'
|
77
77
|
|
78
78
|
machine_options :docker_options => {
|
79
79
|
:base_image => {
|
@@ -84,11 +84,12 @@ machine_image 'web_server' do
|
|
84
84
|
}
|
85
85
|
end
|
86
86
|
|
87
|
-
machine '
|
88
|
-
from_image '
|
87
|
+
machine 'ssh00' do
|
88
|
+
from_image 'ssh_server'
|
89
89
|
|
90
90
|
machine_options :docker_options => {
|
91
|
-
:command => '/usr/sbin/
|
91
|
+
:command => '/usr/sbin/sshd -D -o UsePAM=no -o UsePrivilegeSeparation=no -o PidFile=/tmp/sshd.pid',
|
92
|
+
:ports => [22]
|
92
93
|
}
|
93
94
|
end
|
94
95
|
```
|
data/Rakefile
CHANGED
@@ -4,3 +4,12 @@ require 'bundler/gem_tasks'
|
|
4
4
|
task :spec do
|
5
5
|
require File.expand_path('spec/run')
|
6
6
|
end
|
7
|
+
|
8
|
+
require "github_changelog_generator/task"
|
9
|
+
|
10
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
11
|
+
config.future_release = Chef::Provisioning::DockerDriver::VERSION
|
12
|
+
config.enhancement_labels = "enhancement,Enhancement,New Feature".split(",")
|
13
|
+
config.bug_labels = "bug,Bug,Improvement,Upstream Bug".split(",")
|
14
|
+
config.exclude_labels = "duplicate,question,invalid,wontfix,no_changelog,Exclude From Changelog,Question".split(",")
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/lib')
|
2
|
+
require 'chef/provisioning/docker_driver/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'chef-provisioning-docker'
|
6
|
+
s.version = Chef::Provisioning::DockerDriver::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.extra_rdoc_files = ['README.md', 'LICENSE' ]
|
9
|
+
s.summary = 'Provisioner for creating Docker containers in Chef Provisioning.'
|
10
|
+
s.description = s.summary
|
11
|
+
s.author = 'Tom Duffield'
|
12
|
+
s.email = 'tom@getchef.com'
|
13
|
+
s.homepage = 'https://github.com/opscode/chef-provisioning-docker'
|
14
|
+
|
15
|
+
s.add_dependency 'chef'
|
16
|
+
s.add_dependency 'chef-provisioning', '~> 1.0'
|
17
|
+
s.add_dependency 'docker-api'
|
18
|
+
s.add_dependency 'minitar'
|
19
|
+
s.add_dependency 'sys-proctable'
|
20
|
+
|
21
|
+
s.add_development_dependency 'rspec'
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
s.add_development_dependency 'github_changelog_generator'
|
24
|
+
|
25
|
+
s.bindir = "bin"
|
26
|
+
s.executables = %w( )
|
27
|
+
|
28
|
+
s.require_path = 'lib'
|
29
|
+
s.files = %w(Gemfile Rakefile LICENSE README.md) + Dir.glob("*.gemspec") +
|
30
|
+
Dir.glob("{distro,lib,tasks,spec}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
|
31
|
+
end
|
@@ -9,29 +9,30 @@ module DockerDriver
|
|
9
9
|
# Options is expected to contain the optional keys
|
10
10
|
# :command => the final command to execute
|
11
11
|
# :ports => a list of port numbers to listen on
|
12
|
-
def initialize(machine_spec, transport, convergence_strategy,
|
12
|
+
def initialize(machine_spec, transport, convergence_strategy, command = nil)
|
13
13
|
super(machine_spec, transport, convergence_strategy)
|
14
|
-
@
|
15
|
-
@command = opts[:command]
|
16
|
-
@ports = opts[:ports]
|
17
|
-
@volumes = opts[:volumes]
|
18
|
-
@keep_stdin_open = opts[:keep_stdin_open]
|
19
|
-
@container_name = machine_spec.location['container_name']
|
14
|
+
@command = command
|
20
15
|
@transport = transport
|
21
16
|
end
|
22
17
|
|
23
|
-
def execute_always(command, options = {})
|
24
|
-
transport.execute(command, { :read_only => true }.merge(options))
|
25
|
-
end
|
26
|
-
|
27
18
|
def converge(action_handler)
|
28
19
|
super action_handler
|
29
|
-
|
30
|
-
|
31
|
-
|
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']
|
24
|
+
)
|
25
|
+
machine_spec.reference['image_id'] = image.id
|
26
|
+
|
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'])
|
31
|
+
machine_spec.reference['container_id'] = container.id
|
32
|
+
transport.container = container
|
32
33
|
end
|
34
|
+
machine_spec.save(action_handler)
|
33
35
|
end
|
34
|
-
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
@@ -12,117 +12,38 @@ class Chef
|
|
12
12
|
module Provisioning
|
13
13
|
module DockerDriver
|
14
14
|
class DockerTransport < Chef::Provisioning::Transport
|
15
|
-
def initialize(
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@image = Docker::Image.get(base_image_name, connection)
|
19
|
-
@credentials = credentials
|
20
|
-
@connection = connection
|
21
|
-
@tunnel_transport = tunnel_transport
|
15
|
+
def initialize(container, config)
|
16
|
+
@container = container
|
17
|
+
@config = config
|
22
18
|
end
|
23
19
|
|
24
|
-
|
20
|
+
attr_reader :config
|
21
|
+
attr_accessor :container
|
25
22
|
|
26
|
-
attr_reader :container_name
|
27
|
-
attr_reader :repository_name
|
28
|
-
attr_reader :image
|
29
|
-
attr_reader :credentials
|
30
|
-
attr_reader :connection
|
31
|
-
attr_reader :tunnel_transport
|
32
|
-
|
33
|
-
# Execute the specified command inside the container, returns a Mixlib::Shellout object
|
34
|
-
# Options contains the optional keys:
|
35
|
-
# :env => env vars
|
36
|
-
# :read_only => Do not commit this execute operation, just execute it
|
37
|
-
# :ports => ports to listen on (-p command-line options)
|
38
|
-
# :detached => true/false, execute this command in detached mode (for final program to run)
|
39
23
|
def execute(command, options={})
|
40
24
|
Chef::Log.debug("execute '#{command}' with options #{options}")
|
41
25
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
rescue Excon::Errors::NotModified
|
46
|
-
Chef::Log.debug("Already stopped #{container_name}")
|
47
|
-
rescue Docker::Error::NotFoundError
|
48
|
-
end
|
49
|
-
|
50
|
-
begin
|
51
|
-
# Delete the container if it exists and is dormant
|
52
|
-
connection.delete("/containers/#{container_name}?v=true&force=true")
|
53
|
-
Chef::Log.debug("deleted /containers/#{container_name}")
|
54
|
-
rescue Docker::Error::NotFoundError
|
26
|
+
opts = {}
|
27
|
+
if options[:keep_stdin_open]
|
28
|
+
opts[:stdin] = true
|
55
29
|
end
|
56
30
|
|
57
31
|
command = Shellwords.split(command) if command.is_a?(String)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
args = ['docker', 'run', '--name', container_name]
|
65
|
-
|
66
|
-
if options[:env]
|
67
|
-
options[:env].each do |key, value|
|
68
|
-
args << '-e'
|
69
|
-
args << "#{key}=#{value}"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
if options[:detached]
|
74
|
-
args << '--detach'
|
75
|
-
end
|
76
|
-
|
77
|
-
if options[:ports]
|
78
|
-
options[:ports].each do |portnum|
|
79
|
-
args << '-p'
|
80
|
-
args << "#{portnum}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
if options[:volumes]
|
85
|
-
options[:volumes].each do |volume|
|
86
|
-
args << '-v'
|
87
|
-
args << "#{volume}"
|
32
|
+
response = container.exec(command, opts) do |stream, chunk|
|
33
|
+
case stream
|
34
|
+
when :stdout
|
35
|
+
stream_chunk(options, chunk, nil)
|
36
|
+
when :stderr
|
37
|
+
stream_chunk(options, nil, chunk)
|
88
38
|
end
|
89
39
|
end
|
90
40
|
|
91
|
-
|
92
|
-
args << '-i'
|
93
|
-
end
|
94
|
-
|
95
|
-
args << @image.id
|
96
|
-
args += command
|
41
|
+
Chef::Log.debug("Execute complete: status #{response[2]}")
|
97
42
|
|
98
|
-
|
99
|
-
Chef::Log.debug("Executing #{cmdstr}")
|
100
|
-
|
101
|
-
# Remove this when https://github.com/opscode/chef/pull/2100 gets merged and released
|
102
|
-
# nullify live_stream because at the moment EventsOutputStream doesn't understand <<, which
|
103
|
-
# ShellOut uses
|
104
|
-
live_stream = nil unless live_stream.respond_to? :<<
|
105
|
-
|
106
|
-
cmd = Mixlib::ShellOut.new(cmdstr, :live_stream => live_stream, :timeout => execute_timeout(options))
|
107
|
-
|
108
|
-
cmd.run_command
|
109
|
-
|
110
|
-
unless options[:read_only]
|
111
|
-
Chef::Log.debug("Committing #{container_name} as #{repository_name}:#{container_name}")
|
112
|
-
container = Docker::Container.get(container_name)
|
113
|
-
@image = container.commit('repo' => repository_name, 'tag' => container_name)
|
114
|
-
end
|
115
|
-
|
116
|
-
Chef::Log.debug("Execute complete: status #{cmd.exitstatus}")
|
117
|
-
|
118
|
-
cmd
|
43
|
+
DockerResult.new(command.join(' '), options, response[0].join, response[1].join, response[2])
|
119
44
|
end
|
120
45
|
|
121
46
|
def read_file(path)
|
122
|
-
container = Docker::Container.create({
|
123
|
-
'Image' => @image.id,
|
124
|
-
'Cmd' => %w(echo true)
|
125
|
-
}, connection)
|
126
47
|
begin
|
127
48
|
tarfile = ''
|
128
49
|
# NOTE: this would be more efficient if we made it a stream and passed that to Minitar
|
@@ -135,8 +56,6 @@ module DockerDriver
|
|
135
56
|
else
|
136
57
|
raise
|
137
58
|
end
|
138
|
-
ensure
|
139
|
-
container.delete
|
140
59
|
end
|
141
60
|
|
142
61
|
output = ''
|
@@ -153,12 +72,7 @@ module DockerDriver
|
|
153
72
|
end
|
154
73
|
|
155
74
|
def write_file(path, content)
|
156
|
-
|
157
|
-
Tempfile.open('metal_docker_write_file') do |file|
|
158
|
-
file.write(content)
|
159
|
-
file.close
|
160
|
-
@image = @image.insert_local('localPath' => file.path, 'outputPath' => path, 't' => "#{repository_name}:#{container_name}")
|
161
|
-
end
|
75
|
+
File.open(container_path(path), 'w') { |file| file.write(content) }
|
162
76
|
end
|
163
77
|
|
164
78
|
def download_file(path, local_path)
|
@@ -173,7 +87,7 @@ module DockerDriver
|
|
173
87
|
end
|
174
88
|
|
175
89
|
def upload_file(local_path, path)
|
176
|
-
|
90
|
+
FileUtils.cp(local_path, container_path(path))
|
177
91
|
end
|
178
92
|
|
179
93
|
def make_url_available_to_remote(url)
|
@@ -236,40 +150,8 @@ module DockerDriver
|
|
236
150
|
end
|
237
151
|
end
|
238
152
|
|
239
|
-
|
240
|
-
|
241
|
-
opts = {
|
242
|
-
:stream => true, :stdout => true, :stderr => true
|
243
|
-
}.merge(options)
|
244
|
-
# Creates list to store stdout and stderr messages
|
245
|
-
msgs = Docker::Messages.new
|
246
|
-
connection.start_request(
|
247
|
-
:post,
|
248
|
-
"/containers/#{container.id}/attach",
|
249
|
-
opts,
|
250
|
-
:response_block => attach_for(block, msgs),
|
251
|
-
:read_timeout => read_timeout,
|
252
|
-
:pipeline => true,
|
253
|
-
:persistent => true
|
254
|
-
)
|
255
|
-
end
|
256
|
-
|
257
|
-
# Method that takes chunks and calls the attached block for each mux'd message
|
258
|
-
def attach_for(block, msg_stack)
|
259
|
-
messages = Docker::Messages.new
|
260
|
-
lambda do |c,r,t|
|
261
|
-
messages = messages.decipher_messages(c)
|
262
|
-
msg_stack.append(messages)
|
263
|
-
|
264
|
-
unless block.nil?
|
265
|
-
messages.stdout_messages.each do |msg|
|
266
|
-
block.call(:stdout, msg)
|
267
|
-
end
|
268
|
-
messages.stderr_messages.each do |msg|
|
269
|
-
block.call(:stderr, msg)
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
153
|
+
def container_path(path)
|
154
|
+
File.join('proc', container.info['State']['Pid'].to_s, 'root', path)
|
273
155
|
end
|
274
156
|
|
275
157
|
class DockerResult
|
@@ -300,26 +182,3 @@ module DockerDriver
|
|
300
182
|
end
|
301
183
|
end
|
302
184
|
end
|
303
|
-
|
304
|
-
class Docker::Connection
|
305
|
-
def start_request(method, *args, &block)
|
306
|
-
request = compile_request_params(method, *args, &block)
|
307
|
-
if Docker.logger
|
308
|
-
Docker.logger.debug(
|
309
|
-
[request[:method], request[:path], request[:query], request[:body]]
|
310
|
-
)
|
311
|
-
end
|
312
|
-
excon = resource
|
313
|
-
[ excon, excon.request(request) ]
|
314
|
-
rescue Excon::Errors::BadRequest => ex
|
315
|
-
raise ClientError, ex.message
|
316
|
-
rescue Excon::Errors::Unauthorized => ex
|
317
|
-
raise UnauthorizedError, ex.message
|
318
|
-
rescue Excon::Errors::NotFound => ex
|
319
|
-
raise NotFoundError, ex.message
|
320
|
-
rescue Excon::Errors::InternalServerError => ex
|
321
|
-
raise ServerError, ex.message
|
322
|
-
rescue Excon::Errors::Timeout => ex
|
323
|
-
raise TimeoutError, ex.message
|
324
|
-
end
|
325
|
-
end
|
@@ -70,66 +70,116 @@ module DockerDriver
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
|
74
73
|
def allocate_machine(action_handler, machine_spec, machine_options)
|
74
|
+
machine_spec.from_image = from_image_from_action_handler(
|
75
|
+
action_handler,
|
76
|
+
machine_spec
|
77
|
+
)
|
78
|
+
docker_options = machine_options[:docker_options]
|
79
|
+
container_id = nil
|
80
|
+
image_id = machine_options[:image_id]
|
81
|
+
if machine_spec.reference
|
82
|
+
container_name = machine_spec.reference['container_name']
|
83
|
+
container_id = machine_spec.reference['container_id']
|
84
|
+
image_id ||= machine_spec.reference['image_id']
|
85
|
+
docker_options ||= machine_spec.reference['docker_options']
|
86
|
+
end
|
75
87
|
|
76
|
-
container_name
|
88
|
+
container_name ||= machine_spec.name
|
77
89
|
machine_spec.reference = {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
90
|
+
'driver_url' => driver_url,
|
91
|
+
'driver_version' => Chef::Provisioning::DockerDriver::VERSION,
|
92
|
+
'allocated_at' => Time.now.utc.to_s,
|
93
|
+
'host_node' => action_handler.host_node,
|
94
|
+
'container_name' => container_name,
|
95
|
+
'image_id' => image_id,
|
96
|
+
'docker_options' => docker_options,
|
97
|
+
'container_id' => container_id
|
85
98
|
}
|
99
|
+
build_container(machine_spec, docker_options)
|
86
100
|
end
|
87
101
|
|
88
102
|
def ready_machine(action_handler, machine_spec, machine_options)
|
89
|
-
|
90
|
-
|
91
|
-
machine_for(machine_spec, machine_options, base_image_name)
|
103
|
+
start_machine(action_handler, machine_spec, machine_options)
|
104
|
+
machine_for(machine_spec, machine_options)
|
92
105
|
end
|
93
106
|
|
94
|
-
def build_container(machine_spec,
|
95
|
-
|
107
|
+
def build_container(machine_spec, docker_options)
|
108
|
+
container = container_for(machine_spec)
|
109
|
+
return container unless container.nil?
|
110
|
+
|
111
|
+
image = find_image(machine_spec) ||
|
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}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
if docker_options[:ports]
|
134
|
+
docker_options[:ports].each do |portnum|
|
135
|
+
args << '-p'
|
136
|
+
args << "#{portnum}"
|
137
|
+
end
|
138
|
+
end
|
96
139
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
140
|
+
if docker_options[:volumes]
|
141
|
+
docker_options[:volumes].each do |volume|
|
142
|
+
args << '-v'
|
143
|
+
args << "#{volume}"
|
144
|
+
end
|
101
145
|
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
|
+
end
|
162
|
+
|
163
|
+
def build_image(machine_spec, docker_options)
|
164
|
+
base_image = docker_options[:base_image] || base_image_for(machine_spec)
|
102
165
|
source_name = base_image[:name]
|
103
166
|
source_repository = base_image[:repository]
|
104
167
|
source_tag = base_image[:tag]
|
105
168
|
|
106
|
-
|
107
|
-
if docker_options[:from_image]
|
108
|
-
"#{source_repository}:#{source_tag}"
|
109
|
-
else
|
110
|
-
target_repository = 'chef'
|
111
|
-
target_tag = machine_spec.name
|
112
|
-
|
113
|
-
# check if target image exists, if not try to look up for source image.
|
114
|
-
image = find_image(target_repository, target_tag) || find_image(source_repository, source_tag)
|
115
|
-
|
116
|
-
# kick off image creation
|
117
|
-
if image == nil
|
118
|
-
Chef::Log.debug("No matching images for #{target_repository}:#{target_tag}, creating!")
|
119
|
-
image = Docker::Image.create('fromImage' => source_name,
|
120
|
-
'repo' => source_repository ,
|
121
|
-
'tag' => source_tag)
|
122
|
-
Chef::Log.debug("Allocated #{image}")
|
123
|
-
image.tag('repo' => 'chef', 'tag' => target_tag)
|
124
|
-
Chef::Log.debug("Tagged image #{image}")
|
125
|
-
elsif not image.info['RepoTags'].include? "#{target_repository}:#{target_tag}"
|
126
|
-
# if `find_image(source_repository, source_tag)` returned result, assign target tag to it to be able
|
127
|
-
# find it in `start_machine`.
|
128
|
-
image.tag('repo' => target_repository, 'tag' => target_tag)
|
129
|
-
end
|
169
|
+
target_tag = machine_spec.reference['container_name']
|
130
170
|
|
131
|
-
|
132
|
-
|
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
|
133
183
|
end
|
134
184
|
|
135
185
|
def allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options)
|
@@ -163,101 +213,112 @@ module DockerDriver
|
|
163
213
|
|
164
214
|
# Connect to machine without acquiring it
|
165
215
|
def connect_to_machine(machine_spec, machine_options)
|
166
|
-
Chef::Log.debug('Connect to machine
|
216
|
+
Chef::Log.debug('Connect to machine')
|
217
|
+
machine_for(machine_spec, machine_options)
|
167
218
|
end
|
168
219
|
|
169
220
|
def destroy_machine(action_handler, machine_spec, machine_options)
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
begin
|
175
|
-
Chef::Log.debug("Stopping #{container_name}")
|
176
|
-
container.stop
|
177
|
-
rescue Excon::Errors::NotModified
|
178
|
-
# this is okay
|
179
|
-
Chef::Log.debug('Already stopped!')
|
221
|
+
container = container_for(machine_spec)
|
222
|
+
if container
|
223
|
+
Chef::Log.debug("Destroying container: #{container.id}")
|
224
|
+
container.delete(:force => true)
|
180
225
|
end
|
181
226
|
|
182
|
-
Chef::Log.debug("Removing #{container_name}")
|
183
|
-
container.delete
|
184
|
-
|
185
227
|
if !machine_spec.attrs[:keep_image] && !machine_options[:keep_image]
|
186
|
-
|
187
|
-
|
228
|
+
image = find_image(machine_spec)
|
229
|
+
Chef::Log.debug("Destroying image: chef:#{image.id}")
|
188
230
|
image.delete
|
189
231
|
end
|
190
232
|
end
|
191
233
|
|
192
|
-
def stop_machine(action_handler,
|
193
|
-
|
234
|
+
def stop_machine(action_handler, machine_spec, machine_options)
|
235
|
+
container = container_for(machine_spec)
|
236
|
+
return if container.nil?
|
237
|
+
|
238
|
+
container.stop if container.info['State']['Running']
|
194
239
|
end
|
195
240
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
241
|
+
def find_image(machine_spec)
|
242
|
+
image = nil
|
243
|
+
|
244
|
+
if machine_spec.reference['image_id']
|
245
|
+
begin
|
246
|
+
image = Docker::Image.get(machine_spec.reference['image_id'])
|
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
|
200
270
|
end
|
201
271
|
|
202
|
-
def
|
203
|
-
|
204
|
-
|
205
|
-
|
272
|
+
def from_image_from_action_handler(action_handler, machine_spec)
|
273
|
+
case action_handler
|
274
|
+
when Chef::Provisioning::AddPrefixActionHandler
|
275
|
+
machines = action_handler.action_handler.provider.new_resource.machines
|
276
|
+
this_machine = machines.select { |m| m.name == machine_spec.name}.first
|
277
|
+
this_machine.from_image
|
278
|
+
else
|
279
|
+
action_handler.provider.new_resource.from_image
|
280
|
+
end
|
206
281
|
end
|
207
282
|
|
208
283
|
def driver_url
|
209
284
|
"docker:#{Docker.url}"
|
210
285
|
end
|
211
286
|
|
212
|
-
def start_machine(action_handler, machine_spec, machine_options
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
begin
|
217
|
-
Docker::Container.get(container_name, @connection)
|
218
|
-
rescue Docker::Error::NotFoundError
|
219
|
-
docker_options = machine_options[:docker_options]
|
220
|
-
Chef::Log.debug("Start machine for container #{container_name} using base image #{base_image_name} with options #{docker_options.inspect}")
|
221
|
-
image = image_named(base_image_name)
|
222
|
-
container = Docker::Container.create('Image' => image.id, 'name' => container_name)
|
223
|
-
Chef::Log.debug("Container id: #{container.id}")
|
224
|
-
machine_spec.location['container_id'] = container.id
|
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
|
225
291
|
end
|
226
|
-
|
227
292
|
end
|
228
293
|
|
229
|
-
def machine_for(machine_spec, machine_options
|
294
|
+
def machine_for(machine_spec, machine_options)
|
230
295
|
Chef::Log.debug('machine_for...')
|
296
|
+
docker_options = machine_options[:docker_options] || Mash.from_hash(machine_spec.reference['docker_options'])
|
231
297
|
|
232
|
-
|
298
|
+
container = Docker::Container.get(machine_spec.reference['container_id'], @connection)
|
299
|
+
|
300
|
+
if machine_spec.from_image
|
301
|
+
convergence_strategy = Chef::Provisioning::ConvergenceStrategy::NoConverge.new({}, config)
|
302
|
+
else
|
303
|
+
convergence_strategy = Chef::Provisioning::ConvergenceStrategy::InstallCached.
|
304
|
+
new(machine_options[:convergence_options], config)
|
305
|
+
end
|
233
306
|
|
234
|
-
transport = DockerTransport.new(
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
convergence_strategy_for(machine_spec, machine_options)
|
243
|
-
end
|
244
|
-
|
245
|
-
Chef::Provisioning::DockerDriver::DockerContainerMachine.new(
|
246
|
-
machine_spec,
|
247
|
-
transport,
|
248
|
-
convergence_strategy,
|
249
|
-
:command => docker_options[:command],
|
250
|
-
:env => docker_options[:env],
|
251
|
-
:ports => Array(docker_options[:ports]),
|
252
|
-
:volumes => Array(docker_options[:volumes]),
|
253
|
-
:keep_stdin_open => docker_options[:keep_stdin_open]
|
254
|
-
)
|
307
|
+
transport = DockerTransport.new(container, config)
|
308
|
+
|
309
|
+
Chef::Provisioning::DockerDriver::DockerContainerMachine.new(
|
310
|
+
machine_spec,
|
311
|
+
transport,
|
312
|
+
convergence_strategy,
|
313
|
+
docker_options[:command]
|
314
|
+
)
|
255
315
|
end
|
256
316
|
|
257
|
-
def
|
258
|
-
|
259
|
-
|
260
|
-
|
317
|
+
def container_for(machine_spec)
|
318
|
+
container_id = machine_spec.reference['container_id']
|
319
|
+
begin
|
320
|
+
container = Docker::Container.get(container_id, @connection) if container_id
|
321
|
+
rescue Docker::Error::NotFoundError
|
261
322
|
end
|
262
323
|
end
|
263
324
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-provisioning-docker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Duffield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: github_changelog_generator
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
description: Provisioner for creating Docker containers in Chef Provisioning.
|
112
126
|
email: tom@getchef.com
|
113
127
|
executables: []
|
@@ -116,9 +130,11 @@ extra_rdoc_files:
|
|
116
130
|
- README.md
|
117
131
|
- LICENSE
|
118
132
|
files:
|
133
|
+
- Gemfile
|
119
134
|
- LICENSE
|
120
135
|
- README.md
|
121
136
|
- Rakefile
|
137
|
+
- chef-provisioning-docker.gemspec
|
122
138
|
- lib/chef/provisioning/docker_driver.rb
|
123
139
|
- lib/chef/provisioning/docker_driver/chef_zero_http_proxy.rb
|
124
140
|
- lib/chef/provisioning/docker_driver/docker_container_machine.rb
|
@@ -148,9 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
164
|
version: '0'
|
149
165
|
requirements: []
|
150
166
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.4.
|
167
|
+
rubygems_version: 2.4.5.1
|
152
168
|
signing_key:
|
153
169
|
specification_version: 4
|
154
170
|
summary: Provisioner for creating Docker containers in Chef Provisioning.
|
155
171
|
test_files: []
|
156
|
-
has_rdoc:
|