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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74c0ac801cbf4908bc4c4afa128e205764b899fd
|
4
|
+
data.tar.gz: 0e842c7729c4bd1a746aa41c16506006720722a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2727626ab76dab2502ba3671e36999dbfd38efbba0528089d43f2f80169c862ed4555c70b8dd2acaa57873123511a1e60537ae8255f1edc331df0cf43d21615
|
7
|
+
data.tar.gz: abee837f9c6b2bd264204ae6990523213d3951c6dfe2a00e063a028ec4a7cd51e370c555a78805e8008a9983c4700efc003aac36f90f5daca02c6abe40333d98
|
data/.gitignore
ADDED
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).
|
6
|
-
the `SSHFS` client software within the guest, which
|
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 -
|
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
|
91
|
-
iterate through the Vagrant file and attempt to mount (via
|
92
|
-
folders that aren't already mounted in the Vagrant guest
|
93
|
-
|
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
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
$
|
207
|
-
|
208
|
-
|
209
|
-
$
|
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
|
-
|
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
|
|
data/features/README.md
ADDED
@@ -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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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.
|
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.
|
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
|
-
|
134
|
-
|
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..
|
251
|
+
for i in 0..6
|
139
252
|
machine.ui.info("Checking Mount..")
|
140
|
-
if self.
|
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
|
-
|
148
|
-
|
149
|
-
|
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
|
File without changes
|
File without changes
|