# The MIT License (MIT) # Copyright (c) 2013 Mitchell Hashimoto # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. require 'vagrant/util/subprocess' require 'vagrant/util/scoped_hash_override' require 'vagrant/util/which' module VagrantPlugins module VCloud module Action # This class syncs Vagrant folders using RSYNC, this code has been ported # from vagrant-aws (https://github.com/mitchellh/vagrant-aws) class SyncFolders include Vagrant::Util::ScopedHashOverride def initialize(app, env) @app = app @logger = Log4r::Logger.new('vagrant_vcloud::action::sync_folders') end def call(env) @app.call(env) ssh_info = env[:machine].ssh_info unless Vagrant::Util::Which.which('rsync') env[:ui].warn( I18n.t( 'vagrant_vcloud.sync.rsync_not_found_warning', :side => 'host' ) ) return end if env[:machine].communicate.execute('which rsync', :error_check => false) != 0 env[:ui].warn( I18n.t( 'vagrant_vcloud.sync.rsync_not_found_warning', :side => 'guest' ) ) return end env[:machine].config.vm.synced_folders.each do |id, data| data = scoped_hash_override(data, :vCloud) # Ignore disabled shared folders next if data[:disabled] hostpath = File.expand_path(data[:hostpath], env[:root_path]) guestpath = data[:guestpath] # Make sure there is a trailing slash on the host path to # avoid creating an additional directory with rsync hostpath = "#{hostpath}/" if hostpath !~ /\/$/ # on windows rsync.exe requires cygdrive-style paths if Vagrant::Util::Platform.windows? hostpath = hostpath.gsub(/^(\w):/) { "/cygdrive/\1" } end env[:ui].info( I18n.t( 'vagrant_vcloud.sync.rsync_folder', :hostpath => hostpath, :guestpath => guestpath ) ) # Create the host path if it doesn't exist and option flag is set if data[:create] begin FileUtils.mkdir_p(hostpath) rescue => err raise Errors::MkdirError, :hostpath => hostpath, :err => err end end # Create the guest path env[:machine].communicate.sudo("mkdir -p '#{guestpath}'") env[:machine].communicate.sudo( "chown -R #{ssh_info[:username]} '#{guestpath}'" ) # collect rsync excludes specified :rsync_excludes=>['path1',...] # in synced_folder options excludes = [ '.vagrant/', 'Vagrantfile', *Array(data[:rsync_excludes]) ].uniq # Rsync over to the guest path using the SSH info command = [ 'rsync', '--verbose', '--archive', '-z', *excludes.map { |e|['--exclude', e] }.flatten, '-e', "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no " + "#{ssh_key_options(ssh_info)}", hostpath, "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}" ] # we need to fix permissions when using rsync.exe on windows, see # http://stackoverflow.com/questions/5798807/rsync-permission- # denied-created-directories-have-no-permissions if Vagrant::Util::Platform.windows? command.insert(1, '--chmod', 'ugo=rwX') end r = Vagrant::Util::Subprocess.execute(*command) if r.exit_code != 0 fail Errors::RsyncError, :guestpath => guestpath, :hostpath => hostpath, :stderr => r.stderr end end end private def ssh_key_options(ssh_info) # Ensure that `private_key_path` is an Array (for Vagrant < 1.4) Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join end end end end end