vagrant-prison 0.0.4 → 0.1.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.
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: