vagrant-unison2 1.2.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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