vagrant-nfs_guest 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +19 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +3 -0
- data/lib/vagrant-nfs_guest/action/prepare_nfs_guest_settings.rb +99 -0
- data/lib/vagrant-nfs_guest/action/unmount_mounts.rb +20 -0
- data/lib/vagrant-nfs_guest/cap/linux/export_nfs_folders.rb +115 -0
- data/lib/vagrant-nfs_guest/cap/linux/halt.rb +20 -0
- data/lib/vagrant-nfs_guest/cap/linux/read_user_ids.rb +29 -0
- data/lib/vagrant-nfs_guest/config.rb +26 -0
- data/lib/vagrant-nfs_guest/errors.rb +9 -0
- data/lib/vagrant-nfs_guest/hosts/bsd/host.rb +30 -0
- data/lib/vagrant-nfs_guest/hosts/host.rb +23 -0
- data/lib/vagrant-nfs_guest/plugin.rb +60 -0
- data/lib/vagrant-nfs_guest/synced_folder.rb +75 -0
- data/lib/vagrant-nfs_guest/version.rb +5 -0
- data/lib/vagrant-nfs_guest.rb +27 -0
- data/locales/en.yml +6 -0
- data/templates/nfs_guest/guest_export_linux.erb +7 -0
- data/vagrant-nfs_guest.gemspec +23 -0
- metadata +105 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in vagrant-nfs_guest.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
# We depend on Vagrant for development, but we don't add it as a
|
8
|
+
# gem dependency because we expect to be installed within the
|
9
|
+
# Vagrant environment itself using `vagrant plugin`.
|
10
|
+
gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
|
11
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Alan Garfield
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Vagrant-NFS_Guest
|
2
|
+
|
3
|
+
Allows a guest VM to export synced folders via NFS and the host to mount them.
|
4
|
+
|
5
|
+
Basically it's just the usual NFS synced folders in Vagrant but the roles are reversed.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'vagrant-nfs_guest'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install vagrant-nfs_guest
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
To enable for example:
|
24
|
+
|
25
|
+
```config.vm.synced_folder 'srv', '/srv', type: 'nfs_guest'```
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SyncedFolderNFSGuest
|
3
|
+
module Action
|
4
|
+
class PrepareNFSGuestSettings
|
5
|
+
include Vagrant::Util::Retryable
|
6
|
+
|
7
|
+
# This is only required to deal with the hard coded :nfs_host_ip and :nfs_machine_ip symbols
|
8
|
+
# not using the impl name this stops them being availabe in nfsopts because the impl is called
|
9
|
+
# nfs_guest. There has to be a better way.
|
10
|
+
|
11
|
+
def initialize(app,env)
|
12
|
+
@app = app
|
13
|
+
@logger = Log4r::Logger.new("vagrant::action::vm::nfs_guest")
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@machine = env[:machine]
|
18
|
+
@app.call(env)
|
19
|
+
|
20
|
+
if using_nfs?
|
21
|
+
@logger.info("Using NFS_guest, preparing NFS settings by reading host IP and machine IP")
|
22
|
+
add_nfs_settings_to_env!(env)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# We're using NFS if we have any synced folder with NFS configured. If
|
27
|
+
# we are not using NFS we don't need to do the extra work to
|
28
|
+
# populate these fields in the environment.
|
29
|
+
def using_nfs?
|
30
|
+
@machine.config.vm.synced_folders.any? { |_, opts| opts[:type] == :nfs_guest }
|
31
|
+
end
|
32
|
+
|
33
|
+
# Extracts the proper host and guest IPs for NFS mounts and stores them
|
34
|
+
# in the environment for the SyncedFolder action to use them in
|
35
|
+
# mounting.
|
36
|
+
#
|
37
|
+
# The ! indicates that this method modifies its argument.
|
38
|
+
def add_nfs_settings_to_env!(env)
|
39
|
+
adapter, host_ip = find_host_only_adapter
|
40
|
+
machine_ip = nil
|
41
|
+
machine_ip = read_machine_ip(adapter) if adapter
|
42
|
+
|
43
|
+
raise Vagrant::Errors::NFSNoHostonlyNetwork if !host_ip || !machine_ip
|
44
|
+
|
45
|
+
env[:nfs_guest_host_ip] = host_ip
|
46
|
+
env[:nfs_guest_machine_ip] = machine_ip
|
47
|
+
end
|
48
|
+
|
49
|
+
# Finds first host only network adapter and returns its adapter number
|
50
|
+
# and IP address
|
51
|
+
#
|
52
|
+
# @return [Integer, String] adapter number, ip address of found host-only adapter
|
53
|
+
def find_host_only_adapter
|
54
|
+
@machine.provider.driver.read_network_interfaces.each do |adapter, opts|
|
55
|
+
if opts[:type] == :hostonly
|
56
|
+
@machine.provider.driver.read_host_only_interfaces.each do |interface|
|
57
|
+
if interface[:name] == opts[:hostonly]
|
58
|
+
return adapter, interface[:ip]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the IP address of the guest by looking at vbox guest property
|
68
|
+
# for the appropriate guest adapter.
|
69
|
+
#
|
70
|
+
# For DHCP interfaces, the guest property will not be present until the
|
71
|
+
# guest completes
|
72
|
+
#
|
73
|
+
# @param [Integer] adapter number to read IP for
|
74
|
+
# @return [String] ip address of adapter
|
75
|
+
def read_machine_ip(adapter)
|
76
|
+
# vbox guest properties are 0-indexed, while showvminfo network
|
77
|
+
# interfaces are 1-indexed. go figure.
|
78
|
+
guestproperty_adapter = adapter - 1
|
79
|
+
|
80
|
+
# we need to wait for the guest's IP to show up as a guest property.
|
81
|
+
# retry thresholds are relatively high since we might need to wait
|
82
|
+
# for DHCP, but even static IPs can take a second or two to appear.
|
83
|
+
retryable(retry_options.merge(on: Vagrant::Errors::VirtualBoxGuestPropertyNotFound)) do
|
84
|
+
@machine.provider.driver.read_guest_ip(guestproperty_adapter)
|
85
|
+
end
|
86
|
+
rescue Vagrant::Errors::VirtualBoxGuestPropertyNotFound
|
87
|
+
# this error is more specific with a better error message directing
|
88
|
+
# the user towards the fact that it's probably a reportable bug
|
89
|
+
raise Vagrant::Errors::NFSNoGuestIP
|
90
|
+
end
|
91
|
+
|
92
|
+
# Separating these out so we can stub out the sleep in tests
|
93
|
+
def retry_options
|
94
|
+
{tries: 15, sleep: 1}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SyncedFolderNFSGuest
|
3
|
+
module Action
|
4
|
+
class UnmountMounts
|
5
|
+
def initialize(app,env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new("vagrant::action::vm::nfs_guest")
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
@machine = env[:machine]
|
12
|
+
@app.call(env)
|
13
|
+
|
14
|
+
folders = @machine.config.vm.synced_folders
|
15
|
+
@machine.env.host.unmount_nfs_folders(folders)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'vagrant/util/platform'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SyncedFolderNFSGuest
|
5
|
+
module Cap
|
6
|
+
module Linux
|
7
|
+
class ExportNFS
|
8
|
+
include Vagrant::Util
|
9
|
+
|
10
|
+
def self.export_nfs_capable(machine)
|
11
|
+
me = self.new(machine)
|
12
|
+
return me.nfs_capable?
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.export_nfs_folders(machine, ip, folders)
|
16
|
+
me = self.new(machine, ip, folders)
|
17
|
+
|
18
|
+
me.nfs_opts_setup()
|
19
|
+
|
20
|
+
tpl_path = VagrantPlugins::SyncedFolderNFSGuest.source_root.join(
|
21
|
+
'templates/nfs_guest/guest_export_linux')
|
22
|
+
output = TemplateRenderer.render(tpl_path,
|
23
|
+
:uuid => machine.id,
|
24
|
+
:ips => [ip],
|
25
|
+
:folders => folders,
|
26
|
+
:user => Process.uid)
|
27
|
+
|
28
|
+
machine.ui.info I18n.t("vagrant.hosts.linux.nfs_export")
|
29
|
+
sleep 0.5
|
30
|
+
|
31
|
+
me.nfs_cleanup()
|
32
|
+
|
33
|
+
output.split("\n").each do |line|
|
34
|
+
machine.communicate.sudo(%Q[echo '#{line}' >> /etc/exports])
|
35
|
+
end
|
36
|
+
|
37
|
+
me.restart_nfs()
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(machine, ip = [], folders = [])
|
41
|
+
@machine = machine
|
42
|
+
@ip = ip
|
43
|
+
@folders = folders
|
44
|
+
|
45
|
+
@folder_test_command = "test -d"
|
46
|
+
@nfs_test_command = "test -e /etc/exports"
|
47
|
+
@nfs_apply_command = "/usr/sbin/exportfs -r"
|
48
|
+
@nfs_check_command = "/etc/init.d/nfs-kernel-server status"
|
49
|
+
@nfs_start_command = "/etc/init.d/nfs-kernel-server start"
|
50
|
+
end
|
51
|
+
|
52
|
+
def nfs_running?
|
53
|
+
@machine.communicate.test("#{@nfs_check_command}")
|
54
|
+
end
|
55
|
+
|
56
|
+
def nfs_capable?
|
57
|
+
@machine.communicate.test("#{@nfs_test_command}")
|
58
|
+
end
|
59
|
+
|
60
|
+
# TODO - DRY this; ripped completely from plugins/hosts/linux/host.rb
|
61
|
+
def nfs_opts_setup()
|
62
|
+
@folders.each do |k, opts|
|
63
|
+
if !opts[:linux__nfs_options]
|
64
|
+
opts[:linux__nfs_options] ||= ["rw", "no_subtree_check", "all_squash", "insecure"]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Only automatically set anonuid/anongid if they weren't
|
68
|
+
# explicitly set by the user.
|
69
|
+
hasgid = false
|
70
|
+
hasuid = false
|
71
|
+
opts[:linux__nfs_options].each do |opt|
|
72
|
+
hasgid = !!(opt =~ /^anongid=/) if !hasgid
|
73
|
+
hasuid = !!(opt =~ /^anonuid=/) if !hasuid
|
74
|
+
end
|
75
|
+
|
76
|
+
opts[:linux__nfs_options] << "anonuid=#{opts[:map_uid]}" if !hasuid
|
77
|
+
opts[:linux__nfs_options] << "anongid=#{opts[:map_gid]}" if !hasgid
|
78
|
+
opts[:linux__nfs_options] << "fsid=#{opts[:uuid]}"
|
79
|
+
|
80
|
+
# Expand the guest path so we can handle things like "~/vagrant"
|
81
|
+
expanded_guest_path = @machine.guest.capability(
|
82
|
+
:shell_expand_guest_path, opts[:guestpath])
|
83
|
+
|
84
|
+
# Do the actual creating and mounting
|
85
|
+
@machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
|
86
|
+
@machine.communicate.sudo("chgrp -R vagrant #{expanded_guest_path}")
|
87
|
+
@machine.communicate.sudo("chmod g+rw #{expanded_guest_path}")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def nfs_cleanup()
|
92
|
+
return if !nfs_capable?
|
93
|
+
|
94
|
+
id = @machine.id
|
95
|
+
user = Process.uid
|
96
|
+
|
97
|
+
# Use sed to just strip out the block of code which was inserted
|
98
|
+
# by Vagrant
|
99
|
+
@machine.communicate.sudo("sed -r -e '/^# VAGRANT-BEGIN:( #{user})? #{id}/,/^# VAGRANT-END:( #{user})? #{id}/ d' -ibak /etc/exports")
|
100
|
+
end
|
101
|
+
|
102
|
+
def restart_nfs()
|
103
|
+
if nfs_running?
|
104
|
+
@machine.communicate.sudo("#{@nfs_apply_command}")
|
105
|
+
else
|
106
|
+
@machine.communicate.sudo("#{@nfs_start_command}")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require Vagrant.source_root.join("plugins/guests/linux/cap/halt")
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SyncedFolderNFSGuest
|
5
|
+
module Cap
|
6
|
+
module Linux
|
7
|
+
class Halt
|
8
|
+
def self.halt(machine)
|
9
|
+
# unmount any host mounted NFS folders
|
10
|
+
folders = machine.config.vm.synced_folders
|
11
|
+
machine.env.host.unmount_nfs_folders(folders)
|
12
|
+
|
13
|
+
VagrantPlugins::GuestLinux::Cap::Halt.halt(machine)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SyncedFolderNFSGuest
|
3
|
+
module Cap
|
4
|
+
module Linux
|
5
|
+
class ReadUserIDs
|
6
|
+
def self.read_uid(machine)
|
7
|
+
command = "id -u"
|
8
|
+
result = ""
|
9
|
+
machine.communicate.execute(command) do |type, data|
|
10
|
+
result << data if type == :stdout
|
11
|
+
end
|
12
|
+
|
13
|
+
result.chomp.split("\n").first
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.read_gid(machine)
|
17
|
+
command = "id -g"
|
18
|
+
result = ""
|
19
|
+
machine.communicate.execute(command) do |type, data|
|
20
|
+
result << data if type == :stdout
|
21
|
+
end
|
22
|
+
|
23
|
+
result.chomp.split("\n").first
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "vagrant"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SyncedFolderNFSGuest
|
5
|
+
class Config < Vagrant.plugin("2", :config)
|
6
|
+
attr_accessor :map_uid
|
7
|
+
attr_accessor :map_gid
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
|
12
|
+
@map_uid = UNSET_VALUE
|
13
|
+
@map_gid = UNSET_VALUE
|
14
|
+
end
|
15
|
+
|
16
|
+
def finalize!
|
17
|
+
@map_uid = nil if @map_uid == UNSET_VALUE
|
18
|
+
@map_gid = nil if @map_gid == UNSET_VALUE
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"NFS_Guest"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module HostBSD
|
3
|
+
class Host < Vagrant.plugin("2", :host)
|
4
|
+
def mount_nfs_folders(id, ips, folders)
|
5
|
+
@logger.debug "Mounting NFS mounts..."
|
6
|
+
folders.each do |name, opts|
|
7
|
+
@logger.info opts
|
8
|
+
ips.each do |ip|
|
9
|
+
system("mkdir -p #{opts[:hostpath]}")
|
10
|
+
mount_command = "mount -t nfs -o noatime '#{ip}:#{opts[:guestpath]}' '#{opts[:hostpath]}'"
|
11
|
+
if system(mount_command)
|
12
|
+
break
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def unmount_nfs_folders(folders)
|
19
|
+
@logger.debug "Unmounting NFS mounts..."
|
20
|
+
folders.each do |name, opts|
|
21
|
+
if opts[:type] == :nfs_guest
|
22
|
+
expanded_host_path = `printf #{opts[:hostpath]}`
|
23
|
+
system("umount '#{expanded_host_path}'")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Plugin
|
3
|
+
module V2
|
4
|
+
class Host
|
5
|
+
# Mounts the given hash of folders via the guests NFS export
|
6
|
+
#
|
7
|
+
# @param [String] id A unique ID that is guaranteed to be unique to
|
8
|
+
# match these sets of folders.
|
9
|
+
# @param [Array<String>] ip IPs of the guest machine.
|
10
|
+
# @param [Hash] folders Shared folders to sync.
|
11
|
+
def mount_nfs_folders(id, ips, folders)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Unmounts the given hash of folders
|
15
|
+
#
|
16
|
+
# @param [Hash] folders Shared folders to sync.
|
17
|
+
def unmount_nfs_folders(folders)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path("../hosts/host", __FILE__)
|
2
|
+
require File.expand_path("../hosts/bsd/host", __FILE__)
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module SyncedFolderNFSGuest
|
6
|
+
class Plugin < Vagrant.plugin("2")
|
7
|
+
name "vagrant-nfs_guest"
|
8
|
+
description <<-DESC
|
9
|
+
Adds support for guest nfs exporting of synced folders
|
10
|
+
DESC
|
11
|
+
|
12
|
+
config(:nfs_guest) do
|
13
|
+
require File.expand_path("../config", __FILE__)
|
14
|
+
Config
|
15
|
+
end
|
16
|
+
|
17
|
+
synced_folder(:nfs_guest, 4) do
|
18
|
+
require File.expand_path("../synced_folder", __FILE__)
|
19
|
+
SyncedFolder
|
20
|
+
end
|
21
|
+
|
22
|
+
guest_capability(:linux, :export_nfs_folders) do
|
23
|
+
require File.expand_path("../cap/linux/export_nfs_folders", __FILE__)
|
24
|
+
Cap::Linux::ExportNFS
|
25
|
+
end
|
26
|
+
|
27
|
+
guest_capability(:linux, :export_nfs_capable) do
|
28
|
+
require File.expand_path("../cap/linux/export_nfs_folders", __FILE__)
|
29
|
+
Cap::Linux::ExportNFS
|
30
|
+
end
|
31
|
+
|
32
|
+
guest_capability(:linux, :read_uid) do
|
33
|
+
require File.expand_path("../cap/linux/read_user_ids", __FILE__)
|
34
|
+
Cap::Linux::ReadUserIDs
|
35
|
+
end
|
36
|
+
|
37
|
+
guest_capability(:linux, :read_gid) do
|
38
|
+
require File.expand_path("../cap/linux/read_user_ids", __FILE__)
|
39
|
+
Cap::Linux::ReadUserIDs
|
40
|
+
end
|
41
|
+
|
42
|
+
guest_capability(:linux, :halt) do
|
43
|
+
require File.expand_path("../cap/linux/halt", __FILE__)
|
44
|
+
Cap::Linux::Halt
|
45
|
+
end
|
46
|
+
|
47
|
+
require File.expand_path("../action/prepare_nfs_guest_settings", __FILE__)
|
48
|
+
action_hook(:nfs_guest, :machine_action_up) do |hook|
|
49
|
+
hook.before(VagrantPlugins::ProviderVirtualBox::Action::PrepareNFSSettings,
|
50
|
+
Action::PrepareNFSGuestSettings)
|
51
|
+
end
|
52
|
+
|
53
|
+
require File.expand_path("../action/unmount_mounts", __FILE__)
|
54
|
+
action_hook(:nfs_guest, :machine_action_destroy) do |hook|
|
55
|
+
hook.after(Vagrant::Action::Builtin::DestroyConfirm,
|
56
|
+
Action::UnmountMounts)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SyncedFolderNFSGuest
|
5
|
+
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
6
|
+
def usable?(machine)
|
7
|
+
# NFS is always available
|
8
|
+
true
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare(machine, folders, opts)
|
12
|
+
# Nothing is necessary to do before VM boot.
|
13
|
+
end
|
14
|
+
|
15
|
+
def enable(machine, folders, nfsopts)
|
16
|
+
raise Vagrant::Errors::NFSNoHostIP if !nfsopts[:nfs_guest_host_ip]
|
17
|
+
raise Vagrant::Errors::NFSNoGuestIP if !nfsopts[:nfs_guest_machine_ip]
|
18
|
+
|
19
|
+
if !machine.guest.capability(:export_nfs_capable)
|
20
|
+
raise VagrantPlugins::SyncedFolderNFSGuest::Error, :no_nfsd
|
21
|
+
end
|
22
|
+
|
23
|
+
machine_ip = nfsopts[:nfs_guest_machine_ip]
|
24
|
+
machine_ip = [machine_ip] if !machine_ip.is_a?(Array)
|
25
|
+
|
26
|
+
# Prepare the folder, this means setting up various options
|
27
|
+
# and such on the folder itself.
|
28
|
+
folders.each { |id, opts| prepare_folder(machine, opts) }
|
29
|
+
|
30
|
+
# Only mount folders that have a guest path specified.
|
31
|
+
mount_folders = {}
|
32
|
+
folders.each do |id, opts|
|
33
|
+
mount_folders[id] = opts.dup if opts[:guestpath]
|
34
|
+
end
|
35
|
+
|
36
|
+
machine.ui.info I18n.t("vagrant.actions.vm.nfs.exporting")
|
37
|
+
machine.guest.capability(
|
38
|
+
:export_nfs_folders, nfsopts[:nfs_guest_host_ip], mount_folders)
|
39
|
+
|
40
|
+
machine.ui.info I18n.t("vagrant.actions.vm.nfs.mounting")
|
41
|
+
machine.env.host.mount_nfs_folders(
|
42
|
+
machine.id, machine_ip, mount_folders)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def prepare_folder(machine, opts)
|
48
|
+
opts[:map_uid] = prepare_permission(machine, :uid, opts)
|
49
|
+
opts[:map_gid] = prepare_permission(machine, :gid, opts)
|
50
|
+
opts[:nfs_udp] = true if !opts.has_key?(:nfs_udp)
|
51
|
+
opts[:nfs_version] ||= 3
|
52
|
+
|
53
|
+
# We use a CRC32 to generate a 32-bit checksum so that the
|
54
|
+
# fsid is compatible with both old and new kernels.
|
55
|
+
opts[:uuid] = Zlib.crc32(opts[:hostpath]).to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
# Prepares the UID/GID settings for a single folder.
|
59
|
+
def prepare_permission(machine, perm, opts)
|
60
|
+
key = "map_#{perm}".to_sym
|
61
|
+
return nil if opts.has_key?(key) && opts[key].nil?
|
62
|
+
|
63
|
+
# The options on the hash get priority, then the default
|
64
|
+
# values
|
65
|
+
value = opts.has_key?(key) ? opts[key] : machine.config.nfs.send(key)
|
66
|
+
return value if value != :auto
|
67
|
+
|
68
|
+
# Get UID/GID from guests user if we've made it this far
|
69
|
+
# (value == :auto)
|
70
|
+
return machine.guest.capability("read_#{perm}".to_sym)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require "vagrant"
|
3
|
+
rescue LoadError
|
4
|
+
raise "The Vagrant nfs_guest plugin must be run within Vagrant."
|
5
|
+
end
|
6
|
+
|
7
|
+
# This is a sanity check to make sure no one is attempting to install
|
8
|
+
# this into an early Vagrant version.
|
9
|
+
if Vagrant::VERSION < "1.4.0"
|
10
|
+
raise "The Vagrant nfs_guest plugin is only compatible with Vagrant 1.4+"
|
11
|
+
end
|
12
|
+
|
13
|
+
require "vagrant-nfs_guest/plugin"
|
14
|
+
require 'vagrant-nfs_guest/errors'
|
15
|
+
|
16
|
+
require "pathname"
|
17
|
+
|
18
|
+
module VagrantPlugins
|
19
|
+
module SyncedFolderNFSGuest
|
20
|
+
def self.source_root
|
21
|
+
@source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
|
22
|
+
end
|
23
|
+
|
24
|
+
I18n.load_path << File.expand_path('locales/en.yml', source_root)
|
25
|
+
I18n.reload!
|
26
|
+
end
|
27
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'vagrant-nfs_guest/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "vagrant-nfs_guest"
|
8
|
+
spec.version = VagrantPlugins::SyncedFolderNFSGuest::VERSION
|
9
|
+
spec.authors = ["Alan Garfield"]
|
10
|
+
spec.email = ["alan.garfield@learnosity.com"]
|
11
|
+
spec.description = %q{Adds support for guest nfs exporting of synced folders}
|
12
|
+
spec.summary = %q{Adds support for guest nfs exporting of synced folders}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-nfs_guest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alan Garfield
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Adds support for guest nfs exporting of synced folders
|
47
|
+
email:
|
48
|
+
- alan.garfield@learnosity.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/vagrant-nfs_guest.rb
|
59
|
+
- lib/vagrant-nfs_guest/action/prepare_nfs_guest_settings.rb
|
60
|
+
- lib/vagrant-nfs_guest/action/unmount_mounts.rb
|
61
|
+
- lib/vagrant-nfs_guest/cap/linux/export_nfs_folders.rb
|
62
|
+
- lib/vagrant-nfs_guest/cap/linux/halt.rb
|
63
|
+
- lib/vagrant-nfs_guest/cap/linux/read_user_ids.rb
|
64
|
+
- lib/vagrant-nfs_guest/config.rb
|
65
|
+
- lib/vagrant-nfs_guest/errors.rb
|
66
|
+
- lib/vagrant-nfs_guest/hosts/bsd/host.rb
|
67
|
+
- lib/vagrant-nfs_guest/hosts/host.rb
|
68
|
+
- lib/vagrant-nfs_guest/plugin.rb
|
69
|
+
- lib/vagrant-nfs_guest/synced_folder.rb
|
70
|
+
- lib/vagrant-nfs_guest/version.rb
|
71
|
+
- locales/en.yml
|
72
|
+
- templates/nfs_guest/guest_export_linux.erb
|
73
|
+
- vagrant-nfs_guest.gemspec
|
74
|
+
homepage: ''
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
hash: -1357282251529375209
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
hash: -1357282251529375209
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.23
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Adds support for guest nfs exporting of synced folders
|
105
|
+
test_files: []
|