mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Merge pull request #170 from teto/virtfs
Add 9p (virtfs) support to vagrant-libvirt.
This commit is contained in:
commit
489e096227
4
Gemfile
4
Gemfile
@ -10,3 +10,7 @@ group :development do
|
||||
gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
|
||||
end
|
||||
|
||||
group :plugins do
|
||||
gem "vagrant-libvirt", :path => '.'
|
||||
end
|
||||
|
||||
|
@ -27,19 +27,26 @@ module VagrantPlugins
|
||||
b2.use CreateNetworks
|
||||
b2.use CreateNetworkInterfaces
|
||||
|
||||
b2.use StartDomain
|
||||
b2.use WaitTillUp
|
||||
|
||||
b2.use PrepareNFSValidIds
|
||||
b2.use SyncedFolderCleanup
|
||||
b2.use SyncedFolders
|
||||
|
||||
b2.use StartDomain
|
||||
b2.use WaitTillUp
|
||||
|
||||
b2.use StartDomain
|
||||
b2.use WaitTillUp
|
||||
|
||||
|
||||
|
||||
|
||||
b2.use ForwardPorts
|
||||
|
||||
b2.use PrepareNFSSettings
|
||||
# b2.use PrepareNFSSettings
|
||||
b2.use ShareFolders
|
||||
b2.use SetHostname
|
||||
b2.use SyncFolders
|
||||
# b2.use SyncFolders
|
||||
else
|
||||
b2.use action_start
|
||||
end
|
||||
@ -70,6 +77,11 @@ module VagrantPlugins
|
||||
# Ensure networks are created and active
|
||||
b3.use CreateNetworks
|
||||
|
||||
b3.use PrepareNFSValidIds
|
||||
b3.use SyncedFolderCleanup
|
||||
b3.use SyncedFolders
|
||||
|
||||
|
||||
# Start it..
|
||||
b3.use StartDomain
|
||||
|
||||
@ -77,12 +89,9 @@ module VagrantPlugins
|
||||
# so wait for dhcp lease and store IP into machines data_dir.
|
||||
b3.use WaitTillUp
|
||||
|
||||
b3.use PrepareNFSValidIds
|
||||
b3.use SyncedFolderCleanup
|
||||
b3.use SyncedFolders
|
||||
|
||||
b3.use ForwardPorts
|
||||
b3.use PrepareNFSSettings
|
||||
# b3.use PrepareNFSSettings
|
||||
b3.use ShareFolders
|
||||
|
||||
end
|
||||
@ -147,7 +156,7 @@ module VagrantPlugins
|
||||
|
||||
b2.use ConnectLibvirt
|
||||
b2.use ClearForwardedPorts
|
||||
b2.use PruneNFSExports
|
||||
# b2.use PruneNFSExports
|
||||
b2.use DestroyDomain
|
||||
b2.use DestroyNetworks
|
||||
end
|
||||
@ -195,7 +204,7 @@ module VagrantPlugins
|
||||
end
|
||||
|
||||
b3.use Provision
|
||||
b3.use SyncFolders
|
||||
# b3.use SyncFolders
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -312,18 +321,25 @@ module VagrantPlugins
|
||||
autoload :MessageNotCreated, action_root.join('message_not_created')
|
||||
autoload :MessageNotRunning, action_root.join('message_not_running')
|
||||
autoload :MessageNotSuspended, action_root.join('message_not_suspended')
|
||||
|
||||
autoload :PrepareNFSSettings, action_root.join('prepare_nfs_settings')
|
||||
autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
|
||||
autoload :PruneNFSExports, action_root.join('prune_nfs_exports')
|
||||
|
||||
autoload :ReadSSHInfo, action_root.join('read_ssh_info')
|
||||
autoload :ReadState, action_root.join('read_state')
|
||||
autoload :ResumeDomain, action_root.join('resume_domain')
|
||||
autoload :SetNameOfDomain, action_root.join('set_name_of_domain')
|
||||
|
||||
# I don't think we need it anymore
|
||||
autoload :ShareFolders, action_root.join('share_folders')
|
||||
autoload :StartDomain, action_root.join('start_domain')
|
||||
autoload :SuspendDomain, action_root.join('suspend_domain')
|
||||
autoload :SyncFolders, action_root.join('sync_folders')
|
||||
autoload :TimedProvision, action_root.join('timed_provision')
|
||||
|
||||
autoload :WaitTillUp, action_root.join('wait_till_up')
|
||||
autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
|
||||
|
||||
autoload :SSHRun, 'vagrant/action/builtin/ssh_run'
|
||||
autoload :HandleBoxUrl, 'vagrant/action/builtin/handle_box_url'
|
||||
autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
|
||||
|
@ -1,66 +0,0 @@
|
||||
require "log4r"
|
||||
require "vagrant/util/subprocess"
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderLibvirt
|
||||
module Action
|
||||
# This middleware uses `rsync` to sync the folders over to the
|
||||
# libvirt domain.
|
||||
class SyncFolders
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant_libvirt::action::sync_folders")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@app.call(env)
|
||||
|
||||
ssh_info = env[:machine].ssh_info
|
||||
|
||||
env[:machine].config.vm.synced_folders.each do |id, data|
|
||||
next unless data[:type] == :rsync
|
||||
proxycommand = "-o ProxyCommand='#{ssh_info[:proxy_command]}'" if ssh_info[:proxy_command]
|
||||
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
||||
guestpath = data[:guestpath]
|
||||
|
||||
# Make sure there is a trailing slash on the host path to
|
||||
# avoid creating an additional directory with rsync
|
||||
hostpath = "#{hostpath}/" if hostpath !~ /\/$/
|
||||
|
||||
env[:ui].info(I18n.t('vagrant_libvirt.rsync_folder',
|
||||
:hostpath => hostpath,
|
||||
:guestpath => guestpath))
|
||||
|
||||
# Create the guest path
|
||||
env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
|
||||
env[:machine].communicate.sudo(
|
||||
"chown #{ssh_info[:username]} '#{guestpath}'")
|
||||
|
||||
# Rsync over to the guest path using the SSH info
|
||||
command = [
|
||||
'rsync', '--del', '--verbose', '--archive', '-z',
|
||||
'--exclude', '.vagrant/',
|
||||
'-e', "ssh -p #{ssh_info[:port]} #{proxycommand} -o StrictHostKeyChecking=no #{ssh_key_options(ssh_info)}",
|
||||
hostpath,
|
||||
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
||||
|
||||
r = Vagrant::Util::Subprocess.execute(*command)
|
||||
if r.exit_code != 0
|
||||
raise Errors::RsyncError,
|
||||
:guestpath => guestpath,
|
||||
:hostpath => hostpath,
|
||||
:stderr => r.stderr
|
||||
end
|
||||
end
|
||||
end
|
||||
private
|
||||
|
||||
def ssh_key_options(ssh_info)
|
||||
# Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
|
||||
Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
38
lib/vagrant-libvirt/cap/mount_p9.rb
Normal file
38
lib/vagrant-libvirt/cap/mount_p9.rb
Normal file
@ -0,0 +1,38 @@
|
||||
require "vagrant/util/retryable"
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderLibvirt
|
||||
module Cap
|
||||
class MountP9
|
||||
extend Vagrant::Util::Retryable
|
||||
|
||||
def self.mount_p9_shared_folder(machine, folders, options)
|
||||
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_tag = name.dup
|
||||
|
||||
mount_opts="-o trans=virtio"
|
||||
mount_opts += ",access=#{options[:owner]}" if options[:owner]
|
||||
mount_opts += ",version=#{options[:version]}" if options[:version]
|
||||
mount_opts += ",#{opts[:mount_options]}" if opts[:mount_options]
|
||||
|
||||
mount_command = "mount -t 9p #{mount_opts} '#{mount_tag}' #{expanded_guest_path}"
|
||||
retryable(:on => Vagrant::Errors::LinuxMountFailed,
|
||||
:tries => 5,
|
||||
:sleep => 3) do
|
||||
machine.communicate.sudo(mount_command,
|
||||
:error_class => Vagrant::Errors::LinuxMountFailed)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
75
lib/vagrant-libvirt/cap/synced_folder.rb
Normal file
75
lib/vagrant-libvirt/cap/synced_folder.rb
Normal file
@ -0,0 +1,75 @@
|
||||
require "log4r"
|
||||
require 'ostruct'
|
||||
|
||||
|
||||
require "vagrant/util/subprocess"
|
||||
require "vagrant/errors"
|
||||
require "vagrant-libvirt/errors"
|
||||
# require_relative "helper"
|
||||
|
||||
module VagrantPlugins
|
||||
module SyncedFolder9p
|
||||
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
||||
include Vagrant::Util
|
||||
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
|
||||
@logger = Log4r::Logger.new("vagrant_libvirt::synced_folders::9p")
|
||||
end
|
||||
|
||||
def usable?(machine, raise_error=false)
|
||||
# TODO check for host support (eg in linux is 9p compiled ?)
|
||||
# and support in Qemu for instance ?
|
||||
machine.provider_name == :libvirt
|
||||
end
|
||||
|
||||
def prepare(machine, folders, opts)
|
||||
|
||||
raise Vagrant::Errors::Error("No libvirt connection") if ProviderLibvirt.libvirt_connection.nil?
|
||||
|
||||
@conn = ProviderLibvirt.libvirt_connection.client
|
||||
|
||||
begin
|
||||
# loop through folders
|
||||
folders.each do |id, folder_opts|
|
||||
folder_opts.merge!({ :accessmode => "passthrough",
|
||||
:readonly => true })
|
||||
# machine.ui.info "================\nMachine id: #{machine.id}Should be mounting folders\n #{id}, opts: #{folder_opts}"
|
||||
|
||||
xml = to_xml('filesystem', folder_opts )
|
||||
# puts "<<<<< XML:\n #{xml}\n >>>>>"
|
||||
@conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
|
||||
|
||||
end
|
||||
rescue => e
|
||||
# machine.ui.error("could not attach device because: #{e}")
|
||||
raise VagrantPlugins::ProviderLibvirt::Errors::AttachDeviceError,:error_message => e.message
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# TODO once up, mount folders
|
||||
def enable(machine, folders, _opts)
|
||||
# Go through each folder and mount
|
||||
machine.ui.info("mounting p9 share in guest")
|
||||
# Only mount folders that have a guest path specified.
|
||||
mount_folders = {}
|
||||
folders.each do |id, opts|
|
||||
mount_folders[id] = opts.dup if opts[:guestpath]
|
||||
end
|
||||
common_opts = {
|
||||
:version => '9p2000.L',
|
||||
}
|
||||
# Mount the actual folder
|
||||
machine.guest.capability(
|
||||
:mount_p9_shared_folder, mount_folders, common_opts)
|
||||
end
|
||||
|
||||
def cleanup(machine, opts)
|
||||
# driver(machine).clear_shared_folders if machine.id && machine.id != ""
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -6,7 +6,7 @@ end
|
||||
|
||||
# This is a sanity check to make sure no one is attempting to install
|
||||
# this into an early Vagrant version.
|
||||
if Vagrant::VERSION < '1.4.0'
|
||||
if Vagrant::VERSION < '1.5.0'
|
||||
raise 'The Vagrant Libvirt plugin is only compatible with Vagrant 1.4+'
|
||||
end
|
||||
|
||||
@ -32,6 +32,17 @@ module VagrantPlugins
|
||||
Provider
|
||||
end
|
||||
|
||||
guest_capability("linux", "mount_p9_shared_folder") do
|
||||
require_relative "cap/mount_p9"
|
||||
Cap::MountP9
|
||||
end
|
||||
|
||||
# We set p9 as high priority (default 10)
|
||||
synced_folder("9p", 20) do
|
||||
require_relative "cap/synced_folder"
|
||||
VagrantPlugins::SyncedFolder9p::SyncedFolder
|
||||
end
|
||||
|
||||
# This initializes the internationalization strings.
|
||||
def self.setup_i18n
|
||||
I18n.load_path << File.expand_path('locales/en.yml',
|
||||
|
8
lib/vagrant-libvirt/templates/filesystem.xml.erb
Normal file
8
lib/vagrant-libvirt/templates/filesystem.xml.erb
Normal file
@ -0,0 +1,8 @@
|
||||
<filesystem type='mount' accessmode='<%= accessmode %>'>
|
||||
<driver type='path' wrpolicy='immediate'/>
|
||||
<source dir='<%= hostpath %>'/>
|
||||
<target dir='<%= guestpath %>'/>
|
||||
<% unless readonly.nil? %>
|
||||
<readonly />
|
||||
<% end %>
|
||||
</filesystem>
|
@ -1,17 +1,21 @@
|
||||
require 'erb'
|
||||
require 'erubis'
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderLibvirt
|
||||
module Util
|
||||
module ErbTemplate
|
||||
|
||||
# Taken from fog source.
|
||||
def to_xml template_name = nil
|
||||
|
||||
# TODO might be a chance to use vagrant template system according to https://github.com/mitchellh/vagrant/issues/3231
|
||||
def to_xml template_name = nil, data = binding
|
||||
erb = template_name || self.class.to_s.split("::").last.downcase
|
||||
path = File.join(File.dirname(__FILE__), "..", "templates",
|
||||
"#{erb}.xml.erb")
|
||||
template = File.read(path)
|
||||
ERB.new(template, nil, '-').result(binding)
|
||||
|
||||
# TODO according to erubis documentation, we should rather use evaluate and forget about
|
||||
# binding since the template may then change variables values
|
||||
Erubis::Eruby.new(template, :trim => true).result(data)
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user