From e1d42256444da2770a7a4d591e4c0abf98f67ed1 Mon Sep 17 00:00:00 2001 From: dima Date: Fri, 10 May 2013 21:24:14 +0200 Subject: [PATCH] add nfs support --- lib/vagrant-libvirt/action.rb | 9 +++ lib/vagrant-libvirt/action/connect_libvirt.rb | 8 +- .../action/prepare_nfs_settings.rb | 54 +++++++++++++ .../action/prune_nfs_exports.rb | 21 +++++ lib/vagrant-libvirt/action/share_folders.rb | 76 +++++++++++++++++++ lib/vagrant-libvirt/config.rb | 16 ++++ 6 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 lib/vagrant-libvirt/action/prepare_nfs_settings.rb create mode 100644 lib/vagrant-libvirt/action/prune_nfs_exports.rb create mode 100644 lib/vagrant-libvirt/action/share_folders.rb diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb index 259a28f..6bd7327 100644 --- a/lib/vagrant-libvirt/action.rb +++ b/lib/vagrant-libvirt/action.rb @@ -24,6 +24,11 @@ module VagrantPlugins b2.use TimedProvision b2.use CreateNetworks b2.use CreateNetworkInterfaces + + b2.use PruneNFSExports + b2.use NFS + b2.use PrepareNFSSettings + b2.use ShareFolders b2.use StartDomain b2.use WaitTillUp b2.use SyncFolders @@ -100,6 +105,7 @@ module VagrantPlugins next end + b2.use PruneNFSExports b2.use ConnectLibvirt b2.use DestroyDomain b2.use DestroyNetworks @@ -279,6 +285,9 @@ module VagrantPlugins autoload :WaitTillUp, action_root.join("wait_till_up") autoload :SyncFolders, action_root.join("sync_folders") autoload :SSHRun, "vagrant/action/builtin/ssh_run" + autoload :PrepareNFSSettings, action_root.join("prepare_nfs_settings") + autoload :PruneNFSExports, action_root.join("prune_nfs_exports") + autoload :ShareFolders, action_root.join("share_folders") end end end diff --git a/lib/vagrant-libvirt/action/connect_libvirt.rb b/lib/vagrant-libvirt/action/connect_libvirt.rb index 83ad752..d48236b 100644 --- a/lib/vagrant-libvirt/action/connect_libvirt.rb +++ b/lib/vagrant-libvirt/action/connect_libvirt.rb @@ -18,7 +18,7 @@ module VagrantPlugins env[:libvirt_compute] = Libvirt.libvirt_connection return @app.call(env) end - + # Get config options for libvirt provider. config = env[:machine].provider_config @@ -38,7 +38,7 @@ module VagrantPlugins else uri << '://' uri << config.host if config.host - end + end uri << '/system?no_verify=1' conn_attr = {} @@ -46,7 +46,7 @@ module VagrantPlugins conn_attr[:libvirt_uri] = uri conn_attr[:libvirt_username] = config.username if config.username conn_attr[:libvirt_password] = config.password if config.password - + # Setup command for retrieving IP address for newly created machine # with some MAC address. Get it from dnsmasq leases table - either # /var/lib/libvirt/dnsmasq/*.leases files, or @@ -54,7 +54,7 @@ module VagrantPlugins ip_command = "LEASES='/var/lib/libvirt/dnsmasq/*.leases'; " ip_command << "[ -f /var/lib/misc/dnsmasq.leases ] && " ip_command << "LEASES='/var/lib/misc/dnsmasq.leases'; " - ip_command << "cat $LEASES | grep $mac | awk '{ print $3 }'" + ip_command << "grep $mac $LEASES | awk '{ print $3 }'" conn_attr[:libvirt_ip_command] = ip_command @logger.info("Connecting to Libvirt (#{uri}) ...") diff --git a/lib/vagrant-libvirt/action/prepare_nfs_settings.rb b/lib/vagrant-libvirt/action/prepare_nfs_settings.rb new file mode 100644 index 0000000..b00d790 --- /dev/null +++ b/lib/vagrant-libvirt/action/prepare_nfs_settings.rb @@ -0,0 +1,54 @@ +module VagrantPlugins + module Libvirt + module Action + class PrepareNFSSettings + def initialize(app,env) + @app = app + @logger = Log4r::Logger.new("vagrant::action::vm::nfs") + end + + def call(env) + @app.call(env) + + using_nfs = false + env[:machine].config.vm.synced_folders.each do |id, opts| + if opts[:nfs] + using_nfs = true + break + end + end + + if using_nfs + @logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP") + env[:nfs_host_ip] = read_host_ip(env[:machine]) + env[:nfs_machine_ip] = env[:machine].ssh_info[:host] + + raise Vagrant::Errors::NFSNoHostonlyNetwork if !env[:nfs_machine_ip] + end + end + + # Returns the IP address of the first host only network adapter + # + # @param [Machine] machine + # @return [String] + def read_host_ip(machine) + `ip addr show | grep -A 2 virbr0 | grep -i 'inet ' | tr -s ' ' | cut -d' ' -f3 | cut -d'/' -f 1`.chomp + end + + # Returns the IP address of the guest by looking at the first + # enabled host only network. + # + # @return [String] + def read_machine_ip(machine) + machine.config.vm.networks.each do |type, options| + if type == :private_network && options[:ip].is_a?(String) + return options[:ip] + end + end + + nil + end + end + end + end +end diff --git a/lib/vagrant-libvirt/action/prune_nfs_exports.rb b/lib/vagrant-libvirt/action/prune_nfs_exports.rb new file mode 100644 index 0000000..dcc2d49 --- /dev/null +++ b/lib/vagrant-libvirt/action/prune_nfs_exports.rb @@ -0,0 +1,21 @@ +require 'yaml' +module VagrantPlugins + module Libvirt + module Action + class PruneNFSExports + def initialize(app, env) + @app = app + end + + def call(env) + if env[:host] + uuid = env[:machine].id + env[:host].nfs_prune(uuid) + end + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-libvirt/action/share_folders.rb b/lib/vagrant-libvirt/action/share_folders.rb new file mode 100644 index 0000000..c6b496d --- /dev/null +++ b/lib/vagrant-libvirt/action/share_folders.rb @@ -0,0 +1,76 @@ +require "pathname" + +require "log4r" + +module VagrantPlugins + module Libvirt + module Action + class ShareFolders + def initialize(app, env) + @logger = Log4r::Logger.new("vagrant::action::vm::share_folders") + @app = app + end + + def call(env) + @env = env + + prepare_folders + create_metadata + + @app.call(env) + end + + # This method returns an actual list of shared + # folders to create and their proper path. + def shared_folders + {}.tap do |result| + @env[:machine].config.vm.synced_folders.each do |id, data| + # Ignore NFS shared folders + #next if data[:nfs] + + # convert to NFS share + data[:nfs] = true + + # This to prevent overwriting the actual shared folders data + result[id] = data.dup + end + end + end + + # Prepares the shared folders by verifying they exist and creating them + # if they don't. + def prepare_folders + shared_folders.each do |id, options| + hostpath = Pathname.new(options[:hostpath]).expand_path(@env[:root_path]) + + if !hostpath.directory? && options[:create] + # Host path doesn't exist, so let's create it. + @logger.debug("Host path doesn't exist, creating: #{hostpath}") + + begin + hostpath.mkpath + rescue Errno::EACCES + raise Vagrant::Errors::SharedFolderCreateFailed, + :path => hostpath.to_s + end + end + end + end + + def create_metadata + @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating") + + folders = [] + shared_folders.each do |id, data| + folders << { + :name => id, + :hostpath => File.expand_path(data[:hostpath], @env[:root_path]), + :transient => data[:transient] + } + end + end + + end + end + end +end diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index a8a151f..7422459 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -27,7 +27,10 @@ module VagrantPlugins attr_accessor :cpus attr_accessor :nested + attr_reader :shared_folders + def initialize + @shared_folders = {} @driver = UNSET_VALUE @host = UNSET_VALUE @connect_via_ssh = UNSET_VALUE @@ -55,6 +58,19 @@ module VagrantPlugins @nested = false if @nested == UNSET_VALUE end + def share_folder(name, guestpath, hostpath, opts=nil) + @shared_folders[name] = { + :guestpath => guestpath.to_s, + :hostpath => hostpath.to_s, + :create => false, + :owner => nil, + :group => nil, + :nfs => false, + :transient => false, + :extra => nil + }.merge(opts || {}) + end + def validate(machine) end end