class Dockerspec::Builder
A class to build a container image.
Public Class Methods
Constructs a Docker image builder class.
@example Build an Image From CWD or `DOCKERFILE_PATH`
Dockerspec::Builder.new #=> #<Dockerspec::Builder:0x0123>
@example Build an Image from a Directory
Dockerspec::Builder.new('imagedir') #=> #<Dockerspec::Builder:0x0124>
@example Do Not Remove the Image
Dockerspec::Builder.new('../', rm: false) #=> #<Dockerspec::Builder:0x0125>
@example Passing Multiple Params
Dockerspec::Builder.new(path: '../', tag: 'myapp', rm: false) #=> #<Dockerspec::Builder:0x0125>
@param opts [String, Hash] The `:path` or a list of options.
@option opts [String] :path ('.') The directory or file that contains the
*Dockerfile*. By default tries to read it from the `DOCKERFILE_PATH` environment variable and uses `'.'` if it is not set.
@option opts [String] :string Use this string as Dockerfile instead of
`:path`. Not set by default.
@option opts [String] :string_build_path Used to specify the path that is
used for the docker build of a string *Dockerfile*. This enables ADD statements in the Dockerfile to access files that are outside of . Not set by default and overrides the default '.'
@option opts [String] :template Use this [Erubis]
(http://www.kuwata-lab.com/erubis/users-guide.html) template file as *Dockerfile*.
@option opts [String] :id Use this Docker image ID instead of a
*Dockerfile*.
@option opts [Boolean] :rm Whether to remove the generated docker images
after running the tests. By default only removes them if it is running on a CI machine.
@option opts [Hash, Erubis::Context] :context ({}) Template context
used when the `:template` source is used.
@option opts [String] :tag Repository tag to be applied to the resulting
image.
@option opts [Integer, Symbol] :log_level Sets the docker library
verbosity level. Possible values: `:silent` or `0` (no output), `:ci` or `1` (enables some outputs recommended for CI environments), `:info` or `2` (gives information about main build steps), `:debug` or `3` (outputs all the provided information in its raw original form).
@see Dockerspec::RSpec::Resources#docker_build
@api public
# File lib/dockerspec/builder.rb, line 95 def initialize(*opts) @image = nil @options = parse_options(opts) end
Public Instance Methods
Builds the docker image.
@example Build an Image From a Path
d = Dockerspec::Builder.new(path: 'dockerfile_dir') d.build #=> #<Dockerspec::Builder:0x0125>
@return [String] Docker image ID.
@raise [Dockerspec::DockerError] For underlaying docker errors.
@api public
# File lib/dockerspec/builder.rb, line 129 def build send("build_from_#{source}", @options[source]) self end
Returns Docker image ID.
@example Get the Image ID After Building the Image
d = Dockerspec::Builder.new d.build d.id #=> "9f8866b49bfb[...]"
@return [String] Docker image ID.
@api public
# File lib/dockerspec/builder.rb, line 112 def id @image.id end
Gets a descriptions of the object.
@example
d = Dockerspec::Builder.new('.') d.to_s #=> "Docker Build from path: ."
@return [String] The object description.
@api public
# File lib/dockerspec/builder.rb, line 145 def to_s description('Docker Build from') end
Protected Instance Methods
Adds a repository name and a tag to the Docker image.
@return void
@api private
# File lib/dockerspec/builder.rb, line 408 def add_repository_tag return unless @options.key?(:tag) repo, repo_tag = @options[:tag].split(':', 2) @image.tag(repo: repo, tag: repo_tag, force: true) end
Generates the Ruby block used to parse the logs during image construction.
@return [Proc] The Ruby block.
@api private
# File lib/dockerspec/builder.rb, line 267 def build_block proc { |chunk| logger.print_chunk(chunk) } end
Builds the image from a directory with a Dockerfile.
It also saves the generated image in the object internally.
@param dir [String] The directory path.
@return void
@raise [Dockerspec::DockerError] For underlaying docker errors.
@api private
# File lib/dockerspec/builder.rb, line 332 def build_from_dir(dir) image(::Docker::Image.build_from_dir(dir, &build_block)) add_repository_tag rescue ::Docker::Error::DockerError => e DockerExceptionParser.new(e) end
Builds the image from a file that is not called Dockerfile.
It also saves the generated image in the object internally.
This creates a temporary directory where it copies all the files and generates the temporary Dockerfile.
@param file [String] The Dockerfile file path.
@return void
@api private
# File lib/dockerspec/builder.rb, line 313 def build_from_file(file) dir = File.dirname(file) string = IO.read(file) build_from_string(string, dir) end
Gets the image from a Image ID.
It also saves the image in the object internally.
@param id [String] The Docker image ID.
@return void
@raise [Dockerspec::DockerError] For underlaying docker errors.
@api private
# File lib/dockerspec/builder.rb, line 391 def build_from_id(id) @image = ::Docker::Image.get(id) add_repository_tag rescue ::Docker::Error::NotFoundError @image = ::Docker::Image.create('fromImage' => id) add_repository_tag rescue ::Docker::Error::DockerError => e DockerExceptionParser.new(e) end
Builds the image from a directory or a file.
It also saves the generated image in the object internally.
@param path [String] The path.
@return void
@api private
# File lib/dockerspec/builder.rb, line 350 def build_from_path(path) if !File.directory?(path) && File.basename(path) == 'Dockerfile' path = File.dirname(path) end File.directory?(path) ? build_from_dir(path) : build_from_file(path) end
Builds the image from a string. Generates the Docker tag if required.
It also saves the generated image in the object internally.
This creates a temporary directory where it copies all the files and generates the temporary Dockerfile.
@param string [String] The Dockerfile content. @param dir [String] The directory to copy the files from. Files that are
required by the Dockerfile passed in *string*. If not passed, then the 'string_build_path' option is used. If that is not used, '.' is assumed.
@return void
@api private
# File lib/dockerspec/builder.rb, line 289 def build_from_string(string, dir = '.') dir = @options[:string_build_path] if @options[:string_build_path] Dir.mktmpdir do |tmpdir| FileUtils.cp_r("#{dir}/.", tmpdir) dockerfile = File.join(tmpdir, 'Dockerfile') File.open(dockerfile, 'w') { |f| f.write(string) } build_from_dir(tmpdir) end end
Builds the image from a template.
It also saves the generated image in the object internally.
@param file [String] The Dockerfile [Erubis] (www.kuwata-lab.com/erubis/users-guide.html) template path.
@return void
@api private
# File lib/dockerspec/builder.rb, line 369 def build_from_template(file) context = @options[:context] || {} template = IO.read(file) eruby = Erubis::Eruby.new(template) string = eruby.evaluate(context) build_from_string(string, File.dirname(file)) end
Gets the default configuration options after merging them with RSpec
configuration options.
@example
self.default_options #=> {:path=>".", :rm=>true, :log_level=>:silent}
@return [Hash] The configuration options.
@api private
# File lib/dockerspec/builder.rb, line 230 def default_options { path: ENV['DOCKERFILE_PATH'] || '.', # Autoremove images in all CIs except Travis (not supported): rm: ci? && !travis_ci?, # Avoid CI timeout errors: log_level: ci? ? :ci : :silent }.merge(rspec_options) end
Sets or gets the Docker image.
@param img [Docker::Image] The Docker image to set.
@return [Docker::Image] The Docker image object.
@api private
# File lib/dockerspec/builder.rb, line 194 def image(img = nil) return @image if img.nil? ImageGC.instance.add(img.id) if @options[:rm] @image = img end
Gets the Docker Logger
to use during the build process.
@return void
@api private
# File lib/dockerspec/builder.rb, line 421 def logger @logger ||= Logger.instance(@options[:log_level]) end
Parses the configuration options passed to the constructor.
@example
self.parse_options #=> {:path=>".", :rm=>true, :log_level=>:silent}
@param opts [Array<String, Hash>] The list of optitag. The strings will
be interpreted as `:path`, others will be merged.
@return [Hash] The configuration options.
@see initialize
@api private
# File lib/dockerspec/builder.rb, line 255 def parse_options(opts) opts_hs_ary = opts.map { |x| x.is_a?(Hash) ? x : { path: x } } opts_hs_ary.reduce(default_options) { |a, e| a.merge(e) } end
Gets the default options configured using `RSpec.configuration`.
@example
self.rspec_options #=> {:path=>".", :rm=>true, :log_level=>:silent}
@return [Hash] The configuration options.
@api private
# File lib/dockerspec/builder.rb, line 210 def rspec_options config = ::RSpec.configuration {}.tap do |opts| opts[:path] = config.dockerfile_path if config.dockerfile_path? opts[:rm] = config.rm_build if config.rm_build? opts[:log_level] = config.log_level if config.log_level? end end
Gets the source to generate the image from.
Possible values: `:string`, `:template`, `:id`, `:path`.
@example Building an Image from a Path
self.source #=> :path
@example Building an Image from a Template
self.source #=> :template
@return [Symbol] The source.
@api private
# File lib/dockerspec/builder.rb, line 166 def source return @source unless @source.nil? @source = %i(string template id path).find { |from| @options.key?(from) } end