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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -1
  4. data/README.md +82 -21
  5. data/Rakefile +37 -1
  6. data/features/README.md +21 -0
  7. data/features/sshfs_cwd_mount.feature +46 -0
  8. data/features/step_definitions/sshfs_cwd_mount_steps.rb +12 -0
  9. data/features/support/env.rb +27 -0
  10. data/lib/vagrant-sshfs/cap/{arch → guest/arch}/sshfs_client.rb +0 -0
  11. data/lib/vagrant-sshfs/cap/{debian → guest/debian}/sshfs_client.rb +0 -0
  12. data/lib/vagrant-sshfs/cap/{fedora → guest/fedora}/sshfs_client.rb +0 -0
  13. data/lib/vagrant-sshfs/cap/{linux → guest/linux}/sshfs_client.rb +0 -0
  14. data/lib/vagrant-sshfs/cap/{linux/sshfs_mount.rb → guest/linux/sshfs_forward_mount.rb} +124 -14
  15. data/lib/vagrant-sshfs/cap/{redhat → guest/redhat}/sshfs_client.rb +0 -0
  16. data/lib/vagrant-sshfs/cap/{suse → guest/suse}/sshfs_client.rb +0 -0
  17. data/lib/vagrant-sshfs/cap/host/linux/sshfs_reverse_mount.rb +176 -0
  18. data/lib/vagrant-sshfs/command.rb +16 -4
  19. data/lib/vagrant-sshfs/errors.rb +8 -0
  20. data/lib/vagrant-sshfs/plugin.rb +35 -15
  21. data/lib/vagrant-sshfs/synced_folder/sshfs_forward_mount.rb +116 -0
  22. data/lib/vagrant-sshfs/synced_folder/sshfs_reverse_mount.rb +51 -0
  23. data/lib/vagrant-sshfs/synced_folder.rb +43 -83
  24. data/lib/vagrant-sshfs/version.rb +1 -1
  25. data/lib/vagrant-sshfs.rb +8 -0
  26. data/locales/synced_folder_sshfs.yml +42 -5
  27. data/test/libvirt/README.txt +15 -0
  28. data/test/libvirt/Vagrantfile +35 -0
  29. data/test/misc/README.txt +29 -0
  30. data/test/misc/Vagrantfile +27 -0
  31. data/test/misc/dotests.sh +13 -0
  32. data/test/virtualbox/README.txt +17 -0
  33. data/test/virtualbox/Vagrantfile +42 -0
  34. data/vagrant-sshfs.gemspec +7 -2
  35. metadata +93 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d4ee117625b76ea4c7fb4a599a3cc4fa99f4a2c
4
- data.tar.gz: 148d5131b8afa0b2b67280753a38da6ba3342bc7
3
+ metadata.gz: 74c0ac801cbf4908bc4c4afa128e205764b899fd
4
+ data.tar.gz: 0e842c7729c4bd1a746aa41c16506006720722a9
5
5
  SHA512:
6
- metadata.gz: 5f47cf465600415b77f95da2453c2b79947c7b50758ea386d037bb80c6ec0cbacf75b556fae2494a684652dd6f2ea9ed0dae3d158b6b166609157805a27d6056
7
- data.tar.gz: 31c56873df6f858699d0675a8da871e321426e61081c132da4d40efa9e29d56d798dc20e6c1283bf039ed89301d33299928d802ec0b4f92a0b9dea7d07800b86
6
+ metadata.gz: a2727626ab76dab2502ba3671e36999dbfd38efbba0528089d43f2f80169c862ed4555c70b8dd2acaa57873123511a1e60537ae8255f1edc331df0cf43d21615
7
+ data.tar.gz: abee837f9c6b2bd264204ae6990523213d3951c6dfe2a00e063a028ec4a7cd51e370c555a78805e8008a9983c4700efc003aac36f90f5daca02c6abe40333d98
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ # Build artifacts
2
+ pkg
3
+ build
4
+
5
+ # Ruby / Bundler
6
+ Gemfile.lock
7
+ .ruby-gemset
8
+ .ruby-version
9
+
10
+ # .vagrant dirs
11
+ .vagrant
12
+
13
+ # IDE config files
14
+ .idea
15
+ *.iml
16
+
17
+
data/Gemfile CHANGED
@@ -6,9 +6,12 @@ group :development do
6
6
  # We depend on Vagrant for development, but we don't add it as a
7
7
  # gem dependency because we expect to be installed within the
8
8
  # Vagrant environment itself using `vagrant plugin`.
9
- gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git"
9
+ gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git", :ref => 'v1.8.4'
10
10
  end
11
11
 
12
12
  group :plugins do
13
13
  gem "vagrant-sshfs" , path: "."
14
+ # Add vagrant-libvirt plugin here, otherwise you won't be able to
15
+ # use libvirt as a provider when you execute `bundle exec vagrant up`
16
+ gem "vagrant-libvirt" , '0.0.33'
14
17
  end
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  This is a vagrant plugin that adds synced folder support for mounting
4
4
  folders from the Vagrant host into the Vagrant guest via
5
- [SSHFS](https://github.com/libfuse/sshfs). It does this by executing
6
- the `SSHFS` client software within the guest, which creates and SSH
7
- connection from the Vagrant guest back to the Vagrant host.
5
+ [SSHFS](https://github.com/libfuse/sshfs). In the default mode it does
6
+ this by executing the `SSHFS` client software within the guest, which
7
+ creates an SSH connection from the Vagrant guest back to the Vagrant host.
8
8
 
9
9
  The benefits of this approach:
10
10
  - Works on any host platform and hypervisor type
@@ -35,7 +35,7 @@ folder plugin from the Vagrant core code and molding it to fit SSHFS.
35
35
 
36
36
  ## Modes of Operation
37
37
 
38
- ### Sharing Vagrant Host Directory to Vagrant Guest - 99% of users
38
+ ### Sharing Vagrant Host Directory to Vagrant Guest - 98% of users
39
39
 
40
40
  This plugin uses SSHFS slave mounts
41
41
  (see [link](https://github.com/dustymabe/vagrant-sshfs/issues/11))
@@ -58,6 +58,19 @@ See [Options](#options-specific-to-arbitrary-host-mounting) and
58
58
  [Appendix A](#appendix-a-using-keys-and-forwarding-ssh-agent) for
59
59
  more information.
60
60
 
61
+ ### Sharing Vagrant Guest Directory to Vagrant Host - 1% of users
62
+
63
+ *NOTE:* This option is dangerous as data will be destroyed upon `vagrant destroy`
64
+
65
+ This plugin allows you to share a folder from a Vagrant guest into the
66
+ host. If you have workloads where there are a lot of disk intensive
67
+ operations (such as compilation) it may be ideal to have the files
68
+ live in the guest where the disk intensive operations would occur.
69
+ For discussion see [Issue #7](https://github.com/dustymabe/vagrant-sshfs/issues/7).
70
+
71
+ See [Options](#options-specific-to-reverse-mounting-guest-host-mount)
72
+ for more information on how to enable this type of mount.
73
+
61
74
  ## Getting Started
62
75
 
63
76
  In order to use this synced folder implementation perform the
@@ -87,13 +100,13 @@ section.
87
100
  ## Executing the `vagrant sshfs` Command
88
101
 
89
102
  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.
103
+ command from the command line. Executing this command with the `--mount`
104
+ option will iterate through the Vagrant file and attempt to mount (via
105
+ SSHFS) any folders that aren't already mounted in the Vagrant guest.
106
+ Executing with the `--unmount` option will unmount any mounted folders.
94
107
 
95
108
  ```
96
- vagrant sshfs
109
+ vagrant sshfs [--mount|--unmount] [vm-name]
97
110
  ```
98
111
 
99
112
  ## Options
@@ -122,7 +135,7 @@ An example snippet from a `Vagrantfile`:
122
135
  config.vm.synced_folder "/path/on/host", "/path/on/guest",
123
136
  ssh_opts_append: "-o Compression=yes -o CompressionLevel=5",
124
137
  sshfs_opts_append: "-o auto_cache -o cache_timeout=115200",
125
- disabled: false
138
+ disabled: false, type: "sshfs"
126
139
  ```
127
140
 
128
141
  ### Options Specific to Arbitrary Host Mounting
@@ -156,9 +169,49 @@ config.vm.synced_folder "/path/on/host", "/path/on/guest",
156
169
  ssh_host: "somehost.com", ssh_username: "fedora",
157
170
  ssh_opts_append: "-o Compression=yes -o CompressionLevel=5",
158
171
  sshfs_opts_append: "-o auto_cache -o cache_timeout=115200",
159
- disabled: false
172
+ disabled: false, type: "sshfs"
160
173
  ```
161
174
 
175
+ ### Options Specific to Reverse Mounting (Guest->Host Mount)
176
+
177
+ If your host has the `sshfs` software installed then the following
178
+ options enable mounting a folder from a Vagrant Guest into the
179
+ Vagrant Host:
180
+
181
+ - `reverse`
182
+ - This can be set to 'true' to enable reverse mounting a guest
183
+ folder into the Vagrant host.
184
+
185
+ An example snippet from a `Vagrantfile` where we want to mount `/data`
186
+ on the guest into `/guest/data` on the host:
187
+
188
+ ```
189
+ config.vm.synced_folder "/guest/data", "/data", type: 'sshfs', reverse: true
190
+ ```
191
+
192
+ ## FAQ
193
+
194
+ Here are some answers to some frequently asked questions:
195
+
196
+ ### Why do new files take time to appear inside the guest?
197
+
198
+ Sometimes it can take time for files to appear on the other end of the
199
+ sshfs mount. An example would be I create a file on my host system and
200
+ then it doesn't show up inside the guest mount for 10 to 20 seconds.
201
+ This is because of caching that SSHFS does to improve performance.
202
+ Performance vs accuracy is always going to be a trade-off. If you'd
203
+ like to disable caching completely you can disable caching completely
204
+ by appending the `cache=no` SSHFS option to the synced folder
205
+ definition in the Vagrantfile like so:
206
+
207
+ ```
208
+ config.vm.synced_folder "/path/on/host", "/path/on/guest",
209
+ type: "sshfs", sshfs_opts_append: "-o cache=no"
210
+ ```
211
+
212
+ All caching options that are available to sshfs can be added/modified
213
+ in this same manner.
214
+
162
215
  ## Appendix A: Using Keys and Forwarding SSH Agent
163
216
 
164
217
  When [sharing an arbitrary host directory](#sharing-arbitrary-host-directory-to-vagrant-guest---1-of-users)
@@ -195,16 +248,24 @@ And finally bring up your Vagrant guest:
195
248
 
196
249
  ## Appendix B: Development
197
250
 
198
- For local development of this plugin here is an example of how to build
199
- and install this plugin on your local machine:
251
+ For local development of this plugin here is an example of how to build, test and install this plugin on your local machine:
200
252
 
201
253
  ```
202
- $ rake build
203
- vagrant-sshfs 0.1.0 built to pkg/vagrant-sshfs-0.1.0.gem.
204
- $ mkdir -p /tmp/gems/gems
205
- $ cp pkg/vagrant-sshfs-0.1.0.gem /tmp/gems/gems/
206
- $ pushd /tmp/gems/
207
- $ gem generate_index
208
- $ popd
209
- $ vagrant plugin install vagrant-sshfs --plugin-source file:///tmp/gems/
254
+ # Install development dependencies
255
+ $ gem install bundler && bundle install
256
+
257
+ # List available Rake tasks
258
+ $ bundle exec rake -T
259
+
260
+ # Run Cucumber tests
261
+ $ bundle exec rake featuretests
262
+
263
+ # Build the gem (gets generated in the 'pkg' directory
264
+ $ bundle exec rake build
265
+
266
+ # Run Vagrant in the context of the plugin
267
+ $ bundle exec vagrant <command>
268
+
269
+ # Install built gem into global Vagrant installation (run outside of git checkout!)
270
+ $ vagrant plugin install <path to gem in pkg directory>
210
271
  ```
data/Rakefile CHANGED
@@ -1,2 +1,38 @@
1
- require "bundler/gem_tasks"
1
+ # A Rakefile is like a Makefile for ruby
2
+
3
+ # bundler/gem_tasks provides functionality like:
4
+ # bundle exec rake build
5
+ # bundle exec rake install
6
+ # bundle exec rake release
7
+ #
8
+ require 'bundler/gem_tasks'
9
+
10
+ # cucumber/rake/task provides us with an easy way to call cucumber
11
+ require 'cucumber/rake/task'
12
+
13
+ # rake/clean provides CLEAN/CLOBBER
14
+ # http://www.virtuouscode.com/2014/04/28/rake-part-6-clean-and-clobber/
15
+ # CLEAN - list to let rake know what files can be cleaned up after build
16
+ # CLOBBER - list to let rake know what files are final products of the build
17
+ #
18
+ require 'rake/clean'
19
+
20
+
21
+ # Add the build dir to the list of items to clean up
22
+ CLEAN.include('build')
23
+
24
+ # We want to keep the build artifacts in the pkg dir
25
+ CLOBBER.include('pkg')
26
+
27
+ # Define a Rake::Task that will do initialization for us
28
+ # See http://www.ultrasaurus.com/2009/12/creating-a-custom-rake-task/
29
+ task :init do
30
+ FileUtils.mkdir_p 'build'
31
+ end
32
+
33
+ # Create new Cucumber::Rake::Task that will run Cucumber tests
34
+ Cucumber::Rake::Task.new(:featuretests)
35
+
36
+ # Define Rake::Task dependency - run :init before :featuretests
37
+ task :featuretests => :init
2
38
 
@@ -0,0 +1,21 @@
1
+
2
+ We are using Cucumber for automated testing. Read more at the
3
+ following two links:
4
+
5
+ - [link1](https://en.wikipedia.org/wiki/Cucumber_(software))
6
+ - [link2](http://www.methodsandtools.com/tools/cucumber.php)
7
+
8
+ features/
9
+ This is the features directory. The features directory Contains
10
+ feature files, which all have a .feature extension. May contain
11
+ subdirectories to organize feature files.
12
+
13
+ features/step_definitions
14
+ This directory contains step definition files, which are Ruby code
15
+ and have a .rb extension.
16
+
17
+ features/support
18
+ This directory contains supporting Ruby code. Files in support
19
+ load before those in step_definitions, which makes it useful for
20
+ such things as environment configuration (commonly done in a file
21
+ called env.rb).
@@ -0,0 +1,46 @@
1
+ # The language in this file is Gherkin. It is the language Cucumber
2
+ # uses to define test cases and is designed to be non-technical and
3
+ # human readable. All Gherkin files have a .feature extension
4
+ #
5
+ # See more here: https://en.wikipedia.org/wiki/Cucumber_(software)
6
+ #
7
+ # Additoinally in the setup/env.rb file we set up Aruba. Aruba is used
8
+ # to define most of the basic step definitions that we use as part of
9
+ # the Gherkin syntax in this file.
10
+ #
11
+ # For more information on the step definitions provided see:
12
+ # https://github.com/cucumber/aruba/tree/bb5d7ff71809b5461e29153ded793d2b9a3a0624/features/testing_frameworks/cucumber/steps
13
+ #
14
+ Feature: SSHFS mount of vagrant current working directory
15
+
16
+ Scenario Outline: SSHFS mounting of vagrant cwd
17
+ Given a file named "Vagrantfile" with:
18
+ """
19
+ Vagrant.configure('2') do |config|
20
+ config.vm.box = '<box>'
21
+ # Disable the default rsync
22
+ config.vm.synced_folder '.', '/vagrant', disabled: true
23
+
24
+ # If using libvirt and nested virt (vagrant in vagrant) then
25
+ # we need to use a different network than 192.168.121.0
26
+ config.vm.provider :libvirt do |libvirt|
27
+ libvirt.management_network_name = 'vagrant-libvirt-test'
28
+ libvirt.management_network_address = '192.168.129.0/24'
29
+ end
30
+
31
+ # Mount up the current dir. It will have the Vagrantfile in there.
32
+ config.vm.synced_folder './', '/testdir', type: 'sshfs'
33
+ end
34
+ """
35
+ When I successfully run `bundle exec vagrant up`
36
+ Then stdout from "bundle exec vagrant up" should contain "Installing SSHFS client..."
37
+ And stdout from "bundle exec vagrant up" should contain "Mounting SSHFS shared folder..."
38
+ And stdout from "bundle exec vagrant up" should contain "Folder Successfully Mounted!"
39
+ # The code for the following test is in ./step_definitions/sshfs_cwd_mount_steps.rb
40
+ And vagrant current working directory should be mounted
41
+
42
+ Examples:
43
+ | box |
44
+ | centos/7 |
45
+
46
+
@@ -0,0 +1,12 @@
1
+ # This is a cucumber step definition. Cucumber scenarios become automated
2
+ # tests with the addition of what are called step definitions. A step
3
+ # definition is a block of code associated with one or more steps by a
4
+ # regular expression (or, in simple cases, a string).
5
+ #
6
+ # This is the step definition for the `And vagrant current working
7
+ # directory should be mounted` step from sshfs_cwd_mount.feature
8
+ #
9
+ And(/^vagrant current working directory should be mounted$/) do
10
+ run("vagrant ssh -c 'ls /testdir/Vagrantfile'")
11
+ expect(last_command_started).to have_exit_status(0)
12
+ end
@@ -0,0 +1,27 @@
1
+ # This is a support file for the cucumber tests. This file sets up the
2
+ # environment for the tests to run. At this point mainly that means
3
+ # configuring Aruba. Aruba is used to define most of the basic step
4
+ # definitions that we use as part of the Gherkin syntax in our .feature files.
5
+ #
6
+ # For more information on the step definitions provided see:
7
+ # https://github.com/cucumber/aruba/tree/bb5d7ff71809b5461e29153ded793d2b9a3a0624/features/testing_frameworks/cucumber/steps
8
+ require 'aruba/cucumber'
9
+ require 'komenda' # use komenda for easily executing a command
10
+
11
+ # Configure aruba. The options can be inferred from here:
12
+ # https://github.com/cucumber/aruba/tree/bb5d7ff71809b5461e29153ded793d2b9a3a0624/features/configuration
13
+ Aruba.configure do |config|
14
+ # Wait up to 300 seconds for the test to run
15
+ config.exit_timeout = 300
16
+ # Output stdout and stderr on test failure
17
+ config.activate_announcer_on_command_failure = [:stdout, :stderr]
18
+ # The directory where the tests are to be run
19
+ config.working_directory = 'build/aruba'
20
+ end
21
+
22
+ # After running tests, clean up
23
+ After do |_scenario|
24
+ if File.exist?(File.join(aruba.config.working_directory, 'Vagrantfile'))
25
+ Komenda.run('bundle exec vagrant destroy -f', cwd: aruba.config.working_directory, fail_on_fail: true)
26
+ end
27
+ end
@@ -1,6 +1,13 @@
1
1
  require "log4r"
2
-
3
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
4
11
 
5
12
  module VagrantPlugins
6
13
  module GuestLinux
@@ -9,7 +16,7 @@ module VagrantPlugins
9
16
  extend Vagrant::Util::Retryable
10
17
  @@logger = Log4r::Logger.new("vagrant::synced_folders::sshfs_mount")
11
18
 
12
- def self.sshfs_is_folder_mounted(machine, opts)
19
+ def self.sshfs_forward_is_folder_mounted(machine, opts)
13
20
  mounted = false
14
21
  # expand the guest path so we can handle things like "~/vagrant"
15
22
  expanded_guest_path = machine.guest.capability(
@@ -27,7 +34,7 @@ module VagrantPlugins
27
34
  return mounted
28
35
  end
29
36
 
30
- def self.sshfs_mount_folder(machine, opts)
37
+ def self.sshfs_forward_mount_folder(machine, opts)
31
38
  # opts contains something like:
32
39
  # { :type=>:sshfs,
33
40
  # :guestpath=>"/sharedfolder",
@@ -69,8 +76,82 @@ module VagrantPlugins
69
76
  end
70
77
  end
71
78
 
79
+ def self.sshfs_forward_unmount_folder(machine, opts)
80
+ # opts contains something like:
81
+ # { :type=>:sshfs,
82
+ # :guestpath=>"/sharedfolder",
83
+ # :hostpath=>"/guests/sharedfolder",
84
+ # :disabled=>false
85
+ # :ssh_host=>"192.168.1.1"
86
+ # :ssh_port=>"22"
87
+ # :ssh_username=>"username"
88
+ # :ssh_password=>"password"
89
+ # }
90
+
91
+ # expand the guest path so we can handle things like "~/vagrant"
92
+ expanded_guest_path = machine.guest.capability(
93
+ :shell_expand_guest_path, opts[:guestpath])
94
+
95
+ # Log some information
96
+ machine.ui.info(I18n.t("vagrant.sshfs.actions.unmounting_folder",
97
+ guestpath: expanded_guest_path))
98
+
99
+ # Build up the command and connect
100
+ error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSUnmountFailed
101
+ cmd = "umount #{expanded_guest_path}"
102
+ machine.communicate.sudo(
103
+ cmd, error_class: error_class, error_key: :unmount_failed)
104
+ end
105
+
72
106
  protected
73
107
 
108
+ def self.windows_uninherit_handles
109
+ # For win32-process Process.create, if we pass any file handles to the
110
+ # underlying process for stdin/stdout/stderr then all file handles are
111
+ # inherited by default. We'll explicitly go through and set all Handles
112
+ # to not be inheritable by default. See following links for more info
113
+ #
114
+ # https://github.com/djberg96/win32-process/blob/6b380f450aebb69d44bb7accd958ecb6b9e1d246/lib/win32/process.rb#L445-L447
115
+ # bInheritHandles from https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
116
+ #
117
+ # For each open IO object
118
+ ObjectSpace.each_object(IO) do |io|
119
+ if !io.closed?
120
+ fileno = io.fileno
121
+ @@logger.debug("Setting file handle #{fileno} to not be inherited")
122
+ self.windows_uninherit_handle(fileno)
123
+ end
124
+ end
125
+ end
126
+
127
+ def self.windows_uninherit_handle(fileno)
128
+ # Right now we'll be doing this using private methods from the win32-process
129
+ # module by calling For each open IO object. Much of this code was copied from
130
+ # that module. We access the private methods by using the object.send(:method, args)
131
+ # technique. In the future we want to get a patch upstream so we don't need to
132
+ # access privat methods.
133
+
134
+ # Get the windows IO handle and make sure we were successful getting it
135
+ handle = Process.send(:get_osfhandle, fileno)
136
+ if handle == Process::Constants::INVALID_HANDLE_VALUE
137
+ ptr = FFI::MemoryPointer.new(:int)
138
+ if Process.send(:windows_version) >= 6 && Process.get_errno(ptr) == 0
139
+ errno = ptr.read_int
140
+ else
141
+ errno = FFI.errno
142
+ end
143
+ raise SystemCallError.new("get_osfhandle", errno)
144
+ end
145
+
146
+ # Now clear the HANDLE_FLAG_INHERIT from the HANDLE so that the handle
147
+ # won't get shared by default. See:
148
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms724935(v=vs.85).aspx
149
+ #
150
+ bool = Process.send(:SetHandleInformation,
151
+ handle, Process::Constants::HANDLE_FLAG_INHERIT, 0)
152
+ raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool
153
+ end
154
+
74
155
  # Perform a mount by running an sftp-server on the vagrant host
75
156
  # and piping stdin/stdout to sshfs running inside the guest
76
157
  def self.sshfs_slave_mount(machine, opts, hostpath, expanded_guest_path)
@@ -115,6 +196,14 @@ module VagrantPlugins
115
196
  r1, w1 = IO.pipe # reader/writer from pipe1
116
197
  r2, w2 = IO.pipe # reader/writer from pipe2
117
198
 
199
+ # Log STDERR to predictable files so that we can inspect them
200
+ # later in case things go wrong. We'll use the machines data
201
+ # directory (i.e. .vagrant/machines/default/virtualbox/) for this
202
+ f1path = machine.data_dir.join('vagrant_sshfs_sftp_server_stderr.txt')
203
+ f2path = machine.data_dir.join('vagrant_sshfs_ssh_stderr.txt')
204
+ f1 = File.new(f1path, 'w+')
205
+ f2 = File.new(f2path, 'w+')
206
+
118
207
  # The way this works is by hooking up the stdin+stdout of the
119
208
  # sftp-server process to the stdin+stdout of the sshfs process
120
209
  # running inside the guest in slave mode. An illustration is below:
@@ -130,29 +219,50 @@ module VagrantPlugins
130
219
  # stdin <= r2 pipe2 w2 <= stdout
131
220
  #
132
221
  # 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)
222
+ if Vagrant::Util::Platform.windows?
223
+ # For windows we need to set it so not all file handles are inherited
224
+ # by default. See https://github.com/dustymabe/vagrant-sshfs/issues/41
225
+ # The r1,r2,w1,w2,f1,f2 we pass below will get set back to be shared
226
+ self.windows_uninherit_handles
227
+ # For windows, we are using win32-process' Process.create because ruby
228
+ # doesn't properly detach processes. See https://github.com/dustymabe/vagrant-sshfs/issues/31
229
+ Process.create(:command_line => sftp_server_cmd,
230
+ :creation_flags => Process::DETACHED_PROCESS,
231
+ :process_inherit => false,
232
+ :thread_inherit => true,
233
+ :startup_info => {:stdin => w2, :stdout => r1, :stderr => f1})
234
+
235
+ Process.create(:command_line => ssh_cmd,
236
+ :creation_flags => Process::DETACHED_PROCESS,
237
+ :process_inherit => false,
238
+ :thread_inherit => true,
239
+ :startup_info => {:stdin => w1, :stdout => r2, :stderr => f2})
240
+ else
241
+ p1 = spawn(sftp_server_cmd, :out => w2, :in => r1, :err => f1, :pgroup => true)
242
+ p2 = spawn(ssh_cmd, :out => w1, :in => r2, :err => f2, :pgroup => true)
243
+
244
+ # Detach from the processes so they will keep running
245
+ Process.detach(p1)
246
+ Process.detach(p2)
247
+ end
135
248
 
136
249
  # Check that the mount made it
137
250
  mounted = false
138
- for i in 0..10
251
+ for i in 0..6
139
252
  machine.ui.info("Checking Mount..")
140
- if self.sshfs_is_folder_mounted(machine, opts)
253
+ if self.sshfs_forward_is_folder_mounted(machine, opts)
141
254
  mounted = true
142
255
  break
143
256
  end
144
257
  sleep(2)
145
258
  end
146
259
  if !mounted
147
- Process.kill("TERM", p1)
148
- Process.kill("TERM", p2)
149
- raise VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSSlaveMountFailed
260
+ f1.rewind # Seek to beginning of the file
261
+ f2.rewind # Seek to beginning of the file
262
+ error_class = VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSSlaveMountFailed
263
+ raise error_class, sftp_stderr: f1.read, ssh_stderr: f2.read
150
264
  end
151
265
  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
266
  end
157
267
 
158
268
  # Do a normal sshfs mount in which we will ssh into the guest