Class: Hoosegow
- Inherits:
-
Object
- Object
- Hoosegow
- Defined in:
- lib/hoosegow.rb,
lib/hoosegow/docker.rb,
lib/hoosegow/protocol.rb,
lib/hoosegow/exceptions.rb,
lib/hoosegow/image_bundle.rb
Defined Under Namespace
Modules: Protocol Classes: Docker, Error, ImageBuildError, ImageBundle, InmateImportError, InmateRuntimeError
Instance Method Summary collapse
-
#build_image(&block) ⇒ Object
Public: Build a Docker image from the Dockerfile in the root directory of the gem.
-
#cleanup ⇒ Object
Public: We create/start a container after every run to reduce latency.
-
#image_bundle ⇒ Object
Public: The thing that defines which files go into the docker image tarball.
-
#image_exists? ⇒ Boolean
Check if the Docker image exists.
-
#image_name ⇒ Object
Private: The name of the docker image to use.
-
#initialize(options = {}) ⇒ Hoosegow
constructor
Public: Initialize a Hoosegow instance.
-
#load_inmate_methods ⇒ Object
Public: Load inmate methods from #inmate_dir/inmate.rb and hook them up to proxied to the Docker container.
-
#proxy_send(name, args, &block) ⇒ Object
Public: Proxies method call to instance running in a Docker container.
Constructor Details
#initialize(options = {}) ⇒ Hoosegow
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.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/hoosegow.rb', line 31 def initialize( = {}) = .dup @no_proxy = .delete(:no_proxy) @inmate_dir = .delete(:inmate_dir) || '/hoosegow/inmate' @image_name = .delete(:image_name) @ruby_version = .delete(:ruby_version) || RUBY_VERSION @docker_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 |
Instance Method Details
#build_image(&block) ⇒ Object
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.
134 135 136 |
# File 'lib/hoosegow.rb', line 134 def build_image(&block) docker.build_image image_name, image_bundle.tarball, &block end |
#cleanup ⇒ Object
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.
118 119 120 121 |
# File 'lib/hoosegow.rb', line 118 def cleanup docker.stop_container docker.delete_container end |
#image_bundle ⇒ Object
Public: The thing that defines which files go into the docker image tarball.
50 51 52 53 54 55 56 57 |
# File 'lib/hoosegow.rb', line 50 def image_bundle @image_bundle ||= Hoosegow::ImageBundle.new.tap do |image| image.add(File.('../../*', __FILE__), :ignore_hidden => true) image.add(File.join(@inmate_dir, "*"), :prefix => 'inmate') image.ruby_version = @ruby_version end end |
#image_exists? ⇒ Boolean
Check if the Docker image exists.
Returns true/false.
126 127 128 |
# File 'lib/hoosegow.rb', line 126 def image_exists? docker.image_exist? image_name end |
#image_name ⇒ Object
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.
142 143 144 |
# File 'lib/hoosegow.rb', line 142 def image_name @image_name || image_bundle.image_name end |
#load_inmate_methods ⇒ Object
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.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# 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) ⇒ Object
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.
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# 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 |