sfpagent 0.3.1 → 0.3.2
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/.travis.yml +31 -0
- data/Gemfile +3 -0
- data/Gemfile.1.8.7 +5 -0
- data/README.md +1 -1
- data/Rakefile +21 -0
- data/VERSION +1 -1
- data/bin/sfpagent +7 -8
- data/bin/test +24 -0
- data/lib/sfpagent/agent.rb +52 -23
- data/lib/sfpagent/bsig.rb +2 -2
- data/lib/sfpagent/sfplanner.rb +1 -1
- data/sfpagent.gemspec +2 -0
- metadata +19 -3
data/.travis.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
language: ruby
|
2
|
+
|
3
|
+
gemfile:
|
4
|
+
- Gemfile
|
5
|
+
- Gemfile.1.8.7
|
6
|
+
|
7
|
+
rvm:
|
8
|
+
- 1.8.7
|
9
|
+
- 1.9.2
|
10
|
+
- 1.9.3
|
11
|
+
- 2.0.0
|
12
|
+
- jruby-18mode
|
13
|
+
- jruby-19mode
|
14
|
+
|
15
|
+
matrix:
|
16
|
+
exclude:
|
17
|
+
- rvm: 1.8.7
|
18
|
+
gemfile: Gemfile
|
19
|
+
- rvm: 1.9.2
|
20
|
+
gemfile: Gemfile.1.8.7
|
21
|
+
- rvm: 1.9.3
|
22
|
+
gemfile: Gemfile.1.8.7
|
23
|
+
- rvm: 2.0.0
|
24
|
+
gemfile: Gemfile.1.8.7
|
25
|
+
- rvm: jruby-18mode
|
26
|
+
gemfile: Gemfile
|
27
|
+
- rvm: jruby-19mode
|
28
|
+
gemfile: Gemfile.1.8.7
|
29
|
+
|
30
|
+
notification:
|
31
|
+
- email: false
|
data/Gemfile
ADDED
data/Gemfile.1.8.7
ADDED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
SFP Agent for Ruby
|
2
2
|
==================
|
3
3
|
- Author: Herry (herry13@gmail.com)
|
4
|
-
- [Version](https://github.com/herry13/sfpagent/blob/master/VERSION)
|
5
4
|
- License: [BSD License](https://github.com/herry13/sfpagent/blob/master/LICENSE)
|
6
5
|
|
6
|
+
[![Build Status](https://travis-ci.org/herry13/sfpagent.png?branch=master)](https://travis-ci.org/herry13/sfpagent)
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/sfpagent.png)](http://badge.fury.io/rb/sfpagent)
|
8
8
|
|
9
9
|
A Ruby script and library of SFP agent. The agent could be accessed through HTTP RESTful API.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
def name
|
2
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
3
|
+
end
|
4
|
+
|
5
|
+
def version
|
6
|
+
File.read('VERSION').strip
|
7
|
+
end
|
8
|
+
|
9
|
+
def date
|
10
|
+
Date.today.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_script
|
14
|
+
File.dirname(__FILE__) + '/bin/test'
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => :test
|
18
|
+
|
19
|
+
namespace :test do
|
20
|
+
sh(test_script)
|
21
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
data/bin/sfpagent
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require File.dirname(__FILE__) + '/../lib/sfpagent'
|
4
|
+
|
5
|
+
def version?
|
6
|
+
File.read(File.dirname(__FILE__) + '/../VERSION').strip
|
7
|
+
end
|
5
8
|
|
6
9
|
opts = Trollop::options do
|
7
|
-
version "sfpagent
|
10
|
+
version "sfpagent #{version?} (c) 2013 Herry"
|
8
11
|
banner <<-EOS
|
9
12
|
SFP Agent that provides a Ruby framework for managing system configurations. The configurations are modelled in SFP language.
|
10
13
|
|
@@ -19,10 +22,6 @@ EOS
|
|
19
22
|
opt :restart, "Restart the daemon agent.", :short => '-r'
|
20
23
|
opt :status, "Print the status of the daemon agent.", :short => '-a'
|
21
24
|
opt :port, "Port number of the daemon agent should listen to.", :short => '-p', :default => Sfp::Agent::DefaultPort
|
22
|
-
#opt :state, "Given a model, print the state of all modules. (Note: [model-file] should be specified.)"
|
23
|
-
#opt :execute, "Given a model, execute a plan in given file. (Note: [model-file] should be specified.)"
|
24
|
-
#opt :pretty, "Print the result in a pretty JSON format.", :short => '-r'
|
25
|
-
#opt :daemon, "Start the agent as a daemon.", :default => true
|
26
25
|
opt :ssl, "Set the agent to use HTTPS instead of HTTP.", :default => false
|
27
26
|
opt :certfile, "Certificate file for HTTPS.", :default => ''
|
28
27
|
opt :keyfile, "Private key file for HTTPS.", :default => ''
|
@@ -44,7 +43,7 @@ if opts[:start]
|
|
44
43
|
Sfp::Agent.start(opts)
|
45
44
|
|
46
45
|
elsif opts[:stop]
|
47
|
-
Sfp::Agent.stop
|
46
|
+
Sfp::Agent.stop(opts)
|
48
47
|
|
49
48
|
elsif opts[:restart]
|
50
49
|
opts[:daemon] = true
|
data/bin/test
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../lib/sfpagent'
|
4
|
+
|
5
|
+
opts = {
|
6
|
+
:daemon => false,
|
7
|
+
:port => Sfp::Agent::DefaultPort,
|
8
|
+
:certfile => '',
|
9
|
+
:keyfile => '',
|
10
|
+
:modules_dir => '',
|
11
|
+
:mock => true
|
12
|
+
}
|
13
|
+
|
14
|
+
### start agent as non-daemon process
|
15
|
+
Sfp::Agent.start(opts)
|
16
|
+
|
17
|
+
### get agent's status
|
18
|
+
Sfp::Agent.status
|
19
|
+
|
20
|
+
### generate agent's current state
|
21
|
+
Sfp::Agent.get_state
|
22
|
+
|
23
|
+
### stop agent
|
24
|
+
Sfp::Agent.stop(opts)
|
data/lib/sfpagent/agent.rb
CHANGED
@@ -27,7 +27,7 @@ module Sfp
|
|
27
27
|
|
28
28
|
BSigFile = "#{CacheDir}/bsig.model"
|
29
29
|
BSigPIDFile = "#{CacheDir}/bsig.pid"
|
30
|
-
BSigThreadsLockFile = "#{CacheDir}/bsig.threads.lock.#{Time.now.
|
30
|
+
BSigThreadsLockFile = "#{CacheDir}/bsig.threads.lock.#{Time.now.to_i}"
|
31
31
|
|
32
32
|
@@logger = WEBrick::Log.new(LogFile, WEBrick::BasicLog::INFO ||
|
33
33
|
WEBrick::BasicLog::ERROR ||
|
@@ -68,45 +68,51 @@ module Sfp
|
|
68
68
|
# :certfile => certificate file path for HTTPS
|
69
69
|
# :keyfile => key file path for HTTPS
|
70
70
|
#
|
71
|
-
def self.start(
|
71
|
+
def self.start(opts={})
|
72
72
|
Sfp::Agent.logger.info "Starting SFP Agent daemons..."
|
73
73
|
puts "Starting SFP Agent daemons..."
|
74
74
|
|
75
|
-
|
75
|
+
@@config = opts
|
76
|
+
|
77
|
+
Process.daemon if opts[:daemon] and not opts[:mock]
|
76
78
|
|
77
79
|
begin
|
78
80
|
# check modules directory, and create it if it's not exist
|
79
|
-
|
80
|
-
Dir.mkdir(
|
81
|
-
@@config = p
|
81
|
+
opts[:modules_dir] = File.expand_path(opts[:modules_dir].to_s.strip != '' ? opts[:modules_dir].to_s : "#{CacheDir}/modules")
|
82
|
+
Dir.mkdir(opts[:modules_dir], 0700) if not File.exist?(opts[:modules_dir])
|
82
83
|
|
83
84
|
# load modules from cached directory
|
84
|
-
load_modules(
|
85
|
+
load_modules(opts)
|
85
86
|
|
86
87
|
# reload model
|
87
88
|
update_model({:rebuild => true})
|
88
89
|
|
89
90
|
# create web server
|
90
91
|
server_type = WEBrick::SimpleServer
|
91
|
-
port = (
|
92
|
+
port = (opts[:port] ? opts[:port] : DefaultPort)
|
92
93
|
config = { :Host => '0.0.0.0',
|
93
94
|
:Port => port,
|
94
95
|
:ServerType => server_type,
|
95
96
|
:pid => '/tmp/webrick.pid',
|
96
97
|
:Logger => Sfp::Agent.logger }
|
97
|
-
if
|
98
|
+
if opts[:ssl]
|
98
99
|
config[:SSLEnable] = true
|
99
100
|
config[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_NONE
|
100
|
-
config[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.open(
|
101
|
-
config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.open(
|
101
|
+
config[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.open(opts[:certfile]).read)
|
102
|
+
config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.open(opts[:keyfile]).read)
|
102
103
|
config[:SSLCertName] = [["CN", WEBrick::Utils::getservername]]
|
103
104
|
end
|
104
105
|
server = WEBrick::HTTPServer.new(config)
|
105
106
|
server.mount("/", Sfp::Agent::Handler, Sfp::Agent.logger)
|
106
107
|
|
108
|
+
# create maintenance object
|
109
|
+
maintenance = Maintenance.new(opts)
|
110
|
+
|
107
111
|
# trap signal
|
108
112
|
['INT', 'KILL', 'HUP'].each { |signal|
|
109
113
|
trap(signal) {
|
114
|
+
maintenance.stop
|
115
|
+
|
110
116
|
Sfp::Agent.logger.info "Shutting down web server and BSig engine..."
|
111
117
|
bsig_engine.stop
|
112
118
|
loop do
|
@@ -121,7 +127,9 @@ module Sfp
|
|
121
127
|
|
122
128
|
bsig_engine.start
|
123
129
|
|
124
|
-
|
130
|
+
maintenance.start
|
131
|
+
|
132
|
+
server.start if not opts[:mock]
|
125
133
|
|
126
134
|
rescue Exception => e
|
127
135
|
Sfp::Agent.logger.error "Starting the agent [Failed] #{e}\n#{e.backtrace.join("\n")}"
|
@@ -131,23 +139,26 @@ module Sfp
|
|
131
139
|
|
132
140
|
# Stop the agent's daemon.
|
133
141
|
#
|
134
|
-
def self.stop
|
142
|
+
def self.stop(opts={})
|
135
143
|
begin
|
136
144
|
pid = File.read(PIDFile).to_i
|
137
145
|
puts "Stopping SFP Agent with PID #{pid}..."
|
138
146
|
Process.kill 'HUP', pid
|
139
147
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
148
|
+
if not opts[:mock]
|
149
|
+
begin
|
150
|
+
sleep (Sfp::BSig::SleepTime + 0.25)
|
151
|
+
Process.kill 0, pid
|
152
|
+
Sfp::Agent.logger.info "SFP Agent daemon is still running."
|
153
|
+
puts "SFP Agent daemon is still running."
|
154
|
+
return false
|
155
|
+
rescue
|
156
|
+
Sfp::Agent.logger.info "SFP Agent daemon has stopped."
|
157
|
+
puts "SFP Agent daemon has stopped."
|
158
|
+
File.delete(PIDFile) if File.exist?(PIDFile)
|
159
|
+
end
|
150
160
|
end
|
161
|
+
|
151
162
|
rescue
|
152
163
|
puts "SFP Agent is not running."
|
153
164
|
File.delete(PIDFile) if File.exist?(PIDFile)
|
@@ -616,6 +627,24 @@ module Sfp
|
|
616
627
|
@@agents_database = JSON[File.read(AgentsDataFile)]
|
617
628
|
end
|
618
629
|
|
630
|
+
class Maintenance
|
631
|
+
IntervalTime = 600 # 10 minutes
|
632
|
+
|
633
|
+
def initialize(opts={})
|
634
|
+
@opts = opts
|
635
|
+
end
|
636
|
+
|
637
|
+
def start
|
638
|
+
return if not defined?(@@enabled) or @@enabled
|
639
|
+
@@enabled = true
|
640
|
+
# TODO
|
641
|
+
end
|
642
|
+
|
643
|
+
def stop
|
644
|
+
@@enabled = false
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
619
648
|
# A class that handles HTTP request.
|
620
649
|
#
|
621
650
|
class Handler < WEBrick::HTTPServlet::AbstractServlet
|
data/lib/sfpagent/bsig.rb
CHANGED
@@ -8,7 +8,7 @@ class Sfp::BSig
|
|
8
8
|
|
9
9
|
SatisfierPath = '/bsig/satisfier'
|
10
10
|
CacheDir = (Process.euid == 0 ? '/var/sfpagent' : File.expand_path('~/.sfpagent'))
|
11
|
-
SatisfierLockFile = "#{CacheDir}/bsig.satisfier.lock.#{Time.now.
|
11
|
+
SatisfierLockFile = "#{CacheDir}/bsig.satisfier.lock.#{Time.now.to_i}"
|
12
12
|
|
13
13
|
attr_reader :enabled, :status, :mode
|
14
14
|
|
@@ -331,7 +331,7 @@ class Sfp::BSig
|
|
331
331
|
agent_goal
|
332
332
|
end
|
333
333
|
|
334
|
-
def send_goal_to_agent(agent, id, goal, pi, agent_name
|
334
|
+
def send_goal_to_agent(agent, id, goal, pi, agent_name, mode)
|
335
335
|
begin
|
336
336
|
data = {
|
337
337
|
'id' => id,
|
data/lib/sfpagent/sfplanner.rb
CHANGED
data/sfpagent.gemspec
CHANGED
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.3.
|
4
|
+
version: 0.3.2
|
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: &6888980 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,7 +21,18 @@ dependencies:
|
|
21
21
|
version: 0.3.16
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *6888980
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &6069840 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *6069840
|
25
36
|
description: A Ruby implementation of SFP agent.
|
26
37
|
email: herry13@gmail.com
|
27
38
|
executables:
|
@@ -30,13 +41,18 @@ extensions: []
|
|
30
41
|
extra_rdoc_files: []
|
31
42
|
files:
|
32
43
|
- .gitignore
|
44
|
+
- .travis.yml
|
45
|
+
- Gemfile
|
46
|
+
- Gemfile.1.8.7
|
33
47
|
- LICENSE
|
34
48
|
- README.md
|
49
|
+
- Rakefile
|
35
50
|
- VERSION
|
36
51
|
- bin/cert.rb
|
37
52
|
- bin/init_script
|
38
53
|
- bin/install_module
|
39
54
|
- bin/sfpagent
|
55
|
+
- bin/test
|
40
56
|
- lib/sfpagent.rb
|
41
57
|
- lib/sfpagent/agent.rb
|
42
58
|
- lib/sfpagent/bsig.rb
|