Mitchell Hashimoto 0eddda3552 Halt works with new machine.
This required some modifications to the linux guest implementation. And
the other guests will have to be modified as well. This is because
`channel` is now `communicate`.
2012-08-12 18:54:52 -07:00

124 lines
4.2 KiB
Ruby

require 'log4r'
require "vagrant"
module VagrantPlugins
module GuestLinux
class Guest < Vagrant.plugin("1", :guest)
class LinuxError < Vagrant::Errors::VagrantError
error_namespace("vagrant.guest.linux")
end
def initialize(*args)
super
@logger = Log4r::Logger.new("vagrant::guest::linux")
end
def distro_dispatch
@vm.communicate.tap do |comm|
if comm.test("cat /etc/debian_version") == 0
return :debian if comm.test("cat /proc/version | grep 'Debian'") == 0
return :ubuntu if comm.test("cat /proc/version | grep 'Ubuntu'") == 0
end
return :gentoo if comm.test("cat /etc/gentoo-release") == 0
return :fedora if comm.test("grep 'Fedora release 16' /etc/redhat-release") == 0
return :redhat if comm.test("cat /etc/redhat-release") == 0
return :suse if comm.test("cat /etc/SuSE-release") == 0
return :arch if comm.test("cat /etc/arch-release") == 0
end
# Can't detect the distro, assume vanilla linux
nil
end
def halt
@vm.communicate.sudo("shutdown -h now")
# Wait until the VM's state is actually powered off. If this doesn't
# occur within a reasonable amount of time (15 seconds by default),
# then simply return and allow Vagrant to kill the machine.
count = 0
while @vm.state != :poweroff
count += 1
return if count >= @vm.config.linux.halt_timeout
sleep @vm.config.linux.halt_check_interval
end
end
def mount_shared_folder(name, guestpath, options)
real_guestpath = expanded_guest_path(guestpath)
@logger.debug("Shell expanded guest path: #{real_guestpath}")
@vm.channel.sudo("mkdir -p #{real_guestpath}")
mount_folder(name, real_guestpath, options)
@vm.channel.sudo("chown `id -u #{options[:owner]}`:`id -g #{options[:group]}` #{real_guestpath}")
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.channel.sudo("mkdir -p #{real_guestpath}")
@vm.channel.sudo("mount -o vers=#{opts[:nfs_version]} #{ip}:'#{opts[:hostpath]}' #{real_guestpath}",
:error_class => LinuxError,
:error_key => :mount_nfs_fail)
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.channel.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
def mount_folder(name, guestpath, options)
# Determine the permission string to attach to the mount command
mount_options = "-o uid=`id -u #{options[:owner]}`,gid=`id -g #{options[:group]}`"
mount_options += ",#{options[:extra]}" if options[:extra]
attempts = 0
while true
success = true
@vm.channel.sudo("mount -t vboxsf #{mount_options} #{name} #{guestpath}") do |type, data|
success = false if type == :stderr && data =~ /No such device/i
end
break if success
attempts += 1
raise LinuxError, :mount_fail if attempts >= 10
sleep 5
end
end
end
end
end