class Hoosegow::Docker
Minimal API client for Docker
, allowing attaching to container stdin/stdout/stderr.
Constants
- DEFAULT_HOST
- DEFAULT_PORT
- DEFAULT_SOCKET
Public Class Methods
Initialize a new Docker
API client.
options - Connection options.
:host - IP or hostname to connect to (unless using Unix socket). :port - TCP port to connect to (unless using Unix socket). :socket - Path to local Unix socket (unless using host and port). :after_create - A proc that will be called after a container is created. :after_start - A proc that will be called after a container is started. :after_stop - A proc that will be called after a container stops. :prestart - Start a new container after each `run_container` call. :volumes - A mapping of volumes to mount in the container. e.g. if the Dockerfile has `VOLUME /work`, where the container will write data, and `VOLUME /config` where read-only configuration is, you might use :volumes => { "/config" => "/etc/shared-config", "/work" => "/data/work:rw", } `:volumes => { "/work" => "/home/localuser/work/to/do" }` :Other - any option with a capitalized key will be passed on to the 'create container' call. See http://docs.docker.io/en/latest/reference/api/docker_remote_api_v1.9/#create-a-container
# File lib/hoosegow/docker.rb, line 40 def initialize(options = {}) set_docker_url! options @after_create = options[:after_create] @after_start = options[:after_start] @after_stop = options[:after_stop] @volumes = options[:volumes] @prestart = options.fetch(:prestart, true) @container_options = options.select { |k,v| k =~ /\A[A-Z]/ } end
Public Instance Methods
Attach to a container, writing data to container's STDIN.
Returns combined STDOUT/STDERR from container.
# File lib/hoosegow/docker.rb, line 106 def attach_container(data, &block) stdin = StringIO.new data @container.attach :stdin => stdin, &block end
Public: Build a new image.
name - The name to give the image. tarfile - Tarred data for creating image. See docs.docker.io/en/latest/api/docker_remote_api_v1.5/#build-an-image-from-dockerfile-via-stdin
Returns Array of build result objects from the Docker
API.
# File lib/hoosegow/docker.rb, line 144 def build_image(name, tarfile) # Setup parser to receive chunks and yield parsed JSON objects. ret = [] error = nil parser = Yajl::Parser.new parser.on_parse_complete = Proc.new do |obj| ret << obj error = Hoosegow::ImageBuildError.new(obj) if obj["error"] yield obj if block_given? end # Make API call to create image. opts = {:t => name, :rm => '1'} ::Docker::Image.build_from_tar StringIO.new(tarfile), opts do |chunk| parser << chunk end raise error if error # Return Array of received objects. ret end
Public: Create a container using the specified image.
image - The name of the image to start the container with.
Returns nothing.
# File lib/hoosegow/docker.rb, line 81 def create_container(image) create_options = default_container_options(image) # Merge in additional :HostConfig options into default options if @container_options.has_key?(:HostConfig) create_options[:HostConfig].merge!(@container_options[:HostConfig]) end @container = ::Docker::Container.create @container_options.merge( create_options ) callback @after_create end
Public: Delete the last started container.
Returns response body or nil if no container was started.
# File lib/hoosegow/docker.rb, line 131 def delete_container return unless @container @container.delete :v => 1 rescue ::Docker::Error::ServerError => e $stderr.puts "Docker could not delete #{@container.id}: #{e}" end
Check if a Docker
image exists.
name - The name of the image to check for.
Returns true/false.
# File lib/hoosegow/docker.rb, line 172 def image_exist?(name) ::Docker::Image.exist? name end
Public: Create and start a Docker
container if one hasn't been started already, then attach to it its stdin/stdout.
image - The image to run. data - The data to pipe to the container's stdin.
Returns the data from the container's stdout.
# File lib/hoosegow/docker.rb, line 57 def run_container(image, data, &block) unless @prestart && @container create_container(image) start_container end begin attach_container(data, &block) ensure wait_container delete_container if @prestart create_container(image) start_container end end nil end
Public: Start a Docker
container.
Returns nothing.
# File lib/hoosegow/docker.rb, line 98 def start_container @container.start callback @after_start end
Public: Stop the running container.
Returns response body or nil if no container is running.
# File lib/hoosegow/docker.rb, line 122 def stop_container return unless @container @container.stop :timeout => 0 callback @after_stop end
Public: Wait for a container to finish.
Returns nothing.
# File lib/hoosegow/docker.rb, line 114 def wait_container @container.wait callback @after_stop end
Private Instance Methods
# File lib/hoosegow/docker.rb, line 246 def callback(callback_proc) callback_proc.call(@container.info) if callback_proc rescue Object end
Private: Default options used to create containers
# File lib/hoosegow/docker.rb, line 179 def default_container_options(image) { :StdinOnce => true, :OpenStdin => true, :HostConfig => { :Binds => volumes_for_bind }, :Image => image } end
Private: Get the URL to use for communicating with Docker
. If a host and/or port a present, a TCP socket URL will be generated. Otherwise a Unix socket will be used.
options - A Hash of options for building the URL.
:host - The hostname or IP of a remote Docker daemon (optional). :port - The TCP port of the remote Docker daemon (optional). :socket - The path of a local Unix socket (optional).
Returns a String url.
# File lib/hoosegow/docker.rb, line 208 def docker_url(options) if options[:host] || options[:port] host = options[:host] || DEFAULT_HOST port = options[:port] || DEFAULT_PORT "tcp://#{host}:#{port}" elsif path = options[:socket] "unix://#{path}" else nil end end
Private: Yields information about each `@volume`.
each_volume do |container_path, local_path, permissions| end
# File lib/hoosegow/docker.rb, line 236 def each_volume if @volumes @volumes.each do |container_path, local_path| local_path, permissions = local_path.split(':', 2) permissions ||= "ro" yield container_path, local_path, permissions end end end
Private: Set the docker URL, if related options are present.
# File lib/hoosegow/docker.rb, line 191 def set_docker_url!(options) if url = docker_url(options) ::Docker.url = url end end
Private: Generate the `Binds` argument for creating a container.
Given a hash of container_path => local_path in @volumes, generate an array of “local_path:container_path:rw”.
# File lib/hoosegow/docker.rb, line 224 def volumes_for_bind result = [] each_volume do |container_path, local_path, permissions| result << "#{local_path}:#{container_path}:#{permissions}" end result end