sfpagent 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sfpagent might be problematic. Click here for more details.
- data/VERSION +1 -1
- data/lib/sfpagent/agent.rb +8 -7
- data/lib/sfpagent/bsig.rb +38 -41
- data/lib/sfpagent/runtime.rb +4 -15
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.10
|
data/lib/sfpagent/agent.rb
CHANGED
@@ -25,6 +25,7 @@ module Sfp
|
|
25
25
|
|
26
26
|
BSigFile = "#{CachedDir}/bsig.model"
|
27
27
|
BSigPIDFile = "#{CachedDir}/bsig.pid"
|
28
|
+
BSigThreadsLockFile = "#{CachedDir}/bsig.threads.lock.#{Time.now.nsec}"
|
28
29
|
|
29
30
|
@@logger = WEBrick::Log.new(LogFile, WEBrick::BasicLog::INFO ||
|
30
31
|
WEBrick::BasicLog::ERROR ||
|
@@ -90,6 +91,7 @@ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
|
|
90
91
|
['INT', 'KILL', 'HUP'].each { |signal|
|
91
92
|
trap(signal) {
|
92
93
|
Sfp::Agent.logger.info "Shutting down web server"
|
94
|
+
bsig_engine.disable
|
93
95
|
server.shutdown
|
94
96
|
}
|
95
97
|
}
|
@@ -693,13 +695,14 @@ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
|
|
693
695
|
end
|
694
696
|
|
695
697
|
def get_model
|
696
|
-
model = Sfp::Agent.get_model
|
697
|
-
|
698
698
|
# The model is not exist.
|
699
|
-
return [404, '', ''] if
|
699
|
+
return [404, '', ''] if not File.exist?(Sfp::Agent::ModelFile)
|
700
700
|
|
701
|
-
|
702
|
-
|
701
|
+
begin
|
702
|
+
# The model is exist, and then send it in JSON.
|
703
|
+
return [200, 'application/json', File.read(Sfp::Agent::ModelFile)]
|
704
|
+
rescue
|
705
|
+
end
|
703
706
|
|
704
707
|
# There is an error when retrieving the model!
|
705
708
|
[500, '', '']
|
@@ -751,8 +754,6 @@ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
|
|
751
754
|
def satisfy_bsig_request(p={})
|
752
755
|
return [400, '', ''] if not p[:query]
|
753
756
|
|
754
|
-
Sfp::Agent.logger.info Sfp::Agent.bsig_engine.to_s
|
755
|
-
|
756
757
|
return [500, '', ''] if Sfp::Agent.bsig_engine.nil?
|
757
758
|
|
758
759
|
req = p[:query]
|
data/lib/sfpagent/bsig.rb
CHANGED
@@ -8,11 +8,11 @@ class Sfp::BSig
|
|
8
8
|
|
9
9
|
SatisfierPath = '/bsig/satisfier'
|
10
10
|
CachedDir = (Process.euid == 0 ? '/var/sfpagent' : File.expand_path('~/.sfpagent'))
|
11
|
-
SatisfierLockFile = CachedDir
|
11
|
+
SatisfierLockFile = "#{CachedDir}/bsig.satisfier.lock.#{Time.now.nsec}"
|
12
12
|
|
13
|
-
|
13
|
+
attr_reader :enabled, :mode
|
14
14
|
|
15
|
-
def initialize
|
15
|
+
def initialize(p={})
|
16
16
|
@lock = Mutex.new
|
17
17
|
@enabled = false
|
18
18
|
end
|
@@ -27,6 +27,7 @@ class Sfp::BSig
|
|
27
27
|
@enabled = true
|
28
28
|
}
|
29
29
|
|
30
|
+
@mode = p[:mode]
|
30
31
|
if p[:mode] == :main
|
31
32
|
enable_main_thread
|
32
33
|
elsif p[:mode] == :satisfier
|
@@ -35,53 +36,58 @@ class Sfp::BSig
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def enable_satisfier_thread
|
38
|
-
@mode
|
39
|
-
Sfp::Agent.logger.info "[satisfier] BSig engine is enabled."
|
39
|
+
Sfp::Agent.logger.info "[#{@mode}] BSig engine is enabled."
|
40
40
|
end
|
41
41
|
|
42
42
|
def enable_main_thread
|
43
|
-
@mode = :main
|
44
|
-
|
45
43
|
['INT', 'KILL', 'HUP'].each { |signal|
|
46
44
|
trap(signal) {
|
47
|
-
Sfp::Agent.logger.info "Shutting down BSig engine"
|
45
|
+
Sfp::Agent.logger.info "[#{@mode}] Shutting down BSig engine"
|
48
46
|
disable
|
49
47
|
}
|
50
48
|
}
|
51
49
|
register_satisfier_thread(:reset)
|
52
50
|
|
53
|
-
Sfp::Agent.logger.info "[
|
51
|
+
Sfp::Agent.logger.info "[#{@mode}] BSig engine is running."
|
54
52
|
|
55
53
|
puts "BSig Engine is running with PID #{$$}"
|
56
54
|
File.open(Sfp::Agent::BSigPIDFile, 'w') { |f| f.write($$.to_s) }
|
57
55
|
|
58
56
|
self.execute_model
|
59
57
|
|
60
|
-
|
58
|
+
File.delete(SatisfierLockFile) if File.exist?(SatisfierLockFile)
|
59
|
+
Sfp::Agent.logger.info "[#{@mode}] BSig engine has stopped."
|
61
60
|
end
|
62
61
|
|
63
62
|
def execute_model
|
63
|
+
Sfp::Agent.logger.info "[#{@mode}] Executing BSig model"
|
64
|
+
|
65
|
+
previous_status = nil
|
64
66
|
while @enabled
|
65
67
|
begin
|
66
|
-
Sfp::Agent.logger.info "[main] Sfp::BSig enabled"
|
67
68
|
|
68
69
|
wait_for_satisfier?
|
69
70
|
|
70
71
|
bsig = Sfp::Agent.get_bsig
|
71
72
|
if bsig.nil?
|
73
|
+
status = :no_bsig
|
72
74
|
sleep BSigSleepTime
|
73
75
|
else
|
74
|
-
status = achieve_local_goal(bsig['id'], bsig['goal'], bsig['operators'], 1
|
75
|
-
Sfp::Agent.logger.info "[main] execute model - status: " + status.to_s
|
76
|
+
status = achieve_local_goal(bsig['id'], bsig['goal'], bsig['operators'], 1)
|
76
77
|
if status == :failure
|
77
|
-
Sfp::Agent.logger.error "[
|
78
|
+
Sfp::Agent.logger.error "[#{@mode}] Executing BSig model [Failed]"
|
78
79
|
sleep BSigSleepTime
|
79
80
|
elsif status == :no_flaw
|
80
81
|
sleep BSigSleepTime
|
81
82
|
end
|
82
83
|
end
|
84
|
+
|
85
|
+
if previous_status != status
|
86
|
+
Sfp::Agent.logger.info "[#{@mode}] BSig engine - status: " + status.to_s
|
87
|
+
previous_status = status
|
88
|
+
end
|
83
89
|
rescue Exception => e
|
84
|
-
Sfp::Agent.logger.error "Error on executing BSig model\n#{e}\n#{e.backtrace.join("\n")}"
|
90
|
+
Sfp::Agent.logger.error "[#{@mode}] Error on executing BSig model\n#{e}\n#{e.backtrace.join("\n")}"
|
85
91
|
sleep BSigSleepTime
|
86
92
|
end
|
87
93
|
end
|
@@ -91,7 +97,7 @@ Sfp::Agent.logger.info "[main] execute model - status: " + status.to_s
|
|
91
97
|
total_satisfier = 1
|
92
98
|
loop do
|
93
99
|
total_satisfier = (File.exist?(SatisfierLockFile) ? File.read(SatisfierLockFile).to_i : 0)
|
94
|
-
return if total_satisfier <= 0
|
100
|
+
return if total_satisfier <= 0 or not @enabled
|
95
101
|
sleep 1
|
96
102
|
end
|
97
103
|
end
|
@@ -101,13 +107,12 @@ Sfp::Agent.logger.info "[main] execute model - status: " + status.to_s
|
|
101
107
|
# :failure : there is a failure on achieving the goal
|
102
108
|
# :ongoing : the selected operator is being executed
|
103
109
|
# :repaired : some goal-flaws have been repaired, but the goal may have other flaws
|
104
|
-
def achieve_local_goal(id, goal, operators, pi
|
110
|
+
def achieve_local_goal(id, goal, operators, pi)
|
105
111
|
operator = nil
|
106
112
|
|
107
113
|
current = get_current_state
|
108
114
|
flaws = compute_flaws(goal, current)
|
109
115
|
return :no_flaw if flaws.length <= 0
|
110
|
-
Sfp::Agent.logger.info "[#{mode}] Flaws: #{JSON.generate(flaws)}"
|
111
116
|
|
112
117
|
operator = select_operator(flaws, operators, pi)
|
113
118
|
return :failure if operator.nil?
|
@@ -115,14 +120,13 @@ Sfp::Agent.logger.info "[#{mode}] Flaws: #{JSON.generate(flaws)}"
|
|
115
120
|
@lock.synchronize {
|
116
121
|
return :ongoing if operator['selected']
|
117
122
|
operator['selected'] = true
|
118
|
-
Sfp::Agent.logger.info "[#{mode}] Selected operator: #{JSON.generate(operator)}"
|
119
123
|
}
|
124
|
+
Sfp::Agent.logger.info "[#{@mode}] Selected operator: #{operator['name']}" #{JSON.generate(operator)}"
|
120
125
|
|
121
126
|
next_pi = pi + 1
|
122
127
|
pre_local, pre_remote = split_preconditions(operator)
|
123
128
|
|
124
|
-
Sfp::Agent.logger.info "[#{mode}] local-flaws: #{JSON.generate(pre_local)}"
|
125
|
-
Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
|
129
|
+
Sfp::Agent.logger.info "[#{@mode}] local-flaws: #{JSON.generate(pre_local)}, remote-flaws: #{JSON.generate(pre_remote)}"
|
126
130
|
|
127
131
|
status = nil
|
128
132
|
tries = MaxTries
|
@@ -139,8 +143,7 @@ Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
|
|
139
143
|
tries -= 1
|
140
144
|
end until tries <= 0
|
141
145
|
|
142
|
-
|
143
|
-
return :failure if status == :failure
|
146
|
+
return :failure if status != :no_flaw
|
144
147
|
|
145
148
|
return :failure if not achieve_remote_goal(id, pre_remote, next_pi)
|
146
149
|
|
@@ -155,9 +158,10 @@ Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
|
|
155
158
|
def achieve_remote_goal(id, goal, pi)
|
156
159
|
if goal.length > 0
|
157
160
|
agents = Sfp::Agent.get_agents
|
158
|
-
split_goal_by_agent(goal).each do |
|
159
|
-
return false if not agents.has_key?(
|
160
|
-
|
161
|
+
split_goal_by_agent(goal).each do |agent_name,agent_goal|
|
162
|
+
return false if not agents.has_key?(agent_name) or agents[agent_name]['sfpAddress'].to_s == ''
|
163
|
+
|
164
|
+
return false if not send_goal_to_agent(agents[agent_name], id, agent_goal, pi, agent_name)
|
161
165
|
end
|
162
166
|
end
|
163
167
|
true
|
@@ -166,20 +170,16 @@ Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
|
|
166
170
|
def receive_goal_from_agent(id, goal, pi)
|
167
171
|
register_satisfier_thread
|
168
172
|
|
169
|
-
Sfp::Agent.logger.info "[satisfier] enabled: " + @enabled.to_s
|
170
173
|
return false if not @enabled
|
171
174
|
|
172
175
|
bsig = Sfp::Agent.get_bsig
|
173
176
|
|
174
|
-
Sfp::Agent.logger.info "[satisfier] receive_goal_from_agent - " + id.inspect + " - " + goal.inspect + " - " + pi.inspect
|
175
|
-
Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
|
176
|
-
|
177
177
|
return false if bsig.nil? or id < bsig['id']
|
178
178
|
|
179
179
|
status = nil
|
180
180
|
tries = MaxTries
|
181
181
|
begin
|
182
|
-
status = achieve_local_goal(bsig['id'], goal, bsig['operators'], pi
|
182
|
+
status = achieve_local_goal(bsig['id'], goal, bsig['operators'], pi)
|
183
183
|
if status == :no_flaw or status == :failure or not @enabled
|
184
184
|
break
|
185
185
|
elsif status == :ongoing
|
@@ -191,9 +191,7 @@ Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
|
|
191
191
|
tries -= 1
|
192
192
|
end until tries <= 0
|
193
193
|
|
194
|
-
return
|
195
|
-
|
196
|
-
true
|
194
|
+
return (status == :no_flaw)
|
197
195
|
|
198
196
|
ensure
|
199
197
|
unregister_satisfier_thread
|
@@ -201,8 +199,6 @@ Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
|
|
201
199
|
|
202
200
|
protected
|
203
201
|
def register_satisfier_thread(mode=nil)
|
204
|
-
return if mode == :reset and File.exist?(SatisfierLockFile)
|
205
|
-
|
206
202
|
File.open(SatisfierLockFile, File::RDWR|File::CREAT, 0644) { |f|
|
207
203
|
f.flock(File::LOCK_EX)
|
208
204
|
value = (mode == :reset ? 0 : (f.read.to_i + 1))
|
@@ -236,12 +232,14 @@ Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
|
|
236
232
|
agent_goal
|
237
233
|
end
|
238
234
|
|
239
|
-
def send_goal_to_agent(agent, id, g, pi)
|
235
|
+
def send_goal_to_agent(agent, id, g, pi, agent_name='')
|
240
236
|
data = {'id' => id,
|
241
237
|
'goal' => JSON.generate(g),
|
242
238
|
'pi' => pi}
|
243
239
|
code, _ = put_data(agent['sfpAddress'], agent['sfpPort'], SatisfierPath, data)
|
244
|
-
|
240
|
+
|
241
|
+
Sfp::Agent.logger.info "[#{@mode}] Request goal to: #{agent_name} - status: " + code.to_s
|
242
|
+
|
245
243
|
(code == '200')
|
246
244
|
end
|
247
245
|
|
@@ -282,9 +280,7 @@ Sfp::Agent.logger.info "send_goal_to_agent - status: " + code.to_s
|
|
282
280
|
end
|
283
281
|
|
284
282
|
def can_repair?(operator, flaws)
|
285
|
-
operator['effect'].each { |
|
286
|
-
return true if flaws[var] == val
|
287
|
-
}
|
283
|
+
operator['effect'].each { |variable,value| return true if flaws[variable] == value }
|
288
284
|
false
|
289
285
|
end
|
290
286
|
|
@@ -306,6 +302,7 @@ Sfp::Agent.logger.info "send_goal_to_agent - status: " + code.to_s
|
|
306
302
|
end
|
307
303
|
|
308
304
|
def invoke(operator)
|
305
|
+
Sfp::Agent.logger.info "[#{@mode}] Invoking #{operator['name']}"
|
309
306
|
Sfp::Agent.execute_action(operator)
|
310
307
|
end
|
311
308
|
end
|
data/lib/sfpagent/runtime.rb
CHANGED
@@ -94,24 +94,13 @@ class Sfp::Runtime
|
|
94
94
|
def update_model(model, root, path)
|
95
95
|
object = {}
|
96
96
|
if model['_context'] == 'object' and model['_isa'].to_s.isref and model['_isa'].to_s != '$.Object'
|
97
|
-
|
98
|
-
# get the current state of this object
|
99
|
-
obj = (!defined?(@root) or @root.nil? ? nil : @root.at?(path))
|
100
|
-
if obj.is_a?(Hash)
|
101
|
-
object[:_self] = obj[:_self]
|
102
|
-
object[:_self].update_model(model)
|
103
|
-
else
|
104
|
-
Sfp::Agent.logger.info "Instantiating object: #{model['_self']}"
|
105
|
-
# the module has not been instantiated yet!
|
106
|
-
object[:_self] = instantiate_sfp_object(model, root)
|
107
|
-
end
|
97
|
+
object[:_self] = instantiate_sfp_object(model, root)
|
108
98
|
end
|
109
99
|
|
110
100
|
model.each do |key,child|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
object[key] = update_model(child, root, path.push(key))
|
101
|
+
if key[0,1] != '_' and child.is_a?(Hash) and child['_context'] == 'object' and child['_isa'].to_s != '$.Object'
|
102
|
+
object[key] = update_model(child, root, path.push(key))
|
103
|
+
end
|
115
104
|
end
|
116
105
|
|
117
106
|
object
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sfpagent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2013-08-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sfp
|
16
|
-
requirement: &
|
16
|
+
requirement: &16928140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 0.3.12
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *16928140
|
25
25
|
description: A Ruby implementation of SFP agent.
|
26
26
|
email: herry13@gmail.com
|
27
27
|
executables:
|