cosmos 5.0.2.pre.beta2 → 5.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cosmos +1 -1
- data/data/config/microservice.yaml +47 -35
- data/data/config/plugins.yaml +3 -150
- data/data/config/target.yaml +70 -0
- data/data/config/tool.yaml +37 -31
- data/lib/cosmos/api/api.rb +1 -25
- data/lib/cosmos/api/cmd_api.rb +17 -6
- data/lib/cosmos/api/config_api.rb +10 -4
- data/lib/cosmos/api/limits_api.rb +1 -1
- data/lib/cosmos/api/settings_api.rb +19 -7
- data/lib/cosmos/api/target_api.rb +2 -2
- data/lib/cosmos/api/tlm_api.rb +69 -41
- data/lib/cosmos/config/config_parser.rb +19 -22
- data/lib/cosmos/config/meta_config_parser.rb +1 -1
- data/lib/cosmos/conversions/generic_conversion.rb +2 -2
- data/lib/cosmos/conversions/polynomial_conversion.rb +5 -8
- data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +26 -9
- data/lib/cosmos/io/json_drb.rb +5 -1
- data/lib/cosmos/logs/log_writer.rb +2 -2
- data/lib/cosmos/microservices/cleanup_microservice.rb +28 -29
- data/lib/cosmos/microservices/decom_microservice.rb +1 -1
- data/lib/cosmos/microservices/interface_microservice.rb +0 -1
- data/lib/cosmos/microservices/microservice.rb +3 -3
- data/lib/cosmos/microservices/reducer_microservice.rb +12 -10
- data/lib/cosmos/models/cvt_model.rb +6 -6
- data/lib/cosmos/models/gem_model.rb +3 -3
- data/lib/cosmos/models/info_model.rb +1 -1
- data/lib/cosmos/models/interface_status_model.rb +1 -1
- data/lib/cosmos/models/metadata_model.rb +42 -216
- data/lib/cosmos/models/metric_model.rb +2 -2
- data/lib/cosmos/models/microservice_model.rb +1 -1
- data/lib/cosmos/models/microservice_status_model.rb +1 -1
- data/lib/cosmos/models/model.rb +16 -16
- data/lib/cosmos/models/note_model.rb +124 -0
- data/lib/cosmos/models/ping_model.rb +2 -1
- data/lib/cosmos/models/plugin_model.rb +1 -1
- data/lib/cosmos/models/process_status_model.rb +1 -1
- data/lib/cosmos/models/scope_model.rb +9 -26
- data/lib/cosmos/models/settings_model.rb +55 -0
- data/lib/cosmos/models/sorted_model.rb +165 -0
- data/lib/cosmos/models/target_model.rb +120 -13
- data/lib/cosmos/models/tool_config_model.rb +38 -0
- data/lib/cosmos/models/tool_model.rb +1 -1
- data/lib/cosmos/models/widget_model.rb +1 -1
- data/lib/cosmos/operators/microservice_operator.rb +2 -1
- data/lib/cosmos/packets/packet.rb +23 -0
- data/lib/cosmos/packets/packet_config.rb +2 -2
- data/lib/cosmos/packets/packet_item.rb +57 -0
- data/lib/cosmos/packets/packet_item_limits.rb +14 -2
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +1 -1
- data/lib/cosmos/packets/parsers/packet_parser.rb +1 -1
- data/lib/cosmos/packets/parsers/xtce_parser.rb +1 -1
- data/lib/cosmos/packets/structure_item.rb +10 -1
- data/lib/cosmos/script/api_shared.rb +30 -25
- data/lib/cosmos/script/calendar.rb +26 -15
- data/lib/cosmos/script/commands.rb +5 -7
- data/lib/cosmos/script/script.rb +19 -39
- data/lib/cosmos/script/storage.rb +92 -105
- data/lib/cosmos/system/system.rb +2 -1
- data/lib/cosmos/tools/table_manager/table_item.rb +1 -1
- data/lib/cosmos/top_level.rb +5 -1
- data/lib/cosmos/topics/autonomic_topic.rb +2 -2
- data/lib/cosmos/topics/calendar_topic.rb +1 -1
- data/lib/cosmos/topics/command_decom_topic.rb +35 -1
- data/lib/cosmos/topics/command_topic.rb +6 -4
- data/lib/cosmos/topics/interface_topic.rb +8 -8
- data/lib/cosmos/topics/limits_event_topic.rb +5 -3
- data/lib/cosmos/topics/notifications_topic.rb +1 -1
- data/lib/cosmos/topics/router_topic.rb +9 -9
- data/lib/cosmos/topics/telemetry_decom_topic.rb +5 -1
- data/lib/cosmos/topics/telemetry_topic.rb +1 -1
- data/lib/cosmos/topics/timeline_topic.rb +1 -1
- data/lib/cosmos/topics/topic.rb +23 -8
- data/lib/cosmos/utilities/logger.rb +4 -3
- data/lib/cosmos/utilities/metric.rb +32 -26
- data/lib/cosmos/utilities/s3.rb +61 -0
- data/lib/cosmos/utilities/s3_file_cache.rb +12 -6
- data/lib/cosmos/utilities/store.rb +1 -0
- data/lib/cosmos/utilities/store_autoload.rb +25 -134
- data/lib/cosmos/version.rb +6 -5
- data/templates/plugin-template/plugin.gemspec +0 -2
- metadata +9 -6
- data/lib/cosmos/models/narrative_model.rb +0 -280
@@ -300,10 +300,10 @@ module Cosmos
|
|
300
300
|
#
|
301
301
|
# @param args [String|Array<String>] See the description for calling style
|
302
302
|
# @param type [Symbol] Telemetry type, :RAW, :CONVERTED (default), :FORMATTED, or :WITH_UNITS
|
303
|
-
def wait_check(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token)
|
303
|
+
def wait_check(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token, &block)
|
304
304
|
target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate = _wait_check_process_args(args, scope: scope, token: token)
|
305
305
|
start_time = Time.now.sys
|
306
|
-
success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, type, comparison_to_eval, timeout, polling_rate, scope: scope, token: token)
|
306
|
+
success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, type, comparison_to_eval, timeout, polling_rate, scope: scope, token: token, &block)
|
307
307
|
time = Time.now.sys - start_time
|
308
308
|
check_str = "CHECK: #{_upcase(target_name, packet_name, item_name)} #{comparison_to_eval}"
|
309
309
|
with_value_str = "with value == #{value} after waiting #{time} seconds"
|
@@ -321,8 +321,8 @@ module Cosmos
|
|
321
321
|
end
|
322
322
|
|
323
323
|
# @deprecated use wait_check with type: :RAW
|
324
|
-
def wait_check_raw(*args, scope: $cosmos_scope, token: $cosmos_token)
|
325
|
-
wait_check(*args, type: :RAW, scope: scope, token: token)
|
324
|
+
def wait_check_raw(*args, scope: $cosmos_scope, token: $cosmos_token, &block)
|
325
|
+
wait_check(*args, type: :RAW, scope: scope, token: token, &block)
|
326
326
|
end
|
327
327
|
|
328
328
|
# Wait for the value of a telmetry item to be within a tolerance of a value
|
@@ -334,7 +334,7 @@ module Cosmos
|
|
334
334
|
#
|
335
335
|
# @param args [String|Array<String>] See the description for calling style
|
336
336
|
# @param type [Symbol] Telemetry type, :RAW or :CONVERTED (default)
|
337
|
-
def wait_check_tolerance(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token)
|
337
|
+
def wait_check_tolerance(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token, &block)
|
338
338
|
raise "Invalid type '#{type}' for wait_check_tolerance" unless %i(RAW CONVERTED).include?(type)
|
339
339
|
|
340
340
|
target_name, packet_name, item_name, expected_value, tolerance, timeout, polling_rate = _wait_tolerance_process_args(args, scope: scope, token: token)
|
@@ -343,7 +343,7 @@ module Cosmos
|
|
343
343
|
if value.is_a?(Array)
|
344
344
|
expected_value, tolerance = array_tolerance_process_args(value.size, expected_value, tolerance, 'wait_check_tolerance', scope: scope, token: token)
|
345
345
|
|
346
|
-
success, value = cosmos_script_wait_implementation_array_tolerance(value.size, target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate, scope: scope, token: token)
|
346
|
+
success, value = cosmos_script_wait_implementation_array_tolerance(value.size, target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate, scope: scope, token: token, &block)
|
347
347
|
time = Time.now.sys - start_time
|
348
348
|
|
349
349
|
message = ""
|
@@ -388,8 +388,8 @@ module Cosmos
|
|
388
388
|
end
|
389
389
|
|
390
390
|
# @deprecated Use wait_check_tolerance with type: :RAW
|
391
|
-
def wait_check_tolerance_raw(*args, scope: $cosmos_scope, token: $cosmos_token)
|
392
|
-
wait_check_tolerance(*args, type: :RAW, scope: scope, token: token)
|
391
|
+
def wait_check_tolerance_raw(*args, scope: $cosmos_scope, token: $cosmos_token, &block)
|
392
|
+
wait_check_tolerance(*args, type: :RAW, scope: scope, token: token, &block)
|
393
393
|
end
|
394
394
|
|
395
395
|
# Wait on an expression to be true. On a timeout, the script will pause.
|
@@ -397,12 +397,12 @@ module Cosmos
|
|
397
397
|
timeout,
|
398
398
|
polling_rate = DEFAULT_TLM_POLLING_RATE,
|
399
399
|
context = nil,
|
400
|
-
scope: $cosmos_scope, token: $cosmos_token)
|
400
|
+
scope: $cosmos_scope, token: $cosmos_token, &block)
|
401
401
|
start_time = Time.now.sys
|
402
402
|
success = cosmos_script_wait_implementation_expression(exp_to_eval,
|
403
403
|
timeout,
|
404
404
|
polling_rate,
|
405
|
-
context, scope: scope, token: token)
|
405
|
+
context, scope: scope, token: token, &block)
|
406
406
|
time = Time.now.sys - start_time
|
407
407
|
if success
|
408
408
|
Logger.info "CHECK: #{exp_to_eval} is TRUE after waiting #{time} seconds"
|
@@ -691,15 +691,20 @@ module Cosmos
|
|
691
691
|
return [target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate]
|
692
692
|
end
|
693
693
|
|
694
|
-
def _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, scope: $cosmos_scope, token: $cosmos_token)
|
694
|
+
def _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: $cosmos_scope, token: $cosmos_token, &block)
|
695
695
|
end_time = Time.now.sys + timeout
|
696
|
-
exp_to_eval = yield
|
697
696
|
|
698
697
|
while true
|
699
698
|
work_start = Time.now.sys
|
700
699
|
value = tlm(target_name, packet_name, item_name, type: value_type, scope: scope, token: token)
|
701
|
-
if
|
702
|
-
|
700
|
+
if not block.nil?
|
701
|
+
if block.call(value)
|
702
|
+
return true, value
|
703
|
+
end
|
704
|
+
else
|
705
|
+
if eval(exp_to_eval)
|
706
|
+
return true, value
|
707
|
+
end
|
703
708
|
end
|
704
709
|
break if Time.now.sys >= end_time
|
705
710
|
|
@@ -724,25 +729,25 @@ module Cosmos
|
|
724
729
|
end
|
725
730
|
|
726
731
|
# Wait for a converted telemetry item to pass a comparison
|
727
|
-
def cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token)
|
728
|
-
|
729
|
-
"value " + comparison_to_eval
|
732
|
+
def cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token, &block)
|
733
|
+
if comparison_to_eval
|
734
|
+
exp_to_eval = "value " + comparison_to_eval
|
735
|
+
else
|
736
|
+
exp_to_eval = nil
|
730
737
|
end
|
738
|
+
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: scope, token: token, &block)
|
731
739
|
end
|
732
740
|
|
733
|
-
def cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token)
|
734
|
-
|
735
|
-
|
736
|
-
end
|
741
|
+
def cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token, &block)
|
742
|
+
exp_to_eval = "((#{expected_value} - #{tolerance})..(#{expected_value} + #{tolerance})).include? value"
|
743
|
+
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: scope, token: token, &block)
|
737
744
|
end
|
738
745
|
|
739
|
-
def cosmos_script_wait_implementation_array_tolerance(array_size, target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token)
|
746
|
+
def cosmos_script_wait_implementation_array_tolerance(array_size, target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token, &block)
|
740
747
|
statements = []
|
741
748
|
array_size.times { |i| statements << "(((#{expected_value[i]} - #{tolerance[i]})..(#{expected_value[i]} + #{tolerance[i]})).include? value[#{i}])" }
|
742
749
|
exp_to_eval = statements.join(" && ")
|
743
|
-
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, scope: scope, token: token)
|
744
|
-
exp_to_eval
|
745
|
-
end
|
750
|
+
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: scope, token: token, &block)
|
746
751
|
end
|
747
752
|
|
748
753
|
# Wait on an expression to be true.
|
@@ -18,6 +18,7 @@
|
|
18
18
|
# copyright holder
|
19
19
|
|
20
20
|
require 'cosmos/script/extract'
|
21
|
+
require 'time'
|
21
22
|
|
22
23
|
module Cosmos
|
23
24
|
module Script
|
@@ -25,38 +26,48 @@ module Cosmos
|
|
25
26
|
|
26
27
|
private
|
27
28
|
|
28
|
-
#
|
29
|
+
# Gets the current metadata
|
29
30
|
#
|
30
|
-
# @param target [String] Target to set metadata on
|
31
31
|
# @return The result of the method call.
|
32
|
-
def get_metadata(
|
33
|
-
|
34
|
-
response = $api_server.request('get', endpoint)
|
32
|
+
def get_metadata()
|
33
|
+
response = $api_server.request('get', "/cosmos-api/metadata/latest")
|
35
34
|
return nil if response.nil? || response.code != 200
|
36
35
|
return JSON.parse(response.body)
|
37
36
|
end
|
38
37
|
|
39
|
-
# Sets the metadata
|
38
|
+
# Sets the metadata
|
40
39
|
#
|
41
|
-
# @param target [String] Target to set metadata on
|
42
40
|
# @param metadata [Hash<Symbol, Variable>] A hash of metadata
|
43
|
-
# @param color [String] Events color to show on Calendar tool
|
44
|
-
# @param start
|
41
|
+
# @param color [String] Events color to show on Calendar tool, if nil will be blue
|
42
|
+
# @param start [Time] Metadata time value, if nil will be current time
|
45
43
|
# @return The result of the method call.
|
46
|
-
def set_metadata(
|
44
|
+
def set_metadata(metadata, color: nil, start: nil)
|
47
45
|
color = color.nil? ? '#003784' : color
|
48
|
-
data = {:
|
49
|
-
data[:start] = start unless start.nil?
|
46
|
+
data = { color: color, metadata: metadata }
|
47
|
+
data[:start] = start.iso8601 unless start.nil?
|
50
48
|
response = $api_server.request('post', '/cosmos-api/metadata', data: data, json: true)
|
51
49
|
return nil if response.nil? || response.code != 201
|
52
50
|
return JSON.parse(response.body)
|
53
51
|
end
|
54
52
|
|
55
|
-
#
|
53
|
+
# Updates the metadata
|
56
54
|
#
|
57
|
-
|
58
|
-
|
55
|
+
# @param start [Integer] Metadata time value as integer seconds from epoch
|
56
|
+
# @param metadata [Hash<Symbol, Variable>] A hash of metadata
|
57
|
+
# @param color [String] Events color to show on Calendar tool, if nil will be blue
|
58
|
+
# @return The result of the method call.
|
59
|
+
def update_metadata(start, metadata, color: nil)
|
60
|
+
color = color.nil? ? '#003784' : color
|
61
|
+
data = { :color => color, :metadata => metadata }
|
62
|
+
data[:start] = Time.at(start).iso8601
|
63
|
+
response = $api_server.request('put', "/cosmos-api/metadata/#{start}", data: data, json: true)
|
64
|
+
return nil if response.nil? || response.code != 201
|
65
|
+
return JSON.parse(response.body)
|
59
66
|
end
|
60
67
|
|
68
|
+
# Requests the metadata from the user for a target
|
69
|
+
def input_metadata(*args, **kwargs)
|
70
|
+
raise StandardError "can only be used in Script Runner"
|
71
|
+
end
|
61
72
|
end
|
62
73
|
end
|
@@ -112,13 +112,11 @@ module Cosmos
|
|
112
112
|
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args)
|
113
113
|
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
114
114
|
rescue HazardousError => e
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
retry unless prompt_for_script_abort()
|
121
|
-
end
|
115
|
+
# This opens a prompt at which point they can cancel and stop the script
|
116
|
+
# or say Yes and send the command. Thus we don't care about the return value.
|
117
|
+
prompt_for_hazardous(e.target_name, e.cmd_name, e.hazardous_description)
|
118
|
+
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args)
|
119
|
+
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
122
120
|
end
|
123
121
|
end
|
124
122
|
end
|
data/lib/cosmos/script/script.rb
CHANGED
@@ -129,58 +129,38 @@ module Cosmos
|
|
129
129
|
message_box(string, *items, **options)
|
130
130
|
end
|
131
131
|
|
132
|
-
def _file_dialog(
|
132
|
+
def _file_dialog(title, message, filter:)
|
133
133
|
answer = ''
|
134
|
-
|
135
|
-
if
|
136
|
-
|
137
|
-
|
138
|
-
files.select! { |f| File.directory? f }
|
139
|
-
end
|
134
|
+
path = "./*"
|
135
|
+
path += filter if filter
|
136
|
+
files = Dir[path]
|
137
|
+
files.select! { |f| !File.directory? f }
|
140
138
|
while answer.empty?
|
141
|
-
print
|
139
|
+
print "#{title}\n#{message}\n#{files.join("\n")}\n<Type file name>:"
|
142
140
|
answer = gets
|
143
141
|
answer.chomp!
|
144
142
|
end
|
145
143
|
return answer
|
146
144
|
end
|
147
145
|
|
148
|
-
def
|
149
|
-
_file_dialog(
|
150
|
-
end
|
151
|
-
|
152
|
-
def open_file_dialog(directory, message = "Open File", filter = "*")
|
153
|
-
_file_dialog(message, directory, filter)
|
154
|
-
end
|
155
|
-
|
156
|
-
def open_files_dialog(directory, message = "Open File(s)", filter = "*")
|
157
|
-
_file_dialog(message, directory, filter)
|
146
|
+
def open_file_dialog(title, message = "Open File", filter:)
|
147
|
+
_file_dialog(title, message, filter)
|
158
148
|
end
|
159
149
|
|
160
|
-
def
|
161
|
-
_file_dialog(
|
150
|
+
def open_files_dialog(title, message = "Open File(s)", filter:)
|
151
|
+
_file_dialog(title, message, filter)
|
162
152
|
end
|
163
153
|
|
164
154
|
def prompt_for_hazardous(target_name, cmd_name, hazardous_description)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def prompt_for_script_abort
|
178
|
-
print "Stop running script? (y,n): "
|
179
|
-
answer = gets.chomp
|
180
|
-
if answer.downcase == 'y'
|
181
|
-
exit
|
182
|
-
else
|
183
|
-
return false # Not aborted - Retry
|
155
|
+
loop do
|
156
|
+
message = "Warning: Command #{target_name} #{cmd_name} is Hazardous. "
|
157
|
+
message << "\n#{hazardous_description}\n" if hazardous_description
|
158
|
+
message << "Send? (y): "
|
159
|
+
print message
|
160
|
+
answer = gets.chomp
|
161
|
+
if answer.downcase == 'y'
|
162
|
+
return true
|
163
|
+
end
|
184
164
|
end
|
185
165
|
end
|
186
166
|
|
@@ -23,137 +23,124 @@ module Cosmos
|
|
23
23
|
module Script
|
24
24
|
private
|
25
25
|
|
26
|
-
#
|
26
|
+
# Delete a file on a target
|
27
|
+
#
|
28
|
+
# @param [String] Path to a file in a target directory
|
29
|
+
def delete_target_file(path, scope: $cosmos_scope)
|
30
|
+
begin
|
31
|
+
# Only delete from the targets_modified
|
32
|
+
delete_path = "#{scope}/targets_modified/#{path}"
|
33
|
+
endpoint = "/cosmos-api/storage/delete/#{delete_path}"
|
34
|
+
Cosmos::Logger.info "Deleting #{delete_path}"
|
35
|
+
response = $api_server.request('delete', endpoint, query: {bucket: 'config'})
|
36
|
+
if response.nil? || response.code != 200
|
37
|
+
raise "Failed to delete #{delete_path}. Note: #{scope}/targets is read-only."
|
38
|
+
end
|
39
|
+
rescue => error
|
40
|
+
raise "Failed deleting #{path} due to #{error.message}"
|
41
|
+
end
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get a handle to write a target file
|
27
46
|
#
|
28
47
|
# @param path [String] Path to a file in a target directory
|
29
|
-
# @param
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
48
|
+
# @param io_or_string [Io or String] IO object
|
49
|
+
def put_target_file(path, io_or_string, scope: $cosmos_scope)
|
50
|
+
raise "Disallowed path modifier '..' found in #{path}" if path.include?('..')
|
51
|
+
upload_path = "#{scope}/targets_modified/#{path}"
|
52
|
+
endpoint = "/cosmos-api/storage/upload/#{upload_path}"
|
53
|
+
Cosmos::Logger.info "Writing #{upload_path}"
|
54
|
+
result = _get_presigned_request(endpoint)
|
34
55
|
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
endpoint = "/cosmos-api/storage/download/#{scope}/#{part}/#{path}"
|
44
|
-
Cosmos::Logger.info "Reading #{scope}/#{part}/#{path}"
|
45
|
-
if $cosmos_in_cluster
|
46
|
-
response = $api_server.request('get', endpoint, query: {bucket: 'config', internal: true})
|
47
|
-
else
|
48
|
-
response = $api_server.request('get', endpoint, query: {bucket: 'config'})
|
49
|
-
end
|
50
|
-
if response.nil? || response.code != 201
|
51
|
-
Cosmos::Logger.error "Failed Get Presigned URL for #{scope}/#{part}/#{path}"
|
52
|
-
if part == "targets_modified"
|
53
|
-
part = "targets"
|
54
|
-
redo
|
56
|
+
# Try to put the file
|
57
|
+
success = false
|
58
|
+
begin
|
59
|
+
uri = _get_uri(result['url'])
|
60
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
61
|
+
request = Net::HTTP::Put.new(uri, {'Content-Length' => io_or_string.length.to_s})
|
62
|
+
if String === io_or_string
|
63
|
+
request.body = io_or_string
|
55
64
|
else
|
56
|
-
|
65
|
+
request.body_stream = io_or_string
|
66
|
+
end
|
67
|
+
result = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
68
|
+
http.request(request)
|
57
69
|
end
|
70
|
+
return result
|
58
71
|
end
|
59
|
-
|
72
|
+
rescue => error
|
73
|
+
raise "Failed to write #{upload_path}"
|
74
|
+
end
|
75
|
+
nil
|
76
|
+
end
|
60
77
|
|
61
|
-
|
78
|
+
# Get a handle to access a target file
|
79
|
+
#
|
80
|
+
# @param path [String] Path to a file in a target directory, e.g. "INST/procedures/test.rb"
|
81
|
+
# @param original [Boolean] Whether to get the original or modified file
|
82
|
+
# @return [File|nil]
|
83
|
+
def get_target_file(path, original: false, scope: $cosmos_scope)
|
84
|
+
part = "targets"
|
85
|
+
part += "_modified" unless original
|
86
|
+
# Loop to allow redo when switching from modified to original
|
87
|
+
loop do
|
62
88
|
begin
|
63
|
-
|
64
|
-
uri = URI.parse("http://cosmos-minio:9000" + result['url'])
|
65
|
-
else
|
66
|
-
uri = URI.parse($api_server.generate_url + result['url'])
|
67
|
-
end
|
68
|
-
Net::HTTP.start(uri.host, uri.port) do |http|
|
69
|
-
request = Net::HTTP::Get.new uri
|
70
|
-
|
71
|
-
http.request request do |response|
|
72
|
-
response.read_body do |chunk|
|
73
|
-
puts chunk.length
|
74
|
-
file.write chunk
|
75
|
-
end
|
76
|
-
end
|
77
|
-
file.rewind
|
78
|
-
end
|
79
|
-
return file
|
89
|
+
return _get_storage_file("#{part}/#{path}", scope: scope)
|
80
90
|
rescue => error
|
81
|
-
Cosmos::Logger.info("#{scope}/#{part}/#{path} not found")
|
82
91
|
if part == "targets_modified"
|
83
92
|
part = "targets"
|
84
93
|
redo
|
85
94
|
else
|
86
|
-
raise
|
95
|
+
raise error
|
87
96
|
end
|
88
97
|
end
|
89
98
|
break
|
90
99
|
end
|
91
100
|
end
|
92
101
|
|
93
|
-
#
|
94
|
-
#
|
95
|
-
# @param path [String] Path to a file in a target directory
|
96
|
-
# @param io_or_string [Io or String] IO object
|
97
|
-
def put_target_file(path, io_or_string, scope: $cosmos_scope)
|
98
|
-
# Get presigned url
|
99
|
-
part = "targets_modified"
|
100
|
-
begin
|
101
|
-
endpoint = "/cosmos-api/storage/upload/#{scope}/#{part}/#{path}"
|
102
|
-
Cosmos::Logger.info "Writing #{scope}/#{part}/#{path}"
|
103
|
-
if $cosmos_in_cluster
|
104
|
-
response = $api_server.request('get', endpoint, query: {bucket: 'config', internal: true})
|
105
|
-
else
|
106
|
-
response = $api_server.request('get', endpoint, query: {bucket: 'config'})
|
107
|
-
end
|
108
|
-
if response.nil? || response.code != 201
|
109
|
-
Cosmos::Logger.error "Failed Get Presigned URL for #{scope}/#{part}/#{path}"
|
110
|
-
return nil
|
111
|
-
end
|
112
|
-
result = JSON.parse(response.body)
|
102
|
+
# These are helper methods ... should not be used directly
|
113
103
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
result = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
130
|
-
http.request(request)
|
131
|
-
end
|
132
|
-
return result
|
104
|
+
def _get_storage_file(path, scope: $cosmos_scope)
|
105
|
+
# Create Tempfile to store data
|
106
|
+
file = Tempfile.new('target', binmode: true)
|
107
|
+
|
108
|
+
endpoint = "/cosmos-api/storage/download/#{scope}/#{path}"
|
109
|
+
Cosmos::Logger.info "Reading #{scope}/#{path}"
|
110
|
+
result = _get_presigned_request(endpoint)
|
111
|
+
|
112
|
+
# Try to get the file
|
113
|
+
uri = _get_uri(result['url'])
|
114
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
115
|
+
request = Net::HTTP::Get.new uri
|
116
|
+
http.request request do |response|
|
117
|
+
response.read_body do |chunk|
|
118
|
+
file.write chunk
|
133
119
|
end
|
134
|
-
rescue => error
|
135
|
-
raise "Failed to write #{scope}/#{part}/#{path}"
|
136
120
|
end
|
121
|
+
file.rewind
|
137
122
|
end
|
138
|
-
|
123
|
+
return file
|
139
124
|
end
|
140
125
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
# Only delete from the targets_modified
|
147
|
-
endpoint = "/cosmos-api/storage/delete/#{scope}/targets_modified/#{path}"
|
148
|
-
Cosmos::Logger.info "Deleting #{scope}/targets_modified/#{path}"
|
149
|
-
response = $api_server.request('delete', endpoint, query: {bucket: 'config'})
|
150
|
-
if response.nil? || response.code != 200
|
151
|
-
raise "Failed to delete #{scope}/targets_modified/#{path}"
|
152
|
-
end
|
153
|
-
rescue => error
|
154
|
-
raise "Failed deleting #{path} due to #{error.message}"
|
126
|
+
def _get_uri(url)
|
127
|
+
if $cosmos_in_cluster
|
128
|
+
uri = URI.parse("http://cosmos-minio:9000" + url)
|
129
|
+
else
|
130
|
+
uri = URI.parse($api_server.generate_url + url)
|
155
131
|
end
|
156
|
-
|
132
|
+
end
|
133
|
+
|
134
|
+
def _get_presigned_request(endpoint)
|
135
|
+
if $cosmos_in_cluster
|
136
|
+
response = $api_server.request('get', endpoint, query: { bucket: 'config', internal: true })
|
137
|
+
else
|
138
|
+
response = $api_server.request('get', endpoint, query: { bucket: 'config' })
|
139
|
+
end
|
140
|
+
if response.nil? || response.code != 201
|
141
|
+
raise "Failed to get presigned URL for #{endpoint}"
|
142
|
+
end
|
143
|
+
JSON.parse(response.body)
|
157
144
|
end
|
158
145
|
end
|
159
146
|
end
|
data/lib/cosmos/system/system.rb
CHANGED
@@ -26,6 +26,7 @@ require 'cosmos/packets/limits'
|
|
26
26
|
require 'cosmos/system/target'
|
27
27
|
require 'cosmos/utilities/s3'
|
28
28
|
require 'cosmos/utilities/zip'
|
29
|
+
require 'cosmos/models/scope_model'
|
29
30
|
require 'thread'
|
30
31
|
require 'fileutils'
|
31
32
|
|
@@ -54,7 +55,7 @@ module Cosmos
|
|
54
55
|
|
55
56
|
# @return [Symbol] The current limits_set of the system returned from Redis
|
56
57
|
def self.limits_set
|
57
|
-
|
58
|
+
ScopeModel.limits_set(scope: $cosmos_scope)
|
58
59
|
end
|
59
60
|
|
60
61
|
def self.setup_targets(target_names, base_dir, scope:)
|
data/lib/cosmos/top_level.rb
CHANGED
@@ -37,9 +37,13 @@ class HazardousError < StandardError
|
|
37
37
|
attr_accessor :cmd_name
|
38
38
|
attr_accessor :cmd_params
|
39
39
|
attr_accessor :hazardous_description
|
40
|
+
attr_accessor :formatted # formatted command for use in resending original
|
40
41
|
|
41
42
|
def to_s
|
42
|
-
"#{target_name} #{cmd_name} with #{cmd_params} is Hazardous
|
43
|
+
string = "#{target_name} #{cmd_name} with #{cmd_params} is Hazardous"
|
44
|
+
string << "due to '#{hazardous_description}'" if hazardous_description
|
45
|
+
# Pass along the original formatted command so it can be resent
|
46
|
+
string << ".\n#{formatted}"
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
@@ -26,7 +26,7 @@ module Cosmos
|
|
26
26
|
# Notify to the topic
|
27
27
|
#
|
28
28
|
# ```json
|
29
|
-
# {
|
29
|
+
# {
|
30
30
|
# "kind" => "created",
|
31
31
|
# "type" => "trigger",
|
32
32
|
# "data" => {
|
@@ -46,7 +46,7 @@ module Cosmos
|
|
46
46
|
# }
|
47
47
|
# ```
|
48
48
|
def self.write_notification(notification, scope:)
|
49
|
-
|
49
|
+
Topic.write_topic("#{scope}#{PRIMARY_KEY}", notification, '*', 1000)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -21,6 +21,10 @@ require 'cosmos/topics/topic'
|
|
21
21
|
|
22
22
|
module Cosmos
|
23
23
|
class CommandDecomTopic < Topic
|
24
|
+
def self.topics(scope:)
|
25
|
+
super(scope, 'DECOMCMD')
|
26
|
+
end
|
27
|
+
|
24
28
|
def self.write_packet(packet, scope:)
|
25
29
|
topic = "#{scope}__DECOMCMD__{#{packet.target_name}}__#{packet.packet_name}"
|
26
30
|
msg_hash = { time: packet.received_time.to_nsec_from_epoch,
|
@@ -36,7 +40,37 @@ module Cosmos
|
|
36
40
|
json_hash[item.name + "__U"] = packet.read_item(item, :WITH_UNITS) if item.units
|
37
41
|
end
|
38
42
|
msg_hash['json_data'] = JSON.generate(json_hash.as_json)
|
39
|
-
|
43
|
+
Topic.write_topic(topic, msg_hash)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.get_cmd_item(target_name, packet_name, param_name, type: :WITH_UNITS, scope: $cosmos_scope)
|
47
|
+
msg_id, msg_hash = Topic.get_newest_message("#{scope}__DECOMCMD__{#{target_name}}__#{packet_name}")
|
48
|
+
if msg_id
|
49
|
+
# TODO: We now have these reserved items directly on command packets
|
50
|
+
# Do we still calculate from msg_hash['time'] or use the times directly?
|
51
|
+
#
|
52
|
+
# if param_name == 'RECEIVED_TIMESECONDS' || param_name == 'PACKET_TIMESECONDS'
|
53
|
+
# Time.from_nsec_from_epoch(msg_hash['time'].to_i).to_f
|
54
|
+
# elsif param_name == 'RECEIVED_TIMEFORMATTED' || param_name == 'PACKET_TIMEFORMATTED'
|
55
|
+
# Time.from_nsec_from_epoch(msg_hash['time'].to_i).formatted
|
56
|
+
if param_name == 'RECEIVED_COUNT'
|
57
|
+
msg_hash['received_count'].to_i
|
58
|
+
else
|
59
|
+
json = msg_hash['json_data']
|
60
|
+
hash = JSON.parse(json)
|
61
|
+
# Start from the most complex down to the basic raw value
|
62
|
+
value = hash["#{param_name}__U"]
|
63
|
+
return value if value && type == :WITH_UNITS
|
64
|
+
|
65
|
+
value = hash["#{param_name}__F"]
|
66
|
+
return value if value && (type == :WITH_UNITS || type == :FORMATTED)
|
67
|
+
|
68
|
+
value = hash["#{param_name}__C"]
|
69
|
+
return value if value && (type == :WITH_UNITS || type == :FORMATTED || type == :CONVERTED)
|
70
|
+
|
71
|
+
return hash[param_name]
|
72
|
+
end
|
73
|
+
end
|
40
74
|
end
|
41
75
|
end
|
42
76
|
end
|