├── .gitignore ├── CHANGELOG.md ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Vagrantfile ├── lib ├── vagrant-sshfs.rb └── vagrant-sshfs │ ├── actions.rb │ ├── builders │ ├── base.rb │ ├── guest.rb │ └── host.rb │ ├── command.rb │ ├── config.rb │ ├── errors.rb │ ├── plugin.rb │ └── version.rb ├── locales └── en.yml └── vagrant-sshfs.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | mountpoint 3 | .vagrant 4 | *.gem 5 | .idea 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## vagrant-sshfs 0.0.7 (Dec 8, 2014) ## 2 | 3 | * Smooth folders creation. 4 | * Unmount on machine Destroy/Halt/Suspend 5 | * Remount on machine Resume/Provision/Suspend 6 | 7 | *dmatora* 8 | 9 | ## vagrant-sshfs 0.0.6 (Oct 14, 2014) ## 10 | 11 | * Avoids StrictHostKeyChecking by default. 12 | 13 | *James O'Doherty* 14 | 15 | ## vagrant-sshfs 0.0.5 (May 26, 2014) ## 16 | 17 | * Allows to disable the plugin to run on demand. 18 | 19 | *Stéphane Klein* 20 | 21 | * Allows to mount a host folder on the guest machine 22 | 23 | *Adrian Olek* 24 | 25 | * Checks if the `sshfs` command is available 26 | 27 | *Fabio Kreusch* 28 | 29 | * Unmount/mount on vagrant reload 30 | 31 | *Fabio Kreusch* 32 | 33 | * Adds sshfs command 34 | 35 | *Fabio Kreusch* 36 | 37 | ## vagrant-sshfs 0.0.4 (March 5, 2014) ## 38 | 39 | * Allows to set a custom ssh username. 40 | 41 | *Daichi Nakajima* 42 | 43 | ## vagrant-sshfs 0.0.3 (December 15, 2013) ## 44 | 45 | * Uses an absolute source for the remote path. 46 | 47 | *Fabio Kreusch* 48 | 49 | ## vagrant-sshfs 0.0.2 (November 29, 2013) ## 50 | 51 | * Revoked on wrong push. 52 | 53 | *Fabio Kreusch* 54 | 55 | ## vagrant-sshfs 0.0.1 (September 27, 2013) ## 56 | 57 | * First release. 58 | 59 | *Fabio Kreusch* 60 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :development do 4 | gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.4.0' 5 | end 6 | 7 | gemspec 8 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/mitchellh/vagrant.git 3 | revision: 059de113a705f84ff165a4df049d38a2abcc60a8 4 | tag: v1.4.0 5 | specs: 6 | vagrant (1.4.0) 7 | childprocess (~> 0.3.7) 8 | erubis (~> 2.7.0) 9 | i18n (~> 0.6.0) 10 | log4r (~> 1.1.9) 11 | net-scp (~> 1.1.0) 12 | net-ssh (>= 2.6.6, < 2.8.0) 13 | 14 | PATH 15 | remote: . 16 | specs: 17 | vagrant-sshfs (0.0.6) 18 | 19 | GEM 20 | remote: https://rubygems.org/ 21 | specs: 22 | childprocess (0.3.9) 23 | ffi (~> 1.0, >= 1.0.11) 24 | erubis (2.7.0) 25 | ffi (1.9.3) 26 | i18n (0.6.9) 27 | log4r (1.1.10) 28 | net-scp (1.1.2) 29 | net-ssh (>= 2.6.5) 30 | net-ssh (2.7.0) 31 | rake (10.1.0) 32 | 33 | PLATFORMS 34 | ruby 35 | 36 | DEPENDENCIES 37 | bundler (~> 1.3) 38 | rake 39 | vagrant! 40 | vagrant-sshfs! 41 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Fabio Kreusch 2 | https://github.com/fabiokr/vagrant-sshfs 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vagrant-sshfs 2 | 3 | THIS PROJECT HAS MOVED TO https://github.com/dustymabe/vagrant-sshfs 4 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.require_plugin "vagrant-sshfs" 2 | 3 | Vagrant.configure("2") do |config| 4 | config.vm.box = "precise64" 5 | config.vm.box_url = "http://files.vagrantup.com/precise64.box" 6 | 7 | config.sshfs.paths = { "/home/vagrant/src" => "mountpoint" } 8 | end 9 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require "vagrant" 3 | rescue LoadError 4 | raise "The Vagrant sshfs plugin must be run within Vagrant" 5 | end 6 | 7 | require "vagrant-sshfs/version" 8 | require "vagrant-sshfs/errors" 9 | require "vagrant-sshfs/plugin" 10 | require "vagrant-sshfs/actions" 11 | require "vagrant-sshfs/command" 12 | 13 | module Vagrant 14 | module SshFS 15 | # Returns the path to the source of this plugin 16 | def self.source_root 17 | @source_root ||= Pathname.new(File.expand_path('../../', __FILE__)) 18 | end 19 | 20 | I18n.load_path << File.expand_path('locales/en.yml', source_root) 21 | I18n.reload! 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/actions.rb: -------------------------------------------------------------------------------- 1 | require 'vagrant-sshfs/builders/base' 2 | require 'vagrant-sshfs/builders/host' 3 | require 'vagrant-sshfs/builders/guest' 4 | 5 | module Vagrant 6 | module SshFS 7 | module Actions 8 | class Base 9 | def initialize(app, env) 10 | @machine = env[:machine] 11 | end 12 | 13 | private 14 | 15 | def get_builder(env) 16 | if @machine.config.sshfs.mount_on_guest 17 | Builders::Guest.new(env[:machine], env[:ui]) 18 | else 19 | Builders::Host.new(env[:machine], env[:ui]) 20 | end 21 | end 22 | end 23 | 24 | class Up < Base 25 | def call(env) 26 | get_builder(env).mount! if @machine.config.sshfs.enabled 27 | end 28 | end 29 | 30 | class Destroy < Base 31 | def call(env) 32 | get_builder(env).unmount! if @machine.config.sshfs.enabled 33 | end 34 | end 35 | 36 | class Reload < Up; end 37 | class Provision < Up; end 38 | class Suspend < Destroy; end 39 | class Resume < Up; end 40 | class Halt < Destroy; end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/builders/base.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | module Builders 4 | class Base 5 | attr_reader :machine, :ui 6 | 7 | def initialize(machine, ui) 8 | @machine, @ui = machine, ui 9 | end 10 | 11 | def mount! 12 | unmount! 13 | 14 | paths.each do |src, target| 15 | info("mounting", src: src, target: target) 16 | mount(src, target) 17 | end 18 | end 19 | 20 | def unmount! 21 | paths.each do |src, target| 22 | info("unmounting", src: target) 23 | unmount(target) 24 | end 25 | end 26 | 27 | def mount 28 | raise NotImplementedError 29 | end 30 | 31 | def paths 32 | machine.config.sshfs.paths 33 | end 34 | 35 | def info(key, *args) 36 | ui.info(i18n("info.#{key}", *args)) 37 | end 38 | 39 | def ask(key, *args) 40 | ui.ask(i18n("ask.#{key}", *args), :new_line => true) 41 | end 42 | 43 | def error(key, *args) 44 | ui.error(i18n("error.#{key}", *args)) 45 | raise Error, :base 46 | end 47 | 48 | def i18n(key, *args) 49 | I18n.t("vagrant.config.sshfs.#{key}", *args) 50 | end 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/builders/guest.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | module Builders 4 | class Guest < Base 5 | private 6 | 7 | def unmount(target) 8 | if machine.communicate.execute("which fusermount", error_check: false) == 0 9 | machine.communicate.execute("fusermount -u -q #{target}", error_check: false) 10 | else 11 | machine.communicate.execute("umount #{target}", error_check: false) 12 | end 13 | end 14 | 15 | def mount(src, target) 16 | source = File.expand_path(src) 17 | 18 | status = machine.communicate.execute( 19 | "echo \"#{password}\" | sshfs -o allow_other -o password_stdin #{username}@#{host}:#{source} #{target}", 20 | :sudo => true, :error_check => false) 21 | 22 | if status != 0 23 | error('not_mounted', src: source, target: target) 24 | end 25 | end 26 | 27 | def host 28 | machine.config.sshfs.host_addr 29 | end 30 | 31 | def username 32 | `whoami`.strip 33 | end 34 | 35 | def password 36 | Shellwords.escape(ui.ask(i18n("ask.pass", :user => "#{username}@#{host}"), :echo => false)) 37 | end 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/builders/host.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | module Vagrant 4 | module SshFS 5 | module Builders 6 | class Host < Base 7 | private 8 | 9 | def unmount(target) 10 | if `which fusermount`.empty? 11 | `killall -9 sshfs 2>/dev/null` 12 | `umount -f #{target}` 13 | else 14 | `fusermount -u -q #{target}` 15 | end 16 | end 17 | 18 | def mount(src, target) 19 | `#{sshfs_bin} -p #{port} #{username}@#{host}:#{check_src!(src)} #{check_target!(target)} -o IdentityFile=#{private_key} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ` 20 | end 21 | 22 | def ssh_info 23 | machine.ssh_info 24 | end 25 | 26 | def username 27 | machine.config.sshfs.username ||= ssh_info[:username] 28 | end 29 | 30 | def host 31 | ssh_info[:host] 32 | end 33 | 34 | def port 35 | ssh_info[:port] 36 | end 37 | 38 | def private_key 39 | Array(ssh_info[:private_key_path]).first 40 | end 41 | 42 | def sshfs_bin 43 | bin = `which sshfs`.chomp 44 | 45 | if bin.empty? 46 | error("bin_not_found") 47 | else 48 | bin 49 | end 50 | end 51 | 52 | def check_src!(src) 53 | unless machine.communicate.test("test -d #{src}") 54 | if machine.config.sshfs.prompt_create_folders == false || ask("create_src", src: src) == "y" 55 | if machine.config.sshfs.sudo 56 | machine.communicate.execute("sudo su -c 'mkdir -p #{src}'") 57 | else 58 | machine.communicate.execute("mkdir -p #{src}") 59 | end 60 | info("created_src", src: src) 61 | else 62 | error("not_created_src", src: src) 63 | end 64 | end 65 | 66 | src 67 | end 68 | 69 | def check_target!(target) 70 | folder = target_folder(target) 71 | 72 | # entries return . and .. when empty 73 | if File.exist?(folder) && Dir.entries(folder).size > 2 74 | error("non_empty_target", target: folder) 75 | elsif !File.exist?(folder) 76 | if machine.config.sshfs.prompt_create_folders == false || ask("create_target", target: folder) == "y" 77 | FileUtils.mkdir_p(folder) 78 | info("created_target", target: folder) 79 | else 80 | error("not_created_target", target: folder) 81 | end 82 | end 83 | 84 | folder 85 | end 86 | 87 | def target_folder(target) 88 | File.expand_path(target) 89 | end 90 | end 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/command.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | class Command < Vagrant.plugin(2, :command) 4 | def self.synopsis 5 | "mounts sshfs shared folders" 6 | end 7 | 8 | def execute 9 | with_target_vms do |machine| 10 | get_builder(machine).mount! 11 | end 12 | 13 | 0 14 | end 15 | 16 | private 17 | 18 | def get_builder(machine) 19 | if machine.config.sshfs.mount_on_guest 20 | Builders::Guest.new(machine, @env.ui) 21 | else 22 | Builders::Host.new(machine, @env.ui) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/config.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | class Config < Vagrant.plugin(2, :config) 4 | attr_accessor :paths 5 | attr_accessor :username 6 | attr_accessor :enabled 7 | attr_accessor :prompt_create_folders 8 | attr_accessor :sudo 9 | attr_accessor :mount_on_guest 10 | attr_accessor :host_addr 11 | 12 | def initialize 13 | @paths = {} 14 | @username = nil 15 | @enabled = true 16 | @prompt_create_folders = false 17 | @sudo = true 18 | end 19 | 20 | def merge(other) 21 | super.tap do |result| 22 | result.paths = @paths.merge(other.paths) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/errors.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | class Error < Errors::VagrantError 4 | error_namespace("vagrant.config.sshfs.error") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/plugin.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | class Plugin < Vagrant.plugin("2") 4 | name "vagrant-sshfs" 5 | description "A Vagrant plugin that mounts sshfs in the host machine." 6 | 7 | config "sshfs" do 8 | require "vagrant-sshfs/config" 9 | Config 10 | end 11 | 12 | action_hook(:sshfs, :machine_action_up) do |hook| 13 | hook.append(Vagrant::SshFS::Actions::Up) 14 | end 15 | 16 | action_hook(:sshfs, :machine_action_reload) do |hook| 17 | hook.append(Vagrant::SshFS::Actions::Reload) 18 | end 19 | 20 | action_hook(:sshfs, :machine_action_provision) do |hook| 21 | hook.append(Vagrant::SshFS::Actions::Provision) 22 | end 23 | 24 | action_hook(:sshfs, :machine_action_suspend) do |hook| 25 | hook.append(Vagrant::SshFS::Actions::Suspend) 26 | end 27 | 28 | action_hook(:sshfs, :machine_action_resume) do |hook| 29 | hook.append(Vagrant::SshFS::Actions::Resume) 30 | end 31 | 32 | action_hook(:sshfs, :machine_action_halt) do |hook| 33 | hook.append(Vagrant::SshFS::Actions::Halt) 34 | end 35 | 36 | action_hook(:sshfs, :machine_action_destroy) do |hook| 37 | hook.append(Vagrant::SshFS::Actions::Destroy) 38 | end 39 | 40 | command "sshfs" do 41 | Vagrant::SshFS::Command 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/vagrant-sshfs/version.rb: -------------------------------------------------------------------------------- 1 | module Vagrant 2 | module SshFS 3 | VERSION = "0.0.7" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /locales/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | vagrant: 3 | config: 4 | sshfs: 5 | info: 6 | unmounting: "Unmounting SSHFS for `%{src}`" 7 | mounting: "Mounting SSHFS for `%{src}` to `%{target}`" 8 | unmounted: "Unmounted SSHFS for `%{target}`" 9 | created_src: "Created src `%{src}`" 10 | created_target: "Created target `%{target}`" 11 | ask: 12 | create_src: "Source folder `%{src}` does not exist, create? (y/n)" 13 | create_target: "Target folder `%{target}` does not exist, create? (y/n)" 14 | pass: "Password for `%{user}`:" 15 | error: 16 | base: "vagrant-sshfs failed and couldn't proceed" 17 | non_empty_target: "Non empty target folder `%{target}`" 18 | not_created_src: "Source folder `%{src}` was not created" 19 | not_created_target: "Target folder `%{target}` was not created" 20 | not_mounted: "Error when mounting `%{src}` to `%{target}`" 21 | bin_not_found: "Could not find sshfs bin in the host machine. Please make sure it is installed." 22 | -------------------------------------------------------------------------------- /vagrant-sshfs.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'vagrant-sshfs/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "vagrant-sshfs" 8 | spec.version = Vagrant::SshFS::VERSION 9 | spec.authors = ["fabiokr"] 10 | spec.email = ["fabiokr@gmail.com"] 11 | spec.description = "A Vagrant plugin that mounts folders with sshfs in the host machine." 12 | spec.summary = spec.description 13 | spec.homepage = "https://github.com/fabiokr/vagrant-sshfs" 14 | spec.license = "MIT" 15 | 16 | spec.files = `git ls-files`.split($/) 17 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 18 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 19 | spec.require_paths = ["lib"] 20 | 21 | spec.add_development_dependency "bundler", "~> 1.3" 22 | spec.add_development_dependency "rake" 23 | end 24 | --------------------------------------------------------------------------------