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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -0
- data/Gemfile +20 -5
- data/LICENSE.md +22 -0
- data/README.md +158 -19
- data/Rakefile +56 -3
- data/config/paths.yml +15 -0
- data/cuboid.gemspec +61 -23
- data/lib/cuboid.rb +96 -4
- data/lib/cuboid/application.rb +326 -0
- data/lib/cuboid/application/parts/data.rb +18 -0
- data/lib/cuboid/application/parts/report.rb +29 -0
- data/lib/cuboid/application/parts/state.rb +274 -0
- data/lib/cuboid/application/runtime.rb +25 -0
- data/lib/cuboid/banner.rb +13 -0
- data/lib/cuboid/data.rb +86 -0
- data/lib/cuboid/data/application.rb +52 -0
- data/lib/cuboid/error.rb +9 -0
- data/lib/cuboid/option_group.rb +129 -0
- data/lib/cuboid/option_groups.rb +8 -0
- data/lib/cuboid/option_groups/datastore.rb +23 -0
- data/lib/cuboid/option_groups/dispatcher.rb +38 -0
- data/lib/cuboid/option_groups/output.rb +14 -0
- data/lib/cuboid/option_groups/paths.rb +184 -0
- data/lib/cuboid/option_groups/report.rb +39 -0
- data/lib/cuboid/option_groups/rpc.rb +105 -0
- data/lib/cuboid/option_groups/scheduler.rb +27 -0
- data/lib/cuboid/option_groups/snapshot.rb +13 -0
- data/lib/cuboid/option_groups/system.rb +10 -0
- data/lib/cuboid/options.rb +254 -0
- data/lib/cuboid/processes.rb +13 -0
- data/lib/cuboid/processes/dispatchers.rb +140 -0
- data/lib/cuboid/processes/executables/base.rb +54 -0
- data/lib/cuboid/processes/executables/dispatcher.rb +5 -0
- data/lib/cuboid/processes/executables/instance.rb +12 -0
- data/lib/cuboid/processes/executables/rest_service.rb +13 -0
- data/lib/cuboid/processes/executables/scheduler.rb +5 -0
- data/lib/cuboid/processes/helpers.rb +4 -0
- data/lib/cuboid/processes/helpers/dispatchers.rb +23 -0
- data/lib/cuboid/processes/helpers/instances.rb +39 -0
- data/lib/cuboid/processes/helpers/processes.rb +23 -0
- data/lib/cuboid/processes/helpers/schedulers.rb +23 -0
- data/lib/cuboid/processes/instances.rb +203 -0
- data/lib/cuboid/processes/manager.rb +262 -0
- data/lib/cuboid/processes/schedulers.rb +128 -0
- data/lib/cuboid/report.rb +220 -0
- data/lib/cuboid/rest/server.rb +165 -0
- data/lib/cuboid/rest/server/instance_helpers.rb +99 -0
- data/lib/cuboid/rest/server/routes/dispatcher.rb +41 -0
- data/lib/cuboid/rest/server/routes/grid.rb +41 -0
- data/lib/cuboid/rest/server/routes/instances.rb +131 -0
- data/lib/cuboid/rest/server/routes/scheduler.rb +140 -0
- data/lib/cuboid/rpc/client.rb +3 -0
- data/lib/cuboid/rpc/client/base.rb +58 -0
- data/lib/cuboid/rpc/client/dispatcher.rb +58 -0
- data/lib/cuboid/rpc/client/instance.rb +100 -0
- data/lib/cuboid/rpc/client/instance/service.rb +37 -0
- data/lib/cuboid/rpc/client/scheduler.rb +46 -0
- data/lib/cuboid/rpc/serializer.rb +92 -0
- data/lib/cuboid/rpc/server/active_options.rb +38 -0
- data/lib/cuboid/rpc/server/application_wrapper.rb +138 -0
- data/lib/cuboid/rpc/server/base.rb +63 -0
- data/lib/cuboid/rpc/server/dispatcher.rb +317 -0
- data/lib/cuboid/rpc/server/dispatcher/node.rb +247 -0
- data/lib/cuboid/rpc/server/dispatcher/service.rb +145 -0
- data/lib/cuboid/rpc/server/instance.rb +338 -0
- data/lib/cuboid/rpc/server/output.rb +92 -0
- data/lib/cuboid/rpc/server/scheduler.rb +482 -0
- data/lib/cuboid/ruby.rb +4 -0
- data/lib/cuboid/ruby/array.rb +17 -0
- data/lib/cuboid/ruby/hash.rb +41 -0
- data/lib/cuboid/ruby/object.rb +32 -0
- data/lib/cuboid/snapshot.rb +186 -0
- data/lib/cuboid/state.rb +94 -0
- data/lib/cuboid/state/application.rb +309 -0
- data/lib/cuboid/state/options.rb +27 -0
- data/lib/cuboid/support.rb +11 -0
- data/lib/cuboid/support/buffer.rb +3 -0
- data/lib/cuboid/support/buffer/autoflush.rb +61 -0
- data/lib/cuboid/support/buffer/base.rb +91 -0
- data/lib/cuboid/support/cache.rb +7 -0
- data/lib/cuboid/support/cache/base.rb +226 -0
- data/lib/cuboid/support/cache/least_cost_replacement.rb +77 -0
- data/lib/cuboid/support/cache/least_recently_pushed.rb +21 -0
- data/lib/cuboid/support/cache/least_recently_used.rb +31 -0
- data/lib/cuboid/support/cache/preference.rb +31 -0
- data/lib/cuboid/support/cache/random_replacement.rb +20 -0
- data/lib/cuboid/support/crypto.rb +2 -0
- data/lib/cuboid/support/crypto/rsa_aes_cbc.rb +86 -0
- data/lib/cuboid/support/database.rb +5 -0
- data/lib/cuboid/support/database/base.rb +177 -0
- data/lib/cuboid/support/database/categorized_queue.rb +195 -0
- data/lib/cuboid/support/database/hash.rb +300 -0
- data/lib/cuboid/support/database/queue.rb +149 -0
- data/lib/cuboid/support/filter.rb +3 -0
- data/lib/cuboid/support/filter/base.rb +110 -0
- data/lib/cuboid/support/filter/set.rb +29 -0
- data/lib/cuboid/support/glob.rb +27 -0
- data/lib/cuboid/support/mixins.rb +8 -0
- data/lib/cuboid/support/mixins/observable.rb +99 -0
- data/lib/cuboid/support/mixins/parts.rb +20 -0
- data/lib/cuboid/support/mixins/profiler.rb +93 -0
- data/lib/cuboid/support/mixins/spec_instances.rb +65 -0
- data/lib/cuboid/support/mixins/terminal.rb +57 -0
- data/lib/cuboid/system.rb +119 -0
- data/lib/cuboid/system/platforms.rb +84 -0
- data/lib/cuboid/system/platforms/linux.rb +26 -0
- data/lib/cuboid/system/platforms/mixins/unix.rb +46 -0
- data/lib/cuboid/system/platforms/osx.rb +25 -0
- data/lib/cuboid/system/platforms/windows.rb +81 -0
- data/lib/cuboid/system/slots.rb +143 -0
- data/lib/cuboid/ui/output.rb +52 -0
- data/lib/cuboid/ui/output_interface.rb +43 -0
- data/lib/cuboid/ui/output_interface/abstract.rb +68 -0
- data/lib/cuboid/ui/output_interface/controls.rb +84 -0
- data/lib/cuboid/ui/output_interface/error_logging.rb +119 -0
- data/lib/cuboid/ui/output_interface/implemented.rb +58 -0
- data/lib/cuboid/ui/output_interface/personalization.rb +62 -0
- data/lib/cuboid/utilities.rb +155 -0
- data/lib/cuboid/version.rb +4 -3
- data/lib/version +1 -0
- data/logs/placeholder +0 -0
- data/spec/cuboid/application/parts/data_spec.rb +12 -0
- data/spec/cuboid/application/parts/report_spec.rb +6 -0
- data/spec/cuboid/application/parts/state_spec.rb +192 -0
- data/spec/cuboid/application/runtime_spec.rb +21 -0
- data/spec/cuboid/application_spec.rb +37 -0
- data/spec/cuboid/data/application_spec.rb +22 -0
- data/spec/cuboid/data_spec.rb +47 -0
- data/spec/cuboid/error_spec.rb +23 -0
- data/spec/cuboid/option_groups/datastore_spec.rb +54 -0
- data/spec/cuboid/option_groups/dispatcher_spec.rb +12 -0
- data/spec/cuboid/option_groups/output_spec.rb +11 -0
- data/spec/cuboid/option_groups/paths_spec.rb +184 -0
- data/spec/cuboid/option_groups/report_spec.rb +26 -0
- data/spec/cuboid/option_groups/rpc_spec.rb +53 -0
- data/spec/cuboid/option_groups/snapshot_spec.rb +26 -0
- data/spec/cuboid/option_groups/system.rb +12 -0
- data/spec/cuboid/options_spec.rb +218 -0
- data/spec/cuboid/report_spec.rb +221 -0
- data/spec/cuboid/rest/server_spec.rb +1205 -0
- data/spec/cuboid/rpc/client/base_spec.rb +151 -0
- data/spec/cuboid/rpc/client/dispatcher_spec.rb +13 -0
- data/spec/cuboid/rpc/client/instance_spec.rb +38 -0
- data/spec/cuboid/rpc/server/active_options_spec.rb +21 -0
- data/spec/cuboid/rpc/server/base_spec.rb +60 -0
- data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +222 -0
- data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +112 -0
- data/spec/cuboid/rpc/server/dispatcher_spec.rb +317 -0
- data/spec/cuboid/rpc/server/instance_spec.rb +307 -0
- data/spec/cuboid/rpc/server/output_spec.rb +32 -0
- data/spec/cuboid/rpc/server/scheduler_spec.rb +400 -0
- data/spec/cuboid/ruby/array_spec.rb +77 -0
- data/spec/cuboid/ruby/hash_spec.rb +63 -0
- data/spec/cuboid/ruby/object_spec.rb +22 -0
- data/spec/cuboid/snapshot_spec.rb +123 -0
- data/spec/cuboid/state/application_spec.rb +538 -0
- data/spec/cuboid/state/options_spec.rb +37 -0
- data/spec/cuboid/state_spec.rb +53 -0
- data/spec/cuboid/support/buffer/autoflush_spec.rb +78 -0
- data/spec/cuboid/support/buffer/base_spec.rb +193 -0
- data/spec/cuboid/support/cache/least_cost_replacement_spec.rb +61 -0
- data/spec/cuboid/support/cache/least_recently_pushed_spec.rb +90 -0
- data/spec/cuboid/support/cache/least_recently_used_spec.rb +80 -0
- data/spec/cuboid/support/cache/preference_spec.rb +37 -0
- data/spec/cuboid/support/cache/random_replacement_spec.rb +42 -0
- data/spec/cuboid/support/crypto/rsa_aes_cbc_spec.rb +28 -0
- data/spec/cuboid/support/database/categorized_queue_spec.rb +327 -0
- data/spec/cuboid/support/database/hash_spec.rb +204 -0
- data/spec/cuboid/support/database/scheduler_spec.rb +325 -0
- data/spec/cuboid/support/filter/set_spec.rb +19 -0
- data/spec/cuboid/support/glob_spec.rb +75 -0
- data/spec/cuboid/support/mixins/observable_spec.rb +95 -0
- data/spec/cuboid/system/platforms/linux_spec.rb +31 -0
- data/spec/cuboid/system/platforms/osx_spec.rb +32 -0
- data/spec/cuboid/system/platforms/windows_spec.rb +41 -0
- data/spec/cuboid/system/slots_spec.rb +202 -0
- data/spec/cuboid/system_spec.rb +105 -0
- data/spec/cuboid/utilities_spec.rb +131 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/factories/placeholder +0 -0
- data/spec/support/factories/scan_report.rb +18 -0
- data/spec/support/fixtures/empty/placeholder +0 -0
- data/spec/support/fixtures/executables/node.rb +50 -0
- data/spec/support/fixtures/mock_app.rb +61 -0
- data/spec/support/fixtures/mock_app/test_service.rb +64 -0
- data/spec/support/fixtures/services/echo.rb +64 -0
- data/spec/support/helpers/framework.rb +3 -0
- data/spec/support/helpers/matchers.rb +5 -0
- data/spec/support/helpers/misc.rb +3 -0
- data/spec/support/helpers/paths.rb +15 -0
- data/spec/support/helpers/request_helpers.rb +38 -0
- data/spec/support/helpers/requires.rb +8 -0
- data/spec/support/helpers/resets.rb +52 -0
- data/spec/support/helpers/web_server.rb +15 -0
- data/spec/support/lib/factory.rb +107 -0
- data/spec/support/lib/web_server_client.rb +41 -0
- data/spec/support/lib/web_server_dispatcher.rb +25 -0
- data/spec/support/lib/web_server_manager.rb +118 -0
- data/spec/support/logs/placeholder +0 -0
- data/spec/support/pems/cacert.pem +37 -0
- data/spec/support/pems/client/cert.pem +37 -0
- data/spec/support/pems/client/foo-cert.pem +39 -0
- data/spec/support/pems/client/foo-key.pem +51 -0
- data/spec/support/pems/client/key.pem +51 -0
- data/spec/support/pems/server/cert.pem +37 -0
- data/spec/support/pems/server/key.pem +51 -0
- data/spec/support/reports/placeholder +0 -0
- data/spec/support/shared/application.rb +10 -0
- data/spec/support/shared/component.rb +31 -0
- data/spec/support/shared/component/options/base.rb +187 -0
- data/spec/support/shared/option_group.rb +98 -0
- data/spec/support/shared/support/cache.rb +419 -0
- data/spec/support/shared/support/filter.rb +143 -0
- data/spec/support/shared/system/platforms/base.rb +25 -0
- data/spec/support/shared/system/platforms/mixins/unix.rb +37 -0
- data/spec/support/snapshots/placeholder +0 -0
- metadata +566 -21
- data/.gitignore +0 -8
- data/bin/console +0 -15
- data/bin/setup +0 -8
@@ -0,0 +1,326 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'monitor'
|
5
|
+
require 'bundler/setup'
|
6
|
+
|
7
|
+
require_relative 'options'
|
8
|
+
|
9
|
+
module Cuboid
|
10
|
+
|
11
|
+
lib = Options.paths.lib
|
12
|
+
require lib + 'support/mixins/spec_instances'
|
13
|
+
require lib + 'system'
|
14
|
+
require lib + 'version'
|
15
|
+
require lib + 'support'
|
16
|
+
require lib + 'ruby'
|
17
|
+
require lib + 'error'
|
18
|
+
require lib + 'utilities'
|
19
|
+
require lib + 'snapshot'
|
20
|
+
require lib + 'report'
|
21
|
+
require lib + 'processes'
|
22
|
+
require lib + 'application/runtime'
|
23
|
+
|
24
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
25
|
+
class Application
|
26
|
+
include Singleton
|
27
|
+
|
28
|
+
module PrependMethods
|
29
|
+
|
30
|
+
def run
|
31
|
+
if !self.class.valid_options?( options )
|
32
|
+
fail ArgumentError, 'Invalid options!'
|
33
|
+
end
|
34
|
+
|
35
|
+
prepare
|
36
|
+
return if aborted? || suspended?
|
37
|
+
|
38
|
+
state.status = :running
|
39
|
+
|
40
|
+
super if defined? super
|
41
|
+
|
42
|
+
return if aborted? || suspended?
|
43
|
+
|
44
|
+
clean_up
|
45
|
+
state.status = :done
|
46
|
+
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Cleans up the framework; should be called after running the audit or
|
51
|
+
# after canceling a running scan.
|
52
|
+
def clean_up
|
53
|
+
return if @cleaned_up
|
54
|
+
@cleaned_up = true
|
55
|
+
|
56
|
+
state.resume
|
57
|
+
|
58
|
+
state.status = :cleanup
|
59
|
+
|
60
|
+
@finish_datetime = Time.now
|
61
|
+
@start_datetime ||= Time.now
|
62
|
+
|
63
|
+
state.running = false
|
64
|
+
|
65
|
+
super if defined? super
|
66
|
+
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# @note Must be called before calling any audit methods.
|
73
|
+
#
|
74
|
+
# Prepares the framework for the audit.
|
75
|
+
#
|
76
|
+
# * Sets the status to `:preparing`.
|
77
|
+
# * Starts the clock.
|
78
|
+
def prepare
|
79
|
+
state.status = :preparing
|
80
|
+
state.running = true
|
81
|
+
@start_datetime = Time.now
|
82
|
+
|
83
|
+
super if defined? super
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
class <<self
|
89
|
+
|
90
|
+
def provision_cores( cores )
|
91
|
+
@max_cores = cores
|
92
|
+
end
|
93
|
+
|
94
|
+
def max_cores
|
95
|
+
@max_cores ||= 0
|
96
|
+
end
|
97
|
+
|
98
|
+
def provision_memory( ram )
|
99
|
+
@max_memory = ram
|
100
|
+
end
|
101
|
+
|
102
|
+
def max_memory
|
103
|
+
@max_memory ||= 0
|
104
|
+
end
|
105
|
+
|
106
|
+
def provision_disk( ram )
|
107
|
+
@max_disk = ram
|
108
|
+
end
|
109
|
+
|
110
|
+
def max_disk
|
111
|
+
@max_memory ||= 0
|
112
|
+
end
|
113
|
+
|
114
|
+
def instance_service_for(name, service )
|
115
|
+
instance_services[name] = service
|
116
|
+
end
|
117
|
+
|
118
|
+
def instance_services
|
119
|
+
@instance_services ||= {}
|
120
|
+
end
|
121
|
+
|
122
|
+
def rest_service_for( name, service )
|
123
|
+
rest_services[name] = service
|
124
|
+
end
|
125
|
+
|
126
|
+
def rest_services
|
127
|
+
@rest_services ||= {}
|
128
|
+
end
|
129
|
+
|
130
|
+
def dispatcher_service_for( name, service )
|
131
|
+
dispatcher_services[name] = service
|
132
|
+
end
|
133
|
+
|
134
|
+
def dispatcher_services
|
135
|
+
@dispatcher_services ||= {}
|
136
|
+
end
|
137
|
+
|
138
|
+
def handler_for( signal, handler )
|
139
|
+
signal_handlers[signal] = handler
|
140
|
+
end
|
141
|
+
|
142
|
+
def signal_handlers
|
143
|
+
@signal_handlers ||= {}
|
144
|
+
end
|
145
|
+
|
146
|
+
def serialize_with( serializer)
|
147
|
+
@serializer = serializer
|
148
|
+
end
|
149
|
+
|
150
|
+
def serializer
|
151
|
+
@serializer ||= nil
|
152
|
+
@serializer || RPC::Serializer
|
153
|
+
end
|
154
|
+
|
155
|
+
def validate_options_with( handler )
|
156
|
+
@validate_options_with = handler
|
157
|
+
end
|
158
|
+
|
159
|
+
def valid_options?( options )
|
160
|
+
@validate_options_with ||= nil
|
161
|
+
if @validate_options_with
|
162
|
+
return instance.method( @validate_options_with ).call( options )
|
163
|
+
end
|
164
|
+
|
165
|
+
true
|
166
|
+
end
|
167
|
+
|
168
|
+
def source_location
|
169
|
+
splits = self.to_s.split ( '::' )
|
170
|
+
app = splits.pop
|
171
|
+
|
172
|
+
last_const = Object
|
173
|
+
splits.each do |const_name|
|
174
|
+
last_const = last_const.const_get( const_name.to_sym )
|
175
|
+
end
|
176
|
+
|
177
|
+
last_const.const_source_location( app.to_sym ).first
|
178
|
+
end
|
179
|
+
|
180
|
+
def spawn( type, options = {}, &block )
|
181
|
+
const = nil
|
182
|
+
|
183
|
+
case type
|
184
|
+
when :instance
|
185
|
+
const = :Instances
|
186
|
+
when :dispatcher
|
187
|
+
const = :Dispatchers
|
188
|
+
when :scheduler
|
189
|
+
const = :Schedulers
|
190
|
+
when :rest
|
191
|
+
return Processes::Manager.spawn(
|
192
|
+
:rest_service,
|
193
|
+
options.merge( options: { paths: { application: source_location } } ),
|
194
|
+
&block
|
195
|
+
)
|
196
|
+
end
|
197
|
+
|
198
|
+
Processes.const_get( const ).spawn(
|
199
|
+
options.merge( application: source_location ),
|
200
|
+
&block
|
201
|
+
)
|
202
|
+
end
|
203
|
+
|
204
|
+
def connect( info )
|
205
|
+
info = info.my_symbolize_keys
|
206
|
+
Processes::Instances.connect( info[:url], info[:token] )
|
207
|
+
end
|
208
|
+
|
209
|
+
def inherited( application )
|
210
|
+
super
|
211
|
+
|
212
|
+
application.prepend PrependMethods
|
213
|
+
@application = application
|
214
|
+
end
|
215
|
+
|
216
|
+
def application
|
217
|
+
@application ||= nil
|
218
|
+
end
|
219
|
+
|
220
|
+
def method_missing( sym, *args, &block )
|
221
|
+
if instance.respond_to?( sym )
|
222
|
+
instance.send( sym, *args, &block )
|
223
|
+
else
|
224
|
+
super( sym, *args, &block )
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def respond_to?( *args )
|
229
|
+
super || instance.respond_to?( *args )
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
include UI::Output
|
235
|
+
include Utilities
|
236
|
+
|
237
|
+
prepend Support::Mixins::SpecInstances
|
238
|
+
include Support::Mixins::Observable
|
239
|
+
include Support::Mixins::Parts
|
240
|
+
|
241
|
+
# {Framework} error namespace.
|
242
|
+
#
|
243
|
+
# All {Framework} errors inherit from and live under it.
|
244
|
+
#
|
245
|
+
# When I say Framework I mean the {Framework} class, not the entire Engine
|
246
|
+
# Framework.
|
247
|
+
#
|
248
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
249
|
+
class Error < Cuboid::Error
|
250
|
+
end
|
251
|
+
|
252
|
+
def initialize
|
253
|
+
super
|
254
|
+
|
255
|
+
@runtime = Runtime.new
|
256
|
+
end
|
257
|
+
|
258
|
+
def runtime
|
259
|
+
@runtime
|
260
|
+
end
|
261
|
+
|
262
|
+
def options=( opts )
|
263
|
+
Options.application = opts
|
264
|
+
end
|
265
|
+
|
266
|
+
def options
|
267
|
+
Options.application
|
268
|
+
end
|
269
|
+
|
270
|
+
# @return [Hash]
|
271
|
+
#
|
272
|
+
# Framework statistics:
|
273
|
+
#
|
274
|
+
# * `:runtime` -- Scan runtime in seconds.
|
275
|
+
def statistics
|
276
|
+
{
|
277
|
+
runtime: @start_datetime ? (@finish_datetime || Time.now) - @start_datetime : 0,
|
278
|
+
}
|
279
|
+
end
|
280
|
+
|
281
|
+
def inspect
|
282
|
+
stats = statistics
|
283
|
+
|
284
|
+
s = "#<#{self.class} (#{status}) "
|
285
|
+
s << "runtime=#{stats[:runtime]} "
|
286
|
+
s << '>'
|
287
|
+
end
|
288
|
+
|
289
|
+
# @return [String]
|
290
|
+
# Returns the version of the framework.
|
291
|
+
def version
|
292
|
+
Cuboid::VERSION
|
293
|
+
end
|
294
|
+
|
295
|
+
def self._spec_instance_cleanup( i )
|
296
|
+
# i.clean_up
|
297
|
+
i.reset
|
298
|
+
end
|
299
|
+
|
300
|
+
def unsafe
|
301
|
+
self
|
302
|
+
end
|
303
|
+
|
304
|
+
def application
|
305
|
+
Cuboid::Application.application
|
306
|
+
end
|
307
|
+
|
308
|
+
def serializer
|
309
|
+
self.class.serializer
|
310
|
+
end
|
311
|
+
|
312
|
+
def safe( &block )
|
313
|
+
raise ArgumentError, 'Missing block.' if !block_given?
|
314
|
+
|
315
|
+
begin
|
316
|
+
block.call self
|
317
|
+
ensure
|
318
|
+
clean_up
|
319
|
+
reset
|
320
|
+
end
|
321
|
+
|
322
|
+
nil
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Cuboid
|
2
|
+
class Application
|
3
|
+
module Parts
|
4
|
+
# Provides access to {Cuboid::Data::Framework} and helpers.
|
5
|
+
#
|
6
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
7
|
+
module Data
|
8
|
+
|
9
|
+
# @return [Data::Application]
|
10
|
+
def data
|
11
|
+
Cuboid::Data.application
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Cuboid
|
2
|
+
class Application
|
3
|
+
module Parts
|
4
|
+
|
5
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
6
|
+
module Report
|
7
|
+
|
8
|
+
def report( results )
|
9
|
+
data.report = results
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Cuboid::Report]
|
13
|
+
# Scan results.
|
14
|
+
def generate_report
|
15
|
+
Cuboid::Report.new(
|
16
|
+
application: self.class,
|
17
|
+
status: state.status,
|
18
|
+
options: Options.application,
|
19
|
+
data: data.report,
|
20
|
+
start_datetime: @start_datetime,
|
21
|
+
finish_datetime: @finish_datetime
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
module Cuboid
|
2
|
+
class Application
|
3
|
+
module Parts
|
4
|
+
|
5
|
+
# Provides access to {Cuboid::State::Application} and helpers.
|
6
|
+
#
|
7
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
8
|
+
module State
|
9
|
+
|
10
|
+
def self.included( base )
|
11
|
+
base.extend ClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
|
16
|
+
# @param [String] ses
|
17
|
+
# Path to an `.ses.` (Cuboid Application Snapshot) file created by
|
18
|
+
# {#suspend}.
|
19
|
+
#
|
20
|
+
# @return [Application]
|
21
|
+
# Restored instance.
|
22
|
+
def restore!( ses, &block )
|
23
|
+
f = self.instance.restore!( ses )
|
24
|
+
block_given? ? f.safe( &block ) : f
|
25
|
+
end
|
26
|
+
|
27
|
+
# @note You should first reset {Cuboid::Options}.
|
28
|
+
#
|
29
|
+
# Resets everything and allows the framework environment to be re-used.
|
30
|
+
def reset
|
31
|
+
Cuboid::State.clear
|
32
|
+
Cuboid::Data.clear
|
33
|
+
Cuboid::Snapshot.reset
|
34
|
+
|
35
|
+
Cuboid::Support::Database::Base.reset
|
36
|
+
Cuboid::System.reset
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
super
|
42
|
+
|
43
|
+
state.status = :ready
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [String]
|
47
|
+
# Provisioned {#suspend} dump file for this instance.
|
48
|
+
def snapshot_path
|
49
|
+
return @state_archive if @state_archive
|
50
|
+
|
51
|
+
default_filename =
|
52
|
+
"Cuboid #{Time.now.to_s.gsub( ':', '_' )} " <<
|
53
|
+
"#{generate_token}.#{Snapshot::EXTENSION}"
|
54
|
+
|
55
|
+
location = Cuboid::Options.snapshot.path
|
56
|
+
|
57
|
+
if !location
|
58
|
+
location = default_filename
|
59
|
+
elsif File.directory? location
|
60
|
+
location += "/#{default_filename}"
|
61
|
+
end
|
62
|
+
|
63
|
+
@state_archive ||= File.expand_path( location )
|
64
|
+
end
|
65
|
+
|
66
|
+
# @note Prefer this from {.reset} if you already have an instance.
|
67
|
+
# @note You should first reset {Cuboid::Options}.
|
68
|
+
#
|
69
|
+
# Resets everything and allows the framework to be re-used.
|
70
|
+
def reset
|
71
|
+
@state_archive = nil
|
72
|
+
@cleaned_up = false
|
73
|
+
@start_datetime = nil
|
74
|
+
@finish_datetime = nil
|
75
|
+
|
76
|
+
# This needs to happen before resetting the other components so they
|
77
|
+
# will be able to put in their hooks.
|
78
|
+
self.class.reset
|
79
|
+
|
80
|
+
clear_observers
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [State::Application]
|
84
|
+
def state
|
85
|
+
Cuboid::State.application
|
86
|
+
end
|
87
|
+
|
88
|
+
# @param [String] ses
|
89
|
+
# Path to an `.ses.` (Cuboid Application Snapshot) file created by {#suspend}.
|
90
|
+
#
|
91
|
+
# @return [Application]
|
92
|
+
# Restored instance.
|
93
|
+
def restore!( ses )
|
94
|
+
if handler = self.class.signal_handlers[:restore]
|
95
|
+
method( handler ).call
|
96
|
+
end
|
97
|
+
|
98
|
+
Snapshot.load ses
|
99
|
+
|
100
|
+
state.status = :restored
|
101
|
+
|
102
|
+
self
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Array<String>]
|
106
|
+
# Messages providing more information about the current {#status} of
|
107
|
+
# the framework.
|
108
|
+
def status_messages
|
109
|
+
state.status_messages
|
110
|
+
end
|
111
|
+
|
112
|
+
# @return [Symbol]
|
113
|
+
# Status of the instance, possible values are (in order):
|
114
|
+
#
|
115
|
+
# * `:ready` -- {#initialize Initialised} and waiting for instructions.
|
116
|
+
# * `:preparing` -- Getting ready to start.
|
117
|
+
# * `:pausing` -- The instance is being {#pause paused} (if applicable).
|
118
|
+
# * `:paused` -- The instance has been {#pause paused} (if applicable).
|
119
|
+
# * `:suspending` -- The instance is being {#suspend suspended} (if applicable).
|
120
|
+
# * `:suspended` -- The instance has being {#suspend suspended} (if applicable).
|
121
|
+
# * `:cleanup` -- The instance is done and cleaning up.
|
122
|
+
# * `:aborted` -- The scan has been {Application::Parts::State#abort}, you can grab the
|
123
|
+
# report and shutdown.
|
124
|
+
# * `:done` -- The scan has completed, you can grab the report and shutdown.
|
125
|
+
# * `:timed_out` -- The scan was aborted due to a time-out..
|
126
|
+
def status
|
127
|
+
state.status
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [Bool]
|
131
|
+
# `true` if the framework is running, `false` otherwise. This is `true`
|
132
|
+
# even if the scan is {#paused?}.
|
133
|
+
def running?
|
134
|
+
state.running?
|
135
|
+
end
|
136
|
+
|
137
|
+
# @return [Bool]
|
138
|
+
# `true` if the framework is paused, `false` otherwise.
|
139
|
+
def paused?
|
140
|
+
state.paused?
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Bool]
|
144
|
+
# `true` if the framework has been instructed to pause (i.e. is in the
|
145
|
+
# process of being paused or has been paused), `false` otherwise.
|
146
|
+
def pause?
|
147
|
+
state.pause?
|
148
|
+
end
|
149
|
+
|
150
|
+
# @return [Bool]
|
151
|
+
# `true` if the framework is in the process of pausing, `false` otherwise.
|
152
|
+
def pausing?
|
153
|
+
state.pausing?
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return (see Cuboid::State::Application#done?)
|
157
|
+
def done?
|
158
|
+
state.done?
|
159
|
+
end
|
160
|
+
|
161
|
+
# @note Each call from a unique caller is counted as a pause request
|
162
|
+
# and in order for the system to resume **all** pause callers need to
|
163
|
+
# {#resume} it.
|
164
|
+
#
|
165
|
+
# Pauses the framework on a best effort basis.
|
166
|
+
#
|
167
|
+
# @return [Integer]
|
168
|
+
# ID identifying this pause request.
|
169
|
+
def pause!
|
170
|
+
state.pause
|
171
|
+
|
172
|
+
if handler = self.class.signal_handlers[:pause]
|
173
|
+
method( handler ).call
|
174
|
+
end
|
175
|
+
|
176
|
+
state.paused
|
177
|
+
|
178
|
+
nil
|
179
|
+
end
|
180
|
+
|
181
|
+
# @return [Bool]
|
182
|
+
# `true` if the {Application#run} has been aborted, `false` otherwise.
|
183
|
+
def aborted?
|
184
|
+
state.aborted?
|
185
|
+
end
|
186
|
+
|
187
|
+
# @return [Bool]
|
188
|
+
# `true` if the framework has been instructed to abort (i.e. is in the
|
189
|
+
# process of being aborted or has been aborted), `false` otherwise.
|
190
|
+
def abort?
|
191
|
+
state.abort?
|
192
|
+
end
|
193
|
+
|
194
|
+
# @return [Bool]
|
195
|
+
# `true` if the framework is in the process of aborting, `false` otherwise.
|
196
|
+
def aborting?
|
197
|
+
state.aborting?
|
198
|
+
end
|
199
|
+
|
200
|
+
# Aborts the {Application#run} on a best effort basis.
|
201
|
+
def abort!
|
202
|
+
state.abort
|
203
|
+
|
204
|
+
if handler = self.class.signal_handlers[:abort]
|
205
|
+
method( handler ).call
|
206
|
+
end
|
207
|
+
|
208
|
+
state.aborted
|
209
|
+
end
|
210
|
+
|
211
|
+
def resume!
|
212
|
+
state.resume
|
213
|
+
|
214
|
+
if handler = self.class.signal_handlers[:resume]
|
215
|
+
method( handler ).call
|
216
|
+
end
|
217
|
+
|
218
|
+
state.resumed
|
219
|
+
end
|
220
|
+
|
221
|
+
# Writes a {Snapshot.dump} to disk and aborts the scan.
|
222
|
+
#
|
223
|
+
# @return [String,nil]
|
224
|
+
# Path to the state file `wait` is `true`, `nil` otherwise.
|
225
|
+
def suspend!
|
226
|
+
state.suspend
|
227
|
+
|
228
|
+
if handler = self.class.signal_handlers[:suspend]
|
229
|
+
method( handler ).call
|
230
|
+
end
|
231
|
+
|
232
|
+
suspend_to_disk
|
233
|
+
state.suspended
|
234
|
+
|
235
|
+
snapshot_path
|
236
|
+
end
|
237
|
+
|
238
|
+
# @return [Bool]
|
239
|
+
# `true` if the system is in the process of being suspended, `false`
|
240
|
+
# otherwise.
|
241
|
+
def suspend?
|
242
|
+
state.suspend?
|
243
|
+
end
|
244
|
+
|
245
|
+
# @return [Bool]
|
246
|
+
# `true` if the system has been suspended, `false` otherwise.
|
247
|
+
def suspended?
|
248
|
+
state.suspended?
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
def wait_if_paused
|
254
|
+
state.paused if pause?
|
255
|
+
sleep 0.2 while pause? && !abort?
|
256
|
+
end
|
257
|
+
|
258
|
+
def suspend_to_disk
|
259
|
+
state.set_status_message :saving_snapshot, snapshot_path
|
260
|
+
Snapshot.dump( snapshot_path )
|
261
|
+
state.clear_status_messages
|
262
|
+
|
263
|
+
clean_up
|
264
|
+
|
265
|
+
state.set_status_message :snapshot_location, snapshot_path
|
266
|
+
print_info status_messages.first
|
267
|
+
state.suspended
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|