lib/sfpagent/agent.rb in sfpagent-0.3.10 vs lib/sfpagent/agent.rb in sfpagent-0.4.0
- old
+ new
@@ -11,25 +11,25 @@
module Sfp
module Agent
NetHelper = Object.new.extend(Sfp::Helper::Net)
- CacheDir = (Process.euid == 0 ? '/var/sfpagent' : File.expand_path(Dir.home + '/.sfpagent'))
- Dir.mkdir(CacheDir, 0700) if not File.exist?(CacheDir)
+ Home = ((Process.euid == 0 and File.directory?('/var')) ? '/var/sfpagent' : File.expand_path(Dir.home + '/.sfpagent'))
+ Dir.mkdir(Home, 0700) if not File.exist?(Home)
DefaultPort = 1314
- PIDFile = "#{CacheDir}/sfpagent.pid"
- LogFile = "#{CacheDir}/sfpagent.log"
- ModelFile = "#{CacheDir}/sfpagent.model"
- AgentsDataFile = "#{CacheDir}/sfpagent.agents"
+ PIDFile = "#{Home}/sfpagent.pid"
+ LogFile = "#{Home}/sfpagent.log"
+ ModelFile = "#{Home}/sfpagent.model"
+ AgentsDataFile = "#{Home}/sfpagent.agents"
- CacheModelFile = "#{CacheDir}/cache.model"
+ CacheModelFile = "#{Home}/cache.model"
- BSigFile = "#{CacheDir}/bsig.model"
- BSigPIDFile = "#{CacheDir}/bsig.pid"
- BSigThreadsLockFile = "#{CacheDir}/bsig.threads.lock.#{Time.now.to_i}"
+ BSigFile = "#{Home}/bsig.model"
+ BSigPIDFile = "#{Home}/bsig.pid"
+ BSigThreadsLockFile = "#{Home}/bsig.threads.lock.#{Time.now.to_i}"
@@logger = WEBrick::Log.new(LogFile, WEBrick::BasicLog::INFO ||
WEBrick::BasicLog::ERROR ||
WEBrick::BasicLog::FATAL ||
WEBrick::BasicLog::WARN)
@@ -76,11 +76,11 @@
Process.daemon if opts[:daemon] and not opts[:mock]
begin
# check modules directory, and create it if it's not exist
- opts[:modules_dir] = File.expand_path(opts[:modules_dir].to_s.strip != '' ? opts[:modules_dir].to_s : "#{CacheDir}/modules")
+ opts[:modules_dir] = File.expand_path(opts[:modules_dir].to_s.strip != '' ? opts[:modules_dir].to_s : "#{Home}/modules")
Dir.mkdir(opts[:modules_dir], 0700) if not File.exist?(opts[:modules_dir])
# load modules from cached directory
load_modules(opts)
@@ -106,24 +106,26 @@
server.mount("/", Sfp::Agent::Handler, Sfp::Agent.logger)
# create maintenance object
maintenance = Maintenance.new(opts)
- # trap signal
- ['INT', 'KILL', 'HUP'].each { |signal|
- trap(signal) {
- maintenance.stop
+ if not is_windows
+ # trap signal
+ ['INT', 'KILL', 'HUP'].each do |signal|
+ trap(signal) {
+ maintenance.stop
- Sfp::Agent.logger.info "Shutting down web server and BSig engine..."
- bsig_engine.stop
- loop do
- break if bsig_engine.status == :stopped
- sleep 1
- end
- server.shutdown
- }
- }
+ Sfp::Agent.logger.info "Shutting down web server and BSig engine..."
+ bsig_engine.stop
+ loop do
+ break if bsig_engine.status == :stopped
+ sleep 1
+ end
+ server.shutdown
+ }
+ end
+ end
File.open(PIDFile, 'w', 0644) { |f| f.write($$.to_s) }
bsig_engine.start
@@ -195,10 +197,14 @@
return model[name] if model.has_key?(name)
end
nil
end
+ def self.is_windows
+ (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
+ end
+
def self.set_cache_model(p={})
File.open(CacheModelFile, File::RDWR|File::CREAT, 0600) do |f|
f.flock(File::LOCK_EX)
json = f.read
model = (json.length >= 2 ? JSON[json] : {})
@@ -412,35 +418,55 @@
logger.error "Executing #{action_string} [Failed] #{e}\n#{e.backtrace.join("\n")}"
end
false
end
- # Load all modules in given directory.
+ ###############
#
+ # Load all modules in given agent's module directory.
+ #
# options:
- # :dir => directory that holds all modules
+ # :dir => directory that contains all modules
#
+ ###############
def self.load_modules(p={})
dir = p[:modules_dir]
- @@modules = []
+ @@modules = {}
counter = 0
- if dir != '' and File.exist?(dir)
+ if dir != '' and File.directory?(dir)
Sfp::Agent.logger.info "Modules directory: #{dir}"
- Dir.entries(dir).each { |name|
- next if name == '.' or name == '..' or File.file?("#{dir}/#{name}")
- module_file = "#{dir}/#{name}/#{name}.rb"
- next if not File.exist?(module_file)
- begin
- load module_file # use 'load' than 'require'
- Sfp::Agent.logger.info "Loading module #{dir}/#{name} [OK]"
+ Dir.entries(dir).each do |name|
+ module_dir = "#{dir}/#{name}"
+ next if name == '.' or name == '..' or not File.directory?(module_dir)
+ module_file = "#{module_dir}/#{name}.rb"
+ if File.exist?(module_file)
+ begin
+ ### use 'load' than 'require' to rewrite previous definitions
+ load module_file
+ Sfp::Agent.logger.info "Loading module #{module_dir} [OK]"
+ counter += 1
+ @@modules[name] = {
+ :type => :ruby,
+ :home => module_dir,
+ :hash => get_module_hash(name)
+ }
+ rescue Exception => e
+ Sfp::Agent.logger.warn "Loading module #{dir}/#{name} [Failed]\n#{e}"
+ end
+ elsif File.exist?("#{module_dir}/main")
+ Sfp::Agent.logger.info "Loading module #{module_dir} [OK]"
+ @@modules[name] = {
+ :type => :shell,
+ :home => module_dir,
+ :hash => get_module_hash(name)
+ }
counter += 1
- @@modules << name
- rescue Exception => e
- Sfp::Agent.logger.warn "Loading module #{dir}/#{name} [Failed]\n#{e}"
+ else
+ logger.warn "Module #{module_dir} is invalid."
end
- }
+ end
end
Sfp::Agent.logger.info "Successfully loading #{counter} modules."
end
def self.get_sfp(module_name)
@@ -465,33 +491,17 @@
end
nil
end
def self.get_modules
- return [] if not (defined? @@modules and @@modules.is_a? Array)
- data = {}
- @@modules.each { |m| data[m] = get_module_hash(m) }
- data
+ #return [] if not (defined? @@modules and @@modules.is_a?(Hash))
+ #data = {}
+ #@@modules.each_key { |m| data[m] = get_module_hash(m) }
+ #data
+ (defined?(@@modules) ? @@modules : {})
end
- # Push a list of modules to an agent using a script in $SFPAGENT_HOME/bin/install_module.
- #
- # parameters:
- # :address => address of target agent
- # :port => port of target agent
- # :modules => an array of modules' name that will be pushed
- #
- def self.push_modules(p={})
- fail "Incomplete parameters." if !p[:modules] or !p[:address] or !p[:port]
-
- install_module = File.expand_path('../../../bin/install_module', __FILE__)
- modules = p[:modules].join(' ')
- cmd = "cd #{@@config[:modules_dir]}; #{install_module} #{p[:address]} #{p[:port]} #{modules}"
- result = `#{cmd}`
- (result =~ /status: ok/)
- end
-
def self.uninstall_all_modules(p={})
return true if @@config[:modules_dir] == ''
if system("rm -rf #{@@config[:modules_dir]}/*")
load_modules(@@config)
Sfp::Agent.logger.info "Deleting all modules [OK]"
@@ -660,18 +670,18 @@
class Handler < WEBrick::HTTPServlet::AbstractServlet
def initialize(server, logger)
@logger = logger
end
- # Process HTTP Get request
+ # Process HTTP GET request
#
# uri:
- # /pid => save daemon's PID to a file (only requested from localhost)
- # /state => return the current state
- # /model => return the current model
- # /sfp => return the SFP description of a module
- # /modules => return a list of available modules
+ # /pid => save daemon's PID to a file (only requested from localhost)
+ # /state => return the current state
+ # /model => return the current model
+ # /sfp => return the SFP description of a module
+ # /modules => return a list of available modules
# /agents => return a list of agents database
# /log => return last 100 lines of log file
#
def do_GET(request, response)
status = 400
@@ -706,11 +716,13 @@
elsif path =~ /^\/sfp\/.+/
status, content_type, body = get_sfp({:module => path[10, path.length-10]})
elsif path == '/modules'
- status, content_type, body = [200, 'application/json', JSON.generate(Sfp::Agent.get_modules)]
+ mods = {}
+ Sfp::Agent.get_modules.each { |name,data| mods[name] = data[:hash] }
+ status, content_type, body = [200, 'application/json', JSON.generate(mods)]
elsif path == '/agents'
status, content_type, body = [200, 'application/JSON', JSON.generate(Sfp::Agent.get_agents)]
elsif path == '/log'
@@ -722,11 +734,11 @@
response.status = status
response['Content-Type'] = content_type
response.body = body
end
- # Handle HTTP Post request
+ # Handle HTTP POST request
#
# uri:
# /execute => receive an action's schema and execute it
#
def do_POST(request, response)
@@ -744,20 +756,20 @@
response.status = status
response['Content-Type'] = content_type
response.body = body
end
- # Handle HTTP Put request
+ # Handle HTTP PUT request
#
# uri:
- # /model => receive a new model and then save it
+ # /model => receive a new model and then save it
# /model/cache => receive a "cache" model and then save it
- # /modules => save the module if parameter "module" is provided
- # /agents => save the agents' list if parameter "agents" is provided
+ # /modules => save the module if parameter "module" is provided
+ # /agents => save the agents' list if parameter "agents" is provided
# /bsig => receive BSig model and receive it in cached directory
# /bsig/satisfier => receive goal request from other agents and then start
- # a satisfier thread to try to achieve it
+ # a satisfier thread in order to achieve it
#
def do_PUT(request, response)
status = 400
content_type = body = ''
if not self.trusted(request)
@@ -798,18 +810,18 @@
response.status = status
response['Content-Type'] = content_type
response.body = body
end
- # Handle HTTP Delete request
+ # Handle HTTP DELETE request
#
# uri:
- # /model => delete existing model
+ # /model => delete existing model
# /model/cache => delete all cache models
# /model/cache/name => delete cache model of agent "name"
- # /modules => delete all modules from module database
- # /modules/name => delete module "name" from module database
- # /agents => delete all agents from agent database
+ # /modules => delete all modules from module database
+ # /modules/name => delete module "name" from module database
+ # /agents => delete all agents from agent database
# /agents/name => delete "name" from agent database
# /bsig => delete existing BSig model
#
def do_DELETE(request, response)
status = 400