class Chef::Knife::ContainerDockerBuild
Public Instance Methods
Determines whether a Berksfile exists in the Docker context
@returns [TrueClass, FalseClass]
# File lib/chef/knife/container_docker_build.rb, line 133 def berksfile_exists? File.exists?(File.join(docker_context, "Berksfile")) end
Builds the Docker image
# File lib/chef/knife/container_docker_build.rb, line 176 def build_image run_command(docker_build_command) end
Returns the path to the chef-repo inside the Docker Context
@return [String]
# File lib/chef/knife/container_docker_build.rb, line 223 def chef_repo File.join(docker_context, "chef") end
Cleanup build artifacts
# File lib/chef/knife/container_docker_build.rb, line 183 def cleanup_artifacts unless config[:local_mode] destroy_item(Chef::Node, node_name, "node") destroy_item(Chef::ApiClient, node_name, "client") end end
Extracted from Chef::Knife.delete_object, because it has a confirmation step built in… By not specifying the '–no-cleanup' flag the user is already making their intent known. It is not necessary to make them confirm two more times.
# File lib/chef/knife/container_docker_build.rb, line 240 def destroy_item(klass, name, type_name) begin object = klass.load(name) object.destroy ui.warn("Deleted #{type_name} #{name}") rescue Net::HTTPServerException ui.warn("Could not find a #{type_name} named #{name} to delete!") end end
The command to use to build the Docker image
# File lib/chef/knife/container_docker_build.rb, line 193 def docker_build_command "docker build -t #{@name_args[0]} #{docker_context}" end
Returns the path to the Docker Context
@return [String]
# File lib/chef/knife/container_docker_build.rb, line 214 def docker_context File.join(config[:dockerfiles_path], @name_args[0]) end
Generates a node name for the Docker container
@return [String]
# File lib/chef/knife/container_docker_build.rb, line 232 def node_name File.read(File.join(chef_repo, ".node_name")).strip end
Reads the input parameters and validates them. Will exit if it encounters an error
# File lib/chef/knife/container_docker_build.rb, line 75 def read_and_validate_params if @name_args.length < 1 show_usage ui.fatal("You must specify a Dockerfile name") exit 1 end # if berkshelf isn't installed, set run_berks to false if config[:run_berks] ver = shell_out("berks -v") config[:run_berks] = ver.stdout.match(/\d+\.\d+\.\d+/) ? true : false if config[:berks_config] unless File.exists?(config[:berks_config]) ui.fatal("No Berksfile configuration found at #{config[:berks_config]}") exit 1 end end end end
Run the plugin
# File lib/chef/knife/container_docker_build.rb, line 63 def run read_and_validate_params setup_config_defaults run_berks if config[:run_berks] build_image cleanup_artifacts if config[:cleanup] end
Execute berkshelf locally
# File lib/chef/knife/container_docker_build.rb, line 118 def run_berks if File.exists?(File.join(docker_context, "Berksfile")) if File.exists?(File.join(chef_repo, "zero.rb")) run_berks_vendor elsif File.exists?(File.join(chef_repo, "client.rb")) run_berks_upload end end end
Installs all the cookbooks via Berkshelf
# File lib/chef/knife/container_docker_build.rb, line 140 def run_berks_install run_command("berks install") end
Upload the cookbooks to the Chef
Server
# File lib/chef/knife/container_docker_build.rb, line 165 def run_berks_upload run_berks_install berks_upload_cmd = "berks upload" berks_upload_cmd << " --force" if config[:force_build] berks_upload_cmd << " --config=#{File.expand_path(config[:berks_config])}" if config[:berks_config] run_command(berks_upload_cmd) end
Vendors all the cookbooks into a directory inside the Docker Context
# File lib/chef/knife/container_docker_build.rb, line 147 def run_berks_vendor if File.exists?(File.join(chef_repo, "cookbooks")) if config[:force_build] FileUtils.rm_rf(File.join(chef_repo, "cookbooks")) else show_usage ui.fatal("A `cookbooks` directory already exists. You must either remove this directory from your dockerfile directory or use the `force` flag") exit 1 end end run_berks_install run_command("berks vendor #{chef_repo}/cookbooks") end
Run a shell command from the Docker Context directory
# File lib/chef/knife/container_docker_build.rb, line 200 def run_command(cmd) Open3.popen2e(cmd, chdir: docker_context) do |stdin, stdout_err, wait_thr| while line = stdout_err.gets puts line end wait_thr.value.to_i end end
Set defaults for configuration values
# File lib/chef/knife/container_docker_build.rb, line 99 def setup_config_defaults config[:dockerfiles_path] ||= Chef::Config[:knife][:dockerfiles_path] || File.join(Chef::Config[:chef_repo_path], 'dockerfiles') # Determine if we are running local or server mode case when File.exists?(File.join(config[:dockerfiles_path], @name_args[0], 'chef', 'zero.rb')) config[:local_mode] = true when File.exists?(File.join(config[:dockerfiles_path], @name_args[0], 'chef', 'client.rb')) config[:local_mode] = false else show_usage ui.fatal("Can not find a Chef configuration file in #{config[:dockerfiles_path]}/#{@name_args[0]}/chef") exit 1 end end