vagrant-sparseimage 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/Rakefile +3 -0
- data/Readme.md +57 -0
- data/lib/vagrant-sparseimage.rb +302 -0
- data/lib/vagrant-sparseimage/command.rb +120 -0
- data/lib/vagrant-sparseimage/hdiutil.rb +61 -0
- data/lib/version.rb +3 -0
- data/vagrant-sparseimage.gemspec +26 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2a0f121456732b4aeacec24a5796225d43c6d71e
|
4
|
+
data.tar.gz: 4ffeb73df027750366d21955d52a55f6c4aa4f49
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 808161d145589729590d300e26672dc1962d2dcf4581462cba39d51eee9409b559d4403bb08a1ea713fe4a4554bac0eb940d5eec1be3f4e7bb720411afe84568
|
7
|
+
data.tar.gz: 56fbfcaf2dac82c1aa4f97bbb6b6e1742c5ce5e9015280bf0cadc8a8fcea558bc9db93461981d5536b4479d0153839d750da4f2f78ac880e8dc69c7ee58770b0
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2006-2013 Learnosity Ltd.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# vagrant-sparseimage
|
2
|
+
|
3
|
+
`vagrant-sparseimage` is a [Vagrant](http://vagrantup.com) plugin which automatically creates and mounts a sparseimage for the guest system to share. This allows alternative filesystems to be used between the host and the guest (eg. journaled, case sensitive).
|
4
|
+
|
5
|
+
The image can be browser from OSX Finder and is completely configurable. It can be unmounted automatically when the guest is halted, or left mounted for other uses. When the Vagrant guest is destroyed, the image can optionally be destroyed too.
|
6
|
+
|
7
|
+
## Dependencies
|
8
|
+
|
9
|
+
Only runs in OSX. Requires Vagrant v1.2+.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
See **building** below for building the gem.
|
14
|
+
|
15
|
+
Use `vagrant plugin` to install the gem in your Vagrant environment:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ vagrant plugin install vagrant-sparseimage.gem
|
19
|
+
```
|
20
|
+
|
21
|
+
## Configuration
|
22
|
+
|
23
|
+
See `example-box/Vagrantfile`. Each vm has a sparseimage configuration object which can have an arbitrary number of images added to it.
|
24
|
+
|
25
|
+
The following config properties for `config.sparseimage` are compulsory:
|
26
|
+
|
27
|
+
* **volume_name**: the name that will be used to mount the volume and derive its filename
|
28
|
+
* **image_type**: `SPARSEIMAGE` or `SPARSEBUNDLE`
|
29
|
+
* **image_fs**: filesystem type: see below for list of supported formats
|
30
|
+
* **vm_mountpoint**: where to mount the image wihtin the guest
|
31
|
+
* **image_size**: size in MB. both image types will consume space lazily
|
32
|
+
* **image_folder**: the folder on the host to store the image file in
|
33
|
+
|
34
|
+
The following properties are optional:
|
35
|
+
|
36
|
+
* **auto_unmount**: whether to unmount the image from the host when the guest is stopped. Defaults to true.
|
37
|
+
* **mounted_name**: the full path to mount the sparse bundles in. Defaults using the name of the volume.
|
38
|
+
|
39
|
+
## Filesystems
|
40
|
+
|
41
|
+
* HFS+
|
42
|
+
* HFS+J (`JHFS+` in the config)
|
43
|
+
* HFSX
|
44
|
+
* JHFS+X
|
45
|
+
* MS-DOS
|
46
|
+
* UDF
|
47
|
+
|
48
|
+
## Building
|
49
|
+
|
50
|
+
If you installed vagrant using RubyGems, use:
|
51
|
+
|
52
|
+
```bash
|
53
|
+
$ bundle install
|
54
|
+
$ gem build vagrant-sparseimage.gemspec
|
55
|
+
```
|
56
|
+
|
57
|
+
If you installed Vagrant with a prebuilt package or installer, you need to use Vagrant's gem wrapper:
|
@@ -0,0 +1,302 @@
|
|
1
|
+
begin
|
2
|
+
FileUtils
|
3
|
+
rescue NameError
|
4
|
+
begin
|
5
|
+
require 'FileUtils'
|
6
|
+
rescue LoadError
|
7
|
+
require 'fileutils'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'pp'
|
12
|
+
require 'optparse'
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'vagrant'
|
16
|
+
rescue LoadError
|
17
|
+
raise 'The Vagrant SparseImage plugin must be run within Vagrant.'
|
18
|
+
end
|
19
|
+
require Vagrant.source_root.join("plugins/commands/up/start_mixins")
|
20
|
+
|
21
|
+
require File.expand_path("../vagrant-sparseimage/command", __FILE__)
|
22
|
+
require File.expand_path("../vagrant-sparseimage/hdiutil", __FILE__)
|
23
|
+
|
24
|
+
module SparseImage
|
25
|
+
|
26
|
+
class << self
|
27
|
+
# Run the command, wait for exit and return the Process object.
|
28
|
+
def run(cmd)
|
29
|
+
pid = Process.fork { exec(cmd) }
|
30
|
+
Process.waitpid(pid)
|
31
|
+
return $?
|
32
|
+
end
|
33
|
+
|
34
|
+
def list(vm)
|
35
|
+
vm.config.sparseimage.to_hash[:images].each do |opts|
|
36
|
+
pp opts.to_hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def mount(vm)
|
41
|
+
# mount each configured sparse image
|
42
|
+
vm.config.sparseimage.to_hash[:images].each do |opts|
|
43
|
+
# Derive the full image filename and volume mount path (for the host)
|
44
|
+
full_image_filename = "#{opts.image_folder}/#{opts.volume_name}.#{opts.image_type}".downcase
|
45
|
+
|
46
|
+
# Does the image need to be created?
|
47
|
+
if File.exists? full_image_filename
|
48
|
+
vm.ui.info "Found sparse disk image: #{full_image_filename}"
|
49
|
+
else
|
50
|
+
# Create the directory if it does not exist
|
51
|
+
FileUtils.mkdir_p opts.image_folder if not File.exists? opts.image_folder
|
52
|
+
|
53
|
+
# hdiutil is finnicky with image type
|
54
|
+
type = opts.image_type == 'SPARSEIMAGE' ? 'SPARSE' : opts.image_type
|
55
|
+
vm.ui.info "Creating #{opts.image_size}MB sparse disk image: #{full_image_filename}"
|
56
|
+
# TODO - move this into SparseImage::HDIUTIL::create
|
57
|
+
# TODO - raise an exception if create fails
|
58
|
+
SparseImage::HDIUTIL::create(vm, type, opts.image_size, opts.image_fs, opts.volume_name, full_image_filename)
|
59
|
+
vm.ui.info("Created disk image in the host: #{full_image_filename}")
|
60
|
+
end
|
61
|
+
|
62
|
+
# Mount the image in the host
|
63
|
+
vm.ui.info("Mounting disk image in the host: #{full_image_filename} at #{opts.mounted_name}")
|
64
|
+
SparseImage::HDIUTIL::mount(vm, opts.mounted_name, full_image_filename)
|
65
|
+
|
66
|
+
# Remove nonsense hidden files
|
67
|
+
errors = SparseImage::HDIUTIL::remove_OSX_fuzz(vm, opts.mounted_name)
|
68
|
+
if errors.length > 0
|
69
|
+
errors.each do |error| vm.ui.info(error) end
|
70
|
+
end
|
71
|
+
|
72
|
+
if opts.vm_mountpoint
|
73
|
+
vm.config.vm.synced_folders[opts.volume_name] = {
|
74
|
+
:hostpath => opts.mounted_name,
|
75
|
+
:guestpath => opts.vm_mountpoint,
|
76
|
+
:disabled => false,
|
77
|
+
}
|
78
|
+
vm.ui.info("Mounted disk image in the guest: #{full_image_filename} at #{opts.vm_mountpoint}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def unmount(vm)
|
84
|
+
# Unmount each configured sparse image
|
85
|
+
vm.config.sparseimage.to_hash[:images].each do |opts|
|
86
|
+
if opts.auto_unmount
|
87
|
+
SparseImage::HDIUTIL::unmount(vm, opts.mounted_name)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def destroy(vm)
|
93
|
+
# Prompt to destroy each configured sparse image
|
94
|
+
vm.config.sparseimage.to_hash[:images].each do |opts|
|
95
|
+
cancel = false
|
96
|
+
full_image_filename = "#{opts.image_folder}/#{opts.volume_name}.#{opts.image_type}".downcase
|
97
|
+
# Confirm destruction of the sparse image
|
98
|
+
while cancel == false
|
99
|
+
choice = vm.ui.ask("Do you want to delete the sparse image at #{full_image_filename}? [y/N] ")
|
100
|
+
if choice.upcase == 'Y'
|
101
|
+
choice = vm.ui.ask("Confirm the name of the volume to destroy [#{ opts.volume_name}] ")
|
102
|
+
if choice == opts.volume_name
|
103
|
+
# TODO - Test first whether it's mounted before trying to unmount
|
104
|
+
#SparseImage::HDIUTIL::unmount(vm, opts.mounted_name)
|
105
|
+
SparseImage::HDIUTIL::destroy(vm, full_image_filename)
|
106
|
+
cancel = true
|
107
|
+
else
|
108
|
+
vm.ui.error("name does not match.")
|
109
|
+
end
|
110
|
+
else
|
111
|
+
cancel = true
|
112
|
+
vm.ui.error("Image '#{opts.volume_name}' was not destroyed.")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class ImageConfig
|
120
|
+
# Configuration for a single sparse image
|
121
|
+
# Not exposed to vagrant.
|
122
|
+
|
123
|
+
attr_accessor :vm_mountpoint, :image_size, :image_fs, :image_type, :volume_name, :image_folder,
|
124
|
+
:auto_unmount, :mounted_name
|
125
|
+
|
126
|
+
@@required = [
|
127
|
+
:volume_name,
|
128
|
+
:image_type,
|
129
|
+
:image_fs,
|
130
|
+
:image_size,
|
131
|
+
:image_folder
|
132
|
+
]
|
133
|
+
|
134
|
+
@@valid_image_types = ["SPARSEIMAGE", "SPARSEBUNDLE"]
|
135
|
+
|
136
|
+
def validate
|
137
|
+
errors = []
|
138
|
+
# Check for the required config keys
|
139
|
+
@@required.each do |key|
|
140
|
+
if not to_hash[key] or (to_hash[key].is_a? String and to_hash[key].length == 0)
|
141
|
+
errors.push "#{key} must be present."
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Validate image type
|
146
|
+
if not @@valid_image_types.include?(@image_type)
|
147
|
+
errors.push "image_type: invalid value: only supports #{@@valid_image_types.join(',')}"
|
148
|
+
end
|
149
|
+
|
150
|
+
# Size must be an int
|
151
|
+
if @image_size and not @image_size.is_a? Fixnum
|
152
|
+
errors.push "image_size: Must be a number."
|
153
|
+
end
|
154
|
+
{ "vagrant-sparseimage" => errors }
|
155
|
+
end
|
156
|
+
|
157
|
+
def finalize!
|
158
|
+
if @auto_unmount.nil?
|
159
|
+
@auto_unmount = true
|
160
|
+
end
|
161
|
+
if @mounted_name.nil?
|
162
|
+
@mounted_name = "./#{@volume_name}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_hash
|
167
|
+
{ :vm_mountpoint => @vm_mountpoint,
|
168
|
+
:image_size => @image_size,
|
169
|
+
:image_fs => @image_fs,
|
170
|
+
:image_type => @image_type,
|
171
|
+
:volume_name => @volume_name,
|
172
|
+
:auto_unmount => @auto_unmount,
|
173
|
+
:image_folder => @image_folder,
|
174
|
+
:mounted_name => @mounted_name
|
175
|
+
}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class Mount
|
180
|
+
# Mount sparse images on the host machine and add them to the config for the guest
|
181
|
+
# Create the sparse image files if necessary.
|
182
|
+
|
183
|
+
def initialize(app, env)
|
184
|
+
@app = app
|
185
|
+
@env = env
|
186
|
+
end
|
187
|
+
|
188
|
+
def call(env)
|
189
|
+
vm = env[:machine]
|
190
|
+
SparseImage::mount(vm)
|
191
|
+
@app.call(env)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class Unmount
|
196
|
+
# Startup hook
|
197
|
+
# Unmount the shared drive from the host machine
|
198
|
+
# Fails silently if the drive was not mounted
|
199
|
+
def initialize(app, env)
|
200
|
+
@app = app
|
201
|
+
@env = env
|
202
|
+
end
|
203
|
+
def call(env)
|
204
|
+
vm = env[:machine]
|
205
|
+
SparseImage::mount(vm)
|
206
|
+
@app.call(env)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
class Unmount
|
211
|
+
# Shutdown hook
|
212
|
+
# Unmount the shared drive from the host machine
|
213
|
+
# Fails silently if the drive was not mounted
|
214
|
+
def initialize(app, env)
|
215
|
+
@app = app
|
216
|
+
@env = env
|
217
|
+
end
|
218
|
+
def call(env)
|
219
|
+
vm = env[:machine]
|
220
|
+
SparseImage::unmount(vm)
|
221
|
+
@app.call(env)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class Destroy
|
226
|
+
# Shutdown hook
|
227
|
+
# Unmount the shared drive from the host machine and delete it.
|
228
|
+
# Confirm with the user first.
|
229
|
+
def initialize(app, env)
|
230
|
+
@app = app
|
231
|
+
@env = env
|
232
|
+
end
|
233
|
+
def call(env)
|
234
|
+
vm = env[:machine]
|
235
|
+
SparseImage::destroy(vm)
|
236
|
+
@app.call(env)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class Config < Vagrant.plugin("2", :config)
|
241
|
+
# Singleton
|
242
|
+
@@images = []
|
243
|
+
class << self
|
244
|
+
attr_accessor :images
|
245
|
+
end
|
246
|
+
|
247
|
+
def add_image
|
248
|
+
if not block_given?
|
249
|
+
raise 'add_image must be given a block.'
|
250
|
+
end
|
251
|
+
image = ImageConfig.new
|
252
|
+
yield image
|
253
|
+
@@images.push(image)
|
254
|
+
end
|
255
|
+
|
256
|
+
def finalize!
|
257
|
+
@@images.each do |image|
|
258
|
+
image.finalize!
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def validate(machine)
|
263
|
+
errors = {}
|
264
|
+
# Validate each of the image configs in turn
|
265
|
+
@@images.each_with_index do |image, i|
|
266
|
+
image_errors = image.validate()
|
267
|
+
if image_errors.length > 0
|
268
|
+
image_errors.each do |key, value|
|
269
|
+
errors[key] ||= []
|
270
|
+
errors[key] += value
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
errors
|
275
|
+
end
|
276
|
+
|
277
|
+
def to_hash
|
278
|
+
return { :images => @@images }
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
class Plugin < Vagrant.plugin("2")
|
283
|
+
name "vagrant sparse image support"
|
284
|
+
description "A vagrant plugin to managed shared sparse images."
|
285
|
+
|
286
|
+
config(:sparseimage) do
|
287
|
+
# Yield a config object to the vagrant file.
|
288
|
+
# Vagrant will handle persisting the state of this object for each VM.
|
289
|
+
Config
|
290
|
+
end
|
291
|
+
|
292
|
+
command("sparseimage") do
|
293
|
+
Command::Root
|
294
|
+
end
|
295
|
+
|
296
|
+
action_hook(self::ALL_ACTIONS) do |hook|
|
297
|
+
hook.before(Vagrant::Action::Builtin::SyncedFolders, Mount)
|
298
|
+
hook.after(Vagrant::Action::Builtin::GracefulHalt, Unmount)
|
299
|
+
hook.after(Vagrant::Action::Builtin::DestroyConfirm, Destroy)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'vagrant'
|
2
|
+
|
3
|
+
module SparseImage
|
4
|
+
module Command
|
5
|
+
class Root < Vagrant.plugin("2", :command)
|
6
|
+
def initialize(argv, env)
|
7
|
+
super
|
8
|
+
@main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
|
9
|
+
@subcommands = Vagrant::Registry.new
|
10
|
+
@subcommands.register(:mount) do
|
11
|
+
Mount
|
12
|
+
end
|
13
|
+
@subcommands.register(:unmount) do
|
14
|
+
Unmount
|
15
|
+
end
|
16
|
+
@subcommands.register(:destroy) do
|
17
|
+
Destroy
|
18
|
+
end
|
19
|
+
@subcommands.register(:list) do
|
20
|
+
List
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute
|
25
|
+
if @main_args.include?("-h") || @main_args.include?("--help")
|
26
|
+
# Print the help for all the sparseimage commands.
|
27
|
+
return help
|
28
|
+
end
|
29
|
+
|
30
|
+
# If we reached this far then we must have a subcommand. If not,
|
31
|
+
# then we also just print the help and exit.
|
32
|
+
command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
|
33
|
+
return help if !command_class || !@sub_command
|
34
|
+
@logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
|
35
|
+
# Initialize and execute the command class
|
36
|
+
command_class.new(@sub_args, @env).execute
|
37
|
+
end
|
38
|
+
|
39
|
+
# Prints the help out for this command
|
40
|
+
def help
|
41
|
+
opts = OptionParser.new do |opts|
|
42
|
+
opts.banner = "Usage: vagrant sparseimage <command>"
|
43
|
+
opts.separator ""
|
44
|
+
opts.separator "Available subcommands:"
|
45
|
+
|
46
|
+
# Add the available subcommands as separators in order to print them
|
47
|
+
# out as well.
|
48
|
+
keys = []
|
49
|
+
@subcommands.each { |key, value| keys << key.to_s }
|
50
|
+
|
51
|
+
keys.sort.each do |key|
|
52
|
+
opts.separator " #{key}"
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.separator ""
|
56
|
+
opts.separator "For help on any individual command run `vagrant sparseimage COMMAND -h`"
|
57
|
+
end
|
58
|
+
@env.ui.info(opts.help, :prefix => false)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class List < Vagrant.plugin("2", :command)
|
63
|
+
def execute
|
64
|
+
@env.machine_names.each do |mname|
|
65
|
+
machine = @env.machine(mname, :virtualbox)
|
66
|
+
machine.ui.info("Listing sparse images for machine #{mname}")
|
67
|
+
SparseImage::list(machine)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
def help
|
71
|
+
@env.ui.info("Usage: vagrant sparseimage mount")
|
72
|
+
@env.ui.info("\tMount all configured sparse images")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
class Mount < Vagrant.plugin("2", :command)
|
79
|
+
def execute
|
80
|
+
@env.machine_names.each do |mname|
|
81
|
+
machine = @env.machine(mname, :virtualbox)
|
82
|
+
machine.ui.info("Mounting sparse images for machine #{mname}")
|
83
|
+
SparseImage::mount(machine)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
def help
|
87
|
+
@env.ui.info("Usage: vagrant sparseimage mount")
|
88
|
+
@env.ui.info("\tMount all configured sparse images")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Unmount < Vagrant.plugin("2", :command)
|
93
|
+
def execute
|
94
|
+
@env.machine_names.each do |mname|
|
95
|
+
machine = @env.machine(mname, :virtualbox)
|
96
|
+
machine.ui.info("Unmounting sparse images for machine #{mname}")
|
97
|
+
SparseImage::unmount(machine)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
def help
|
101
|
+
@env.ui.info("Usage: vagrant sparseimage unmount")
|
102
|
+
@env.ui.info("\tUnmount all configured sparse images")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class Destroy < Vagrant.plugin("2", :command)
|
107
|
+
def execute
|
108
|
+
@env.machine_names.each do |mname|
|
109
|
+
machine = @env.machine(mname, :virtualbox)
|
110
|
+
machine.ui.info("Destroying sparse images for machine #{mname}")
|
111
|
+
SparseImage::destroy(machine)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
def help
|
115
|
+
@env.ui.info("Usage: vagrant sparseimage destroy")
|
116
|
+
@env.ui.info("\tDestroy all configured sparse images")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module SparseImage
|
2
|
+
module HDIUTIL
|
3
|
+
class << self
|
4
|
+
# Try to mount the image. If it fails, return a warning (as a string)
|
5
|
+
def mount(vm, mount_in, image_path)
|
6
|
+
if not SparseImage::run("hdiutil attach -mountpoint '#{mount_in}' '#{image_path}'").success?
|
7
|
+
vm.ui.error("WARNING: Failed to mount #{image_path} at #{mount_in}")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Unmount the image
|
12
|
+
def unmount(vm, mounted_in)
|
13
|
+
vm.ui.info("Unmounting disk image from host: #{mounted_in}")
|
14
|
+
if not SparseImage::run("hdiutil detach -quiet '#{mounted_in}'").success?
|
15
|
+
vm.ui.error("WARNING: Failed to unmount #{mounted_in}. It may not have been mounted.")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Delete the image
|
20
|
+
def destroy(vm, image_filename)
|
21
|
+
vm.ui.info("Destroying disk image at #{image_filename}")
|
22
|
+
if File.exists?(image_filename)
|
23
|
+
if File.directory?(image_filename)
|
24
|
+
FileUtils.rm_rf(image_filename)
|
25
|
+
else
|
26
|
+
File.delete(image_filename)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create a sparseimage
|
32
|
+
def create(vm, type, image_size, image_fs, volume_name, full_image_filename)
|
33
|
+
if not SparseImage::run("hdiutil create -type '#{type}' " +
|
34
|
+
"-size '#{image_size}m' " +
|
35
|
+
"-fs '#{image_fs}' " +
|
36
|
+
"-volname '#{volume_name}' " +
|
37
|
+
"'#{full_image_filename}'")
|
38
|
+
vm.ui.error("ERROR: Failed to create sparseimage #{full_image_filename}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Remove all the nonsense that comes with a mounted sparse image in OSX
|
43
|
+
def remove_OSX_fuzz(vm, mounted_dir)
|
44
|
+
# Append trailing slash if it's missing from the mounted dir
|
45
|
+
mounted_dir = "#{mounted_dir}/" unless mounted_dir[-1] == '/'
|
46
|
+
errors = []
|
47
|
+
['.fseventsd', '.Spotlight-V*', '.Trashes'].each do |rubbish|
|
48
|
+
path = "#{mounted_dir}#{rubbish}"
|
49
|
+
if File.exists?(path)
|
50
|
+
p = SparseImage::run("rm -rf #{path}")
|
51
|
+
vm.ui.info("Removing #{path}")
|
52
|
+
if not p.success?
|
53
|
+
vm.ui.error("Failed to remove #{rubbish} from #{mounted_dir}. It may not have existed.")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return errors
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
require 'version.rb'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'vagrant-sparseimage'
|
6
|
+
s.version = SparseImage::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Alan Garfield', 'Daniel Bryan']
|
9
|
+
s.license = 'MIT'
|
10
|
+
s.email = ['alan.garfield@learnosity.com', 'danbryan@gmail.com']
|
11
|
+
s.homepage = 'https://github.com/Learnosity/vagrant-sparseimage'
|
12
|
+
s.summary = %q{A vagrant plugin to create a mount sparse images into the guest VM.}
|
13
|
+
s.description = %q{A vagrant plugin to create a mount sparse images into the guest VM.}
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
|
17
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
18
|
+
|
19
|
+
if s.respond_to? :specification_version
|
20
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
21
|
+
s.specification_version = 2
|
22
|
+
end
|
23
|
+
|
24
|
+
s.add_development_dependency 'bundler', '>= 1.2.0'
|
25
|
+
s.add_development_dependency 'vagrant', '>= 1.2'
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-sparseimage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alan Garfield
|
8
|
+
- Daniel Bryan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-07-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.2.0
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 1.2.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: vagrant
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.2'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.2'
|
42
|
+
description: A vagrant plugin to create a mount sparse images into the guest VM.
|
43
|
+
email:
|
44
|
+
- alan.garfield@learnosity.com
|
45
|
+
- danbryan@gmail.com
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- ".gitignore"
|
51
|
+
- Gemfile
|
52
|
+
- LICENSE
|
53
|
+
- Rakefile
|
54
|
+
- Readme.md
|
55
|
+
- example_box/Vagrantfile
|
56
|
+
- lib/vagrant-sparseimage.rb
|
57
|
+
- lib/vagrant-sparseimage/command.rb
|
58
|
+
- lib/vagrant-sparseimage/hdiutil.rb
|
59
|
+
- lib/version.rb
|
60
|
+
- vagrant-sparseimage.gemspec
|
61
|
+
homepage: https://github.com/Learnosity/vagrant-sparseimage
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.2.2
|
82
|
+
signing_key:
|
83
|
+
specification_version: 2
|
84
|
+
summary: A vagrant plugin to create a mount sparse images into the guest VM.
|
85
|
+
test_files: []
|