Halt and mount NFS are caps

This commit is contained in:
Mitchell Hashimoto 2013-04-03 23:33:20 -07:00
parent 61d2f9f96f
commit 2f232e0175
8 changed files with 65 additions and 70 deletions

View File

@ -44,7 +44,7 @@ module Vagrant
# checked above.
if graceful
env[:ui].info I18n.t("vagrant.actions.vm.halt.graceful")
env[:machine].guest.halt
env[:machine].guest.capability(:halt)
@logger.debug("Waiting for target graceful halt state: #{@target_state}")
count = 0

View File

@ -78,7 +78,8 @@ module Vagrant
end
# Mount them!
env[:machine].guest.mount_nfs(env[:nfs_host_ip], mount_folders)
env[:machine].guest.capability(
:mount_nfs, env[:nfs_host_ip], mount_folders)
end
end

View File

@ -243,6 +243,10 @@ module Vagrant
error_key(:linux_mount_failed)
end
class LinuxNFSMountFailed < VagrantError
error_key(:linux_nfs_mount_failed)
end
class LinuxShellExpandFailed < VagrantError
error_key(:linux_shell_expand_failed)
end

View File

@ -0,0 +1,16 @@
module VagrantPlugins
module GuestLinux
module Cap
class Halt
def self.halt(machine)
begin
machine.communicate.sudo("shutdown -h now")
rescue IOError
# Do nothing, because it probably means the machine shut down
# and SSH connection was lost.
end
end
end
end
end
end

View File

@ -0,0 +1,26 @@
module VagrantPlugins
module GuestLinux
module Cap
class MountNFS
def self.mount_nfs(machine, ip, folders)
folders.each do |name, opts|
# Expand the guest path so we can handle things like "~/vagrant"
expanded_guest_path = machine.guest.capability(
:shell_expand_guest_path, opts[:guestpath])
# Do the actual creating and mounting
machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
# Mount
mount_command = "mount -o vers=#{opts[:nfs_version]} #{ip}:'#{opts[:hostpath]}' #{expanded_guest_path}"
retryable(:on => Vagrant::Errors::LinuxNFSMountFailed, :tries => 5, :sleep => 2) do
machine.communicate.sudo(mount_command,
:error_class => Vagrant::Errors::LinuxNFSMountFailed)
end
end
end
end
end
end
end

View File

@ -1,71 +1,12 @@
require 'log4r'
require "vagrant"
require "vagrant/util/retryable"
module VagrantPlugins
module GuestLinux
class Guest < Vagrant.plugin("2", :guest)
include Vagrant::Util::Retryable
def detect?(machine)
# TODO: Linux detection
false
end
def halt
begin
@vm.communicate.sudo("shutdown -h now")
rescue IOError
# Do nothing, because it probably means the machine shut down
# and SSH connection was lost.
end
end
def mount_nfs(ip, folders)
# TODO: Maybe check for nfs support on the guest, since its often
# not installed by default
folders.each do |name, opts|
# Expand the guestpath, so we can handle things like "~/vagrant"
real_guestpath = expanded_guest_path(opts[:guestpath])
# Do the actual creating and mounting
@vm.communicate.sudo("mkdir -p #{real_guestpath}")
retryable(:on => LinuxError, :tries => 5, :sleep => 2) do
@vm.communicate.sudo("mount -o vers=#{opts[:nfs_version]} #{ip}:'#{opts[:hostpath]}' #{real_guestpath}",
:error_class => LinuxError,
:error_key => :mount_nfs_fail)
end
end
end
protected
# Determine the real guest path. Since we use a `sudo` shell everywhere
# else, things like '~' don't expand properly in shared folders. We have
# to `echo` here to get that path.
#
# @param [String] guestpath The unexpanded guest path.
# @return [String] The expanded guestpath
def expanded_guest_path(guestpath)
real_guestpath = nil
@vm.communicate.execute("printf #{guestpath}") do |type, data|
if type == :stdout
real_guestpath ||= ""
real_guestpath += data
end
end
if !real_guestpath
# Really strange error case if this happens. Let's throw an error,
# tell the user to check the echo output.
raise LinuxError, :_key => :guestpath_expand_fail
end
# Chomp the string so that any trailing newlines are killed
return real_guestpath.chomp
end
end
end
end

View File

@ -16,11 +16,21 @@ module VagrantPlugins
Guest
end
guest_capability("linux", "halt") do
require_relative "cap/halt"
Cap::Halt
end
guest_capability("linux", "shell_expand_guest_path") do
require_relative "cap/shell_expand_guest_path"
Cap::ShellExpandGuestPath
end
guest_capability("linux", "mount_nfs_folder") do
require_relative "cap/mount_nfs"
Cap::MountNFS
end
guest_capability("linux", "mount_virtualbox_shared_folder") do
require_relative "cap/mount_virtualbox_shared_folder"
Cap::MountVirtualBoxSharedFolder

View File

@ -211,6 +211,12 @@ en:
can work properly. The command attempted was:
%{command}
linux_nfs_mount_failed: |-
Mounting NFS shared folders failed. This is most often caused by the NFS
client software not being installed on the guest machine. Please verify
that the NFS client software is properly installed, and consult any resources
specific to the linux distro you're using for more information on how to
do this.
linux_shell_expand_failed: |-
Vagrant failed to determine the shell expansion of the guest path
for one of your shared folders. This is an extremely rare error case
@ -1032,12 +1038,3 @@ en:
no_path_or_inline: "One of `path` or `inline` must be set."
path_invalid: "`path` for shell provisioner does not exist on the host system: %{path}"
upload_path_not_set: "`upload_path` must be set for the shell provisioner."
guest:
linux:
mount_nfs_fail: |-
Mounting NFS shared folders failed. This is most often caused by the NFS
client software not being installed on the guest machine. Please verify
that the NFS client software is properly installed, and consult any resources
specific to the linux distro you're using for more information on how to
do this.