Class: Vagrant::Action::VM::NFS

Inherits:
Object
  • Object
show all
Includes:
NFSHelpers
Defined in:
lib/vagrant/action/vm/nfs.rb

Overview

Enables NFS based shared folders. nfsd must already be installed on the host machine, and NFS client must already be installed on the guest machine.

This is a two part process:

  1. Adds an entry to /etc/exports on the host machine using the host class to export the proper folder to the proper machine.
  2. After boot, runs mount on the guest to mount the shared folder.

Instance Method Summary collapse

Methods included from NFSHelpers

#clear_nfs_exports

Constructor Details

#initialize(app, env) ⇒ NFS

Returns a new instance of NFS.



21
22
23
24
25
26
# File 'lib/vagrant/action/vm/nfs.rb', line 21

def initialize(app,env)
  @app = app
  @env = env

  verify_settings if nfs_enabled?
end

Instance Method Details

#call(env) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/vagrant/action/vm/nfs.rb', line 28

def call(env)
  @env = env

  extract_folders

  if !folders.empty?
    prepare_folders
    clear_nfs_exports(env)
    export_folders
  end

  @app.call(env)

  mount_folders if !folders.empty?
end

#export_foldersObject

Uses the host class to export the folders via NFS. This typically involves adding a line to /etc/exports for this VM, but it is up to the host class to define the specific behavior.



106
107
108
109
110
# File 'lib/vagrant/action/vm/nfs.rb', line 106

def export_folders
  @env.ui.info I18n.t("vagrant.actions.vm.nfs.exporting")

  @env["host"].nfs_export(guest_ip, folders)
end

#extract_foldersObject

Removes the NFS enabled shared folders from the configuration, so they will no longer be mounted by the actual shared folder task.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/vagrant/action/vm/nfs.rb', line 56

def extract_folders
  # Load the NFS enabled shared folders
  @folders = @env["config"].vm.shared_folders.inject({}) do |acc, data|
    key, opts = data

    if opts[:nfs]
      # Duplicate the options, set the hostpath, and set disabled on the original
      # options so the ShareFolders middleware doesn't try to mount it.
      acc[key] = opts.dup
      acc[key][:hostpath] = File.expand_path(opts[:hostpath], @env.env.root_path)
      opts[:disabled] = true
    end

    acc
  end
end

#foldersObject

Returns the folders which are to be synced via NFS.



49
50
51
# File 'lib/vagrant/action/vm/nfs.rb', line 49

def folders
  @folders ||= {}
end

#guest_ipString

Returns the IP address of the guest by looking at the first enabled host only network.

Returns:

  • (String)


137
138
139
# File 'lib/vagrant/action/vm/nfs.rb', line 137

def guest_ip
  @env["config"].vm.network_options[1][:ip]
end

#host_ipString

Returns the IP address of the first host only network adapter

Returns:

  • (String)


124
125
126
127
128
129
130
131
# File 'lib/vagrant/action/vm/nfs.rb', line 124

def host_ip
  interface = @env["vm"].vm.network_adapters.find do |adapter|
    adapter.host_interface_object
  end

  return nil if !interface
  interface.host_interface_object.ip_address
end

#mount_foldersObject

Uses the system class to mount the NFS folders.



113
114
115
116
117
118
119
# File 'lib/vagrant/action/vm/nfs.rb', line 113

def mount_folders
  @env.ui.info I18n.t("vagrant.actions.vm.nfs.mounting")

  # Only mount the folders which have a guest path specified
  am_folders = folders.select { |name, folder| folder[:guestpath] }
  @env["vm"].system.mount_nfs(host_ip, Hash[am_folders])
end

#nfs_enabled?Boolean

Checks if there are any NFS enabled shared folders.

Returns:

  • (Boolean)


142
143
144
145
146
147
148
# File 'lib/vagrant/action/vm/nfs.rb', line 142

def nfs_enabled?
  @env["config"].vm.shared_folders.each do |key, opts|
    return true if opts[:nfs]
  end

  false
end

#prepare_foldersObject

Prepares the settings for the NFS folders, such as setting the options on the NFS folders.



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/vagrant/action/vm/nfs.rb', line 75

def prepare_folders
  @folders = @folders.inject({}) do |acc, data|
    key, opts = data
    opts[:nfs] = {} if !opts.is_a?(Hash)
    opts[:map_uid] = prepare_permission(:uid, opts)
    opts[:map_gid] = prepare_permission(:gid, opts)

    acc[key] = opts
    acc
  end
end

#prepare_permission(perm, opts) ⇒ Object

Prepares the UID/GID settings for a single folder.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/vagrant/action/vm/nfs.rb', line 88

def prepare_permission(perm, opts)
  key = "map_#{perm}".to_sym
  return nil if opts.has_key?(key) && opts[key].nil?

  # The options on the hash get priority, then the default
  # values
  value = opts.has_key?(key) ? opts[key] : @env["config"].nfs.send(key)
  return value if value != :auto

  # Get UID/GID from folder if we've made it this far
  # (value == :auto)
  stat = File.stat(opts[:hostpath])
  return stat.send(perm)
end

#recover(env) ⇒ Object



44
45
46
# File 'lib/vagrant/action/vm/nfs.rb', line 44

def recover(env)
  clear_nfs_exports(env) if env["vm"].created?
end

#verify_settingsObject

Verifies that the host is set and supports NFS.



151
152
153
154
155
# File 'lib/vagrant/action/vm/nfs.rb', line 151

def verify_settings
  raise Errors::NFSHostRequired if @env["host"].nil?
  raise Errors::NFSNotSupported if !@env["host"].nfs?
  raise Errors::NFSNoHostNetwork if @env["config"].vm.network_options.empty?
end