isono 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/LICENSE +202 -0
  2. data/NOTICE +2 -0
  3. data/bin/cli +122 -0
  4. data/isono.gemspec +47 -0
  5. data/lib/ext/shellwords.rb +172 -0
  6. data/lib/isono.rb +61 -0
  7. data/lib/isono/amqp_client.rb +169 -0
  8. data/lib/isono/daemonize.rb +96 -0
  9. data/lib/isono/event_delegate_context.rb +56 -0
  10. data/lib/isono/event_observable.rb +86 -0
  11. data/lib/isono/logger.rb +48 -0
  12. data/lib/isono/manifest.rb +161 -0
  13. data/lib/isono/messaging_client.rb +116 -0
  14. data/lib/isono/models/event_log.rb +28 -0
  15. data/lib/isono/models/job_state.rb +35 -0
  16. data/lib/isono/models/node_state.rb +70 -0
  17. data/lib/isono/models/resource_instance.rb +35 -0
  18. data/lib/isono/node.rb +158 -0
  19. data/lib/isono/node_modules/base.rb +65 -0
  20. data/lib/isono/node_modules/data_store.rb +57 -0
  21. data/lib/isono/node_modules/event_channel.rb +72 -0
  22. data/lib/isono/node_modules/event_logger.rb +39 -0
  23. data/lib/isono/node_modules/job_channel.rb +86 -0
  24. data/lib/isono/node_modules/job_collector.rb +47 -0
  25. data/lib/isono/node_modules/job_worker.rb +152 -0
  26. data/lib/isono/node_modules/node_collector.rb +87 -0
  27. data/lib/isono/node_modules/node_heartbeat.rb +26 -0
  28. data/lib/isono/node_modules/rpc_channel.rb +482 -0
  29. data/lib/isono/rack.rb +67 -0
  30. data/lib/isono/rack/builder.rb +40 -0
  31. data/lib/isono/rack/data_store.rb +20 -0
  32. data/lib/isono/rack/job.rb +74 -0
  33. data/lib/isono/rack/map.rb +56 -0
  34. data/lib/isono/rack/object_method.rb +20 -0
  35. data/lib/isono/rack/proc.rb +50 -0
  36. data/lib/isono/rack/thread_pass.rb +22 -0
  37. data/lib/isono/resource_manifest.rb +273 -0
  38. data/lib/isono/runner/agent.rb +89 -0
  39. data/lib/isono/runner/rpc_server.rb +198 -0
  40. data/lib/isono/serializer.rb +43 -0
  41. data/lib/isono/thread_pool.rb +169 -0
  42. data/lib/isono/util.rb +212 -0
  43. metadata +185 -0
@@ -0,0 +1,212 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'digest/sha1'
4
+ require 'hmac-sha1'
5
+ require 'thread'
6
+ require 'stringio'
7
+
8
+ require 'shellwords'
9
+ unless Shellwords.respond_to? :shellescape
10
+ require 'ext/shellwords'
11
+ end
12
+
13
+ require 'eventmachine'
14
+
15
+ module Isono
16
+ module Util
17
+
18
+ ##
19
+ # Convert to snake case.
20
+ #
21
+ # "FooBar".snake_case #=> "foo_bar"
22
+ # "HeadlineCNNNews".snake_case #=> "headline_cnn_news"
23
+ # "CNN".snake_case #=> "cnn"
24
+ #
25
+ # @return [String] Receiver converted to snake case.
26
+ #
27
+ # @api public
28
+ def snake_case(str)
29
+ return str.downcase if str.match(/\A[A-Z]+\z/)
30
+ str.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
31
+ gsub(/([a-z])([A-Z])/, '\1_\2').
32
+ downcase
33
+ end
34
+ module_function :snake_case
35
+
36
+ def gen_id(str=nil)
37
+ Digest::SHA1.hexdigest( (str.nil? ? rand.to_s : str) )
38
+ end
39
+ module_function :gen_id
40
+
41
+ # Return the IP address assigned to default gw interface
42
+ def default_gw_ipaddr
43
+ ip = case `/bin/uname -s`.rstrip
44
+ when 'Linux'
45
+ `/sbin/ip route get 8.8.8.8`.split("\n")[0].split.last
46
+ when 'SunOS'
47
+ `/sbin/ifconfig $(route get 1.1.1.1 | awk '$1 == "interface:" {print $2}') | awk '$1 == "inet" { print $2 }'`
48
+ else
49
+ raise "Unsupported platform to detect gateway IP address: #{`/bin/uname`}"
50
+ end
51
+ ip = ip.rstrip
52
+ raise "Failed to run command lines or empty result" if ip == '' || $?.exitstatus != 0
53
+ ip
54
+ end
55
+ module_function :default_gw_ipaddr
56
+
57
+ def quote_args(cmd_str, args=[], quote_char='\'')
58
+ quote_helper =
59
+ if quote_char
60
+ proc { |a|
61
+ [quote_char, Shellwords.shellescape(a), quote_char].join
62
+ }
63
+ else
64
+ proc { |a|
65
+ Shellwords.shellescape(a)
66
+ }
67
+ end
68
+ sprintf(cmd_str, *args.map {|a| quote_helper.call(a) })
69
+ end
70
+ module_function :quote_args
71
+
72
+ # system('/bin/ls')
73
+ # second arg gives
74
+ # system('/bin/ls %s', ['/home'])
75
+ def system(cmd_str, args=[], opts={})
76
+ unless EventMachine.reactor_running?
77
+ raise "has to prepare EventMachine context"
78
+ end
79
+
80
+ cmd = quote_args(cmd_str, args, (opts[:quote_char] || '\''))
81
+
82
+ capture_io = opts[:io] || StringIO.new
83
+ stdin_buf = opts[:stdin_input]
84
+
85
+ evmsg = {:cmd => cmd}
86
+ wait_q = ::Queue.new
87
+ if opts[:timeout] && opts[:timeout].to_f > 0.0
88
+ EventMachine.add_timer(opts[:timeout].to_f) {
89
+ wait_q.enq(RuntimeError.new("timeout child process wait: #{opts[:timeout].to_f} sec(s)"))
90
+ }
91
+ evmsg[:timeout] = opts[:timeout].to_f
92
+ end
93
+ popenobj = EventMachine.popen(cmd, EmSystemCb, capture_io, stdin_buf, proc { |exit_stat|
94
+ wait_q.enq(exit_stat)
95
+ })
96
+ pid = EventMachine.get_subprocess_pid(popenobj.signature)
97
+ evmsg[:pid] = pid
98
+ if self.respond_to? :logger
99
+ logger.debug("Exec command (pid=#{pid}): #{cmd}")
100
+ end
101
+
102
+ stat = wait_q.deq
103
+ evmsg = {}
104
+
105
+ case stat
106
+ when Process::Status
107
+ evmsg[:exit_code] = stat.exitstatus
108
+ if stat.exited? && stat.exitstatus == 0
109
+ else
110
+ raise "Unexpected status from child: #{stat}"
111
+ end
112
+ when Exception
113
+ raise stat
114
+ else
115
+ raise "Unknown signal from child: #{stat}"
116
+ end
117
+
118
+ end
119
+ module_function :system
120
+
121
+ class EmSystemCb < EventMachine::Connection
122
+ def initialize(io, in_buf, exit_cb)
123
+ @io = io
124
+ @in_buf = in_buf
125
+ @exit_cb = exit_cb
126
+ end
127
+
128
+ def post_init
129
+ # send data to stdin for child process
130
+ if @in_buf
131
+ send_data @in_buf
132
+ end
133
+ end
134
+
135
+ def receive_data data
136
+ @io.write(data)
137
+ end
138
+
139
+ def unbind()
140
+ @exit_cb.call(get_status)
141
+ end
142
+ end
143
+
144
+ # return ruby binary path which is expected to be used in
145
+ # the current environment.
146
+ def ruby_bin_path
147
+ #config_section.ruby_bin_path || ENV['_'] =~ /ruby/ ||
148
+ require 'rbconfig'
149
+ File.expand_path(Config::CONFIG['RUBY_INSTALL_NAME'], Config::CONFIG['bindir'])
150
+ end
151
+ module_function :ruby_bin_path
152
+
153
+ # A utility class to interact success/error message with two different threads.
154
+ # dm = DeferedMsg.new
155
+ # EM.schedule {
156
+ # if condition
157
+ # dm.success
158
+ # else
159
+ # dm.error(RuntimeError.new("fail"))
160
+ # end
161
+ #
162
+ # dm.wait rescue abort("got failure")
163
+ # }
164
+ # # will raise RuntimeError in case of error().
165
+ # dm.wait unless EM.reactor_thread?
166
+ #
167
+ class DeferedMsg < ::Queue
168
+ class TimeoutError < StandardError; end
169
+
170
+ def initialize(timeout=60*15, th=Thread.current)
171
+ super()
172
+ @thread_wait = th
173
+ @timer_sig = EventMachine.add_timer(timeout) {
174
+ error(TimeoutError.new)
175
+ }
176
+ end
177
+
178
+ def success(returnval=true)
179
+ self.enq(returnval)
180
+ @thread_called = Thread.current
181
+ end
182
+
183
+
184
+ def error(ex)
185
+ raise TypeError unless ex.is_a?(Exception)
186
+ self.enq(ex)
187
+ @thread_called = Thread.current
188
+ end
189
+
190
+ def wait
191
+ if (@thread_called == @thread_wait || @thread_called == Thread.current ) &&
192
+ self.empty?
193
+ raise "do success() or error() prior to calling wait()"
194
+ end
195
+
196
+ ret = self.deq()
197
+ # requeue the message to distribute to another wait().
198
+ self.enq(ret)
199
+ if ret.is_a?(Exception)
200
+ raise ret
201
+ else
202
+ return ret
203
+ end
204
+ ensure
205
+ @thread_wait = nil
206
+ EventMachine.cancel_timer(@timer_sig) rescue nil
207
+ end
208
+ end
209
+
210
+ end
211
+ end
212
+
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: isono
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - axsh Ltd.
13
+ - Masahiro Fujiwara
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-18 00:00:00 +09:00
19
+ default_executable: cli
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: amqp
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 6
31
+ - 7
32
+ version: 0.6.7
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: eventmachine
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ - 12
45
+ - 10
46
+ version: 0.12.10
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: statemachine
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 1
58
+ - 0
59
+ - 0
60
+ version: 1.0.0
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: log4r
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ type: :runtime
74
+ version_requirements: *id004
75
+ - !ruby/object:Gem::Dependency
76
+ name: bacon
77
+ prerelease: false
78
+ requirement: &id005 !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ type: :development
86
+ version_requirements: *id005
87
+ - !ruby/object:Gem::Dependency
88
+ name: rake
89
+ prerelease: false
90
+ requirement: &id006 !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ type: :development
98
+ version_requirements: *id006
99
+ description:
100
+ email:
101
+ - dev@axsh.net
102
+ - m-fujiwara@axsh.net
103
+ executables:
104
+ - cli
105
+ extensions: []
106
+
107
+ extra_rdoc_files: []
108
+
109
+ files:
110
+ - bin/cli
111
+ - lib/ext/shellwords.rb
112
+ - lib/isono.rb
113
+ - lib/isono/rack/object_method.rb
114
+ - lib/isono/rack/proc.rb
115
+ - lib/isono/rack/data_store.rb
116
+ - lib/isono/rack/map.rb
117
+ - lib/isono/rack/job.rb
118
+ - lib/isono/rack/builder.rb
119
+ - lib/isono/rack/thread_pass.rb
120
+ - lib/isono/logger.rb
121
+ - lib/isono/rack.rb
122
+ - lib/isono/messaging_client.rb
123
+ - lib/isono/resource_manifest.rb
124
+ - lib/isono/node.rb
125
+ - lib/isono/manifest.rb
126
+ - lib/isono/event_delegate_context.rb
127
+ - lib/isono/amqp_client.rb
128
+ - lib/isono/node_modules/job_channel.rb
129
+ - lib/isono/node_modules/base.rb
130
+ - lib/isono/node_modules/event_logger.rb
131
+ - lib/isono/node_modules/event_channel.rb
132
+ - lib/isono/node_modules/node_heartbeat.rb
133
+ - lib/isono/node_modules/node_collector.rb
134
+ - lib/isono/node_modules/data_store.rb
135
+ - lib/isono/node_modules/job_collector.rb
136
+ - lib/isono/node_modules/rpc_channel.rb
137
+ - lib/isono/node_modules/job_worker.rb
138
+ - lib/isono/serializer.rb
139
+ - lib/isono/models/node_state.rb
140
+ - lib/isono/models/resource_instance.rb
141
+ - lib/isono/models/event_log.rb
142
+ - lib/isono/models/job_state.rb
143
+ - lib/isono/daemonize.rb
144
+ - lib/isono/util.rb
145
+ - lib/isono/thread_pool.rb
146
+ - lib/isono/runner/rpc_server.rb
147
+ - lib/isono/runner/agent.rb
148
+ - lib/isono/event_observable.rb
149
+ - isono.gemspec
150
+ - LICENSE
151
+ - NOTICE
152
+ has_rdoc: true
153
+ homepage: http://github.com/axsh/isono
154
+ licenses: []
155
+
156
+ post_install_message:
157
+ rdoc_options: []
158
+
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 1
167
+ - 8
168
+ - 7
169
+ version: 1.8.7
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ segments:
175
+ - 0
176
+ version: "0"
177
+ requirements: []
178
+
179
+ rubyforge_project:
180
+ rubygems_version: 1.3.6
181
+ signing_key:
182
+ specification_version: 3
183
+ summary: Messageing and agent fabric
184
+ test_files: []
185
+