vagrant-sshfs 1.1.0 → 1.2.0
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.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/Gemfile +4 -1
- data/README.md +82 -21
- data/Rakefile +37 -1
- data/features/README.md +21 -0
- data/features/sshfs_cwd_mount.feature +46 -0
- data/features/step_definitions/sshfs_cwd_mount_steps.rb +12 -0
- data/features/support/env.rb +27 -0
- data/lib/vagrant-sshfs/cap/{arch → guest/arch}/sshfs_client.rb +0 -0
- data/lib/vagrant-sshfs/cap/{debian → guest/debian}/sshfs_client.rb +0 -0
- data/lib/vagrant-sshfs/cap/{fedora → guest/fedora}/sshfs_client.rb +0 -0
- data/lib/vagrant-sshfs/cap/{linux → guest/linux}/sshfs_client.rb +0 -0
- data/lib/vagrant-sshfs/cap/{linux/sshfs_mount.rb → guest/linux/sshfs_forward_mount.rb} +124 -14
- data/lib/vagrant-sshfs/cap/{redhat → guest/redhat}/sshfs_client.rb +0 -0
- data/lib/vagrant-sshfs/cap/{suse → guest/suse}/sshfs_client.rb +0 -0
- data/lib/vagrant-sshfs/cap/host/linux/sshfs_reverse_mount.rb +176 -0
- data/lib/vagrant-sshfs/command.rb +16 -4
- data/lib/vagrant-sshfs/errors.rb +8 -0
- data/lib/vagrant-sshfs/plugin.rb +35 -15
- data/lib/vagrant-sshfs/synced_folder/sshfs_forward_mount.rb +116 -0
- data/lib/vagrant-sshfs/synced_folder/sshfs_reverse_mount.rb +51 -0
- data/lib/vagrant-sshfs/synced_folder.rb +43 -83
- data/lib/vagrant-sshfs/version.rb +1 -1
- data/lib/vagrant-sshfs.rb +8 -0
- data/locales/synced_folder_sshfs.yml +42 -5
- data/test/libvirt/README.txt +15 -0
- data/test/libvirt/Vagrantfile +35 -0
- data/test/misc/README.txt +29 -0
- data/test/misc/Vagrantfile +27 -0
- data/test/misc/dotests.sh +13 -0
- data/test/virtualbox/README.txt +17 -0
- data/test/virtualbox/Vagrantfile +42 -0
- data/vagrant-sshfs.gemspec +7 -2
- metadata +93 -11
@@ -0,0 +1,176 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "vagrant/util/retryable"
|
3
|
+
require "tempfile"
|
4
|
+
|
5
|
+
# This is already done for us in lib/vagrant-sshfs.rb. We needed to
|
6
|
+
# do it there before Process.uid is called the first time by Vagrant
|
7
|
+
# This provides a new Process.create() that works on Windows.
|
8
|
+
if Vagrant::Util::Platform.windows?
|
9
|
+
require 'win32/process'
|
10
|
+
end
|
11
|
+
|
12
|
+
module VagrantPlugins
|
13
|
+
module HostLinux
|
14
|
+
module Cap
|
15
|
+
class MountSSHFS
|
16
|
+
extend Vagrant::Util::Retryable
|
17
|
+
@@logger = Log4r::Logger.new("vagrant::synced_folders::sshfs_reverse_mount")
|
18
|
+
|
19
|
+
def self.sshfs_reverse_is_folder_mounted(env, opts)
|
20
|
+
mounted = false
|
21
|
+
hostpath = opts[:hostpath].dup
|
22
|
+
hostpath.gsub!("'", "'\\\\''")
|
23
|
+
hostpath = hostpath.chomp('/') # remove trailing / if exists
|
24
|
+
cat_cmd = Vagrant::Util::Which.which('cat')
|
25
|
+
result = Vagrant::Util::Subprocess.execute(cat_cmd, '/proc/mounts')
|
26
|
+
mounts = File.open('/proc/mounts', 'r')
|
27
|
+
mounts.each_line do |line|
|
28
|
+
if line.split()[1] == hostpath
|
29
|
+
mounted = true
|
30
|
+
break
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return mounted
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.sshfs_reverse_mount_folder(env, machine, opts)
|
37
|
+
# opts contains something like:
|
38
|
+
# { :type=>:sshfs,
|
39
|
+
# :guestpath=>"/sharedfolder",
|
40
|
+
# :hostpath=>"/guests/sharedfolder",
|
41
|
+
# :disabled=>false
|
42
|
+
# :ssh_host=>"192.168.1.1"
|
43
|
+
# :ssh_port=>"22"
|
44
|
+
# :ssh_username=>"username"
|
45
|
+
# :ssh_password=>"password"
|
46
|
+
# }
|
47
|
+
self.sshfs_mount(machine, opts)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.sshfs_reverse_unmount_folder(env, machine, opts)
|
51
|
+
self.sshfs_unmount(machine, opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
# Perform a mount by running an sftp-server on the vagrant host
|
57
|
+
# and piping stdin/stdout to sshfs running inside the guest
|
58
|
+
def self.sshfs_mount(machine, opts)
|
59
|
+
|
60
|
+
sshfs_path = Vagrant::Util::Which.which('sshfs')
|
61
|
+
|
62
|
+
# expand the guest path so we can handle things like "~/vagrant"
|
63
|
+
expanded_guest_path = machine.guest.capability(
|
64
|
+
:shell_expand_guest_path, opts[:guestpath])
|
65
|
+
|
66
|
+
# Mount path information
|
67
|
+
hostpath = opts[:hostpath].dup
|
68
|
+
hostpath.gsub!("'", "'\\\\''")
|
69
|
+
|
70
|
+
# Add in some sshfs/fuse options that are common to both mount methods
|
71
|
+
opts[:sshfs_opts] = ' -o noauto_cache '# disable caching based on mtime
|
72
|
+
|
73
|
+
# Add in some ssh options that are common to both mount methods
|
74
|
+
opts[:ssh_opts] = ' -o StrictHostKeyChecking=no '# prevent yes/no question
|
75
|
+
opts[:ssh_opts]+= ' -o ServerAliveInterval=30 ' # send keepalives
|
76
|
+
|
77
|
+
# SSH connection options
|
78
|
+
ssh_opts = opts[:ssh_opts]
|
79
|
+
ssh_opts+= ' -o Port=' + machine.ssh_info[:port].to_s
|
80
|
+
ssh_opts+= ' -o IdentityFile=' + machine.ssh_info[:private_key_path][0]
|
81
|
+
ssh_opts+= ' -o UserKnownHostsFile=/dev/null '
|
82
|
+
ssh_opts+= ' -F /dev/null ' # Don't pick up options from user's config
|
83
|
+
|
84
|
+
ssh_opts_append = opts[:ssh_opts_append].to_s # provided by user
|
85
|
+
|
86
|
+
# SSHFS executable options
|
87
|
+
sshfs_opts = opts[:sshfs_opts]
|
88
|
+
sshfs_opts_append = opts[:sshfs_opts_append].to_s # provided by user
|
89
|
+
|
90
|
+
username = machine.ssh_info[:username]
|
91
|
+
host = machine.ssh_info[:host]
|
92
|
+
|
93
|
+
|
94
|
+
# The sshfs command to mount the guest directory on the host
|
95
|
+
sshfs_cmd = "#{sshfs_path} #{ssh_opts} #{ssh_opts_append} "
|
96
|
+
sshfs_cmd+= "#{sshfs_opts} #{sshfs_opts_append} "
|
97
|
+
sshfs_cmd+= "#{username}@#{host}:#{expanded_guest_path} #{hostpath}"
|
98
|
+
|
99
|
+
# Log some information
|
100
|
+
@@logger.debug("sshfs cmd: #{sshfs_cmd}")
|
101
|
+
|
102
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.reverse_mounting_folder",
|
103
|
+
hostpath: hostpath, guestpath: expanded_guest_path))
|
104
|
+
|
105
|
+
# Log STDERR to predictable files so that we can inspect them
|
106
|
+
# later in case things go wrong. We'll use the machines data
|
107
|
+
# directory (i.e. .vagrant/machines/default/virtualbox/) for this
|
108
|
+
f1path = machine.data_dir.join('vagrant_sshfs_sshfs_stderr.txt')
|
109
|
+
f1 = File.new(f1path, 'w+')
|
110
|
+
|
111
|
+
# Launch sshfs command to mount guest dir into the host
|
112
|
+
if Vagrant::Util::Platform.windows?
|
113
|
+
# Need to handle Windows differently. Kernel.spawn fails to work,
|
114
|
+
# if the shell creating the process is closed.
|
115
|
+
# See https://github.com/dustymabe/vagrant-sshfs/issues/31
|
116
|
+
Process.create(:command_line => ssh_cmd,
|
117
|
+
:creation_flags => Process::DETACHED_PROCESS,
|
118
|
+
:process_inherit => false,
|
119
|
+
:thread_inherit => true,
|
120
|
+
:startup_info => {:stdin => w2, :stdout => r1, :stderr => f1})
|
121
|
+
else
|
122
|
+
p1 = spawn(sshfs_cmd, :out => f1, :err => f1, :pgroup => true)
|
123
|
+
Process.detach(p1) # Detach so process will keep running
|
124
|
+
end
|
125
|
+
|
126
|
+
# Check that the mount made it
|
127
|
+
mounted = false
|
128
|
+
for i in 0..6
|
129
|
+
machine.ui.info("Checking Mount..")
|
130
|
+
if self.sshfs_reverse_is_folder_mounted(machine, opts)
|
131
|
+
mounted = true
|
132
|
+
break
|
133
|
+
end
|
134
|
+
sleep(2)
|
135
|
+
end
|
136
|
+
if !mounted
|
137
|
+
f1.rewind # Seek to beginning of the file
|
138
|
+
error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSReverseMountFailed
|
139
|
+
raise error_class, sshfs_output: f1.read
|
140
|
+
end
|
141
|
+
machine.ui.info("Folder Successfully Mounted!")
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.sshfs_unmount(machine, opts)
|
145
|
+
# opts contains something like:
|
146
|
+
# { :type=>:sshfs,
|
147
|
+
# :guestpath=>"/sharedfolder",
|
148
|
+
# :hostpath=>"/guests/sharedfolder",
|
149
|
+
# :disabled=>false
|
150
|
+
# :ssh_host=>"192.168.1.1"
|
151
|
+
# :ssh_port=>"22"
|
152
|
+
# :ssh_username=>"username"
|
153
|
+
# :ssh_password=>"password"
|
154
|
+
# }
|
155
|
+
|
156
|
+
# Mount path information
|
157
|
+
hostpath = opts[:hostpath].dup
|
158
|
+
hostpath.gsub!("'", "'\\\\''")
|
159
|
+
|
160
|
+
# Log some information
|
161
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.reverse_unmounting_folder",
|
162
|
+
hostpath: hostpath))
|
163
|
+
|
164
|
+
# Build up the command and connect
|
165
|
+
error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSUnmountFailed
|
166
|
+
fusermount_cmd = Vagrant::Util::Which.which('fusermount')
|
167
|
+
cmd = "#{fusermount_cmd} -u #{hostpath}"
|
168
|
+
result = Vagrant::Util::Subprocess.execute(*cmd.split())
|
169
|
+
if result.exit_code != 0
|
170
|
+
raise error_class, command: cmd, stdout: result.stdout, stderr: result.stderr
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -10,11 +10,19 @@ module VagrantPlugins
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def execute
|
13
|
+
options = {:unmount => false} # Default to mounting shares
|
13
14
|
opts = OptionParser.new do |o|
|
14
|
-
o.banner = "Usage: vagrant sshfs"
|
15
|
+
o.banner = "Usage: vagrant sshfs [--mount|--unmount] [vm-name]"
|
15
16
|
o.separator ""
|
16
|
-
o.separator "Mount
|
17
|
+
o.separator "Mount or unmount sshfs synced folders into the vagrant box"
|
17
18
|
o.separator ""
|
19
|
+
|
20
|
+
o.on("--mount", "Mount folders - the default") do
|
21
|
+
options[:unmount] = false
|
22
|
+
end
|
23
|
+
o.on("--unmount", "Unmount folders") do
|
24
|
+
options[:unmount] = true
|
25
|
+
end
|
18
26
|
end
|
19
27
|
|
20
28
|
# Parse the options and return if we don't have any target.
|
@@ -36,8 +44,12 @@ module VagrantPlugins
|
|
36
44
|
folders = synced_folders(machine, cached: false)[:sshfs]
|
37
45
|
next if !folders || folders.empty?
|
38
46
|
|
39
|
-
#
|
40
|
-
|
47
|
+
# Mount or Unmount depending on the user's request
|
48
|
+
if options[:unmount]
|
49
|
+
SyncedFolder.new.disable(machine, folders, {})
|
50
|
+
else
|
51
|
+
SyncedFolder.new.enable(machine, folders, {})
|
52
|
+
end
|
41
53
|
end
|
42
54
|
return error ? 1 : 0
|
43
55
|
end
|
data/lib/vagrant-sshfs/errors.rb
CHANGED
@@ -14,6 +14,14 @@ module VagrantPlugins
|
|
14
14
|
error_key(:slave_mount_failed)
|
15
15
|
end
|
16
16
|
|
17
|
+
class SSHFSReverseMountFailed < SSHFSError
|
18
|
+
error_key(:reverse_mount_failed)
|
19
|
+
end
|
20
|
+
|
21
|
+
class SSHFSUnmountFailed < SSHFSError
|
22
|
+
error_key(:unmount_failed)
|
23
|
+
end
|
24
|
+
|
17
25
|
class SSHFSInstallFailed < SSHFSError
|
18
26
|
error_key(:install_failed)
|
19
27
|
end
|
data/lib/vagrant-sshfs/plugin.rb
CHANGED
@@ -15,68 +15,88 @@ module VagrantPlugins
|
|
15
15
|
SyncedFolder
|
16
16
|
end
|
17
17
|
|
18
|
-
command("sshfs", primary:
|
18
|
+
command("sshfs", primary: true) do
|
19
19
|
require_relative "command"
|
20
20
|
Command::SSHFS
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
require_relative "cap/linux/
|
23
|
+
host_capability("linux", "sshfs_reverse_mount_folder") do
|
24
|
+
require_relative "cap/host/linux/sshfs_reverse_mount"
|
25
|
+
VagrantPlugins::HostLinux::Cap::MountSSHFS
|
26
|
+
end
|
27
|
+
|
28
|
+
host_capability("linux", "sshfs_reverse_unmount_folder") do
|
29
|
+
require_relative "cap/host/linux/sshfs_reverse_mount"
|
30
|
+
VagrantPlugins::HostLinux::Cap::MountSSHFS
|
31
|
+
end
|
32
|
+
|
33
|
+
host_capability("linux", "sshfs_reverse_is_folder_mounted") do
|
34
|
+
require_relative "cap/host/linux/sshfs_reverse_mount"
|
35
|
+
VagrantPlugins::HostLinux::Cap::MountSSHFS
|
36
|
+
end
|
37
|
+
|
38
|
+
guest_capability("linux", "sshfs_forward_mount_folder") do
|
39
|
+
require_relative "cap/guest/linux/sshfs_forward_mount"
|
40
|
+
VagrantPlugins::GuestLinux::Cap::MountSSHFS
|
41
|
+
end
|
42
|
+
|
43
|
+
guest_capability("linux", "sshfs_forward_unmount_folder") do
|
44
|
+
require_relative "cap/guest/linux/sshfs_forward_mount"
|
25
45
|
VagrantPlugins::GuestLinux::Cap::MountSSHFS
|
26
46
|
end
|
27
47
|
|
28
|
-
guest_capability("linux", "
|
29
|
-
require_relative "cap/linux/
|
48
|
+
guest_capability("linux", "sshfs_forward_is_folder_mounted") do
|
49
|
+
require_relative "cap/guest/linux/sshfs_forward_mount"
|
30
50
|
VagrantPlugins::GuestLinux::Cap::MountSSHFS
|
31
51
|
end
|
32
52
|
|
33
53
|
guest_capability("redhat", "sshfs_installed") do
|
34
|
-
require_relative "cap/redhat/sshfs_client"
|
54
|
+
require_relative "cap/guest/redhat/sshfs_client"
|
35
55
|
VagrantPlugins::GuestRedHat::Cap::SSHFSClient
|
36
56
|
end
|
37
57
|
|
38
58
|
guest_capability("redhat", "sshfs_install") do
|
39
|
-
require_relative "cap/redhat/sshfs_client"
|
59
|
+
require_relative "cap/guest/redhat/sshfs_client"
|
40
60
|
VagrantPlugins::GuestRedHat::Cap::SSHFSClient
|
41
61
|
end
|
42
62
|
|
43
63
|
guest_capability("fedora", "sshfs_installed") do
|
44
|
-
require_relative "cap/fedora/sshfs_client"
|
64
|
+
require_relative "cap/guest/fedora/sshfs_client"
|
45
65
|
VagrantPlugins::GuestFedora::Cap::SSHFSClient
|
46
66
|
end
|
47
67
|
|
48
68
|
guest_capability("fedora", "sshfs_install") do
|
49
|
-
require_relative "cap/fedora/sshfs_client"
|
69
|
+
require_relative "cap/guest/fedora/sshfs_client"
|
50
70
|
VagrantPlugins::GuestFedora::Cap::SSHFSClient
|
51
71
|
end
|
52
72
|
|
53
73
|
guest_capability("debian", "sshfs_installed") do
|
54
|
-
require_relative "cap/debian/sshfs_client"
|
74
|
+
require_relative "cap/guest/debian/sshfs_client"
|
55
75
|
VagrantPlugins::GuestDebian::Cap::SSHFSClient
|
56
76
|
end
|
57
77
|
|
58
78
|
guest_capability("debian", "sshfs_install") do
|
59
|
-
require_relative "cap/debian/sshfs_client"
|
79
|
+
require_relative "cap/guest/debian/sshfs_client"
|
60
80
|
VagrantPlugins::GuestDebian::Cap::SSHFSClient
|
61
81
|
end
|
62
82
|
|
63
83
|
guest_capability("arch", "sshfs_installed") do
|
64
|
-
require_relative "cap/arch/sshfs_client"
|
84
|
+
require_relative "cap/guest/arch/sshfs_client"
|
65
85
|
VagrantPlugins::GuestArch::Cap::SSHFSClient
|
66
86
|
end
|
67
87
|
|
68
88
|
guest_capability("arch", "sshfs_install") do
|
69
|
-
require_relative "cap/arch/sshfs_client"
|
89
|
+
require_relative "cap/guest/arch/sshfs_client"
|
70
90
|
VagrantPlugins::GuestArch::Cap::SSHFSClient
|
71
91
|
end
|
72
92
|
|
73
93
|
guest_capability("suse", "sshfs_installed") do
|
74
|
-
require_relative "cap/suse/sshfs_client"
|
94
|
+
require_relative "cap/guest/suse/sshfs_client"
|
75
95
|
VagrantPlugins::GuestSUSE::Cap::SSHFSClient
|
76
96
|
end
|
77
97
|
|
78
98
|
guest_capability("suse", "sshfs_install") do
|
79
|
-
require_relative "cap/suse/sshfs_client"
|
99
|
+
require_relative "cap/guest/suse/sshfs_client"
|
80
100
|
VagrantPlugins::GuestSUSE::Cap::SSHFSClient
|
81
101
|
end
|
82
102
|
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require "vagrant/util/platform"
|
4
|
+
require "vagrant/util/which"
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module SyncedFolderSSHFS
|
8
|
+
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
# Do a forward mount: mounting host folder into the guest
|
13
|
+
def do_forward_mount(machine, opts)
|
14
|
+
|
15
|
+
# Check to see if sshfs software is in the guest
|
16
|
+
if machine.guest.capability?(:sshfs_installed)
|
17
|
+
if !machine.guest.capability(:sshfs_installed)
|
18
|
+
can_install = machine.guest.capability?(:sshfs_install)
|
19
|
+
if !can_install
|
20
|
+
raise VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSNotInstalledInGuest
|
21
|
+
end
|
22
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.installing"))
|
23
|
+
machine.guest.capability(:sshfs_install)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# If already mounted then there is nothing to do
|
28
|
+
if machine.guest.capability(:sshfs_forward_is_folder_mounted, opts)
|
29
|
+
machine.ui.info(
|
30
|
+
I18n.t("vagrant.sshfs.info.already_mounted",
|
31
|
+
location: 'guest', folder: opts[:guestpath]))
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
# If the synced folder entry has host information in it then
|
36
|
+
# assume we are doing a normal sshfs mount to a host that isn't
|
37
|
+
# the machine running vagrant. Rely on password/ssh keys.
|
38
|
+
#
|
39
|
+
# If not, then we are doing a slave mount and we need to
|
40
|
+
# make sure we can find the sftp-server and ssh execuatable
|
41
|
+
# files on the host.
|
42
|
+
if opts.has_key?(:ssh_host) and opts[:ssh_host]
|
43
|
+
# Check port information and find out auth info
|
44
|
+
check_host_port(machine, opts)
|
45
|
+
get_auth_info(machine, opts)
|
46
|
+
else
|
47
|
+
opts[:ssh_exe_path] = find_executable('ssh')
|
48
|
+
opts[:sftp_server_exe_path] = find_executable('sftp-server')
|
49
|
+
end
|
50
|
+
# Do the mount
|
51
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.mounting"))
|
52
|
+
machine.guest.capability(:sshfs_forward_mount_folder, opts)
|
53
|
+
end
|
54
|
+
|
55
|
+
def do_forward_unmount(machine, opts)
|
56
|
+
|
57
|
+
# If not mounted then there is nothing to do
|
58
|
+
if ! machine.guest.capability(:sshfs_forward_is_folder_mounted, opts)
|
59
|
+
machine.ui.info(
|
60
|
+
I18n.t("vagrant.sshfs.info.not_mounted",
|
61
|
+
location: 'guest', folder: opts[:guestpath]))
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
# Do the Unmount
|
66
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.unmounting"))
|
67
|
+
machine.guest.capability(:sshfs_forward_unmount_folder, opts)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Check if port information was provided in the options. If not,
|
71
|
+
# then default to port 22 for ssh
|
72
|
+
def check_host_port(machine, opts)
|
73
|
+
if not opts.has_key?(:ssh_port) or not opts[:ssh_port]
|
74
|
+
opts[:ssh_port] = '22'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Function to gather authentication information (username/password)
|
79
|
+
# for doing a normal sshfs mount
|
80
|
+
def get_auth_info(machine, opts)
|
81
|
+
prompt_for_password = false
|
82
|
+
ssh_info = machine.ssh_info
|
83
|
+
|
84
|
+
# Detect the username of the current user
|
85
|
+
username = `whoami`.strip
|
86
|
+
|
87
|
+
# If no username provided then default to the current
|
88
|
+
# user that is executing vagrant
|
89
|
+
if not opts.has_key?(:ssh_username) or not opts[:ssh_username]
|
90
|
+
opts[:ssh_username] = username
|
91
|
+
end
|
92
|
+
|
93
|
+
# Check to see if we need to prompt the user for a password.
|
94
|
+
# We will prompt if:
|
95
|
+
# - User asked us to via prompt_for_password option
|
96
|
+
# - User did not provide a password in options and is not fwding ssh agent
|
97
|
+
#
|
98
|
+
if opts.has_key?(:prompt_for_password) and opts[:prompt_for_password]
|
99
|
+
prompt_for_password = opts[:prompt_for_password]
|
100
|
+
end
|
101
|
+
if not opts.has_key?(:ssh_password) or not opts[:ssh_password]
|
102
|
+
if not ssh_info.has_key?(:forward_agent) or not ssh_info[:forward_agent]
|
103
|
+
prompt_for_password = true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Now do the prompt
|
108
|
+
if prompt_for_password
|
109
|
+
opts[:ssh_password] = machine.ui.ask(
|
110
|
+
I18n.t("vagrant.sshfs.ask.prompt_for_password", username: opts[:ssh_username]),
|
111
|
+
echo: false)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require "vagrant/util/platform"
|
4
|
+
require "vagrant/util/which"
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module SyncedFolderSSHFS
|
8
|
+
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
# Do a reverse mount: mounting guest folder onto the host
|
13
|
+
def do_reverse_mount(machine, opts)
|
14
|
+
|
15
|
+
# Check to see if sshfs software is in the host
|
16
|
+
if machine.env.host.capability?(:sshfs_installed)
|
17
|
+
if !machine.env.host.capability(:sshfs_installed)
|
18
|
+
raise VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSNotInstalledInHost
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# If already mounted then there is nothing to do
|
23
|
+
if machine.env.host.capability(:sshfs_reverse_is_folder_mounted, opts)
|
24
|
+
machine.ui.info(
|
25
|
+
I18n.t("vagrant.sshfs.info.already_mounted",
|
26
|
+
location: 'host', folder: opts[:hostpath]))
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# Do the mount
|
31
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.mounting"))
|
32
|
+
machine.env.host.capability(:sshfs_reverse_mount_folder, machine, opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def do_reverse_unmount(machine, opts)
|
36
|
+
|
37
|
+
# If not mounted then there is nothing to do
|
38
|
+
if ! machine.env.host.capability(:sshfs_reverse_is_folder_mounted, opts)
|
39
|
+
machine.ui.info(
|
40
|
+
I18n.t("vagrant.sshfs.info.not_mounted",
|
41
|
+
location: 'host', folder: opts[:hostpath]))
|
42
|
+
return
|
43
|
+
end
|
44
|
+
|
45
|
+
# Do the Unmount
|
46
|
+
machine.ui.info(I18n.t("vagrant.sshfs.actions.unmounting"))
|
47
|
+
machine.env.host.capability(:sshfs_reverse_unmount_folder, machine, opts)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -3,6 +3,9 @@ require "log4r"
|
|
3
3
|
require "vagrant/util/platform"
|
4
4
|
require "vagrant/util/which"
|
5
5
|
|
6
|
+
require_relative "synced_folder/sshfs_forward_mount"
|
7
|
+
require_relative "synced_folder/sshfs_reverse_mount"
|
8
|
+
|
6
9
|
module VagrantPlugins
|
7
10
|
module SyncedFolderSSHFS
|
8
11
|
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
@@ -35,47 +38,36 @@ module VagrantPlugins
|
|
35
38
|
# No return value.
|
36
39
|
def enable(machine, folders, pluginopts)
|
37
40
|
|
38
|
-
# Check to see if sshfs software is in the guest
|
39
|
-
if machine.guest.capability?(:sshfs_installed)
|
40
|
-
if !machine.guest.capability(:sshfs_installed)
|
41
|
-
can_install = machine.guest.capability?(:sshfs_install)
|
42
|
-
if !can_install
|
43
|
-
raise VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSNotInstalledInGuest
|
44
|
-
end
|
45
|
-
machine.ui.info(I18n.t("vagrant.sshfs.actions.installing"))
|
46
|
-
machine.guest.capability(:sshfs_install)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
41
|
# Iterate through the folders and mount if needed
|
51
42
|
folders.each do |id, opts|
|
52
43
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
folder: opts[:guestpath]))
|
58
|
-
next
|
44
|
+
if opts.has_key?(:reverse) and opts[:reverse]
|
45
|
+
do_reverse_mount(machine, opts)
|
46
|
+
else
|
47
|
+
do_forward_mount(machine, opts)
|
59
48
|
end
|
49
|
+
end
|
50
|
+
end
|
60
51
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
52
|
+
# This is called to remove the synced folders from a running
|
53
|
+
# machine.
|
54
|
+
#
|
55
|
+
# This is not guaranteed to be called, but this should be implemented
|
56
|
+
# by every synced folder implementation.
|
57
|
+
#
|
58
|
+
# @param [Machine] machine The machine to modify.
|
59
|
+
# @param [Hash] folders The folders to remove. This will not contain
|
60
|
+
# any folders that should remain.
|
61
|
+
# @param [Hash] opts Any options for the synced folders.
|
62
|
+
def disable(machine, folders, opts)
|
63
|
+
|
64
|
+
# Iterate through the folders and mount if needed
|
65
|
+
folders.each do |id, opts|
|
66
|
+
if opts.has_key?(:reverse) and opts[:reverse]
|
67
|
+
do_reverse_unmount(machine, opts)
|
72
68
|
else
|
73
|
-
|
74
|
-
opts[:sftp_server_exe_path] = find_executable('sftp-server')
|
69
|
+
do_forward_unmount(machine, opts)
|
75
70
|
end
|
76
|
-
# Do the mount
|
77
|
-
machine.ui.info(I18n.t("vagrant.sshfs.actions.mounting"))
|
78
|
-
machine.guest.capability(:sshfs_mount_folder, opts)
|
79
71
|
end
|
80
72
|
end
|
81
73
|
|
@@ -92,51 +84,6 @@ module VagrantPlugins
|
|
92
84
|
|
93
85
|
protected
|
94
86
|
|
95
|
-
# Check if port information was provided in the options. If not,
|
96
|
-
# then default to port 22 for ssh
|
97
|
-
def check_host_port(machine, opts)
|
98
|
-
if not opts.has_key?(:ssh_port) or not opts[:ssh_port]
|
99
|
-
opts[:ssh_port] = '22'
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Function to gather authentication information (username/password)
|
104
|
-
# for doing a normal sshfs mount
|
105
|
-
def get_auth_info(machine, opts)
|
106
|
-
prompt_for_password = false
|
107
|
-
ssh_info = machine.ssh_info
|
108
|
-
|
109
|
-
# Detect the username of the current user
|
110
|
-
username = `whoami`.strip
|
111
|
-
|
112
|
-
# If no username provided then default to the current
|
113
|
-
# user that is executing vagrant
|
114
|
-
if not opts.has_key?(:ssh_username) or not opts[:ssh_username]
|
115
|
-
opts[:ssh_username] = username
|
116
|
-
end
|
117
|
-
|
118
|
-
# Check to see if we need to prompt the user for a password.
|
119
|
-
# We will prompt if:
|
120
|
-
# - User asked us to via prompt_for_password option
|
121
|
-
# - User did not provide a password in options and is not fwding ssh agent
|
122
|
-
#
|
123
|
-
if opts.has_key?(:prompt_for_password) and opts[:prompt_for_password]
|
124
|
-
prompt_for_password = opts[:prompt_for_password]
|
125
|
-
end
|
126
|
-
if not opts.has_key?(:ssh_password) or not opts[:ssh_password]
|
127
|
-
if not ssh_info.has_key?(:forward_agent) or not ssh_info[:forward_agent]
|
128
|
-
prompt_for_password = true
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
# Now do the prompt
|
133
|
-
if prompt_for_password
|
134
|
-
opts[:ssh_password] = machine.ui.ask(
|
135
|
-
I18n.t("vagrant.sshfs.ask.prompt_for_password", username: opts[:ssh_username]),
|
136
|
-
echo: false)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
87
|
# Function to find the path to an executable with name "name"
|
141
88
|
def find_executable(name)
|
142
89
|
error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSExeNotAvailable
|
@@ -146,13 +93,26 @@ module VagrantPlugins
|
|
146
93
|
|
147
94
|
# Try to include paths where sftp-server may live so
|
148
95
|
# That we have a good chance of finding it
|
149
|
-
if Vagrant::Util::Platform.windows?
|
150
|
-
|
151
|
-
|
152
|
-
|
96
|
+
if Vagrant::Util::Platform.windows?
|
97
|
+
if Vagrant::Util::Platform.cygwin?
|
98
|
+
# If in a cygwin terminal then we can programmatically
|
99
|
+
# determine where sftp-server would be. ssh should already
|
100
|
+
# be in path.
|
101
|
+
cygwin_root = Vagrant::Util::Platform.cygwin_windows_path('/')
|
102
|
+
ENV['PATH'] += ';' + cygwin_root + '\usr\sbin'
|
103
|
+
else
|
104
|
+
# If not in a cygwin terminal then we'll have to guess
|
105
|
+
# where cygwin is installed and add the /bin/ (for ssh) and
|
106
|
+
# /usr/sbin (for sftp-server) to the PATH.
|
107
|
+
ENV['PATH'] += ';C:\cygwin\bin'
|
108
|
+
ENV['PATH'] += ';C:\cygwin\usr\sbin'
|
109
|
+
ENV['PATH'] += ';C:\cygwin64\bin'
|
110
|
+
ENV['PATH'] += ';C:\cygwin64\usr\sbin'
|
111
|
+
end
|
153
112
|
else
|
154
113
|
ENV['PATH'] += ':/usr/libexec/openssh' # Linux (Red Hat Family)
|
155
114
|
ENV['PATH'] += ':/usr/lib/openssh' # Linux (Debian Family)
|
115
|
+
ENV['PATH'] += ':/usr/lib/ssh' # Linux (Arch Linux Family)
|
156
116
|
ENV['PATH'] += ':/usr/libexec/' # Mac OS X
|
157
117
|
end
|
158
118
|
|