Skip to content

Commit

Permalink
Merge pull request #33 from hferentschik/issue-31
Browse files Browse the repository at this point in the history
Switch to win32-process for sub-process creation on Windows
  • Loading branch information
dustymabe authored Jul 20, 2016
2 parents bd62fd2 + 2fa2514 commit b244de9
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 26 deletions.
7 changes: 7 additions & 0 deletions .config/cucumber.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# config/cucumber.yml
##YAML Template
---
default: --profile html

pretty: --format pretty -b
html: --format progress --format html --out=build/features_report.html -b
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Build artifacts
pkg
build

# Ruby / Bundler
Gemfile.lock
.ruby-gemset
.ruby-version

# IDE config files
.idea
*.iml
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ group :development do
# We depend on Vagrant for development, but we don't add it as a
# gem dependency because we expect to be installed within the
# Vagrant environment itself using `vagrant plugin`.
gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git"
gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git", :ref => 'v1.8.4'
end

group :plugins do
Expand Down
32 changes: 20 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,24 @@ And finally bring up your Vagrant guest:

## Appendix B: Development

For local development of this plugin here is an example of how to build
and install this plugin on your local machine:

```
$ rake build
vagrant-sshfs 0.1.0 built to pkg/vagrant-sshfs-0.1.0.gem.
$ mkdir -p /tmp/gems/gems
$ cp pkg/vagrant-sshfs-0.1.0.gem /tmp/gems/gems/
$ pushd /tmp/gems/
$ gem generate_index
$ popd
$ vagrant plugin install vagrant-sshfs --plugin-source file:///tmp/gems/
For local development of this plugin here is an example of how to build, test and install this plugin on your local machine:

```
# Install development dependencies
$ gem install bundler && bundle install
# List available Rake tasks
$ bundle exec rake -T
# Run Cucumber tests
$ bundle exec rake features
# Build the gem (gets generated in the 'pkg' directory
$ bundle exec rake build
# Run Vagrant in the context of the plugin
$ bundle exec rake vagrant <command>
# Install built gem into global Vagrant installation (run outside of git checkout!)
$ vagrant plugin install <path to gem in pkg directory>
```
23 changes: 22 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
require "bundler/gem_tasks"
require 'bundler/gem_tasks'
require 'rake/clean'
require 'cucumber/rake/task'
require 'launchy'

CLOBBER.include('pkg')
CLEAN.include('build')

task :init do
FileUtils.mkdir_p 'build'
end

# Cucumber acceptance test task
Cucumber::Rake::Task.new(:features)
task :features => :init

namespace :features do
desc 'Opens the HTML Cucumber test report'
task :open_report do
Launchy.open('./build/features_report.html')
end
end

4 changes: 4 additions & 0 deletions features/step_definitions/user_home_dir_mount_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
And(/^user's home directory should be mounted$/) do
run("vagrant ssh -c \"ls #{ENV['HOME']}\"")
expect(last_command_started).to have_exit_status(0)
end
14 changes: 14 additions & 0 deletions features/support/env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'aruba/cucumber'
require 'komenda'

Aruba.configure do |config|
config.exit_timeout = 300
config.activate_announcer_on_command_failure = [:stdout, :stderr]
config.working_directory = 'build/aruba'
end

After do |_scenario|
if File.exist?(File.join(aruba.config.working_directory, 'Vagrantfile'))
Komenda.run('bundle exec vagrant destroy -f', cwd: aruba.config.working_directory, fail_on_fail: true)
end
end
28 changes: 28 additions & 0 deletions features/user_home_dir_mount.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Feature: Mount of user home directory

Scenario Outline: Mounting the user's home directory
Given a file named "Vagrantfile" with:
"""
Vagrant.configure('2') do |config|
config.vm.box = '<box>'
config.vm.synced_folder '.', '/vagrant', disabled: true
if Vagrant::Util::Platform.windows?
target_path = ENV['USERPROFILE'].gsub(/\\/,'/').gsub(/[[:alpha:]]{1}:/){|s|'/' + s.downcase.sub(':', '')}
config.vm.synced_folder ENV['USERPROFILE'], target_path, type: 'sshfs', sshfs_opts_append: '-o umask=000 -o uid=1000 -o gid=1000'
else
config.vm.synced_folder ENV['HOME'], ENV['HOME'], type: 'sshfs', sshfs_opts_append: '-o umask=000 -o uid=1000 -o gid=1000'
end
end
"""
When I successfully run `bundle exec vagrant up --provider <provider>`
Then stdout from "bundle exec vagrant up --provider <provider>" should contain "Installing SSHFS client..."
And stdout from "bundle exec vagrant up --provider <provider>" should contain "Mounting SSHFS shared folder..."
And stdout from "bundle exec vagrant up --provider <provider>" should contain "Folder Successfully Mounted!"
And user's home directory should be mounted

Examples:
| box | provider |
| centos/7 | virtualbox |


6 changes: 6 additions & 0 deletions lib/vagrant-sshfs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
raise "The Vagrant sshfs plugin must be run within Vagrant"
end

# Only load the gem on Windows since it replaces some methods in Ruby's Process class
# Also load before Process.uid is called the first time by Vagrant
if Vagrant::Util::Platform.windows?
require 'win32/process'
end

require "vagrant-sshfs/errors"
require "vagrant-sshfs/version"
require "vagrant-sshfs/plugin"
Expand Down
33 changes: 24 additions & 9 deletions lib/vagrant-sshfs/cap/linux/sshfs_mount.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require "log4r"

require "vagrant/util/retryable"
require "tempfile"

Expand Down Expand Up @@ -146,8 +145,8 @@ def self.sshfs_slave_mount(machine, opts, hostpath, expanded_guest_path)
# For issue #27 we'll need to create a tmp files for STDERR
# Can't send to /dev/null. Doesn't work on Windows.
# Can't close FD with :close. Doesn't work on Windows.
t1 = Tempfile.new('vagrant_sshfs_sftp_server_stderr').path()
t2 = Tempfile.new('vagrant_sshfs_ssh_stderr').path()
t1 = Tempfile.new('vagrant_sshfs_sftp_server_stderr')
t2 = Tempfile.new('vagrant_sshfs_ssh_stderr')

# The way this works is by hooking up the stdin+stdout of the
# sftp-server process to the stdin+stdout of the sshfs process
Expand All @@ -164,8 +163,28 @@ def self.sshfs_slave_mount(machine, opts, hostpath, expanded_guest_path)
# stdin <= r2 pipe2 w2 <= stdout
#
# Wire up things appropriately and start up the processes
p1 = spawn(sftp_server_cmd, :out => w2, :in => r1, :err => t1)
p2 = spawn(ssh_cmd, :out => w1, :in => r2, :err => t2)
if Vagrant::Util::Platform.windows?
# Need to handle Windows differently. Kernel.spawn fails to work, if the shell creating the process is closed.
# See https://github.com/dustymabe/vagrant-sshfs/issues/31
Process.create(:command_line => sftp_server_cmd,
:creation_flags => Process::DETACHED_PROCESS,
:process_inherit => false,
:thread_inherit => true,
:startup_info => {:stdin => w2, :stdout => r1, :stderr => t1})

Process.create(:command_line => ssh_cmd,
:creation_flags => Process::DETACHED_PROCESS,
:process_inherit => false,
:thread_inherit => true,
:startup_info => {:stdin => w1, :stdout => r2, :stderr => t2})
else
p1 = spawn(sftp_server_cmd, :out => w2, :in => r1, :err => t1, :pgroup => true)
p2 = spawn(ssh_cmd, :out => w1, :in => r2, :err => t2, :pgroup => true)

# Detach from the processes so they will keep running
Process.detach(p1)
Process.detach(p2)
end

# Check that the mount made it
mounted = false
Expand All @@ -181,10 +200,6 @@ def self.sshfs_slave_mount(machine, opts, hostpath, expanded_guest_path)
raise VagrantPlugins::SyncedFolderSSHFS::Errors::SSHFSSlaveMountFailed
end
machine.ui.info("Folder Successfully Mounted!")

# Detach from the processes so they will keep running
Process.detach(p1)
Process.detach(p2)
end

# Do a normal sshfs mount in which we will ssh into the guest
Expand Down
2 changes: 1 addition & 1 deletion lib/vagrant-sshfs/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module VagrantPlugins
module SyncedFolderSSHFS
VERSION = "1.1.0"
VERSION = "1.1.0.dev"
end
end
10 changes: 8 additions & 2 deletions vagrant-sshfs.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_dependency 'win32-process'

spec.add_development_dependency 'bundler', '~> 1.7'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'cucumber', '~> 2.1'
spec.add_development_dependency 'aruba', '~> 0.13'
spec.add_development_dependency 'komenda', '~> 0.1.6'
spec.add_development_dependency 'launchy'
end

0 comments on commit b244de9

Please sign in to comment.