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 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
- # if you don't set :ui_class here, it still works, it just provides no output.
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
@@ -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, env=nil)
32
- @dir = dir ||= Dir.mktmpdir
33
- @initial_config = nil
34
- @env = env
35
- @cleanup_on_exit = 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
- def self.cleanup(dir, env)
39
- Vagrant::Prison.new(dir, false, env).cleanup
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
- destroy
48
- FileUtils.rm_r(dir)
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 ||= env_opts.merge(:cwd => dir)
110
- @env ||= Vagrant::Environment.new(@env_opts)
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
- obj = self # look ma, closures
188
+ return @env
189
+ end
144
190
 
145
- at_exit do
146
- obj.cleanup
147
- end
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
- return @env
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
- Dir.chdir(dir)
159
- Vagrant::Command::Destroy.new(%w[-f], @env).execute
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
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
2
  class Prison
3
- VERSION = "0.0.4"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -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
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-11-09 00:00:00.000000000 Z
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: