openc3 5.0.11 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Guardfile +3 -0
- data/LICENSE.txt +7 -5
- data/README.md +11 -9
- data/Rakefile +3 -0
- data/bin/cstol_converter +3 -0
- data/bin/openc3cli +29 -18
- data/bin/rubysloc +3 -0
- data/data/config/screen.yaml +10 -2
- data/data/config/target.yaml +1 -1
- data/data/config/widgets.yaml +6 -6
- data/ext/mkrf_conf.rb +3 -0
- data/ext/openc3/ext/array/array.c +3 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +3 -0
- data/ext/openc3/ext/config_parser/config_parser.c +3 -0
- data/ext/openc3/ext/crc/crc.c +3 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +3 -0
- data/ext/openc3/ext/packet/packet.c +3 -0
- data/ext/openc3/ext/platform/platform.c +3 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +3 -0
- data/ext/openc3/ext/string/string.c +3 -0
- data/ext/openc3/ext/structure/structure.c +3 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +3 -0
- data/ext/openc3/ext/telemetry/telemetry.c +3 -0
- data/lib/cosmos.rb +3 -0
- data/lib/cosmosc2.rb +3 -0
- data/lib/openc3/accessors/accessor.rb +3 -0
- data/lib/openc3/accessors/binary_accessor.rb +3 -0
- data/lib/openc3/accessors/cbor_accessor.rb +3 -0
- data/lib/openc3/accessors/html_accessor.rb +3 -0
- data/lib/openc3/accessors/json_accessor.rb +4 -1
- data/lib/openc3/accessors/xml_accessor.rb +3 -0
- data/lib/openc3/accessors.rb +3 -0
- data/lib/openc3/api/api.rb +3 -0
- data/lib/openc3/api/authorized_api.rb +3 -0
- data/lib/openc3/api/cmd_api.rb +6 -3
- data/lib/openc3/api/config_api.rb +3 -0
- data/lib/openc3/api/interface_api.rb +6 -2
- data/lib/openc3/api/limits_api.rb +54 -61
- data/lib/openc3/api/router_api.rb +6 -3
- data/lib/openc3/api/settings_api.rb +3 -0
- data/lib/openc3/api/target_api.rb +3 -0
- data/lib/openc3/api/tlm_api.rb +27 -32
- data/lib/openc3/bridge/bridge.rb +3 -0
- data/lib/openc3/bridge/bridge_config.rb +3 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +3 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +3 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +3 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +3 -0
- data/lib/openc3/config/config_parser.rb +3 -0
- data/lib/openc3/config/meta_config_parser.rb +3 -0
- data/lib/openc3/conversions/conversion.rb +3 -0
- data/lib/openc3/conversions/generic_conversion.rb +3 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +3 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +3 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +3 -0
- data/lib/openc3/conversions/processor_conversion.rb +3 -0
- data/lib/openc3/conversions/received_count_conversion.rb +3 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +3 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +3 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +3 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +3 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +3 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +3 -0
- data/lib/openc3/conversions.rb +3 -0
- data/lib/openc3/core_ext/array.rb +3 -0
- data/lib/openc3/core_ext/binding.rb +3 -0
- data/lib/openc3/core_ext/class.rb +3 -0
- data/lib/openc3/core_ext/exception.rb +3 -0
- data/lib/openc3/core_ext/file.rb +3 -0
- data/lib/openc3/core_ext/hash.rb +3 -0
- data/lib/openc3/core_ext/io.rb +3 -0
- data/lib/openc3/core_ext/kernel.rb +3 -0
- data/lib/openc3/core_ext/math.rb +3 -0
- data/lib/openc3/core_ext/matrix.rb +3 -0
- data/lib/openc3/core_ext/objectspace.rb +3 -0
- data/lib/openc3/core_ext/openc3_io.rb +3 -0
- data/lib/openc3/core_ext/range.rb +3 -0
- data/lib/openc3/core_ext/socket.rb +3 -0
- data/lib/openc3/core_ext/string.rb +3 -0
- data/lib/openc3/core_ext/stringio.rb +3 -0
- data/lib/openc3/core_ext/tempfile.rb +3 -0
- data/lib/openc3/core_ext/time.rb +3 -0
- data/lib/openc3/core_ext.rb +3 -0
- data/lib/openc3/interfaces/interface.rb +3 -0
- data/lib/openc3/interfaces/linc_interface.rb +3 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +3 -0
- data/lib/openc3/interfaces/serial_interface.rb +3 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +3 -0
- data/lib/openc3/interfaces/stream_interface.rb +3 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +3 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -0
- data/lib/openc3/interfaces/udp_interface.rb +3 -0
- data/lib/openc3/interfaces.rb +3 -0
- data/lib/openc3/io/buffered_file.rb +3 -0
- data/lib/openc3/io/io_multiplexer.rb +8 -0
- data/lib/openc3/io/json_api_object.rb +5 -2
- data/lib/openc3/io/json_drb.rb +3 -0
- data/lib/openc3/io/json_drb_object.rb +5 -2
- data/lib/openc3/io/json_drb_rack.rb +3 -0
- data/lib/openc3/io/json_rpc.rb +8 -3
- data/lib/openc3/io/openc3_snmp.rb +3 -0
- data/lib/openc3/io/posix_serial_driver.rb +3 -0
- data/lib/openc3/io/raw_logger.rb +3 -0
- data/lib/openc3/io/raw_logger_pair.rb +3 -0
- data/lib/openc3/io/serial_driver.rb +3 -0
- data/lib/openc3/io/stderr.rb +3 -0
- data/lib/openc3/io/stdout.rb +3 -0
- data/lib/openc3/io/udp_sockets.rb +3 -0
- data/lib/openc3/io/win32_serial_driver.rb +3 -0
- data/lib/openc3/logs/buffered_packet_log_reader.rb +65 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +120 -0
- data/lib/openc3/logs/log_writer.rb +95 -40
- data/lib/openc3/logs/packet_log_constants.rb +9 -0
- data/lib/openc3/logs/packet_log_reader.rb +34 -3
- data/lib/openc3/logs/packet_log_writer.rb +85 -18
- data/lib/openc3/logs/text_log_writer.rb +9 -5
- data/lib/openc3/logs.rb +8 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +18 -18
- data/lib/openc3/microservices/decom_microservice.rb +30 -24
- data/lib/openc3/microservices/interface_microservice.rb +136 -91
- data/lib/openc3/microservices/log_microservice.rb +35 -13
- data/lib/openc3/microservices/microservice.rb +16 -14
- data/lib/openc3/microservices/plugin_microservice.rb +3 -1
- data/lib/openc3/microservices/reaction_microservice.rb +4 -1
- data/lib/openc3/microservices/reducer_microservice.rb +332 -149
- data/lib/openc3/microservices/router_microservice.rb +3 -0
- data/lib/openc3/microservices/text_log_microservice.rb +22 -7
- data/lib/openc3/microservices/timeline_microservice.rb +4 -1
- data/lib/openc3/microservices/trigger_group_microservice.rb +3 -0
- data/lib/openc3/models/activity_model.rb +3 -0
- data/lib/openc3/models/auth_model.rb +3 -0
- data/lib/openc3/models/cvt_model.rb +14 -5
- data/lib/openc3/models/environment_model.rb +3 -0
- data/lib/openc3/models/gem_model.rb +30 -51
- data/lib/openc3/models/info_model.rb +3 -0
- data/lib/openc3/models/interface_model.rb +3 -0
- data/lib/openc3/models/interface_status_model.rb +4 -1
- data/lib/openc3/models/metadata_model.rb +3 -0
- data/lib/openc3/models/metric_model.rb +3 -0
- data/lib/openc3/models/microservice_model.rb +9 -6
- data/lib/openc3/models/microservice_status_model.rb +4 -1
- data/lib/openc3/models/model.rb +3 -0
- data/lib/openc3/models/note_model.rb +3 -0
- data/lib/openc3/models/notification_model.rb +3 -0
- data/lib/openc3/models/ping_model.rb +3 -0
- data/lib/openc3/models/plugin_model.rb +20 -14
- data/lib/openc3/models/process_status_model.rb +4 -1
- data/lib/openc3/models/reaction_model.rb +3 -0
- data/lib/openc3/models/reducer_model.rb +31 -24
- data/lib/openc3/models/router_model.rb +3 -0
- data/lib/openc3/models/router_status_model.rb +3 -0
- data/lib/openc3/models/scope_model.rb +3 -4
- data/lib/openc3/models/settings_model.rb +3 -0
- data/lib/openc3/models/sorted_model.rb +3 -0
- data/lib/openc3/models/target_model.rb +61 -94
- data/lib/openc3/models/timeline_model.rb +4 -1
- data/lib/openc3/models/tool_config_model.rb +3 -0
- data/lib/openc3/models/tool_model.rb +11 -9
- data/lib/openc3/models/trigger_group_model.rb +3 -0
- data/lib/openc3/models/trigger_model.rb +3 -0
- data/lib/openc3/models/widget_model.rb +18 -11
- data/lib/openc3/operators/microservice_operator.rb +3 -0
- data/lib/openc3/operators/operator.rb +105 -34
- data/lib/openc3/packets/commands.rb +3 -0
- data/lib/openc3/packets/json_packet.rb +87 -14
- data/lib/openc3/packets/limits.rb +4 -1
- data/lib/openc3/packets/limits_response.rb +3 -0
- data/lib/openc3/packets/packet.rb +5 -1
- data/lib/openc3/packets/packet_config.rb +3 -0
- data/lib/openc3/packets/packet_item.rb +9 -3
- data/lib/openc3/packets/packet_item_limits.rb +3 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +3 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +3 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +3 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +3 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +3 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +3 -0
- data/lib/openc3/packets/parsers/state_parser.rb +3 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +3 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +3 -0
- data/lib/openc3/packets/structure.rb +3 -0
- data/lib/openc3/packets/structure_item.rb +3 -0
- data/lib/openc3/packets/telemetry.rb +3 -0
- data/lib/openc3/processors/processor.rb +3 -0
- data/lib/openc3/processors/statistics_processor.rb +3 -0
- data/lib/openc3/processors/watermark_processor.rb +3 -0
- data/lib/openc3/processors.rb +3 -0
- data/lib/openc3/script/api_shared.rb +35 -6
- data/lib/openc3/script/calendar.rb +3 -0
- data/lib/openc3/script/commands.rb +3 -0
- data/lib/openc3/script/exceptions.rb +3 -0
- data/lib/openc3/script/extract.rb +3 -0
- data/lib/openc3/script/limits.rb +3 -24
- data/lib/openc3/script/script.rb +11 -7
- data/lib/openc3/script/script_runner.rb +3 -0
- data/lib/openc3/script/storage.rb +33 -16
- data/lib/openc3/script/suite.rb +3 -0
- data/lib/openc3/script/suite_results.rb +3 -0
- data/lib/openc3/script/suite_runner.rb +3 -0
- data/lib/openc3/script/telemetry.rb +43 -0
- data/lib/openc3/script.rb +3 -0
- data/lib/openc3/streams/serial_stream.rb +3 -0
- data/lib/openc3/streams/stream.rb +3 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +3 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +3 -0
- data/lib/openc3/system/system.rb +23 -10
- data/lib/openc3/system/system_config.rb +3 -0
- data/lib/openc3/system/target.rb +3 -0
- data/lib/openc3/system.rb +3 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +3 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +3 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +3 -0
- data/lib/openc3/tools/table_manager/table.rb +3 -0
- data/lib/openc3/tools/table_manager/table_config.rb +3 -0
- data/lib/openc3/tools/table_manager/table_item.rb +3 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +3 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +3 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +3 -0
- data/lib/openc3/tools/test_runner/test.rb +3 -0
- data/lib/openc3/top_level.rb +3 -0
- data/lib/openc3/topics/autonomic_topic.rb +3 -0
- data/lib/openc3/topics/calendar_topic.rb +3 -0
- data/lib/openc3/topics/command_decom_topic.rb +4 -1
- data/lib/openc3/topics/command_topic.rb +6 -1
- data/lib/openc3/topics/config_topic.rb +3 -0
- data/lib/openc3/topics/interface_topic.rb +9 -2
- data/lib/openc3/topics/limits_event_topic.rb +144 -10
- data/lib/openc3/topics/notifications_topic.rb +3 -0
- data/lib/openc3/topics/router_topic.rb +10 -3
- data/lib/openc3/topics/telemetry_decom_topic.rb +26 -20
- data/lib/openc3/topics/telemetry_reduced_topics.rb +92 -0
- data/lib/openc3/topics/telemetry_topic.rb +5 -2
- data/lib/openc3/topics/timeline_topic.rb +3 -0
- data/lib/openc3/topics/topic.rb +3 -0
- data/lib/openc3/utilities/authentication.rb +3 -0
- data/lib/openc3/utilities/authorization.rb +3 -0
- data/lib/openc3/utilities/aws_bucket.rb +199 -0
- data/lib/openc3/utilities/bucket.rb +82 -0
- data/lib/openc3/utilities/bucket_file_cache.rb +264 -0
- data/lib/openc3/utilities/bucket_utilities.rb +109 -0
- data/lib/openc3/utilities/crc.rb +3 -0
- data/lib/openc3/utilities/csv.rb +3 -0
- data/lib/openc3/utilities/local_bucket.rb +28 -0
- data/lib/openc3/utilities/local_mode.rb +47 -61
- data/lib/openc3/utilities/logger.rb +7 -1
- data/lib/openc3/utilities/message_log.rb +7 -4
- data/lib/openc3/utilities/metric.rb +4 -1
- data/lib/openc3/utilities/open_telemetry.rb +96 -0
- data/lib/openc3/utilities/process_manager.rb +3 -0
- data/lib/openc3/utilities/quaternion.rb +3 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +3 -0
- data/lib/openc3/utilities/s3_autoload.rb +3 -3
- data/lib/openc3/utilities/simulated_target.rb +3 -0
- data/lib/openc3/utilities/sleeper.rb +3 -0
- data/lib/openc3/utilities/store.rb +3 -0
- data/lib/openc3/utilities/store_autoload.rb +30 -23
- data/lib/openc3/utilities/target_file.rb +70 -83
- data/lib/openc3/utilities/zip.rb +3 -0
- data/lib/openc3/utilities.rb +3 -0
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3/win32/excel.rb +3 -0
- data/lib/openc3/win32/win32.rb +3 -0
- data/lib/openc3/win32/win32_main.rb +3 -0
- data/lib/openc3.rb +3 -0
- data/tasks/gemfile_stats.rake +3 -0
- data/tasks/spec.rake +3 -0
- data/templates/plugin-template/plugin.gemspec +1 -1
- metadata +112 -6
- data/lib/openc3/utilities/s3.rb +0 -220
- data/lib/openc3/utilities/s3_file_cache.rb +0 -274
data/lib/openc3/utilities/s3.rb
DELETED
@@ -1,220 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
4
|
-
# All Rights Reserved.
|
5
|
-
#
|
6
|
-
# This program is free software; you can modify and/or redistribute it
|
7
|
-
# under the terms of the GNU Affero General Public License
|
8
|
-
# as published by the Free Software Foundation; version 3 with
|
9
|
-
# attribution addendums as found in the LICENSE.txt
|
10
|
-
#
|
11
|
-
# This program is distributed in the hope that it will be useful,
|
12
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
-
# GNU Affero General Public License for more details.
|
15
|
-
|
16
|
-
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright 2022, OpenC3, Inc.
|
18
|
-
# All Rights Reserved
|
19
|
-
|
20
|
-
module Aws
|
21
|
-
autoload(:S3, 'openc3/utilities/s3_autoload.rb')
|
22
|
-
end
|
23
|
-
require 'openc3/models/reducer_model'
|
24
|
-
|
25
|
-
module OpenC3
|
26
|
-
class S3Utilities
|
27
|
-
def self.put_object_and_check(params = {})
|
28
|
-
rubys3_client = Aws::S3::Client.new
|
29
|
-
rubys3_client.put_object(params)
|
30
|
-
# polls in a loop, sleeping between attempts
|
31
|
-
rubys3_client.wait_until(:object_exists,
|
32
|
-
{
|
33
|
-
bucket: params[:bucket],
|
34
|
-
key: params[:key]
|
35
|
-
},
|
36
|
-
{
|
37
|
-
max_attempts: 30,
|
38
|
-
delay: 0.1, # seconds
|
39
|
-
}
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.list_files_before_time(bucket, prefix, time)
|
44
|
-
rubys3_client = Aws::S3::Client.new
|
45
|
-
oldest_list = []
|
46
|
-
total_size = 0
|
47
|
-
|
48
|
-
# Return nothing if bucket doesn't exist (it won't at the very beginning)
|
49
|
-
begin
|
50
|
-
rubys3_client.head_bucket(bucket: bucket)
|
51
|
-
rescue Aws::S3::Errors::NotFound
|
52
|
-
return total_size, oldest_list
|
53
|
-
end
|
54
|
-
|
55
|
-
# Get List of Packet Names - Assumes prefix gets us to a folder of packet names
|
56
|
-
token = nil
|
57
|
-
folder_list = []
|
58
|
-
while true
|
59
|
-
resp = rubys3_client.list_objects_v2({
|
60
|
-
bucket: bucket,
|
61
|
-
max_keys: 1000,
|
62
|
-
prefix: prefix,
|
63
|
-
delimiter: '/',
|
64
|
-
continuation_token: token
|
65
|
-
})
|
66
|
-
|
67
|
-
resp.common_prefixes.each do |item|
|
68
|
-
folder_list << item.prefix
|
69
|
-
end
|
70
|
-
break unless resp.is_truncated
|
71
|
-
token = resp.next_continuation_token
|
72
|
-
end
|
73
|
-
|
74
|
-
# Go through each folder and keep files that end before time
|
75
|
-
folder_list.each do |folder|
|
76
|
-
token = nil
|
77
|
-
next_folder = false
|
78
|
-
while true
|
79
|
-
resp = rubys3_client.list_objects_v2({
|
80
|
-
bucket: bucket,
|
81
|
-
max_keys: 1000,
|
82
|
-
prefix: folder,
|
83
|
-
continuation_token: token
|
84
|
-
})
|
85
|
-
resp.contents.each do |item|
|
86
|
-
t = item.key.split('__')[1]
|
87
|
-
file_end_time = Time.utc(t[0..3], t[4..5], t[6..7], t[8..9], t[10..11], t[12..13])
|
88
|
-
if file_end_time < time
|
89
|
-
oldest_list << item
|
90
|
-
total_size += item.size
|
91
|
-
else
|
92
|
-
next_folder = true
|
93
|
-
break
|
94
|
-
end
|
95
|
-
end
|
96
|
-
break if !resp.is_truncated or next_folder
|
97
|
-
|
98
|
-
token = resp.next_continuation_token
|
99
|
-
end
|
100
|
-
end
|
101
|
-
return total_size, oldest_list
|
102
|
-
end
|
103
|
-
|
104
|
-
def self.get_total_size_and_oldest_list(bucket, prefix, max_list_length = 10000)
|
105
|
-
rubys3_client = Aws::S3::Client.new
|
106
|
-
oldest_list = []
|
107
|
-
total_size = 0
|
108
|
-
|
109
|
-
# Return nothing if bucket doesn't exist (it won't at the very beginning)
|
110
|
-
begin
|
111
|
-
rubys3_client.head_bucket(bucket: bucket)
|
112
|
-
rescue Aws::S3::Errors::NotFound
|
113
|
-
return total_size, oldest_list
|
114
|
-
end
|
115
|
-
|
116
|
-
# Get List of Files from S3
|
117
|
-
token = nil
|
118
|
-
while true
|
119
|
-
resp = rubys3_client.list_objects_v2({
|
120
|
-
bucket: bucket,
|
121
|
-
max_keys: 1000,
|
122
|
-
prefix: prefix,
|
123
|
-
continuation_token: token
|
124
|
-
})
|
125
|
-
resp.contents.each do |item|
|
126
|
-
total_size += item.size
|
127
|
-
end
|
128
|
-
oldest_list.concat(resp.contents)
|
129
|
-
oldest_list.sort! { |a, b| File.basename(a.key) <=> File.basename(b.key) }
|
130
|
-
oldest_list = oldest_list[0..(max_list_length - 1)]
|
131
|
-
break unless resp.is_truncated
|
132
|
-
|
133
|
-
token = resp.next_continuation_token
|
134
|
-
end
|
135
|
-
return total_size, oldest_list
|
136
|
-
end
|
137
|
-
|
138
|
-
def self.move_log_file_to_s3(filename, s3_key, metadata: {})
|
139
|
-
Thread.new do
|
140
|
-
rubys3_client = Aws::S3::Client.new
|
141
|
-
|
142
|
-
# Ensure logs bucket exists
|
143
|
-
begin
|
144
|
-
rubys3_client.head_bucket(bucket: 'logs')
|
145
|
-
rescue Aws::S3::Errors::NotFound
|
146
|
-
rubys3_client.create_bucket(bucket: 'logs')
|
147
|
-
end
|
148
|
-
|
149
|
-
# Write to S3 Bucket
|
150
|
-
File.open(filename, 'rb') do |read_file|
|
151
|
-
rubys3_client.put_object(bucket: 'logs', key: s3_key, body: read_file, metadata: metadata)
|
152
|
-
end
|
153
|
-
Logger.debug "logs/#{s3_key} written to S3"
|
154
|
-
ReducerModel.add_file(s3_key) # Record the new file for data reduction
|
155
|
-
|
156
|
-
File.delete(filename)
|
157
|
-
rescue => err
|
158
|
-
Logger.error("Error saving log file to bucket: #{filename}\n#{err.formatted}")
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def self.ensure_public_bucket(bucket_name)
|
163
|
-
rubys3_client = Aws::S3::Client.new
|
164
|
-
begin
|
165
|
-
rubys3_client.head_bucket(bucket: bucket_name)
|
166
|
-
rescue Aws::S3::Errors::NotFound
|
167
|
-
rubys3_client.create_bucket(bucket: bucket_name)
|
168
|
-
|
169
|
-
policy = <<~EOL
|
170
|
-
{
|
171
|
-
"Version": "2012-10-17",
|
172
|
-
"Statement": [
|
173
|
-
{
|
174
|
-
"Action": [
|
175
|
-
"s3:GetBucketLocation",
|
176
|
-
"s3:ListBucket"
|
177
|
-
],
|
178
|
-
"Effect": "Allow",
|
179
|
-
"Principal": {
|
180
|
-
"AWS": [
|
181
|
-
"*"
|
182
|
-
]
|
183
|
-
},
|
184
|
-
"Resource": [
|
185
|
-
"arn:aws:s3:::#{bucket_name}"
|
186
|
-
],
|
187
|
-
"Sid": ""
|
188
|
-
},
|
189
|
-
{
|
190
|
-
"Action": [
|
191
|
-
"s3:GetObject"
|
192
|
-
],
|
193
|
-
"Effect": "Allow",
|
194
|
-
"Principal": {
|
195
|
-
"AWS": [
|
196
|
-
"*"
|
197
|
-
]
|
198
|
-
},
|
199
|
-
"Resource": [
|
200
|
-
"arn:aws:s3:::#{bucket_name}/*"
|
201
|
-
],
|
202
|
-
"Sid": ""
|
203
|
-
}
|
204
|
-
]
|
205
|
-
}
|
206
|
-
EOL
|
207
|
-
|
208
|
-
rubys3_client.put_bucket_policy({ bucket: bucket_name, policy: policy })
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def self.get_cache_control(filename)
|
213
|
-
# Allow caching for files that have a filename versioning strategy
|
214
|
-
has_version_number = /(-|_|\.)\d+(-|_|\.)\d+(-|_|\.)\d+\./.match(@filename)
|
215
|
-
has_content_hash = /\.[a-f0-9]{20}\./.match(@filename)
|
216
|
-
return nil if has_version_number or has_content_hash
|
217
|
-
return 'no-cache'
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
@@ -1,274 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
4
|
-
# All Rights Reserved.
|
5
|
-
#
|
6
|
-
# This program is free software; you can modify and/or redistribute it
|
7
|
-
# under the terms of the GNU Affero General Public License
|
8
|
-
# as published by the Free Software Foundation; version 3 with
|
9
|
-
# attribution addendums as found in the LICENSE.txt
|
10
|
-
#
|
11
|
-
# This program is distributed in the hope that it will be useful,
|
12
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
-
# GNU Affero General Public License for more details.
|
15
|
-
|
16
|
-
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright 2022, OpenC3, Inc.
|
18
|
-
# All Rights Reserved
|
19
|
-
|
20
|
-
require 'fileutils'
|
21
|
-
require 'tmpdir'
|
22
|
-
require 'openc3'
|
23
|
-
require 'openc3/utilities/s3'
|
24
|
-
|
25
|
-
class S3File
|
26
|
-
attr_reader :s3_path
|
27
|
-
attr_reader :local_path
|
28
|
-
attr_reader :reservation_count
|
29
|
-
attr_reader :size
|
30
|
-
attr_reader :error
|
31
|
-
attr_accessor :priority
|
32
|
-
|
33
|
-
def initialize(s3_path, size = 0, priority = 0)
|
34
|
-
@rubys3_client = Aws::S3::Client.new
|
35
|
-
begin
|
36
|
-
@rubys3_client.head_bucket(bucket: 'logs')
|
37
|
-
rescue Aws::S3::Errors::NotFound
|
38
|
-
@rubys3_client.create_bucket(bucket: 'logs')
|
39
|
-
end
|
40
|
-
|
41
|
-
@s3_path = s3_path
|
42
|
-
@local_path = nil
|
43
|
-
@reservation_count = 0
|
44
|
-
@size = size
|
45
|
-
@priority = priority
|
46
|
-
@error = nil
|
47
|
-
@mutex = Mutex.new
|
48
|
-
end
|
49
|
-
|
50
|
-
def retrieve
|
51
|
-
local_path = "#{S3FileCache.instance.cache_dir}/#{File.basename(@s3_path)}"
|
52
|
-
OpenC3::Logger.debug "Retrieving #{@s3_path} from logs bucket"
|
53
|
-
@rubys3_client.get_object(bucket: "logs", key: @s3_path, response_target: local_path)
|
54
|
-
if File.exist?(local_path)
|
55
|
-
@size = File.size(local_path)
|
56
|
-
@local_path = local_path
|
57
|
-
end
|
58
|
-
rescue => err
|
59
|
-
@error = err
|
60
|
-
OpenC3::Logger.error "Failed to retrieve #{@s3_path}\n#{err.formatted}"
|
61
|
-
raise err
|
62
|
-
end
|
63
|
-
|
64
|
-
def reserve
|
65
|
-
@mutex.synchronize do
|
66
|
-
@reservation_count += 1
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def unreserve
|
71
|
-
@mutex.synchronize do
|
72
|
-
@reservation_count -= 1
|
73
|
-
delete() if @reservation_count <= 0
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# private
|
78
|
-
|
79
|
-
def delete
|
80
|
-
if @local_path and File.exist?(local_path)
|
81
|
-
File.delete(@local_path)
|
82
|
-
@local_path = nil
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
class S3FileCollection
|
88
|
-
def initialize
|
89
|
-
@array = []
|
90
|
-
@mutex = Mutex.new
|
91
|
-
end
|
92
|
-
|
93
|
-
def add(s3_path, size, priority)
|
94
|
-
@mutex.synchronize do
|
95
|
-
@array.each do |file|
|
96
|
-
if file.s3_path == s3_path
|
97
|
-
file.priority = priority if priority < file.priority
|
98
|
-
@array.sort! {|a,b| a.priority <=> b.priority}
|
99
|
-
return file
|
100
|
-
end
|
101
|
-
end
|
102
|
-
file = S3File.new(s3_path, size, priority)
|
103
|
-
@array << file
|
104
|
-
@array.sort! {|a,b| a.priority <=> b.priority}
|
105
|
-
return file
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def length
|
110
|
-
@array.length
|
111
|
-
end
|
112
|
-
|
113
|
-
def get(local_path)
|
114
|
-
@mutex.synchronize do
|
115
|
-
@array.each do |file|
|
116
|
-
return file if file.local_path == local_path
|
117
|
-
end
|
118
|
-
end
|
119
|
-
return nil
|
120
|
-
end
|
121
|
-
|
122
|
-
def get_next_to_retrieve
|
123
|
-
@mutex.synchronize do
|
124
|
-
@array.each do |file|
|
125
|
-
return file unless file.local_path
|
126
|
-
end
|
127
|
-
end
|
128
|
-
return nil
|
129
|
-
end
|
130
|
-
|
131
|
-
def current_disk_usage
|
132
|
-
@mutex.synchronize do
|
133
|
-
total_size = 0
|
134
|
-
@array.each do |file|
|
135
|
-
total_size += file.size if file.local_path
|
136
|
-
end
|
137
|
-
return total_size
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
class S3FileCache
|
143
|
-
MAX_DISK_USAGE = 20_000_000_000 # 20 GB
|
144
|
-
TIMESTAMP_FORMAT = "%Y%m%d%H%M%S%N" # TODO: get from different class?
|
145
|
-
|
146
|
-
attr_reader :cache_dir
|
147
|
-
|
148
|
-
@@instance = nil
|
149
|
-
@@mutex = Mutex.new
|
150
|
-
|
151
|
-
def self.instance
|
152
|
-
return @@instance if @@instance
|
153
|
-
@@mutex.synchronize do
|
154
|
-
@@instance ||= S3FileCache.new
|
155
|
-
end
|
156
|
-
@@instance
|
157
|
-
end
|
158
|
-
|
159
|
-
def initialize(name = 'default', max_disk_usage = MAX_DISK_USAGE)
|
160
|
-
@max_disk_usage = max_disk_usage
|
161
|
-
|
162
|
-
@rubys3_client = Aws::S3::Client.new
|
163
|
-
begin
|
164
|
-
@rubys3_client.head_bucket(bucket: 'logs')
|
165
|
-
rescue Aws::S3::Errors::NotFound
|
166
|
-
@rubys3_client.create_bucket(bucket: 'logs')
|
167
|
-
end
|
168
|
-
|
169
|
-
# Create local file cache location
|
170
|
-
@cache_dir = Dir.mktmpdir
|
171
|
-
FileUtils.mkdir_p(@cache_dir)
|
172
|
-
at_exit do
|
173
|
-
FileUtils.remove_dir(@cache_dir, true)
|
174
|
-
end
|
175
|
-
|
176
|
-
@cached_files = S3FileCollection.new
|
177
|
-
|
178
|
-
@thread = Thread.new do
|
179
|
-
while true
|
180
|
-
file = @cached_files.get_next_to_retrieve
|
181
|
-
# OpenC3::Logger.debug "Next file: #{file}"
|
182
|
-
if file and (file.size + @cached_files.current_disk_usage()) <= @max_disk_usage
|
183
|
-
begin
|
184
|
-
file.retrieve
|
185
|
-
rescue
|
186
|
-
# Will be automatically retried
|
187
|
-
end
|
188
|
-
else
|
189
|
-
sleep(1)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
rescue => err
|
193
|
-
OpenC3::Logger.error "S3FileCache thread unexpectedly died\n#{err.formatted}"
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
def reserve_file(cmd_or_tlm, target_name, packet_name, start_time_nsec, end_time_nsec, type = :DECOM, timeout = 60, scope:)
|
198
|
-
# OpenC3::Logger.debug "reserve_file #{cmd_or_tlm}:#{target_name}:#{packet_name} start:#{start_time_nsec / 1_000_000_000} end:#{end_time_nsec / 1_000_000_000} type:#{type} timeout:#{timeout}"
|
199
|
-
# Get List of Files from S3
|
200
|
-
total_resp = []
|
201
|
-
token = nil
|
202
|
-
dates = []
|
203
|
-
cur_date = Time.at(start_time_nsec / Time::NSEC_PER_SECOND).beginning_of_day
|
204
|
-
end_date = Time.at(end_time_nsec / Time::NSEC_PER_SECOND).beginning_of_day
|
205
|
-
cur_date -= 1.day # start looking in the folder for the day before because log files can span across midnight
|
206
|
-
while cur_date <= end_date
|
207
|
-
dates << cur_date.strftime("%Y%m%d")
|
208
|
-
cur_date += 1.day
|
209
|
-
end
|
210
|
-
prefixes = []
|
211
|
-
dates.each do |date|
|
212
|
-
while true
|
213
|
-
prefixes << "#{scope}/#{type.to_s.downcase}_logs/#{cmd_or_tlm.to_s.downcase}/#{target_name}/#{packet_name}/#{date}"
|
214
|
-
resp = @rubys3_client.list_objects_v2({
|
215
|
-
bucket: "logs",
|
216
|
-
max_keys: 1000,
|
217
|
-
prefix: prefixes[-1],
|
218
|
-
continuation_token: token
|
219
|
-
})
|
220
|
-
total_resp.concat(resp.contents)
|
221
|
-
break unless resp.is_truncated
|
222
|
-
token = resp.next_continuation_token
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
# Add to needed files
|
227
|
-
files = []
|
228
|
-
total_resp.each_with_index do |item, index|
|
229
|
-
s3_path = item.key
|
230
|
-
if file_in_time_range(s3_path, start_time_nsec, end_time_nsec)
|
231
|
-
file = @cached_files.add(s3_path, item.size, index)
|
232
|
-
files << file
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
# Wait for first file retrieval
|
237
|
-
if files.length > 0
|
238
|
-
wait_start = Time.now
|
239
|
-
file = files[0]
|
240
|
-
file.reserve
|
241
|
-
while (Time.now - wait_start) < timeout
|
242
|
-
return file.local_path if file.local_path
|
243
|
-
sleep(1)
|
244
|
-
end
|
245
|
-
# Remove reservations if we timeout
|
246
|
-
file.unreserve
|
247
|
-
else
|
248
|
-
OpenC3::Logger.info "No files found for #{prefixes}"
|
249
|
-
end
|
250
|
-
|
251
|
-
return nil
|
252
|
-
end
|
253
|
-
|
254
|
-
def unreserve_file(filename)
|
255
|
-
@@mutex.synchronize do
|
256
|
-
file = @cached_files.get(filename)
|
257
|
-
file.unreserve if file
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
# private
|
262
|
-
|
263
|
-
def file_in_time_range(s3_path, start_time_nsec, end_time_nsec)
|
264
|
-
basename = File.basename(s3_path)
|
265
|
-
file_start_timestamp, file_end_timestamp, other = basename.split("__")
|
266
|
-
file_start_time_nsec = DateTime.strptime(file_start_timestamp, TIMESTAMP_FORMAT).to_f * Time::NSEC_PER_SECOND
|
267
|
-
file_end_time_nsec = DateTime.strptime(file_end_timestamp, TIMESTAMP_FORMAT).to_f * Time::NSEC_PER_SECOND
|
268
|
-
if (start_time_nsec < file_end_time_nsec) and (end_time_nsec >= file_start_time_nsec)
|
269
|
-
return true
|
270
|
-
else
|
271
|
-
return false
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|