vagrant-prison 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +44 -1
- data/lib/vagrant/prison.rb +108 -23
- data/lib/vagrant/prison/version.rb +1 -1
- data/vagrant-prison.gemspec +1 -1
- metadata +4 -3
data/README.md
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
# Vagrant::Prison
|
2
2
|
|
3
3
|
Drive vagrant configuration directly from your test suite, rakefiles, etc.
|
4
|
+
Basically anywhere you can write ruby, you can drive Vagrant.
|
5
|
+
|
6
|
+
## Reasoning and Use Cases
|
7
|
+
|
8
|
+
When you create and configure a `Vagrantfile`, the internals of Vagrant coerce
|
9
|
+
this into a `Vagrant::Environment` object that has a number of properties.
|
10
|
+
Unfortunately, much of Vagrant's design runs under the expectation that all
|
11
|
+
this data comes from a `Vagrantfile` on disk in the current working directory,
|
12
|
+
and therefore `Vagrant::Environment` objects can't be created programmatically
|
13
|
+
-- a problem when you have a desire to create them dynamically and templating
|
14
|
+
Vagrantfiles all over the place isn't really a solution.
|
15
|
+
|
16
|
+
For example, if you want to maintain parity between configuration supplied to
|
17
|
+
Vagrant and your tool that uses Vagrant, or if you want to allow the user to
|
18
|
+
supply additional code to be injected into Vagrantfiles and ensure the code is
|
19
|
+
not only syntactically correct, but is evaluated in the right context.
|
20
|
+
Additionally prison objects can be modified and appended to post hoc, which has
|
21
|
+
some nice advantages from a flexibility standpoint.
|
22
|
+
|
23
|
+
You can also marshal `Vagrant::Prison` objects -- something you can't do with
|
24
|
+
`Vagrant::Environment`. What this is good for is left as an exercise to the
|
25
|
+
reader.
|
26
|
+
|
27
|
+
Vagrant::Prison is to Vagrant what unix jails are ... to unix. It fakes out
|
28
|
+
Vagrant well enough to think it's working with a traditional `Vagrantfile`, but
|
29
|
+
it's actually working with something emulating one, without actually modifying
|
30
|
+
the internals of Vagrant itself. It accomplishes this with recording proxies
|
31
|
+
that are played back to Vagrant when it starts.
|
32
|
+
|
33
|
+
Vagrant::Prison is **not** threadsafe. This is actually a limitation of
|
34
|
+
Vagrant, but there's nothing we can or will do to work around it.
|
4
35
|
|
5
36
|
## Installation
|
6
37
|
|
@@ -36,12 +67,24 @@ prison.configure do |config|
|
|
36
67
|
end
|
37
68
|
end
|
38
69
|
|
39
|
-
#
|
70
|
+
# here's a basic way to start your vms:
|
71
|
+
|
72
|
+
prison.start
|
73
|
+
|
74
|
+
# If you need more flexibility, all the internal Vagrant tooling works -- it
|
75
|
+
# has no idea it's working with a facsimile.
|
76
|
+
#
|
77
|
+
# note that if you don't set :ui_class here, it still works, it just provides
|
78
|
+
# no output.
|
40
79
|
Vagrant::Command::Up.new(
|
41
80
|
[],
|
42
81
|
prison.construct(:ui_class => Vagrant::UI::Basic)
|
43
82
|
).execute
|
44
83
|
|
84
|
+
#
|
85
|
+
# Since we've configured it to destroy on exit here, sleep until someone hits
|
86
|
+
# ^C.
|
87
|
+
#
|
45
88
|
begin
|
46
89
|
sleep
|
47
90
|
rescue Interrupt
|
data/lib/vagrant/prison.rb
CHANGED
@@ -16,6 +16,23 @@ EOF
|
|
16
16
|
|
17
17
|
class Vagrant::Prison
|
18
18
|
attr_reader :dir
|
19
|
+
# name this prison. only used for your needs to refer to later.
|
20
|
+
attr_accessor :name
|
21
|
+
|
22
|
+
def self.cleanup(dir, env)
|
23
|
+
Vagrant::Prison.new(dir, false, env).cleanup
|
24
|
+
end
|
25
|
+
|
26
|
+
# Prisons can't be marshalled because they contain a Vagrant::Environment,
|
27
|
+
# which has some properties about it that Marshal rejects. This routine takes
|
28
|
+
# the output of Vagrant::Prison#save and rebuilds the object.
|
29
|
+
def self._load(str)
|
30
|
+
hash = Marshal.load(str)
|
31
|
+
prison = new(hash[:dir], hash[:cleanup_on_exit])
|
32
|
+
prison.name = hash[:name]
|
33
|
+
prison.configure_environment(hash[:env_opts])
|
34
|
+
return prison
|
35
|
+
end
|
19
36
|
|
20
37
|
#
|
21
38
|
# Construct a new Vagrant sandbox. Takes two arguments: (the third should be
|
@@ -28,15 +45,33 @@ class Vagrant::Prison
|
|
28
45
|
# the program exits, or when this object is garbage collected, which ever
|
29
46
|
# comes first.
|
30
47
|
#
|
31
|
-
def initialize(dir=nil, cleanup_on_exit=true,
|
32
|
-
@dir
|
33
|
-
@initial_config
|
34
|
-
@
|
35
|
-
@cleanup_on_exit
|
48
|
+
def initialize(dir=nil, cleanup_on_exit=true, env_opts={})
|
49
|
+
@dir = dir ||= Dir.mktmpdir
|
50
|
+
@initial_config = nil
|
51
|
+
@env_opts = env_opts.merge(:cwd => @dir, :ui_class => Vagrant::UI::Basic)
|
52
|
+
@cleanup_on_exit = cleanup_on_exit
|
53
|
+
@name = "default"
|
36
54
|
end
|
37
55
|
|
38
|
-
|
39
|
-
|
56
|
+
#
|
57
|
+
# Return a marshalled representation of a Vagrant::Prison. This actually
|
58
|
+
# yields a marshalled array of the directory the prison lives in, and the
|
59
|
+
# options used for creating the Vagrant::Environment.
|
60
|
+
#
|
61
|
+
# This routine will raise if the environment has not been configured yet.
|
62
|
+
#
|
63
|
+
|
64
|
+
def _dump(level)
|
65
|
+
unless @env_opts
|
66
|
+
raise "This environment has not been configured/created! Cannot be dumped."
|
67
|
+
end
|
68
|
+
|
69
|
+
Marshal.dump({
|
70
|
+
:dir => @dir,
|
71
|
+
:cleanup_on_exit => @cleanup_on_exit,
|
72
|
+
:env_opts => @env_opts,
|
73
|
+
:name => @name
|
74
|
+
})
|
40
75
|
end
|
41
76
|
|
42
77
|
#
|
@@ -44,8 +79,11 @@ class Vagrant::Prison
|
|
44
79
|
# the directory will be deleted.
|
45
80
|
#
|
46
81
|
def cleanup
|
47
|
-
|
48
|
-
|
82
|
+
if File.directory?(dir)
|
83
|
+
return destroy && FileUtils.rm_r(dir)
|
84
|
+
end
|
85
|
+
|
86
|
+
return false
|
49
87
|
end
|
50
88
|
|
51
89
|
#
|
@@ -63,6 +101,13 @@ class Vagrant::Prison
|
|
63
101
|
@env_opts
|
64
102
|
end
|
65
103
|
|
104
|
+
#
|
105
|
+
# Returns the Vagrant::Environment, if any.
|
106
|
+
#
|
107
|
+
def env
|
108
|
+
@env
|
109
|
+
end
|
110
|
+
|
66
111
|
#
|
67
112
|
# Configures a Vagrantfile.
|
68
113
|
#
|
@@ -106,8 +151,8 @@ class Vagrant::Prison
|
|
106
151
|
# re-creating it.
|
107
152
|
#
|
108
153
|
def configure_environment(env_opts={})
|
109
|
-
@env_opts
|
110
|
-
@env
|
154
|
+
@env_opts.merge!(env_opts)
|
155
|
+
@env = Vagrant::Environment.new(@env_opts)
|
111
156
|
end
|
112
157
|
|
113
158
|
#
|
@@ -120,6 +165,10 @@ class Vagrant::Prison
|
|
120
165
|
# * if you set `cleanup_on_exit` in the constructor, runs `cleanup` on
|
121
166
|
# garbage collection of this object or program exit, which ever comes first.
|
122
167
|
#
|
168
|
+
# Note, if you supplied environment options here, they will merge into the
|
169
|
+
# ones supplied to the constructor, before the Vagrant::Environment was
|
170
|
+
# created.
|
171
|
+
#
|
123
172
|
def construct(env_opts={})
|
124
173
|
FileUtils.mkdir_p(dir)
|
125
174
|
|
@@ -134,20 +183,44 @@ class Vagrant::Prison
|
|
134
183
|
|
135
184
|
File.binwrite(File.join(dir, "Vagrantfile"), to_write)
|
136
185
|
|
137
|
-
if @cleanup_on_exit
|
138
|
-
# clean up after garbage collection or if the system exits
|
139
|
-
ObjectSpace.define_finalizer(self) do
|
140
|
-
Vagrant::Prison.cleanup(dir, env)
|
141
|
-
end
|
186
|
+
build_cleanup_hooks if @cleanup_on_exit
|
142
187
|
|
143
|
-
|
188
|
+
return @env
|
189
|
+
end
|
144
190
|
|
145
|
-
|
146
|
-
|
147
|
-
|
191
|
+
#
|
192
|
+
# Create the cleanup hooks that tell ruby to torch this prison on garbage
|
193
|
+
# collection or exit.
|
194
|
+
#
|
195
|
+
def build_cleanup_hooks
|
196
|
+
raise "Environment not configured!" unless @env
|
197
|
+
|
198
|
+
env = @env
|
199
|
+
|
200
|
+
# clean up after garbage collection or if the system exits
|
201
|
+
ObjectSpace.define_finalizer(self) do
|
202
|
+
Vagrant::Prison.cleanup(dir, env)
|
148
203
|
end
|
149
204
|
|
150
|
-
|
205
|
+
at_exit do
|
206
|
+
self.cleanup
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
#
|
211
|
+
# Start or 'up' the entire prison. Convenience Method. Will also construct
|
212
|
+
# the environment if it is not already constructed.
|
213
|
+
#
|
214
|
+
|
215
|
+
def start
|
216
|
+
construct unless @env
|
217
|
+
|
218
|
+
Dir.chdir(dir) do
|
219
|
+
Vagrant::Command::Up.new([], @env).execute
|
220
|
+
end
|
221
|
+
return true
|
222
|
+
rescue SystemExit => e
|
223
|
+
return e.status == 0
|
151
224
|
end
|
152
225
|
|
153
226
|
#
|
@@ -155,7 +228,19 @@ class Vagrant::Prison
|
|
155
228
|
# `cleanup` for a one-shot way to orchestrate that.
|
156
229
|
#
|
157
230
|
def destroy
|
158
|
-
|
159
|
-
|
231
|
+
require 'timeout'
|
232
|
+
Dir.chdir(dir) do
|
233
|
+
begin
|
234
|
+
Timeout.timeout(60) do
|
235
|
+
Vagrant::Command::Halt.new([], @env).execute rescue nil
|
236
|
+
end
|
237
|
+
rescue Timeout::Error
|
238
|
+
$stderr.puts "Timeout reached; forcing destroy"
|
239
|
+
end
|
240
|
+
Vagrant::Command::Destroy.new(%w[-f], @env).execute rescue nil
|
241
|
+
end
|
242
|
+
return true
|
243
|
+
rescue SystemExit => e
|
244
|
+
return e.status == 0
|
160
245
|
end
|
161
246
|
end
|
data/vagrant-prison.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.email = ["erik+github@hollensbe.org"]
|
11
11
|
gem.description = %q{A programmatic way to configure and sandbox Vagrant}
|
12
12
|
gem.summary = %q{A programmatic way to configure and sandbox Vagrant}
|
13
|
-
gem.homepage = ""
|
13
|
+
gem.homepage = "https://github.com/chef-workflow/vagrant-prison"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-prison
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: vagrant
|
@@ -43,7 +43,7 @@ files:
|
|
43
43
|
- lib/vagrant/prison/config_proxy.rb
|
44
44
|
- lib/vagrant/prison/version.rb
|
45
45
|
- vagrant-prison.gemspec
|
46
|
-
homepage:
|
46
|
+
homepage: https://github.com/chef-workflow/vagrant-prison
|
47
47
|
licenses: []
|
48
48
|
post_install_message:
|
49
49
|
rdoc_options: []
|
@@ -68,3 +68,4 @@ signing_key:
|
|
68
68
|
specification_version: 3
|
69
69
|
summary: A programmatic way to configure and sandbox Vagrant
|
70
70
|
test_files: []
|
71
|
+
has_rdoc:
|