class Hoosegow

Public Class Methods

new(options = {}) click to toggle source

Public: Initialize a Hoosegow instance.

options -

:no_proxy     - Development mode. Use this if you don't want to
                setup Docker on your development instance, but
                still need to test rendering files. This is how
                Hoosegow runs inside the Docker container.
:inmate_dir   - Dependency directory to be coppied to the hoosegow
                image. This should include a file called
               `inmate.rb` that defines a Hoosegow::Inmate module.
:image_name   - The name of the Docker image to use. If this isn't
                specified, we will infer the image name from the
                hash the files present.
:ruby_version - The Ruby version to install in the Docker
                container (Default RUBY_VERSION).
:socket       - Path to Unix socket where Docker daemon is
                running. (optional. defaults to
                "/var/run/docker.sock")
:host         - IP or hostname where Docker daemon is running.
                Don't set this if Docker is listening locally on a
                Unix socket.
:port         - TCP port where Docker daemon is running. Don't set
                this if Docker is listening locally on a Unix
                socket.
# File lib/hoosegow.rb, line 31
def initialize(options = {})
  options         = options.dup
  @no_proxy       = options.delete(:no_proxy)
  @inmate_dir     = options.delete(:inmate_dir) || '/hoosegow/inmate'
  @image_name     = options.delete(:image_name)
  @ruby_version   = options.delete(:ruby_version) || RUBY_VERSION
  @docker_options = options
  load_inmate_methods

  # Don't want to have to require these in the container.
  unless no_proxy?
    require 'tmpdir'
    require 'fileutils'
    require 'open3'
    require 'digest'
  end
end

Public Instance Methods

build_image(&block) click to toggle source

Public: Build a Docker image from the Dockerfile in the root directory of the gem.

Returns build output text. Raises ImageBuildError if there is a problem.

# File lib/hoosegow.rb, line 134
def build_image(&block)
  docker.build_image image_name, image_bundle.tarball, &block
end
cleanup() click to toggle source

Public: We create/start a container after every run to reduce latency. This needs to be called before the process ends to cleanup that remaining container.

Returns nothing.

# File lib/hoosegow.rb, line 118
def cleanup
  docker.stop_container
  docker.delete_container
end
image_bundle() click to toggle source

Public: The thing that defines which files go into the docker image tarball.

# File lib/hoosegow.rb, line 50
def image_bundle
  @image_bundle ||=
    Hoosegow::ImageBundle.new.tap do |image|
      image.add(File.expand_path('../../*', __FILE__), :ignore_hidden => true)
      image.add(File.join(@inmate_dir, "*"), :prefix => 'inmate')
      image.ruby_version = @ruby_version
    end
end
image_exists?() click to toggle source

Check if the Docker image exists.

Returns true/false.

# File lib/hoosegow.rb, line 126
def image_exists?
  docker.image_exist? image_name
end
image_name() click to toggle source

Private: The name of the docker image to use. If not specified manually, this will be infered from the hash of the tarball.

Returns string image name.

# File lib/hoosegow.rb, line 142
def image_name
  @image_name || image_bundle.image_name
end
load_inmate_methods() click to toggle source

Public: Load inmate methods from #{inmate_dir}/inmate.rb and hook them up to proxied to the Docker container. If we are in the container, the methods are loaded and setup to be called directly.

Returns nothing. Raises InmateImportError if there is a problem.

# File lib/hoosegow.rb, line 87
def load_inmate_methods
  inmate_file = File.join @inmate_dir, 'inmate.rb'

  unless File.exist?(inmate_file)
    raise Hoosegow::InmateImportError, "inmate file doesn't exist"
  end

  require inmate_file

  unless Hoosegow.const_defined?(:Inmate) && Hoosegow::Inmate.is_a?(Module)
    raise Hoosegow::InmateImportError,
      "inmate file doesn't define Hoosegow::Inmate"
  end

  if no_proxy?
    self.extend Hoosegow::Inmate
  else
    inmate_methods = Hoosegow::Inmate.instance_methods
    inmate_methods.each do |name|
      define_singleton_method name do |*args, &block|
        proxy_send name, args, &block
      end
    end
  end
end
proxy_send(name, args, &block) click to toggle source

Public: Proxies method call to instance running in a Docker container.

name - The method to call in the Docker instance. args - Arguments that should be passed to the Docker instance method. block - A block that can be yielded to.

See docs/dispatch.md for more information.

Returns the return value from the Docker instance method.

# File lib/hoosegow.rb, line 68
def proxy_send(name, args, &block)
  proxy = Hoosegow::Protocol::Proxy.new(
    :stdout => $stdout,
    :stderr => $stderr,
    :yield  => block
  )
  encoded_send = proxy.encode_send(name, args)
  docker.run_container(image_name, encoded_send) do |type, msg|
    proxy.receive(type, msg)
  end

  proxy.return_value
end

Private Instance Methods

docker() click to toggle source

Private: Get or create a Docker instance.

Returns an Docker instance.

# File lib/hoosegow.rb, line 150
def docker
  @docker ||= Docker.new @docker_options
end
no_proxy?() click to toggle source

Returns true if we are in the Docker instance or are in develpment mode.

Returns true/false.

# File lib/hoosegow.rb, line 157
def no_proxy?
  !!@no_proxy
end