module DockerHelper

Various helper methods to control the Docker command-line client. Main entrance point is the docker helper. Use ::proxy for a self-contained controller object to call these methods on.

See ::docker_command

Constants

VERSION

Attributes

docker_command[W]

Setter for the Docker command (see ::docker_command).

Public Class Methods

docker_command → aString click to toggle source

Returns the Docker command or aborts if none could be found.

Override by setting the DOCKER_COMMAND environment variable or by setting the docker_command attribute on this module.

   # File lib/docker_helper.rb
58 def docker_command
59   @docker_command ||= ENV.fetch('DOCKER_COMMAND') {
60     find_docker_command || abort('Docker command not found.') }
61 end
proxy → aProxy click to toggle source

Returns a new instance of Proxy with helper methods available both in abbreviated and unabbreviated form.

   # File lib/docker_helper.rb
47 def proxy
48   Proxy.new.extend(self)
49 end

Public Instance Methods

docker(cmd, args...) click to toggle source
docker(cmd, args...) { ... }

Central helper method to execute Docker commands.

If the command (first argument) is a symbol or if the pipe option is set, runs the command through docker_pipe and returns the result as a string. Otherwise, runs the command through docker_system and returns true or false, indicating whether the command exited successfully or not.

In the pipe case, calls docker_fail when the fail_if_empty option is set and the command returned no result.

In the system case, ignores errors when the ignore_errors option is set. The block is passed on to docker_system if given.

    # File lib/docker_helper.rb
132 def docker(*args, &block)
133   options, pipe, fail_if_empty, ignore_errors = DockerHelper.
134     extract_options(args, :pipe, :fail_if_empty, :ignore_errors)
135 
136   DockerHelper.build_args(args, options)
137 
138   if pipe
139     docker_pipe(*args).tap { |res|
140       if fail_if_empty && !res
141         docker_fail(*args)
142       end
143     }
144   else
145     if ignore_errors
146       options[:err] = :close
147       block ||= lambda { |*| }
148     end
149 
150     docker_system(*args, &block)
151   end
152 end
docker_build(build_path, image) click to toggle source

Builds the image image from the Dockerfile and context at build_path.

Command reference: docker build

    # File lib/docker_helper.rb
193 def docker_build(build_path, image = nil)
194   image ||= docker_image_name
195 
196   docker %W[build -t #{image} #{build_path}]  # --force-rm
197 end
docker_clean(name) click to toggle source

Stops and then removes container name, including associated volumes.

Command reference: docker rm

    # File lib/docker_helper.rb
325 def docker_clean(name = nil, _ = nil)
326   name ||= docker_container_name
327 
328   docker_stop name
329   docker %W[rm -v -f #{name}], ignore_errors: true
330 end
docker_clobber(name, image) click to toggle source

Removes container name (see docker_clean) as well as image image.

Command reference: docker rmi

    # File lib/docker_helper.rb
339 def docker_clobber(name = nil, image = nil)
340   name  ||= docker_container_name
341   image ||= docker_image_name
342 
343   docker_clean name
344   docker %W[rmi #{image}], ignore_errors: true
345 end
docker_port(port, name) → aString click to toggle source

Returns the host and port for container name on port port. Fails if container is not running or the specified port is not exposed.

Command reference: docker port

    # File lib/docker_helper.rb
220 def docker_port(port, name = nil)
221   name ||= docker_container_name
222 
223   docker :port, name, port
224 end
docker_ready(host_with_port[, path]) → true or false click to toggle source

Argument host_with_port must be of the form host:port, as returned by docker_port, or an array of host and port.

Returns true if and when the TCP port is available on the host and, if path is given, a HTTP request for path is successful.

Returns false if the port and the path haven’t become available after 30 attempts each. Sleeps for 0.1 seconds inbetween attempts.

    # File lib/docker_helper.rb
246 def docker_ready(host_with_port, path = nil, attempts = 30, sleep = 0.1)
247   host, port = host_with_port.is_a?(Array) ?
248     host_with_port : host_with_port.split(':')
249 
250   docker_socket_ready(host, port, attempts, sleep) &&
251     (!path || docker_http_ready(host, port, path, attempts, sleep))
252 end
docker_reset(name, image) click to toggle source

Resets container name by removing (see docker_clean) and then starting (see docker_start) it from image image.

    # File lib/docker_helper.rb
352 def docker_reset(name = nil, image = nil)
353   docker_clean(name)
354   docker_start(name, image)
355 end
docker_restart(name) click to toggle source

Restarts container name by stopping (see docker_stop) and then starting it.

Command reference: docker start

    # File lib/docker_helper.rb
311 def docker_restart(name = nil, _ = nil)
312   name ||= docker_container_name
313 
314   docker_stop name
315   docker %W[start #{name}]
316 end
docker_start(name, image) click to toggle source

Starts container name from image image. This will fail if a container with that name is already running. Use docker_start! in case you want to unconditionally start the container.

Runs the container detached and with all exposed ports published.

Command reference: docker run

    # File lib/docker_helper.rb
265 def docker_start(name = nil, image = nil)
266   name  ||= docker_container_name
267   image ||= docker_image_name
268 
269   docker %W[run -d -P --name #{name} #{image}]
270 end
docker_start!(name, image) click to toggle source
docker_start!(name, image) { |name, image| ... }

Unconditionally starts container name from image image.

If the container is already running, it’s restarted (see docker_restart). Otherwise, it’s started (see docker_start) and its name and image are yielded to the block if given.

    # File lib/docker_helper.rb
281 def docker_start!(name = nil, image = nil)
282   name  ||= docker_container_name
283   image ||= docker_image_name
284 
285   docker_restart(name) || docker_start(name, image).tap {
286     yield name, image if block_given?
287   }
288 end
docker_stop(name) click to toggle source

Stops container name.

Command reference: docker stop

    # File lib/docker_helper.rb
297 def docker_stop(name = nil, _ = nil)
298   name ||= docker_container_name
299 
300   docker %W[stop #{name}], ignore_errors: true
301 end
docker_tags(image) → anArray click to toggle source

Returns the tags associated with image image.

Command reference: docker images

    # File lib/docker_helper.rb
172 def docker_tags(image = nil)
173   image ||= docker_image_name
174 
175   needle = image[/[^:]+/]
176 
177   docker(:images).lines.map { |line|
178     repo, tag, = line.split
179     tag if repo == needle
180   }.compact.sort.sort_by { |tag|
181     tag.split('.').map(&:to_i)
182   }
183 end
docker_url(port, name) → aString click to toggle source

Returns the HTTP URL for container name on port port (see docker_port).

    # File lib/docker_helper.rb
231 def docker_url(port, name = nil)
232   "http://#{docker_port(port, name)}"
233 end
docker_version → aString click to toggle source

Returns the version number of the Docker client.

Command reference: docker version

    # File lib/docker_helper.rb
161 def docker_version
162   docker(:version).lines.first.split.last
163 end
docker_volume(volume, name) → aString click to toggle source

Returns the path to volume volume shared by container name.

Command reference: docker inspect

    # File lib/docker_helper.rb
206 def docker_volume(volume, name = nil)
207   name ||= docker_container_name
208 
209   docker :inspect, %W[-f {{index\ .Volumes\ "#{volume}"}} #{name}]
210 end

Private Instance Methods

docker_container_name() click to toggle source

Placeholder for default container name; must be implemented by utilizing class.

    # File lib/docker_helper.rb
361 def docker_container_name
362   raise ArgumentError, 'container name missing', caller(1)
363 end
docker_fail(*args) click to toggle source

Simply aborts; override for different behaviour.

    # File lib/docker_helper.rb
384 def docker_fail(*args)
385   abort
386 end
docker_http_ready(host, port, path, attempts, sleep) click to toggle source

Checks HTTP connection.

    # File lib/docker_helper.rb
398 def docker_http_ready(host, port, path, attempts, sleep)
399   loop {
400     begin
401       break if Net::HTTP.get_response(host, path, port).is_a?(Net::HTTPSuccess)
402     rescue Errno::ECONNRESET, EOFError => err
403       return false unless docker_ready_sleep(sleep, attempts -= 1)
404       retry
405     end
406 
407     return false unless docker_ready_sleep(sleep, attempts -= 1)
408   }
409 
410   true
411 end
docker_image_name() click to toggle source

Placeholder for default image name; must be implemented by utilizing class.

    # File lib/docker_helper.rb
367 def docker_image_name
368   raise ArgumentError, 'image name missing', caller(1)
369 end
docker_pipe(*args) click to toggle source

Executes the command in a subprocess and returns its output as a string, or nil if output is empty; override for different behaviour.

    # File lib/docker_helper.rb
373 def docker_pipe(*args)
374   res = IO.popen(args, &:read).chomp
375   res unless res.empty?
376 end
docker_ready_sleep(sleep, attempts) click to toggle source

Sleeps unless out of attempts.

    # File lib/docker_helper.rb
414 def docker_ready_sleep(sleep, attempts)
415   sleep(sleep) unless attempts.zero?
416 end
docker_socket_ready(host, port, attempts, sleep) click to toggle source

Checks TCP connection.

    # File lib/docker_helper.rb
389 def docker_socket_ready(host, port, attempts, sleep)
390   TCPSocket.new(host, port).close
391   true
392 rescue Errno::ECONNREFUSED
393   return false unless docker_ready_sleep(sleep, attempts -= 1)
394   retry
395 end
docker_system(*args) click to toggle source

Executes the command in a subshell; override for different behaviour.

    # File lib/docker_helper.rb
379 def docker_system(*args)
380   system(*args)
381 end

Internal

↑ top

Public Class Methods

build_args(args, options) click to toggle source

Builds arguments array suitable for docker_system and docker_pipe.

Prefixes the command with sudo unless the NOSUDO environment variable is set.

Flattens all arguments, converts them to strings and appends the options hash.

    # File lib/docker_helper.rb
105 def build_args(args, options)
106   args.unshift(docker_command)
107   args.unshift(:sudo) unless ENV['NOSUDO']
108 
109   args.flatten!
110   args.map!(&:to_s) << options
111 end
extract_options(args, *keys) click to toggle source

Extracts options hash from args and applies default options.

Returns the options hash as well as the values for keys, which will be removed from the options.

   # File lib/docker_helper.rb
82 def extract_options(args, *keys)
83   options = args.last.is_a?(Hash) ? args.pop : {}
84 
85   unless options.key?(:pipe)
86     options[:pipe] = args.first.is_a?(Symbol)
87   end
88 
89   unless options.key?(:fail_if_empty)
90     options[:fail_if_empty] = options[:pipe]
91   end
92 
93   [options, *keys.map(&options.method(:delete))]
94 end
find_docker_command() click to toggle source

Tries to find the Docker command for the host system. Usually, it’s just docker, but on Debian-based systems it’s docker.io.

   # File lib/docker_helper.rb
67 def find_docker_command
68   commands = %w[docker docker.io]
69 
70   require 'nuggets/file/which'
71   File.which_command(commands)
72 rescue LoadError
73   commands.first
74 end