Class: Jerbil::Servers

Inherits:
Object
  • Object
show all
Defined in:
lib/jerbil/servers.rb

Overview

An informational class for servers on the network, used by brokers to keep track of each other and by services and clients to find the local broker

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fqdn, key, env = :prod, port = nil) ⇒ Servers

create a new server record with

Parameters:

  • fqdn (String)
    • string fully qualified domain name

  • key (String)
    • private access key for system methods

  • env (Symbol) (defaults to: :prod)

    to set the environment to :dev, :test or :prod

  • port (Numeric) (defaults to: nil)
    • optional integer for port number



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/jerbil/servers.rb', line 102

def initialize(fqdn, key, env=:prod, port=nil)
  @fqdn = fqdn
  @key = key
  @env = env
  if port.nil? then
    @port = Socket.getservbyname('jerbil')
    @port += 1 if env == :test
    @port += 2 if env == :dev
  else
    @port = port
  end
  @active = false
end

Instance Attribute Details

#envObject (readonly)

the environment that the server is running in



126
127
128
# File 'lib/jerbil/servers.rb', line 126

def env
  @env
end

#fqdnObject (readonly)

the full-qualified domain name for the server



117
118
119
# File 'lib/jerbil/servers.rb', line 117

def fqdn
  @fqdn
end

#keyObject (readonly)

the private key for the server



120
121
122
# File 'lib/jerbil/servers.rb', line 120

def key
  @key
end

#portObject (readonly)

the port for the server



123
124
125
# File 'lib/jerbil/servers.rb', line 123

def port
  @port
end

Class Method Details

.create_local_server(env, pkey) ⇒ Jerbil::Servers

create the local server record

used by Broker during startup to create its own record

Parameters:

  • env (Symbol)

    being one of :dev, :test, :prod

  • pkey (String)

    the private key for this server

Returns:



52
53
54
55
56
# File 'lib/jerbil/servers.rb', line 52

def self.create_local_server(env, pkey)
  hostname = Socket.gethostname
  port = self.get_port(env)
  return self.new(hostname, pkey, env, port)
end

.find_servers(env, netaddress, netmask, seconds = 0.1) ⇒ Array

scan the lan for open ports and return an array of servers for each.

These server records have blank keys. Broker#register_server will return the called servers key, which can then be set with #set_key.

The netaddress and netmask are defined in Config where further details about these parameters can be found.

Parameters:

  • env (Symbol)

    being the environment in which the servers should be running

  • netaddress (String)

    for the network to search

  • netmask (Numeric)

    to limit the search

  • seconds (Float) (defaults to: 0.1)

    to wait before timing out

Returns:

  • (Array)

    of jerbiljerbil::Servers that were found



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/jerbil/servers.rb', line 80

def self.find_servers(env, netaddress, netmask, seconds=0.1)
  # get the port number for jerbil
  port = self.get_port(env)
  naddr = NetAddr::CIDR.create("#{netaddress}/#{netmask.to_s}")
  servers = []
  
  naddr.enumerate.each do |ip|
    servers << self.new(Resolv.getname(ip), '', env, port) if self.server_up?(ip, port, seconds)
  end
  # servers.each do |server|
  #   server.get_key
  # end
  return servers
end

.get_local_server(env = nil, check = false) ⇒ Object

return a record for the local server

Parameters:

  • env (Symbol) (defaults to: nil)

    being one of :dev, :test, :prod, and defaulting to :prod

  • check (Boolean) (defaults to: false)

    set true to ensure server is running

Raises:



36
37
38
39
40
41
42
43
# File 'lib/jerbil/servers.rb', line 36

def self.get_local_server(env=nil, check=false)
  env ||= :prod
  hostname = Socket.gethostname
  ip = Resolv.getaddress(hostname)
  port = self.get_port(env)
  return self.new(hostname, '', env, port) if ! check || self.server_up?(ip, port, 0.1)
  raise Jerbil::MissingServer, "Cannot find local server on #{hostname}"
end

.get_port(env) ⇒ Object

get the port for the Jerbil Server

Note that jerbil and all its services expect three consecutive ports to be available, one for each environment. The first port should be :prod, then :test and finally :dev

Parameters:

  • env (Symbol)

    the environment in which the servers are running

Raises:



219
220
221
222
223
224
225
226
# File 'lib/jerbil/servers.rb', line 219

def self.get_port(env)
  port = Socket.getservbyname('jerbil')
  port += 1 if env == :test
  port += 2 if env == :dev
  return port
rescue SocketError
  raise Jerbil::MissingJerbilService, "There is no service 'jerbil' in /etc/services"
end

.get_server(servers, fqdn, env = :prod) ⇒ Object

Deprecated.

NOT USED ANYWHERE?

return the server with the given fqdn



60
61
62
63
64
# File 'lib/jerbil/servers.rb', line 60

def self.get_server(servers, fqdn, env=:prod)
  servers.each {|server| return server if server.fqdn == fqdn && server.env == env}
  # found nothing to match
  return nil
end

.server_up?(ip, port, timeout_secs) ⇒ Boolean

check if the given server is running

This is intended for internal use only by find_servers.

Parameters:

  • ip (String)

    address of server to test

  • port (Integer)

    for server

  • timeout_secs (Float)

    to wait for a response

Returns:

  • (Boolean)

    true if server is up



196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/jerbil/servers.rb', line 196

def self.server_up?(ip, port, timeout_secs)
  #puts "Checking for #{ip}:#{port}"
  Timeout::timeout(timeout_secs) do
    begin
      TCPSocket.new(ip, port).close
      true
    rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH
      false
    end
  end
rescue Timeout::Error
  false
end

Instance Method Details

#==(rhs) ⇒ Object

test for equality

ensure equality is across name, key and port. no need to test env because port is unique enough

Parameters:



134
135
136
# File 'lib/jerbil/servers.rb', line 134

def ==(rhs)
  @fqdn == rhs.fqdn && @key == rhs.key && @port == rhs.port
end

#connectObject

connect to this server.

Always assumes that the caller has a DRb service running. Jerbil certainly should!

Raises:



155
156
157
158
159
# File 'lib/jerbil/servers.rb', line 155

def connect
  DRbObject.new(nil, self.drb_address)
rescue Exception
  raise ServerConnectError
end

#copyJerbil::Server

create a deep copy of the server object.

Returns:

  • (Jerbil::Server)

    copy of self



184
185
186
# File 'lib/jerbil/servers.rb', line 184

def copy
  return ServerRecord.new(self.fqdn, self.key, self.env, self.port)
end

#drb_addressString

convenience method to assist Jerbil internals with DRb

drb_address makes it easier to start a DRb server, which is done outside this class because it should only be done under specific circumstances, and not by the general users of this class

Returns:

  • (String)

    the servers DRb address



145
146
147
# File 'lib/jerbil/servers.rb', line 145

def drb_address
  "druby://#{@fqdn}:#{@port}"
end

#get_keyString

get the key for this server from the actual server

Returns:

  • (String)

    private key



163
164
165
# File 'lib/jerbil/servers.rb', line 163

def get_key
  @key = self.connect.get_key
end

#identString

return a string name for the server

Returns:

  • (String)

    ident string



177
178
179
# File 'lib/jerbil/servers.rb', line 177

def ident
  "#{@fqdn}[:#{@env}]"
end

#set_key(pkey) ⇒ Object

save the key for this server, ensuring it is local

Parameters:

  • pkey (String)
    • the server’s private key’



170
171
172
# File 'lib/jerbil/servers.rb', line 170

def set_key(pkey)
  @key = pkey
end