From e1d42256444da2770a7a4d591e4c0abf98f67ed1 Mon Sep 17 00:00:00 2001 From: dima Date: Fri, 10 May 2013 21:24:14 +0200 Subject: [PATCH 1/2] 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 From 36b71b78a714a09f766eb1c9e4a8f5c817bf0788 Mon Sep 17 00:00:00 2001 From: dima Date: Tue, 14 May 2013 01:16:28 +0200 Subject: [PATCH 2/2] improve nfs --- README.md | 2 ++ lib/vagrant-libvirt/action.rb | 3 +-- .../action/prepare_nfs_settings.rb | 18 +++++++++++++++--- .../action/prune_nfs_exports.rb | 7 ++++++- lib/vagrant-libvirt/action/share_folders.rb | 4 ++-- lib/vagrant-libvirt/action/sync_folders.rb | 1 + lib/vagrant-libvirt/config.rb | 16 ---------------- 7 files changed, 27 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 35dca08..63f1eaa 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,8 @@ to the remote machine over SSH. This is good enough for all built-in Vagrant provisioners (shell, chef, and puppet) to work! +if used options :nfs => true, folder will exported by nfs. + ## Box Format You can view an example box in the [example_box/directory](https://github.com/pradels/vagrant-libvirt/tree/master/example_box). That directory also contains instructions on how to build a box. diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb index 6bd7327..7c7647b 100644 --- a/lib/vagrant-libvirt/action.rb +++ b/lib/vagrant-libvirt/action.rb @@ -25,7 +25,6 @@ module VagrantPlugins b2.use CreateNetworks b2.use CreateNetworkInterfaces - b2.use PruneNFSExports b2.use NFS b2.use PrepareNFSSettings b2.use ShareFolders @@ -105,8 +104,8 @@ module VagrantPlugins next end - b2.use PruneNFSExports b2.use ConnectLibvirt + b2.use PruneNFSExports b2.use DestroyDomain b2.use DestroyNetworks diff --git a/lib/vagrant-libvirt/action/prepare_nfs_settings.rb b/lib/vagrant-libvirt/action/prepare_nfs_settings.rb index b00d790..bc0ffb7 100644 --- a/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +++ b/lib/vagrant-libvirt/action/prepare_nfs_settings.rb @@ -1,3 +1,4 @@ +require 'nokogiri' module VagrantPlugins module Libvirt module Action @@ -20,7 +21,7 @@ module VagrantPlugins 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_host_ip] = read_host_ip(env[:machine],env) env[:nfs_machine_ip] = env[:machine].ssh_info[:host] raise Vagrant::Errors::NFSNoHostonlyNetwork if !env[:nfs_machine_ip] @@ -31,8 +32,19 @@ module VagrantPlugins # # @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 + def read_host_ip(machine,env) + nets = env[:libvirt_compute].list_networks + if nets.size == 1 + net = nets.first + else + domain = env[:libvirt_compute].servers.get(machine.id.to_s) + xml=Nokogiri::XML(domain.to_xml) + networkname = xml.xpath('/domain/devices/interface/source').first.attributes['network'].value.to_s + puts "network name = #{networkname}" + net = env[:libvirt_compute].list_networks.map {|netw| netw if netw[:name] == networkname}.first + end + # FIXME better implement by libvirt xml parsing + `ip addr show | grep -A 2 #{net[:bridge_name]} | 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 diff --git a/lib/vagrant-libvirt/action/prune_nfs_exports.rb b/lib/vagrant-libvirt/action/prune_nfs_exports.rb index dcc2d49..435a80e 100644 --- a/lib/vagrant-libvirt/action/prune_nfs_exports.rb +++ b/lib/vagrant-libvirt/action/prune_nfs_exports.rb @@ -3,6 +3,7 @@ module VagrantPlugins module Libvirt module Action class PruneNFSExports + def initialize(app, env) @app = app end @@ -10,7 +11,11 @@ module VagrantPlugins def call(env) if env[:host] uuid = env[:machine].id - env[:host].nfs_prune(uuid) + # get all uuids + uuids = env[:libvirt_compute].servers.all.map(&:id) + # not exiisted in array will removed from nfs + uuids.delete(uuid) + env[:host].nfs_prune(uuids) end @app.call(env) diff --git a/lib/vagrant-libvirt/action/share_folders.rb b/lib/vagrant-libvirt/action/share_folders.rb index c6b496d..285b4e7 100644 --- a/lib/vagrant-libvirt/action/share_folders.rb +++ b/lib/vagrant-libvirt/action/share_folders.rb @@ -26,10 +26,10 @@ module VagrantPlugins {}.tap do |result| @env[:machine].config.vm.synced_folders.each do |id, data| # Ignore NFS shared folders - #next if data[:nfs] + next if !data[:nfs] # convert to NFS share - data[:nfs] = true + #data[:nfs] = true # This to prevent overwriting the actual shared folders data result[id] = data.dup diff --git a/lib/vagrant-libvirt/action/sync_folders.rb b/lib/vagrant-libvirt/action/sync_folders.rb index f16fa02..af5af7d 100644 --- a/lib/vagrant-libvirt/action/sync_folders.rb +++ b/lib/vagrant-libvirt/action/sync_folders.rb @@ -18,6 +18,7 @@ module VagrantPlugins ssh_info = env[:machine].ssh_info env[:machine].config.vm.synced_folders.each do |id, data| + next if data[:nfs] hostpath = File.expand_path(data[:hostpath], env[:root_path]) guestpath = data[:guestpath] diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 7422459..a8a151f 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -27,10 +27,7 @@ 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 @@ -58,19 +55,6 @@ 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