From 67b23be47300410d9853f2950b8a616557bb1b8d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 17 Jul 2010 09:09:06 -0700 Subject: [PATCH] Linux NFS support (host) --- lib/vagrant/hosts/base.rb | 3 +- lib/vagrant/hosts/linux.rb | 50 ++++++++++++ templates/nfs/exports_linux.erb | 3 + test/vagrant/hosts/base_test.rb | 2 +- test/vagrant/hosts/linux_test.rb | 56 ++++++++++++++ vagrant.gemspec | 129 ++++++++++++++++--------------- 6 files changed, 177 insertions(+), 66 deletions(-) create mode 100644 lib/vagrant/hosts/linux.rb create mode 100644 templates/nfs/exports_linux.erb create mode 100644 test/vagrant/hosts/linux_test.rb diff --git a/lib/vagrant/hosts/base.rb b/lib/vagrant/hosts/base.rb index 378949dba..f606cf9ce 100644 --- a/lib/vagrant/hosts/base.rb +++ b/lib/vagrant/hosts/base.rb @@ -30,7 +30,8 @@ module Vagrant # More coming soon classes = { :darwin => BSD, - :bsd => BSD + :bsd => BSD, + :linux => Linux } classes.each do |type, klass| diff --git a/lib/vagrant/hosts/linux.rb b/lib/vagrant/hosts/linux.rb new file mode 100644 index 000000000..7d556961a --- /dev/null +++ b/lib/vagrant/hosts/linux.rb @@ -0,0 +1,50 @@ +module Vagrant + module Hosts + # Represents a Linux based host, such as Ubuntu. + class Linux < Base + include Util + + def nfs? + tries = 10 + begin + # Check procfs to see if NFSd is a supported filesystem + system("cat /proc/filesystems | grep nfsd > /dev/null 2>&1") + rescue TypeError + tries -= 1 + retry if tries > 0 + + # Hopefully this point isn't reached + raise + end + end + + def nfs_export(ip, folders) + output = TemplateRenderer.render('nfs/exports_linux', + :uuid => env.vm.uuid, + :ip => ip, + :folders => folders) + + env.logger.info "Preparing to edit /etc/exports. Administrator priveleges will be required..." + output.split("\n").each do |line| + # This should only ask for administrative permission once, even + # though its executed in multiple subshells. + system(%Q[sudo su root -c "echo '#{line}' >> /etc/exports"]) + end + + # We run restart here instead of "update" just in case nfsd + # is not starting + system("sudo /etc/init.d/nfs-kernel-server restart") + end + + def nfs_cleanup + system("cat /etc/exports | grep 'VAGRANT-BEGIN: #{env.vm.uuid}' > /dev/null 2>&1") + + if $?.to_i == 0 + # Use sed to just strip out the block of code which was inserted + # by Vagrant + system("sudo sed -e '/^# VAGRANT-BEGIN: #{env.vm.uuid}/,/^# VAGRANT-END: #{env.vm.uuid}/ d' -i bak /etc/exports") + end + end + end + end +end diff --git a/templates/nfs/exports_linux.erb b/templates/nfs/exports_linux.erb new file mode 100644 index 000000000..6eab88c1b --- /dev/null +++ b/templates/nfs/exports_linux.erb @@ -0,0 +1,3 @@ +# VAGRANT-BEGIN: <%= uuid %> +<% folders.each do |name, opts| %><%= opts[:hostpath] %> <%= ip %>(rw<% if opts[:map_uid] %>,anonuid=<%= opts[:map_uid] %><% end %><% if opts[:map_gid] %>,anongid=<%= opts[:map_gid] %><% end %>)<% end %> +# VAGRANT-END: <%= uuid %> \ No newline at end of file diff --git a/test/vagrant/hosts/base_test.rb b/test/vagrant/hosts/base_test.rb index dbba39701..271dfc115 100644 --- a/test/vagrant/hosts/base_test.rb +++ b/test/vagrant/hosts/base_test.rb @@ -36,7 +36,7 @@ class BaseHostTest < Test::Unit::TestCase end should "return nil if an exception is raised" do - Vagrant::Util::Platform.expects(:darwin?).raises(Exception) + Vagrant::Util::Platform.stubs(:platform).returns("boo") assert_nothing_raised { assert_nil @klass.detect } diff --git a/test/vagrant/hosts/linux_test.rb b/test/vagrant/hosts/linux_test.rb new file mode 100644 index 000000000..2f089dee7 --- /dev/null +++ b/test/vagrant/hosts/linux_test.rb @@ -0,0 +1,56 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'test_helper') + +class LinuxHostTest < Test::Unit::TestCase + setup do + @klass = Vagrant::Hosts::Linux + @env = mock_environment + @env.stubs(:vm).returns(Vagrant::VM.new(:env => @env)) + @env.logger.stubs(:info) + + @instance = @klass.new(@env) + end + + context "supporting nfs check" do + should "support NFS" do + @instance.expects(:system).returns(true) + assert @instance.nfs? + end + + should "not support NFS if nfsd is not found" do + @instance.expects(:system).returns(false) + assert !@instance.nfs? + end + + should "retry until a boolean is returned" do + seq = sequence("seq") + @instance.expects(:system).in_sequence(seq).raises(TypeError.new("foo")) + @instance.expects(:system).in_sequence(seq).returns(true) + assert @instance.nfs? + end + end + + context "nfs export" do + setup do + @instance.stubs(:system) + + @ip = "foo" + @folders = "bar" + end + + should "output the lines of the rendered template" do + output = %W[foo bar baz].join("\n") + Vagrant::Util::TemplateRenderer.expects(:render).with("nfs/exports_linux", + :uuid => @env.vm.uuid, + :ip => @ip, + :folders => @folders).returns(output) + + @instance.expects(:system).times(output.split("\n").length) + @instance.expects(:system).with("sudo /etc/init.d/nfs-kernel-server restart") + @instance.nfs_export(@ip, @folders) + end + end + + context "nfs cleanup" do + # TODO: How to test all the system calls? + end +end diff --git a/vagrant.gemspec b/vagrant.gemspec index f1641c640..8756a9098 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= s.authors = ["Mitchell Hashimoto", "John Bender"] - s.date = %q{2010-07-16} + s.date = %q{2010-07-17} s.default_executable = %q{vagrant} s.description = %q{Vagrant is a tool for building and distributing virtualized development environments.} s.email = ["mitchell.hashimoto@gmail.com", "john.m.bender@gmail.com"] @@ -97,6 +97,7 @@ Gem::Specification.new do |s| "lib/vagrant/environment.rb", "lib/vagrant/hosts/base.rb", "lib/vagrant/hosts/bsd.rb", + "lib/vagrant/hosts/linux.rb", "lib/vagrant/provisioners/base.rb", "lib/vagrant/provisioners/chef.rb", "lib/vagrant/provisioners/chef_server.rb", @@ -205,93 +206,93 @@ Gem::Specification.new do |s| s.homepage = %q{http://github.com/mitchellh/vagrant} s.rdoc_options = ["--charset=UTF-8"] s.require_paths = ["lib"] - s.rubygems_version = %q{1.3.7} + s.rubygems_version = %q{1.3.6} s.summary = %q{Vagrant is a tool for building and distributing virtualized development environments.} s.test_files = [ "test/test_helper.rb", - "test/vagrant/action/box/destroy_test.rb", - "test/vagrant/action/box/download_test.rb", - "test/vagrant/action/box/unpackage_test.rb", - "test/vagrant/action/box/verify_test.rb", - "test/vagrant/action/builder_test.rb", - "test/vagrant/action/env/error_halt_test.rb", - "test/vagrant/action/env/set_test.rb", + "test/vagrant/vm_test.rb", + "test/vagrant/command_test.rb", "test/vagrant/action/environment_test.rb", "test/vagrant/action/exception_catcher_test.rb", - "test/vagrant/action/vm/boot_test.rb", - "test/vagrant/action/vm/check_guest_additions_test.rb", - "test/vagrant/action/vm/clean_machine_folder_test.rb", - "test/vagrant/action/vm/clear_forwarded_ports_test.rb", - "test/vagrant/action/vm/clear_nfs_exports_test.rb", - "test/vagrant/action/vm/clear_shared_folders_test.rb", - "test/vagrant/action/vm/customize_test.rb", - "test/vagrant/action/vm/destroy_test.rb", - "test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb", - "test/vagrant/action/vm/export_test.rb", - "test/vagrant/action/vm/forward_ports_helpers_test.rb", - "test/vagrant/action/vm/forward_ports_test.rb", - "test/vagrant/action/vm/halt_test.rb", - "test/vagrant/action/vm/import_test.rb", - "test/vagrant/action/vm/match_mac_address_test.rb", - "test/vagrant/action/vm/network_test.rb", - "test/vagrant/action/vm/nfs_helpers_test.rb", - "test/vagrant/action/vm/nfs_test.rb", - "test/vagrant/action/vm/package_test.rb", - "test/vagrant/action/vm/persist_test.rb", - "test/vagrant/action/vm/provision_test.rb", - "test/vagrant/action/vm/resume_test.rb", - "test/vagrant/action/vm/share_folders_test.rb", + "test/vagrant/action/box/verify_test.rb", + "test/vagrant/action/box/destroy_test.rb", + "test/vagrant/action/box/unpackage_test.rb", + "test/vagrant/action/box/download_test.rb", "test/vagrant/action/vm/suspend_test.rb", - "test/vagrant/action_test.rb", - "test/vagrant/active_list_test.rb", + "test/vagrant/action/vm/boot_test.rb", + "test/vagrant/action/vm/package_test.rb", + "test/vagrant/action/vm/share_folders_test.rb", + "test/vagrant/action/vm/forward_ports_helpers_test.rb", + "test/vagrant/action/vm/persist_test.rb", + "test/vagrant/action/vm/nfs_test.rb", + "test/vagrant/action/vm/clear_nfs_exports_test.rb", + "test/vagrant/action/vm/destroy_test.rb", + "test/vagrant/action/vm/halt_test.rb", + "test/vagrant/action/vm/clear_forwarded_ports_test.rb", + "test/vagrant/action/vm/check_guest_additions_test.rb", + "test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb", + "test/vagrant/action/vm/import_test.rb", + "test/vagrant/action/vm/nfs_helpers_test.rb", + "test/vagrant/action/vm/customize_test.rb", + "test/vagrant/action/vm/network_test.rb", + "test/vagrant/action/vm/export_test.rb", + "test/vagrant/action/vm/provision_test.rb", + "test/vagrant/action/vm/clear_shared_folders_test.rb", + "test/vagrant/action/vm/clean_machine_folder_test.rb", + "test/vagrant/action/vm/resume_test.rb", + "test/vagrant/action/vm/match_mac_address_test.rb", + "test/vagrant/action/vm/forward_ports_test.rb", + "test/vagrant/action/builder_test.rb", + "test/vagrant/action/env/set_test.rb", + "test/vagrant/action/env/error_halt_test.rb", + "test/vagrant/environment_test.rb", + "test/vagrant/util_test.rb", "test/vagrant/box_test.rb", "test/vagrant/busy_test.rb", - "test/vagrant/command_test.rb", + "test/vagrant/provisioners/base_test.rb", + "test/vagrant/provisioners/chef_test.rb", + "test/vagrant/provisioners/chef_server_test.rb", + "test/vagrant/provisioners/chef_solo_test.rb", + "test/vagrant/systems/linux_test.rb", + "test/vagrant/config_test.rb", + "test/vagrant/hosts/base_test.rb", + "test/vagrant/hosts/bsd_test.rb", + "test/vagrant/active_list_test.rb", "test/vagrant/commands/base_test.rb", - "test/vagrant/commands/box/add_test.rb", - "test/vagrant/commands/box/list_test.rb", - "test/vagrant/commands/box/remove_test.rb", + "test/vagrant/commands/reload_test.rb", + "test/vagrant/commands/ssh_config_test.rb", + "test/vagrant/commands/suspend_test.rb", + "test/vagrant/commands/package_test.rb", + "test/vagrant/commands/status_test.rb", + "test/vagrant/commands/init_test.rb", "test/vagrant/commands/destroy_test.rb", "test/vagrant/commands/halt_test.rb", - "test/vagrant/commands/init_test.rb", - "test/vagrant/commands/package_test.rb", - "test/vagrant/commands/provision_test.rb", - "test/vagrant/commands/reload_test.rb", - "test/vagrant/commands/resume_test.rb", - "test/vagrant/commands/ssh_config_test.rb", - "test/vagrant/commands/ssh_test.rb", - "test/vagrant/commands/status_test.rb", - "test/vagrant/commands/suspend_test.rb", + "test/vagrant/commands/box/remove_test.rb", + "test/vagrant/commands/box/add_test.rb", + "test/vagrant/commands/box/list_test.rb", "test/vagrant/commands/up_test.rb", - "test/vagrant/config_test.rb", + "test/vagrant/commands/provision_test.rb", + "test/vagrant/commands/resume_test.rb", + "test/vagrant/commands/ssh_test.rb", + "test/vagrant/resource_logger_test.rb", "test/vagrant/downloaders/base_test.rb", "test/vagrant/downloaders/file_test.rb", "test/vagrant/downloaders/http_test.rb", - "test/vagrant/environment_test.rb", - "test/vagrant/hosts/base_test.rb", - "test/vagrant/hosts/bsd_test.rb", - "test/vagrant/provisioners/base_test.rb", - "test/vagrant/provisioners/chef_server_test.rb", - "test/vagrant/provisioners/chef_solo_test.rb", - "test/vagrant/provisioners/chef_test.rb", - "test/vagrant/resource_logger_test.rb", - "test/vagrant/ssh_session_test.rb", - "test/vagrant/ssh_test.rb", - "test/vagrant/systems/linux_test.rb", - "test/vagrant/util/plain_logger_test.rb", - "test/vagrant/util/platform_test.rb", "test/vagrant/util/stacked_proc_runner_test.rb", "test/vagrant/util/template_renderer_test.rb", "test/vagrant/util/translator_test.rb", - "test/vagrant/util_test.rb", - "test/vagrant/vm_test.rb" + "test/vagrant/util/platform_test.rb", + "test/vagrant/util/plain_logger_test.rb", + "test/vagrant/ssh_session_test.rb", + "test/vagrant/action_test.rb", + "test/vagrant/ssh_test.rb" ] if s.respond_to? :specification_version then current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = 3 - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, ["~> 0.7.3"]) s.add_runtime_dependency(%q, [">= 2.0.19"]) s.add_runtime_dependency(%q, [">= 1.0.2"])