cuboid 0.0.0 → 0.0.1alpha

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.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -0
  3. data/Gemfile +20 -5
  4. data/LICENSE.md +22 -0
  5. data/README.md +158 -19
  6. data/Rakefile +56 -3
  7. data/config/paths.yml +15 -0
  8. data/cuboid.gemspec +61 -23
  9. data/lib/cuboid.rb +96 -4
  10. data/lib/cuboid/application.rb +326 -0
  11. data/lib/cuboid/application/parts/data.rb +18 -0
  12. data/lib/cuboid/application/parts/report.rb +29 -0
  13. data/lib/cuboid/application/parts/state.rb +274 -0
  14. data/lib/cuboid/application/runtime.rb +25 -0
  15. data/lib/cuboid/banner.rb +13 -0
  16. data/lib/cuboid/data.rb +86 -0
  17. data/lib/cuboid/data/application.rb +52 -0
  18. data/lib/cuboid/error.rb +9 -0
  19. data/lib/cuboid/option_group.rb +129 -0
  20. data/lib/cuboid/option_groups.rb +8 -0
  21. data/lib/cuboid/option_groups/datastore.rb +23 -0
  22. data/lib/cuboid/option_groups/dispatcher.rb +38 -0
  23. data/lib/cuboid/option_groups/output.rb +14 -0
  24. data/lib/cuboid/option_groups/paths.rb +184 -0
  25. data/lib/cuboid/option_groups/report.rb +39 -0
  26. data/lib/cuboid/option_groups/rpc.rb +105 -0
  27. data/lib/cuboid/option_groups/scheduler.rb +27 -0
  28. data/lib/cuboid/option_groups/snapshot.rb +13 -0
  29. data/lib/cuboid/option_groups/system.rb +10 -0
  30. data/lib/cuboid/options.rb +254 -0
  31. data/lib/cuboid/processes.rb +13 -0
  32. data/lib/cuboid/processes/dispatchers.rb +140 -0
  33. data/lib/cuboid/processes/executables/base.rb +54 -0
  34. data/lib/cuboid/processes/executables/dispatcher.rb +5 -0
  35. data/lib/cuboid/processes/executables/instance.rb +12 -0
  36. data/lib/cuboid/processes/executables/rest_service.rb +13 -0
  37. data/lib/cuboid/processes/executables/scheduler.rb +5 -0
  38. data/lib/cuboid/processes/helpers.rb +4 -0
  39. data/lib/cuboid/processes/helpers/dispatchers.rb +23 -0
  40. data/lib/cuboid/processes/helpers/instances.rb +39 -0
  41. data/lib/cuboid/processes/helpers/processes.rb +23 -0
  42. data/lib/cuboid/processes/helpers/schedulers.rb +23 -0
  43. data/lib/cuboid/processes/instances.rb +203 -0
  44. data/lib/cuboid/processes/manager.rb +262 -0
  45. data/lib/cuboid/processes/schedulers.rb +128 -0
  46. data/lib/cuboid/report.rb +220 -0
  47. data/lib/cuboid/rest/server.rb +165 -0
  48. data/lib/cuboid/rest/server/instance_helpers.rb +99 -0
  49. data/lib/cuboid/rest/server/routes/dispatcher.rb +41 -0
  50. data/lib/cuboid/rest/server/routes/grid.rb +41 -0
  51. data/lib/cuboid/rest/server/routes/instances.rb +131 -0
  52. data/lib/cuboid/rest/server/routes/scheduler.rb +140 -0
  53. data/lib/cuboid/rpc/client.rb +3 -0
  54. data/lib/cuboid/rpc/client/base.rb +58 -0
  55. data/lib/cuboid/rpc/client/dispatcher.rb +58 -0
  56. data/lib/cuboid/rpc/client/instance.rb +100 -0
  57. data/lib/cuboid/rpc/client/instance/service.rb +37 -0
  58. data/lib/cuboid/rpc/client/scheduler.rb +46 -0
  59. data/lib/cuboid/rpc/serializer.rb +92 -0
  60. data/lib/cuboid/rpc/server/active_options.rb +38 -0
  61. data/lib/cuboid/rpc/server/application_wrapper.rb +138 -0
  62. data/lib/cuboid/rpc/server/base.rb +63 -0
  63. data/lib/cuboid/rpc/server/dispatcher.rb +317 -0
  64. data/lib/cuboid/rpc/server/dispatcher/node.rb +247 -0
  65. data/lib/cuboid/rpc/server/dispatcher/service.rb +145 -0
  66. data/lib/cuboid/rpc/server/instance.rb +338 -0
  67. data/lib/cuboid/rpc/server/output.rb +92 -0
  68. data/lib/cuboid/rpc/server/scheduler.rb +482 -0
  69. data/lib/cuboid/ruby.rb +4 -0
  70. data/lib/cuboid/ruby/array.rb +17 -0
  71. data/lib/cuboid/ruby/hash.rb +41 -0
  72. data/lib/cuboid/ruby/object.rb +32 -0
  73. data/lib/cuboid/snapshot.rb +186 -0
  74. data/lib/cuboid/state.rb +94 -0
  75. data/lib/cuboid/state/application.rb +309 -0
  76. data/lib/cuboid/state/options.rb +27 -0
  77. data/lib/cuboid/support.rb +11 -0
  78. data/lib/cuboid/support/buffer.rb +3 -0
  79. data/lib/cuboid/support/buffer/autoflush.rb +61 -0
  80. data/lib/cuboid/support/buffer/base.rb +91 -0
  81. data/lib/cuboid/support/cache.rb +7 -0
  82. data/lib/cuboid/support/cache/base.rb +226 -0
  83. data/lib/cuboid/support/cache/least_cost_replacement.rb +77 -0
  84. data/lib/cuboid/support/cache/least_recently_pushed.rb +21 -0
  85. data/lib/cuboid/support/cache/least_recently_used.rb +31 -0
  86. data/lib/cuboid/support/cache/preference.rb +31 -0
  87. data/lib/cuboid/support/cache/random_replacement.rb +20 -0
  88. data/lib/cuboid/support/crypto.rb +2 -0
  89. data/lib/cuboid/support/crypto/rsa_aes_cbc.rb +86 -0
  90. data/lib/cuboid/support/database.rb +5 -0
  91. data/lib/cuboid/support/database/base.rb +177 -0
  92. data/lib/cuboid/support/database/categorized_queue.rb +195 -0
  93. data/lib/cuboid/support/database/hash.rb +300 -0
  94. data/lib/cuboid/support/database/queue.rb +149 -0
  95. data/lib/cuboid/support/filter.rb +3 -0
  96. data/lib/cuboid/support/filter/base.rb +110 -0
  97. data/lib/cuboid/support/filter/set.rb +29 -0
  98. data/lib/cuboid/support/glob.rb +27 -0
  99. data/lib/cuboid/support/mixins.rb +8 -0
  100. data/lib/cuboid/support/mixins/observable.rb +99 -0
  101. data/lib/cuboid/support/mixins/parts.rb +20 -0
  102. data/lib/cuboid/support/mixins/profiler.rb +93 -0
  103. data/lib/cuboid/support/mixins/spec_instances.rb +65 -0
  104. data/lib/cuboid/support/mixins/terminal.rb +57 -0
  105. data/lib/cuboid/system.rb +119 -0
  106. data/lib/cuboid/system/platforms.rb +84 -0
  107. data/lib/cuboid/system/platforms/linux.rb +26 -0
  108. data/lib/cuboid/system/platforms/mixins/unix.rb +46 -0
  109. data/lib/cuboid/system/platforms/osx.rb +25 -0
  110. data/lib/cuboid/system/platforms/windows.rb +81 -0
  111. data/lib/cuboid/system/slots.rb +143 -0
  112. data/lib/cuboid/ui/output.rb +52 -0
  113. data/lib/cuboid/ui/output_interface.rb +43 -0
  114. data/lib/cuboid/ui/output_interface/abstract.rb +68 -0
  115. data/lib/cuboid/ui/output_interface/controls.rb +84 -0
  116. data/lib/cuboid/ui/output_interface/error_logging.rb +119 -0
  117. data/lib/cuboid/ui/output_interface/implemented.rb +58 -0
  118. data/lib/cuboid/ui/output_interface/personalization.rb +62 -0
  119. data/lib/cuboid/utilities.rb +155 -0
  120. data/lib/cuboid/version.rb +4 -3
  121. data/lib/version +1 -0
  122. data/logs/placeholder +0 -0
  123. data/spec/cuboid/application/parts/data_spec.rb +12 -0
  124. data/spec/cuboid/application/parts/report_spec.rb +6 -0
  125. data/spec/cuboid/application/parts/state_spec.rb +192 -0
  126. data/spec/cuboid/application/runtime_spec.rb +21 -0
  127. data/spec/cuboid/application_spec.rb +37 -0
  128. data/spec/cuboid/data/application_spec.rb +22 -0
  129. data/spec/cuboid/data_spec.rb +47 -0
  130. data/spec/cuboid/error_spec.rb +23 -0
  131. data/spec/cuboid/option_groups/datastore_spec.rb +54 -0
  132. data/spec/cuboid/option_groups/dispatcher_spec.rb +12 -0
  133. data/spec/cuboid/option_groups/output_spec.rb +11 -0
  134. data/spec/cuboid/option_groups/paths_spec.rb +184 -0
  135. data/spec/cuboid/option_groups/report_spec.rb +26 -0
  136. data/spec/cuboid/option_groups/rpc_spec.rb +53 -0
  137. data/spec/cuboid/option_groups/snapshot_spec.rb +26 -0
  138. data/spec/cuboid/option_groups/system.rb +12 -0
  139. data/spec/cuboid/options_spec.rb +218 -0
  140. data/spec/cuboid/report_spec.rb +221 -0
  141. data/spec/cuboid/rest/server_spec.rb +1205 -0
  142. data/spec/cuboid/rpc/client/base_spec.rb +151 -0
  143. data/spec/cuboid/rpc/client/dispatcher_spec.rb +13 -0
  144. data/spec/cuboid/rpc/client/instance_spec.rb +38 -0
  145. data/spec/cuboid/rpc/server/active_options_spec.rb +21 -0
  146. data/spec/cuboid/rpc/server/base_spec.rb +60 -0
  147. data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +222 -0
  148. data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +112 -0
  149. data/spec/cuboid/rpc/server/dispatcher_spec.rb +317 -0
  150. data/spec/cuboid/rpc/server/instance_spec.rb +307 -0
  151. data/spec/cuboid/rpc/server/output_spec.rb +32 -0
  152. data/spec/cuboid/rpc/server/scheduler_spec.rb +400 -0
  153. data/spec/cuboid/ruby/array_spec.rb +77 -0
  154. data/spec/cuboid/ruby/hash_spec.rb +63 -0
  155. data/spec/cuboid/ruby/object_spec.rb +22 -0
  156. data/spec/cuboid/snapshot_spec.rb +123 -0
  157. data/spec/cuboid/state/application_spec.rb +538 -0
  158. data/spec/cuboid/state/options_spec.rb +37 -0
  159. data/spec/cuboid/state_spec.rb +53 -0
  160. data/spec/cuboid/support/buffer/autoflush_spec.rb +78 -0
  161. data/spec/cuboid/support/buffer/base_spec.rb +193 -0
  162. data/spec/cuboid/support/cache/least_cost_replacement_spec.rb +61 -0
  163. data/spec/cuboid/support/cache/least_recently_pushed_spec.rb +90 -0
  164. data/spec/cuboid/support/cache/least_recently_used_spec.rb +80 -0
  165. data/spec/cuboid/support/cache/preference_spec.rb +37 -0
  166. data/spec/cuboid/support/cache/random_replacement_spec.rb +42 -0
  167. data/spec/cuboid/support/crypto/rsa_aes_cbc_spec.rb +28 -0
  168. data/spec/cuboid/support/database/categorized_queue_spec.rb +327 -0
  169. data/spec/cuboid/support/database/hash_spec.rb +204 -0
  170. data/spec/cuboid/support/database/scheduler_spec.rb +325 -0
  171. data/spec/cuboid/support/filter/set_spec.rb +19 -0
  172. data/spec/cuboid/support/glob_spec.rb +75 -0
  173. data/spec/cuboid/support/mixins/observable_spec.rb +95 -0
  174. data/spec/cuboid/system/platforms/linux_spec.rb +31 -0
  175. data/spec/cuboid/system/platforms/osx_spec.rb +32 -0
  176. data/spec/cuboid/system/platforms/windows_spec.rb +41 -0
  177. data/spec/cuboid/system/slots_spec.rb +202 -0
  178. data/spec/cuboid/system_spec.rb +105 -0
  179. data/spec/cuboid/utilities_spec.rb +131 -0
  180. data/spec/spec_helper.rb +46 -0
  181. data/spec/support/factories/placeholder +0 -0
  182. data/spec/support/factories/scan_report.rb +18 -0
  183. data/spec/support/fixtures/empty/placeholder +0 -0
  184. data/spec/support/fixtures/executables/node.rb +50 -0
  185. data/spec/support/fixtures/mock_app.rb +61 -0
  186. data/spec/support/fixtures/mock_app/test_service.rb +64 -0
  187. data/spec/support/fixtures/services/echo.rb +64 -0
  188. data/spec/support/helpers/framework.rb +3 -0
  189. data/spec/support/helpers/matchers.rb +5 -0
  190. data/spec/support/helpers/misc.rb +3 -0
  191. data/spec/support/helpers/paths.rb +15 -0
  192. data/spec/support/helpers/request_helpers.rb +38 -0
  193. data/spec/support/helpers/requires.rb +8 -0
  194. data/spec/support/helpers/resets.rb +52 -0
  195. data/spec/support/helpers/web_server.rb +15 -0
  196. data/spec/support/lib/factory.rb +107 -0
  197. data/spec/support/lib/web_server_client.rb +41 -0
  198. data/spec/support/lib/web_server_dispatcher.rb +25 -0
  199. data/spec/support/lib/web_server_manager.rb +118 -0
  200. data/spec/support/logs/placeholder +0 -0
  201. data/spec/support/pems/cacert.pem +37 -0
  202. data/spec/support/pems/client/cert.pem +37 -0
  203. data/spec/support/pems/client/foo-cert.pem +39 -0
  204. data/spec/support/pems/client/foo-key.pem +51 -0
  205. data/spec/support/pems/client/key.pem +51 -0
  206. data/spec/support/pems/server/cert.pem +37 -0
  207. data/spec/support/pems/server/key.pem +51 -0
  208. data/spec/support/reports/placeholder +0 -0
  209. data/spec/support/shared/application.rb +10 -0
  210. data/spec/support/shared/component.rb +31 -0
  211. data/spec/support/shared/component/options/base.rb +187 -0
  212. data/spec/support/shared/option_group.rb +98 -0
  213. data/spec/support/shared/support/cache.rb +419 -0
  214. data/spec/support/shared/support/filter.rb +143 -0
  215. data/spec/support/shared/system/platforms/base.rb +25 -0
  216. data/spec/support/shared/system/platforms/mixins/unix.rb +37 -0
  217. data/spec/support/snapshots/placeholder +0 -0
  218. metadata +566 -21
  219. data/.gitignore +0 -8
  220. data/bin/console +0 -15
  221. data/bin/setup +0 -8
@@ -0,0 +1,165 @@
1
+ require 'puma'
2
+ require 'puma/minissl'
3
+ require 'sinatra/base'
4
+ require 'sinatra/contrib'
5
+
6
+ module Cuboid
7
+ module Rest
8
+
9
+ class Server < Sinatra::Base
10
+ lib = Options.paths.lib
11
+ require lib + 'processes'
12
+ require lib + 'rest/server/instance_helpers'
13
+
14
+ Dir.glob( "#{File.dirname( __FILE__ )}/server/routes/*.rb" ).each { |f| require f }
15
+
16
+ helpers InstanceHelpers
17
+
18
+ register Sinatra::Namespace
19
+ Cuboid::Application.application.rest_services.each do |name, service|
20
+ namespace "/instances/:instance/#{name}" do
21
+ register service
22
+ end
23
+ end
24
+
25
+ register Routes::Instances
26
+ register Routes::Dispatcher
27
+ register Routes::Grid
28
+ register Routes::Scheduler
29
+
30
+ use Rack::Deflater
31
+ use Rack::Session::Pool
32
+
33
+ set :environment, :production
34
+
35
+ enable :logging
36
+
37
+ VALID_REPORT_FORMATS = %w(json xml yaml html.zip)
38
+
39
+ before do
40
+ protected!
41
+ content_type :json
42
+ end
43
+
44
+ helpers do
45
+ def max_utilization!
46
+ halt 503,
47
+ json( error: 'Service unavailable: System is at maximum ' +
48
+ 'utilization, slot limit reached.' )
49
+ end
50
+
51
+ def protected!
52
+ if !settings.respond_to?( :username )
53
+ settings.set :username, nil
54
+ end
55
+
56
+ if !settings.respond_to?( :password )
57
+ settings.set :password, nil
58
+ end
59
+
60
+ return if !settings.username && !settings.password
61
+ return if authorized?
62
+
63
+ headers['WWW-Authenticate'] = 'Basic realm="Restricted Area"'
64
+ halt 401, "Not authorized\n"
65
+ end
66
+
67
+ def authorized?
68
+ @auth ||= Rack::Auth::Basic::Request.new( request.env )
69
+ @auth.provided? && @auth.basic? && @auth.credentials == [
70
+ settings.username.to_s, settings.password.to_s
71
+ ]
72
+ end
73
+
74
+ def ensure_instance!
75
+ update_from_scheduler
76
+
77
+ id = params[:instance]
78
+
79
+ return if exists? id
80
+
81
+ halt 404, json( "Scan not found for id: #{h id}." )
82
+ end
83
+
84
+ def ensure_dispatcher!
85
+ return if dispatcher
86
+ halt 501, json( 'No Dispatcher has been set.' )
87
+ end
88
+
89
+ def ensure_scheduler!
90
+ return if scheduler
91
+ halt 501, json( 'No Scheduler has been set.' )
92
+ end
93
+
94
+ def handle_error( cleanup = nil, &block )
95
+ block.call
96
+ rescue => e
97
+ cleanup.call if cleanup
98
+
99
+ halt 500,
100
+ json(
101
+ error: e.class,
102
+ description: e.to_s,
103
+ backtrace: e.backtrace
104
+ )
105
+ end
106
+
107
+ def h( text )
108
+ Rack::Utils.escape_html( text )
109
+ end
110
+ end
111
+
112
+ class <<self
113
+ include Cuboid::UI::Output
114
+
115
+ def reset
116
+ @@instances.clear
117
+ @@dispatchers.clear
118
+ end
119
+
120
+ def run!( options )
121
+ set :username, options[:username]
122
+ set :password, options[:password]
123
+
124
+ server = Puma::Server.new( self )
125
+ server.min_threads = 0
126
+ server.max_threads = 16
127
+
128
+ ssl = false
129
+ if options[:ssl_key] && options[:ssl_certificate]
130
+ ctx = Puma::MiniSSL::Context.new
131
+
132
+ ctx.key = options[:ssl_key]
133
+ ctx.cert = options[:ssl_certificate]
134
+
135
+ if options[:ssl_ca]
136
+ print_info 'CA provided, peer verification has been enabled.'
137
+
138
+ ctx.ca = options[:ssl_ca]
139
+ ctx.verify_mode = Puma::MiniSSL::VERIFY_PEER |
140
+ Puma::MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
141
+ else
142
+ print_info 'CA missing, peer verification has been disabled.'
143
+ end
144
+
145
+ ssl = true
146
+ server.binder.add_ssl_listener( options[:bind], options[:port], ctx )
147
+ else
148
+ ssl = false
149
+ server.add_tcp_listener( options[:bind], options[:port] )
150
+ end
151
+
152
+ print_status "Listening on http#{'s' if ssl}://#{options[:bind]}:#{options[:port]}"
153
+
154
+ begin
155
+ server.run.join
156
+ rescue Interrupt
157
+ server.stop( true )
158
+ end
159
+ end
160
+ end
161
+
162
+ end
163
+
164
+ end
165
+ end
@@ -0,0 +1,99 @@
1
+ module Cuboid
2
+ module Rest
3
+ class Server
4
+
5
+ module InstanceHelpers
6
+
7
+ @@instances = {}
8
+ @@dispatchers = {}
9
+
10
+ def get_instance
11
+ if dispatcher
12
+ options = {
13
+ owner: self.class.to_s,
14
+ helpers: {
15
+ owner: {
16
+ url: env['HTTP_HOST']
17
+ }
18
+ }
19
+ }
20
+
21
+ if (info = dispatcher.dispatch( options ))
22
+ connect_to_instance( info['url'], info['token'] )
23
+ end
24
+ else
25
+ Processes::Instances.spawn( application: Options.paths.application )
26
+ end
27
+ end
28
+
29
+ def dispatchers
30
+ @@dispatchers.keys
31
+ end
32
+
33
+ def dispatcher
34
+ return if !Options.dispatcher.url
35
+ @dispatcher ||= connect_to_dispatcher( Options.dispatcher.url )
36
+ end
37
+
38
+ def unplug_dispatcher( url )
39
+ connect_to_dispatcher( url ).node.unplug
40
+
41
+ c = @@dispatchers.delete( url )
42
+ c.close if c
43
+ end
44
+
45
+ def connect_to_dispatcher( url )
46
+ @@dispatchers[url] ||= RPC::Client::Dispatcher.new( url )
47
+ end
48
+
49
+ def connect_to_instance( url, token )
50
+ RPC::Client::Instance.new( url, token )
51
+ end
52
+
53
+ def update_from_scheduler
54
+ return if !scheduler
55
+
56
+ scheduler.running.each do |id, info|
57
+ instances[id] ||= connect_to_instance( info['url'], info['token'] )
58
+ end
59
+
60
+ (scheduler.failed.keys | scheduler.completed.keys).each do |id|
61
+ session.delete id
62
+ client = instances.delete( id )
63
+ client.close if client
64
+ end
65
+ end
66
+
67
+ def scheduler
68
+ return if !Options.scheduler.url
69
+ @scheduler ||= connect_to_scheduler( Options.scheduler.url )
70
+ end
71
+
72
+ def connect_to_scheduler( url )
73
+ RPC::Client::Scheduler.new( url )
74
+ end
75
+
76
+ def instances
77
+ @@instances
78
+ end
79
+
80
+ def instance_for( id, &block )
81
+ cleanup = proc do
82
+ instances.delete( id ).close
83
+ session.delete id
84
+ end
85
+
86
+ handle_error cleanup do
87
+ block.call @@instances[id]
88
+ end
89
+ end
90
+
91
+ def exists?( id )
92
+ instances.include? id
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,41 @@
1
+ module Cuboid
2
+ module Rest
3
+ class Server
4
+ module Routes
5
+
6
+ module Dispatcher
7
+
8
+ def self.registered( app )
9
+
10
+ app.get '/dispatcher/url' do
11
+ ensure_dispatcher!
12
+
13
+ json Options.dispatcher.url
14
+ end
15
+
16
+ app.put '/dispatcher/url' do
17
+ url = ::JSON.load( request.body.read ) || {}
18
+
19
+ handle_error do
20
+ connect_to_dispatcher( url ).alive?
21
+
22
+ @dispatcher = nil
23
+ Options.dispatcher.url = url
24
+ json nil
25
+ end
26
+ end
27
+
28
+ app.delete '/dispatcher/url' do
29
+ ensure_dispatcher!
30
+
31
+ json @dispatcher = Options.dispatcher.url = nil
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ module Cuboid
2
+ module Rest
3
+ class Server
4
+ module Routes
5
+
6
+ module Grid
7
+
8
+ def self.registered( app )
9
+
10
+ app.get '/grid' do
11
+ ensure_dispatcher!
12
+
13
+ handle_error do
14
+ json [Options.dispatcher.url] + dispatcher.statistics['node']['neighbours']
15
+ end
16
+ end
17
+
18
+ app.get '/grid/:dispatcher' do |url|
19
+ ensure_dispatcher!
20
+
21
+ handle_error { json connect_to_dispatcher( url ).statistics }
22
+ end
23
+
24
+ app.delete '/grid/:dispatcher' do |url|
25
+ ensure_dispatcher!
26
+
27
+ handle_error do
28
+ unplug_dispatcher( url )
29
+ end
30
+
31
+ json nil
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,131 @@
1
+ module Cuboid
2
+ module Rest
3
+ class Server
4
+ module Routes
5
+
6
+ module Instances
7
+
8
+ def self.registered( app )
9
+
10
+ # List instances.
11
+ app.get '/instances' do
12
+ update_from_scheduler
13
+
14
+ json instances.keys.inject({}){ |h, k| h.merge! k => {} }
15
+ end
16
+
17
+ # Create
18
+ app.post '/instances' do
19
+ max_utilization! if !dispatcher && System.max_utilization?
20
+
21
+ options = ::JSON.load( request.body.read ) || {}
22
+
23
+ instance = get_instance
24
+ max_utilization! if !instance
25
+
26
+ handle_error proc { instance.shutdown } do
27
+ instance.run( options )
28
+ end
29
+
30
+ instances[instance.token] = instance
31
+
32
+ json id: instance.token
33
+ end
34
+
35
+ # Progress
36
+ app.get '/instances/:instance' do
37
+ ensure_instance!
38
+
39
+ session[params[:instance]] ||= {
40
+ seen_errors: 0,
41
+ }
42
+
43
+ data = instance_for( params[:instance] ) do |instance|
44
+ instance.progress(
45
+ with: [
46
+ errors: session[params[:instance]][:seen_errors],
47
+ ]
48
+ )
49
+ end
50
+
51
+ session[params[:instance]][:seen_errors] += data[:errors].size
52
+
53
+ json data
54
+ end
55
+
56
+ app.put '/instances/:instance/scheduler' do |instance|
57
+ ensure_scheduler!
58
+ ensure_instance!
59
+
60
+ handle_error do
61
+ instance = instances.delete( instance )
62
+ instance.close
63
+
64
+ json scheduler.attach( instance.url, instance.token )
65
+ end
66
+ end
67
+
68
+ app.get '/instances/:instance/summary' do
69
+ ensure_instance!
70
+
71
+ instance_for( params[:instance] ) do |instance|
72
+ json instance.progress
73
+ end
74
+ end
75
+
76
+ app.get '/instances/:instance/report.crf' do
77
+ ensure_instance!
78
+ content_type 'application/octet-stream'
79
+
80
+ instance_for( params[:instance] ) do |instance|
81
+ instance.generate_report.to_crf
82
+ end
83
+ end
84
+
85
+ app.get '/instances/:instance/report.json' do
86
+ ensure_instance!
87
+
88
+ instance_for( params[:instance] ) do |instance|
89
+ instance.generate_report.to_rpc_data.to_json
90
+ end
91
+ end
92
+
93
+ app.put '/instances/:instance/pause' do
94
+ ensure_instance!
95
+
96
+ instance_for( params[:instance] ) do |instance|
97
+ json instance.pause!
98
+ end
99
+ end
100
+
101
+ app.put '/instances/:instance/resume' do
102
+ ensure_instance!
103
+
104
+ instance_for( params[:instance] ) do |instance|
105
+ json instance.resume!
106
+ end
107
+ end
108
+
109
+ # Abort/shutdown
110
+ app.delete '/instances/:instance' do
111
+ ensure_instance!
112
+ id = params[:instance]
113
+
114
+ instance = instances[id]
115
+ handle_error { instance.shutdown }
116
+
117
+ instances.delete( id ).close
118
+
119
+ session.delete params[:instance]
120
+
121
+ json nil
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+ end
130
+ end
131
+ end