hoosegow 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Dockerfile +46 -0
- data/Gemfile +9 -0
- data/LICENSE +21 -0
- data/README.md +82 -0
- data/Rakefile +37 -0
- data/bin/hoosegow +14 -0
- data/docs/dispatch-seq.txt +13 -0
- data/docs/dispatch.md +53 -0
- data/docs/dispatch.png +0 -0
- data/hoosegow.gemspec +32 -0
- data/lib/hoosegow.rb +160 -0
- data/lib/hoosegow/docker.rb +236 -0
- data/lib/hoosegow/exceptions.rb +27 -0
- data/lib/hoosegow/image_bundle.rb +111 -0
- data/lib/hoosegow/protocol.rb +133 -0
- data/script/proxy-integration-test +95 -0
- data/spec/hoosegow_docker_spec.rb +109 -0
- data/spec/hoosegow_spec.rb +170 -0
- data/spec/test_inmate/inmate.rb +7 -0
- metadata +159 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative '../lib/hoosegow'
|
5
|
+
|
6
|
+
inmate_dir = '/hoosegow/inmate'
|
7
|
+
inmate_file = File.join(inmate_dir, 'inmate.rb')
|
8
|
+
if File.exist?(inmate_file)
|
9
|
+
system 'ls', '-l', inmate_dir
|
10
|
+
puts "ERROR: #{inmate_file} must not exist!"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
FileUtils.mkpath(inmate_dir)
|
15
|
+
File.write(inmate_file, <<INMATE)
|
16
|
+
class Hoosegow
|
17
|
+
module Inmate
|
18
|
+
def test_method(a, b)
|
19
|
+
yield :ok if block_given?
|
20
|
+
system "echo stdout in a child process"
|
21
|
+
$stderr.puts "stderr in this process"
|
22
|
+
raise b if a.to_s == 'raise'
|
23
|
+
a + b
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
INMATE
|
28
|
+
|
29
|
+
at_exit { FileUtils.remove_entry_secure(inmate_file) }
|
30
|
+
|
31
|
+
def main
|
32
|
+
each_hoosegow do |hoosegow|
|
33
|
+
try(hoosegow, :test_method, 1, 2)
|
34
|
+
try(hoosegow, :test_method, 1, 2) { |x| puts x }
|
35
|
+
try(hoosegow, :test_method, :raise, 'boom')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def try(hoosegow, method, *args, &block)
|
40
|
+
puts '-'*10
|
41
|
+
p :method => method, :args => args, :block? => !block.nil?
|
42
|
+
result = hoosegow.send(method, *args, &block)
|
43
|
+
p :result => result
|
44
|
+
rescue => error
|
45
|
+
p :error => error
|
46
|
+
#puts error.backtrace
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_hoosegow
|
50
|
+
puts '*'*10, 'no_proxy => true'
|
51
|
+
yield Hoosegow.new(:no_proxy => true)
|
52
|
+
puts '*'*10, 'no_proxy => false'
|
53
|
+
with_fake_docker do |docker|
|
54
|
+
yield docker.inject(Hoosegow.new)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def with_fake_docker
|
59
|
+
yield FakeDocker.new
|
60
|
+
end
|
61
|
+
|
62
|
+
class FakeDocker
|
63
|
+
def inject(hoosegow)
|
64
|
+
docker = self
|
65
|
+
hoosegow.define_singleton_method(:docker) { docker }
|
66
|
+
hoosegow
|
67
|
+
end
|
68
|
+
|
69
|
+
def run_container(image_name, input_data)
|
70
|
+
Open3.popen3("./bin/hoosegow") do |stdin, stdout, stderr, wait_thr|
|
71
|
+
stdin.write(input_data)
|
72
|
+
stdin.close
|
73
|
+
ios = [stdout, stderr]
|
74
|
+
while ios.any? do
|
75
|
+
readers, _, _ = IO.select(ios, [], [], 1)
|
76
|
+
if readers.nil?
|
77
|
+
break unless wait_thr.alive?
|
78
|
+
else
|
79
|
+
readers.each do |reader|
|
80
|
+
begin
|
81
|
+
type = reader == stdout ? 1 : 2
|
82
|
+
data = reader.read_nonblock(2**15)
|
83
|
+
yield([type, data.bytesize].pack('CxxxN') + data)
|
84
|
+
rescue EOFError
|
85
|
+
ios.delete(reader)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
wait_thr.join
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
main
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require_relative '../lib/hoosegow'
|
2
|
+
|
3
|
+
unless defined?(CONFIG)
|
4
|
+
begin
|
5
|
+
require_relative '../config'
|
6
|
+
rescue LoadError
|
7
|
+
CONFIG = {}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
inmate_dir = File.join(File.dirname(__FILE__), 'test_inmate')
|
12
|
+
CONFIG[:inmate_dir] = inmate_dir
|
13
|
+
CONFIG[:image_name] ||= Hoosegow.new(CONFIG).image_name
|
14
|
+
|
15
|
+
describe Hoosegow::Docker do
|
16
|
+
context 'volumes' do
|
17
|
+
subject { described_class.new(:volumes => volumes) }
|
18
|
+
|
19
|
+
context 'unspecified' do
|
20
|
+
subject { described_class.new }
|
21
|
+
its(:volumes_for_create) { should be_empty }
|
22
|
+
its(:volumes_for_bind) { should be_empty }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'empty' do
|
26
|
+
let(:volumes) { {} }
|
27
|
+
its(:volumes_for_create) { should be_empty }
|
28
|
+
its(:volumes_for_bind) { should be_empty }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with volumes' do
|
32
|
+
let(:volumes) { {
|
33
|
+
"/inside/path" => "/home/burke/data-for-container:rw",
|
34
|
+
"/other/path" => "/etc/shared-config",
|
35
|
+
} }
|
36
|
+
its(:volumes_for_create) { should == {
|
37
|
+
"/inside/path" => {},
|
38
|
+
"/other/path" => {},
|
39
|
+
} }
|
40
|
+
its(:volumes_for_bind) { should == [
|
41
|
+
"/home/burke/data-for-container:/inside/path:rw",
|
42
|
+
"/etc/shared-config:/other/path:ro",
|
43
|
+
] }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'docker_url' do
|
48
|
+
it "correctly generates TCP urls" do
|
49
|
+
hoosegow = Hoosegow::Docker.new CONFIG.merge(:host => "1.1.1.1", :port => 1234)
|
50
|
+
expect(::Docker.url).to eq("tcp://1.1.1.1:1234")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "correctly generates Unix urls" do
|
54
|
+
hoosegow = Hoosegow::Docker.new CONFIG.merge(:socket => "/path/to/socket")
|
55
|
+
expect(::Docker.url).to eq("unix:///path/to/socket")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "callbacks" do
|
60
|
+
let(:cb) { lambda { |info| } }
|
61
|
+
|
62
|
+
it "calls after_create" do
|
63
|
+
expect(cb).to receive(:call).with { |*args| args.first.is_a? Hash }
|
64
|
+
docker = Hoosegow::Docker.new CONFIG.merge(:after_create => cb)
|
65
|
+
begin
|
66
|
+
docker.create_container CONFIG[:image_name]
|
67
|
+
ensure
|
68
|
+
docker.stop_container
|
69
|
+
docker.delete_container
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "calls after_start" do
|
74
|
+
expect(cb).to receive(:call).with { |*args| args.first.is_a? Hash }
|
75
|
+
docker = Hoosegow::Docker.new CONFIG.merge(:after_start => cb)
|
76
|
+
begin
|
77
|
+
docker.create_container CONFIG[:image_name]
|
78
|
+
docker.start_container
|
79
|
+
ensure
|
80
|
+
docker.stop_container
|
81
|
+
docker.delete_container
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "calls after_stop" do
|
86
|
+
expect(cb).to receive(:call).with { |*args| args.first.is_a? Hash }
|
87
|
+
docker = Hoosegow::Docker.new CONFIG.merge(:after_stop => cb)
|
88
|
+
begin
|
89
|
+
docker.create_container CONFIG[:image_name]
|
90
|
+
docker.start_container
|
91
|
+
ensure
|
92
|
+
docker.stop_container
|
93
|
+
docker.delete_container
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "image_exist?" do
|
99
|
+
it "returns true if the image exists" do
|
100
|
+
docker = Hoosegow::Docker.new CONFIG
|
101
|
+
expect(docker.image_exist?(CONFIG[:image_name])).to eq(true)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "returns false if the image doesn't exist" do
|
105
|
+
docker = Hoosegow::Docker.new CONFIG
|
106
|
+
expect(docker.image_exist?("not_there")).to eq(false)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require_relative '../lib/hoosegow'
|
2
|
+
require 'msgpack'
|
3
|
+
|
4
|
+
unless defined?(CONFIG)
|
5
|
+
begin
|
6
|
+
require_relative '../config'
|
7
|
+
rescue LoadError
|
8
|
+
CONFIG = {}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
inmate_dir = File.join(File.dirname(__FILE__), 'test_inmate')
|
13
|
+
CONFIG[:inmate_dir] = inmate_dir
|
14
|
+
CONFIG[:image_name] ||= Hoosegow.new(CONFIG).image_name
|
15
|
+
|
16
|
+
describe Hoosegow do
|
17
|
+
context "no_proxy option" do
|
18
|
+
it "runs directly if set" do
|
19
|
+
hoosegow = Hoosegow.new CONFIG.merge(:no_proxy => true)
|
20
|
+
hoosegow.stub :proxy_send => "not raboof"
|
21
|
+
hoosegow.render_reverse("foobar").should eq("raboof")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "runs via proxy if not set" do
|
25
|
+
hoosegow = Hoosegow.new CONFIG
|
26
|
+
hoosegow.stub :proxy_send => "not raboof"
|
27
|
+
hoosegow.render_reverse("foobar").should eq("not raboof")
|
28
|
+
hoosegow.cleanup
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "image_exists?" do
|
33
|
+
it "returns true for existing images" do
|
34
|
+
hoosegow = Hoosegow.new CONFIG
|
35
|
+
expect(hoosegow.image_exists?).to eq(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns false for images that don't exist" do
|
39
|
+
hoosegow = Hoosegow.new CONFIG.merge(:image_name => "not_there")
|
40
|
+
expect(hoosegow.image_exists?).to eq(false)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
describe Hoosegow::Protocol::Proxy do
|
47
|
+
subject(:proxy) { Hoosegow::Protocol::Proxy.new(:yield => block, :stdout => stdout, :stderr => stderr) }
|
48
|
+
let(:block) { double('block') }
|
49
|
+
let(:stdout) { double('stdout') }
|
50
|
+
let(:stderr) { double('stderr') }
|
51
|
+
|
52
|
+
it "encodes the method call" do
|
53
|
+
expect(MessagePack.unpack(proxy.encode_send(:method_name, ["arg1", {:name => 'value'}]))).to eq(['method_name', ["arg1", {'name' => 'value'}]])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "decodes a yield" do
|
57
|
+
block.should_receive(:call).with('a', 'b')
|
58
|
+
proxy.receive(:stdout, MessagePack.pack([:yield, ['a', 'b']]))
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with no block' do
|
62
|
+
let(:block) { nil }
|
63
|
+
it "decodes a yield" do
|
64
|
+
proxy.receive(:stdout, MessagePack.pack([:yield, ['a', 'b']]))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "decodes the return value" do
|
69
|
+
proxy.receive(:stdout, MessagePack.pack([:return, 1]))
|
70
|
+
expect(proxy.return_value).to eq(1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "decodes a known error class" do
|
74
|
+
expect { proxy.receive(:stdout, MessagePack.pack([:raise, {:class => 'RuntimeError', :message => 'I went boom'}])) }.to raise_error(Hoosegow::InmateRuntimeError, "RuntimeError: I went boom")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "decodes an error" do
|
78
|
+
expect { proxy.receive(:stdout, MessagePack.pack([:raise, {:class => 'SomeInternalError', :message => 'I went boom'}])) }.to raise_error(Hoosegow::InmateRuntimeError, "SomeInternalError: I went boom")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "decodes an error with a stack trace" do
|
82
|
+
expect { proxy.receive(:stdout, MessagePack.pack([:raise, {:class => 'SomeInternalError', :message => 'I went boom', :backtrace => ['file.rb:33:in `example\'']}])) }.to raise_error(Hoosegow::InmateRuntimeError, "SomeInternalError: I went boom\nfile.rb:33:in `example'")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "decodes stdout" do
|
86
|
+
stdout.should_receive(:write).with('abc')
|
87
|
+
proxy.receive(:stdout, MessagePack.pack([:stdout, 'abc']))
|
88
|
+
end
|
89
|
+
|
90
|
+
it "decodes stderr" do
|
91
|
+
stderr.should_receive(:write).with('abc')
|
92
|
+
proxy.receive(:stderr, 'abc')
|
93
|
+
end
|
94
|
+
|
95
|
+
it "decodes the return value, across several reads" do
|
96
|
+
MessagePack.pack([:return, :abcdefghijklmn]).each_char do |char|
|
97
|
+
proxy.receive(:stdout, char)
|
98
|
+
end
|
99
|
+
expect(proxy.return_value).to eq('abcdefghijklmn')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe Hoosegow::Protocol::Inmate do
|
104
|
+
it "calls appropriate render method" do
|
105
|
+
inmate = double('inmate')
|
106
|
+
inmate.should_receive(:render).with('foobar').
|
107
|
+
and_yield(:a, 1).
|
108
|
+
and_yield(:b, 2, 3).
|
109
|
+
and_return('raboof')
|
110
|
+
|
111
|
+
stdin = StringIO.new(MessagePack.pack(['render', ['foobar']]))
|
112
|
+
stdout = StringIO.new
|
113
|
+
stdout.set_encoding('BINARY')
|
114
|
+
r,w = IO.pipe
|
115
|
+
|
116
|
+
Hoosegow::Protocol::Inmate.run(:inmate => inmate, :stdin => stdin, :stdout => stdout, :intercepted => r)
|
117
|
+
|
118
|
+
expect(stdout.string).to eq( MessagePack.pack([:yield, [:a, 1]]) + MessagePack.pack([:yield, [:b, 2, 3]]) + MessagePack.pack([:return, 'raboof']) )
|
119
|
+
end
|
120
|
+
|
121
|
+
it "encodes exceptions" do
|
122
|
+
inmate = Object.new
|
123
|
+
def inmate.render(s) ; raise 'boom' ; end
|
124
|
+
|
125
|
+
stdin = StringIO.new(MessagePack.pack(['render', ['foobar']]))
|
126
|
+
stdout = StringIO.new
|
127
|
+
stdout.set_encoding('BINARY')
|
128
|
+
r,w = IO.pipe
|
129
|
+
|
130
|
+
Hoosegow::Protocol::Inmate.run(:inmate => inmate, :stdin => stdin, :stdout => stdout, :intercepted => r)
|
131
|
+
|
132
|
+
unpacked_type, unpacked_data = MessagePack.unpack(stdout.string)
|
133
|
+
expect(unpacked_type).to eq('raise')
|
134
|
+
expect(unpacked_data).to include('class' => 'RuntimeError')
|
135
|
+
expect(unpacked_data).to include('message' => 'boom')
|
136
|
+
expect(unpacked_data['backtrace']).to be_a(Array)
|
137
|
+
expect(unpacked_data['backtrace'].first).to eq("#{__FILE__}:#{__LINE__ - 14}:in `render'")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "does not hang if stdin isn't closed" do
|
141
|
+
# Use a pipe so that we have a not-closed IO
|
142
|
+
stdin, feed_stdin = IO.pipe
|
143
|
+
feed_stdin.write(MessagePack.pack(['render', ['foobar']]))
|
144
|
+
|
145
|
+
inmate = double('inmate')
|
146
|
+
inmate.should_receive(:render).with('foobar').and_return('raboof')
|
147
|
+
stdout = StringIO.new
|
148
|
+
stdout.set_encoding('BINARY')
|
149
|
+
r,w = IO.pipe
|
150
|
+
|
151
|
+
timeout(2) { Hoosegow::Protocol::Inmate.run(:inmate => inmate, :stdin => stdin, :stdout => stdout, :intercepted => r) }
|
152
|
+
end
|
153
|
+
|
154
|
+
it "encodes stdout" do
|
155
|
+
inmate = double('inmate')
|
156
|
+
inmate.should_receive(:render).with('foobar').and_return('raboof')
|
157
|
+
|
158
|
+
stdin = StringIO.new(MessagePack.pack(['render', ['foobar']]))
|
159
|
+
stdout = StringIO.new
|
160
|
+
stdout.set_encoding('BINARY')
|
161
|
+
r,w = IO.pipe
|
162
|
+
w.puts "STDOUT from somewhere"
|
163
|
+
|
164
|
+
Hoosegow::Protocol::Inmate.run(:inmate => inmate, :stdin => stdin, :stdout => stdout, :intercepted => r)
|
165
|
+
|
166
|
+
encoded_stdout = MessagePack.pack([:stdout, "STDOUT from somewhere\n"])
|
167
|
+
encoded_return = MessagePack.pack([:return, 'raboof'])
|
168
|
+
expect([encoded_stdout+encoded_return, encoded_return+encoded_stdout]).to include(stdout.string)
|
169
|
+
end
|
170
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hoosegow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Toews
|
8
|
+
- Matt Burke
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-10-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 10.3.2
|
21
|
+
- - "~>"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '10.3'
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 10.3.2
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.3'
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rspec
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.14.1
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.14'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.14.1
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.14'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: msgpack
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.5.6
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0.5'
|
64
|
+
type: :runtime
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 0.5.6
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0.5'
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: yajl-ruby
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.1.0
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.1'
|
84
|
+
type: :runtime
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.1.0
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.1'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: docker-api
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.13.6
|
101
|
+
type: :runtime
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: 1.13.6
|
108
|
+
description: Hoosegow provides an RPC layer on top of Docker containers so that you
|
109
|
+
can isolate unsafe parts of your application.
|
110
|
+
email: mastahyeti@github.com
|
111
|
+
executables:
|
112
|
+
- hoosegow
|
113
|
+
extensions: []
|
114
|
+
extra_rdoc_files: []
|
115
|
+
files:
|
116
|
+
- Dockerfile
|
117
|
+
- Gemfile
|
118
|
+
- LICENSE
|
119
|
+
- README.md
|
120
|
+
- Rakefile
|
121
|
+
- bin/hoosegow
|
122
|
+
- docs/dispatch-seq.txt
|
123
|
+
- docs/dispatch.md
|
124
|
+
- docs/dispatch.png
|
125
|
+
- hoosegow.gemspec
|
126
|
+
- lib/hoosegow.rb
|
127
|
+
- lib/hoosegow/docker.rb
|
128
|
+
- lib/hoosegow/exceptions.rb
|
129
|
+
- lib/hoosegow/image_bundle.rb
|
130
|
+
- lib/hoosegow/protocol.rb
|
131
|
+
- script/proxy-integration-test
|
132
|
+
- spec/hoosegow_docker_spec.rb
|
133
|
+
- spec/hoosegow_spec.rb
|
134
|
+
- spec/test_inmate/inmate.rb
|
135
|
+
homepage: https://github.com/github/hoosegow
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: 1.9.3
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.2.2
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: A Docker jail for ruby code
|
159
|
+
test_files: []
|