fuel-main/bin/agent
2012-09-20 17:56:21 +04:00

212 lines
4.4 KiB
Ruby
Executable File

#!/usr/bin/env ruby
begin
require 'rubygems'
rescue LoadError
end
require 'ohai/system'
require 'json'
require 'httpclient'
require 'logger'
require 'optparse'
module NodeAgentConfig
extend self
attr_accessor :api
def define
yield self
end
end
class NodeAgent
def initialize(logger, config=nil)
@logger = logger
@api_default_address = "localhost"
@api_default_port = "8000"
if not config.nil?
if not config.api.nil?
@api_url = config.api
end
end
if not @api_url
begin
cmdline = ::File.read("/proc/cmdline")
api_ip = cmdline.match(/\burl=http:\/\/((\d{1,3}\.){3}\d{1,3})/)[1]
@logger.info("Found admin node IP address in kernel cmdline: #{api_ip}")
rescue
@logger.error("Can't get API url from /proc/cmdline. Will use localhost.")
api_ip = "127.0.0.1"
end
@api_url = "http://#{api_ip}:#{@api_default_port}/api"
end
@os = Ohai::System.new()
@os.all_plugins
end
def put
headers = {"Content-Type" => "application/json"}
htclient = HTTPClient.new
@logger.debug("Trying to put host info into #{@api_url}")
res = htclient.put("#{@api_url}/nodes/", [_data].to_json, headers)
if res.status < 200 or res.status >= 300
@logger.error("HTTP PUT failed: #{res.inspect}")
end
return res
end
def post
headers = {"Content-Type" => "application/json"}
htclient = HTTPClient.new
@logger.debug("Trying to create host using #{@api_url}")
res = htclient.post("#{@api_url}/nodes/", _data.to_json, headers)
return res
end
def _interfaces
interfaces = @os[:network][:interfaces].inject([]) do |result, elm|
result << { :name => elm[0], :addresses => elm[1]["addresses"] }
end
interfaces << { "default_interface" => @os["network"]["default_interface"] }
interfaces << { "default_gateway" => @os["network"]["default_gateway"] }
interfaces
end
def _mac
@os[:macaddress]
end
def _metadata
{
:block_device => @os["block_device"].to_hash,
:interfaces => _interfaces,
:cpu => @os["cpu"].to_hash,
:memory => @os["memory"].to_hash,
:serial => _serial
}
end
def _is_virtual
begin
if @os["virtualization"]["role"] == "guest"
return true
end
rescue
end
return false
end
def _manufacturer
if _is_virtual
return @os["virtualization"]["system"].upcase
else
begin
return @os[:dmi][:system][:manufacturer]
rescue
return "Unknown"
end
end
end
def _product_name
if _is_virtual
return @os["virtualization"]["role"]
else
begin
return @os[:dmi][:system][:product_name]
rescue
return "Unknown"
end
end
end
def _serial
begin
return @os[:dmi][:system][:serial_number]
rescue
return "Unknown"
end
end
def _data
res = {
:fqdn => @os[:fqdn],
:mac => @os[:macaddress],
:ip => @os[:ipaddress],
:manufacturer => _manufacturer,
:platform_name => _product_name,
:os_platform => @os[:platform],
:meta => _metadata
}
res[:status] = @node_state if @node_state
res
end
def update_state
@node_state = nil
if File.exist?("/opt/nailgun/system_type")
fl = File.open("/opt/nailgun/system_type", "r")
system_type = fl.readline.rstrip
@node_state = "discover" if system_type == "bootstrap"
else
fl = File.open("/opt/nailgun/system_type", "w")
fl.puts("target")
@node_state = "ready"
end
end
end
logger = Logger.new(STDOUT)
logger.level = Logger::DEBUG
options = {}
optparser = OptionParser.new do |opts|
opts.banner = "Usage: #{__FILE__} [options]"
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
opts.on("-c", "--config CONFIG", "Config file") do |config_file|
options[:config_file] = config_file
end
end
optparser.parse!
if options[:config_file].nil?
options[:config_file] = "/etc/nailgun-agent/config.rb"
end
begin
logger.info("Trying to load agent config #{options[:config_file]}")
load options[:config_file]
rescue LoadError
logger.error("Error occured while loading agent config")
end
agent = NodeAgent.new(logger, NodeAgentConfig)
begin
agent.update_state
res = agent.post
if res.status == 409:
agent.put
end
rescue Exception => e
logger.error("Error in sending node info: #{e.message}")
end