royw-drbman 0.0.3 → 0.0.4

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
data/drbman.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{drbman}
5
- s.version = "0.0.3"
5
+ s.version = "0.0.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Roy Wright"]
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  "lib/drbman/cli.rb",
42
42
  "lib/drbman/drb_pool.rb",
43
43
  "lib/drbman/drbman.rb",
44
+ "lib/drbman/errors.rb",
44
45
  "lib/drbman/host_machine.rb",
45
46
  "spec/drbman_spec.rb",
46
47
  "spec/host_machine_spec.rb",
@@ -31,5 +31,63 @@ describe('SieveOfEratosthenes') do
31
31
  sieve.execute.length.should == 303
32
32
  end
33
33
 
34
+ it 'should find 303 primes below 2000 for password host' do
35
+ env_ok.should be_true
36
+ @choices[:max_integer] = 2000
37
+ @choices[:hosts] = ["#{ENV['TEST_USER']}:#{ENV['TEST_PASSWORD']}@#{ENV['TEST_HOST']}"]
38
+ sieve = Primes.new(@logger, @choices)
39
+ sieve.execute.length.should == 303
40
+ end
41
+
42
+ it 'should robustly fail for invalid password' do
43
+ env_ok.should be_true
44
+ @choices[:max_integer] = 2000
45
+ @choices[:hosts] = ["#{ENV['TEST_USER']}:badpassword@#{ENV['TEST_HOST']}"]
46
+ sieve = Primes.new(@logger, @choices)
47
+ sieve.execute.length.should == 0
48
+ end
49
+
50
+ it 'should robustly fail for missing password' do
51
+ env_ok.should be_true
52
+ @choices[:max_integer] = 2000
53
+ @choices[:hosts] = ["#{ENV['TEST_USER']}@#{ENV['TEST_HOST']}"]
54
+ sieve = Primes.new(@logger, @choices)
55
+ sieve.execute.length.should == 0
56
+ end
57
+
58
+ it 'should find 303 primes below 2000 for password host and localhost' do
59
+ env_ok.should be_true
60
+ @choices[:max_integer] = 2000
61
+ @choices[:hosts] = ["#{ENV['TEST_USER']}:#{ENV['TEST_PASSWORD']}@#{ENV['TEST_HOST']}", 'localhost']
62
+ sieve = Primes.new(@logger, @choices)
63
+ sieve.execute.length.should == 303
64
+ end
65
+
66
+ it 'should find 303 primes below 2000 for invalid password host and localhost' do
67
+ env_ok.should be_true
68
+ @choices[:max_integer] = 2000
69
+ @choices[:hosts] = ["#{ENV['TEST_USER']}:badpassword@#{ENV['TEST_HOST']}", 'localhost']
70
+ sieve = Primes.new(@logger, @choices)
71
+ sieve.execute.length.should == 303
72
+ end
73
+
74
+ it 'should find 303 primes below 2000 for missing password host and localhost' do
75
+ env_ok.should be_true
76
+ @choices[:max_integer] = 2000
77
+ @choices[:hosts] = ["#{ENV['TEST_USER']}@#{ENV['TEST_HOST']}", 'localhost']
78
+ sieve = Primes.new(@logger, @choices)
79
+ sieve.execute.length.should == 303
80
+ end
81
+
34
82
  end
35
83
 
84
+ def env_ok
85
+ result = !(ENV['TEST_HOST'].nil? || ENV['TEST_USER'].nil? || ENV['TEST_PASSWORD'].nil?)
86
+ unless result
87
+ puts
88
+ puts "You need to setup the following environment variables: TEST_HOST, TEST_USER, TEST_PASSWORD"
89
+ puts "Alternatively run spec like: TEST_HOST='box' TEST_USER='who' TEST_PASSWORD='sekret' spec spec/primes_spec.rb"
90
+ puts
91
+ end
92
+ result
93
+ end
data/lib/drbman.rb CHANGED
@@ -3,7 +3,7 @@ $:.unshift(File.dirname(__FILE__)) unless
3
3
 
4
4
  require 'rubygems'
5
5
 
6
- # gem 'ruby-debug', '>=0.10.3'
6
+ gem 'ruby-debug', '>=0.10.3'
7
7
  gem 'log4r', '>=1.0.5'
8
8
  gem 'user-choices', '>=1.1.6'
9
9
  gem 'extlib', '>=0.9.12'
@@ -13,7 +13,7 @@ gem 'daemons', '>=1.0.10'
13
13
  gem 'uuidtools', '>=2.0.0'
14
14
 
15
15
  require 'extlib'
16
- # require 'ruby-debug'
16
+ require 'ruby-debug'
17
17
  require 'log4r'
18
18
  require 'user-choices'
19
19
  require 'net/ssh'
@@ -19,11 +19,16 @@ class DrbPool
19
19
 
20
20
  threads = []
21
21
  mutex = Mutex.new
22
+ @logger.debug { "drb_pool hosts => #{hosts.inspect}"}
22
23
  hosts.each do |host_name, host_machine|
23
24
  threads << Thread.new(host_machine) do |host|
24
- obj = get_drb_object(host.machine, host.port)
25
- mutex.synchronize do
26
- @objects << obj
25
+ if host.alive?
26
+ obj = get_drb_object(host.machine, host.port)
27
+ unless obj.nil?
28
+ mutex.synchronize do
29
+ @objects << obj
30
+ end
31
+ end
27
32
  end
28
33
  end
29
34
  end
@@ -40,6 +45,7 @@ class DrbPool
40
45
  # @example Usage
41
46
  # pool.get_object {|obj| obj.do_something}
42
47
  def get_object(&block)
48
+ raise EmptyDrbPoolError.new("No drb servers available") if @objects.empty?
43
49
  mutex = Mutex.new
44
50
  while((object = next_object(mutex)).nil?)
45
51
  sleep 0.1
data/lib/drbman/drbman.rb CHANGED
@@ -51,7 +51,8 @@ class Drbman
51
51
  port = @user_choices[:port]
52
52
  @user_choices[:hosts].each do |host|
53
53
  host = "#{host}:#{port}" unless host =~ /\:\d+\s*$/
54
- @hosts[host] = HostMachine.new(host, @logger, @user_choices)
54
+ host_machine = HostMachine.new(host, @logger, @user_choices)
55
+ @hosts[host] = host_machine if host_machine.alive? # don't use off-line host machines
55
56
  port += 1
56
57
  end
57
58
 
@@ -60,6 +61,8 @@ class Drbman
60
61
  setup
61
62
  @pool = DrbPool.new(@hosts, @logger)
62
63
  block.call(self)
64
+ rescue EmptyDrbPoolError, EnvironmentError => e
65
+ @logger.error { e }
63
66
  rescue Exception => e
64
67
  @logger.error { e }
65
68
  @logger.debug { e.backtrace.join("\n") }
@@ -85,9 +88,11 @@ class Drbman
85
88
  def setup
86
89
  threads = []
87
90
  @hosts.each do |name, machine|
88
- threads << Thread.new(machine) do |host_machine|
89
- host_machine.session do |host|
90
- startup(host)
91
+ if machine.alive? # no need to thread if the machine is off-line
92
+ threads << Thread.new(machine) do |host_machine|
93
+ host_machine.session do |host|
94
+ startup(host)
95
+ end
91
96
  end
92
97
  end
93
98
  end
@@ -149,7 +154,7 @@ class Drbman
149
154
  def stop_drb_server(host)
150
155
  case host.sh("cd #{host.dir};ruby #{host.controller} stop")
151
156
  when /command not found/
152
- raise Exception.new "Ruby is not installed on #{host.name}"
157
+ raise EnvironmentError.new "Ruby is not installed on #{host.name}"
153
158
  end
154
159
  end
155
160
 
@@ -160,7 +165,7 @@ class Drbman
160
165
  unless host.controller.blank?
161
166
  case host.sh("cd #{host.dir};ruby #{host.controller} start -- #{host.machine} #{host.port}")
162
167
  when /command not found/
163
- raise Exception.new "Ruby is not installed on #{host.name}"
168
+ raise EnvironmentError.new "Ruby is not installed on #{host.name}"
164
169
  end
165
170
  end
166
171
  end
@@ -208,11 +213,11 @@ class Drbman
208
213
  when /false/i
209
214
  missing_gems << gem_name
210
215
  when /command not found/
211
- raise Exception.new "Rubygems is not installed on #{host.name}"
216
+ raise EnvironmentError.new "Rubygems is not installed on #{host.name}"
212
217
  end
213
218
  end
214
219
  unless missing_gems.empty?
215
- raise Exception.new "The following gems are not installed on #{host.name}: #{missing_gems.join(', ')}"
220
+ raise EnvironmentError.new "The following gems are not installed on #{host.name}: #{missing_gems.join(', ')}"
216
221
  end
217
222
  end
218
223
 
@@ -0,0 +1,3 @@
1
+ class EmptyDrbPoolError < Exception; end
2
+
3
+ class EnvironmentError < Exception; end
@@ -57,6 +57,21 @@ class HostMachine
57
57
  @logger.debug { self.pretty_inspect }
58
58
  end
59
59
 
60
+ def alive?
61
+ result = true
62
+ begin
63
+ session do |host|
64
+ response = host.sh('uptime')
65
+ @logger.debug { "#{host.name} #{response}" }
66
+ raise Exception.new('no response from uptime') if response.strip.empty?
67
+ end
68
+ rescue Exception => e
69
+ @logger.warn { "#{@name} is not responding: #{e}" }
70
+ result = false
71
+ end
72
+ result
73
+ end
74
+
60
75
  # Connect to the host, execute the given block, then disconnect from the host
61
76
  # @yield [HostMachine]
62
77
  # @example
@@ -74,10 +89,7 @@ class HostMachine
74
89
  end
75
90
  yield self
76
91
  rescue Net::SSH::AuthenticationFailed => e
77
- @logger.error { "Authentication Failed" }
78
- rescue Exception => e
79
- @logger.error { e }
80
- @logger.error { e.backtrace.join("\n") }
92
+ @logger.error { "Authentication Failed for #{e}" }
81
93
  raise e
82
94
  ensure
83
95
  disconnect
@@ -165,14 +177,22 @@ class HostMachine
165
177
  # @see {#session}
166
178
  def connect
167
179
  if @ssh.nil?
168
- options = @password.merge({
169
- :timeout=>2,
170
- :auth_methods => %w(publickey hostbased password)
171
- })
172
- options = @password.merge({:verbose=>Logger::DEBUG}) if @choices[:ssh_debug]
180
+ options = @password
181
+ options = options.merge({:verbose => Logger::INFO}) if @choices[:ssh_debug]
182
+ options = options.merge({:password => ''}) if options[:password].nil?
173
183
  @logger.debug { "connect: @machine=>#{@machine}, @user=>#{@user}, options=>#{options.inspect}" }
174
- @ssh = Net::SSH.start(@machine, @user, options)
175
- # @ssh.forward.local(@port, @machine, @port)
184
+ begin
185
+ @ssh = Net::SSH.start(@machine, @user, options)
186
+ # @ssh.forward.local(@port, @machine, @port)
187
+ rescue Net::SSH::AuthenticationFailed
188
+ @logger.debug { "connect raised Net::SSH::AuthenticationFailed" }
189
+ @ssh = nil
190
+ raise Net::SSH::AuthenticationFailed.new(@name)
191
+ rescue Exception => e
192
+ @logger.debug { "connect raised #{e}"}
193
+ @ssh = nil
194
+ raise e
195
+ end
176
196
  end
177
197
  end
178
198
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: royw-drbman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roy Wright
@@ -108,6 +108,7 @@ files:
108
108
  - lib/drbman/cli.rb
109
109
  - lib/drbman/drb_pool.rb
110
110
  - lib/drbman/drbman.rb
111
+ - lib/drbman/errors.rb
111
112
  - lib/drbman/host_machine.rb
112
113
  - spec/drbman_spec.rb
113
114
  - spec/host_machine_spec.rb