vagrant-sshfs 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|