vagrant-sshfs 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 349d3d3ae634f9bc990aa78814cf9c9b3fc694c7
4
- data.tar.gz: 892801c2a7aca30bd99356feeb46220920f64718
3
+ metadata.gz: 2d4ee117625b76ea4c7fb4a599a3cc4fa99f4a2c
4
+ data.tar.gz: 148d5131b8afa0b2b67280753a38da6ba3342bc7
5
5
  SHA512:
6
- metadata.gz: 4e8b60fbc21201acb835442e8f7eb4291b56df8663c761177555a384fcea8256c871916938aa1a181c82ed8d27d30ba529af80c6bc618eff019b8e3a88c0614b
7
- data.tar.gz: fee9778ffc2af267f16c17f8ec9dfade6d7b8549eb7f08782a6e91a7c920c6e62d5c253164469a2912c71ba7413da80c3ca53a04ee35bc932e1d786f41ba827e
6
+ metadata.gz: 5f47cf465600415b77f95da2453c2b79947c7b50758ea386d037bb80c6ec0cbacf75b556fae2494a684652dd6f2ea9ed0dae3d158b6b166609157805a27d6056
7
+ data.tar.gz: 31c56873df6f858699d0675a8da871e321426e61081c132da4d40efa9e29d56d798dc20e6c1283bf039ed89301d33299928d802ec0b4f92a0b9dea7d07800b86
data/README.md CHANGED
@@ -10,18 +10,17 @@ The benefits of this approach:
10
10
  - Works on any host platform and hypervisor type
11
11
  - Windows, Linux, Mac OS X
12
12
  - Virtualbox, Libvirt, Hyper-V, VMWare
13
+ - Seamlessly works on remote Vagrant solutions
14
+ - Works with vagrant aws/openstack/etc.. plugins
13
15
 
14
16
  The drawbacks with this approach:
15
17
  - Performance is worse than an implementation like NFS
16
- - There must be an SSH daemon running on the Vagrant host
17
- - The Vagrant guest must be able to SSH to the Vagrant host and authenticate.
18
+ - There must be `sftp-server` software on the Vagrant host
18
19
 
19
- Running an SSH daemon on the host is mainly only a problem on the
20
- Windows platform. [Here](http://docs.oracle.com/cd/E24628_01/install.121/e22624/preinstall_req_cygwin_ssh.htm#EMBSC150)
21
- is a guide for intalling the cygwin SSH daemon on Windows.
22
-
23
- In order to authenticate back to the host daemon you must either
24
- provide your password or use SSH keys and agent forwarding.
20
+ `sftp-server` is usually provided by SSH server software so it already
21
+ exists on Linux/Mac. On windows you only need to install
22
+ [openssh](https://cygwin.com/cgi-bin2/package-cat.cgi?file=x86_64%2Fopenssh%2Fopenssh-7.2p1-1&grep=openssh)
23
+ via [cygwin](https://cygwin.com/) and you will get `sftp-server`.
25
24
 
26
25
  ## History
27
26
 
@@ -34,12 +33,37 @@ plugin just like the other synced folder plugins (NFS/RSYNC/SMB/VirtualBox).
34
33
  This plugin was developed mainly by copying the code from the NFS synced
35
34
  folder plugin from the Vagrant core code and molding it to fit SSHFS.
36
35
 
36
+ ## Modes of Operation
37
+
38
+ ### Sharing Vagrant Host Directory to Vagrant Guest - 99% of users
39
+
40
+ This plugin uses SSHFS slave mounts
41
+ (see [link](https://github.com/dustymabe/vagrant-sshfs/issues/11))
42
+ to mount a directory from the Vagrant Host into the Vagrant Guest. It
43
+ uses the `sftp-server` software that exists on the host and `sshfs`
44
+ running in *slave mode* within the guest to create a connection using
45
+ the existing authentication over SSH that vagrant sets up for you.
46
+
47
+ ### Sharing Arbitrary Host Directory to Vagrant Guest - 1% of users
48
+
49
+ This plugin allows you to share a folder from an arbitrary host to the
50
+ Vagrant Guest. This would allow you to do a folder mount to some other
51
+ host that may have files that you need. To do this the plugin will run
52
+ an SSHFS command from the Guest and connect to the arbitrary host that
53
+ must have an SSH daemon running. You must provide the `ssh_host`
54
+ option in the Vagrantfile to get this to work. You can use ssh key
55
+ forwarding or username/password for authentication for this.
56
+
57
+ See [Options](#options-specific-to-arbitrary-host-mounting) and
58
+ [Appendix A](#appendix-a-using-keys-and-forwarding-ssh-agent) for
59
+ more information.
60
+
37
61
  ## Getting Started
38
62
 
39
63
  In order to use this synced folder implementation perform the
40
64
  following steps:
41
65
 
42
- ### Install plugin
66
+ ### Install Plugin
43
67
 
44
68
  In order to install the plugin simply run the following command:
45
69
 
@@ -47,7 +71,7 @@ In order to install the plugin simply run the following command:
47
71
  # vagrant plugin install vagrant-sshfs
48
72
  ```
49
73
 
50
- ### Add SSHFS synced folder in Vagrantfile
74
+ ### Add SSHFS Synced Folder in Vagrantfile
51
75
 
52
76
  Edit your Vagrantfile to specify a folder to mount from the host into
53
77
  the guest:
@@ -56,64 +80,66 @@ the guest:
56
80
  config.vm.synced_folder "/path/on/host", "/path/on/guest", type: "sshfs"
57
81
  ```
58
82
 
59
- For more options that you can add see the [Options](#options) section.
60
-
61
- ### Recommended: Using Keys and Forwarding SSH Agent
62
-
83
+ Now you can simply `vagrant up` and your folder should be mounted in
84
+ the guest. For more options that you can add see the [Options](#options)
85
+ section.
63
86
 
64
- If you want a completely non-interactive experience you can either
65
- hard code your password in the Vagrantfile or you can use SSH keys.
87
+ ## Executing the `vagrant sshfs` Command
66
88
 
67
- If `key1` is a key that is authorized to log in to the Vagrant host
68
- ,meaning there is an entry for `key1` in the `~/.ssh/authorized_keys`
69
- file, then you should be able to do the following to have a
70
- non-interactive experience with SSH keys and agent forwarding:
71
-
72
- Modify the Vagrantfile to forward your SSH agent:
89
+ The Vagrant SSHFS plugin also supports execution of the `vagrant sshfs`
90
+ command from the command line. Executing this command will
91
+ iterate through the Vagrant file and attempt to mount (via SSHFS) any
92
+ folders that aren't already mounted in the Vagrant guest that is
93
+ associated with the current directory.
73
94
 
74
95
  ```
75
- config.ssh.forward_agent = 'true'
96
+ vagrant sshfs
76
97
  ```
77
98
 
78
- Now set up your agent and add your key to the agent:
99
+ ## Options
79
100
 
80
- ```
81
- # eval $(ssh-agent)
82
- # ssh-add /path/to/key1
83
- ```
101
+ The SSHFS synced folder plugin supports a few options that can be
102
+ provided in the `Vagrantfile`. The following sections describe the
103
+ options in more detail.
84
104
 
85
- And finally bring up your Vagrant guest:
105
+ ### Generic Options
86
106
 
87
- ```
88
- # vagrant up
89
- ```
107
+ The SSHFS synced folder plugin supports a few options that can be
108
+ provided in the `Vagrantfile`. They are described below:
90
109
 
91
- ## Executing the `vagrant sshfs` command
110
+ - `disabled`
111
+ - If set to 'true', ignore this folder and don't mount it.
112
+ - `ssh_opts_append`
113
+ - Add some options for the ssh connection that will be established.
114
+ - See the ssh man page for more details on possible options.
115
+ - `sshfs_opts_append`
116
+ - Add some options for the sshfs fuse mount that will made
117
+ - See the sshfs man page for more details on possible options.
92
118
 
93
- The Vagrant SSHFS plugin also supports execution of the `vagrant sshfs`
94
- command from the command line. Executing this command will
95
- iterate through the Vagrant file and attempt to mount (via SSHFS) any
96
- folders that aren't already mounted in the Vagrant guest that is
97
- associated with the current directory.
119
+ An example snippet from a `Vagrantfile`:
98
120
 
99
121
  ```
100
- vagrant sshfs
122
+ config.vm.synced_folder "/path/on/host", "/path/on/guest",
123
+ ssh_opts_append: "-o Compression=yes -o CompressionLevel=5",
124
+ sshfs_opts_append: "-o auto_cache -o cache_timeout=115200",
125
+ disabled: false
101
126
  ```
102
127
 
103
- ## Options
128
+ ### Options Specific to Arbitrary Host Mounting
104
129
 
105
- The SSHFS synced folder plugin supports a few options that can be
106
- provided on the command line. They are described below:
130
+ The following options are only to be used when
131
+ [sharing an arbitrary host directory](#sharing-arbitrary-host-directory-to-vagrant-guest---1-of-users)
132
+ with the guest. They will be ignored otherwise:
107
133
 
108
134
  - `ssh_host`
109
135
  - The host to connect to via SSH. If not provided this will be
110
136
  detected as the Vagrant host that is running the Vagrant guest.
111
137
  - `ssh_port`
112
138
  - The port to use when connecting. Defaults to port 22.
113
- - `ssh_username`
139
+ - `ssh_username`
114
140
  - The username to use when connecting. If not provided it is
115
141
  detected as the current user who is interacting with Vagrant.
116
- - `ssh_password` - NOT RECOMMENDED
142
+ - `ssh_password`
117
143
  - The password to use when connecting. If not provided and the
118
144
  user is not using SSH keys, then the user will be prompted for
119
145
  the password. Please use SSH keys and don't use this option!
@@ -122,19 +148,52 @@ provided on the command line. They are described below:
122
148
  a password by setting this to 'true'. Alternatively the user can
123
149
  deny Vagrant from ever prompting for the password by setting
124
150
  this to 'false'.
125
- - `disabled`
126
- - If set to 'true', ignore this folder and don't mount it.
127
151
 
128
- Here is an example of how to use the options:
152
+ An example snippet from a `Vagrantfile`:
129
153
 
130
154
  ```
131
- config.vm.synced_folder "/path/on/host", "/path/on/guest",
132
- type: "sshfs",
133
- ssh_username: "user1",
134
- ssh_port: "22"
155
+ config.vm.synced_folder "/path/on/host", "/path/on/guest",
156
+ ssh_host: "somehost.com", ssh_username: "fedora",
157
+ ssh_opts_append: "-o Compression=yes -o CompressionLevel=5",
158
+ sshfs_opts_append: "-o auto_cache -o cache_timeout=115200",
159
+ disabled: false
135
160
  ```
136
161
 
137
- ## Development
162
+ ## Appendix A: Using Keys and Forwarding SSH Agent
163
+
164
+ When [sharing an arbitrary host directory](#sharing-arbitrary-host-directory-to-vagrant-guest---1-of-users)
165
+ you may want a completely non-interactive experience. You can either
166
+ hard code your password in the Vagrantfile or you can use SSH keys.
167
+ A few guides for setting up ssh keys and key forwarding are on Github:
168
+ - [Key Generation](https://help.github.com/articles/generating-ssh-keys)
169
+ - [Key Forwarding](https://developer.github.com/guides/using-ssh-agent-forwarding/)
170
+
171
+ The idea is that if `key1` is a key that is authorized to log in to the
172
+ Vagrant host ,meaning there is an entry for `key1` in the `~/.ssh/authorized_keys`
173
+ file, then you should be able to do the following to have a
174
+ non-interactive experience with SSH keys and agent forwarding:
175
+
176
+ Modify the Vagrantfile to forward your SSH agent:
177
+
178
+ ```
179
+ config.ssh.forward_agent = 'true'
180
+ ```
181
+
182
+ Now set up your agent and add your key to the agent:
183
+
184
+ ```
185
+ # eval $(ssh-agent)
186
+ # ssh-add /path/to/key1
187
+ ```
188
+
189
+ And finally bring up your Vagrant guest:
190
+
191
+ ```
192
+ # vagrant up
193
+ ```
194
+
195
+
196
+ ## Appendix B: Development
138
197
 
139
198
  For local development of this plugin here is an example of how to build
140
199
  and install this plugin on your local machine:
@@ -1,3 +1,5 @@
1
+ require "log4r"
2
+
1
3
  require "vagrant/util/retryable"
2
4
 
3
5
  module VagrantPlugins
@@ -5,6 +7,25 @@ module VagrantPlugins
5
7
  module Cap
6
8
  class MountSSHFS
7
9
  extend Vagrant::Util::Retryable
10
+ @@logger = Log4r::Logger.new("vagrant::synced_folders::sshfs_mount")
11
+
12
+ def self.sshfs_is_folder_mounted(machine, opts)
13
+ mounted = false
14
+ # expand the guest path so we can handle things like "~/vagrant"
15
+ expanded_guest_path = machine.guest.capability(
16
+ :shell_expand_guest_path, opts[:guestpath])
17
+ machine.communicate.execute("cat /proc/mounts") do |type, data|
18
+ if type == :stdout
19
+ data.each_line do |line|
20
+ if line.split()[1] == expanded_guest_path
21
+ mounted = true
22
+ break
23
+ end
24
+ end
25
+ end
26
+ end
27
+ return mounted
28
+ end
8
29
 
9
30
  def self.sshfs_mount_folder(machine, opts)
10
31
  # opts contains something like:
@@ -22,67 +43,160 @@ module VagrantPlugins
22
43
  expanded_guest_path = machine.guest.capability(
23
44
  :shell_expand_guest_path, opts[:guestpath])
24
45
 
25
- # Do the actual creating and mounting
26
- machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
46
+ # Create the mountpoint inside the guest
47
+ machine.communicate.tap do |comm|
48
+ comm.sudo("mkdir -p #{expanded_guest_path}")
49
+ comm.sudo("chmod 777 #{expanded_guest_path}")
50
+ end
27
51
 
28
52
  # Mount path information
29
53
  hostpath = opts[:hostpath].dup
30
54
  hostpath.gsub!("'", "'\\\\''")
31
55
 
56
+ # Add in some sshfs/fuse options that are common to both mount methods
57
+ opts[:sshfs_opts] = ' -o allow_other ' # allow non-root users to access
58
+ opts[:sshfs_opts]+= ' -o noauto_cache '# disable caching based on mtime
59
+
60
+ # Add in some ssh options that are common to both mount methods
61
+ opts[:ssh_opts] = ' -o StrictHostKeyChecking=no '# prevent yes/no question
62
+ opts[:ssh_opts]+= ' -o ServerAliveInterval=30 ' # send keepalives
63
+
64
+ # Do a normal mount only if the user provided host information
65
+ if opts.has_key?(:ssh_host) and opts[:ssh_host]
66
+ self.sshfs_normal_mount(machine, opts, hostpath, expanded_guest_path)
67
+ else
68
+ self.sshfs_slave_mount(machine, opts, hostpath, expanded_guest_path)
69
+ end
70
+ end
71
+
72
+ protected
73
+
74
+ # Perform a mount by running an sftp-server on the vagrant host
75
+ # and piping stdin/stdout to sshfs running inside the guest
76
+ def self.sshfs_slave_mount(machine, opts, hostpath, expanded_guest_path)
77
+
78
+ sftp_server_path = opts[:sftp_server_exe_path]
79
+ ssh_path = opts[:ssh_exe_path]
80
+
81
+ # SSH connection options
82
+ ssh_opts = opts[:ssh_opts]
83
+ ssh_opts_append = opts[:ssh_opts_append].to_s # provided by user
84
+
85
+ # SSHFS executable options
86
+ sshfs_opts = opts[:sshfs_opts]
87
+ sshfs_opts_append = opts[:sshfs_opts_append].to_s # provided by user
88
+
89
+ # The sftp-server command
90
+ sftp_server_cmd = sftp_server_path
91
+
92
+ # The remote sshfs command that will run (in slave mode)
93
+ sshfs_opts+= ' -o slave '
94
+ sshfs_cmd = "sudo -E sshfs :#{hostpath} #{expanded_guest_path}"
95
+ sshfs_cmd+= sshfs_opts + ' ' + sshfs_opts_append + ' '
96
+
97
+ # The ssh command to connect to guest and then launch sshfs
98
+ ssh_opts = opts[:ssh_opts]
99
+ ssh_opts+= ' -o User=' + machine.ssh_info[:username]
100
+ ssh_opts+= ' -o Port=' + machine.ssh_info[:port].to_s
101
+ ssh_opts+= ' -o IdentityFile=' + machine.ssh_info[:private_key_path][0]
102
+ ssh_opts+= ' -o UserKnownHostsFile=/dev/null '
103
+ ssh_opts+= ' -F /dev/null ' # Don't pick up options from user's config
104
+ ssh_cmd = ssh_path + ssh_opts + ' ' + ssh_opts_append + ' ' + machine.ssh_info[:host]
105
+ ssh_cmd+= ' "' + sshfs_cmd + '"'
106
+
32
107
  # Log some information
33
- machine.ui.info(I18n.t("vagrant.sshfs.actions.mounting_folder",
108
+ @@logger.debug("sftp-server cmd: #{sftp_server_cmd}")
109
+ @@logger.debug("ssh cmd: #{ssh_cmd}")
110
+ machine.ui.info(I18n.t("vagrant.sshfs.actions.slave_mounting_folder",
34
111
  hostpath: hostpath, guestpath: expanded_guest_path))
35
112
 
36
- # Figure out any options
37
- # TODO - Allow options override via an option
38
- mount_opts = '-o StrictHostKeyChecking=no '
39
- mount_opts+= '-o allow_other '
40
- mount_opts+= '-o noauto_cache '
113
+ # Create two named pipes for communication between sftp-server and
114
+ # sshfs running in slave mode
115
+ r1, w1 = IO.pipe # reader/writer from pipe1
116
+ r2, w2 = IO.pipe # reader/writer from pipe2
117
+
118
+ # The way this works is by hooking up the stdin+stdout of the
119
+ # sftp-server process to the stdin+stdout of the sshfs process
120
+ # running inside the guest in slave mode. An illustration is below:
121
+ #
122
+ # stdout => w1 pipe1 r1 => stdin
123
+ # />------------->==============>----------->\
124
+ # / \
125
+ # | |
126
+ # sftp-server (on vm host) sshfs (inside guest)
127
+ # | |
128
+ # \ /
129
+ # \<-------------<==============<-----------</
130
+ # stdin <= r2 pipe2 w2 <= stdout
131
+ #
132
+ # Wire up things appropriately and start up the processes
133
+ p1 = spawn(sftp_server_cmd, :out => w2, :in => r1)
134
+ p2 = spawn(ssh_cmd, :out => w1, :in => r2)
135
+
136
+ # Check that the mount made it
137
+ mounted = false
138
+ for i in 0..10
139
+ machine.ui.info("Checking Mount..")
140
+ if self.sshfs_is_folder_mounted(machine, opts)
141
+ mounted = true
142
+ break
143
+ end
144
+ sleep(2)
145
+ end
146
+ if !mounted
147
+ Process.kill("TERM", p1)
148
+ Process.kill("TERM", p2)
149
+ raise VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSSlaveMountFailed
150
+ end
151
+ machine.ui.info("Folder Successfully Mounted!")
152
+
153
+ # Detach from the processes so they will keep running
154
+ Process.detach(p1)
155
+ Process.detach(p2)
156
+ end
157
+
158
+ # Do a normal sshfs mount in which we will ssh into the guest
159
+ # and then execute the sshfs command to connect the the opts[:ssh_host]
160
+ # and mount a folder from opts[:ssh_host] into the guest.
161
+ def self.sshfs_normal_mount(machine, opts, hostpath, expanded_guest_path)
41
162
 
42
- # TODO some other options we might use in the future to help
43
- # connections over low bandwidth
44
- #options+= '-o kernel_cache -o Ciphers=arcfour -o big_writes -o auto_cache -o cache_timeout=115200 -o attr_timeout=115200 -o entry_timeout=1200 -o max_readahead=90000 '
45
- #options+= '-o kernel_cache -o big_writes -o auto_cache -o cache_timeout=115200 -o attr_timeout=115200 -o entry_timeout=1200 -o max_readahead=90000 '
46
- #options+= '-o cache_timeout=3600 '
163
+ # SSH connection options
164
+ ssh_opts = opts[:ssh_opts]
165
+ ssh_opts_append = opts[:ssh_opts_append].to_s # provided by user
47
166
 
167
+ # SSHFS executable options
168
+ sshfs_opts = opts[:sshfs_opts]
169
+ sshfs_opts_append = opts[:sshfs_opts_append].to_s # provided by user
170
+
171
+ # Host/Port and Auth Information
48
172
  username = opts[:ssh_username]
49
173
  password = opts[:ssh_password]
50
174
  host = opts[:ssh_host]
51
175
  port = opts[:ssh_port]
52
176
 
177
+ # Add echo of password if password is being used
53
178
  echopipe = ""
54
179
  if password
55
180
  echopipe = "echo '#{password}' | "
56
- mount_opts+= '-o password_stdin '
181
+ sshfs_opts+= '-o password_stdin '
57
182
  end
183
+
184
+ # Log some information
185
+ machine.ui.info(I18n.t("vagrant.sshfs.actions.normal_mounting_folder",
186
+ user: username, host: host,
187
+ hostpath: hostpath, guestpath: expanded_guest_path))
58
188
 
59
- error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSMountFailed
189
+ # Build up the command and connect
190
+ error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSNormalMountFailed
60
191
  cmd = echopipe
61
192
  cmd+= "sshfs -p #{port} "
62
- cmd+= mount_opts
193
+ cmd+= ssh_opts + ' ' + ssh_opts_append + ' '
194
+ cmd+= sshfs_opts + ' ' + sshfs_opts_append + ' '
63
195
  cmd+= "#{username}@#{host}:'#{hostpath}' #{expanded_guest_path}"
64
196
  retryable(on: error_class, tries: 3, sleep: 3) do
65
197
  machine.communicate.sudo(
66
- cmd, error_class: error_class, error_key: :mount_failed)
67
- end
68
- end
69
-
70
- def self.sshfs_is_folder_mounted(machine, opts)
71
- mounted = false
72
- # expand the guest path so we can handle things like "~/vagrant"
73
- expanded_guest_path = machine.guest.capability(
74
- :shell_expand_guest_path, opts[:guestpath])
75
- machine.communicate.execute("cat /proc/mounts") do |type, data|
76
- if type == :stdout
77
- data.each_line do |line|
78
- if line.split()[1] == expanded_guest_path
79
- mounted = true
80
- break
81
- end
82
- end
83
- end
198
+ cmd, error_class: error_class, error_key: :normal_mount_failed)
84
199
  end
85
- return mounted
86
200
  end
87
201
  end
88
202
  end
@@ -6,8 +6,12 @@ module VagrantPlugins
6
6
  error_namespace("vagrant.sshfs.errors")
7
7
  end
8
8
 
9
- class SSHFSMountFailed < SSHFSError
10
- error_key(:mount_failed)
9
+ class SSHFSNormalMountFailed < SSHFSError
10
+ error_key(:normal_mount_failed)
11
+ end
12
+
13
+ class SSHFSSlaveMountFailed < SSHFSError
14
+ error_key(:slave_mount_failed)
11
15
  end
12
16
 
13
17
  class SSHFSInstallFailed < SSHFSError
@@ -17,6 +21,10 @@ module VagrantPlugins
17
21
  class SSHFSNotInstalledInGuest < SSHFSError
18
22
  error_key(:sshfs_not_in_guest)
19
23
  end
24
+
25
+ class SSHFSExeNotAvailable < SSHFSError
26
+ error_key(:exe_not_in_host)
27
+ end
20
28
  end
21
29
  end
22
30
  end
@@ -1,13 +1,16 @@
1
+ require "log4r"
2
+
1
3
  require "vagrant/util/platform"
4
+ require "vagrant/util/which"
2
5
 
3
6
  module VagrantPlugins
4
7
  module SyncedFolderSSHFS
5
8
  class SyncedFolder < Vagrant.plugin("2", :synced_folder)
6
- @@vagrant_host_machine_ip
7
9
 
8
10
  def initialize(*args)
9
11
  super
10
- @@vagrant_host_machine_ip = nil
12
+
13
+ @logger = Log4r::Logger.new("vagrant::synced_folders::sshfs")
11
14
  end
12
15
 
13
16
  # This is called early when the synced folder is set to determine
@@ -30,8 +33,10 @@ module VagrantPlugins
30
33
  # any existing ones.
31
34
  #
32
35
  # No return value.
33
- def enable(machine, folders, sshfsopts)
34
- if machine.guest.capability?(:sshfs_installed)
36
+ def enable(machine, folders, pluginopts)
37
+
38
+ # Check to see if sshfs software is in the guest
39
+ if machine.guest.capability?(:sshfs_installed)
35
40
  if !machine.guest.capability(:sshfs_installed)
36
41
  can_install = machine.guest.capability?(:sshfs_install)
37
42
  if !can_install
@@ -42,6 +47,7 @@ module VagrantPlugins
42
47
  end
43
48
  end
44
49
 
50
+ # Iterate through the folders and mount if needed
45
51
  folders.each do |id, opts|
46
52
 
47
53
  # If already mounted then there is nothing to do
@@ -52,10 +58,21 @@ module VagrantPlugins
52
58
  next
53
59
  end
54
60
 
55
- # Find out the host info and auth info for each folder
56
- get_host_info(machine, opts)
57
- get_auth_info(machine, opts)
58
-
61
+ # If the synced folder entry has host information in it then
62
+ # assume we are doing a normal sshfs mount to a host that isn't
63
+ # the machine running vagrant. Rely on password/ssh keys.
64
+ #
65
+ # If not, then we are doing a slave mount and we need to
66
+ # make sure we can find the sftp-server and ssh execuatable
67
+ # files on the host.
68
+ if opts.has_key?(:ssh_host) and opts[:ssh_host]
69
+ # Check port information and find out auth info
70
+ check_host_port(machine, opts)
71
+ get_auth_info(machine, opts)
72
+ else
73
+ opts[:ssh_exe_path] = find_executable('ssh')
74
+ opts[:sftp_server_exe_path] = find_executable('sftp-server')
75
+ end
59
76
  # Do the mount
60
77
  machine.ui.info(I18n.t("vagrant.sshfs.actions.mounting"))
61
78
  machine.guest.capability(:sshfs_mount_folder, opts)
@@ -75,47 +92,17 @@ module VagrantPlugins
75
92
 
76
93
  protected
77
94
 
78
- def get_host_info(machine, opts)
79
- # opts - the synced folder options hash
80
- # machine -
81
-
82
- # If the synced folder entry doesn't have host information in it then
83
- # detect the vagrant host machine IP and use that
84
- if not opts.has_key?(:ssh_host) or not opts[:ssh_host]
85
- opts[:ssh_host] = detect_vagrant_host_ip(machine)
86
- end
87
-
88
- # If the synced folder doesn't have host port information in it
89
- # default to port 22 for ssh
90
- # detect the vagrant host machine IP and use that
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)
91
98
  if not opts.has_key?(:ssh_port) or not opts[:ssh_port]
92
99
  opts[:ssh_port] = '22'
93
100
  end
94
101
  end
95
102
 
96
- def detect_vagrant_host_ip(machine)
97
- # Only run detection if it hasn't been run before
98
- if not @@vagrant_host_machine_ip
99
- # Attempt to detect host machine IP by connecting over ssh
100
- # and then using the $SSH_CONNECTION env variable information to
101
- # determine the vagrant host IP address
102
- hostip = ''
103
- machine.communicate.execute('echo $SSH_CONNECTION') do |type, data|
104
- if type == :stdout
105
- hostip = data.split()[0]
106
- end
107
- end
108
- # TODO do some error checking here to make sure hostip was detected
109
- machine.ui.info(I18n.t("vagrant.sshfs.info.detected_host_ip", ip: hostip))
110
- @@vagrant_host_machine_ip = hostip
111
- end
112
- # Return the detected host IP
113
- @@vagrant_host_machine_ip
114
- end
115
-
103
+ # Function to gather authentication information (username/password)
104
+ # for doing a normal sshfs mount
116
105
  def get_auth_info(machine, opts)
117
- # opts - the synced folder options hash
118
- # machine -
119
106
  prompt_for_password = false
120
107
  ssh_info = machine.ssh_info
121
108
 
@@ -149,6 +136,34 @@ module VagrantPlugins
149
136
  echo: false)
150
137
  end
151
138
  end
139
+
140
+ # Function to find the path to an executable with name "name"
141
+ def find_executable(name)
142
+ error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSExeNotAvailable
143
+
144
+ # Save off PATH env var before we modify it
145
+ oldpath = ENV['PATH']
146
+
147
+ # Try to include paths where sftp-server may live so
148
+ # That we have a good chance of finding it
149
+ if Vagrant::Util::Platform.windows? and
150
+ Vagrant::Util::Platform.cygwin?
151
+ cygwin_root = Vagrant::Util::Platform.cygwin_windows_path('/')
152
+ ENV['PATH'] += ';' + cygwin_root + '\usr\sbin'
153
+ else
154
+ ENV['PATH'] += ':/usr/libexec/openssh' # Linux (Red Hat Family)
155
+ ENV['PATH'] += ':/usr/lib/openssh' # Linux (Debian Family)
156
+ ENV['PATH'] += ':/usr/libexec/' # Mac OS X
157
+ end
158
+
159
+ # Try to find the executable
160
+ exepath = Vagrant::Util::Which.which(name)
161
+ raise error_class, executable: name if !exepath
162
+
163
+ # Restore the PATH variable and return
164
+ ENV['PATH'] = oldpath
165
+ return exepath
166
+ end
152
167
  end
153
168
  end
154
169
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module SyncedFolderSSHFS
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -4,8 +4,10 @@ en:
4
4
  actions:
5
5
  installing: Installing SSHFS client...
6
6
  mounting: Mounting SSHFS shared folders...
7
- mounting_folder: |-
7
+ slave_mounting_folder: |-
8
8
  Mounting folder via SSHFS: %{hostpath} => %{guestpath}
9
+ normal_mounting_folder: |-
10
+ Mounting folder via SSHFS: %{user}@%{host}:%{hostpath} => %{guestpath}
9
11
  ask:
10
12
  prompt_for_password: |-
11
13
  SSHFS password for '%{username}':
@@ -18,6 +20,10 @@ en:
18
20
  communicator_not_ready: |-
19
21
  The machine is reporting that it is not ready to communicate via ssh. Verify
20
22
  this machine is properly running.
23
+ exe_not_in_host: |-
24
+ The '%{executable}' executable file can't be found on the host machine but
25
+ is required for sshfs mounting to work. Please install the software and
26
+ try again.
21
27
  sshfs_not_in_guest: |-
22
28
  The necessary SSHFS software is not installed in the guest.
23
29
  install_failed_arch: |-
@@ -27,10 +33,10 @@ en:
27
33
 
28
34
  [1] https://wiki.archlinux.org/index.php/pacman#Packages_cannot_be_retrieved_on_installation
29
35
  [2] https://wiki.archlinux.org/index.php/System_maintenance#Partial_upgrades_are_unsupported
30
- mount_failed: |-
31
- Mounting SSHFS shared folders failed. This is most often caused by either
32
- an SSH Daemon not running on the host or invalid credentials being provided.
33
- Please make sure an SSH daemon is running on the host and proper credentials
36
+ normal_mount_failed: |-
37
+ Mounting SSHFS shared folders failed. This is most often caused by either an
38
+ SSH Daemon not running on the target host or invalid credentials being provided.
39
+ Please make sure an SSH daemon is running on the host and proper credentials
34
40
  were provided to be able to authenticate via SSH.
35
41
 
36
42
  The command and output are:
@@ -44,3 +50,7 @@ en:
44
50
  Stderr from the command:
45
51
 
46
52
  %{stderr}
53
+ slave_mount_failed: |-
54
+ Mounting SSHFS shared via slave SSHFS mount failed. Please look at your
55
+ terminal scrollback to look for any error messages from the processes that
56
+ were run.
@@ -13,8 +13,8 @@ Gem::Specification.new do |spec|
13
13
  This is the successor to Fabio Kreusch's implementation:
14
14
  https://github.com/fabiokr/vagrant-sshfs"""
15
15
  spec.summary = spec.description
16
- spec.homepage = ""
17
- spec.license = "GPL"
16
+ spec.homepage = "https://github.com/dustymabe/vagrant-sshfs"
17
+ spec.license = "GPL-2.0"
18
18
 
19
19
  spec.files = `git ls-files -z`.split("\x0")
20
20
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-sshfs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dusty Mabe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-14 00:00:00.000000000 Z
11
+ date: 2016-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,9 +65,9 @@ files:
65
65
  - lib/vagrant-sshfs/version.rb
66
66
  - locales/synced_folder_sshfs.yml
67
67
  - vagrant-sshfs.gemspec
68
- homepage: ''
68
+ homepage: https://github.com/dustymabe/vagrant-sshfs
69
69
  licenses:
70
- - GPL
70
+ - GPL-2.0
71
71
  metadata: {}
72
72
  post_install_message:
73
73
  rdoc_options: []