chef-provisioning-docker 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -7
- data/lib/chef/provisioning/docker_driver/docker_transport.rb +4 -3
- data/lib/chef/provisioning/docker_driver/driver.rb +39 -12
- data/lib/chef/provisioning/docker_driver/version.rb +1 -1
- data/spec/docker_support.rb +31 -0
- data/spec/integration/primitives_spec.rb +75 -0
- data/spec/spec_helper.rb +32 -0
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e6789da274574121591c374a64e0d9da7b53092
|
4
|
+
data.tar.gz: eaf4c266978efe1a32247ce4a21f25daf77e1a6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ae43fca9bbb00973288ae92d1386802fc97403ce5e8f85dd5002e421f01026a9509247232a345810e94bdb64e40aa0cd28628dee71eea00e93e1a5f2f73a133
|
7
|
+
data.tar.gz: 2e4533eee5d21ab3c049be12494c279333906fc9c6364de16d965174c22b3f71f0295f5be0aa9ed027324ca2f944770ee1d3d69bbf346075b6a4173d4ef6e135
|
data/README.md
CHANGED
@@ -4,11 +4,11 @@ How to use:
|
|
4
4
|
|
5
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:
|
6
6
|
|
7
|
-
```
|
7
|
+
```
|
8
8
|
CHEF_DRIVER=docker bundle exec chef-client -z docker_ubuntu_image.rb
|
9
|
-
```
|
9
|
+
```
|
10
10
|
|
11
|
-
This will run Chef-zero and use the description stored in docker_ubuntu_image.rb (the second example below). Note that some configuration syntax is likely to change a little bit so be sure to check the documentation.
|
11
|
+
This will run Chef-zero and use the description stored in docker_ubuntu_image.rb (the second example below). Note that some configuration syntax is likely to change a little bit so be sure to check the documentation.
|
12
12
|
|
13
13
|
## Machine creation
|
14
14
|
|
@@ -65,10 +65,6 @@ machine 'wario' do
|
|
65
65
|
end
|
66
66
|
```
|
67
67
|
|
68
|
-
This will create a docker container based on Ubuntu 14.04 and
|
69
|
-
then execute the Apache recipe and run the /usr/sbin/httpd command
|
70
|
-
as the container's run command.
|
71
|
-
|
72
68
|
## Machine images
|
73
69
|
|
74
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:
|
@@ -96,3 +92,8 @@ machine 'web00' do
|
|
96
92
|
}
|
97
93
|
end
|
98
94
|
```
|
95
|
+
|
96
|
+
This will create a docker container based on Ubuntu 14.04 and
|
97
|
+
then execute the Apache recipe and run the /usr/sbin/httpd command
|
98
|
+
as the container's run command.
|
99
|
+
|
@@ -63,8 +63,8 @@ module DockerDriver
|
|
63
63
|
|
64
64
|
args = ['docker', 'run', '--name', container_name]
|
65
65
|
|
66
|
-
if options[:env]
|
67
|
-
|
66
|
+
if options[:env]
|
67
|
+
options[:env].each do |key, value|
|
68
68
|
args << '-e'
|
69
69
|
args << "#{key}=#{value}"
|
70
70
|
end
|
@@ -179,11 +179,12 @@ module DockerDriver
|
|
179
179
|
def make_url_available_to_remote(url)
|
180
180
|
# The host is already open to the container. Just find out its address and return it!
|
181
181
|
uri = URI(url)
|
182
|
+
uri.scheme = 'http' if 'chefzero' == uri.scheme && uri.host == 'localhost'
|
182
183
|
host = Socket.getaddrinfo(uri.host, uri.scheme, nil, :STREAM)[0][3]
|
183
184
|
Chef::Log.debug("Making URL available: #{host}")
|
184
185
|
|
185
186
|
if host == '127.0.0.1' || host == '::1'
|
186
|
-
result = execute('ip route
|
187
|
+
result = execute('ip route list', :read_only => true)
|
187
188
|
|
188
189
|
Chef::Log.debug("IP route: #{result.stdout}")
|
189
190
|
|
@@ -5,6 +5,7 @@ require 'chef/provisioning/docker_driver/docker_transport'
|
|
5
5
|
require 'chef/provisioning/docker_driver/docker_container_machine'
|
6
6
|
require 'chef/provisioning/convergence_strategy/install_cached'
|
7
7
|
require 'chef/provisioning/convergence_strategy/no_converge'
|
8
|
+
require 'chef/mash'
|
8
9
|
|
9
10
|
require 'yaml'
|
10
11
|
require 'docker/container'
|
@@ -73,13 +74,14 @@ module DockerDriver
|
|
73
74
|
def allocate_machine(action_handler, machine_spec, machine_options)
|
74
75
|
|
75
76
|
container_name = machine_spec.name
|
76
|
-
machine_spec.
|
77
|
+
machine_spec.reference = {
|
77
78
|
'driver_url' => driver_url,
|
78
79
|
'driver_version' => Chef::Provisioning::DockerDriver::VERSION,
|
79
80
|
'allocated_at' => Time.now.utc.to_s,
|
80
81
|
'host_node' => action_handler.host_node,
|
81
82
|
'container_name' => container_name,
|
82
|
-
'image_id' => machine_options[:image_id]
|
83
|
+
'image_id' => machine_options[:image_id],
|
84
|
+
'docker_options' => machine_options[:docker_options]
|
83
85
|
}
|
84
86
|
end
|
85
87
|
|
@@ -90,10 +92,13 @@ module DockerDriver
|
|
90
92
|
end
|
91
93
|
|
92
94
|
def build_container(machine_spec, machine_options)
|
93
|
-
|
94
95
|
docker_options = machine_options[:docker_options]
|
95
96
|
|
96
97
|
base_image = docker_options[:base_image]
|
98
|
+
if !base_image
|
99
|
+
Chef::Log.debug("No base images specified in docker options.")
|
100
|
+
base_image = base_image_for(machine_spec)
|
101
|
+
end
|
97
102
|
source_name = base_image[:name]
|
98
103
|
source_repository = base_image[:repository]
|
99
104
|
source_tag = base_image[:tag]
|
@@ -105,7 +110,8 @@ module DockerDriver
|
|
105
110
|
target_repository = 'chef'
|
106
111
|
target_tag = machine_spec.name
|
107
112
|
|
108
|
-
image
|
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)
|
109
115
|
|
110
116
|
# kick off image creation
|
111
117
|
if image == nil
|
@@ -116,15 +122,22 @@ module DockerDriver
|
|
116
122
|
Chef::Log.debug("Allocated #{image}")
|
117
123
|
image.tag('repo' => 'chef', 'tag' => target_tag)
|
118
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)
|
119
129
|
end
|
120
130
|
|
121
131
|
"#{target_repository}:#{target_tag}"
|
122
132
|
end
|
123
133
|
end
|
124
134
|
|
125
|
-
def allocate_image(action_handler, image_spec, image_options, machine_spec)
|
135
|
+
def allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options)
|
126
136
|
# Set machine options on the image to match our newly created image
|
127
|
-
image_spec.
|
137
|
+
image_spec.reference = {
|
138
|
+
'driver_url' => driver_url,
|
139
|
+
'driver_version' => Chef::Provisioning::DockerDriver::VERSION,
|
140
|
+
'allocated_at' => Time.now.to_i,
|
128
141
|
:docker_options => {
|
129
142
|
:base_image => {
|
130
143
|
:name => "chef_#{image_spec.name}",
|
@@ -134,12 +147,20 @@ module DockerDriver
|
|
134
147
|
:from_image => true
|
135
148
|
}
|
136
149
|
}
|
150
|
+
# Workaround for chef/chef-provisioning-docker#37
|
151
|
+
machine_spec.attrs[:keep_image] = true
|
137
152
|
end
|
138
153
|
|
139
154
|
def ready_image(action_handler, image_spec, image_options)
|
140
155
|
Chef::Log.debug('READY IMAGE!')
|
141
156
|
end
|
142
157
|
|
158
|
+
# workaround for https://github.com/chef/chef-provisioning/issues/358.
|
159
|
+
def destroy_image(action_handler, image_spec, image_options, machine_options={})
|
160
|
+
image = Docker::Image.get("chef:#{image_spec.name}")
|
161
|
+
image.delete unless image.nil?
|
162
|
+
end
|
163
|
+
|
143
164
|
# Connect to machine without acquiring it
|
144
165
|
def connect_to_machine(machine_spec, machine_options)
|
145
166
|
Chef::Log.debug('Connect to machine!')
|
@@ -161,10 +182,11 @@ module DockerDriver
|
|
161
182
|
Chef::Log.debug("Removing #{container_name}")
|
162
183
|
container.delete
|
163
184
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
185
|
+
if !machine_spec.attrs[:keep_image] && !machine_options[:keep_image]
|
186
|
+
Chef::Log.debug("Destroying image: chef:#{container_name}")
|
187
|
+
image = Docker::Image.get("chef:#{container_name}")
|
188
|
+
image.delete
|
189
|
+
end
|
168
190
|
end
|
169
191
|
|
170
192
|
def stop_machine(action_handler, node)
|
@@ -226,8 +248,8 @@ module DockerDriver
|
|
226
248
|
convergence_strategy,
|
227
249
|
:command => docker_options[:command],
|
228
250
|
:env => docker_options[:env],
|
229
|
-
:ports =>
|
230
|
-
:volumes =>
|
251
|
+
:ports => Array(docker_options[:ports]),
|
252
|
+
:volumes => Array(docker_options[:volumes]),
|
231
253
|
:keep_stdin_open => docker_options[:keep_stdin_open]
|
232
254
|
)
|
233
255
|
end
|
@@ -239,6 +261,11 @@ module DockerDriver
|
|
239
261
|
end
|
240
262
|
end
|
241
263
|
|
264
|
+
def base_image_for(machine_spec)
|
265
|
+
Chef::Log.debug("Looking for image #{machine_spec.from_image}")
|
266
|
+
image_spec = machine_spec.managed_entry_store.get!(:machine_image, machine_spec.from_image)
|
267
|
+
Mash.new(image_spec.reference)[:docker_options][:base_image]
|
268
|
+
end
|
242
269
|
end
|
243
270
|
end
|
244
271
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DockerSupport
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
3
|
+
def self.extended(other)
|
4
|
+
other.extend Cheffish::RSpec::ChefRunSupport
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'chef/provisioning/docker_driver'
|
8
|
+
|
9
|
+
def with_docker(description, *tags, &block)
|
10
|
+
context_block = proc do
|
11
|
+
docker_driver = Chef::Provisioning.driver_for_url("docker")
|
12
|
+
|
13
|
+
@@driver = docker_driver
|
14
|
+
def self.driver
|
15
|
+
@@driver
|
16
|
+
end
|
17
|
+
|
18
|
+
module_eval(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
when_the_repository "exists and #{description}", *tags, &context_block
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module DockerConfig
|
26
|
+
def chef_config
|
27
|
+
@chef_config ||= {
|
28
|
+
driver: Chef::Provisioning.driver_for_url("docker"),
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
describe "chef-provisioning-docker" do
|
5
|
+
extend DockerSupport
|
6
|
+
include DockerConfig
|
7
|
+
|
8
|
+
when_the_chef_12_server "exists", organization: "foo", server_scope: :context, port: 8900..9000 do
|
9
|
+
with_docker "integration tests" do
|
10
|
+
|
11
|
+
# owing to how RSpec works, things defined by let() are not accessible in the recipes we define inside
|
12
|
+
# expect_converge{}.
|
13
|
+
ubuntu_options = {
|
14
|
+
:base_image => {
|
15
|
+
:name => 'ubuntu',
|
16
|
+
:repository => 'ubuntu',
|
17
|
+
:tag => '14.04'
|
18
|
+
},
|
19
|
+
}
|
20
|
+
|
21
|
+
let(:iso_date) { Time.now.iso8601.gsub(':', '') }
|
22
|
+
docker_driver = driver
|
23
|
+
|
24
|
+
context "machine_image resource" do
|
25
|
+
|
26
|
+
let(:spec_image_tag) { "docker_image_spec_#{iso_date}" }
|
27
|
+
|
28
|
+
after(:each) {
|
29
|
+
image = docker_driver.find_image("chef", spec_image_tag)
|
30
|
+
image.delete(force: true) unless image.nil?
|
31
|
+
}
|
32
|
+
|
33
|
+
it ":create succeeds" do
|
34
|
+
tag = spec_image_tag
|
35
|
+
|
36
|
+
expect_converge {
|
37
|
+
|
38
|
+
machine_image tag do
|
39
|
+
machine_options :docker_options => ubuntu_options
|
40
|
+
action :create
|
41
|
+
end
|
42
|
+
}.not_to raise_error
|
43
|
+
|
44
|
+
expect(docker_driver.find_image("chef", tag)).not_to be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it ":destroy succeeds with an existing image" do
|
48
|
+
tag = spec_image_tag
|
49
|
+
|
50
|
+
expect_converge {
|
51
|
+
machine_image tag do
|
52
|
+
machine_options :docker_options => ubuntu_options
|
53
|
+
action :create
|
54
|
+
end
|
55
|
+
|
56
|
+
machine_image tag do
|
57
|
+
action :destroy
|
58
|
+
end
|
59
|
+
}.not_to raise_error
|
60
|
+
|
61
|
+
expect(docker_driver.find_image("chef", tag)).to be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it ":destroy succeeds with a non-existent image" do
|
65
|
+
tag = "bogus_image"
|
66
|
+
expect_converge {
|
67
|
+
machine_image tag do
|
68
|
+
action :destroy
|
69
|
+
end
|
70
|
+
}.not_to raise_error
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# require "mixlib/shellout"
|
2
|
+
require 'chef'
|
3
|
+
require 'chef/mixins'
|
4
|
+
require 'chef/dsl'
|
5
|
+
require 'chef/application'
|
6
|
+
require 'chef/applications'
|
7
|
+
|
8
|
+
require 'chef/shell'
|
9
|
+
require 'chef/util/file_edit'
|
10
|
+
|
11
|
+
require 'chef/config'
|
12
|
+
require 'docker_support'
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.expect_with :rspec do |expectations|
|
16
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
17
|
+
# and `failure_message` of custom matchers include text for helper methods
|
18
|
+
# defined using `chain`, e.g.:
|
19
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
20
|
+
# # => "be bigger than 2 and smaller than 4"
|
21
|
+
# ...rather than:
|
22
|
+
# # => "be bigger than 2"
|
23
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
24
|
+
end
|
25
|
+
|
26
|
+
config.mock_with :rspec do |mocks|
|
27
|
+
mocks.verify_partial_doubles = true
|
28
|
+
end
|
29
|
+
|
30
|
+
config.filter_run :focus
|
31
|
+
config.run_all_when_everything_filtered = true
|
32
|
+
end
|
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: '0.
|
4
|
+
version: '0.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Duffield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: docker-api
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitar
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: sys-proctable
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,6 +126,9 @@ files:
|
|
112
126
|
- lib/chef/provisioning/docker_driver/driver.rb
|
113
127
|
- lib/chef/provisioning/docker_driver/version.rb
|
114
128
|
- lib/chef/provisioning/driver_init/docker.rb
|
129
|
+
- spec/docker_support.rb
|
130
|
+
- spec/integration/primitives_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
115
132
|
homepage: https://github.com/opscode/chef-provisioning-docker
|
116
133
|
licenses: []
|
117
134
|
metadata: {}
|
@@ -131,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
148
|
version: '0'
|
132
149
|
requirements: []
|
133
150
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.4.
|
151
|
+
rubygems_version: 2.4.4
|
135
152
|
signing_key:
|
136
153
|
specification_version: 4
|
137
154
|
summary: Provisioner for creating Docker containers in Chef Provisioning.
|