class VagrantPlugins::HostDarwin::Cap::MountSSHFS

Public Class Methods

sshfs_reverse_is_folder_mounted(env, opts) click to toggle source
# File lib/vagrant-sshfs/cap/host/darwin/sshfs_reverse_mount.rb, line 12
def self.sshfs_reverse_is_folder_mounted(env, opts)
  mounted = false
  hostpath = opts[:hostpath].dup
  hostpath.gsub!("'", "'\\\\''")
  hostpath = hostpath.chomp('/') # remove trailing / if exists
  hostpath = File.expand_path(hostpath) # get the absolute path of the file
  mount_cmd = Vagrant::Util::Which.which('mount')
  result = Vagrant::Util::Subprocess.execute(mount_cmd)
  result.stdout.each_line do |line|
    if line.split()[2] == hostpath
      mounted = true
      break
    end
  end
  return mounted
end
sshfs_reverse_mount_folder(env, machine, opts) click to toggle source
# File lib/vagrant-sshfs/cap/host/darwin/sshfs_reverse_mount.rb, line 29
def self.sshfs_reverse_mount_folder(env, machine, opts)
  # opts contains something like:
  #   { :type=>:sshfs,
  #     :guestpath=>"/sharedfolder",
  #     :hostpath=>"/guests/sharedfolder",
  #     :disabled=>false
  #     :ssh_host=>"192.168.1.1"
  #     :ssh_port=>"22"
  #     :ssh_username=>"username"
  #     :ssh_password=>"password"
  #   }
  self.sshfs_mount(machine, opts)
end
sshfs_reverse_unmount_folder(env, machine, opts) click to toggle source
# File lib/vagrant-sshfs/cap/host/darwin/sshfs_reverse_mount.rb, line 43
def self.sshfs_reverse_unmount_folder(env, machine, opts)
  self.sshfs_unmount(machine, opts)
end

Protected Class Methods

sshfs_mount(machine, opts) click to toggle source

Perform a mount by running an sftp-server on the vagrant host and piping stdin/stdout to sshfs running inside the guest

# File lib/vagrant-sshfs/cap/host/darwin/sshfs_reverse_mount.rb, line 51
def self.sshfs_mount(machine, opts)

  sshfs_path = Vagrant::Util::Which.which('sshfs')

  # expand the guest path so we can handle things like "~/vagrant"
  expanded_guest_path = machine.guest.capability(
    :shell_expand_guest_path, opts[:guestpath])

  # Mount path information
  hostpath = opts[:hostpath].dup
  hostpath.gsub!("'", "'\\\\''")

  # Add in some sshfs/fuse options that are common to both mount methods
  opts[:sshfs_opts] = ' -o noauto_cache '# disable caching based on mtime

  # Add in some ssh options that are common to both mount methods
  opts[:ssh_opts] = ' -o StrictHostKeyChecking=no '# prevent yes/no question
  opts[:ssh_opts]+= ' -o ServerAliveInterval=30 '  # send keepalives

  # SSH connection options
  # Note the backslash escapes for IdentityFile - handles spaces in key path
  ssh_opts = opts[:ssh_opts]
  ssh_opts+= ' -o Port=' + machine.ssh_info[:port].to_s
  ssh_opts+= ' -o "IdentityFile=\"' + machine.ssh_info[:private_key_path][0] + '\""'
  ssh_opts+= ' -o UserKnownHostsFile=/dev/null '
  ssh_opts+= ' -F /dev/null ' # Don't pick up options from user's config
  if machine.ssh_info.key?(:private_key_path) and
     machine.ssh_info[:private_key_path] and
     machine.ssh_info[:private_key_path][0]
     # Add IdentityFile since there is one
     # Note the backslash escapes for IdentityFile - handles spaces in key path
    ssh_opts+= ' -o "IdentityFile=\"' + machine.ssh_info[:private_key_path][0] + '\""'
  end

  ssh_opts_append = opts[:ssh_opts_append].to_s # provided by user

  # SSHFS executable options
  sshfs_opts = opts[:sshfs_opts]
  sshfs_opts_append = opts[:sshfs_opts_append].to_s # provided by user

  username = machine.ssh_info[:username]
  host = machine.ssh_info[:host]


  # The sshfs command to mount the guest directory on the host
  sshfs_cmd = "#{sshfs_path} #{ssh_opts} #{ssh_opts_append} "
  sshfs_cmd+= "#{sshfs_opts} #{sshfs_opts_append} "
  sshfs_cmd+= "#{username}@#{host}:#{expanded_guest_path} #{hostpath}"

  # Log some information
  @@logger.debug("sshfs cmd: #{sshfs_cmd}")

  machine.ui.info(I18n.t("vagrant.sshfs.actions.reverse_mounting_folder",
                  hostpath: hostpath, guestpath: expanded_guest_path))

  # Log STDERR to predictable files so that we can inspect them
  # later in case things go wrong. We'll use the machines data
  # directory (i.e. .vagrant/machines/default/virtualbox/) for this
  f1path = machine.data_dir.join('vagrant_sshfs_sshfs_stderr.txt')
  f1 = File.new(f1path, 'w+')

  # Launch sshfs command to mount guest dir into the host
  if Vagrant::Util::Platform.windows?
    # Need to handle Windows differently. Kernel.spawn fails to work,
    # if the shell creating the process is closed.
    # See https://github.com/dustymabe/vagrant-sshfs/issues/31
    Process.create(:command_line => ssh_cmd,
                   :creation_flags => Process::DETACHED_PROCESS,
                   :process_inherit => false,
                   :thread_inherit => true,
                   :startup_info => {:stdin => w2, :stdout => r1, :stderr => f1})
  else
    p1 = spawn(sshfs_cmd,   :out => f1, :err => f1, :pgroup => true, :close_others => true)
    Process.detach(p1) # Detach so process will keep running
  end

  # Check that the mount made it
  mounted = false
  for i in 0..6
    machine.ui.info("Checking Mount..")
    if self.sshfs_reverse_is_folder_mounted(machine, opts)
      mounted = true
      break
    end
    sleep(2)
  end
  if !mounted
    f1.rewind # Seek to beginning of the file
    error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSReverseMountFailed
    raise error_class, sshfs_output: f1.read
  end
  machine.ui.info("Folder Successfully Mounted!")
end
sshfs_unmount(machine, opts) click to toggle source
# File lib/vagrant-sshfs/cap/host/darwin/sshfs_reverse_mount.rb, line 145
def self.sshfs_unmount(machine, opts)
  # opts contains something like:
  #   { :type=>:sshfs,
  #     :guestpath=>"/sharedfolder",
  #     :hostpath=>"/guests/sharedfolder",
  #     :disabled=>false
  #     :ssh_host=>"192.168.1.1"
  #     :ssh_port=>"22"
  #     :ssh_username=>"username"
  #     :ssh_password=>"password"
  #   }

  # Mount path information
  hostpath = opts[:hostpath].dup
  hostpath.gsub!("'", "'\\\\''")

  # Log some information
  machine.ui.info(I18n.t("vagrant.sshfs.actions.reverse_unmounting_folder",
                         hostpath: hostpath))

  # Build up the command and connect
  # on linux it is fusermount -u, on mac it is just umount
  error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSUnmountFailed
  umount_cmd = Vagrant::Util::Which.which('umount')
  cmd = "#{umount_cmd} #{hostpath}"
  result = Vagrant::Util::Subprocess.execute(*cmd.split())
  if result.exit_code != 0
    raise error_class, command: cmd, stdout: result.stdout, stderr: result.stderr
  end
end