vagrant-unison2 1.2.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f1a063b4601b5928a533c46d120bbf4cb7ba55ec
4
- data.tar.gz: 2394dcb6b9be96e96def0eb797961e2c78b5b571
3
+ metadata.gz: ed6f4a0aff6d665d92570db31cbf86bd6b4a90c8
4
+ data.tar.gz: 6406f1e1242035d1cd69eb8677da1883edb01e71
5
5
  SHA512:
6
- metadata.gz: 584554bbfcd84e1f7fa1b2f54536f9635388e4b22cfd8d751d2753c5994445e911a92024e0cc3387e6e08eaa46bbb8181222961005ae3c6cc252fe1b2432a9bf
7
- data.tar.gz: 133b1bff2cefb725c5bd1a3600b397b18078576660426abbe50d25e3addd04dfcbcad9a83ffac6176657814c62e913593ef768158d2e8b0784d8f52dca974d89
6
+ metadata.gz: c6eae3bfd496db045c71d466f784313c5f0c9db7b340c2c6d87733336427004baf12ba6dfd38bc8c2dbbd08feccd82f2fde91e6c215188b0c49560e5fe9d565f
7
+ data.tar.gz: 2396282604d87889dccee06dace63950a76733e20e86f3f5587c890087d774a2806540d8b3cd8b13c8591629c78a603de91a9e438a30e27708b9945166953b47
data/README.md CHANGED
@@ -19,10 +19,10 @@ to your Vagrant VM (local or on AWS). Under the covers it uses [Unison](http://
19
19
  * Ubuntu Trusty (14.04):
20
20
  * `sudo add-apt-repository ppa:eugenesan/ppa`
21
21
  * `sudo apt-get update`
22
- * `sudo apt-get install unison=2.48.3-1~eugenesan~trusty1`
22
+ * `sudo apt-get install unison=2.48.3-1ubuntu1.02~eugenesan~trusty2`
23
23
  * Other 64-bit Linux:
24
24
  * Install package from `http://ftp5.gwdg.de/pub/linux/archlinux/extra/os/x86_64/unison-2.48.3-2-x86_64.pkg.tar.xz`. (Install at your own risk, this is a plain http link. If someone knows of a signed version, checksum, or https host let me know so I can update it).
25
- * On Windows, download [2.40.102](http://alan.petitepomme.net/unison/assets/Unison-2.40.102.zip), unzip, rename `Unison-2.40.102 Text.exe` to `unison.exe` and copy to somewhere in your path.
25
+ * On Windows, download [2.48.3](http://www.pps.univ-paris-diderot.fr/~vouillon/unison/unison 2.48.3.zip), unzip, rename `unison-2.48.3 text.exe` to `unison.exe` and copy to somewhere in your path. Alternatively, install [using Chocolatey](https://chocolatey.org/packages/unison).
26
26
 
27
27
  2. Install using standard Vagrant 1.1+ plugin installation methods.
28
28
  * `vagrant plugin install vagrant-unison2`
@@ -44,15 +44,19 @@ to your Vagrant VM (local or on AWS). Under the covers it uses [Unison](http://
44
44
  # Optional configs
45
45
  # File patterns to ignore when syncing. Ensure you don't have spaces between the commas!
46
46
  config.unison.ignore = "Name {.DS_Store,.git,node_modules}" # Default: none
47
+
47
48
  # SSH connection details for Vagrant to communicate with VM.
48
49
  config.unison.ssh_host = "10.0.0.1" # Default: '127.0.0.1'
49
50
  config.unison.ssh_port = 22 # Default: 2222
50
51
  config.unison.ssh_user = "deploy" # Default: 'vagrant'
51
52
  config.unison.perms = 0 # if you get "properties changed on both sides" error
53
+
52
54
  # `vagrant unison-sync-polling` command will restart unison in VM if memory
53
55
  # usage gets above this threshold (in MB).
54
56
  config.unison.mem_cap_mb = 500 # Default: 200
55
57
 
58
+ # Change polling interval (in seconds) at which to sync changes
59
+ config.unison.repeat = 5 # Default: 1
56
60
  end
57
61
  ```
58
62
 
@@ -1,7 +1,6 @@
1
1
  require "log4r"
2
2
  require "vagrant"
3
3
  require "thread"
4
- require 'listen'
5
4
 
6
5
  require_relative 'unison_paths'
7
6
  require_relative 'ssh_command'
@@ -10,76 +9,15 @@ require_relative 'unison_sync'
10
9
 
11
10
  module VagrantPlugins
12
11
  module Unison
13
- class Command < Vagrant.plugin("2", :command)
12
+ class CommandOnce < Vagrant.plugin("2", :command)
14
13
  include UnisonSync
15
14
 
16
- def execute
17
- with_target_vms do |machine|
18
- paths = UnisonPaths.new(@env, machine)
19
- host_path = paths.host
20
-
21
- sync(machine, paths)
22
-
23
- @env.ui.info "Watching #{host_path} for changes..."
24
-
25
- listener = Listen.to(host_path) do |modified, added, removed|
26
- @env.ui.info "Detected modifications to #{modified.inspect}" unless modified.empty?
27
- @env.ui.info "Detected new files #{added.inspect}" unless added.empty?
28
- @env.ui.info "Detected deleted files #{removed.inspect}" unless removed.empty?
29
-
30
- sync(machine, paths)
31
- end
32
-
33
- queue = Queue.new
34
-
35
- callback = lambda do
36
- # This needs to execute in another thread because Thread
37
- # synchronization can't happen in a trap context.
38
- Thread.new { queue << true }
39
- end
40
-
41
- # Run the listener in a busy block so that we can cleanly
42
- # exit once we receive an interrupt.
43
- Vagrant::Util::Busy.busy(callback) do
44
- listener.start
45
- queue.pop
46
- listener.stop if listener.paused? || listener.processing?
47
- end
48
- end
49
-
50
- 0
15
+ def self.synopsis
16
+ "sync the unison shared folder once"
51
17
  end
52
18
 
53
- def sync(machine, paths)
54
- execute_sync_command(machine) do |command|
55
- command.batch = true
56
-
57
- @env.ui.info "Running #{command.to_s}"
58
-
59
- r = Vagrant::Util::Subprocess.execute(*command.to_a)
60
-
61
- case r.exit_code
62
- when 0
63
- @env.ui.info "Unison completed succesfully"
64
- when 1
65
- @env.ui.info "Unison completed - all file transfers were successful; some files were skipped"
66
- when 2
67
- @env.ui.info "Unison completed - non-fatal failures during file transfer: #{r.stderr}"
68
- else
69
- raise Vagrant::Errors::UnisonError,
70
- :command => command.to_s,
71
- :guestpath => paths.guest,
72
- :hostpath => paths.host,
73
- :stderr => r.stderr
74
- end
75
- end
76
- end
77
- end
78
-
79
- class CommandOnce < Vagrant.plugin("2", :command)
80
- include UnisonSync
81
-
82
19
  def execute
20
+ status = nil
83
21
  with_target_vms do |machine|
84
22
  execute_sync_command(machine) do |command|
85
23
  command.batch = true
@@ -89,11 +27,15 @@ module VagrantPlugins
89
27
  @env.ui.info "Running unison once"
90
28
  @env.ui.info " #{command}"
91
29
 
92
- system(command)
30
+ status = system(command)
31
+ @env.ui.info "**** unison exited. success: #{status} ****"
93
32
  end
94
33
  end
95
-
96
- 0
34
+ if status
35
+ return 0
36
+ else
37
+ return 1
38
+ end
97
39
  end
98
40
  end
99
41
 
@@ -101,10 +43,14 @@ module VagrantPlugins
101
43
  include UnisonSync
102
44
  attr_accessor :bg_thread
103
45
 
46
+ def self.synopsis
47
+ "sync the unison shared folder forever, by polling for changes"
48
+ end
49
+
104
50
  def execute
51
+ status = nil
105
52
  with_target_vms do |machine|
106
53
  @bg_thread = watch_vm_for_memory_leak(machine)
107
-
108
54
  execute_sync_command(machine) do |command|
109
55
  command.repeat = true
110
56
  command.terse = true
@@ -122,7 +68,8 @@ module VagrantPlugins
122
68
  begin
123
69
  sleep 2 if exit_on_next_sigint
124
70
  exit_on_next_sigint = false
125
- system(command)
71
+ status = system(command)
72
+ @env.ui.info "**** unison exited. success: #{status} ****"
126
73
  rescue Interrupt
127
74
  if exit_on_next_sigint
128
75
  Thread.kill(@bg_thread) if @bg_thread
@@ -136,7 +83,11 @@ module VagrantPlugins
136
83
  end
137
84
  end
138
85
  end
139
- 0
86
+ if status
87
+ return 0
88
+ else
89
+ return 1
90
+ end
140
91
  end
141
92
 
142
93
  def watch_vm_for_memory_leak(machine)
@@ -145,7 +96,9 @@ module VagrantPlugins
145
96
  while true
146
97
  sleep 15
147
98
  total_mem = `#{ssh_command_text} 'free -m | egrep "^Mem:" | awk "{print \\$2}"' 2>/dev/null`
148
- _unison_proc_returnval = `#{ssh_command_text} 'ps aux | grep "[u]nison -server" | awk "{print \\$2, \\$4}"' 2>/dev/null`
99
+ _unison_proc_returnval = (
100
+ `#{ssh_command_text} 'ps aux | grep "[u]nison -server" | awk "{print \\$2, \\$4}"' 2>/dev/null`
101
+ )
149
102
  if _unison_proc_returnval == ''
150
103
  puts "Unison not running in VM"
151
104
  next
@@ -164,7 +117,9 @@ module VagrantPlugins
164
117
  end
165
118
 
166
119
  class CommandCleanup < Vagrant.plugin("2", :command)
167
- include UnisonSync
120
+ def self.synopsis
121
+ "remove all unison supporting state on local and remote system"
122
+ end
168
123
 
169
124
  def execute
170
125
  with_target_vms do |machine|
@@ -190,6 +145,10 @@ module VagrantPlugins
190
145
  class CommandInteract < Vagrant.plugin("2", :command)
191
146
  include UnisonSync
192
147
 
148
+ def self.synopsis
149
+ "run unison in interactive mode, to resolve conflicts"
150
+ end
151
+
193
152
  def execute
194
153
  with_target_vms do |machine|
195
154
  execute_sync_command(machine) do |command|
@@ -15,7 +15,7 @@ module VagrantPlugins
15
15
 
16
16
  # Pattern of files to ignore.
17
17
  #
18
- # @return [String]
18
+ # @return [String, Array<String>]
19
19
  attr_accessor :ignore
20
20
 
21
21
  # Repeat speed.
@@ -49,7 +49,13 @@ module VagrantPlugins
49
49
  # @return [int]
50
50
  attr_accessor :perms
51
51
 
52
- def initialize(region_specific=false)
52
+ # Airlab-specific config option to leave off the Vagrant identity file, so
53
+ # SSH will just use ssh-agent
54
+ #
55
+ # @return [Boolean]
56
+ attr_accessor :ssh_use_agent
57
+
58
+ def initialize(region_specific = false)
53
59
  @host_folder = UNSET_VALUE
54
60
  @guest_folder = UNSET_VALUE
55
61
  @ignore = UNSET_VALUE
@@ -57,6 +63,7 @@ module VagrantPlugins
57
63
  @ssh_host = UNSET_VALUE
58
64
  @ssh_port = UNSET_VALUE
59
65
  @ssh_user = UNSET_VALUE
66
+ @ssh_use_agent = UNSET_VALUE
60
67
  @mem_cap_mb = UNSET_VALUE
61
68
  @perms = UNSET_VALUE
62
69
  end
@@ -72,6 +79,7 @@ module VagrantPlugins
72
79
  @ssh_user = 'vagrant' if @ssh_user == UNSET_VALUE
73
80
  @mem_cap_mb = 200 if @mem_cap_mb == UNSET_VALUE
74
81
  @perms = nil if @perms == UNSET_VALUE
82
+ @ssh_use_agent = false if @ssh_use_agent == UNSET_VALUE
75
83
 
76
84
  # Mark that we finalized
77
85
  @__finalized = true
@@ -16,7 +16,7 @@ module VagrantPlugins
16
16
  name "Unison"
17
17
  description <<-DESC
18
18
  This plugin syncs files over SSH from a local folder
19
- to your Vagrant VM (local or on AWS).
19
+ to your Vagrant VM (local or on AWS).
20
20
  DESC
21
21
 
22
22
  config "unison" do
@@ -24,16 +24,6 @@ module VagrantPlugins
24
24
  Config
25
25
  end
26
26
 
27
- command "unison-sync" do
28
- # Setup logging and i18n
29
- setup_logging
30
- setup_i18n
31
-
32
- #Return the command
33
- require_relative "command"
34
- Command
35
- end
36
-
37
27
  command "unison-sync-once" do
38
28
  setup_logging
39
29
  setup_i18n
@@ -1,13 +1,15 @@
1
1
  module VagrantPlugins
2
2
  module Unison
3
3
  class ShellCommand
4
- def initialize machine, unison_paths, ssh_command
4
+ def initialize(machine, unison_paths, ssh_command)
5
5
  @machine = machine
6
6
  @unison_paths = unison_paths
7
7
  @ssh_command = ssh_command
8
8
  end
9
9
 
10
10
  attr_accessor :batch, :repeat, :terse
11
+ attr_accessor :force_remote, :force_local
12
+ attr_accessor :prefer_remote, :prefer_local
11
13
 
12
14
  def to_a
13
15
  args.map do |arg|
@@ -25,24 +27,47 @@ module VagrantPlugins
25
27
  def args
26
28
  _args = [
27
29
  'unison',
28
- @unison_paths.host,
29
- @ssh_command.uri(@unison_paths),
30
+ local_root_arg,
31
+ remote_root_arg,
30
32
  batch_arg,
31
33
  terse_arg,
32
34
  repeat_arg,
33
35
  ignore_arg,
34
36
  perms_arg,
35
- ['-sshargs', %("#{@ssh_command.ssh_args}")],
37
+ force_arg,
38
+ prefer_arg,
39
+ ssh_args,
36
40
  ].flatten.compact
37
41
  _args
38
42
  end
39
43
 
44
+ def local_root_arg
45
+ @unison_paths.host
46
+ end
47
+
48
+ def remote_root_arg
49
+ @ssh_command.uri(@unison_paths)
50
+ end
51
+
52
+ def ssh_args
53
+ ['-sshargs', %("#{@ssh_command.ssh_args}")]
54
+ end
55
+
40
56
  def batch_arg
41
57
  '-batch' if batch
42
58
  end
43
59
 
44
60
  def ignore_arg
45
- ['-ignore', %("#{@machine.config.unison.ignore}")] if @machine.config.unison.ignore
61
+ patterns = []
62
+ if @machine.config.unison.ignore.is_a? ::Array
63
+ patterns += @machine.config.unison.ignore
64
+ elsif @machine.config.unison.ignore
65
+ patterns << @machine.config.unison.ignore
66
+ end
67
+
68
+ patterns.map do |pattern|
69
+ ['-ignore', %("#{pattern}")]
70
+ end
46
71
  end
47
72
 
48
73
  def perms_arg
@@ -56,6 +81,37 @@ module VagrantPlugins
56
81
  def terse_arg
57
82
  '-terse' if terse
58
83
  end
84
+
85
+ # from the docs:
86
+ #
87
+ # Including the preference -force root causes Unison to resolve all
88
+ # differences (even non-conflicting changes) in favor of root. This
89
+ # effectively changes Unison from a synchronizer into a mirroring
90
+ # utility. You can also specify -force newer (or -force older) to force
91
+ # Unison to choose the file with the later (earlier) modtime. In this
92
+ # case, the -times preference must also be enabled. This preference is
93
+ # overridden by the forcepartial preference. This preference should be
94
+ # used only if you are sure you know what you are doing!
95
+ #
96
+ # soo. I'm not sure if I know what I'm doing. Need to make sure that this
97
+ # doesn't end up deleting .git or some other ignored but critical
98
+ # directory.
99
+ def force_arg
100
+ return ['-force', local_root_arg] if force_local
101
+ return ['-force', remote_root_arg] if force_remote
102
+ end
103
+
104
+ # from the docs, via Daniel Low (thx daniel):
105
+ #
106
+ # Including the preference -prefer root causes Unison always to resolve
107
+ # conflicts in favor of root, rather than asking for guidance from the
108
+ # user.
109
+ #
110
+ # This is much safer than -force
111
+ def prefer_arg
112
+ return ['-prefer', local_root_arg] if prefer_local
113
+ return ['-prefer', remote_root_arg] if prefer_remote
114
+ end
59
115
  end
60
116
  end
61
117
  end
@@ -19,8 +19,7 @@ module VagrantPlugins
19
19
  #{proxy_command}
20
20
  -o StrictHostKeyChecking=no
21
21
  -o UserKnownHostsFile=/dev/null
22
- -o IdentitiesOnly=yes
23
- #{key_paths}
22
+ #{identity}
24
23
  ).compact.join(' ')
25
24
  end
26
25
 
@@ -39,8 +38,16 @@ module VagrantPlugins
39
38
  "-o ProxyCommand='#{command}'"
40
39
  end
41
40
 
41
+ def identity
42
+ if @machine.config.unison.ssh_use_agent
43
+ ''
44
+ else
45
+ (%w(-o IdentitiesOnly=yes) << key_paths).join(' ')
46
+ end
47
+ end
48
+
42
49
  def key_paths
43
- @machine.ssh_info[:private_key_path].map { |p| "-i #{p}" }.join(' ')
50
+ @machine.ssh_info[:private_key_path].map { |p| "-i #{p.shellescape}" }.join(' ')
44
51
  end
45
52
  end
46
53
  end
@@ -1,7 +1,12 @@
1
+ require "optparse"
2
+
1
3
  module VagrantPlugins
2
4
  module Unison
5
+ # mixin providing common functionality for our vagrant commands
3
6
  module UnisonSync
4
7
  def execute_sync_command(machine)
8
+ parse_options!
9
+
5
10
  unison_paths = UnisonPaths.new(@env, machine)
6
11
  guest_path = unison_paths.guest
7
12
  host_path = unison_paths.host
@@ -15,8 +20,78 @@ module VagrantPlugins
15
20
  ssh_command = SshCommand.new(machine)
16
21
  shell_command = ShellCommand.new(machine, unison_paths, ssh_command)
17
22
 
23
+ shell_command.prefer_local = options[:prefer_local]
24
+ shell_command.prefer_remote = options[:prefer_remote]
25
+ shell_command.force_local = options[:force_local]
26
+ shell_command.force_remote = options[:force_remote]
27
+
18
28
  yield shell_command
19
29
  end
30
+
31
+ def parse_options!
32
+ # parse_options(option_parser) is provided by vagrant, but
33
+ # documentation is scarse. Best way to view the docs (imo) is to put
34
+ # a binding.pry in here and then type `? parse_options`
35
+ @parsed_argv ||= parse_options(options_parser)
36
+
37
+ if options[:verbose]
38
+ @env.ui.info "Options: #{options}"
39
+ end
40
+
41
+ # According to the docs:
42
+ # > If parse_options returns `nil`, then you should assume that
43
+ # > help was printed and parsing failed.
44
+ if @parsed_argv == nil
45
+ exit 1
46
+ end
47
+ end
48
+
49
+ def options
50
+ @options ||= {
51
+ :prefer_local => false,
52
+ :prefer_remote => false,
53
+ :force_local => false,
54
+ :force_remote => false,
55
+ :verbose => false,
56
+ }
57
+ end
58
+
59
+ def options_parser
60
+ @option_parser ||= OptionParser.new do |o|
61
+ o.banner = "Usage: vagrant #{ARGV[0]} [options]"
62
+
63
+ o.on('--push', 'prefer changes on the local machine.') do |flag|
64
+ options[:prefer_local] = flag
65
+ check_conflicting_options!
66
+ end
67
+
68
+ o.on('--pull', 'prefer changes on the remote machine.') do |flag|
69
+ options[:prefer_remote] = flag
70
+ check_conflicting_options!
71
+ end
72
+
73
+ o.on('--force-push', 'force-push changes to the remote machine. Dangerous!') do |flag|
74
+ options[:force_local] = flag
75
+ check_conflicting_options!
76
+ end
77
+
78
+ o.on('--force-pull', 'force-pull changes from the remote machine. Super dangerous!') do |flag|
79
+ options[:force_remote] = flag
80
+ check_conflicting_options!
81
+ end
82
+
83
+ o.on('--verbose', 'Print additional debug information') do |flag|
84
+ options[:verbose] = flag
85
+ end
86
+ end
87
+ end
88
+
89
+ def check_conflicting_options!
90
+ enabled = [:prefer_local, :prefer_remote, :force_local, :force_remote].select do |opt|
91
+ options[opt]
92
+ end
93
+ raise ArgumentError.new("Conflicting options: #{enabled.inspect}") if enabled.length > 1
94
+ end
20
95
  end
21
96
  end
22
97
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Unison
3
- VERSION = "1.2.4"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -13,9 +13,6 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.required_rubygems_version = ">= 1.3.6"
15
15
 
16
- s.add_runtime_dependency "listen", ">= 2.8.0"
17
- s.add_runtime_dependency "rb-fsevent", "~> 0.9"
18
-
19
16
  s.add_development_dependency "rake"
20
17
  s.add_development_dependency "rspec-core", "~> 2.12.2"
21
18
  s.add_development_dependency "rspec-expectations", "~> 2.12.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-unison2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Laing
@@ -10,36 +10,8 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-03-22 00:00:00.000000000 Z
13
+ date: 2016-09-08 00:00:00.000000000 Z
14
14
  dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: listen
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: 2.8.0
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: 2.8.0
29
- - !ruby/object:Gem::Dependency
30
- name: rb-fsevent
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - "~>"
34
- - !ruby/object:Gem::Version
35
- version: '0.9'
36
- type: :runtime
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - "~>"
41
- - !ruby/object:Gem::Version
42
- version: '0.9'
43
15
  - !ruby/object:Gem::Dependency
44
16
  name: rake
45
17
  requirement: !ruby/object:Gem::Requirement