nuri 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -1
  3. data/VERSION +1 -1
  4. data/bin/nuri +60 -14
  5. data/bin/nuri-install-module +17 -9
  6. data/examples/mockcloud/apache2.sfp +14 -0
  7. data/examples/mockcloud/ping.rb +38 -0
  8. data/examples/openstack/openstack-hadoop1-cluster.sfp +37 -0
  9. data/examples/openstack/openstack-hadoop2-cluster.sfp +39 -0
  10. data/examples/v2/apache.sfp +30 -0
  11. data/examples/v2/aptpackage.sfp +6 -0
  12. data/examples/v2/mock1.sfp +12 -0
  13. data/examples/v2/package.sfp +22 -0
  14. data/examples/v2/service.sfp +94 -0
  15. data/examples/v2/tarpackage.sfp +5 -0
  16. data/lib/nuri.rb +14 -10
  17. data/lib/nuri/choreographer.rb +3 -3
  18. data/lib/nuri/helper.rb +20 -10
  19. data/lib/nuri/master.rb +82 -54
  20. data/lib/nuri/orchestrator.rb +1 -1
  21. data/modules/.gitignore +0 -4
  22. data/modules/README.md +11 -0
  23. data/modules/apache/apache.sfp +2 -1
  24. data/modules/file/file.rb +49 -19
  25. data/modules/hadoop1/hadoop1.rb +18 -11
  26. data/modules/hadoop2/hadoop2.rb +11 -11
  27. data/modules/hadoop2/hadoop2.sfp +7 -6
  28. data/modules/hadoop2/yarn-site.xml +5 -0
  29. data/modules/machine/machine.rb +24 -14
  30. data/modules/openstack/README.md +24 -0
  31. data/modules/openstack/config.yml +5 -0
  32. data/modules/openstack/example.sfp +9 -0
  33. data/modules/openstack/openstack.rb +329 -0
  34. data/modules/openstack/openstack.sfp +24 -0
  35. data/modules/os/os.rb +1 -1
  36. data/modules/package2/apt-repo-list.sh +15 -0
  37. data/modules/package2/package2.rb +213 -43
  38. data/modules/package2/package2.sfp +3 -2
  39. data/modules/pyfile/README.md +4 -0
  40. data/modules/vm/vm.rb +3 -1
  41. data/modules/vm/vm.sfp +4 -3
  42. metadata +20 -3
  43. data/modules/hpcloud/test.sfp +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52435655f176b90c016bb5f1ae94348f03c480c7
4
- data.tar.gz: 12e8e06d2689353bb6fd3dfe2b8047b709ba8d20
3
+ metadata.gz: 9d540fda2ce76121b09511e85b2c986141462e3f
4
+ data.tar.gz: 36872856f912ad6cbd3998fac2721ac4c7713e8b
5
5
  SHA512:
6
- metadata.gz: fbe8ac30498b9f0c672dcf429d6c7a5e7178e00a24c50c725cd95d1472d06d570e0a35121913d266c112b797c4af141ad16b2bd0870c7899006484102093dadf
7
- data.tar.gz: da39e1869ccf6eae68622497fe2f99c6143079dc57aa8675a6a6ebc2584f28c51d4477587e86359273c8c763537657bc4bf3c32c4dd0220e52ed6b0c9a5c9684
6
+ metadata.gz: d5bf64d0730f0f802a28d0464e79905f0c9a1ed60a7e083d6276b93f3eae99a1016eac02a57ccd7f0ff65b4b9c47f92f3828b4379c8fec942c562af643c0cb61
7
+ data.tar.gz: c593d7e1a00db7e9e8c2e5c95b79e0573b849dcd3f8a6aea7343f34cf762db3de27d6a45c6cee78bd00e63905e8c3f0bcc0f8a57360965c9a70f7180cd3e5b49
data/README.md CHANGED
@@ -58,10 +58,14 @@ Assume that the model of your system is in file "model.sfp".
58
58
 
59
59
  press 'Y' and enter to execute the plan (if the plan exists).
60
60
 
61
- - to execute any generated plan
61
+ - to execute any generated plan with orchestration
62
62
 
63
63
  $ nuri plan -m model.sfp -a
64
64
 
65
+ - to execute any generated plan with choreography
66
+
67
+ $ nuri bsig -a
68
+
65
69
 
66
70
  Console mode
67
71
  ------------
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.3
1
+ 0.5.4
data/bin/nuri CHANGED
@@ -6,8 +6,6 @@ require "#{dir}/lib/nuri"
6
6
  Version = File.read(File.dirname(__FILE__) + "/../VERSION").strip
7
7
  About = "Nuri #{Version} (c) 2013"
8
8
 
9
- Nuri.init
10
-
11
9
  class Nuri::Console
12
10
  include Nuri::Helper
13
11
 
@@ -27,7 +25,7 @@ class Nuri::Console
27
25
  def do_state(args=ARGV, cmd="nuri ")
28
26
  parser = Trollop::Parser.new do
29
27
  banner <<-EOS
30
- Usage: #{cmd}state [options]
28
+ Usage: #{cmd}state [options] [path]
31
29
  where [options] are:
32
30
  EOS
33
31
  opt :model_file, 'file contains a model of desired state', :default => Nuri.main, :short => '-m'
@@ -48,12 +46,17 @@ EOS
48
46
  state = master.get_state opts
49
47
  state.accept(Sfp::Helper::Sfp2Ruby)
50
48
 
49
+ if args.length > 0
50
+ state = state.at?("$.#{args[0]}")
51
+ puts (!opts[:color] ? "Path: #{args[0]}" : "Path: " + "#{args[0]}".yellow)
52
+ end
53
+
51
54
  if opts[:json]
52
55
  puts (!opts[:color] ? JSON.generate(state) : CodeRay.encode(JSON.pretty_generate(state), :json, :terminal))
53
56
  else
54
57
  puts (!opts[:color] ? YAML.dump(state) : CodeRay.encode(YAML.dump(state), :yaml, :terminal))
55
-
56
58
  end
59
+
57
60
  else
58
61
  $stderr.puts "Model file '#{opts[:model_file]}' is not exist! Use \"-h\" option for more details.".red
59
62
 
@@ -73,7 +76,7 @@ EOS
73
76
  opt :color, 'enable colorized output'
74
77
  opt :no_interactive, 'disable interactive input'
75
78
  opt :no_push_module, 'disable automatic push module'
76
- opt :image, 'image graph of the generated plan', :default => Dir.home + '/.nuri/plan.png'
79
+ opt :image, 'image graph of the generated plan', :default => '' #Dir.home + '/.nuri/plan.png'
77
80
  end
78
81
  help, args = check_help(args)
79
82
  opts = process_args args, parser
@@ -92,7 +95,7 @@ EOS
92
95
  plan_file = Dir.home + '/.nuri/plan.json'
93
96
  File.open(plan_file, 'w') { |f| f.write(JSON.generate(plan)) }
94
97
 
95
- if opts[:image]
98
+ if opts[:image].strip.length > 0
96
99
  system "#{File.dirname(__FILE__)}/nuri-sfwgraph #{plan_file} #{opts[:image]}"
97
100
  end
98
101
 
@@ -147,25 +150,60 @@ Usage: #{cmd}bsig [options]
147
150
  where [options] are:
148
151
  EOS
149
152
  opt :model_file, 'file contains a model of desired state', :default => Nuri.main, :short => '-m'
153
+ opt :apply, 'generate and then deploy a BSig model'
154
+ opt :status, 'get BSig status of all agents'
150
155
  opt :purge, 'purge existing BSig model', :short => '-g'
151
- opt :deploy, 'generate and then deploy a BSig model'
152
156
  opt :color, 'enable colorized output'
153
157
  opt :no_interactive, 'disable interactive input'
158
+ opt :no_push_module, 'disable automatic push module'
154
159
  end
155
160
  help, args = check_help(args)
156
161
  opts = process_args args, parser
157
162
 
158
163
  if help
159
164
  parser.educate(STDOUT)
165
+
166
+ elsif opts[:status]
167
+ opts[:push_modules] = true if !opts[:no_push_module]
168
+ master = Nuri::Master.new
169
+ master.set_model opts
170
+ master.get_state(opts).each do |name,state|
171
+ print "- #{name}: "
172
+ if not state.is_a?(Hash) or not state.has_key?('sfpAddress')
173
+ puts (opts[:color] ? "unknown address".yellow : "unknown address")
174
+ else
175
+ address = state['sfpAddress']
176
+ port = (state['sfpPort'] ? state['sfpPort'] : 1314)
177
+ if address.is_a?(String) and port.is_a?(Fixnum)
178
+ status = Net::HTTP.get(URI("http://#{address}:#{port}/bsig/flaws"))
179
+ if status == '{}'
180
+ puts (opts[:color] ? "no-flaws".green : "no-flaws")
181
+ else
182
+ puts (opts[:color] ? status.yellow : status)
183
+ end
184
+ elsif address.is_a?(Sfp::Undefined)
185
+ puts (opts[:color] ? "not-exist".yellow : "not-exist")
186
+ elsif address.is_a?(Sfp::Unknown)
187
+ puts (opts[:color] ? "unknown".yellow : "unknown")
188
+ end
189
+ end
190
+ end
191
+
160
192
  elsif File.exist?(opts[:model_file])
161
193
  opts[:bsig_deploy] = true
162
194
  opts[:parallel] = true
195
+ opts[:push_modules] = true if !opts[:no_push_module]
163
196
  master = Nuri::Master.new
164
197
  master.set_model(opts)
165
198
 
166
199
  if opts[:purge]
167
200
  print "Purging Behavioural Signature model "
168
- if master.purge_bsig(opts)
201
+ puts (opts[:color] ? "[Wait]".yellow : "[Wait]")
202
+
203
+ status = master.purge_bsig(opts)
204
+ print "Purging Behavioural Signature model "
205
+
206
+ if status
169
207
  puts (opts[:color] ? "[OK]".green : "[OK]")
170
208
  else
171
209
  puts (opts[:color] ? "[Failed]".red : "[Failed]")
@@ -179,17 +217,21 @@ EOS
179
217
  json = JSON.pretty_generate(bsig)
180
218
  puts (opts[:color] ? CodeRay.encode(json, :json, :terminal) : json)
181
219
 
182
- if not opts[:no_interactive] and not opts[:deploy]
220
+ if not opts[:no_interactive] and not opts[:apply]
183
221
  print "Deploy the BSig model [y/N]? "
184
- opts[:deploy] = true if STDIN.gets.chomp.upcase == 'Y'
222
+ opts[:apply] = true if STDIN.gets.chomp.upcase == 'Y'
185
223
  end
186
224
 
187
- if opts[:deploy]
225
+ if opts[:apply]
188
226
  print 'Deploying the BSig model '
227
+ puts (opts[:color] ? "[Wait]".yellow : "[Wait]")
228
+
189
229
  opts[:bsig] = bsig
190
230
  if master.deploy_bsig(opts)
231
+ print 'Deploying the BSig model '
191
232
  puts (opts[:color] ? "[OK]".green : "[OK]")
192
233
  else
234
+ print 'Deploying the BSig model '
193
235
  puts (opts[:color] ? "[Failed]".red : "[Failed]")
194
236
  end
195
237
  end
@@ -400,8 +442,8 @@ EOS
400
442
  agents = {}
401
443
  state.each do |name,model|
402
444
  agents[name] = {
403
- 'sfpAddress' => (model['sfpAddress'].is_a?(String) ? model['sfpAddress'] : ''),
404
- 'sfpPort' => (model['sfpPort'].is_a?(Fixnum) ? model['sfpPort'] : 0)
445
+ 'sfpAddress' => (model.is_a?(Hash) and model['sfpAddress'].is_a?(String) ? model['sfpAddress'] : ''),
446
+ 'sfpPort' => (model.is_a?(Hash) and model['sfpPort'].is_a?(Fixnum) ? model['sfpPort'] : 0)
405
447
  }
406
448
  end
407
449
  agents
@@ -554,4 +596,8 @@ EOS
554
596
  end
555
597
  end
556
598
 
557
- Nuri::Console.new.run if $0 == __FILE__
599
+ if $0 == __FILE__
600
+ Nuri.init
601
+ Nuri::Console.new.run
602
+ end
603
+
@@ -9,21 +9,29 @@ module Nuri
9
9
  module Util
10
10
  TarGzip = Object.new.extend(Util::Tar)
11
11
 
12
- def self.install_modules(address, port, modules, protocol="http")
12
+ def self.install_modules(address, port, modules, protocol="http", open_timeout=2, read_timeout=10)
13
13
  data = {}
14
14
  modules.each do |module_name|
15
15
  raise Exception, "Module #{module_name} is not exist!" if not ::File.directory?(module_name)
16
16
  data[module_name] = TarGzip.targzip(module_name, module_name).read
17
17
  end
18
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')
19
+ begin
20
+ url = "#{protocol}://#{address}:#{port}/modules"
21
+ uri = URI.parse(url)
22
+ http = Net::HTTP.new(uri.host, uri.port)
23
+ http.open_timeout = open_timeout
24
+ http.read_timeout = read_timeout
25
+ request = Net::HTTP::Put.new(uri.request_uri)
26
+ request.set_form_data(data)
27
+ response = http.request(request)
28
+
29
+ (response.code == '200')
30
+ rescue Exception => e
31
+ $stderr.puts "Cannot install module with URL: #{url}"
32
+ $stderr.puts e
33
+ false
34
+ end
27
35
  end
28
36
  end
29
37
  end
@@ -0,0 +1,14 @@
1
+ include "modules/node/node.sfp"
2
+ include "modules/apache2/apache2.sfp"
3
+ include "modules/vm/vm.sfp"
4
+ include "modules/mockcloud/mockcloud.sfp"
5
+
6
+ local isa Node {
7
+ sfpAddress is "localhost"
8
+ hpcloud isa MockCloud
9
+ }
10
+ vm1 isa VM {
11
+ apache isa Apache2 {
12
+ running is true
13
+ }
14
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'net/http'
4
+ require 'thread'
5
+
6
+ len = 120
7
+
8
+ def ping(address, port=1314)
9
+ print "print #{address} "
10
+ url = "http://#{address}:#{port}/sfpstate"
11
+ uri = URI.parse(url)
12
+ http = Net::HTTP.new(uri.host, uri.port)
13
+ http.open_timeout = 2
14
+ http.read_timeout = 5
15
+ begin
16
+ req = Net::HTTP::Get.new(uri.path)
17
+ http.start
18
+ http.request(req) { |res|
19
+ puts "[#{res.code}] [OK]"
20
+ }
21
+ rescue Exception => e
22
+ puts "[Failed] #{e}" #\n#{e.backtrace.join("\n")}"
23
+ end
24
+ end
25
+
26
+ ping('hadoopmaster')
27
+ finished = []
28
+ (1..len).each do |i|
29
+ # Thread.new {
30
+ host = "hadoopslave#{i}"
31
+ ping(host)
32
+ finished << host
33
+ # }
34
+ end
35
+
36
+ until finished.length >= len do
37
+ sleep 1
38
+ end
@@ -0,0 +1,37 @@
1
+ include "modules/vm/vm.sfp"
2
+ include "modules/openstack/openstack.sfp"
3
+
4
+ proxy isa Node {
5
+ sfpAddress is "localhost"
6
+ herry isa OpenStack {
7
+ // replace the value of OpenStack Identity's URL plus "/tokens/"
8
+ auth_uri is "http://16.25.166.21:5000/v2.0/tokens/"
9
+
10
+ // replace the value with your SSH key name, and then put
11
+ // the private key (with name <key-name>.pem) in module's directory.
12
+ vm_ssh_key_name is "nurikey"
13
+
14
+ // an image that already has nuri agent
15
+ vm_image is "8fe14786-5388-4787-8aaf-96feebfa8aae"
16
+ }
17
+ }
18
+
19
+ include "modules/hadoop1/hadoop1.sfp"
20
+
21
+ vm1 isa VM {
22
+ hadoop isa Hadoop1Master {
23
+ // replace this with the URL of hadoop1 tar package file
24
+ source is "http://master.nuri.ext9.sup.hpl.hp.com/hadoop"
25
+ }
26
+ }
27
+ vm2 isa VM {
28
+ hadoop isa Hadoop1Slave {
29
+ master is vm1.hadoop
30
+ // replace this with the URL of hadoop1 tar package file
31
+ source is "http://master.nuri.ext9.sup.hpl.hp.com/hadoop"
32
+ }
33
+ }
34
+ vm3 extends vm2
35
+ vm4 extends vm2
36
+ vm5 extends vm2
37
+ vm6 extends vm2
@@ -0,0 +1,39 @@
1
+ include "modules/vm/vm.sfp"
2
+ include "modules/openstack/openstack.sfp"
3
+
4
+ proxy isa Node {
5
+ sfpAddress is "localhost"
6
+ herry isa OpenStack {
7
+ auth_uri is "http://16.25.166.21:5000/v2.0/tokens/"
8
+
9
+ // use m1.medium (id="2") flavor because Hadoop2 requires minimum 4GB of memory
10
+ vm_flavor is "3"
11
+
12
+ // - replace the value with your key name
13
+ // - put the key file <key-name>.pem in module's directory
14
+ vm_ssh_key_name is "nurikey"
15
+
16
+ // a VM image that already has Nuri agent
17
+ vm_image is "8fe14786-5388-4787-8aaf-96feebfa8aae"
18
+ }
19
+ }
20
+
21
+ include "modules/hadoop2/hadoop2.sfp"
22
+
23
+ vm1 isa VM {
24
+ hadoop isa Hadoop2Master {
25
+ // replace this with the URL of hadoop2 tar package file
26
+ source is "http://master.nuri.ext9.sup.hpl.hp.com/hadoop"
27
+ }
28
+ }
29
+ vm2 isa VM {
30
+ hadoop isa Hadoop2Slave {
31
+ master is vm1.hadoop
32
+ // replace this with the URL of hadoop2 tar package file
33
+ source is "http://master.nuri.ext9.sup.hpl.hp.com/hadoop"
34
+ }
35
+ }
36
+ vm3 extends vm2
37
+ vm4 extends vm2
38
+ vm5 extends vm2
39
+ vm6 extends vm2
@@ -0,0 +1,30 @@
1
+ include "service.sfp"
2
+
3
+ schema Apache extends Service {
4
+ package_name = "apache2"
5
+ service_name = "apache2"
6
+ installed = true
7
+ running = true
8
+ configured = true
9
+
10
+ final port = 80
11
+ final document_root = "/var/www"
12
+ final modules isset String
13
+ final server_name = ""
14
+
15
+ // load balancer config
16
+ final load_balancer = false
17
+ final lb_members isset Node
18
+ final lb_method = "byrequests" // byrequests, bytraffic, bybusyness
19
+
20
+ sub configure {
21
+ condition {
22
+ this.installed = true
23
+ this.running = false
24
+ this.configured = false
25
+ }
26
+ effect {
27
+ this.configured = true
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,6 @@
1
+ include "package.sfp"
2
+
3
+ schema AptPackage extends Package {
4
+ final version = "latest"
5
+ final source = "default"
6
+ }
@@ -0,0 +1,12 @@
1
+ include "../../modules/mockcloud/mockcloud.sfp"
2
+ include "../../modules/vm/vm.sfp"
3
+ include "apache.sfp"
4
+
5
+ proxy isa Node {
6
+ sfpAddress is "localhost"
7
+ mockcloud isa MockCloud
8
+ }
9
+ vm1 isa VM {
10
+ //apache isa Apache
11
+ s isa Service
12
+ }
@@ -0,0 +1,22 @@
1
+ schema Package {
2
+ installed = true
3
+
4
+ final package_name = ""
5
+ final version = ""
6
+ final source = ""
7
+
8
+ synchronized sub install {
9
+ effect {
10
+ this.installed = true
11
+ }
12
+ }
13
+
14
+ synchronized sub uninstall {
15
+ condition {
16
+ this.installed = true
17
+ }
18
+ effect {
19
+ this.installed = false
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,94 @@
1
+ include "aptpackage.sfp"
2
+
3
+ schema Service {
4
+ running = true
5
+ configured = true
6
+
7
+ final service_name = ""
8
+
9
+ sub start {
10
+ condition {
11
+ this.running != true
12
+ this.configured = true
13
+ }
14
+ effect {
15
+ this.running = true
16
+ }
17
+ }
18
+
19
+ sub stop {
20
+ condition {
21
+ this.running = true
22
+ }
23
+ effect {
24
+ this.running = false
25
+ }
26
+ }
27
+
28
+ sub configure {
29
+ condition {
30
+ this.running = false
31
+ }
32
+ effect {
33
+ this.configured = true
34
+ }
35
+ }
36
+ }
37
+
38
+ schema SysVService extends Service {
39
+ final runlevel isset String
40
+ }
41
+
42
+ schema AptService extends AptPackage {
43
+ synchronized sub install {
44
+ condition {
45
+ this.installed != true
46
+ }
47
+ effect {
48
+ this.installed = true
49
+ this.running = false
50
+ this.configured = false
51
+ }
52
+ }
53
+
54
+ synchronized sub uninstall {
55
+ condition {
56
+ this.running = false
57
+ this.installed = true
58
+ }
59
+ effect {
60
+ this.installed = false
61
+ this.configured = true
62
+ }
63
+ }
64
+
65
+ sub start {
66
+ condition {
67
+ this.running != true
68
+ this.installed = true
69
+ this.configured = true
70
+ }
71
+ effect {
72
+ this.running = true
73
+ }
74
+ }
75
+
76
+ sub stop {
77
+ condition {
78
+ this.running = true
79
+ }
80
+ effect {
81
+ this.running = false
82
+ }
83
+ }
84
+
85
+ sub configure {
86
+ condition {
87
+ this.installed = true
88
+ this.running = false
89
+ }
90
+ effect {
91
+ this.configured = true
92
+ }
93
+ }
94
+ }