vagrant-nfs_guest 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|