cosmos 5.0.2.pre.beta2 → 5.0.4
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/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
|