nuri 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/VERSION +1 -1
- data/bin/nuri +110 -82
- data/bin/{install_module → nuri-install-module} +7 -4
- data/bin/{sfw2graph → nuri-sfwgraph} +7 -6
- data/bin/nuri-uninstall-module +45 -0
- data/examples/.gitignore +1 -0
- data/examples/mockcloud/generator.rb +14 -58
- data/examples/mockcloud/generator.rb.bak +66 -0
- data/examples/mockcloud/hadoop2.sfp.template +25 -0
- data/lib/nuri.rb +5 -7
- data/lib/nuri/choreographer.rb +8 -8
- data/lib/nuri/helper.rb +10 -3
- data/lib/nuri/master.rb +53 -15
- data/lib/nuri/orchestrator.rb +34 -29
- data/modules/apache2/apache2.rb +9 -0
- data/modules/apache2/apache2.sfp +54 -0
- data/modules/file/file.rb +1 -1
- data/modules/file/file.sfp +1 -1
- data/modules/machine/machine.rb +17 -0
- data/modules/package2/package2.rb +85 -0
- data/modules/package2/package2.sfp +23 -0
- data/modules/pyfile/main +133 -0
- data/modules/pyfile/pyfile.sfp +23 -0
- data/modules/service2/service2.rb +62 -0
- data/modules/service2/service2.sfp +24 -0
- data/nuri.gemspec +1 -1
- metadata +17 -11
- data/bin/delete_modules +0 -35
- data/bin/nuri.old +0 -183
- data/modules/install_module +0 -54
- data/modules/service/model.json +0 -1
- data/modules/service/test.sfp +0 -6
@@ -0,0 +1,23 @@
|
|
1
|
+
schema pyfile {
|
2
|
+
created : Bool
|
3
|
+
final path = ""
|
4
|
+
final content : String
|
5
|
+
|
6
|
+
sub del {
|
7
|
+
condition {
|
8
|
+
this.created = true
|
9
|
+
}
|
10
|
+
effect {
|
11
|
+
this.created = false
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
sub create {
|
16
|
+
condition {
|
17
|
+
this.created != true
|
18
|
+
}
|
19
|
+
effect {
|
20
|
+
this.created = true
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Sfp::Module::Service2
|
2
|
+
include Sfp::Resource
|
3
|
+
|
4
|
+
def update_state
|
5
|
+
to_model
|
6
|
+
|
7
|
+
@state['running'] = running?
|
8
|
+
end
|
9
|
+
|
10
|
+
##############################
|
11
|
+
#
|
12
|
+
# Action methods (see service2.sfp)
|
13
|
+
#
|
14
|
+
##############################
|
15
|
+
|
16
|
+
def start(p={})
|
17
|
+
return true if running?
|
18
|
+
|
19
|
+
if @model['name'].to_s.strip.length > 0
|
20
|
+
shell "sudo service #{@model['name']} start"
|
21
|
+
elsif @model['script'].to_s.strip.length > 0
|
22
|
+
shell "sudo #{@model['script']} start"
|
23
|
+
else
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
sleep 1
|
27
|
+
running?
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop(p={})
|
31
|
+
return true if not running?
|
32
|
+
|
33
|
+
if @model['name'].to_s.strip.length > 0
|
34
|
+
shell "sudo service #{@model['name']} stop"
|
35
|
+
elsif @model['script'].to_s.strip.length > 0
|
36
|
+
shell "sudo #{@model['script']} stop"
|
37
|
+
else
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
sleep 1
|
41
|
+
not running?
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
##############################
|
46
|
+
#
|
47
|
+
# Helper methods
|
48
|
+
#
|
49
|
+
##############################
|
50
|
+
|
51
|
+
def running?
|
52
|
+
output = nil
|
53
|
+
if @model['name'].to_s.strip.length > 0
|
54
|
+
output = `service #{@model['name']} status 2>/dev/null`.to_s.downcase
|
55
|
+
elsif @model['script'].to_s.strip.length > 0
|
56
|
+
output = `#{@model['script']} status 2>/dev/null`.to_s.downcase
|
57
|
+
else
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
return !!(output =~ /is running/ or output =~ /start\/running/ or output =~ /uptime/)
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
schema Service2 {
|
2
|
+
running : Bool
|
3
|
+
|
4
|
+
final name = ""
|
5
|
+
final script = ""
|
6
|
+
|
7
|
+
sub start {
|
8
|
+
condition {
|
9
|
+
this.running != true
|
10
|
+
}
|
11
|
+
effect {
|
12
|
+
this.running = true
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
sub stop {
|
17
|
+
condition {
|
18
|
+
this.running = true
|
19
|
+
}
|
20
|
+
effect {
|
21
|
+
this.running = false
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
data/nuri.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.homepage = 'https://github.com/herry13/nuri'
|
18
18
|
s.rubyforge_project = 'nuri'
|
19
19
|
|
20
|
-
s.add_dependency 'sfplanner', '~> 0.1'
|
20
|
+
s.add_dependency 'sfplanner', '~> 0.2.1'
|
21
21
|
s.add_dependency 'sfpagent', '~> 0.3'
|
22
22
|
s.add_dependency 'colorize', '~> 0.6'
|
23
23
|
s.add_dependency 'coderay', '~> 1'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nuri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Herry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sfplanner
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.2.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.2.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sfpagent
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,12 +95,11 @@ files:
|
|
95
95
|
- README.md
|
96
96
|
- Rakefile
|
97
97
|
- VERSION
|
98
|
-
- bin/delete_modules
|
99
98
|
- bin/install_agent
|
100
|
-
- bin/install_module
|
101
99
|
- bin/nuri
|
102
|
-
- bin/nuri
|
103
|
-
- bin/
|
100
|
+
- bin/nuri-install-module
|
101
|
+
- bin/nuri-sfwgraph
|
102
|
+
- bin/nuri-uninstall-module
|
104
103
|
- examples/.gitignore
|
105
104
|
- examples/bonfire.sfp
|
106
105
|
- examples/bonfire/epcc.sfp
|
@@ -160,6 +159,8 @@ files:
|
|
160
159
|
- examples/hadoop2.sfp
|
161
160
|
- examples/hpcloud.sfp
|
162
161
|
- examples/mockcloud/generator.rb
|
162
|
+
- examples/mockcloud/generator.rb.bak
|
163
|
+
- examples/mockcloud/hadoop2.sfp.template
|
163
164
|
- examples/mockcloud/run.rb
|
164
165
|
- examples/test.inc
|
165
166
|
- examples/test.sfp
|
@@ -189,6 +190,8 @@ files:
|
|
189
190
|
- modules/apache/load_balancer
|
190
191
|
- modules/apache/model.json
|
191
192
|
- modules/apache/test.sfp
|
193
|
+
- modules/apache2/apache2.rb
|
194
|
+
- modules/apache2/apache2.sfp
|
192
195
|
- modules/aptpackage/aptpackage.rb
|
193
196
|
- modules/aptpackage/aptpackage.sfp
|
194
197
|
- modules/bonfire/.gitignore
|
@@ -227,7 +230,6 @@ files:
|
|
227
230
|
- modules/hpcloud/hpcloud.rb
|
228
231
|
- modules/hpcloud/hpcloud.sfp
|
229
232
|
- modules/hpcloud/test.sfp
|
230
|
-
- modules/install_module
|
231
233
|
- modules/machine/machine.rb
|
232
234
|
- modules/machine/machine.sfp
|
233
235
|
- modules/mockcloud/mockcloud.rb
|
@@ -244,10 +246,14 @@ files:
|
|
244
246
|
- modules/package/package.rb
|
245
247
|
- modules/package/package.sfp
|
246
248
|
- modules/package/test.sfp
|
247
|
-
- modules/
|
249
|
+
- modules/package2/package2.rb
|
250
|
+
- modules/package2/package2.sfp
|
251
|
+
- modules/pyfile/main
|
252
|
+
- modules/pyfile/pyfile.sfp
|
248
253
|
- modules/service/service.rb
|
249
254
|
- modules/service/service.sfp
|
250
|
-
- modules/
|
255
|
+
- modules/service2/service2.rb
|
256
|
+
- modules/service2/service2.sfp
|
251
257
|
- modules/tarpackage/tarpackage.rb
|
252
258
|
- modules/tarpackage/tarpackage.sfp
|
253
259
|
- modules/vm/vm.rb
|
data/bin/delete_modules
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
require 'net/http'
|
5
|
-
|
6
|
-
module Nuri
|
7
|
-
module Util
|
8
|
-
def self.delete_modules(address, port, protocol="http")
|
9
|
-
url = "#{protocol}://#{address}:#{port}/modules"
|
10
|
-
uri = URI.parse(url)
|
11
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
12
|
-
request = Net::HTTP::Delete.new(uri.request_uri)
|
13
|
-
response = http.request(request)
|
14
|
-
(response.code == '200')
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
if $0 == __FILE__
|
20
|
-
DefaultPort = 1314
|
21
|
-
|
22
|
-
if ARGV.length < 1
|
23
|
-
puts "Usage: delete_modules <address> [port]"
|
24
|
-
exit(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
address = ARGV.shift
|
28
|
-
port = (ARGV[0].nil? ? DefaultPort : ARGV[0].to_i)
|
29
|
-
|
30
|
-
if Nuri::Util.delete_modules(address, port)
|
31
|
-
puts '{"status":"ok"}'
|
32
|
-
else
|
33
|
-
puts '{"status":"failed"}'
|
34
|
-
end
|
35
|
-
end
|
data/bin/nuri.old
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
dir = File.expand_path(File.dirname(__FILE__)) + '/../lib'
|
4
|
-
require "#{dir}/nuri"
|
5
|
-
|
6
|
-
require 'coderay'
|
7
|
-
require 'logger'
|
8
|
-
|
9
|
-
version = File.read(File.dirname(__FILE__) + '/../VERSION').sub(/\n/, '')
|
10
|
-
|
11
|
-
opts = Trollop::options do
|
12
|
-
version "Nuri #{version} (c) 2013"
|
13
|
-
banner <<-EOS
|
14
|
-
Usage: nuri [options]
|
15
|
-
where [options] are:
|
16
|
-
EOS
|
17
|
-
|
18
|
-
opt :model_file, "Model of configuration file.", :default => '', :short => '-m'
|
19
|
-
opt :state, "Print the current state of the system in JSON based on given model file.", :short => '-s'
|
20
|
-
opt :plan, "Print the plan that could bring the system to the desired state as defined in model file.", :short => '-p'
|
21
|
-
opt :parallel, "Generate a parallel plan.", :short => '-l'
|
22
|
-
opt :bsig_deploy, "Generate and deploy Behavioural Signature model", :short => '-b'
|
23
|
-
opt :bsig_purge, "Purge Behavioural Signature model", :short => '-g'
|
24
|
-
opt :execute, "Execute a plan in given file. Note: model file should be specified.", :default => '', :short => '-x'
|
25
|
-
opt :apply, "Generate and execute a plan that could bring the system to the desired state.", :short => '-a'
|
26
|
-
opt :push_modules, "Automatically push an unavailable module to target agent.", :short => '-u'
|
27
|
-
opt :human, "Use human readable format.", :short => '-h'
|
28
|
-
opt :pretty, "Use pretty JSON format.", :short => '-r'
|
29
|
-
opt :silent, "Set off interactive mode.", :defaut => true, :short => '-n'
|
30
|
-
#opt :start, "Start master daemon.", :short => '-s'
|
31
|
-
#opt :stop, "Stop master daemon.", :short => '-t'
|
32
|
-
end
|
33
|
-
|
34
|
-
puts opts.inspect
|
35
|
-
def plan_to_human(plan)
|
36
|
-
return 'No solution plan.'.red if plan['workflow'].nil?
|
37
|
-
return 'The system is at the goal state.'.green if plan['workflow'].length <= 0
|
38
|
-
|
39
|
-
p = ''
|
40
|
-
actions = plan['workflow']
|
41
|
-
if plan['type'] == 'sequential'
|
42
|
-
p = 'Sequential Plan:'.yellow
|
43
|
-
actions.each_index { |i| p += "\n#{i+1}. #{actions[i]['name']} #{JSON.generate(actions[i]['parameters'])}" }
|
44
|
-
else
|
45
|
-
p = 'Partial-Order Plan:'.yellow
|
46
|
-
actions.each { |op| p += "\n#{op['id']+1}. #{op['name']} #{JSON.generate(op['parameters'])} (#{op['predecessors'].map{|i|i+1}}, #{op['successors'].map{|i|i+1}})" }
|
47
|
-
end
|
48
|
-
p
|
49
|
-
end
|
50
|
-
|
51
|
-
def verify_model(opts)
|
52
|
-
if opts[:model_file].length <= 0
|
53
|
-
puts "Model file is not specified! Use \"-h\" option for more details.".red
|
54
|
-
exit(false)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
if opts[:state]
|
59
|
-
verify_model(opts)
|
60
|
-
|
61
|
-
master = Nuri::Master.new
|
62
|
-
master.set_model(opts)
|
63
|
-
state = master.get_state(opts)
|
64
|
-
state.accept(Sfp::Visitor::PrettyStateGenerator.new)
|
65
|
-
if opts[:human]
|
66
|
-
puts CodeRay.encode(JSON.pretty_generate(state), :json, :terminal)
|
67
|
-
else
|
68
|
-
puts (opts[:pretty] ? JSON.pretty_generate(state) : JSON.generate(state))
|
69
|
-
end
|
70
|
-
|
71
|
-
elsif opts[:plan]
|
72
|
-
verify_model(opts)
|
73
|
-
|
74
|
-
master = Nuri::Master.new
|
75
|
-
master.set_model(opts)
|
76
|
-
plan = master.get_plan(opts)
|
77
|
-
if !plan.is_a?(Hash) or plan['workflow'].nil?
|
78
|
-
puts "Plan: ".yellow + "\nno solution!".red
|
79
|
-
else
|
80
|
-
if opts[:human]
|
81
|
-
puts plan_to_human(plan)
|
82
|
-
else
|
83
|
-
puts (opts[:pretty] ? JSON.pretty_generate(plan) : JSON.generate(plan))
|
84
|
-
end
|
85
|
-
|
86
|
-
if not opts[:silent] and plan['workflow'].is_a?(Array) and plan['workflow'].length > 0
|
87
|
-
print "Execute the plan [y/N]? "
|
88
|
-
if STDIN.gets.chomp.upcase == 'Y'
|
89
|
-
puts 'Executing the plan:'.yellow
|
90
|
-
opts[:plan] = plan
|
91
|
-
puts (master.execute_plan(opts) ? "Execution success!".green : "Execution failed!".red)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
elsif opts[:execute].length > 0
|
97
|
-
verify_model(opts)
|
98
|
-
|
99
|
-
master = Nuri::Master.new
|
100
|
-
master.set_model(opts)
|
101
|
-
puts (master.execute_plan(opts) ? "Execution success!".green : "Execution failed!".red)
|
102
|
-
|
103
|
-
elsif opts[:apply]
|
104
|
-
verify_model(opts)
|
105
|
-
|
106
|
-
master = Nuri::Master.new
|
107
|
-
master.set_model(opts)
|
108
|
-
plan = master.get_plan(opts)
|
109
|
-
if not plan.is_a?(Hash)
|
110
|
-
puts "No solution!".red
|
111
|
-
else
|
112
|
-
if opts[:human]
|
113
|
-
puts plan_to_human(plan)
|
114
|
-
else
|
115
|
-
puts (opts[:pretty] ? JSON.pretty_generate(plan) : JSON.generate(plan))
|
116
|
-
end
|
117
|
-
|
118
|
-
if plan['workflow'].is_a?(Array) and plan['workflow'].length > 0
|
119
|
-
puts 'Executing the plan...'.yellow
|
120
|
-
opts[:plan] = plan
|
121
|
-
puts (master.execute_plan(opts) ? "Execution success!".green : "Execution failed!".red)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
elsif opts[:bsig_deploy]
|
126
|
-
verify_model(opts)
|
127
|
-
opts[:parallel] = true
|
128
|
-
|
129
|
-
master = Nuri::Master.new
|
130
|
-
master.set_model(opts)
|
131
|
-
bsig = master.get_bsig(opts)
|
132
|
-
|
133
|
-
if not bsig.is_a?(Hash)
|
134
|
-
puts "\nNo solution!".red
|
135
|
-
elsif bsig.length > 0
|
136
|
-
empty_local_bsig = bsig.select { |name,local_bsig| local_bsig['operators'].length <= 0 }
|
137
|
-
|
138
|
-
if empty_local_bsig.length == bsig.length
|
139
|
-
puts "The goal state has been achieved!".green
|
140
|
-
|
141
|
-
else
|
142
|
-
# print the BSig model
|
143
|
-
if opts[:human]
|
144
|
-
puts CodeRay.encode(JSON.pretty_generate(bsig), :json, :terminal)
|
145
|
-
else
|
146
|
-
puts (opts[:pretty] ? JSON.pretty_generate(bsig) : JSON.generate(bsig))
|
147
|
-
end
|
148
|
-
|
149
|
-
if not opts[:silent]
|
150
|
-
print "Deploy the BSig model [y/N]? "
|
151
|
-
if STDIN.gets.chomp.upcase == 'Y'
|
152
|
-
puts 'Deploying the BSig model:'.yellow
|
153
|
-
opts[:bsig] = bsig
|
154
|
-
puts (master.deploy_bsig(opts) ? "Deployment success!".green : "Deployment failed!".red)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
elsif opts[:bsig_purge]
|
162
|
-
verify_model(opts)
|
163
|
-
|
164
|
-
puts "Purging Behavioural Signature model...".yellow
|
165
|
-
master = Nuri::Master.new
|
166
|
-
master.set_model(opts)
|
167
|
-
if master.purge_bsig(opts)
|
168
|
-
puts "Purging Behavioural Signature model [OK]".green
|
169
|
-
else
|
170
|
-
puts "Purging Behavioural Signature model [Failed]".red
|
171
|
-
end
|
172
|
-
|
173
|
-
=begin
|
174
|
-
elsif opts[:start]
|
175
|
-
puts "Not implemented yet!".red
|
176
|
-
|
177
|
-
elsif opts[:stop]
|
178
|
-
puts "Not implemented yet!".red
|
179
|
-
=end
|
180
|
-
|
181
|
-
else
|
182
|
-
Trollop::help
|
183
|
-
end
|
data/modules/install_module
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
require 'uri'
|
5
|
-
require 'net/http'
|
6
|
-
require File.dirname(__FILE__) + '/../lib/nuri/targz'
|
7
|
-
|
8
|
-
module Nuri
|
9
|
-
module Util
|
10
|
-
TarGzip = Object.new.extend(Util::Tar)
|
11
|
-
|
12
|
-
def self.install_modules(address, port, modules, protocol="http")
|
13
|
-
data = {}
|
14
|
-
modules.each do |module_name|
|
15
|
-
raise Exception, "Module #{module_name} is not exist!" if not ::File.directory?(module_name)
|
16
|
-
data[module_name] = TarGzip.targzip(module_name, module_name).read
|
17
|
-
end
|
18
|
-
|
19
|
-
url = "#{protocol}://#{address}:#{port}/modules"
|
20
|
-
uri = URI.parse(url)
|
21
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
22
|
-
request = Net::HTTP::Put.new(uri.request_uri)
|
23
|
-
request.set_form_data(data)
|
24
|
-
response = http.request(request)
|
25
|
-
|
26
|
-
(response.code == '200')
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
if $0 == __FILE__
|
32
|
-
if ARGV.length < 2
|
33
|
-
puts "Usage: install_module <address> [port] <module-name> ..."
|
34
|
-
exit(1)
|
35
|
-
end
|
36
|
-
|
37
|
-
DefaultPort = 1314
|
38
|
-
|
39
|
-
address = ARGV.shift
|
40
|
-
port = (ARGV.length >= 2 ? ARGV.shift : DefaultPort)
|
41
|
-
modules = ARGV
|
42
|
-
missing = modules.select { |mod| not ::File.directory?(mod) }
|
43
|
-
modules = modules - missing
|
44
|
-
|
45
|
-
success = Nuri::Util.install_modules(address, port, modules),
|
46
|
-
output = {
|
47
|
-
:status => success,
|
48
|
-
:installed_modules => modules,
|
49
|
-
:missing_modules => missing
|
50
|
-
}
|
51
|
-
puts JSON.generate(output)
|
52
|
-
|
53
|
-
exit (success ? 0 : 1)
|
54
|
-
end
|