vagrant-instant-rsync-auto 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4117f71f6469b9f328afbfcc926054dd2c3b1751
4
+ data.tar.gz: db01eb256c20cb008295fedad381169c4b35a950
5
+ SHA512:
6
+ metadata.gz: b298fe657fb8ee55ab6919a0531f19472b1024f541b22e454fa5a3dd56ccf125b3309b737ad915c220d4e5449b91c8ee3d2d2bd581bd05506717ade64b7a03e8
7
+ data.tar.gz: 1782ff3141f6e2a1eebc070358cfd2dde42ed33a5d878eb1c0bd8320f72288d0a101505fd610cf2651a92ac996d425dcc2daaef98c0c26ad511fcd714d64a037
File without changes
@@ -0,0 +1 @@
1
+ 2.2.3
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vagrant-instant-rsync-auto.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git', tag: 'v1.8.1'
8
+ end
9
+
10
+ group :plugins do
11
+ gem 'vagrant-instant-rsync-auto', path: '.'
12
+ end
@@ -0,0 +1,120 @@
1
+ GIT
2
+ remote: https://github.com/mitchellh/vagrant.git
3
+ revision: c1c00e2f3cf69c579a5aa6922d67bb838a2de9cd
4
+ tag: v1.8.1
5
+ specs:
6
+ vagrant (1.8.1)
7
+ bundler (>= 1.5.2, <= 1.10.6)
8
+ childprocess (~> 0.5.0)
9
+ erubis (~> 2.7.0)
10
+ hashicorp-checkpoint (~> 0.1.1)
11
+ i18n (>= 0.6.0, <= 0.8.0)
12
+ listen (~> 3.0.2)
13
+ log4r (~> 1.1.9, < 1.1.11)
14
+ net-scp (~> 1.1.0)
15
+ net-sftp (~> 2.1)
16
+ net-ssh (~> 3.0.1)
17
+ nokogiri (= 1.6.3.1)
18
+ rb-kqueue (~> 0.2.0)
19
+ rest-client (>= 1.6.0, < 2.0)
20
+ wdm (~> 0.1.0)
21
+ winrm (~> 1.3)
22
+ winrm-fs (~> 0.2.2)
23
+
24
+ PATH
25
+ remote: .
26
+ specs:
27
+ vagrant-instant-rsync-auto (0.1.0)
28
+
29
+ GEM
30
+ remote: https://rubygems.org/
31
+ specs:
32
+ builder (3.2.2)
33
+ childprocess (0.5.9)
34
+ ffi (~> 1.0, >= 1.0.11)
35
+ coderay (1.1.1)
36
+ domain_name (0.5.20160310)
37
+ unf (>= 0.0.5, < 1.0.0)
38
+ erubis (2.7.0)
39
+ ffi (1.9.10)
40
+ gssapi (1.2.0)
41
+ ffi (>= 1.0.1)
42
+ gyoku (1.3.1)
43
+ builder (>= 2.1.2)
44
+ hashicorp-checkpoint (0.1.4)
45
+ http-cookie (1.0.2)
46
+ domain_name (~> 0.5)
47
+ httpclient (2.8.0)
48
+ i18n (0.7.0)
49
+ json (1.8.3)
50
+ listen (3.0.8)
51
+ rb-fsevent (~> 0.9, >= 0.9.4)
52
+ rb-inotify (~> 0.9, >= 0.9.7)
53
+ little-plugger (1.1.4)
54
+ log4r (1.1.10)
55
+ logging (1.8.2)
56
+ little-plugger (>= 1.1.3)
57
+ multi_json (>= 1.8.4)
58
+ method_source (0.8.2)
59
+ mime-types (2.99.1)
60
+ mini_portile (0.6.0)
61
+ multi_json (1.12.1)
62
+ net-scp (1.1.2)
63
+ net-ssh (>= 2.6.5)
64
+ net-sftp (2.1.2)
65
+ net-ssh (>= 2.6.5)
66
+ net-ssh (3.0.2)
67
+ netrc (0.11.0)
68
+ nokogiri (1.6.3.1)
69
+ mini_portile (= 0.6.0)
70
+ nori (2.6.0)
71
+ pry (0.10.3)
72
+ coderay (~> 1.1.0)
73
+ method_source (~> 0.8.1)
74
+ slop (~> 3.4)
75
+ rake (11.1.2)
76
+ rb-fsevent (0.9.7)
77
+ rb-inotify (0.9.7)
78
+ ffi (>= 0.5.0)
79
+ rb-kqueue (0.2.4)
80
+ ffi (>= 0.5.0)
81
+ rest-client (1.8.0)
82
+ http-cookie (>= 1.0.2, < 2.0)
83
+ mime-types (>= 1.16, < 3.0)
84
+ netrc (~> 0.7)
85
+ rubyntlm (0.4.0)
86
+ rubyzip (1.2.0)
87
+ slop (3.6.0)
88
+ unf (0.1.4)
89
+ unf_ext
90
+ unf_ext (0.0.7.2)
91
+ uuidtools (2.1.5)
92
+ wdm (0.1.1)
93
+ winrm (1.3.6)
94
+ builder (>= 2.1.2)
95
+ gssapi (~> 1.2)
96
+ gyoku (~> 1.0)
97
+ httpclient (~> 2.2, >= 2.2.0.2)
98
+ logging (>= 1.6.1, < 3.0)
99
+ nori (~> 2.0)
100
+ rubyntlm (~> 0.4.0)
101
+ uuidtools (~> 2.1.2)
102
+ winrm-fs (0.2.3)
103
+ erubis (~> 2.7)
104
+ logging (~> 1.6, >= 1.6.1)
105
+ rubyzip (~> 1.1)
106
+ winrm (~> 1.3.0)
107
+
108
+ PLATFORMS
109
+ ruby
110
+
111
+ DEPENDENCIES
112
+ bundler
113
+ json (~> 1.8.1)
114
+ pry
115
+ rake
116
+ vagrant!
117
+ vagrant-instant-rsync-auto!
118
+
119
+ BUNDLED WITH
120
+ 1.10.5
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Steven Merrill
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,24 @@
1
+ # vagrant-instant-rsync-auto
2
+
3
+ An rsync watcher for Vagrant 1.5.1+ that's much faster than the native
4
+ `vagrant rsync-auto` command.
5
+
6
+ ## Installation
7
+
8
+ To get started, you need to have Vagrant 1.5.1 installed on your Linux, Mac, or
9
+ Windows host machine. To install the plugin, use the following command.
10
+
11
+ ```bash
12
+ vagrant plugin install vagrant-instant-rsync-auto
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ This plugin should behave exactly the same as `vagrant rsync-auto`, and in
18
+ particular it uses the same configuration. So simply run
19
+ ```bash
20
+ vagrant instant-rsync-auto```
21
+ _in lieu_ of your usual `vagrant rsync-auto`, and you should be good to go!
22
+
23
+ Hopefully this will make it into Vagrant proper, there's a pull request opened
24
+ for that: https://github.com/mitchellh/vagrant/pull/7332
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,12 @@
1
+ # This file is required because Vagrant's plugin system expects
2
+ # an eponymous ruby file matching the rubygem.
3
+ #
4
+ # So this gem is called 'vagrant-instant-rsync-auto' and thus vagrant tries
5
+ # to require 'vagrant-instant-rsync-auto'
6
+
7
+ require 'vagrant-instant-rsync-auto/plugin'
8
+
9
+ module VagrantPlugins
10
+ module InstantRsyncAuto
11
+ end
12
+ end
@@ -0,0 +1,241 @@
1
+ require "log4r"
2
+ require 'optparse'
3
+ require "thread"
4
+
5
+ require "vagrant/action/builtin/mixin_synced_folders"
6
+ require "vagrant/util/busy"
7
+ require "vagrant/util/platform"
8
+
9
+ require_relative "../helper"
10
+
11
+ # This is to avoid a bug in nio 1.0.0. Remove around nio 1.0.1
12
+ if Vagrant::Util::Platform.windows?
13
+ ENV["NIO4R_PURE"] = "1"
14
+ end
15
+
16
+ require "listen"
17
+
18
+ module VagrantPlugins
19
+ module InstantRsyncAuto
20
+ module Command
21
+ class RsyncAuto < Vagrant.plugin('2', :command)
22
+ include Vagrant::Action::Builtin::MixinSyncedFolders
23
+
24
+ def self.synopsis
25
+ "syncs rsync synced folders automatically when files change, faster than Vagrant's native rsync-auto"
26
+ end
27
+
28
+ def execute
29
+ @logger = Log4r::Logger.new("vagrant::commands::instant-rsync-auto")
30
+ @rsync_helpers = {}
31
+
32
+ options = {}
33
+ opts = OptionParser.new do |o|
34
+ o.banner = "Usage: vagrant instant-rsync-auto [vm-name]"
35
+ o.separator ""
36
+ o.separator "Options:"
37
+ o.separator ""
38
+
39
+ o.on("--[no-]poll", "Force polling filesystem (slow)") do |poll|
40
+ options[:poll] = poll
41
+ end
42
+ end
43
+
44
+ # Parse the options and return if we don't have any target.
45
+ argv = parse_options(opts)
46
+ return if !argv
47
+
48
+ # Build up the paths that we need to listen to.
49
+ paths = {}
50
+ ignores = []
51
+ with_target_vms(argv) do |machine|
52
+ if machine.provider.capability?(:proxy_machine)
53
+ proxy = machine.provider.capability(:proxy_machine)
54
+ if proxy
55
+ machine.ui.warn(I18n.t(
56
+ "vagrant.rsync_proxy_machine",
57
+ name: machine.name.to_s,
58
+ provider: machine.provider_name.to_s))
59
+
60
+ machine = proxy
61
+ end
62
+ end
63
+
64
+ cached = synced_folders(machine, cached: true)
65
+ fresh = synced_folders(machine)
66
+ diff = synced_folders_diff(cached, fresh)
67
+ if !diff[:added].empty?
68
+ machine.ui.warn(I18n.t("vagrant.rsync_auto_new_folders"))
69
+ end
70
+
71
+ folders = cached[:rsync]
72
+ next if !folders || folders.empty?
73
+
74
+ # Get the SSH info for this machine so we can do an initial
75
+ # sync to the VM.
76
+ ssh_info = machine.ssh_info
77
+ if ssh_info
78
+ machine.ui.info(I18n.t("vagrant.rsync_auto_initial"))
79
+ folders.each do |id, folder_opts|
80
+ rsync_helper(machine, id, folder_opts).rsync_single
81
+ end
82
+ end
83
+
84
+ folders.each do |id, folder_opts|
85
+ # If we marked this folder to not auto sync, then
86
+ # don't do it.
87
+ next if folder_opts.key?(:auto) && !folder_opts[:auto]
88
+
89
+ hostpath = folder_opts[:hostpath]
90
+ hostpath = File.expand_path(hostpath, machine.env.root_path)
91
+ paths[hostpath] ||= []
92
+ paths[hostpath] << {
93
+ id: id,
94
+ machine: machine,
95
+ opts: folder_opts,
96
+ }
97
+
98
+ if folder_opts[:exclude]
99
+ Array(folder_opts[:exclude]).each do |pattern|
100
+ ignores << RsyncHelper.exclude_to_regexp(hostpath, pattern.to_s)
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ # Exit immediately if there is nothing to watch
107
+ if paths.empty?
108
+ @env.ui.info(I18n.t("vagrant.rsync_auto_no_paths"))
109
+ return 1
110
+ end
111
+
112
+ # Output to the user what paths we'll be watching
113
+ paths.keys.sort.each do |path|
114
+ paths[path].each do |path_opts|
115
+ path_opts[:machine].ui.info(I18n.t(
116
+ "vagrant.rsync_auto_path",
117
+ path: path.to_s,
118
+ ))
119
+ end
120
+ end
121
+
122
+ @logger.info("Listening to paths: #{paths.keys.sort.inspect}")
123
+ @logger.info("Ignoring #{ignores.length} paths:")
124
+ ignores.each do |ignore|
125
+ @logger.info(" -- #{ignore.to_s}")
126
+ end
127
+ @logger.info("Listening via: #{Listen::Adapter.select.inspect}")
128
+ callback = method(:callback).to_proc.curry[paths]
129
+ listopts = { ignore: ignores, force_polling: !!options[:poll] }
130
+ listener = Listen.to(*paths.keys, listopts, &callback)
131
+
132
+ # Create the callback that lets us know when we've been interrupted
133
+ queue = Queue.new
134
+ callback = lambda do
135
+ # This needs to execute in another thread because Thread
136
+ # synchronization can't happen in a trap context.
137
+ Thread.new { queue << true }
138
+ end
139
+
140
+ # Run the listener in a busy block so that we can cleanly
141
+ # exit once we receive an interrupt.
142
+ Vagrant::Util::Busy.busy(callback) do
143
+ listener.start
144
+ queue.pop
145
+ listener.stop if listener.state != :stopped
146
+ end
147
+
148
+ 0
149
+ end
150
+
151
+ # This is the callback that is called when any changes happen
152
+ def callback(paths, modified, added, removed)
153
+ @logger.info("File change callback called!")
154
+ @logger.info(" - Modified: #{modified.inspect}")
155
+ @logger.info(" - Added: #{added.inspect}")
156
+ @logger.info(" - Removed: #{removed.inspect}")
157
+
158
+ tosync = []
159
+ paths.each do |hostpath, folders|
160
+ # Find out if this path should be synced
161
+ found = catch(:done) do
162
+ [modified, added, removed].each do |changed|
163
+ changed.each do |listenpath|
164
+ throw :done, true if listenpath.start_with?(hostpath)
165
+ end
166
+ end
167
+
168
+ # Make sure to return false if all else fails so that we
169
+ # don't sync to this machine.
170
+ false
171
+ end
172
+
173
+ # If it should be synced, store it for later
174
+ tosync << folders if found
175
+ end
176
+
177
+ # Sync all the folders that need to be synced
178
+ tosync.each do |folders|
179
+ folders.each do |opts|
180
+ # Reload so we get the latest ID
181
+ opts[:machine].reload
182
+ if !opts[:machine].id || opts[:machine].id == ""
183
+ # Skip since we can't get SSH info without an ID
184
+ next
185
+ end
186
+
187
+ ssh_info = opts[:machine].ssh_info
188
+ begin
189
+ start = Time.now
190
+ rsync_helper(opts[:machine], opts[:id], opts[:opts]).rsync_single
191
+ finish = Time.now
192
+ time_spent_msg = "Time spent in rsync: #{finish-start} (in seconds)"
193
+ @logger.info(time_spent_msg)
194
+ opts[:machine].ui.info(time_spent_msg)
195
+ rescue Vagrant::Errors::MachineGuestNotReady
196
+ # Error communicating to the machine, probably a reload or
197
+ # halt is happening. Just notify the user but don't fail out.
198
+ opts[:machine].ui.error(I18n.t(
199
+ "vagrant.rsync_communicator_not_ready_callback"))
200
+ rescue Vagrant::Errors::RSyncError => e
201
+ # Error executing rsync, so show an error
202
+ opts[:machine].ui.error(I18n.t(
203
+ "vagrant.rsync_auto_rsync_error", message: e.to_s))
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ def rsync_helper(machine, folder_id, folder_opts)
210
+ machine_helpers = rsync_helpers_for_machine(machine)
211
+
212
+ rsync_helpers_for_id(machine, folder_id, folder_opts, machine_helpers)
213
+ end
214
+
215
+ def rsync_helpers_for_machine(machine)
216
+ @rsync_helpers[machine.id] ||= {}
217
+ end
218
+
219
+ def rsync_helpers_for_id(machine, folder_id, folder_opts, machine_helpers)
220
+ unless machine_helpers.key?(folder_id)
221
+ rsync_helper = nil
222
+ ssh_info = machine.ssh_info
223
+
224
+ if ssh_info
225
+ folder_opts = folder_opts.merge(
226
+ skip_rsync_pre_after_first_sync: true,
227
+ skip_rsync_post_after_first_sync: true
228
+ )
229
+
230
+ rsync_helper = RsyncHelper.new(machine, ssh_info, folder_opts)
231
+ end
232
+
233
+ machine_helpers[folder_id] = rsync_helper
234
+ end
235
+
236
+ machine_helpers[folder_id]
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,257 @@
1
+ require "vagrant/util/platform"
2
+ require "vagrant/util/subprocess"
3
+
4
+ module VagrantPlugins
5
+ module InstantRsyncAuto
6
+ # This is a helper that abstracts out the functionality of rsyncing
7
+ # folders so that it can be called from anywhere.
8
+ class RsyncHelper
9
+ def initialize(machine, ssh_info, opts)
10
+ @machine = machine
11
+
12
+ @opts = normalize_opts(opts, ssh_info)
13
+
14
+ @guestpath = guestpath
15
+ @hostpath = hostpath
16
+ @excludes = excludes
17
+
18
+ @rsync_command = rsync_command(ssh_info)
19
+ @rsync_command_opts = rsync_command_opts
20
+
21
+ @first_sync_done = false
22
+ end
23
+
24
+ def rsync_single
25
+ log_info
26
+
27
+ # If we have tasks to do before rsyncing, do those.
28
+ if !skip_rsync_pre? && @machine.guest.capability?(:rsync_pre)
29
+ @machine.guest.capability(:rsync_pre, @opts)
30
+ end
31
+
32
+ subprocess = if verbose?
33
+ Vagrant::Util::Subprocess.execute(*(@rsync_command + [@rsync_command_opts])) {
34
+ |io_name,data| data.each_line { |line|
35
+ @machine.ui.info("rsync[#{io_name}] -> #{line}") }
36
+ }
37
+ else
38
+ Vagrant::Util::Subprocess.execute(*(@rsync_command + [@rsync_command_opts]))
39
+ end
40
+
41
+ if subprocess.exit_code != 0
42
+ raise Vagrant::Errors::RSyncError,
43
+ command: @rsync_command.join(" "),
44
+ guestpath: @guestpath,
45
+ hostpath: @hostpath,
46
+ stderr: subprocess.stderr
47
+ end
48
+
49
+ # If we have tasks to do after rsyncing, do those.
50
+ if !skip_rsync_post? && @machine.guest.capability?(:rsync_post)
51
+ @machine.guest.capability(:rsync_post, @opts)
52
+ end
53
+
54
+ @first_sync_done = true
55
+ end
56
+
57
+ # This converts an rsync exclude pattern to a regular expression
58
+ # we can send to Listen.
59
+ def self.exclude_to_regexp(path, exclude)
60
+ start_anchor = false
61
+
62
+ if exclude.start_with?("/")
63
+ start_anchor = true
64
+ exclude = exclude[1..-1]
65
+ end
66
+
67
+ path = "#{path}/" if !path.end_with?("/")
68
+ regexp = "^#{Regexp.escape(path)}"
69
+ regexp += ".*" if !start_anchor
70
+
71
+ # This is REALLY ghetto, but its a start. We can improve and
72
+ # keep unit tests passing in the future.
73
+ exclude = exclude.gsub("**", "|||GLOBAL|||")
74
+ exclude = exclude.gsub("*", "|||PATH|||")
75
+ exclude = exclude.gsub("|||PATH|||", "[^/]*")
76
+ exclude = exclude.gsub("|||GLOBAL|||", ".*")
77
+ regexp += exclude
78
+
79
+ Regexp.new(regexp)
80
+ end
81
+
82
+ def self.rsync_single(machine, ssh_info, opts)
83
+ machine.ui.warn("WARNING: `VagrantPlugins::SyncedFolderRSync::RsyncHelper.rsync_single`")
84
+ machine.ui.warn("is a deprecated internal API. Please use an instance of that class instead.")
85
+
86
+ instance = new(machine, ssh_info, opts)
87
+ instance.rsync_single
88
+ end
89
+
90
+ private
91
+
92
+ def verbose?
93
+ @opts.include?(:verbose)
94
+ end
95
+
96
+ def normalize_opts(opts, ssh_info)
97
+ # Folder options
98
+ opts[:owner] ||= ssh_info[:username]
99
+ opts[:group] ||= ssh_info[:username]
100
+
101
+ opts
102
+ end
103
+
104
+ def guestpath
105
+ # if the guest has a guest path scrubber capability, use it
106
+ if @machine.guest.capability?(:rsync_scrub_guestpath)
107
+ @machine.guest.capability(:rsync_scrub_guestpath, @opts)
108
+ else
109
+ @opts[:guestpath]
110
+ end
111
+ end
112
+
113
+ def hostpath
114
+ hostpath = @opts[:hostpath]
115
+ hostpath = File.expand_path(hostpath, @machine.env.root_path)
116
+ hostpath = Vagrant::Util::Platform.fs_real_path(hostpath).to_s
117
+
118
+ if Vagrant::Util::Platform.windows?
119
+ # rsync for Windows expects cygwin style paths, always.
120
+ hostpath = Vagrant::Util::Platform.cygwin_path(hostpath)
121
+ end
122
+
123
+ # Make sure the host path ends with a "/" to avoid creating
124
+ # a nested directory...
125
+ if !hostpath.end_with?("/")
126
+ hostpath += "/"
127
+ end
128
+
129
+ hostpath
130
+ end
131
+
132
+ # Builds up the actual command to execute
133
+ def rsync_command(ssh_info)
134
+ [
135
+ "rsync",
136
+ rsync_args,
137
+ "-e", rsync_ssh_command(ssh_info),
138
+ @excludes.map { |e| ["--exclude", e] },
139
+ @hostpath,
140
+ "#{ssh_connection_info(ssh_info)}:#{@guestpath}",
141
+ ].flatten
142
+ end
143
+
144
+ def rsync_ssh_command(ssh_info)
145
+ # Create the path for the control sockets. We used to do this
146
+ # in the machine data dir but this can result in paths that are
147
+ # too long for unix domain sockets.
148
+ controlpath = File.join(Dir.tmpdir, "ssh.#{rand(1000)}")
149
+
150
+ [
151
+ "ssh -p #{ssh_info[:port]} " +
152
+ proxy_command(ssh_info) +
153
+ "-o ControlMaster=auto " +
154
+ "-o ControlPath=#{controlpath} " +
155
+ "-o ControlPersist=10m " +
156
+ "-o StrictHostKeyChecking=no " +
157
+ "-o IdentitiesOnly=true " +
158
+ "-o UserKnownHostsFile=/dev/null",
159
+ private_key_paths(ssh_info),
160
+ ].flatten.join(' ')
161
+ end
162
+
163
+ def proxy_command(ssh_info)
164
+ if ssh_info[:proxy_command]
165
+ "-o ProxyCommand='#{ssh_info[:proxy_command]}' "
166
+ else
167
+ ''
168
+ end
169
+ end
170
+
171
+ def private_key_paths(ssh_info)
172
+ ssh_info[:private_key_path].map { |p| "-i '#{p}'" }
173
+ end
174
+
175
+ def ssh_connection_info(ssh_info)
176
+ username = ssh_info[:username]
177
+ host = ssh_info[:host]
178
+
179
+ "#{username}@#{host}"
180
+ end
181
+
182
+ # Exclude some files by default, and any that might be configured
183
+ # by the user.
184
+ def excludes
185
+ excludes = ['.vagrant/']
186
+ excludes += Array(@opts[:exclude]).map(&:to_s) if @opts[:exclude]
187
+ excludes.uniq
188
+ end
189
+
190
+ # Builds the command-line arguments for rsync
191
+ def rsync_args
192
+ args = nil
193
+ args = Array(@opts[:args]).dup if @opts[:args]
194
+ args ||= ['--verbose', '--archive', '--delete', '-z', '--copy-links']
195
+
196
+ # On Windows, we have to set a default chmod flag to avoid permission issues
197
+ if Vagrant::Util::Platform.windows? && !args.any? { |arg| arg.start_with?('--chmod=') }
198
+ # Ensures that all non-masked bits get enabled
199
+ args << '--chmod=ugo=rwX'
200
+
201
+ # Remove the -p option if --archive is enabled (--archive equals -rlptgoD)
202
+ # otherwise new files will not have the destination-default permissions
203
+ args << '--no-perms' if args.include?('--archive') || args.include?('-a')
204
+ end
205
+
206
+ # Disable rsync's owner/group preservation (implied by --archive) unless
207
+ # specifically requested, since we adjust owner/group to match shared
208
+ # folder setting ourselves.
209
+ args << '--no-owner' unless args.include?('--owner') || args.include?('-o')
210
+ args << '--no-group' unless args.include?('--group') || args.include?('-g')
211
+
212
+ # Tell local rsync how to invoke remote rsync with sudo
213
+ rsync_path = @opts[:rsync_path]
214
+ if !rsync_path && @machine.guest.capability?(:rsync_command)
215
+ rsync_path = @machine.guest.capability(:rsync_command)
216
+ end
217
+ if rsync_path
218
+ args << "--rsync-path"<< rsync_path
219
+ end
220
+
221
+ args
222
+ end
223
+
224
+ def rsync_command_opts
225
+ # The working directory should be the root path
226
+ command_opts = {}
227
+ command_opts[:workdir] = @machine.env.root_path.to_s
228
+
229
+ if verbose?
230
+ command_opts[:notify] = [:stdout, :stderr]
231
+ end
232
+
233
+ command_opts
234
+ end
235
+
236
+ def log_info
237
+ @machine.ui.info(I18n.t(
238
+ "vagrant.rsync_folder", guestpath: @guestpath, hostpath: @hostpath))
239
+ if excludes.length > 1
240
+ @machine.ui.info(I18n.t(
241
+ "vagrant.rsync_folder_excludes", excludes: @excludes.inspect))
242
+ end
243
+ if verbose?
244
+ @machine.ui.info(I18n.t("vagrant.rsync_showing_output"));
245
+ end
246
+ end
247
+
248
+ def skip_rsync_pre?
249
+ @opts[:skip_rsync_pre] || @first_sync_done && @opts[:skip_rsync_pre_after_first_sync]
250
+ end
251
+
252
+ def skip_rsync_post?
253
+ @opts[:skip_rsync_post] || @first_sync_done && @opts[:skip_rsync_post_after_first_sync]
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'vagrant'
3
+ rescue LoadError
4
+ raise 'The Vagrant instant-rsync-auto plugin must be run within Vagrant.'
5
+ end
6
+
7
+ module VagrantPlugins
8
+ module InstantRsyncAuto
9
+ class Plugin < Vagrant.plugin('2')
10
+ name 'Instant Rsync Auto'
11
+ description 'A vagrant plugin that does the same as `vagrant rsync-auto`, except much faster!'
12
+
13
+ command 'instant-rsync-auto' do
14
+ require_relative 'command/instant_rsync_auto'
15
+ Command::RsyncAuto
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module InstantRsyncAuto
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-instant-rsync-auto/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'vagrant-instant-rsync-auto'
8
+ spec.version = VagrantPlugins::InstantRsyncAuto::VERSION
9
+ spec.authors = ['Jean Rouge']
10
+ spec.email = ['jer329@cornell.edu']
11
+ spec.summary = %q{A faster alternative to `vagrant rsync-auto`}
12
+ spec.homepage = 'https://github.com/wk8/vagrant-instant-rsync-auto'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject {|f| f.start_with?('example/files')}
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'pry'
23
+ # Make Vagrant work on Linux for development.
24
+ spec.add_development_dependency 'json', '~> 1.8.1'
25
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-instant-rsync-auto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jean Rouge
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.8.1
69
+ description:
70
+ email:
71
+ - jer329@cornell.edu
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".ruby-version"
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE
81
+ - README.md
82
+ - Rakefile
83
+ - lib/vagrant-instant-rsync-auto.rb
84
+ - lib/vagrant-instant-rsync-auto/command/instant_rsync_auto.rb
85
+ - lib/vagrant-instant-rsync-auto/helper.rb
86
+ - lib/vagrant-instant-rsync-auto/plugin.rb
87
+ - lib/vagrant-instant-rsync-auto/version.rb
88
+ - vagrant-instant-rsync-auto.gemspec
89
+ homepage: https://github.com/wk8/vagrant-instant-rsync-auto
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.5.1
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: A faster alternative to `vagrant rsync-auto`
113
+ test_files: []