fixed-vagrant 0.7.4.dev
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/.gitignore +15 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +272 -0
- data/Gemfile +21 -0
- data/LICENSE +21 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/bin/vagrant +22 -0
- data/config/default.rb +39 -0
- data/contrib/README.md +12 -0
- data/contrib/emacs/vagrant.el +8 -0
- data/contrib/vim/vagrantfile.vim +9 -0
- data/keys/README.md +17 -0
- data/keys/vagrant +27 -0
- data/keys/vagrant.ppk +26 -0
- data/keys/vagrant.pub +1 -0
- data/lib/vagrant.rb +42 -0
- data/lib/vagrant/action.rb +134 -0
- data/lib/vagrant/action/box.rb +11 -0
- data/lib/vagrant/action/box/destroy.rb +21 -0
- data/lib/vagrant/action/box/download.rb +72 -0
- data/lib/vagrant/action/box/package.rb +19 -0
- data/lib/vagrant/action/box/unpackage.rb +55 -0
- data/lib/vagrant/action/box/verify.rb +23 -0
- data/lib/vagrant/action/builder.rb +124 -0
- data/lib/vagrant/action/builtin.rb +104 -0
- data/lib/vagrant/action/env.rb +7 -0
- data/lib/vagrant/action/env/set.rb +18 -0
- data/lib/vagrant/action/environment.rb +50 -0
- data/lib/vagrant/action/general.rb +8 -0
- data/lib/vagrant/action/general/package.rb +109 -0
- data/lib/vagrant/action/general/validate.rb +19 -0
- data/lib/vagrant/action/vm.rb +31 -0
- data/lib/vagrant/action/vm/boot.rb +48 -0
- data/lib/vagrant/action/vm/check_box.rb +28 -0
- data/lib/vagrant/action/vm/check_guest_additions.rb +30 -0
- data/lib/vagrant/action/vm/clean_machine_folder.rb +43 -0
- data/lib/vagrant/action/vm/clear_forwarded_ports.rb +39 -0
- data/lib/vagrant/action/vm/clear_nfs_exports.rb +20 -0
- data/lib/vagrant/action/vm/clear_shared_folders.rb +32 -0
- data/lib/vagrant/action/vm/customize.rb +21 -0
- data/lib/vagrant/action/vm/destroy.rb +19 -0
- data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +30 -0
- data/lib/vagrant/action/vm/discard_state.rb +22 -0
- data/lib/vagrant/action/vm/export.rb +52 -0
- data/lib/vagrant/action/vm/forward_ports.rb +134 -0
- data/lib/vagrant/action/vm/forward_ports_helpers.rb +28 -0
- data/lib/vagrant/action/vm/halt.rb +29 -0
- data/lib/vagrant/action/vm/host_name.rb +21 -0
- data/lib/vagrant/action/vm/import.rb +35 -0
- data/lib/vagrant/action/vm/match_mac_address.rb +21 -0
- data/lib/vagrant/action/vm/network.rb +139 -0
- data/lib/vagrant/action/vm/nfs.rb +159 -0
- data/lib/vagrant/action/vm/nfs_helpers.rb +11 -0
- data/lib/vagrant/action/vm/package.rb +23 -0
- data/lib/vagrant/action/vm/package_vagrantfile.rb +33 -0
- data/lib/vagrant/action/vm/provision.rb +41 -0
- data/lib/vagrant/action/vm/resume.rb +20 -0
- data/lib/vagrant/action/vm/share_folders.rb +70 -0
- data/lib/vagrant/action/vm/suspend.rb +20 -0
- data/lib/vagrant/action/warden.rb +79 -0
- data/lib/vagrant/box.rb +90 -0
- data/lib/vagrant/box_collection.rb +53 -0
- data/lib/vagrant/cli.rb +55 -0
- data/lib/vagrant/command.rb +25 -0
- data/lib/vagrant/command/base.rb +106 -0
- data/lib/vagrant/command/box.rb +33 -0
- data/lib/vagrant/command/destroy.rb +17 -0
- data/lib/vagrant/command/group_base.rb +107 -0
- data/lib/vagrant/command/halt.rb +18 -0
- data/lib/vagrant/command/helpers.rb +33 -0
- data/lib/vagrant/command/init.rb +14 -0
- data/lib/vagrant/command/named_base.rb +14 -0
- data/lib/vagrant/command/package.rb +41 -0
- data/lib/vagrant/command/provision.rb +17 -0
- data/lib/vagrant/command/reload.rb +17 -0
- data/lib/vagrant/command/resume.rb +17 -0
- data/lib/vagrant/command/ssh.rb +42 -0
- data/lib/vagrant/command/ssh_config.rb +26 -0
- data/lib/vagrant/command/status.rb +22 -0
- data/lib/vagrant/command/suspend.rb +17 -0
- data/lib/vagrant/command/up.rb +19 -0
- data/lib/vagrant/command/upgrade_to_060.rb +45 -0
- data/lib/vagrant/command/version.rb +13 -0
- data/lib/vagrant/config.rb +123 -0
- data/lib/vagrant/config/base.rb +85 -0
- data/lib/vagrant/config/error_recorder.rb +19 -0
- data/lib/vagrant/config/nfs.rb +10 -0
- data/lib/vagrant/config/package.rb +9 -0
- data/lib/vagrant/config/ssh.rb +33 -0
- data/lib/vagrant/config/top.rb +61 -0
- data/lib/vagrant/config/vagrant.rb +16 -0
- data/lib/vagrant/config/vm.rb +137 -0
- data/lib/vagrant/config/vm/provisioner.rb +56 -0
- data/lib/vagrant/config/vm/sub_vm.rb +17 -0
- data/lib/vagrant/data_store.rb +70 -0
- data/lib/vagrant/downloaders.rb +7 -0
- data/lib/vagrant/downloaders/base.rb +23 -0
- data/lib/vagrant/downloaders/file.rb +22 -0
- data/lib/vagrant/downloaders/http.rb +64 -0
- data/lib/vagrant/environment.rb +392 -0
- data/lib/vagrant/errors.rb +332 -0
- data/lib/vagrant/hosts.rb +8 -0
- data/lib/vagrant/hosts/arch.rb +27 -0
- data/lib/vagrant/hosts/base.rb +78 -0
- data/lib/vagrant/hosts/bsd.rb +52 -0
- data/lib/vagrant/hosts/linux.rb +47 -0
- data/lib/vagrant/plugin.rb +57 -0
- data/lib/vagrant/provisioners.rb +9 -0
- data/lib/vagrant/provisioners/base.rb +63 -0
- data/lib/vagrant/provisioners/chef.rb +130 -0
- data/lib/vagrant/provisioners/chef_server.rb +103 -0
- data/lib/vagrant/provisioners/chef_solo.rb +142 -0
- data/lib/vagrant/provisioners/puppet.rb +137 -0
- data/lib/vagrant/provisioners/puppet_server.rb +55 -0
- data/lib/vagrant/provisioners/shell.rb +52 -0
- data/lib/vagrant/ssh.rb +173 -0
- data/lib/vagrant/ssh/session.rb +125 -0
- data/lib/vagrant/systems.rb +11 -0
- data/lib/vagrant/systems/base.rb +87 -0
- data/lib/vagrant/systems/debian.rb +36 -0
- data/lib/vagrant/systems/freebsd.rb +84 -0
- data/lib/vagrant/systems/gentoo.rb +27 -0
- data/lib/vagrant/systems/linux.rb +83 -0
- data/lib/vagrant/systems/linux/config.rb +21 -0
- data/lib/vagrant/systems/linux/error.rb +9 -0
- data/lib/vagrant/systems/redhat.rb +39 -0
- data/lib/vagrant/systems/solaris.rb +62 -0
- data/lib/vagrant/systems/ubuntu.rb +17 -0
- data/lib/vagrant/test_helpers.rb +128 -0
- data/lib/vagrant/ui.rb +69 -0
- data/lib/vagrant/util.rb +13 -0
- data/lib/vagrant/util/busy.rb +59 -0
- data/lib/vagrant/util/hash_with_indifferent_access.rb +63 -0
- data/lib/vagrant/util/plain_logger.rb +25 -0
- data/lib/vagrant/util/platform.rb +65 -0
- data/lib/vagrant/util/resource_logger.rb +63 -0
- data/lib/vagrant/util/retryable.rb +25 -0
- data/lib/vagrant/util/stacked_proc_runner.rb +35 -0
- data/lib/vagrant/util/template_renderer.rb +83 -0
- data/lib/vagrant/version.rb +6 -0
- data/lib/vagrant/vm.rb +177 -0
- data/templates/chef_server_client.erb +18 -0
- data/templates/chef_solo_solo.erb +19 -0
- data/templates/commands/init/Vagrantfile.erb +82 -0
- data/templates/config/validation_failed.erb +7 -0
- data/templates/locales/en.yml +535 -0
- data/templates/network_entry_debian.erb +8 -0
- data/templates/network_entry_gentoo.erb +5 -0
- data/templates/network_entry_redhat.erb +8 -0
- data/templates/nfs/exports.erb +5 -0
- data/templates/nfs/exports_linux.erb +5 -0
- data/templates/package_Vagrantfile.erb +11 -0
- data/templates/ssh_config.erb +9 -0
- data/test/locales/en.yml +8 -0
- data/test/test_helper.rb +26 -0
- data/test/vagrant/action/box/destroy_test.rb +18 -0
- data/test/vagrant/action/box/download_test.rb +125 -0
- data/test/vagrant/action/box/package_test.rb +25 -0
- data/test/vagrant/action/box/unpackage_test.rb +84 -0
- data/test/vagrant/action/box/verify_test.rb +30 -0
- data/test/vagrant/action/builder_test.rb +203 -0
- data/test/vagrant/action/env/set_test.rb +24 -0
- data/test/vagrant/action/environment_test.rb +27 -0
- data/test/vagrant/action/general/package_test.rb +268 -0
- data/test/vagrant/action/general/validate_test.rb +31 -0
- data/test/vagrant/action/vm/boot_test.rb +66 -0
- data/test/vagrant/action/vm/check_box_test.rb +56 -0
- data/test/vagrant/action/vm/check_guest_additions_test.rb +9 -0
- data/test/vagrant/action/vm/clean_machine_folder_test.rb +84 -0
- data/test/vagrant/action/vm/clear_forwarded_ports_test.rb +72 -0
- data/test/vagrant/action/vm/clear_nfs_exports_test.rb +22 -0
- data/test/vagrant/action/vm/clear_shared_folders_test.rb +49 -0
- data/test/vagrant/action/vm/customize_test.rb +30 -0
- data/test/vagrant/action/vm/destroy_test.rb +25 -0
- data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +49 -0
- data/test/vagrant/action/vm/discard_state_test.rb +45 -0
- data/test/vagrant/action/vm/export_test.rb +107 -0
- data/test/vagrant/action/vm/forward_ports_helpers_test.rb +70 -0
- data/test/vagrant/action/vm/forward_ports_test.rb +194 -0
- data/test/vagrant/action/vm/halt_test.rb +79 -0
- data/test/vagrant/action/vm/host_name_test.rb +36 -0
- data/test/vagrant/action/vm/import_test.rb +66 -0
- data/test/vagrant/action/vm/match_mac_address_test.rb +36 -0
- data/test/vagrant/action/vm/network_test.rb +286 -0
- data/test/vagrant/action/vm/nfs_helpers_test.rb +26 -0
- data/test/vagrant/action/vm/nfs_test.rb +260 -0
- data/test/vagrant/action/vm/package_test.rb +25 -0
- data/test/vagrant/action/vm/package_vagrantfile_test.rb +46 -0
- data/test/vagrant/action/vm/provision_test.rb +90 -0
- data/test/vagrant/action/vm/resume_test.rb +35 -0
- data/test/vagrant/action/vm/share_folders_test.rb +139 -0
- data/test/vagrant/action/vm/suspend_test.rb +35 -0
- data/test/vagrant/action/warden_test.rb +119 -0
- data/test/vagrant/action_test.rb +89 -0
- data/test/vagrant/box_collection_test.rb +45 -0
- data/test/vagrant/box_test.rb +74 -0
- data/test/vagrant/cli_test.rb +35 -0
- data/test/vagrant/command/base_test.rb +23 -0
- data/test/vagrant/command/group_base_test.rb +15 -0
- data/test/vagrant/command/helpers_test.rb +88 -0
- data/test/vagrant/command/package_test.rb +27 -0
- data/test/vagrant/config/base_test.rb +52 -0
- data/test/vagrant/config/error_recorder_test.rb +18 -0
- data/test/vagrant/config/ssh_test.rb +12 -0
- data/test/vagrant/config/vagrant_test.rb +35 -0
- data/test/vagrant/config/vm/provisioner_test.rb +92 -0
- data/test/vagrant/config/vm_test.rb +86 -0
- data/test/vagrant/config_test.rb +162 -0
- data/test/vagrant/data_store_test.rb +77 -0
- data/test/vagrant/downloaders/base_test.rb +28 -0
- data/test/vagrant/downloaders/file_test.rb +48 -0
- data/test/vagrant/downloaders/http_test.rb +80 -0
- data/test/vagrant/environment_test.rb +508 -0
- data/test/vagrant/errors_test.rb +42 -0
- data/test/vagrant/hosts/base_test.rb +46 -0
- data/test/vagrant/hosts/bsd_test.rb +53 -0
- data/test/vagrant/hosts/linux_test.rb +54 -0
- data/test/vagrant/plugin_test.rb +9 -0
- data/test/vagrant/provisioners/base_test.rb +63 -0
- data/test/vagrant/provisioners/chef_server_test.rb +188 -0
- data/test/vagrant/provisioners/chef_solo_test.rb +219 -0
- data/test/vagrant/provisioners/chef_test.rb +179 -0
- data/test/vagrant/provisioners/puppet_server_test.rb +68 -0
- data/test/vagrant/provisioners/puppet_test.rb +182 -0
- data/test/vagrant/provisioners/shell_test.rb +68 -0
- data/test/vagrant/ssh/session_test.rb +40 -0
- data/test/vagrant/ssh_test.rb +342 -0
- data/test/vagrant/systems/base_test.rb +18 -0
- data/test/vagrant/systems/linux_test.rb +114 -0
- data/test/vagrant/ui_test.rb +29 -0
- data/test/vagrant/util/busy_test.rb +106 -0
- data/test/vagrant/util/hash_with_indifferent_access_test.rb +39 -0
- data/test/vagrant/util/plain_logger_test.rb +17 -0
- data/test/vagrant/util/platform_test.rb +18 -0
- data/test/vagrant/util/resource_logger_test.rb +78 -0
- data/test/vagrant/util/retryable_test.rb +50 -0
- data/test/vagrant/util/stacked_proc_runner_test.rb +43 -0
- data/test/vagrant/util/template_renderer_test.rb +145 -0
- data/test/vagrant/vm_test.rb +291 -0
- data/vagrant.gemspec +36 -0
- metadata +514 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'forward_ports_helpers')
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
class Action
|
|
5
|
+
module VM
|
|
6
|
+
class ForwardPorts
|
|
7
|
+
include ForwardPortsHelpers
|
|
8
|
+
|
|
9
|
+
def initialize(app,env)
|
|
10
|
+
@app = app
|
|
11
|
+
@env = env
|
|
12
|
+
|
|
13
|
+
threshold_check
|
|
14
|
+
external_collision_check
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#--------------------------------------------------------------
|
|
18
|
+
# Prepare Helpers - These functions are not involved in actually
|
|
19
|
+
# executing the action
|
|
20
|
+
#--------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
# This method checks for any forwarded ports on the host below
|
|
23
|
+
# 1024, which causes the forwarded ports to fail.
|
|
24
|
+
def threshold_check
|
|
25
|
+
@env.env.config.vm.forwarded_ports.each do |name, options|
|
|
26
|
+
raise Errors::ForwardPortBelowThreshold if options[:hostport] <= 1024
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# This method checks for any port collisions with any VMs
|
|
31
|
+
# which are already created (by Vagrant or otherwise).
|
|
32
|
+
# report the collisions detected or will attempt to fix them
|
|
33
|
+
# automatically if the port is configured to do so.
|
|
34
|
+
def external_collision_check
|
|
35
|
+
existing = used_ports
|
|
36
|
+
@env.env.config.vm.forwarded_ports.each do |name, options|
|
|
37
|
+
if existing.include?(options[:hostport].to_i)
|
|
38
|
+
handle_collision(name, options, existing)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Handles any collisions. This method will either attempt to
|
|
44
|
+
# fix the collision automatically or will raise an error if
|
|
45
|
+
# auto fixing is disabled.
|
|
46
|
+
def handle_collision(name, options, existing_ports)
|
|
47
|
+
if !options[:auto]
|
|
48
|
+
# Auto fixing is disabled for this port forward, so we
|
|
49
|
+
# must throw an error so the user can fix it.
|
|
50
|
+
raise Errors::ForwardPortCollision, :name => name,
|
|
51
|
+
:host_port => options[:hostport].to_s,
|
|
52
|
+
:guest_port => options[:guestport].to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Get the auto port range and get rid of the used ports and
|
|
56
|
+
# ports which are being used in other forwards so we're just
|
|
57
|
+
# left with available ports.
|
|
58
|
+
range = @env.env.config.vm.auto_port_range.to_a
|
|
59
|
+
range -= @env.env.config.vm.forwarded_ports.collect { |n, o| o[:hostport].to_i }
|
|
60
|
+
range -= existing_ports
|
|
61
|
+
|
|
62
|
+
if range.empty?
|
|
63
|
+
raise Errors::ForwardPortAutolistEmpty, :vm_name => @env["vm"].name,
|
|
64
|
+
:name => name,
|
|
65
|
+
:host_port => options[:hostport].to_s,
|
|
66
|
+
:guest_port => options[:guestport].to_s
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Set the port up to be the first one and add that port to
|
|
70
|
+
# the used list.
|
|
71
|
+
options[:hostport] = range.shift
|
|
72
|
+
existing_ports << options[:hostport]
|
|
73
|
+
|
|
74
|
+
# Notify the user
|
|
75
|
+
@env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.fixed_collision",
|
|
76
|
+
:name => name,
|
|
77
|
+
:new_port => options[:hostport]))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#--------------------------------------------------------------
|
|
81
|
+
# Execution
|
|
82
|
+
#--------------------------------------------------------------
|
|
83
|
+
def call(env)
|
|
84
|
+
@env = env
|
|
85
|
+
|
|
86
|
+
forward_ports
|
|
87
|
+
|
|
88
|
+
@app.call(env)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def forward_ports
|
|
92
|
+
@env.ui.info I18n.t("vagrant.actions.vm.forward_ports.forwarding")
|
|
93
|
+
|
|
94
|
+
@env.env.config.vm.forwarded_ports.each do |name, options|
|
|
95
|
+
adapter = options[:adapter]
|
|
96
|
+
message_attributes = {
|
|
97
|
+
:name => name,
|
|
98
|
+
:guest_port => options[:guestport],
|
|
99
|
+
:host_port => options[:hostport],
|
|
100
|
+
:adapter => adapter + 1
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Assuming the only reason to establish port forwarding is because the VM is using Virtualbox NAT networking.
|
|
104
|
+
# Host-only or Bridged networking don't require port-forwarding and establishing forwarded ports on these
|
|
105
|
+
# attachment types has uncertain behaviour.
|
|
106
|
+
if @env["vm"].vm.network_adapters[adapter].attachment_type == :nat
|
|
107
|
+
@env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry", message_attributes))
|
|
108
|
+
forward_port(name, options)
|
|
109
|
+
else
|
|
110
|
+
@env.ui.info(I18n.t("vagrant.actions.vm.forward_ports.non_nat", message_attributes))
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
@env["vm"].vm.save
|
|
115
|
+
@env["vm"].reload!
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#--------------------------------------------------------------
|
|
119
|
+
# General Helpers
|
|
120
|
+
#--------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
# Forwards a port.
|
|
123
|
+
def forward_port(name, options)
|
|
124
|
+
port = VirtualBox::NATForwardedPort.new
|
|
125
|
+
port.name = name
|
|
126
|
+
port.guestport = options[:guestport]
|
|
127
|
+
port.hostport = options[:hostport]
|
|
128
|
+
port.protocol = options[:protocol] || :tcp
|
|
129
|
+
@env["vm"].vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class Action
|
|
3
|
+
module VM
|
|
4
|
+
# Helper methods for forwarding ports. Requires that the environment
|
|
5
|
+
# is set to the `@env` instance variable.
|
|
6
|
+
module ForwardPortsHelpers
|
|
7
|
+
# Returns an array of used ports. This method is implemented
|
|
8
|
+
# differently depending on the VirtualBox version, but the
|
|
9
|
+
# behavior is the same.
|
|
10
|
+
#
|
|
11
|
+
# @return [Array<String>]
|
|
12
|
+
def used_ports
|
|
13
|
+
result = VirtualBox::VM.all.collect do |vm|
|
|
14
|
+
if vm.running? && vm.uuid != @env["vm"].uuid
|
|
15
|
+
vm.network_adapters.collect do |na|
|
|
16
|
+
na.nat_driver.forwarded_ports.collect do |fp|
|
|
17
|
+
fp.hostport.to_i
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
result.flatten.uniq
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class Action
|
|
3
|
+
module VM
|
|
4
|
+
class Halt
|
|
5
|
+
def initialize(app, env, options=nil)
|
|
6
|
+
@app = app
|
|
7
|
+
env.merge!(options || {})
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
if env["vm"].created? && env["vm"].vm.running?
|
|
12
|
+
env["vm"].system.halt if !env["force"]
|
|
13
|
+
|
|
14
|
+
if env["vm"].vm.state(true) != :powered_off
|
|
15
|
+
env.ui.info I18n.t("vagrant.actions.vm.halt.force")
|
|
16
|
+
env["vm"].vm.stop
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Sleep for a second to verify that the VM properly
|
|
20
|
+
# cleans itself up
|
|
21
|
+
sleep 1 if !env["vagrant.test"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@app.call(env)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class Action
|
|
3
|
+
module VM
|
|
4
|
+
class HostName
|
|
5
|
+
def initialize(app, env)
|
|
6
|
+
@app = app
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call(env)
|
|
10
|
+
@app.call(env)
|
|
11
|
+
|
|
12
|
+
host_name = env["config"].vm.host_name
|
|
13
|
+
if !host_name.nil?
|
|
14
|
+
env.ui.info I18n.t("vagrant.actions.vm.host_name.setting")
|
|
15
|
+
env["vm"].system.change_host_name(host_name)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class Action
|
|
3
|
+
module VM
|
|
4
|
+
class Import
|
|
5
|
+
def initialize(app, env)
|
|
6
|
+
@app = app
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call(env)
|
|
10
|
+
env.ui.info I18n.t("vagrant.actions.vm.import.importing", :name => env.env.box.name)
|
|
11
|
+
|
|
12
|
+
# Import the virtual machine
|
|
13
|
+
env.env.vm.vm = VirtualBox::VM.import(env.env.box.ovf_file.to_s) do |progress|
|
|
14
|
+
env.ui.report_progress(progress.percent, 100, false)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Flag as erroneous and return if import failed
|
|
18
|
+
raise Errors::VMImportFailure if !env["vm"].vm
|
|
19
|
+
|
|
20
|
+
# Import completed successfully. Continue the chain
|
|
21
|
+
@app.call(env)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def recover(env)
|
|
25
|
+
if env["vm"].created?
|
|
26
|
+
return if env["vagrant.error"].is_a?(Errors::VagrantError)
|
|
27
|
+
|
|
28
|
+
# Interrupted, destroy the VM
|
|
29
|
+
env["actions"].run(:destroy)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class Action
|
|
3
|
+
module VM
|
|
4
|
+
class MatchMACAddress
|
|
5
|
+
def initialize(app, env)
|
|
6
|
+
@app = app
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call(env)
|
|
10
|
+
raise Errors::VMBaseMacNotSpecified if !env.env.config.vm.base_mac
|
|
11
|
+
|
|
12
|
+
env.ui.info I18n.t("vagrant.actions.vm.match_mac.matching")
|
|
13
|
+
env["vm"].vm.network_adapters.first.mac_address = env.env.config.vm.base_mac
|
|
14
|
+
env["vm"].vm.save
|
|
15
|
+
|
|
16
|
+
@app.call(env)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class Action
|
|
3
|
+
module VM
|
|
4
|
+
# Networking middleware for Vagrant. This enables host only
|
|
5
|
+
# networking on VMs if configured as such.
|
|
6
|
+
class Network
|
|
7
|
+
def initialize(app, env)
|
|
8
|
+
@app = app
|
|
9
|
+
@env = env
|
|
10
|
+
|
|
11
|
+
if enable_network? && Util::Platform.windows? && Util::Platform.bit64?
|
|
12
|
+
raise Errors::NetworkNotImplemented
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
env["config"].vm.network_options.compact.each do |network_options|
|
|
16
|
+
raise Errors::NetworkCollision if !verify_no_bridge_collision(network_options)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call(env)
|
|
21
|
+
@env = env
|
|
22
|
+
assign_network if enable_network?
|
|
23
|
+
|
|
24
|
+
@app.call(env)
|
|
25
|
+
|
|
26
|
+
if enable_network?
|
|
27
|
+
@env.ui.info I18n.t("vagrant.actions.vm.network.enabling")
|
|
28
|
+
@env.env.config.vm.network_options.compact.each do |network_options|
|
|
29
|
+
@env["vm"].system.prepare_host_only_network(network_options)
|
|
30
|
+
@env["vm"].system.enable_host_only_network(network_options)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Verifies that there is no collision with a bridged network interface
|
|
36
|
+
# for the given network options.
|
|
37
|
+
def verify_no_bridge_collision(net_options)
|
|
38
|
+
interfaces = VirtualBox::Global.global.host.network_interfaces
|
|
39
|
+
interfaces.each do |ni|
|
|
40
|
+
next if ni.interface_type == :host_only
|
|
41
|
+
|
|
42
|
+
result = if net_options[:name]
|
|
43
|
+
true if net_options[:name] == ni.name
|
|
44
|
+
else
|
|
45
|
+
true if matching_network?(ni, net_options)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
return false if result
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def enable_network?
|
|
55
|
+
!@env.env.config.vm.network_options.compact.empty?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Enables and assigns the host only network to the proper
|
|
59
|
+
# adapter on the VM, and saves the adapter.
|
|
60
|
+
def assign_network
|
|
61
|
+
@env.ui.info I18n.t("vagrant.actions.vm.network.preparing")
|
|
62
|
+
|
|
63
|
+
@env.env.config.vm.network_options.compact.each do |network_options|
|
|
64
|
+
adapter = @env["vm"].vm.network_adapters[network_options[:adapter]]
|
|
65
|
+
adapter.enabled = true
|
|
66
|
+
adapter.attachment_type = :host_only
|
|
67
|
+
adapter.host_interface = network_name(network_options)
|
|
68
|
+
adapter.mac_address = network_options[:mac].gsub(':', '') if network_options[:mac]
|
|
69
|
+
adapter.save
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Returns the name of the proper host only network, or creates
|
|
74
|
+
# it if it does not exist. Vagrant determines if the host only
|
|
75
|
+
# network exists by comparing the netmask and the IP.
|
|
76
|
+
def network_name(net_options)
|
|
77
|
+
# First try to find a matching network
|
|
78
|
+
interfaces = VirtualBox::Global.global.host.network_interfaces
|
|
79
|
+
interfaces.each do |ni|
|
|
80
|
+
# Ignore non-host only interfaces which may also match,
|
|
81
|
+
# since they're not valid options.
|
|
82
|
+
next if ni.interface_type != :host_only
|
|
83
|
+
|
|
84
|
+
if net_options[:name]
|
|
85
|
+
return ni.name if net_options[:name] == ni.name
|
|
86
|
+
else
|
|
87
|
+
return ni.name if matching_network?(ni, net_options)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
raise Errors::NetworkNotFound, :name => net_options[:name] if net_options[:name]
|
|
92
|
+
|
|
93
|
+
# One doesn't exist, create it.
|
|
94
|
+
@env.ui.info I18n.t("vagrant.actions.vm.network.creating")
|
|
95
|
+
|
|
96
|
+
ni = interfaces.create
|
|
97
|
+
ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]),
|
|
98
|
+
net_options[:netmask])
|
|
99
|
+
ni.name
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Tests if a network matches the given options by applying the
|
|
103
|
+
# netmask to the IP of the network and also to the IP of the
|
|
104
|
+
# virtual machine and see if they match.
|
|
105
|
+
def matching_network?(interface, net_options)
|
|
106
|
+
interface.network_mask == net_options[:netmask] &&
|
|
107
|
+
apply_netmask(interface.ip_address, interface.network_mask) ==
|
|
108
|
+
apply_netmask(net_options[:ip], net_options[:netmask])
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Applies a netmask to an IP and returns the corresponding
|
|
112
|
+
# parts.
|
|
113
|
+
def apply_netmask(ip, netmask)
|
|
114
|
+
ip = split_ip(ip)
|
|
115
|
+
netmask = split_ip(netmask)
|
|
116
|
+
|
|
117
|
+
ip.map do |part|
|
|
118
|
+
part & netmask.shift
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Splits an IP and converts each portion into an int.
|
|
123
|
+
def split_ip(ip)
|
|
124
|
+
ip.split(".").map do |i|
|
|
125
|
+
i.to_i
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Returns a "network IP" which is a "good choice" for the IP
|
|
130
|
+
# for the actual network based on the netmask.
|
|
131
|
+
def network_ip(ip, netmask)
|
|
132
|
+
parts = apply_netmask(ip, netmask)
|
|
133
|
+
parts[3] += 1;
|
|
134
|
+
parts.join(".")
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require File.expand_path("../nfs_helpers", __FILE__)
|
|
2
|
+
|
|
3
|
+
module Vagrant
|
|
4
|
+
class Action
|
|
5
|
+
module VM
|
|
6
|
+
# Enables NFS based shared folders. `nfsd` must already be installed
|
|
7
|
+
# on the host machine, and NFS client must already be installed on
|
|
8
|
+
# the guest machine.
|
|
9
|
+
#
|
|
10
|
+
# This is a two part process:
|
|
11
|
+
#
|
|
12
|
+
# 1. Adds an entry to `/etc/exports` on the host machine using
|
|
13
|
+
# the host class to export the proper folder to the proper
|
|
14
|
+
# machine.
|
|
15
|
+
# 2. After boot, runs `mount` on the guest to mount the shared
|
|
16
|
+
# folder.
|
|
17
|
+
#
|
|
18
|
+
class NFS
|
|
19
|
+
include NFSHelpers
|
|
20
|
+
|
|
21
|
+
def initialize(app,env)
|
|
22
|
+
@app = app
|
|
23
|
+
@env = env
|
|
24
|
+
|
|
25
|
+
verify_settings if nfs_enabled?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def call(env)
|
|
29
|
+
@env = env
|
|
30
|
+
|
|
31
|
+
extract_folders
|
|
32
|
+
|
|
33
|
+
if !folders.empty?
|
|
34
|
+
prepare_folders
|
|
35
|
+
clear_nfs_exports(env)
|
|
36
|
+
export_folders
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
@app.call(env)
|
|
40
|
+
|
|
41
|
+
mount_folders if !folders.empty?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def recover(env)
|
|
45
|
+
clear_nfs_exports(env) if env["vm"].created?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns the folders which are to be synced via NFS.
|
|
49
|
+
def folders
|
|
50
|
+
@folders ||= {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Removes the NFS enabled shared folders from the configuration,
|
|
54
|
+
# so they will no longer be mounted by the actual shared folder
|
|
55
|
+
# task.
|
|
56
|
+
def extract_folders
|
|
57
|
+
# Load the NFS enabled shared folders
|
|
58
|
+
@folders = @env["config"].vm.shared_folders.inject({}) do |acc, data|
|
|
59
|
+
key, opts = data
|
|
60
|
+
|
|
61
|
+
if opts[:nfs]
|
|
62
|
+
# Duplicate the options, set the hostpath, and set disabled on the original
|
|
63
|
+
# options so the ShareFolders middleware doesn't try to mount it.
|
|
64
|
+
acc[key] = opts.dup
|
|
65
|
+
acc[key][:hostpath] = File.expand_path(opts[:hostpath], @env.env.root_path)
|
|
66
|
+
opts[:disabled] = true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
acc
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Prepares the settings for the NFS folders, such as setting the
|
|
74
|
+
# options on the NFS folders.
|
|
75
|
+
def prepare_folders
|
|
76
|
+
@folders = @folders.inject({}) do |acc, data|
|
|
77
|
+
key, opts = data
|
|
78
|
+
opts[:nfs] = {} if !opts.is_a?(Hash)
|
|
79
|
+
opts[:map_uid] = prepare_permission(:uid, opts)
|
|
80
|
+
opts[:map_gid] = prepare_permission(:gid, opts)
|
|
81
|
+
|
|
82
|
+
acc[key] = opts
|
|
83
|
+
acc
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Prepares the UID/GID settings for a single folder.
|
|
88
|
+
def prepare_permission(perm, opts)
|
|
89
|
+
key = "map_#{perm}".to_sym
|
|
90
|
+
return nil if opts.has_key?(key) && opts[key].nil?
|
|
91
|
+
|
|
92
|
+
# The options on the hash get priority, then the default
|
|
93
|
+
# values
|
|
94
|
+
value = opts.has_key?(key) ? opts[key] : @env["config"].nfs.send(key)
|
|
95
|
+
return value if value != :auto
|
|
96
|
+
|
|
97
|
+
# Get UID/GID from folder if we've made it this far
|
|
98
|
+
# (value == :auto)
|
|
99
|
+
stat = File.stat(opts[:hostpath])
|
|
100
|
+
return stat.send(perm)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Uses the host class to export the folders via NFS. This typically
|
|
104
|
+
# involves adding a line to `/etc/exports` for this VM, but it is
|
|
105
|
+
# up to the host class to define the specific behavior.
|
|
106
|
+
def export_folders
|
|
107
|
+
@env.ui.info I18n.t("vagrant.actions.vm.nfs.exporting")
|
|
108
|
+
|
|
109
|
+
@env["host"].nfs_export(guest_ip, folders)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Uses the system class to mount the NFS folders.
|
|
113
|
+
def mount_folders
|
|
114
|
+
@env.ui.info I18n.t("vagrant.actions.vm.nfs.mounting")
|
|
115
|
+
|
|
116
|
+
# Only mount the folders which have a guest path specified
|
|
117
|
+
am_folders = folders.select { |name, folder| folder[:guestpath] }
|
|
118
|
+
@env["vm"].system.mount_nfs(host_ip, Hash[am_folders])
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Returns the IP address of the first host only network adapter
|
|
122
|
+
#
|
|
123
|
+
# @return [String]
|
|
124
|
+
def host_ip
|
|
125
|
+
interface = @env["vm"].vm.network_adapters.find do |adapter|
|
|
126
|
+
adapter.host_interface_object
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
return nil if !interface
|
|
130
|
+
interface.host_interface_object.ip_address
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Returns the IP address of the guest by looking at the first
|
|
134
|
+
# enabled host only network.
|
|
135
|
+
#
|
|
136
|
+
# @return [String]
|
|
137
|
+
def guest_ip
|
|
138
|
+
@env["config"].vm.network_options[1][:ip]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Checks if there are any NFS enabled shared folders.
|
|
142
|
+
def nfs_enabled?
|
|
143
|
+
@env["config"].vm.shared_folders.each do |key, opts|
|
|
144
|
+
return true if opts[:nfs]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
false
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Verifies that the host is set and supports NFS.
|
|
151
|
+
def verify_settings
|
|
152
|
+
raise Errors::NFSHostRequired if @env["host"].nil?
|
|
153
|
+
raise Errors::NFSNotSupported if !@env["host"].nfs?
|
|
154
|
+
raise Errors::NFSNoHostNetwork if @env["config"].vm.network_options.empty?
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|