From 3b8171193eea901ad4f59f689ffca49cd1a03491 Mon Sep 17 00:00:00 2001 From: Hardy Ferentschik Date: Tue, 21 Jun 2016 23:56:38 +0200 Subject: [PATCH] Issue #27 Switching to win32-process for creating sub processes on Windows --- .gitignore | 11 ++++++++ Gemfile | 2 +- lib/vagrant-sshfs.rb | 6 ++++ lib/vagrant-sshfs/cap/linux/sshfs_mount.rb | 33 ++++++++++++++++------ lib/vagrant-sshfs/version.rb | 2 +- vagrant-sshfs.gemspec | 2 ++ 6 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7511f9b --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Build artifacts +pkg + +# Ruby / Bundler +Gemfile.lock +.ruby-gemset +.ruby-version + +# IDE config files +.idea +*.iml diff --git a/Gemfile b/Gemfile index 1084686..d247eea 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/lib/vagrant-sshfs.rb b/lib/vagrant-sshfs.rb index 68aad37..2c271c6 100644 --- a/lib/vagrant-sshfs.rb +++ b/lib/vagrant-sshfs.rb @@ -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" diff --git a/lib/vagrant-sshfs/cap/linux/sshfs_mount.rb b/lib/vagrant-sshfs/cap/linux/sshfs_mount.rb index 1ee4be4..d9abd58 100644 --- a/lib/vagrant-sshfs/cap/linux/sshfs_mount.rb +++ b/lib/vagrant-sshfs/cap/linux/sshfs_mount.rb @@ -1,5 +1,4 @@ require "log4r" - require "vagrant/util/retryable" require "tempfile" @@ -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 @@ -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 @@ -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 diff --git a/lib/vagrant-sshfs/version.rb b/lib/vagrant-sshfs/version.rb index 4566c3f..6c91f43 100644 --- a/lib/vagrant-sshfs/version.rb +++ b/lib/vagrant-sshfs/version.rb @@ -1,5 +1,5 @@ module VagrantPlugins module SyncedFolderSSHFS - VERSION = "1.1.0" + VERSION = "1.1.0.dev" end end diff --git a/vagrant-sshfs.gemspec b/vagrant-sshfs.gemspec index cfe5b33..ce96c83 100644 --- a/vagrant-sshfs.gemspec +++ b/vagrant-sshfs.gemspec @@ -21,6 +21,8 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] + spec.add_dependency 'win32-process' + spec.add_development_dependency "bundler", "~> 1.7" spec.add_development_dependency "rake", "~> 10.0" end