knife-container 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/CONTRIBUTING.md +152 -0
- data/Gemfile +10 -0
- data/LICENSE +201 -0
- data/README.md +59 -0
- data/Rakefile +16 -0
- data/knife-container.gemspec +31 -0
- data/lib/chef/knife/container_docker_build.rb +243 -0
- data/lib/chef/knife/container_docker_init.rb +262 -0
- data/lib/knife-container/chef_runner.rb +83 -0
- data/lib/knife-container/command.rb +45 -0
- data/lib/knife-container/generator.rb +88 -0
- data/lib/knife-container/helpers.rb +16 -0
- data/lib/knife-container/skeletons/knife_container/files/default/plugins/docker_container.rb +37 -0
- data/lib/knife-container/skeletons/knife_container/metadata.rb +7 -0
- data/lib/knife-container/skeletons/knife_container/recipes/docker_init.rb +181 -0
- data/lib/knife-container/skeletons/knife_container/templates/default/berksfile.erb +5 -0
- data/lib/knife-container/skeletons/knife_container/templates/default/config.rb.erb +16 -0
- data/lib/knife-container/skeletons/knife_container/templates/default/dockerfile.erb +9 -0
- data/lib/knife-container/skeletons/knife_container/templates/default/dockerignore.erb +0 -0
- data/lib/knife-container/skeletons/knife_container/templates/default/node_name.erb +1 -0
- data/lib/knife-container/version.rb +5 -0
- data/spec/functional/docker_container_ohai_spec.rb +20 -0
- data/spec/functional/fixtures/ohai/Dockerfile +3 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/test_helpers.rb +59 -0
- data/spec/unit/container_docker_build_spec.rb +325 -0
- data/spec/unit/container_docker_init_spec.rb +464 -0
- data/spec/unit/fixtures/.chef/encrypted_data_bag_secret +0 -0
- data/spec/unit/fixtures/.chef/trusted_certs/chef_example_com.crt +0 -0
- data/spec/unit/fixtures/.chef/validator.pem +1 -0
- data/spec/unit/fixtures/Berksfile +3 -0
- data/spec/unit/fixtures/cookbooks/dummy/metadata.rb +0 -0
- data/spec/unit/fixtures/cookbooks/nginx/metadata.rb +0 -0
- data/spec/unit/fixtures/environments/dev.json +0 -0
- data/spec/unit/fixtures/nodes/demo.json +0 -0
- data/spec/unit/fixtures/roles/base.json +0 -0
- data/spec/unit/fixtures/site-cookbooks/apt/metadata.rb +0 -0
- metadata +232 -0
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
5
|
+
t.rspec_opts = [].tap do |a|
|
6
|
+
a.push('--color')
|
7
|
+
a.push('--format progress')
|
8
|
+
end.join(' ')
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Run all tests'
|
12
|
+
task :test => [:spec]
|
13
|
+
|
14
|
+
|
15
|
+
task :default => [:test]
|
16
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'knife-container/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "knife-container"
|
8
|
+
spec.version = Knife::Container::VERSION
|
9
|
+
spec.authors = ["Tom Duffield"]
|
10
|
+
spec.email = ["tom@getchef.com"]
|
11
|
+
spec.summary = %q{Container support for Chef's Knife Command}
|
12
|
+
spec.description = spec.summary
|
13
|
+
spec.homepage = "http://github.com/opscode/knife-container"
|
14
|
+
spec.license = "Apache 2.0"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "chef", "~> 11.0"
|
22
|
+
spec.add_dependency "mixlib-config", "~> 2.0"
|
23
|
+
spec.add_dependency "json", ">= 1.4.4", "<= 1.8.1"
|
24
|
+
|
25
|
+
spec.add_development_dependency 'rspec', '~> 2.14'
|
26
|
+
spec.add_development_dependency 'simplecov', '~> 0.7.1'
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
28
|
+
spec.add_development_dependency 'rake'
|
29
|
+
spec.add_development_dependency 'pry'
|
30
|
+
spec.add_development_dependency 'docker-api', '~> 1.11.1'
|
31
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef/knife'
|
19
|
+
require 'chef/mixin/shell_out'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class ContainerDockerBuild < Knife
|
24
|
+
include Chef::Mixin::ShellOut
|
25
|
+
|
26
|
+
deps do
|
27
|
+
# These two are needed for cleanup
|
28
|
+
require 'chef/node'
|
29
|
+
require 'chef/api_client'
|
30
|
+
end
|
31
|
+
|
32
|
+
banner "knife container docker build REPO/NAME [options]"
|
33
|
+
|
34
|
+
option :run_berks,
|
35
|
+
:long => "--[no-]berks",
|
36
|
+
:description => "Run Berkshelf",
|
37
|
+
:default => true,
|
38
|
+
:boolean => true
|
39
|
+
|
40
|
+
option :cleanup,
|
41
|
+
:long => "--[no-]cleanup",
|
42
|
+
:description => "Cleanup Chef and Docker artifacts",
|
43
|
+
:default => true,
|
44
|
+
:boolean => true
|
45
|
+
|
46
|
+
option :force_build,
|
47
|
+
:long => "--force",
|
48
|
+
:description => "Force the Docker image build",
|
49
|
+
:boolean => true
|
50
|
+
|
51
|
+
option :dockerfiles_path,
|
52
|
+
:short => "-d PATH",
|
53
|
+
:long => "--dockerfiles-path PATH",
|
54
|
+
:description => "Path to the directory where Docker contexts are kept",
|
55
|
+
:proc => Proc.new { |d| Chef::Config[:knife][:dockerfiles_path] = d }
|
56
|
+
|
57
|
+
#
|
58
|
+
# Run the plugin
|
59
|
+
#
|
60
|
+
def run
|
61
|
+
read_and_validate_params
|
62
|
+
setup_config_defaults
|
63
|
+
run_berks if config[:run_berks]
|
64
|
+
build_image
|
65
|
+
cleanup_artifacts if config[:cleanup]
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Reads the input parameters and validates them.
|
70
|
+
# Will exit if it encounters an error
|
71
|
+
#
|
72
|
+
def read_and_validate_params
|
73
|
+
if @name_args.length < 1
|
74
|
+
show_usage
|
75
|
+
ui.fatal("You must specify a Dockerfile name")
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
|
79
|
+
# if berkshelf isn't installed, set run_berks to false
|
80
|
+
if config[:run_berks]
|
81
|
+
ver = shell_out("berks -v")
|
82
|
+
config[:run_berks] = ver.stdout.match(/\d+\.\d+\.\d+/) ? true : false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Set defaults for configuration values
|
88
|
+
#
|
89
|
+
def setup_config_defaults
|
90
|
+
Chef::Config[:knife][:dockerfiles_path] ||= File.join(Chef::Config[:chef_repo_path], "dockerfiles")
|
91
|
+
config[:dockerfiles_path] = Chef::Config[:knife][:dockerfiles_path]
|
92
|
+
|
93
|
+
# Determine if we are running local or server mode
|
94
|
+
case
|
95
|
+
when File.exists?(File.join(config[:dockerfiles_path], @name_args[0], 'chef', 'zero.rb'))
|
96
|
+
config[:local_mode] = true
|
97
|
+
when File.exists?(File.join(config[:dockerfiles_path], @name_args[0], 'chef', 'client.rb'))
|
98
|
+
config[:local_mode] = false
|
99
|
+
else
|
100
|
+
show_usage
|
101
|
+
ui.fatal("Can not find a Chef configuration file in #{config[:dockerfiles_path]}/#{@name_args[0]}/chef")
|
102
|
+
exit 1
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Execute berkshelf locally
|
108
|
+
#
|
109
|
+
def run_berks
|
110
|
+
if File.exists?(File.join(docker_context, "Berksfile"))
|
111
|
+
if File.exists?(File.join(chef_repo, "zero.rb"))
|
112
|
+
run_berks_vendor
|
113
|
+
elsif File.exists?(File.join(chef_repo, "client.rb"))
|
114
|
+
run_berks_upload
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# Determines whether a Berksfile exists in the Docker context
|
121
|
+
#
|
122
|
+
# @returns [TrueClass, FalseClass]
|
123
|
+
#
|
124
|
+
def berksfile_exists?
|
125
|
+
File.exists?(File.join(docker_context, "Berksfile"))
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Installs all the cookbooks via Berkshelf
|
130
|
+
#
|
131
|
+
def run_berks_install
|
132
|
+
run_command("berks install")
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Vendors all the cookbooks into a directory inside the Docker Context
|
137
|
+
#
|
138
|
+
def run_berks_vendor
|
139
|
+
if File.exists?(File.join(chef_repo, "cookbooks"))
|
140
|
+
if config[:force_build]
|
141
|
+
FileUtils.rm_rf(File.join(chef_repo, "cookbooks"))
|
142
|
+
else
|
143
|
+
show_usage
|
144
|
+
ui.fatal("A `cookbooks` directory already exists. You must either remove this directory from your dockerfile directory or use the `force` flag")
|
145
|
+
exit 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
run_berks_install
|
150
|
+
run_command("berks vendor #{chef_repo}/cookbooks")
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Upload the cookbooks to the Chef Server
|
155
|
+
#
|
156
|
+
def run_berks_upload
|
157
|
+
run_berks_install
|
158
|
+
if config[:force_build]
|
159
|
+
run_command("berks upload --force")
|
160
|
+
else
|
161
|
+
run_command("berks upload")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Builds the Docker image
|
167
|
+
#
|
168
|
+
def build_image
|
169
|
+
run_command(docker_build_command)
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
# Cleanup build artifacts
|
174
|
+
#
|
175
|
+
def cleanup_artifacts
|
176
|
+
unless config[:local_mode]
|
177
|
+
destroy_item(Chef::Node, node_name, "node")
|
178
|
+
destroy_item(Chef::ApiClient, node_name, "client")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# The command to use to build the Docker image
|
184
|
+
#
|
185
|
+
def docker_build_command
|
186
|
+
"docker build -t #{@name_args[0]} #{docker_context}"
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
# Run a shell command from the Docker Context directory
|
191
|
+
#
|
192
|
+
def run_command(cmd)
|
193
|
+
Open3.popen2e(cmd, chdir: docker_context) do |stdin, stdout_err, wait_thr|
|
194
|
+
while line = stdout_err.gets
|
195
|
+
puts line
|
196
|
+
end
|
197
|
+
wait_thr.value.to_i
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# Returns the path to the Docker Context
|
203
|
+
#
|
204
|
+
# @return [String]
|
205
|
+
#
|
206
|
+
def docker_context
|
207
|
+
File.join(config[:dockerfiles_path], @name_args[0])
|
208
|
+
end
|
209
|
+
|
210
|
+
#
|
211
|
+
# Returns the path to the chef-repo inside the Docker Context
|
212
|
+
#
|
213
|
+
# @return [String]
|
214
|
+
#
|
215
|
+
def chef_repo
|
216
|
+
File.join(docker_context, "chef")
|
217
|
+
end
|
218
|
+
|
219
|
+
#
|
220
|
+
# Generates a node name for the Docker container
|
221
|
+
#
|
222
|
+
# @return [String]
|
223
|
+
#
|
224
|
+
def node_name
|
225
|
+
"#{@name_args[0].gsub('/','-')}-build"
|
226
|
+
end
|
227
|
+
|
228
|
+
# Extracted from Chef::Knife.delete_object, because it has a
|
229
|
+
# confirmation step built in... By not specifying the '--no-cleanup'
|
230
|
+
# flag the user is already making their intent known. It is not
|
231
|
+
# necessary to make them confirm two more times.
|
232
|
+
def destroy_item(klass, name, type_name)
|
233
|
+
begin
|
234
|
+
object = klass.load(name)
|
235
|
+
object.destroy
|
236
|
+
ui.warn("Deleted #{type_name} #{name}")
|
237
|
+
rescue Net::HTTPServerException
|
238
|
+
ui.warn("Could not find a #{type_name} named #{name} to delete!")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'json'
|
19
|
+
require 'chef/knife'
|
20
|
+
require 'knife-container/command'
|
21
|
+
require 'chef/mixin/shell_out'
|
22
|
+
|
23
|
+
class Chef
|
24
|
+
class Knife
|
25
|
+
class ContainerDockerInit < Knife
|
26
|
+
|
27
|
+
include KnifeContainer::Command
|
28
|
+
include Chef::Mixin::ShellOut
|
29
|
+
|
30
|
+
banner "knife container docker init REPO/NAME [options]"
|
31
|
+
|
32
|
+
option :base_image,
|
33
|
+
:short => "-f [REPO/]IMAGE[:TAG]",
|
34
|
+
:long => "--from [REPO/]IMAGE[:TAG]",
|
35
|
+
:description => "The image to use for the FROM value in your Dockerfile",
|
36
|
+
:proc => Proc.new { |f| Chef::Config[:knife][:docker_image] = f }
|
37
|
+
|
38
|
+
option :run_list,
|
39
|
+
:short => "-r RunlistItem,RunlistItem...,",
|
40
|
+
:long => "--run-list RUN_LIST",
|
41
|
+
:description => "Comma seperated list of roles/recipes to apply to your Docker image",
|
42
|
+
:proc => Proc.new { |o| o.split(/[\s,]+/) }
|
43
|
+
|
44
|
+
option :local_mode,
|
45
|
+
:boolean => true,
|
46
|
+
:short => "-z",
|
47
|
+
:long => "--local-mode",
|
48
|
+
:description => "Include and use a local chef repository to build the Docker image"
|
49
|
+
|
50
|
+
option :generate_berksfile,
|
51
|
+
:short => "-b",
|
52
|
+
:long => "--berksfile",
|
53
|
+
:description => "Generate a Berksfile based on the run_list provided",
|
54
|
+
:boolean => true,
|
55
|
+
:default => false
|
56
|
+
|
57
|
+
option :include_credentials,
|
58
|
+
:long => "--include-credentials",
|
59
|
+
:description => "Include secure credentials in your Docker image",
|
60
|
+
:boolean => true,
|
61
|
+
:default => false
|
62
|
+
|
63
|
+
option :validation_key,
|
64
|
+
:long => "--validation-key PATH",
|
65
|
+
:description => "The path to the validation key used by the client, typically a file named validation.pem"
|
66
|
+
|
67
|
+
option :validation_client_name,
|
68
|
+
:long => "--validation-client-name NAME",
|
69
|
+
:description => "The name of the validation client, typically a client named chef-validator"
|
70
|
+
|
71
|
+
option :trusted_certs_dir,
|
72
|
+
:long => "--trusted-certs PATH",
|
73
|
+
:description => "The path to the directory containing trusted certs"
|
74
|
+
|
75
|
+
option :encrypted_data_bag_secret,
|
76
|
+
:long => "--secret-file SECRET_FILE",
|
77
|
+
:description => "A file containing the secret key to use to encrypt data bag item values"
|
78
|
+
|
79
|
+
option :chef_server_url,
|
80
|
+
:long => "--server-url URL",
|
81
|
+
:description => "Chef Server URL"
|
82
|
+
|
83
|
+
option :force,
|
84
|
+
:long => "--force",
|
85
|
+
:boolean => true,
|
86
|
+
:desription => "Will overwrite existing Docker Contexts"
|
87
|
+
|
88
|
+
option :cookbook_path,
|
89
|
+
:long => "--cookbook-path PATH[:PATH]",
|
90
|
+
:description => "A colon-seperated path to look for cookbooks",
|
91
|
+
:proc => Proc.new { |o| o.split(':') }
|
92
|
+
|
93
|
+
option :role_path,
|
94
|
+
:long => "--role-path PATH[:PATH]",
|
95
|
+
:description => "A colon-seperated path to look for roles",
|
96
|
+
:proc => Proc.new { |o| o.split(':') }
|
97
|
+
|
98
|
+
option :node_path,
|
99
|
+
:long => "--node-path PATH[:PATH]",
|
100
|
+
:description => "A colon-seperated path to look for node objects",
|
101
|
+
:proc => Proc.new { |o| o.split(':') }
|
102
|
+
|
103
|
+
option :environment_path,
|
104
|
+
:long => "--environment-path PATH[:PATH]",
|
105
|
+
:description => "A colon-seperated path to look for environments",
|
106
|
+
:proc => Proc.new { |o| o.split(':') }
|
107
|
+
|
108
|
+
option :dockerfiles_path,
|
109
|
+
:short => "-d PATH",
|
110
|
+
:long => "--dockerfiles-path PATH",
|
111
|
+
:description => "Path to the directory where Docker contexts are kept",
|
112
|
+
:proc => Proc.new { |d| Chef::Config[:knife][:dockerfiles_path] = d }
|
113
|
+
|
114
|
+
#
|
115
|
+
# Run the plugin
|
116
|
+
#
|
117
|
+
def run
|
118
|
+
read_and_validate_params
|
119
|
+
set_config_defaults
|
120
|
+
eval_current_system
|
121
|
+
setup_context
|
122
|
+
chef_runner.converge
|
123
|
+
download_and_tag_base_image
|
124
|
+
ui.info("\n#{ui.color("Context Created: #{config[:dockerfiles_path]}/#{@name_args[0]}", :magenta)}")
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# Read and validate the parameters
|
129
|
+
#
|
130
|
+
def read_and_validate_params
|
131
|
+
if @name_args.length < 1
|
132
|
+
show_usage
|
133
|
+
ui.fatal("You must specify a Dockerfile name")
|
134
|
+
exit 1
|
135
|
+
end
|
136
|
+
|
137
|
+
if config[:generate_berksfile]
|
138
|
+
begin
|
139
|
+
require 'berkshelf'
|
140
|
+
rescue LoadError
|
141
|
+
show_usage
|
142
|
+
ui.fatal("You must have the Berkshelf gem installed to use the Berksfile flag.")
|
143
|
+
exit 1
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Set default configuration values
|
150
|
+
# We do this here and not in the option syntax because the Chef::Config
|
151
|
+
# is not available to us at that point. It also gives us a space to set
|
152
|
+
# other defaults.
|
153
|
+
#
|
154
|
+
def set_config_defaults
|
155
|
+
%w(
|
156
|
+
chef_server_url
|
157
|
+
cookbook_path
|
158
|
+
node_path
|
159
|
+
role_path
|
160
|
+
environment_path
|
161
|
+
validation_key
|
162
|
+
validation_client_name
|
163
|
+
trusted_certs_dir
|
164
|
+
encrypted_data_bag_secret
|
165
|
+
).each do |var|
|
166
|
+
config[:"#{var}"] ||= Chef::Config[:"#{var}"]
|
167
|
+
end
|
168
|
+
|
169
|
+
config[:base_image] ||= "chef/ubuntu-12.04:latest"
|
170
|
+
|
171
|
+
# if no tag is specified, use latest
|
172
|
+
unless config[:base_image] =~ /[a-zA-Z0-9\/]+:[a-zA-Z0-9.\-]+/
|
173
|
+
config[:base_image] = "#{config[:base_image]}:latest"
|
174
|
+
end
|
175
|
+
|
176
|
+
config[:run_list] ||= []
|
177
|
+
|
178
|
+
Chef::Config[:knife][:dockerfiles_path] ||= File.join(Chef::Config[:chef_repo_path], "dockerfiles")
|
179
|
+
config[:dockerfiles_path] = Chef::Config[:knife][:dockerfiles_path]
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Setup the generator context
|
184
|
+
#
|
185
|
+
def setup_context
|
186
|
+
generator_context.dockerfile_name = @name_args[0]
|
187
|
+
generator_context.dockerfiles_path = config[:dockerfiles_path]
|
188
|
+
generator_context.base_image = config[:base_image]
|
189
|
+
generator_context.chef_client_mode = chef_client_mode
|
190
|
+
generator_context.run_list = config[:run_list]
|
191
|
+
generator_context.cookbook_path = config[:cookbook_path]
|
192
|
+
generator_context.role_path = config[:role_path]
|
193
|
+
generator_context.node_path = config[:node_path]
|
194
|
+
generator_context.environment_path = config[:environment_path]
|
195
|
+
generator_context.chef_server_url = config[:chef_server_url]
|
196
|
+
generator_context.validation_key = config[:validation_key]
|
197
|
+
generator_context.validation_client_name = config[:validation_client_name]
|
198
|
+
generator_context.trusted_certs_dir = config[:trusted_certs_dir]
|
199
|
+
generator_context.encrypted_data_bag_secret = config[:encrypted_data_bag_secret]
|
200
|
+
generator_context.first_boot = first_boot_content
|
201
|
+
generator_context.generate_berksfile = config[:generate_berksfile]
|
202
|
+
generator_context.include_credentials = config[:include_credentials]
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
# The name of the recipe to use
|
207
|
+
#
|
208
|
+
# @return [String]
|
209
|
+
#
|
210
|
+
def recipe
|
211
|
+
"docker_init"
|
212
|
+
end
|
213
|
+
|
214
|
+
#
|
215
|
+
# Generate the JSON object for our first-boot.json
|
216
|
+
#
|
217
|
+
# @return [String]
|
218
|
+
#
|
219
|
+
def first_boot_content
|
220
|
+
first_boot = {}
|
221
|
+
first_boot['run_list'] = config[:run_list]
|
222
|
+
JSON.pretty_generate(first_boot)
|
223
|
+
end
|
224
|
+
|
225
|
+
#
|
226
|
+
# Return the mode in which to run: zero or client
|
227
|
+
#
|
228
|
+
# @return [String]
|
229
|
+
#
|
230
|
+
def chef_client_mode
|
231
|
+
config[:local_mode] ? "zero" : "client"
|
232
|
+
end
|
233
|
+
|
234
|
+
#
|
235
|
+
# Download the base Docker image and tag it with the image name
|
236
|
+
#
|
237
|
+
def download_and_tag_base_image
|
238
|
+
ui.info("Downloading base image: #{config[:base_image]}. This process may take awhile...")
|
239
|
+
shell_out("docker pull #{config[:base_image]}")
|
240
|
+
image_name = config[:base_image].split(':')[0]
|
241
|
+
ui.info("Tagging base image #{image_name} as #{@name_args[0]}")
|
242
|
+
shell_out("docker tag #{image_name} #{@name_args[0]}")
|
243
|
+
end
|
244
|
+
|
245
|
+
#
|
246
|
+
# Run some evaluations on the system to make sure it is in the state we need.
|
247
|
+
#
|
248
|
+
def eval_current_system
|
249
|
+
# Check to see if the Docker context already exists.
|
250
|
+
if File.exist?(File.join(config[:dockerfiles_path], @name_args[0]))
|
251
|
+
if config[:force]
|
252
|
+
FileUtils.rm_rf(File.join(config[:dockerfiles_path], @name_args[0]))
|
253
|
+
else
|
254
|
+
show_usage
|
255
|
+
ui.fatal("The Docker Context you are trying to create already exists. Please use the --force flag if you would like to re-create this context.")
|
256
|
+
exit 1
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|