vagrant-mount 0.0.1

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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rbenv-gemsets +1 -0
  4. data/.rspec +1 -0
  5. data/Gemfile +72 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +2 -0
  8. data/Rakefile +31 -0
  9. data/lib/vagrant-mount/actions/providers/virtualbox/action/message_not_mounted.rb +16 -0
  10. data/lib/vagrant-mount/actions/providers/virtualbox/action/message_not_unmounted.rb +16 -0
  11. data/lib/vagrant-mount/actions/providers/virtualbox/action/mount.rb +19 -0
  12. data/lib/vagrant-mount/actions/providers/virtualbox/action/unmount.rb +28 -0
  13. data/lib/vagrant-mount/actions/providers/virtualbox/action.rb +48 -0
  14. data/lib/vagrant-mount/actions/providers/virtualbox/driver/base.rb +155 -0
  15. data/lib/vagrant-mount/actions/providers/virtualbox/driver/meta.rb +9 -0
  16. data/lib/vagrant-mount/actions/providers/virtualbox/driver.rb +2 -0
  17. data/lib/vagrant-mount/actions/providers/vmware-fusion/action/message_not_mounted.rb +16 -0
  18. data/lib/vagrant-mount/actions/providers/vmware-fusion/action/message_not_unmounted.rb +16 -0
  19. data/lib/vagrant-mount/actions/providers/vmware-fusion/action/mount.rb +19 -0
  20. data/lib/vagrant-mount/actions/providers/vmware-fusion/action/unmount.rb +27 -0
  21. data/lib/vagrant-mount/actions/providers/vmware-fusion/action.rb +47 -0
  22. data/lib/vagrant-mount/actions/providers/vmware-fusion/driver/base.rb +84 -0
  23. data/lib/vagrant-mount/actions/providers/vmware-fusion/driver.rb +1 -0
  24. data/lib/vagrant-mount/commands/mount.rb +39 -0
  25. data/lib/vagrant-mount/commands/unmount.rb +39 -0
  26. data/lib/vagrant-mount/plugin.rb +78 -0
  27. data/lib/vagrant-mount/version.rb +5 -0
  28. data/lib/vagrant-mount.rb +18 -0
  29. data/locales/en.yml +26 -0
  30. data/spec/Vagrantfile +27 -0
  31. data/spec/command_spec.rb +28 -0
  32. data/spec/dummy.iso +0 -0
  33. data/spec/helpers/isolated_environment.rb +52 -0
  34. data/vagrant-mount.gemspec +28 -0
  35. metadata +138 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 656e36f4eda550bc886cd4ffc1491e7b014e47dc
4
+ data.tar.gz: 47c9ebc0ae2a0060aea61a82abddd39b1c55afea
5
+ SHA512:
6
+ metadata.gz: e1995672d620827690a0f8b917c70f5d311820ab9e71d676fba566ffece9d2b3df2c1d2876bb52ed43f77fcfd6f7e43852f97b73c40efa13811dc20741e5593f
7
+ data.tar.gz: a45c015231cff289e972136212c6fffe1384ebae4c93ac61a03736ef6b3abb7e1a7e50609276a3ad2eb459b52b0fba142c48de4a836210ba4aaab25cbb3461af
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ .bundle/
2
+ .yardoc
3
+ Gemfile.lock
4
+ _yardoc/
5
+ coverage/
6
+ doc/
7
+ pkg/
8
+ spec/reports/
9
+ tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .vagrant/
16
+ .gems/
17
+ log/
data/.rbenv-gemsets ADDED
@@ -0,0 +1 @@
1
+ .gems
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation
data/Gemfile ADDED
@@ -0,0 +1,72 @@
1
+ source 'http://rubygems.org'
2
+
3
+ def which(command, *additional_paths)
4
+ extensions = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
5
+ ENV['PATH'].split(File::PATH_SEPARATOR).push(*additional_paths).each do |path|
6
+ extensions.each do |extension|
7
+ filepath = File.join(path, "#{command}#{extension}")
8
+ return filepath if File.executable?(filepath) && !File.directory?(filepath)
9
+ end
10
+ end
11
+ return nil
12
+ end
13
+
14
+ def has_vmware_fusion?
15
+ return ! which('vmrun', '/Applications/VMware Fusion.app/Contents/Library').nil?
16
+ end
17
+
18
+ vagrant_locations = %w{ /Applications/Vagrant/embedded /opt/vagrant/embedded C:/HashiCorp/Vagrant/embedded }
19
+ vagrant_location = vagrant_locations.find {|location| File.directory? location }
20
+
21
+ if vagrant_location
22
+ ENV['VAGRANT_INSTALLER_EMBEDDED_DIR'] = vagrant_location
23
+ puts "Using vagrant from #{vagrant_location}" if $DEBUG
24
+ else
25
+ STDERR.puts 'Could not find an official install of vagrant! The RubyEncoder libraries will not work.'
26
+ exit 1
27
+ end
28
+
29
+ puts "We can use VMWare Fusion" if has_vmware_fusion? && $DEBUG
30
+
31
+ group :development do
32
+ gem 'winrm', '~> 1.1.3'
33
+ gem 'vagrant', github: 'mitchellh/vagrant', tag: 'v1.7.2'
34
+ gem 'rake'
35
+
36
+ if has_vmware_fusion?
37
+ require 'fileutils'
38
+
39
+ begin
40
+ STDERR.puts "Loading gem vagrant-vmware-fusion" if $DEBUG
41
+ gem 'vagrant-vmware-fusion', source: 'http://gems.hashicorp.com'
42
+ STDERR.puts "Finding where gem vagrant-vmware-fusion is installed" if $DEBUG
43
+ fusion_location = Gem::Specification.find_by_name('vagrant-vmware-fusion').gem_dir
44
+ puts "VMWare fusion gem is in #{fusion_location}" if $DEBUG
45
+
46
+ gem 'rgloader'
47
+ unless Dir.exists? File.join(fusion_location, 'rgloader')
48
+ STDERR.puts "Linking local 'rgloader' file to embedded installer" if $DEBUG
49
+ FileUtils.ln_s(
50
+ File.join(ENV['VAGRANT_INSTALLER_EMBEDDED_DIR'], 'rgloader'),
51
+ File.join(fusion_location, 'rgloader')
52
+ )
53
+ end
54
+
55
+ unless File.symlink?(File.join(fusion_location, 'license-vagrant-vmware-fusion.lic'))
56
+ STDERR.puts "Linking your license file for vmware plugin" if $DEBUG
57
+ vagrant_home = ENV["VAGRANT_HOME"] || File.join(ENV['HOME'], '.vagrant.d')
58
+ FileUtils.ln_s(
59
+ File.join(vagrant_home, 'license-vagrant-vmware-fusion.lic'),
60
+ File.join(fusion_location, 'license-vagrant-vmware-fusion.lic')
61
+ )
62
+ end
63
+ rescue Gem::LoadError
64
+ STDERR.puts "Cannot load Vagrant VMWare plugin. #{$!}"
65
+ end
66
+ end
67
+ end
68
+
69
+ group :plugins do
70
+ gem 'vagrant-vmware-fusion', source: 'http://gems.hashicorp.com' if has_vmware_fusion?
71
+ gemspec
72
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Gildas Cherruel
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # vagrant-mount
2
+ Mounts ISO files in Virtual Machines for Vagrant
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'bundler/gem_tasks'
4
+ require 'yard'
5
+ require 'rspec/core/rake_task'
6
+
7
+ $stdout.sync = true
8
+ $stderr.sync = true
9
+
10
+ # Change to the directory of this file
11
+ Dir.chdir(File.expand_path("../", __FILE__))
12
+
13
+ # Tasks to help with gem creation and publishing
14
+ Bundler::GemHelper.install_tasks
15
+
16
+ # Test tasks with RSpec
17
+ RSpec::Core::RakeTask.new
18
+
19
+ # Documentation tasks
20
+ YARD::Rake::YardocTask.new do |t|
21
+ t.files = ['lib/**/*.rb']
22
+ end
23
+
24
+ # Build the ctags fo vim
25
+ desc "Builds the tags"
26
+ task :ctags do
27
+ %x[ git ls-files | ctags --tag-relative --sort=no --exclude=.idea -L - -f ".git/tags" ]
28
+ end
29
+
30
+ # By default we test the gem
31
+ task :default => 'spec'
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Action
4
+ class MessageNotMounted
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t('vagrant_mount.errors.vm.mount.not_mounted', mount: env[:mount_point]))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Action
4
+ class MessageNotUnmounted
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t('vagrant_mount.errors.vm.unmount.not_unmounted', mount: env[:mount_point]))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Action
4
+ class Mount
5
+ def initialize(app, env)
6
+ @app = app
7
+ @env = env
8
+ end
9
+
10
+ def call(env)
11
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.mount.mounting', mount: env[:mount_point]))
12
+ env[:result] = env[:machine].provider.driver.mount(env[:mount_point])
13
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.mount.mounted', mount: env[:mount_point]))
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+
2
+ module VagrantPlugins
3
+ module ProviderVirtualBox
4
+ module Action
5
+ class Unmount
6
+ def initialize(app, env)
7
+ @app = app
8
+ @env = env
9
+ end
10
+
11
+ def call(env)
12
+ if env[:mount_point]
13
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounting', mount: env[:mount_point]))
14
+ else
15
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounting_all'))
16
+ end
17
+ env[:result] = env[:machine].provider.driver.unmount(env[:mount_point], env[:remove_device])
18
+ if env[:mount_point]
19
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounted', mount: env[:mount_point]))
20
+ else
21
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounted_all'))
22
+ end
23
+ @app.call(env)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ require 'vagrant'
2
+ require 'vagrant/action/builder'
3
+
4
+ module VagrantPlugins
5
+ module ProviderVirtualBox
6
+ module Action
7
+ autoload :Mount, File.expand_path("../action/mount.rb", __FILE__)
8
+ autoload :Unmount, File.expand_path("../action/unmount.rb", __FILE__)
9
+ autoload :MessageNotMounted, File.expand_path("../action/message_not_mounted.rb", __FILE__)
10
+
11
+ def self.action_mount
12
+ Vagrant::Action::Builder.new.tap do |builder|
13
+ builder.use CheckVirtualbox
14
+ builder.use Call, Created do |created_env, created_builder|
15
+ if created_env[:result]
16
+ created_builder.use CheckAccessible
17
+ created_builder.use Call, Mount do |mount_env, mount_builder|
18
+ unless mount_env[:result]
19
+ mount_builder.use MessageNotMounted
20
+ end
21
+ end
22
+ else
23
+ created_builder.use MessageNotCreated
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.action_unmount
30
+ Vagrant::Action::Builder.new.tap do |builder|
31
+ builder.use CheckVirtualbox
32
+ builder.use Call, Created do |created_env, created_builder|
33
+ if created_env[:result]
34
+ created_builder.use CheckAccessible
35
+ created_builder.use Call, Unmount do |unmount_env, unmount_builder|
36
+ unless unmount_env[:result]
37
+ unmount_builder.use MessageNotUnmounted
38
+ end
39
+ end
40
+ else
41
+ created_builder.use MessageNotCreated
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,155 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Driver
4
+ class Base
5
+ def mount(mount_point)
6
+ # Find an IDE or SCSI controller
7
+ @logger.debug "Mounting #{mount_point}"
8
+ info = get_vm_info(@uuid)
9
+ begin
10
+ controller_name, device_id, port_id = find_iso(info, mount_point)
11
+ @logger.debug "Already mounted on #{controller_name}, device: #{device_id}, port: #{port_id}"
12
+ return 1
13
+ rescue KeyError
14
+ @logger.debug "Not mounted yet, we are good to go"
15
+ end
16
+ ide_types = ['PIIX3', 'PIIX4', 'ICH6']
17
+ controller_name, device_id, port_id = find_free_port(info, ide_types)
18
+ execute('storageattach', @uuid,
19
+ '--storagectl', controller_name,
20
+ '--device', device_id.to_s,
21
+ '--port', port_id.to_s,
22
+ '--type', 'dvddrive',
23
+ '--medium', mount_point
24
+ )
25
+ end
26
+
27
+ def unmount(mount_point, remove_device=false)
28
+ # Find an IDE or SCSI controller
29
+ @logger.debug "Mounting #{mount_point}"
30
+ info = get_vm_info(@uuid)
31
+ begin
32
+ if mount_point
33
+ controller_name, device_id, port_id = find_iso(info, mount_point)
34
+ else
35
+ controller_name, device_id, port_id = find_first_iso(info)
36
+ end
37
+ @logger.debug "Mounted on #{controller_name}, device: #{device_id}, port: #{port_id}"
38
+ if remove_device
39
+ execute('storageattach', @uuid,
40
+ '--storagectl', controller_name,
41
+ '--device', device_id.to_s,
42
+ '--port', port_id.to_s,
43
+ '--medium', 'none'
44
+ )
45
+ else
46
+ execute('storageattach', @uuid,
47
+ '--storagectl', controller_name,
48
+ '--device', device_id.to_s,
49
+ '--port', port_id.to_s,
50
+ '--type', 'dvddrive',
51
+ '--medium', 'emptydrive'
52
+ )
53
+ end
54
+ rescue KeyError
55
+ @logger.debug "Not mounted, we cannot proceed"
56
+ return 0
57
+ end
58
+ end
59
+
60
+ def find_iso(vm_info, mount_point)
61
+ device_id = port_id = nil
62
+ controller = vm_info[:storagecontrollers].find do |ctrl|
63
+ device_id = ctrl[:devices].find_index do |device|
64
+ port_id = device[:ports].find_index do |port|
65
+ port[:mount].include? mount_point if port
66
+ end
67
+ end
68
+ end
69
+ raise KeyError unless controller
70
+ @logger.debug "Found ISO on Storage: #{controller[:name]}, device ##{device_id}, port ##{port_id}"
71
+ return [controller[:name], device_id, port_id]
72
+ end
73
+
74
+ def find_first_iso(vm_info)
75
+ device_id = port_id = nil
76
+ controller = vm_info[:storagecontrollers].find do |ctrl|
77
+ device_id = ctrl[:devices].find_index do |device|
78
+ port_id = device[:ports].find_index do |port|
79
+ port[:mount] =~ /\.iso$/i if port
80
+ end
81
+ end
82
+ end
83
+ raise KeyError unless controller
84
+ @logger.debug "Found ISO on Storage: #{controller[:name]}, device ##{device_id}, port ##{port_id}"
85
+ return [controller[:name], device_id, port_id]
86
+ end
87
+
88
+ def find_free_port(vm_info, controller_types)
89
+ device_id = port_id = nil
90
+ controller = vm_info[:storagecontrollers].find do |ctrl|
91
+ device_id = ctrl[:devices].find_index do |device|
92
+ port_id = device[:ports].find_index do |port|
93
+ port.nil? || port[:mount] == 'emptydrive'
94
+ end
95
+ end
96
+ end
97
+ raise KeyError, "No suitable Controller on VM #{@uuid}" unless controller
98
+ @logger.debug "Found a suitable Storage: #{controller[:name]}, device ##{device_id}, port ##{port_id}"
99
+ return [controller[:name], device_id, port_id]
100
+ end
101
+
102
+ def get_vm_info(name_or_uuid)
103
+ @logger.debug "Fetching info for VM #{name_or_uuid}"
104
+ output = execute('showvminfo', name_or_uuid, '--machinereadable', retryable: true)
105
+ nic_index = nil
106
+ output.split("\n").inject({storagecontrollers: [], nics: [], lpts: [], uarts: []}) do |hash, line|
107
+ if line =~ /^"?([^="]+)"?="?(|[^"]+)"?$/
108
+ key = $1
109
+ value = $2.to_s
110
+ case key
111
+ when /^storagecontroller([a-z]+)(\d+)$/
112
+ key = $1.tr('- ', '__').to_sym
113
+ controller = hash[:storagecontrollers][$2.to_i]
114
+ if controller
115
+ controller[key] = value
116
+ if key == :portcount
117
+ controller[:devices] = value.to_i.times.inject([]) {|array| array << { ports: [nil, nil] } }
118
+ end
119
+ else
120
+ hash[:storagecontrollers] << { key => value }
121
+ end
122
+ when /^([a-zA-Z ]+)(?:-([a-zA-Z]+))?-(\d+)-(\d+)$/
123
+ unless value == 'none'
124
+ key = ($2 || 'mount').tr('- ', '__').to_sym
125
+ controller = hash[:storagecontrollers].find { |s| s[:name] == $1 }
126
+ raise KeyError, $1 unless controller
127
+ device = controller[:devices][$4.to_i]
128
+ raise IndexError, $4.to_i unless device
129
+ raise IndexError, $3.to_i unless $3.to_i < 2
130
+ device[:ports][$3.to_i] ||= {}
131
+ device[:ports][$3.to_i][key] = value
132
+ end
133
+ when /^natnet(\d+)$/
134
+ nic_index = $1.to_i - 1
135
+ hash[:nics][nic_index] ||= { forwardings: [] }
136
+ hash[:nics][nic_index][:natnet] = value
137
+ when /^(cableconnected|macaddress|nic|nictype|nicspeed)(\d+)$/
138
+ hash[:nics][$2.to_i - 1][$1.to_sym] = value unless value == 'none'
139
+ when /^(mtu|sockSnd|sockRcv|tcpWndSnd|tcpWndRcv)$/
140
+ hash[:nics][nic_index][$1.to_sym] = value
141
+ when /^Forwarding\((\d+)\)$/
142
+ hash[:nics][nic_index][:forwardings][$1.to_i] = value
143
+ when /^(lpt|uart)(\d+)$/
144
+ hash[($1 << 's').to_sym][$2.to_i - 1] = value
145
+ else
146
+ hash[key.tr('- ','__').to_sym] = value
147
+ end
148
+ end
149
+ hash
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,9 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Driver
4
+ class Meta
5
+ def_delegators :@driver, :mount, :unmount
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'driver/base'
2
+ require_relative 'driver/meta'
@@ -0,0 +1,16 @@
1
+ module HashiCorp
2
+ module VagrantVMwarefusion
3
+ module Action
4
+ class MessageNotMounted
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t('vagrant_mount.errors.vm.mount.not_mounted', mount: env[:mount_point]))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module HashiCorp
2
+ module VagrantVMwarefusion
3
+ module Action
4
+ class MessageNotUnmounted
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t('vagrant_mount.errors.vm.unmount.not_unmounted', mount: env[:mount_point]))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module HashiCorp
2
+ module VagrantVMwarefusion
3
+ module Action
4
+ class Mount
5
+ def initialize(app, env)
6
+ @app = app
7
+ @env = env
8
+ end
9
+
10
+ def call(env)
11
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.mount.mounting', mount: env[:mount_point]))
12
+ env[:result] = env[:machine].provider.driver.mount(env[:mount_point])
13
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.mount.mounted', mount: env[:mount_point]))
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ module HashiCorp
2
+ module VagrantVMwarefusion
3
+ module Action
4
+ class Unmount
5
+ def initialize(app, env)
6
+ @app = app
7
+ @env = env
8
+ end
9
+
10
+ def call(env)
11
+ if env[:mount_point]
12
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounting', mount: env[:mount_point]))
13
+ else
14
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounting_all'))
15
+ end
16
+ env[:result] = env[:machine].provider.driver.unmount(env[:mount_point], env[:remove_device])
17
+ if env[:mount_point]
18
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounted', mount: env[:mount_point]))
19
+ else
20
+ env[:ui].info(I18n.t('vagrant_mount.actions.vm.unmount.unmounted_all'))
21
+ end
22
+ @app.call(env)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ require 'vagrant'
2
+ require 'vagrant/action/builder'
3
+
4
+ module HashiCorp
5
+ module VagrantVMwarefusion
6
+ module Action
7
+ autoload :Mount, File.expand_path("../action/mount.rb", __FILE__)
8
+ autoload :Unmount, File.expand_path("../action/unmount.rb", __FILE__)
9
+ autoload :MessageNotMounted, File.expand_path("../action/message_not_mounted.rb", __FILE__)
10
+ autoload :MessageNotUnmounted, File.expand_path("../action/message_not_unmounted.rb", __FILE__)
11
+
12
+ def self.action_mount
13
+ Vagrant::Action::Builder.new.tap do |builder|
14
+ builder.use CheckVMware
15
+ builder.use Call, Created do |created_env, created_builder|
16
+ if created_env[:result]
17
+ created_builder.use Call, Mount do |mount_env, mount_builder|
18
+ unless mount_env[:result]
19
+ mount_builder.use MessageNotMounted
20
+ end
21
+ end
22
+ else
23
+ created_builder.use MessageNotCreated
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.action_unmount
30
+ Vagrant::Action::Builder.new.tap do |builder|
31
+ builder.use CheckVMware
32
+ builder.use Call, Created do |created_env, created_builder|
33
+ if created_env[:result]
34
+ created_builder.use Call, Unmount do |unmount_env, unmount_builder|
35
+ unless unmount_env[:result]
36
+ unmount_builder.use MessageNotUnmounted
37
+ end
38
+ end
39
+ else
40
+ created_builder.use MessageNotCreated
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,84 @@
1
+ require 'pathname'
2
+
3
+ module HashiCorp
4
+ module VagrantVMwarefusion
5
+ module Driver
6
+ class Base
7
+ def mount(mount_point)
8
+ @logger.info "Mounting #{mount_point}"
9
+ info = vminfo(vmx_path)
10
+ begin
11
+ controller_name = find_iso(info, mount_point)
12
+ @logger.debug "Already mounted on #{controller_name}"
13
+ return 1
14
+ rescue KeyError
15
+ @logger.debug "Not mounted, we are good to go"
16
+ end
17
+ begin
18
+ controller_name = find_free_port(info)
19
+ @logger.info "Mounting on: #{controller_name}"
20
+ info["#{controller_name}.devicetype"] = "cdrom-image"
21
+ info["#{controller_name}.filename"] = Pathname.new(mount_point).realpath.to_s
22
+ info["#{controller_name}.present"] = "TRUE"
23
+ info["#{controller_name}.autodetect"] = "TRUE"
24
+ info["#{controller_name}.startconnected"] = "TRUE"
25
+ vmsave(vmx_path, info)
26
+ return 1
27
+ rescue KeyError
28
+ @logger.error "Could not find any free port"
29
+ return 0
30
+ end
31
+ end
32
+
33
+ def unmount(mount_point, remove_device=false)
34
+ @logger.info "Unmounting #{mount_point}"
35
+ info = vminfo(vmx_path)
36
+ begin
37
+ controller_name = find_iso(info, mount_point)
38
+ @logger.info "Mounted on #{controller_name}"
39
+ info["#{controller_name}.devicetype"] = "cdrom-raw"
40
+ info["#{controller_name}.filename"] = "auto detect"
41
+ info["#{controller_name}.present"] = "TRUE"
42
+ info["#{controller_name}.autodetect"] = "TRUE"
43
+ info["#{controller_name}.startconnected"] = "FALSE"
44
+ vmsave(vmx_path, info)
45
+ return 1
46
+ rescue KeyError
47
+ @logger.debug "Not mounted, nothing to do"
48
+ return 0
49
+ end
50
+ end
51
+
52
+ def vminfo(path)
53
+ return Hash[*File.readlines(path).map {|line| line.scan(/^(.+?) = "(.*?)"$/m)}.flatten]
54
+ end
55
+
56
+ def vmsave(path, vm_info)
57
+ temp_path="#{path}.new"
58
+ @logger.debug "Saving in: #{temp_path}"
59
+ File.open("#{temp_path}", "w") { |f| vm_info.each{|k,v| f.puts "#{k} = \"#{v}\""}}
60
+ FileUtils.mv temp_path, path, force: true
61
+ end
62
+
63
+ def find_iso(vm_info, mount_point)
64
+ data = vm_info.find {|k, v| v =~ /.*\/#{mount_point}/ }
65
+ raise KeyError unless data
66
+ @logger.debug "Found data: #{data.inspect}"
67
+ data[0] =~ /([a-z]+)(\d+):(\d+)\.filename/
68
+ raise KeyError unless data[0] =~ /([a-z]+)(\d+):(\d+)\.filename/
69
+ @logger.debug "type: #{$1}, device: #{$2}, port: #{$3}"
70
+ "#{$1}#{$2}:#{$3}"
71
+ end
72
+
73
+ def find_free_port(vm_info)
74
+ data = vm_info.find {|k, v| v == 'cdrom-raw' }
75
+ raise KeyError unless data
76
+ @logger.debug "Found data: #{data.inspect}"
77
+ raise KeyError unless data[0] =~ /([a-z]+)(\d+):(\d+)\.devicetype/
78
+ @logger.debug "type: #{$1}, device: #{$2}, port: #{$3}"
79
+ "#{$1}#{$2}:#{$3}"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1 @@
1
+ require_relative 'driver/base'
@@ -0,0 +1,39 @@
1
+ require 'optparse'
2
+ require 'vagrant'
3
+
4
+ module VagrantPlugins
5
+ module Mount
6
+ module Command
7
+ class Mount < Vagrant.plugin('2', :command)
8
+ def self.synopsis
9
+ 'Mount ISO in Virtual Machine'
10
+ end
11
+
12
+ def initialize(argv, env)
13
+ @env=env
14
+ super
15
+ end
16
+
17
+ def execute
18
+ options = {}
19
+ parser = OptionParser.new do |opts|
20
+ opts.banner = 'Usage: vagrant mount [options] [vm-name]'
21
+ opts.separator ''
22
+ opts.separator ' Options:'
23
+ opts.on("--iso path", "The path of the ISO to mount") { |arg| options[:path] = arg }
24
+ end
25
+
26
+ argv = parse_options(parser)
27
+ return unless argv
28
+ argv << "default" if argv.empty?
29
+
30
+ raise Vagrant::Errors::CLIInvalidUsage, { help: parser.help.chomp } unless options[:path]
31
+ with_target_vms(argv) do |vm|
32
+ vm.action(:mount, mount_point: options[:path])
33
+ end
34
+ 0
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require 'optparse'
2
+ require 'vagrant'
3
+
4
+ module VagrantPlugins
5
+ module Mount
6
+ module Command
7
+ class Unmount < Vagrant.plugin('2', :command)
8
+ def self.synopsis
9
+ 'Unmount ISO from Virtual Machine'
10
+ end
11
+
12
+ def initialize(argv, env)
13
+ @env=env
14
+ super
15
+ end
16
+
17
+ def execute
18
+ options = { remove_device: false }
19
+ parser = OptionParser.new do |opts|
20
+ opts.banner = 'Usage: vagrant unmount [options] [vm-name]'
21
+ opts.separator ''
22
+ opts.separator ' Options:'
23
+ opts.on("--iso path", "The path of the ISO to unmount") { |arg| options[:path] = arg }
24
+ opts.on("--remove-device", "Remove the controller/device/port after unmounting") { |arg| options[:remove_device] = true }
25
+ end
26
+
27
+ argv = parse_options(parser)
28
+ return unless argv
29
+ argv << "default" if argv.empty?
30
+
31
+ with_target_vms(argv) do |vm|
32
+ vm.action(:unmount, mount_point: options[:path], remove_device: options[:remove_device])
33
+ end
34
+ 0
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,78 @@
1
+ begin
2
+ require 'vagrant'
3
+ rescue LoadError
4
+ raise 'The Vagrant Mount plugin must be run within Vagrant.'
5
+ end
6
+
7
+ raise 'The Vagrant Mount plugin is only compatible with Vagrant 1.2+' if Vagrant::VERSION < '1.2.0'
8
+
9
+ module VagrantPlugins
10
+ module Mount
11
+ class Plugin < Vagrant.plugin('2')
12
+ name 'mount'
13
+ description <<-DESC
14
+ This plugin mount ISO files inside Virtual Machines as DVD/CD
15
+ DESC
16
+ # @logger.info "Loading command :mount"
17
+ command(:mount) do
18
+ require_relative 'commands/mount'
19
+ Command::Mount
20
+ end
21
+
22
+ # @logger.info "Loading command :unmount"
23
+ command(:unmount) do
24
+ require_relative 'commands/unmount'
25
+ Command::Unmount
26
+ end
27
+
28
+ # VirtualBox
29
+ begin
30
+ require_relative 'actions/providers/virtualbox/action'
31
+ require_relative 'actions/providers/virtualbox/driver'
32
+ rescue LoadError
33
+ # If plugin cannot be loaded, silently ignore
34
+ end
35
+
36
+ # Hyper-V
37
+ begin
38
+ require_relative 'actions/providers/hyperv/mount'
39
+ require_relative 'actions/providers/hyperv/driver'
40
+ rescue LoadError
41
+ # If plugin cannot be loaded, silently ignore
42
+ end
43
+
44
+ # VMWare Fusion
45
+ begin
46
+ require 'vagrant-vmware-fusion/action'
47
+ require 'vagrant-vmware-fusion/driver'
48
+
49
+ require_relative 'actions/providers/vmware-fusion/action'
50
+ require_relative 'actions/providers/vmware-fusion/driver'
51
+ rescue LoadError
52
+ # If plugin cannot be loaded, silently ignore
53
+ end
54
+
55
+ # VMWare Workstation
56
+ begin
57
+ require 'vagrant-vmware-workstation/action'
58
+ require 'vagrant-vmware-workstation/driver'
59
+
60
+ require_relative 'actions/providers/vmware-workstation/mount'
61
+ require_relative 'actions/providers/vmware-workstation/driver'
62
+ rescue LoadError
63
+ # If plugin cannot be loaded, silently ignore
64
+ end
65
+
66
+ # Parallels Desktop
67
+ begin
68
+ require 'vagrant-parallels/action'
69
+ require 'vagrant-parallels/driver'
70
+
71
+ require_relative 'actions/providers/parallels/mount'
72
+ require_relative 'actions/providers/parallels/driver'
73
+ rescue LoadError
74
+ # If plugin cannot be loaded, silently ignore
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Mount
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ require 'vagrant-mount/version'
2
+ require 'vagrant-mount/plugin'
3
+
4
+ module VagrantPlugins
5
+ module Mount
6
+ lib_path = Pathname.new(File.expand_path('../vagrant-mount', __FILE__))
7
+ autoload :Errors, lib_path.join('errors')
8
+
9
+ def self.source_root
10
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
11
+ end
12
+
13
+ Dir.glob(File.expand_path('locales/*.yml', Mount.source_root)).each do |lang|
14
+ I18n.load_path << File.expand_path(lang)
15
+ end
16
+ I18n.reload!
17
+ end
18
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,26 @@
1
+ en:
2
+ vagrant_mount:
3
+ actions:
4
+ vm:
5
+ mount:
6
+ mounting: |-
7
+ Mounting ISO %{mount}...
8
+ mounted: |-
9
+ Successfully mounted ISO %{mount}
10
+ unmount:
11
+ unmounting: |-
12
+ Unmounting ISO %{mount}...
13
+ unmounting_all: |-
14
+ Unmounting all ISOs...
15
+ unmounted: |-
16
+ Successfully unmounted ISO %{mount}
17
+ unmounted_all: |-
18
+ Successfully unmounted all ISOs
19
+ errors:
20
+ vm:
21
+ mount:
22
+ not_mounted: |-
23
+ Failed to mount %{mount}
24
+ unmount:
25
+ not_unmounted: |-
26
+ Failed to unmount %{mount}
data/spec/Vagrantfile ADDED
@@ -0,0 +1,27 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure(2) do |config|
5
+ config.vm.define :centos, primary: true do |centos|
6
+ centos.vm.box = "box-cutter/centos70"
7
+ end
8
+
9
+ config.vm.define :ubuntu, autostart: false do |ubuntu|
10
+ ubuntu.vm.box = "box-cutter/ubuntu1404"
11
+ end
12
+
13
+ config.vm.define :windows, autostart: false do |windows|
14
+ windows.vm.box = "windows-2012R2-full-standard-eval"
15
+ windows.vm.box_check_update = false
16
+ windows.vm.guest = :windows
17
+ windows.vm.communicator = :winrm
18
+
19
+ windows.vm.provider :virtualbox do |provider, override|
20
+ provider.gui = true
21
+ provider.customize ['modifyvm', :id, '--ioapic', 'on'] # So we can assign multiple CPUs to the VM
22
+ provider.customize ['modifyvm', :id, '--memory', 2048]
23
+ provider.customize ['modifyvm', :id, '--cpus', 2]
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ require 'rspec'
2
+ require 'helpers/isolated_environment'
3
+ require 'vagrant-mount/commands/mount'
4
+
5
+ describe VagrantPlugins::Mount::Command::Mount do
6
+ describe 'help' do
7
+ let (:argv) { [] }
8
+ let (:env) do
9
+ IsolatedEnvironment.new.create_environment
10
+ end
11
+
12
+ subject { described_class.new(argv, env) }
13
+
14
+ context 'with no arguments' do
15
+ it 'shows help' do
16
+ expect { subject.execute }.to raise_error(Vagrant::Errors::CLIInvalidUsage)
17
+ end
18
+ end
19
+
20
+ context 'with an ISO' do
21
+ let(:argv) { [ 'dummy.iso' ] }
22
+
23
+ it 'mounts it' do
24
+ expect(subject.execute).to eq(0)
25
+ end
26
+ end
27
+ end
28
+ end
data/spec/dummy.iso ADDED
Binary file
@@ -0,0 +1,52 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'tmpdir'
4
+ require 'logger'
5
+
6
+ class IsolatedEnvironment
7
+ attr_reader :homedir
8
+ attr_reader :workdir
9
+
10
+ def initialize
11
+ Dir.mkdir 'tmp' unless Dir.exists? 'tmp'
12
+ @logger = Logger.new(File.open('tmp/isolated_environment.log', 'a'))
13
+ @tempdir = Dir.mktmpdir('vagrant')
14
+ @logger.info("Initialized Isolated Environment in #{@tempdir}")
15
+ @homedir = Pathname.new(File.join(@tempdir, 'home'))
16
+ @workdir = Pathname.new(File.join(@tempdir, 'work'))
17
+ @homedir.mkdir
18
+ @workdir.mkdir
19
+ end
20
+
21
+ def create_environment(options=nil)
22
+ Vagrant::Environment.new({cwd: workdir, home_path: homedir}.merge(options || {}))
23
+ end
24
+
25
+ def close
26
+ @logger.info("Removing Isolated Environment from #{@tempdir}")
27
+ FileUtils.rm_rf(@tempdir)
28
+ end
29
+
30
+ def file(name, contents, root=nil)
31
+ (root || @workdir).join(name).open('w+') { |f| f.write(contents) }
32
+ end
33
+
34
+ def vagrantfile(contents, root=nil)
35
+ file('Vagrantfile', contents, root)
36
+ end
37
+
38
+ def box(name, vagrantfile_contents='')
39
+ box_dir=boxes_dir.join(name)
40
+ box_dir.mkpath
41
+
42
+ box_dir.join('box.ovf').open('w') { |f| f.write('') }
43
+ vagrantfile(vagrantfile_contents, box_dir)
44
+ box_dir
45
+ end
46
+
47
+ def boxes_dir
48
+ dir=@homedir.join('boxes')
49
+ dir.mkpath
50
+ dir
51
+ end
52
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-mount/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'vagrant-mount'
8
+ spec.version = VagrantPlugins::Mount::VERSION
9
+ spec.authors = ['Gildas Cherruel']
10
+ spec.email = ['gildas@breizh.org']
11
+ spec.summary = %q{Mounts ISO in Virtual Machines}
12
+ spec.description = %q{Mounts ISO in Virtual Machines via the provider}
13
+ spec.homepage = 'http://www.vagrantup.com'
14
+ spec.license = 'MIT'
15
+
16
+ spec.required_rubygems_version = '>= 1.3.6'
17
+ spec.rubyforge_project = 'vagrant-mount'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.7'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3.1'
27
+ spec.add_development_dependency 'yard'
28
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-mount
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gildas Cherruel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Mounts ISO in Virtual Machines via the provider
70
+ email:
71
+ - gildas@breizh.org
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rbenv-gemsets"
78
+ - ".rspec"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/vagrant-mount.rb
84
+ - lib/vagrant-mount/actions/providers/virtualbox/action.rb
85
+ - lib/vagrant-mount/actions/providers/virtualbox/action/message_not_mounted.rb
86
+ - lib/vagrant-mount/actions/providers/virtualbox/action/message_not_unmounted.rb
87
+ - lib/vagrant-mount/actions/providers/virtualbox/action/mount.rb
88
+ - lib/vagrant-mount/actions/providers/virtualbox/action/unmount.rb
89
+ - lib/vagrant-mount/actions/providers/virtualbox/driver.rb
90
+ - lib/vagrant-mount/actions/providers/virtualbox/driver/base.rb
91
+ - lib/vagrant-mount/actions/providers/virtualbox/driver/meta.rb
92
+ - lib/vagrant-mount/actions/providers/vmware-fusion/action.rb
93
+ - lib/vagrant-mount/actions/providers/vmware-fusion/action/message_not_mounted.rb
94
+ - lib/vagrant-mount/actions/providers/vmware-fusion/action/message_not_unmounted.rb
95
+ - lib/vagrant-mount/actions/providers/vmware-fusion/action/mount.rb
96
+ - lib/vagrant-mount/actions/providers/vmware-fusion/action/unmount.rb
97
+ - lib/vagrant-mount/actions/providers/vmware-fusion/driver.rb
98
+ - lib/vagrant-mount/actions/providers/vmware-fusion/driver/base.rb
99
+ - lib/vagrant-mount/commands/mount.rb
100
+ - lib/vagrant-mount/commands/unmount.rb
101
+ - lib/vagrant-mount/plugin.rb
102
+ - lib/vagrant-mount/version.rb
103
+ - locales/en.yml
104
+ - spec/Vagrantfile
105
+ - spec/command_spec.rb
106
+ - spec/dummy.iso
107
+ - spec/helpers/isolated_environment.rb
108
+ - vagrant-mount.gemspec
109
+ homepage: http://www.vagrantup.com
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 1.3.6
127
+ requirements: []
128
+ rubyforge_project: vagrant-mount
129
+ rubygems_version: 2.2.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Mounts ISO in Virtual Machines
133
+ test_files:
134
+ - spec/Vagrantfile
135
+ - spec/command_spec.rb
136
+ - spec/dummy.iso
137
+ - spec/helpers/isolated_environment.rb
138
+ has_rdoc: