syncwrap 2.6.2 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +44 -0
  3. data/Manifest.txt +2 -0
  4. data/README.rdoc +3 -3
  5. data/bin/syncwrap +1 -1
  6. data/lib/syncwrap/amazon_ec2.rb +1 -1
  7. data/lib/syncwrap/amazon_ws.rb +51 -17
  8. data/lib/syncwrap/base.rb +2 -2
  9. data/lib/syncwrap/cli.rb +1 -1
  10. data/lib/syncwrap/component.rb +6 -1
  11. data/lib/syncwrap/components/amazon_linux.rb +1 -1
  12. data/lib/syncwrap/components/arch.rb +48 -5
  13. data/lib/syncwrap/components/bundle.rb +1 -1
  14. data/lib/syncwrap/components/bundled_iyyov_daemon.rb +1 -1
  15. data/lib/syncwrap/components/bundler_gem.rb +1 -1
  16. data/lib/syncwrap/components/centos.rb +1 -1
  17. data/lib/syncwrap/components/commercial_jdk.rb +2 -1
  18. data/lib/syncwrap/components/cruby_vm.rb +15 -11
  19. data/lib/syncwrap/components/debian.rb +46 -10
  20. data/lib/syncwrap/components/etc_hosts.rb +1 -1
  21. data/lib/syncwrap/components/geminabox.rb +1 -1
  22. data/lib/syncwrap/components/hashdot.rb +2 -2
  23. data/lib/syncwrap/components/iyyov.rb +1 -1
  24. data/lib/syncwrap/components/iyyov_daemon.rb +1 -1
  25. data/lib/syncwrap/components/jruby_vm.rb +13 -7
  26. data/lib/syncwrap/components/lvm_cache.rb +1 -1
  27. data/lib/syncwrap/components/mdraid.rb +1 -1
  28. data/lib/syncwrap/components/network.rb +1 -1
  29. data/lib/syncwrap/components/open_jdk.rb +1 -1
  30. data/lib/syncwrap/components/postgresql.rb +24 -4
  31. data/lib/syncwrap/components/puma.rb +1 -1
  32. data/lib/syncwrap/components/qpid.rb +1 -1
  33. data/lib/syncwrap/components/rake_gem.rb +1 -1
  34. data/lib/syncwrap/components/rhel.rb +38 -17
  35. data/lib/syncwrap/components/run_user.rb +1 -1
  36. data/lib/syncwrap/components/source_tree.rb +1 -1
  37. data/lib/syncwrap/components/tarpit_gem.rb +1 -1
  38. data/lib/syncwrap/components/ubuntu.rb +1 -1
  39. data/lib/syncwrap/components/users.rb +10 -1
  40. data/lib/syncwrap/context.rb +11 -1
  41. data/lib/syncwrap/distro.rb +10 -5
  42. data/lib/syncwrap/formatter.rb +1 -1
  43. data/lib/syncwrap/git_help.rb +1 -1
  44. data/lib/syncwrap/hash_support.rb +1 -1
  45. data/lib/syncwrap/host.rb +1 -1
  46. data/lib/syncwrap/main.rb +1 -1
  47. data/lib/syncwrap/path_util.rb +1 -1
  48. data/lib/syncwrap/rsync.rb +8 -17
  49. data/lib/syncwrap/ruby_support.rb +1 -1
  50. data/lib/syncwrap/shell.rb +1 -1
  51. data/lib/syncwrap/systemd.rb +1 -1
  52. data/lib/syncwrap/user_data.rb +1 -1
  53. data/lib/syncwrap/version_support.rb +1 -1
  54. data/lib/syncwrap/zone_balancer.rb +65 -0
  55. data/lib/syncwrap.rb +19 -6
  56. data/sync/postgresql/postgresql.conf.erb +27 -5
  57. data/test/setup.rb +1 -1
  58. data/test/test_components.rb +3 -1
  59. data/test/test_context.rb +1 -1
  60. data/test/test_context_rput.rb +1 -1
  61. data/test/test_rsync.rb +1 -1
  62. data/test/test_shell.rb +1 -1
  63. data/test/test_space.rb +1 -1
  64. data/test/test_space_main.rb +9 -2
  65. data/test/test_version_support.rb +1 -1
  66. data/test/test_zone_balancer.rb +48 -0
  67. metadata +4 -2
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -40,6 +40,7 @@ module SyncWrap
40
40
  # * RHEL, CentOS 7: 9.2
41
41
  # * AmazonLinux 2013.03: 8.4 9.2
42
42
  # * AmazonLinux 2014.09: 8.4 9.2 9.3
43
+ # * AmazonLinux 2015.09: 9.2 9.3 9.4
43
44
  # * Debian 7: 9.1
44
45
  # * Debian 8: 9.4
45
46
  # * Ubuntu 14: 9.3
@@ -150,8 +151,25 @@ module SyncWrap
150
151
  # increased risk. (PG Default: 0 -> none)
151
152
  attr_accessor :commit_delay
152
153
 
153
- # WAL log segments (16MB each) (PG Default: 3)
154
- attr_accessor :checkpoint_segments
154
+ # WAL log segments (16MB each)
155
+ # Deprecated with PostgreSQL 9.5: Use min/max_wal_size instead
156
+ attr_writer :checkpoint_segments
157
+
158
+ def checkpoint_segments
159
+ @checkpoint_segments || ( version_lt?(pg_version, [9,5]) ? 3 : 5 )
160
+ end
161
+
162
+ # Minimum WAL size as string with units
163
+ # Default: PG <9.5: "48MB"; PG 9.5+: "80MB"
164
+ attr_writer :min_wal_size
165
+
166
+ def min_wal_size
167
+ @min_wal_size || "#{ checkpoint_segments * 16 }MB"
168
+ end
169
+
170
+ # Maximum WAL size as string with units.
171
+ # (Default: unset, PG Default: '1GB')
172
+ attr_accessor :max_wal_size
155
173
 
156
174
  # Shared buffers (Default: '256MB' vs PG: '128MB')
157
175
  attr_accessor :shared_buffers
@@ -231,7 +249,9 @@ module SyncWrap
231
249
  @service_name = 'postgresql'
232
250
  @synchronous_commit = :on
233
251
  @commit_delay = 0
234
- @checkpoint_segments = 3
252
+ @checkpoint_segments = nil
253
+ @min_wal_size = nil
254
+ @max_wal_size = nil
235
255
  @shared_buffers = '256MB'
236
256
  @work_mem = '128MB'
237
257
  @maintenance_work_mem = '128MB'
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -45,17 +45,21 @@ module SyncWrap
45
45
  # interpreted as options, see below.
46
46
  #
47
47
  # ==== Options
48
- # :succeed:: Always succeed (useful for local rpm files which
49
- # might already be installed.)
50
48
  #
51
- # Other options will be ignored.
49
+ # :check_install:: Short-circuit if all packages already
50
+ # installed. Thus no upgrades will be performed.
51
+ #
52
+ # :succeed:: Deprecated, use check_install instead
53
+ #
54
+ # Additional options are passed to the sudo calls.
52
55
  def dist_install( *pkgs )
53
- opts = pkgs.last.is_a?( Hash ) && pkgs.pop || {}
54
-
55
- if opts[ :succeed ]
56
- sudo "yum install -q -y #{pkgs.join( ' ' )} || true"
57
- else
58
- sudo "yum install -q -y #{pkgs.join( ' ' )}"
56
+ opts = pkgs.last.is_a?( Hash ) && pkgs.pop.dup || {}
57
+ opts.delete( :minimal )
58
+ pkgs.flatten!
59
+ chk = opts.delete( :check_install ) || opts.delete( :succeed )
60
+ chk = check_install? if chk.nil?
61
+ dist_if_not_installed?( pkgs, chk, opts ) do
62
+ sudo( "yum install -q -y #{pkgs.join( ' ' )}", opts )
59
63
  end
60
64
  end
61
65
 
@@ -63,19 +67,36 @@ module SyncWrap
63
67
  # interpreted as options, see below.
64
68
  #
65
69
  # ==== Options
66
- # :succeed:: Succeed even if no such packages are installed
67
70
  #
68
- # Other options will be ignored.
71
+ # :succeed:: Succeed even if none of the packages are
72
+ # installed. (Deprecated, Default: true)
73
+ #
74
+ # Additional options are passed to the sudo calls.
69
75
  def dist_uninstall( *pkgs )
70
- opts = pkgs.last.is_a?( Hash ) && pkgs.pop || {}
71
- if opts[ :succeed ]
72
- sudo <<-SH
73
- if yum list -q installed #{pkgs.join( ' ' )} >/dev/null 2>&1; then
76
+ opts = pkgs.last.is_a?( Hash ) && pkgs.pop.dup || {}
77
+ pkgs.flatten!
78
+ if opts.delete( :succeed ) != false
79
+ sudo( <<-SH, opts )
80
+ if yum list -C -q installed #{pkgs.join( ' ' )} >/dev/null 2>&1; then
74
81
  yum remove -q -y #{pkgs.join( ' ' )}
75
82
  fi
76
83
  SH
77
84
  else
78
- sudo "yum remove -q -y #{pkgs.join( ' ' )}"
85
+ sudo( "yum remove -q -y #{pkgs.join( ' ' )}", opts )
86
+ end
87
+ end
88
+
89
+ # If chk is true, then wrap block in a sudo bash conditional
90
+ # testing if any specified pkgs are not installed. Otherwise just
91
+ # yield to block.
92
+ def dist_if_not_installed?( pkgs, chk, opts, &block )
93
+ if chk
94
+ qry = "yum list -C -q installed #{pkgs.join ' '}"
95
+ cnt = qry + " | tail -n +2 | wc -l"
96
+ cond = %Q{if [ "$(#{cnt})" != "#{pkgs.count}" ]; then}
97
+ sudo( cond, opts.merge( close: 'fi' ), &block )
98
+ else
99
+ block.call
79
100
  end
80
101
  end
81
102
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -99,6 +99,15 @@ module SyncWrap
99
99
  set_sudoers( u )
100
100
  end
101
101
 
102
+ # Some distro's, like Debian, don't come with rsync installed so
103
+ # need to install it here. For backward compatibly, only do
104
+ # this if dist_install is defined (i.e. Distro component before
105
+ # self.)
106
+ if !users.empty? && respond_to?( :dist_install )
107
+ dist_install( 'rsync',
108
+ ssh_flags.merge( minimal: true, check_install: true ) )
109
+ end
110
+
102
111
  users.each do |u|
103
112
  sync_home_files( u )
104
113
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You
@@ -82,6 +82,12 @@ module SyncWrap
82
82
  @default_options[ :verbose ]
83
83
  end
84
84
 
85
+ # Return any value of :check_install set in constructed default
86
+ # options.
87
+ def check_install?
88
+ @default_options[ :check_install ]
89
+ end
90
+
85
91
  # See Component#sh for interface details
86
92
  def sh( command, opts = {} )
87
93
  opts = @default_options.merge( opts )
@@ -150,6 +156,10 @@ module SyncWrap
150
156
  if maybes.empty?
151
157
  changes = rsync( plains, target, opts ) unless plains.empty?
152
158
  else
159
+ if ssh_host_name == 'localhost' && opts[ :user ]
160
+ # tmpdir needs to be visable to alt. opts[ :user ]
161
+ opts[ :tmpdir_mode ] = 0755
162
+ end
153
163
  process_templates( maybes, opts ) do |processed|
154
164
  unless processed.empty? || plains.empty?
155
165
  opts = opts.dup
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -41,15 +41,20 @@ module SyncWrap
41
41
  #
42
42
  # ==== Options
43
43
  #
44
- # :succeed:: Always succeed (useful for local rpms which might
45
- # already be installed.
44
+ # :check_install:: Short-circuit if all packages already
45
+ # installed. Thus no upgrades will be performed.
46
46
  #
47
- # :minimal:: Avoid additional "optional" packages when possible.
47
+ # :succeed:: Deprecated, use check_install instead
48
+ #
49
+ # :minimal:: Avoid additional "optional" packages when possible
50
+ #
51
+ # Additional options are passed to the sudo calls.
48
52
  def dist_install( *pkgs )
49
53
  raise "Include a distro-specific component, e.g. Debian, RHEL"
50
54
  end
51
55
 
52
- # Uninstall the specified package names.
56
+ # Uninstall the specified package names. A trailing hash is
57
+ # interpreted as options, passed to the sudo calls.
53
58
  def dist_uninstall( *pkgs )
54
59
  raise "Include a distro-specific component, e.g. Debian, RHEL"
55
60
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
data/lib/syncwrap/host.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You
data/lib/syncwrap/main.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -169,7 +169,7 @@ module SyncWrap
169
169
  def process_templates( srcs, opts ) # :doc:
170
170
  bnd = opts[ :erb_binding ] or raise "required :erb_binding param missing"
171
171
  erb_mode = opts[ :erb_mode ] || '<>' #Trim new line on "<% ... %>\n"
172
- mktmpdir( 'syncwrap-' ) do |tmp_dir|
172
+ mktmpdir( opts ) do |tmp_dir|
173
173
  processed_sources = []
174
174
  out_dir = File.join( tmp_dir, 'd' ) #for default perms
175
175
  srcs.each do |src|
@@ -196,23 +196,14 @@ module SyncWrap
196
196
  end
197
197
  end
198
198
 
199
- # Just like Dir.mktmpdir but with an attempt to workaround a JRuby
200
- # 1.6.x bug. See https://jira.codehaus.org/browse/JRUBY-5678
201
- def mktmpdir( prefix ) # :doc:
202
- old_env_tmpdir = nil
203
- newdir = nil
204
- if defined?( JRUBY_VERSION ) && JRUBY_VERSION =~ /^1.6/
205
- old_env_tmpdir = ENV['TMPDIR']
206
- newdir = "/tmp/syncwrap.#{ENV['USER']}"
207
- FileUtils.mkdir_p( newdir, mode: 0700 )
208
- ENV['TMPDIR'] = newdir
209
- end
210
- Dir.mktmpdir( prefix ) do |tmp_dir|
211
- yield tmp_dir
199
+ # Like Dir.mktmpdir but with option to specify :tmpdir_mode.
200
+ def mktmpdir( opts ) # :doc:
201
+ path = Dir::Tmpname.create( 'syncwrap-' ) do |n|
202
+ Dir.mkdir( n, opts[ :tmpdir_mode ] || 0700 )
212
203
  end
204
+ yield path
213
205
  ensure
214
- FileUtils.rmdir( newdir ) if newdir
215
- ENV['TMPDIR'] = old_env_tmpdir if old_env_tmpdir
206
+ FileUtils.remove_entry( path ) if path
216
207
  end
217
208
 
218
209
  def find_source_erbs( sources ) # :doc:
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -0,0 +1,65 @@
1
+ #--
2
+ # Copyright (c) 2011-2016 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ module SyncWrap
18
+
19
+ # Utility for balancing new hosts accross multiple (AWS)
20
+ # availability zones for fault tolarance.
21
+ module ZoneBalancer
22
+
23
+ # Returns a ruby Proc which when called will return the best
24
+ # pick of availability zone, via ::next_zone. This variant
25
+ # uses Space.current within a Space#with block.
26
+ def self.zone( zones, roles )
27
+ space = Space.current
28
+ lambda do
29
+ next_zone( space, zones, roles )
30
+ end
31
+ end
32
+
33
+ # Return the next best zone from zones Array<String>, preferring
34
+ # the least frequent :availability_zone of existing hosts in the
35
+ # specified space and roles (Array<Symbol>, if empty all hosts).
36
+ def self.next_zone( space, zones, roles = [] )
37
+ if zones
38
+ hosts = filter_hosts( space.hosts, roles )
39
+ zfreqs = {}
40
+ zones.each { |z| zfreqs[z] = 0 }
41
+ czones = hosts.map { |h| h[:availability_zone] }.compact
42
+ czones.each { |z| zfreqs[z] += 1 if zfreqs.has_key?( z ) }
43
+
44
+ # Sort by ascending frequency (lowest first). Keep order stable
45
+ # from original zones, when frequency tied.
46
+ # Return the first (least frequent, zones stable) zone.
47
+ n = 0
48
+ zfreqs.sort_by { |_,f| [ f, (n+=1) ] }.first[0]
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def self.filter_hosts( hosts, roles )
55
+ unless roles.empty?
56
+ hosts = hosts.select do |h|
57
+ h.roles.any? { |r| roles.include?( r ) }
58
+ end
59
+ end
60
+ hosts
61
+ end
62
+
63
+ end
64
+
65
+ end
data/lib/syncwrap.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2015 David Kellum
2
+ # Copyright (c) 2011-2016 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -22,6 +22,7 @@ require 'syncwrap/context'
22
22
  require 'syncwrap/host'
23
23
  require 'syncwrap/formatter'
24
24
  require 'syncwrap/path_util'
25
+ require 'syncwrap/version_support.rb'
25
26
 
26
27
  module SyncWrap
27
28
 
@@ -51,6 +52,7 @@ module SyncWrap
51
52
  # level #execute.
52
53
  class Space
53
54
  include PathUtil
55
+ include VersionSupport
54
56
 
55
57
  # Return the current space, as setup within a Space#with block, or
56
58
  # raise something fierce.
@@ -92,11 +94,11 @@ module SyncWrap
92
94
  def load_sync_file( filename )
93
95
  require 'syncwrap/main'
94
96
  with do
95
- load( filename, true )
96
- # This is true -> wrapped to avoid pollution of sync
97
- # namespace. This is particularly important given the dynamic
98
- # binding scheme of components. If not done, top-level
99
- # methods/vars in sync.rb would have precidents over
97
+ load( filename, wrap_sync_load? )
98
+ # Should wrap to avoid pollution of sync namespace, but there
99
+ # are jruby bugs to workaround. This is particularly important
100
+ # given the dynamic binding scheme of components. If not done,
101
+ # top-level methods/vars in sync.rb would have precidents over
100
102
  # component methods.
101
103
  end
102
104
  end
@@ -291,6 +293,16 @@ module SyncWrap
291
293
 
292
294
  private
293
295
 
296
+ # Return true if wrapped load should be attempted on this ruby
297
+ # Avoid this only on JRuby 9.0.0-9.0.4, which will fail hard.
298
+ #
299
+ # See https://github.com/jruby/jruby/issues/3180
300
+ def wrap_sync_load?
301
+ ( !defined?( JRUBY_VERSION ) ||
302
+ version_lt?( JRUBY_VERSION, [9] ) ||
303
+ version_gte?( JRUBY_VERSION, [9,0,5] ) )
304
+ end
305
+
294
306
  def execute_host( host, component_plan = [], opts = {} )
295
307
  comp_roles = opts[ :comp_roles ]
296
308
  comps = if comp_roles && !comp_roles.empty?
@@ -413,5 +425,6 @@ module SyncWrap
413
425
  autoload :AmazonEC2, 'syncwrap/amazon_ec2'
414
426
  autoload :GitHelp, 'syncwrap/git_help'
415
427
  autoload :UserData, 'syncwrap/user_data'
428
+ autoload :ZoneBalancer, 'syncwrap/zone_balancer'
416
429
 
417
430
  end