openc3 5.0.6
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 +7 -0
- data/Gemfile +18 -0
- data/Guardfile +35 -0
- data/LICENSE.txt +727 -0
- data/README.md +37 -0
- data/Rakefile +131 -0
- data/bin/cstol_converter +1178 -0
- data/bin/openc3cli +531 -0
- data/bin/rubysloc +139 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +214 -0
- data/data/config/_interfaces.yaml.err +1017 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +60 -0
- data/data/config/cmd_tlm_server.yaml +136 -0
- data/data/config/command.yaml +44 -0
- data/data/config/command_modifiers.yaml +160 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/interface_modifiers.yaml +104 -0
- data/data/config/item_modifiers.yaml +221 -0
- data/data/config/microservice.yaml +78 -0
- data/data/config/param_item_modifiers.yaml +52 -0
- data/data/config/parameter_modifiers.yaml +200 -0
- data/data/config/plugins.yaml +80 -0
- data/data/config/protocols.yaml +290 -0
- data/data/config/screen.yaml +147 -0
- data/data/config/table_manager.yaml +89 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +142 -0
- data/data/config/target_config.yaml +94 -0
- data/data/config/telemetry.yaml +87 -0
- data/data/config/telemetry_modifiers.yaml +159 -0
- data/data/config/tool.yaml +63 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1505 -0
- data/ext/mkrf_conf.rb +49 -0
- data/ext/openc3/ext/array/array.c +122 -0
- data/ext/openc3/ext/array/extconf.rb +13 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
- data/ext/openc3/ext/config_parser/config_parser.c +280 -0
- data/ext/openc3/ext/config_parser/extconf.rb +13 -0
- data/ext/openc3/ext/crc/crc.c +351 -0
- data/ext/openc3/ext/crc/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
- data/ext/openc3/ext/packet/extconf.rb +13 -0
- data/ext/openc3/ext/packet/packet.c +318 -0
- data/ext/openc3/ext/platform/extconf.rb +13 -0
- data/ext/openc3/ext/platform/platform.c +134 -0
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
- data/ext/openc3/ext/string/extconf.rb +13 -0
- data/ext/openc3/ext/string/string.c +63 -0
- data/ext/openc3/ext/structure/structure.c +1719 -0
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
- data/ext/openc3/ext/telemetry/extconf.rb +13 -0
- data/ext/openc3/ext/telemetry/telemetry.c +336 -0
- data/lib/cosmos.rb +20 -0
- data/lib/cosmosc2.rb +20 -0
- data/lib/openc3/api/api.rb +39 -0
- data/lib/openc3/api/authorized_api.rb +30 -0
- data/lib/openc3/api/cmd_api.rb +451 -0
- data/lib/openc3/api/config_api.rb +58 -0
- data/lib/openc3/api/interface_api.rb +117 -0
- data/lib/openc3/api/limits_api.rb +375 -0
- data/lib/openc3/api/router_api.rb +117 -0
- data/lib/openc3/api/settings_api.rb +70 -0
- data/lib/openc3/api/target_api.rb +78 -0
- data/lib/openc3/api/tlm_api.rb +455 -0
- data/lib/openc3/bridge/bridge.rb +54 -0
- data/lib/openc3/bridge/bridge_config.rb +167 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
- data/lib/openc3/config/config_parser.rb +549 -0
- data/lib/openc3/config/meta_config_parser.rb +74 -0
- data/lib/openc3/conversions/conversion.rb +70 -0
- data/lib/openc3/conversions/generic_conversion.rb +83 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
- data/lib/openc3/conversions/processor_conversion.rb +70 -0
- data/lib/openc3/conversions/received_count_conversion.rb +38 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
- data/lib/openc3/conversions.rb +34 -0
- data/lib/openc3/core_ext/array.rb +416 -0
- data/lib/openc3/core_ext/binding.rb +29 -0
- data/lib/openc3/core_ext/class.rb +72 -0
- data/lib/openc3/core_ext/exception.rb +61 -0
- data/lib/openc3/core_ext/file.rb +83 -0
- data/lib/openc3/core_ext/hash.rb +37 -0
- data/lib/openc3/core_ext/io.rb +134 -0
- data/lib/openc3/core_ext/kernel.rb +42 -0
- data/lib/openc3/core_ext/math.rb +128 -0
- data/lib/openc3/core_ext/matrix.rb +156 -0
- data/lib/openc3/core_ext/objectspace.rb +36 -0
- data/lib/openc3/core_ext/openc3_io.rb +57 -0
- data/lib/openc3/core_ext/range.rb +27 -0
- data/lib/openc3/core_ext/socket.rb +38 -0
- data/lib/openc3/core_ext/string.rb +389 -0
- data/lib/openc3/core_ext/stringio.rb +33 -0
- data/lib/openc3/core_ext/time.rb +508 -0
- data/lib/openc3/core_ext.rb +36 -0
- data/lib/openc3/interfaces/interface.rb +498 -0
- data/lib/openc3/interfaces/linc_interface.rb +475 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
- data/lib/openc3/interfaces/serial_interface.rb +94 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
- data/lib/openc3/interfaces/stream_interface.rb +81 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
- data/lib/openc3/interfaces/udp_interface.rb +169 -0
- data/lib/openc3/interfaces.rb +44 -0
- data/lib/openc3/io/buffered_file.rb +109 -0
- data/lib/openc3/io/io_multiplexer.rb +80 -0
- data/lib/openc3/io/json_api_object.rb +208 -0
- data/lib/openc3/io/json_drb.rb +335 -0
- data/lib/openc3/io/json_drb_object.rb +114 -0
- data/lib/openc3/io/json_drb_rack.rb +84 -0
- data/lib/openc3/io/json_rpc.rb +420 -0
- data/lib/openc3/io/openc3_snmp.rb +58 -0
- data/lib/openc3/io/posix_serial_driver.rb +156 -0
- data/lib/openc3/io/raw_logger.rb +167 -0
- data/lib/openc3/io/raw_logger_pair.rb +77 -0
- data/lib/openc3/io/serial_driver.rb +105 -0
- data/lib/openc3/io/stderr.rb +43 -0
- data/lib/openc3/io/stdout.rb +43 -0
- data/lib/openc3/io/udp_sockets.rb +194 -0
- data/lib/openc3/io/win32_serial_driver.rb +196 -0
- data/lib/openc3/logs/log_writer.rb +302 -0
- data/lib/openc3/logs/packet_log_constants.rb +62 -0
- data/lib/openc3/logs/packet_log_reader.rb +345 -0
- data/lib/openc3/logs/packet_log_writer.rb +299 -0
- data/lib/openc3/logs/text_log_writer.rb +68 -0
- data/lib/openc3/logs.rb +25 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
- data/lib/openc3/microservices/decom_microservice.rb +136 -0
- data/lib/openc3/microservices/interface_microservice.rb +532 -0
- data/lib/openc3/microservices/log_microservice.rb +108 -0
- data/lib/openc3/microservices/microservice.rb +204 -0
- data/lib/openc3/microservices/plugin_microservice.rb +43 -0
- data/lib/openc3/microservices/reaction_microservice.rb +541 -0
- data/lib/openc3/microservices/reducer_microservice.rb +313 -0
- data/lib/openc3/microservices/router_microservice.rb +44 -0
- data/lib/openc3/microservices/text_log_microservice.rb +84 -0
- data/lib/openc3/microservices/timeline_microservice.rb +363 -0
- data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
- data/lib/openc3/models/activity_model.rb +319 -0
- data/lib/openc3/models/auth_model.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +185 -0
- data/lib/openc3/models/environment_model.rb +58 -0
- data/lib/openc3/models/gem_model.rb +137 -0
- data/lib/openc3/models/info_model.rb +31 -0
- data/lib/openc3/models/interface_model.rb +281 -0
- data/lib/openc3/models/interface_status_model.rb +117 -0
- data/lib/openc3/models/metadata_model.rb +139 -0
- data/lib/openc3/models/metric_model.rb +59 -0
- data/lib/openc3/models/microservice_model.rb +206 -0
- data/lib/openc3/models/microservice_status_model.rb +74 -0
- data/lib/openc3/models/model.rb +204 -0
- data/lib/openc3/models/note_model.rb +122 -0
- data/lib/openc3/models/notification_model.rb +40 -0
- data/lib/openc3/models/ping_model.rb +35 -0
- data/lib/openc3/models/plugin_model.rb +292 -0
- data/lib/openc3/models/process_status_model.rb +76 -0
- data/lib/openc3/models/reaction_model.rb +322 -0
- data/lib/openc3/models/reducer_model.rb +65 -0
- data/lib/openc3/models/router_model.rb +35 -0
- data/lib/openc3/models/router_status_model.rb +27 -0
- data/lib/openc3/models/scope_model.rb +153 -0
- data/lib/openc3/models/settings_model.rb +55 -0
- data/lib/openc3/models/sorted_model.rb +167 -0
- data/lib/openc3/models/target_model.rb +759 -0
- data/lib/openc3/models/timeline_model.rb +154 -0
- data/lib/openc3/models/tool_config_model.rb +38 -0
- data/lib/openc3/models/tool_model.rb +262 -0
- data/lib/openc3/models/trigger_group_model.rb +186 -0
- data/lib/openc3/models/trigger_model.rb +330 -0
- data/lib/openc3/models/widget_model.rb +138 -0
- data/lib/openc3/operators/microservice_operator.rb +128 -0
- data/lib/openc3/operators/operator.rb +277 -0
- data/lib/openc3/packets/binary_accessor.rb +1207 -0
- data/lib/openc3/packets/commands.rb +373 -0
- data/lib/openc3/packets/json_packet.rb +134 -0
- data/lib/openc3/packets/limits.rb +271 -0
- data/lib/openc3/packets/limits_response.rb +53 -0
- data/lib/openc3/packets/packet.rb +1168 -0
- data/lib/openc3/packets/packet_config.rb +625 -0
- data/lib/openc3/packets/packet_item.rb +586 -0
- data/lib/openc3/packets/packet_item_limits.rb +162 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
- data/lib/openc3/packets/parsers/state_parser.rb +127 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
- data/lib/openc3/packets/structure.rb +553 -0
- data/lib/openc3/packets/structure_item.rb +365 -0
- data/lib/openc3/packets/telemetry.rb +487 -0
- data/lib/openc3/processors/processor.rb +86 -0
- data/lib/openc3/processors/statistics_processor.rb +82 -0
- data/lib/openc3/processors/watermark_processor.rb +58 -0
- data/lib/openc3/processors.rb +24 -0
- data/lib/openc3/script/api_shared.rb +828 -0
- data/lib/openc3/script/calendar.rb +89 -0
- data/lib/openc3/script/commands.rb +227 -0
- data/lib/openc3/script/exceptions.rb +29 -0
- data/lib/openc3/script/extract.rb +161 -0
- data/lib/openc3/script/limits.rb +60 -0
- data/lib/openc3/script/script.rb +299 -0
- data/lib/openc3/script/script_runner.rb +238 -0
- data/lib/openc3/script/storage.rb +146 -0
- data/lib/openc3/script/suite.rb +542 -0
- data/lib/openc3/script/suite_results.rb +196 -0
- data/lib/openc3/script/suite_runner.rb +217 -0
- data/lib/openc3/script.rb +21 -0
- data/lib/openc3/streams/serial_stream.rb +167 -0
- data/lib/openc3/streams/stream.rb +63 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
- data/lib/openc3/system/system.rb +127 -0
- data/lib/openc3/system/system_config.rb +411 -0
- data/lib/openc3/system/target.rb +269 -0
- data/lib/openc3/system.rb +24 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
- data/lib/openc3/tools/table_manager/table.rb +77 -0
- data/lib/openc3/tools/table_manager/table_config.rb +273 -0
- data/lib/openc3/tools/table_manager/table_item.rb +90 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
- data/lib/openc3/tools/test_runner/test.rb +67 -0
- data/lib/openc3/top_level.rb +595 -0
- data/lib/openc3/topics/autonomic_topic.rb +52 -0
- data/lib/openc3/topics/calendar_topic.rb +44 -0
- data/lib/openc3/topics/command_decom_topic.rb +76 -0
- data/lib/openc3/topics/command_topic.rb +83 -0
- data/lib/openc3/topics/config_topic.rb +68 -0
- data/lib/openc3/topics/interface_topic.rb +73 -0
- data/lib/openc3/topics/limits_event_topic.rb +109 -0
- data/lib/openc3/topics/notifications_topic.rb +28 -0
- data/lib/openc3/topics/router_topic.rb +85 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
- data/lib/openc3/topics/telemetry_topic.rb +36 -0
- data/lib/openc3/topics/timeline_topic.rb +45 -0
- data/lib/openc3/topics/topic.rb +53 -0
- data/lib/openc3/utilities/authentication.rb +141 -0
- data/lib/openc3/utilities/authorization.rb +51 -0
- data/lib/openc3/utilities/crc.rb +278 -0
- data/lib/openc3/utilities/csv.rb +153 -0
- data/lib/openc3/utilities/logger.rb +187 -0
- data/lib/openc3/utilities/message_log.rb +91 -0
- data/lib/openc3/utilities/metric.rb +141 -0
- data/lib/openc3/utilities/process_manager.rb +139 -0
- data/lib/openc3/utilities/quaternion.rb +257 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
- data/lib/openc3/utilities/s3.rb +202 -0
- data/lib/openc3/utilities/s3_autoload.rb +9 -0
- data/lib/openc3/utilities/s3_file_cache.rb +274 -0
- data/lib/openc3/utilities/simulated_target.rb +117 -0
- data/lib/openc3/utilities/sleeper.rb +51 -0
- data/lib/openc3/utilities/store.rb +23 -0
- data/lib/openc3/utilities/store_autoload.rb +237 -0
- data/lib/openc3/utilities/zip.rb +21 -0
- data/lib/openc3/utilities.rb +35 -0
- data/lib/openc3/version.rb +14 -0
- data/lib/openc3/win32/excel.rb +132 -0
- data/lib/openc3/win32/win32.rb +402 -0
- data/lib/openc3/win32/win32_main.rb +333 -0
- data/lib/openc3.rb +49 -0
- data/tasks/gemfile_stats.rake +113 -0
- data/tasks/spec.rake +30 -0
- data/templates/plugin-template/README.md +15 -0
- data/templates/plugin-template/Rakefile +12 -0
- data/templates/plugin-template/plugin.gemspec +23 -0
- data/templates/plugin-template/plugin.txt +9 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
- data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
- data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
- data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
- data/templates/plugin-template/targets/TARGET/target.txt +5 -0
- metadata +849 -0
|
@@ -0,0 +1,759 @@
|
|
|
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 'openc3/top_level'
|
|
21
|
+
require 'openc3/models/model'
|
|
22
|
+
require 'openc3/models/cvt_model'
|
|
23
|
+
require 'openc3/models/microservice_model'
|
|
24
|
+
require 'openc3/topics/limits_event_topic'
|
|
25
|
+
require 'openc3/topics/config_topic'
|
|
26
|
+
require 'openc3/system'
|
|
27
|
+
require 'openc3/utilities/s3'
|
|
28
|
+
require 'openc3/utilities/zip'
|
|
29
|
+
require 'fileutils'
|
|
30
|
+
require 'tmpdir'
|
|
31
|
+
|
|
32
|
+
module OpenC3
|
|
33
|
+
# Manages the target in Redis. It stores the target itself under the
|
|
34
|
+
# <SCOPE>__openc3_targets key under the target name field. All the command packets
|
|
35
|
+
# in the target are stored under the <SCOPE>__openc3cmd__<TARGET NAME> key and the
|
|
36
|
+
# telemetry under the <SCOPE>__openc3tlm__<TARGET NAME> key. Any new limits sets
|
|
37
|
+
# are merged into the <SCOPE>__limits_sets key as fields. Any new limits groups are
|
|
38
|
+
# created under <SCOPE>__limits_groups with field name. These Redis key/fields are
|
|
39
|
+
# all removed when the undeploy method is called.
|
|
40
|
+
class TargetModel < Model
|
|
41
|
+
PRIMARY_KEY = 'openc3_targets'
|
|
42
|
+
VALID_TYPES = %i(CMD TLM)
|
|
43
|
+
|
|
44
|
+
attr_accessor :folder_name
|
|
45
|
+
attr_accessor :requires
|
|
46
|
+
attr_accessor :ignored_parameters
|
|
47
|
+
attr_accessor :ignored_items
|
|
48
|
+
attr_accessor :limits_groups
|
|
49
|
+
attr_accessor :cmd_tlm_files
|
|
50
|
+
attr_accessor :cmd_unique_id_mode
|
|
51
|
+
attr_accessor :tlm_unique_id_mode
|
|
52
|
+
attr_accessor :id
|
|
53
|
+
attr_accessor :cmd_log_cycle_time
|
|
54
|
+
attr_accessor :cmd_log_cycle_size
|
|
55
|
+
attr_accessor :cmd_log_retain_time
|
|
56
|
+
attr_accessor :cmd_decom_log_cycle_time
|
|
57
|
+
attr_accessor :cmd_decom_log_cycle_size
|
|
58
|
+
attr_accessor :cmd_decom_log_retain_time
|
|
59
|
+
attr_accessor :tlm_log_cycle_time
|
|
60
|
+
attr_accessor :tlm_log_cycle_size
|
|
61
|
+
attr_accessor :tlm_log_retain_time
|
|
62
|
+
attr_accessor :tlm_decom_log_cycle_time
|
|
63
|
+
attr_accessor :tlm_decom_log_cycle_size
|
|
64
|
+
attr_accessor :tlm_decom_log_retain_time
|
|
65
|
+
attr_accessor :reduced_minute_log_retain_time
|
|
66
|
+
attr_accessor :reduced_hour_log_retain_time
|
|
67
|
+
attr_accessor :reduced_day_log_retain_time
|
|
68
|
+
attr_accessor :cleanup_poll_time
|
|
69
|
+
attr_accessor :needs_dependencies
|
|
70
|
+
|
|
71
|
+
# NOTE: The following three class methods are used by the ModelController
|
|
72
|
+
# and are reimplemented to enable various Model class methods to work
|
|
73
|
+
def self.get(name:, scope:)
|
|
74
|
+
super("#{scope}__#{PRIMARY_KEY}", name: name)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.names(scope:)
|
|
78
|
+
super("#{scope}__#{PRIMARY_KEY}")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.all(scope:)
|
|
82
|
+
super("#{scope}__#{PRIMARY_KEY}")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @return [Array] Array of all the packet names
|
|
86
|
+
def self.packet_names(target_name, type: :TLM, scope:)
|
|
87
|
+
raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
|
|
88
|
+
# If the key doesn't exist or if there are no packets we return empty array
|
|
89
|
+
Store.hkeys("#{scope}__openc3#{type.to_s.downcase}__#{target_name}").sort
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @return [Hash] Packet hash or raises an exception
|
|
93
|
+
def self.packet(target_name, packet_name, type: :TLM, scope:)
|
|
94
|
+
raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
|
|
95
|
+
|
|
96
|
+
# Assume it exists and just try to get it to avoid an extra call to Store.exist?
|
|
97
|
+
json = Store.hget("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name)
|
|
98
|
+
raise "Packet '#{target_name} #{packet_name}' does not exist" if json.nil?
|
|
99
|
+
|
|
100
|
+
JSON.parse(json, :allow_nan => true, :create_additions => true)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @return [Array>Hash>] All packet hashes under the target_name
|
|
104
|
+
def self.packets(target_name, type: :TLM, scope:)
|
|
105
|
+
raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
|
|
106
|
+
raise "Target '#{target_name}' does not exist" unless get(name: target_name, scope: scope)
|
|
107
|
+
|
|
108
|
+
result = []
|
|
109
|
+
packets = Store.hgetall("#{scope}__openc3#{type.to_s.downcase}__#{target_name}")
|
|
110
|
+
packets.sort.each do |packet_name, packet_json|
|
|
111
|
+
result << JSON.parse(packet_json, :allow_nan => true, :create_additions => true)
|
|
112
|
+
end
|
|
113
|
+
result
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @return [Array>Hash>] All packet hashes under the target_name
|
|
117
|
+
def self.all_packet_name_descriptions(target_name, type: :TLM, scope:)
|
|
118
|
+
self.packets(target_name, type: type, scope: scope).map! { |hash| hash.slice("packet_name", "description") }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.set_packet(target_name, packet_name, packet, type: :TLM, scope:)
|
|
122
|
+
raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
|
|
123
|
+
|
|
124
|
+
begin
|
|
125
|
+
Store.hset("#{scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
|
|
126
|
+
rescue JSON::GeneratorError => err
|
|
127
|
+
Logger.error("Invalid text present in #{target_name} #{packet_name} #{type.to_s.downcase} packet")
|
|
128
|
+
raise err
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @return [Hash] Item hash or raises an exception
|
|
133
|
+
def self.packet_item(target_name, packet_name, item_name, type: :TLM, scope:)
|
|
134
|
+
packet = packet(target_name, packet_name, type: type, scope: scope)
|
|
135
|
+
item = packet['items'].find { |item| item['name'] == item_name.to_s }
|
|
136
|
+
raise "Item '#{packet['target_name']} #{packet['packet_name']} #{item_name}' does not exist" unless item
|
|
137
|
+
item
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @return [Array<Hash>] Item hash array or raises an exception
|
|
141
|
+
def self.packet_items(target_name, packet_name, items, type: :TLM, scope:)
|
|
142
|
+
packet = packet(target_name, packet_name, type: type, scope: scope)
|
|
143
|
+
found = packet['items'].find_all { |item| items.map(&:to_s).include?(item['name']) }
|
|
144
|
+
if found.length != items.length # we didn't find them all
|
|
145
|
+
found_items = found.collect { |item| item['name'] }
|
|
146
|
+
not_found = []
|
|
147
|
+
(items - found_items).each do |item|
|
|
148
|
+
not_found << "'#{target_name} #{packet_name} #{item}'"
|
|
149
|
+
end
|
|
150
|
+
# 'does not exist' not gramatically correct but we use it in every other exception
|
|
151
|
+
raise "Item(s) #{not_found.join(', ')} does not exist"
|
|
152
|
+
end
|
|
153
|
+
found
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @return [Hash{String => Array<Array<String, String, String>>}]
|
|
157
|
+
def self.limits_groups(scope:)
|
|
158
|
+
groups = Store.hgetall("#{scope}__limits_groups")
|
|
159
|
+
if groups
|
|
160
|
+
groups.map { |group, items| [group, JSON.parse(items, :allow_nan => true, :create_additions => true)] }.to_h
|
|
161
|
+
else
|
|
162
|
+
{}
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Called by the PluginModel to allow this class to validate it's top-level keyword: "TARGET"
|
|
167
|
+
def self.handle_config(parser, keyword, parameters, plugin: nil, needs_dependencies: false, scope:)
|
|
168
|
+
case keyword
|
|
169
|
+
when 'TARGET'
|
|
170
|
+
usage = "#{keyword} <TARGET FOLDER NAME> <TARGET NAME>"
|
|
171
|
+
parser.verify_num_parameters(2, 2, usage)
|
|
172
|
+
parser.verify_parameter_naming(2) # Target name is the 2nd parameter
|
|
173
|
+
return self.new(name: parameters[1].to_s.upcase, folder_name: parameters[0].to_s.upcase, plugin: plugin, needs_dependencies: needs_dependencies, scope: scope)
|
|
174
|
+
else
|
|
175
|
+
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Target: #{keyword} #{parameters.join(" ")}")
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def initialize(
|
|
180
|
+
name:,
|
|
181
|
+
folder_name: nil,
|
|
182
|
+
requires: [],
|
|
183
|
+
ignored_parameters: [],
|
|
184
|
+
ignored_items: [],
|
|
185
|
+
limits_groups: [],
|
|
186
|
+
cmd_tlm_files: [],
|
|
187
|
+
cmd_unique_id_mode: false,
|
|
188
|
+
tlm_unique_id_mode: false,
|
|
189
|
+
id: nil,
|
|
190
|
+
updated_at: nil,
|
|
191
|
+
plugin: nil,
|
|
192
|
+
cmd_log_cycle_time: 600,
|
|
193
|
+
cmd_log_cycle_size: 50_000_000,
|
|
194
|
+
cmd_log_retain_time: nil,
|
|
195
|
+
cmd_decom_log_cycle_time: 600,
|
|
196
|
+
cmd_decom_log_cycle_size: 50_000_000,
|
|
197
|
+
cmd_decom_log_retain_time: nil,
|
|
198
|
+
tlm_log_cycle_time: 600,
|
|
199
|
+
tlm_log_cycle_size: 50_000_000,
|
|
200
|
+
tlm_log_retain_time: nil,
|
|
201
|
+
tlm_decom_log_cycle_time: 600,
|
|
202
|
+
tlm_decom_log_cycle_size: 50_000_000,
|
|
203
|
+
tlm_decom_log_retain_time: nil,
|
|
204
|
+
reduced_minute_log_retain_time: nil,
|
|
205
|
+
reduced_hour_log_retain_time: nil,
|
|
206
|
+
reduced_day_log_retain_time: nil,
|
|
207
|
+
cleanup_poll_time: 900,
|
|
208
|
+
needs_dependencies: false,
|
|
209
|
+
scope:
|
|
210
|
+
)
|
|
211
|
+
super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at,
|
|
212
|
+
cmd_log_cycle_time: cmd_log_cycle_time, cmd_log_cycle_size: cmd_log_cycle_size,
|
|
213
|
+
cmd_log_retain_time: cmd_log_retain_time,
|
|
214
|
+
cmd_decom_log_cycle_time: cmd_decom_log_cycle_time, cmd_decom_log_cycle_size: cmd_decom_log_cycle_size,
|
|
215
|
+
cmd_decom_log_retain_time: cmd_decom_log_retain_time,
|
|
216
|
+
tlm_log_cycle_time: tlm_log_cycle_time, tlm_log_cycle_size: tlm_log_cycle_size,
|
|
217
|
+
tlm_log_retain_time: tlm_log_retain_time,
|
|
218
|
+
tlm_decom_log_cycle_time: tlm_decom_log_cycle_time, tlm_decom_log_cycle_size: tlm_decom_log_cycle_size,
|
|
219
|
+
tlm_decom_log_retain_time: tlm_decom_log_retain_time,
|
|
220
|
+
reduced_minute_log_retain_time: reduced_minute_log_retain_time,
|
|
221
|
+
reduced_hour_log_retain_time: reduced_hour_log_retain_time, reduced_day_log_retain_time: reduced_day_log_retain_time,
|
|
222
|
+
cleanup_poll_time: cleanup_poll_time, needs_dependencies: needs_dependencies,
|
|
223
|
+
scope: scope)
|
|
224
|
+
@folder_name = folder_name
|
|
225
|
+
@requires = requires
|
|
226
|
+
@ignored_parameters = ignored_parameters
|
|
227
|
+
@ignored_items = ignored_items
|
|
228
|
+
@limits_groups = limits_groups
|
|
229
|
+
@cmd_tlm_files = cmd_tlm_files
|
|
230
|
+
@cmd_unique_id_mode = cmd_unique_id_mode
|
|
231
|
+
@tlm_unique_id_mode = tlm_unique_id_mode
|
|
232
|
+
@id = id
|
|
233
|
+
@cmd_log_cycle_time = cmd_log_cycle_time
|
|
234
|
+
@cmd_log_cycle_size = cmd_log_cycle_size
|
|
235
|
+
@cmd_log_retain_time = cmd_log_retain_time
|
|
236
|
+
@cmd_decom_log_cycle_time = cmd_decom_log_cycle_time
|
|
237
|
+
@cmd_decom_log_cycle_size = cmd_decom_log_cycle_size
|
|
238
|
+
@cmd_decom_log_retain_time = cmd_decom_log_retain_time
|
|
239
|
+
@tlm_log_cycle_time = tlm_log_cycle_time
|
|
240
|
+
@tlm_log_cycle_size = tlm_log_cycle_size
|
|
241
|
+
@tlm_log_retain_time = tlm_log_retain_time
|
|
242
|
+
@tlm_decom_log_cycle_time = tlm_decom_log_cycle_time
|
|
243
|
+
@tlm_decom_log_cycle_size = tlm_decom_log_cycle_size
|
|
244
|
+
@tlm_decom_log_retain_time = tlm_decom_log_retain_time
|
|
245
|
+
@reduced_minute_log_retain_time = reduced_minute_log_retain_time
|
|
246
|
+
@reduced_hour_log_retain_time = reduced_hour_log_retain_time
|
|
247
|
+
@reduced_day_log_retain_time = reduced_day_log_retain_time
|
|
248
|
+
@cleanup_poll_time = cleanup_poll_time
|
|
249
|
+
@needs_dependencies = needs_dependencies
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def as_json(*a)
|
|
253
|
+
{
|
|
254
|
+
'name' => @name,
|
|
255
|
+
'folder_name' => @folder_name,
|
|
256
|
+
'requires' => @requires,
|
|
257
|
+
'ignored_parameters' => @ignored_parameters,
|
|
258
|
+
'ignored_items' => @ignored_items,
|
|
259
|
+
'limits_groups' => @limits_groups,
|
|
260
|
+
'cmd_tlm_files' => @cmd_tlm_files,
|
|
261
|
+
'cmd_unique_id_mode' => cmd_unique_id_mode,
|
|
262
|
+
'tlm_unique_id_mode' => @tlm_unique_id_mode,
|
|
263
|
+
'id' => @id,
|
|
264
|
+
'updated_at' => @updated_at,
|
|
265
|
+
'plugin' => @plugin,
|
|
266
|
+
'cmd_log_cycle_time' => @cmd_log_cycle_time,
|
|
267
|
+
'cmd_log_cycle_size' => @cmd_log_cycle_size,
|
|
268
|
+
'cmd_log_retain_time' => @cmd_log_retain_time,
|
|
269
|
+
'cmd_decom_log_cycle_time' => @cmd_decom_log_cycle_time,
|
|
270
|
+
'cmd_decom_log_cycle_size' => @cmd_decom_log_cycle_size,
|
|
271
|
+
'cmd_decom_log_retain_time' => @cmd_decom_log_retain_time,
|
|
272
|
+
'tlm_log_cycle_time' => @tlm_log_cycle_time,
|
|
273
|
+
'tlm_log_cycle_size' => @tlm_log_cycle_size,
|
|
274
|
+
'tlm_log_retain_time' => @tlm_log_retain_time,
|
|
275
|
+
'tlm_decom_log_cycle_time' => @tlm_decom_log_cycle_time,
|
|
276
|
+
'tlm_decom_log_cycle_size' => @tlm_decom_log_cycle_size,
|
|
277
|
+
'tlm_decom_log_retain_time' => @tlm_decom_log_retain_time,
|
|
278
|
+
'reduced_minute_log_retain_time' => @reduced_minute_log_retain_time,
|
|
279
|
+
'reduced_hour_log_retain_time' => @reduced_hour_log_retain_time,
|
|
280
|
+
'reduced_day_log_retain_time' => @reduced_day_log_retain_time,
|
|
281
|
+
'cleanup_poll_time' => @cleanup_poll_time,
|
|
282
|
+
'needs_dependencies' => @needs_dependencies,
|
|
283
|
+
}
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def as_config
|
|
287
|
+
"TARGET #{@folder_name} #{@name}\n"
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Handles Target specific configuration keywords
|
|
291
|
+
def handle_config(parser, keyword, parameters)
|
|
292
|
+
case keyword
|
|
293
|
+
when 'CMD_LOG_CYCLE_TIME'
|
|
294
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
|
|
295
|
+
@cmd_log_cycle_time = parameters[0].to_i
|
|
296
|
+
when 'CMD_LOG_CYCLE_SIZE'
|
|
297
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
|
|
298
|
+
@cmd_log_cycle_size = parameters[0].to_i
|
|
299
|
+
when 'CMD_LOG_RETAIN_TIME'
|
|
300
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for cmd log files in seconds - nil = Forever>")
|
|
301
|
+
@cmd_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
302
|
+
@cmd_log_retain_time = @cmd_log_retain_time.to_i if @cmd_log_retain_time
|
|
303
|
+
when 'CMD_DECOM_LOG_CYCLE_TIME'
|
|
304
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
|
|
305
|
+
@cmd_decom_log_cycle_time = parameters[0].to_i
|
|
306
|
+
when 'CMD_DECOM_LOG_CYCLE_SIZE'
|
|
307
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
|
|
308
|
+
@cmd_decom_log_cycle_size = parameters[0].to_i
|
|
309
|
+
when 'CMD_DECOM_LOG_RETAIN_TIME'
|
|
310
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for cmd decom log files in seconds - nil = Forever>")
|
|
311
|
+
@cmd_decom_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
312
|
+
@cmd_decom_log_retain_time = @cmd_decom_log_retain_time.to_i if @cmd_decom_log_retain_time
|
|
313
|
+
when 'TLM_LOG_CYCLE_TIME'
|
|
314
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
|
|
315
|
+
@tlm_log_cycle_time = parameters[0].to_i
|
|
316
|
+
when 'TLM_LOG_CYCLE_SIZE'
|
|
317
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
|
|
318
|
+
@tlm_log_cycle_size = parameters[0].to_i
|
|
319
|
+
when 'TLM_LOG_RETAIN_TIME'
|
|
320
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for tlm log files in seconds - nil = Forever>")
|
|
321
|
+
@tlm_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
322
|
+
@tlm_log_retain_time = @tlm_log_retain_time.to_i if @tlm_log_retain_time
|
|
323
|
+
when 'TLM_DECOM_LOG_CYCLE_TIME'
|
|
324
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
|
|
325
|
+
@tlm_decom_log_cycle_time = parameters[0].to_i
|
|
326
|
+
when 'TLM_DECOM_LOG_CYCLE_SIZE'
|
|
327
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
|
|
328
|
+
@tlm_decom_log_cycle_size = parameters[0].to_i
|
|
329
|
+
when 'TLM_DECOM_LOG_RETAIN_TIME'
|
|
330
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for tlm decom log files in seconds - nil = Forever>")
|
|
331
|
+
@tlm_decom_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
332
|
+
@tlm_decom_log_retain_time = @tlm_decom_log_retain_time.to_i if @tlm_decom_log_retain_time
|
|
333
|
+
when 'REDUCED_MINUTE_LOG_RETAIN_TIME'
|
|
334
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced minute log files in seconds - nil = Forever>")
|
|
335
|
+
@reduced_minute_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
336
|
+
@reduced_minute_log_retain_time = @reduced_minute_log_retain_time.to_i if @reduced_minute_log_retain_time
|
|
337
|
+
when 'REDUCED_HOUR_LOG_RETAIN_TIME'
|
|
338
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced hour log files in seconds - nil = Forever>")
|
|
339
|
+
@reduced_hour_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
340
|
+
@reduced_hour_log_retain_time = @reduced_hour_log_retain_time.to_i if @reduced_hour_log_retain_time
|
|
341
|
+
when 'REDUCED_DAY_LOG_RETAIN_TIME'
|
|
342
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced day log files in seconds - nil = Forever>")
|
|
343
|
+
@reduced_day_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
344
|
+
@reduced_day_log_retain_time = @reduced_day_log_retain_time.to_i if @reduced_day_log_retain_time
|
|
345
|
+
when 'LOG_RETAIN_TIME'
|
|
346
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all log files in seconds - nil = Forever>")
|
|
347
|
+
log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
348
|
+
if log_retain_time
|
|
349
|
+
@cmd_log_retain_time = log_retain_time.to_i
|
|
350
|
+
@cmd_decom_log_retain_time = log_retain_time.to_i
|
|
351
|
+
@tlm_log_retain_time = log_retain_time.to_i
|
|
352
|
+
@tlm_decom_log_retain_time = log_retain_time.to_i
|
|
353
|
+
end
|
|
354
|
+
when 'REDUCED_LOG_RETAIN_TIME'
|
|
355
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all reduced log files in seconds - nil = Forever>")
|
|
356
|
+
reduced_log_retain_time = ConfigParser.handle_nil(parameters[0])
|
|
357
|
+
if reduced_log_retain_time
|
|
358
|
+
@reduced_minute_log_retain_time = reduced_log_retain_time.to_i
|
|
359
|
+
@reduced_hour_log_retain_time = reduced_log_retain_time.to_i
|
|
360
|
+
@reduced_day_log_retain_time = reduced_log_retain_time.to_i
|
|
361
|
+
end
|
|
362
|
+
when 'CLEANUP_POLL_TIME'
|
|
363
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Cleanup polling period in seconds>")
|
|
364
|
+
@cleanup_poll_time = parameters[0].to_i
|
|
365
|
+
else
|
|
366
|
+
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Target: #{keyword} #{parameters.join(" ")}")
|
|
367
|
+
end
|
|
368
|
+
return nil
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def deploy(gem_path, variables, validate_only: false)
|
|
372
|
+
rubys3_client = Aws::S3::Client.new
|
|
373
|
+
variables["target_name"] = @name
|
|
374
|
+
start_path = "/targets/#{@folder_name}/"
|
|
375
|
+
temp_dir = Dir.mktmpdir
|
|
376
|
+
found = false
|
|
377
|
+
begin
|
|
378
|
+
target_path = gem_path + start_path + "**/*"
|
|
379
|
+
Dir.glob(target_path) do |filename|
|
|
380
|
+
next if filename == '.' or filename == '..' or File.directory?(filename)
|
|
381
|
+
|
|
382
|
+
path = filename.split(gem_path)[-1]
|
|
383
|
+
target_folder_path = path.split(start_path)[-1]
|
|
384
|
+
key = "#{@scope}/targets/#{@name}/#{target_folder_path}"
|
|
385
|
+
|
|
386
|
+
# Load target files
|
|
387
|
+
@filename = filename # For render
|
|
388
|
+
data = File.read(filename, mode: "rb")
|
|
389
|
+
begin
|
|
390
|
+
OpenC3.set_working_dir(File.dirname(filename)) do
|
|
391
|
+
data = ERB.new(data, trim_mode: "-").result(binding.set_variables(variables)) if data.is_printable? and File.basename(filename)[0] != '_'
|
|
392
|
+
end
|
|
393
|
+
rescue => error
|
|
394
|
+
raise "ERB error parsing: #{filename}: #{error.formatted}"
|
|
395
|
+
end
|
|
396
|
+
local_path = File.join(temp_dir, @name, target_folder_path)
|
|
397
|
+
FileUtils.mkdir_p(File.dirname(local_path))
|
|
398
|
+
File.open(local_path, 'wb') { |file| file.write(data) }
|
|
399
|
+
found = true
|
|
400
|
+
rubys3_client.put_object(bucket: 'config', key: key, body: data) unless validate_only
|
|
401
|
+
end
|
|
402
|
+
raise "No target files found at #{target_path}" unless found
|
|
403
|
+
|
|
404
|
+
target_folder = File.join(temp_dir, @name)
|
|
405
|
+
# Build a System for just this target
|
|
406
|
+
system = System.new([@name], temp_dir)
|
|
407
|
+
if variables["xtce_output"]
|
|
408
|
+
puts "Converting target #{@name} to .xtce files in #{variables["xtce_output"]}/#{@name}"
|
|
409
|
+
system.packet_config.to_xtce(variables["xtce_output"])
|
|
410
|
+
end
|
|
411
|
+
unless validate_only
|
|
412
|
+
build_target_archive(rubys3_client, temp_dir, target_folder)
|
|
413
|
+
system = update_store(system)
|
|
414
|
+
deploy_microservices(gem_path, variables, system)
|
|
415
|
+
ConfigTopic.write({ kind: 'created', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
|
|
416
|
+
end
|
|
417
|
+
ensure
|
|
418
|
+
FileUtils.remove_entry(temp_dir) if temp_dir and File.exist?(temp_dir)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def undeploy
|
|
423
|
+
# Note: The plugin_model undeploy method removes all the microservices first
|
|
424
|
+
# so we don't need to destroy them here
|
|
425
|
+
|
|
426
|
+
rubys3_client = Aws::S3::Client.new
|
|
427
|
+
prefix = "#{@scope}/targets/#{@name}/"
|
|
428
|
+
rubys3_client.list_objects(bucket: 'config', prefix: prefix).contents.each do |object|
|
|
429
|
+
rubys3_client.delete_object(bucket: 'config', key: object.key)
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
self.class.get_model(name: @name, scope: @scope).limits_groups.each do |group|
|
|
433
|
+
Store.hdel("#{@scope}__limits_groups", group)
|
|
434
|
+
end
|
|
435
|
+
self.class.packets(@name, type: :CMD, scope: @scope).each do |packet|
|
|
436
|
+
Topic.del("#{@scope}__COMMAND__{#{@name}}__#{packet['packet_name']}")
|
|
437
|
+
Topic.del("#{@scope}__DECOMCMD__{#{@name}}__#{packet['packet_name']}")
|
|
438
|
+
end
|
|
439
|
+
self.class.packets(@name, scope: @scope).each do |packet|
|
|
440
|
+
Topic.del("#{@scope}__TELEMETRY__{#{@name}}__#{packet['packet_name']}")
|
|
441
|
+
Topic.del("#{@scope}__DECOM__{#{@name}}__#{packet['packet_name']}")
|
|
442
|
+
CvtModel.del(target_name: @name, packet_name: packet['packet_name'], scope: @scope)
|
|
443
|
+
LimitsEventTopic.delete(@name, packet['packet_name'], scope: @scope)
|
|
444
|
+
end
|
|
445
|
+
Store.del("#{@scope}__openc3tlm__#{@name}")
|
|
446
|
+
Store.del("#{@scope}__openc3cmd__#{@name}")
|
|
447
|
+
|
|
448
|
+
# Note: these match the names of the services in deploy_microservices
|
|
449
|
+
%w(DECOM COMMANDLOG DECOMCMDLOG PACKETLOG DECOMLOG REDUCER CLEANUP).each do |type|
|
|
450
|
+
model = MicroserviceModel.get_model(name: "#{@scope}__#{type}__#{@name}", scope: @scope)
|
|
451
|
+
model.destroy if model
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
ConfigTopic.write({ kind: 'deleted', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
##################################################
|
|
458
|
+
# The following methods are implementation details
|
|
459
|
+
##################################################
|
|
460
|
+
|
|
461
|
+
# Called by the ERB template to render a partial
|
|
462
|
+
def render(template_name, options = {})
|
|
463
|
+
raise "Partial name '#{template_name}' must begin with an underscore." if File.basename(template_name)[0] != '_'
|
|
464
|
+
|
|
465
|
+
b = binding
|
|
466
|
+
b.local_variable_set(:target_name, @name)
|
|
467
|
+
if options[:locals]
|
|
468
|
+
options[:locals].each { |key, value| b.local_variable_set(key, value) }
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Assume the file is there. If not we raise a pretty obvious error
|
|
472
|
+
if File.expand_path(template_name) == template_name # absolute path
|
|
473
|
+
path = template_name
|
|
474
|
+
else # relative to the current @filename
|
|
475
|
+
path = File.join(File.dirname(@filename), template_name)
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
begin
|
|
479
|
+
OpenC3.set_working_dir(File.dirname(path)) do
|
|
480
|
+
return ERB.new(File.read(path), trim_mode: "-").result(b)
|
|
481
|
+
end
|
|
482
|
+
rescue => error
|
|
483
|
+
raise "ERB error parsing: #{path}: #{error.formatted}"
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
def build_target_archive(rubys3_client, temp_dir, target_folder)
|
|
488
|
+
target_files = []
|
|
489
|
+
Find.find(target_folder) { |file| target_files << file }
|
|
490
|
+
target_files.sort!
|
|
491
|
+
hash = OpenC3.hash_files(target_files, nil, 'SHA256').hexdigest
|
|
492
|
+
File.open(File.join(target_folder, 'target_id.txt'), 'wb') { |file| file.write(hash) }
|
|
493
|
+
key = "#{@scope}/targets/#{@name}/target_id.txt"
|
|
494
|
+
rubys3_client.put_object(bucket: 'config', key: key, body: hash)
|
|
495
|
+
|
|
496
|
+
# Create target archive zip file
|
|
497
|
+
prefix = File.dirname(target_folder) + '/'
|
|
498
|
+
output_file = File.join(temp_dir, @name + '_' + hash + '.zip')
|
|
499
|
+
Zip.continue_on_exists_proc = true
|
|
500
|
+
Zip::File.open(output_file, Zip::File::CREATE) do |zipfile|
|
|
501
|
+
target_files.each do |target_file|
|
|
502
|
+
zip_file_path = target_file.delete_prefix(prefix)
|
|
503
|
+
if File.directory?(target_file)
|
|
504
|
+
zipfile.mkdir(zip_file_path)
|
|
505
|
+
else
|
|
506
|
+
zipfile.add(zip_file_path, target_file)
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# Write Target Archive to S3 Bucket
|
|
512
|
+
File.open(output_file, 'rb') do |file|
|
|
513
|
+
s3_key = key = "#{@scope}/target_archives/#{@name}/#{@name}_current.zip"
|
|
514
|
+
rubys3_client.put_object(bucket: 'config', key: s3_key, body: file)
|
|
515
|
+
end
|
|
516
|
+
File.open(output_file, 'rb') do |file|
|
|
517
|
+
s3_key = key = "#{@scope}/target_archives/#{@name}/#{@name}_#{hash}.zip"
|
|
518
|
+
rubys3_client.put_object(bucket: 'config', key: s3_key, body: file)
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
def update_store(system)
|
|
523
|
+
target = system.targets[@name]
|
|
524
|
+
|
|
525
|
+
# Add in the information from the target and update
|
|
526
|
+
@requires = target.requires
|
|
527
|
+
@ignored_parameters = target.ignored_parameters
|
|
528
|
+
@ignored_items = target.ignored_items
|
|
529
|
+
@cmd_tlm_files = target.cmd_tlm_files
|
|
530
|
+
@cmd_unique_id_mode = target.cmd_unique_id_mode
|
|
531
|
+
@tlm_unique_id_mode = target.tlm_unique_id_mode
|
|
532
|
+
@id = target.id
|
|
533
|
+
@limits_groups = system.limits.groups.keys
|
|
534
|
+
update()
|
|
535
|
+
|
|
536
|
+
# Store Packet Definitions
|
|
537
|
+
system.telemetry.all.each do |target_name, packets|
|
|
538
|
+
Store.del("#{@scope}__openc3tlm__#{target_name}")
|
|
539
|
+
packets.each do |packet_name, packet|
|
|
540
|
+
Logger.info "Configuring tlm packet: #{target_name} #{packet_name}"
|
|
541
|
+
begin
|
|
542
|
+
Store.hset("#{@scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
|
|
543
|
+
rescue JSON::GeneratorError => err
|
|
544
|
+
Logger.error("Invalid text present in #{target_name} #{packet_name} tlm packet")
|
|
545
|
+
raise err
|
|
546
|
+
end
|
|
547
|
+
json_hash = Hash.new
|
|
548
|
+
packet.sorted_items.each do |item|
|
|
549
|
+
json_hash[item.name] = nil
|
|
550
|
+
end
|
|
551
|
+
CvtModel.set(json_hash, target_name: packet.target_name, packet_name: packet.packet_name, scope: @scope)
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
system.commands.all.each do |target_name, packets|
|
|
555
|
+
Store.del("#{@scope}__openc3cmd__#{target_name}")
|
|
556
|
+
packets.each do |packet_name, packet|
|
|
557
|
+
Logger.info "Configuring cmd packet: #{target_name} #{packet_name}"
|
|
558
|
+
begin
|
|
559
|
+
Store.hset("#{@scope}__openc3cmd__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
|
|
560
|
+
rescue JSON::GeneratorError => err
|
|
561
|
+
Logger.error("Invalid text present in #{target_name} #{packet_name} cmd packet")
|
|
562
|
+
raise err
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
# Store Limits Groups
|
|
567
|
+
system.limits.groups.each do |group, items|
|
|
568
|
+
begin
|
|
569
|
+
Store.hset("#{@scope}__limits_groups", group, JSON.generate(items))
|
|
570
|
+
rescue JSON::GeneratorError => err
|
|
571
|
+
Logger.error("Invalid text present in #{group} limits group")
|
|
572
|
+
raise err
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
# Merge in Limits Sets
|
|
576
|
+
sets = Store.hgetall("#{@scope}__limits_sets")
|
|
577
|
+
sets ||= {}
|
|
578
|
+
system.limits.sets.each do |set|
|
|
579
|
+
sets[set.to_s] = "false" unless sets.key?(set.to_s)
|
|
580
|
+
end
|
|
581
|
+
Store.hmset("#{@scope}__limits_sets", *sets)
|
|
582
|
+
|
|
583
|
+
return system
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def deploy_microservices(gem_path, variables, system)
|
|
587
|
+
command_topic_list = []
|
|
588
|
+
decom_command_topic_list = []
|
|
589
|
+
packet_topic_list = []
|
|
590
|
+
decom_topic_list = []
|
|
591
|
+
begin
|
|
592
|
+
system.commands.packets(@name).each do |packet_name, packet|
|
|
593
|
+
command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
|
|
594
|
+
decom_command_topic_list << "#{@scope}__DECOMCMD__{#{@name}}__#{packet_name}"
|
|
595
|
+
end
|
|
596
|
+
rescue
|
|
597
|
+
# No command packets for this target
|
|
598
|
+
end
|
|
599
|
+
begin
|
|
600
|
+
system.telemetry.packets(@name).each do |packet_name, packet|
|
|
601
|
+
packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
|
|
602
|
+
decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
|
|
603
|
+
end
|
|
604
|
+
rescue
|
|
605
|
+
# No telemetry packets for this target
|
|
606
|
+
end
|
|
607
|
+
# It's ok to call initialize_streams with an empty array
|
|
608
|
+
Topic.initialize_streams(command_topic_list)
|
|
609
|
+
Topic.initialize_streams(decom_command_topic_list)
|
|
610
|
+
Topic.initialize_streams(packet_topic_list)
|
|
611
|
+
Topic.initialize_streams(decom_topic_list)
|
|
612
|
+
|
|
613
|
+
unless command_topic_list.empty?
|
|
614
|
+
# CommandLog Microservice
|
|
615
|
+
microservice_name = "#{@scope}__COMMANDLOG__#{@name}"
|
|
616
|
+
microservice = MicroserviceModel.new(
|
|
617
|
+
name: microservice_name,
|
|
618
|
+
folder_name: @folder_name,
|
|
619
|
+
cmd: ["ruby", "log_microservice.rb", microservice_name],
|
|
620
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
621
|
+
options: [
|
|
622
|
+
["RAW_OR_DECOM", "RAW"],
|
|
623
|
+
["CMD_OR_TLM", "CMD"],
|
|
624
|
+
["CYCLE_TIME", @cmd_log_cycle_time],
|
|
625
|
+
["CYCLE_SIZE", @cmd_log_cycle_size]
|
|
626
|
+
],
|
|
627
|
+
topics: command_topic_list,
|
|
628
|
+
target_names: [@name],
|
|
629
|
+
plugin: @plugin,
|
|
630
|
+
needs_dependencies: @needs_dependencies,
|
|
631
|
+
scope: @scope
|
|
632
|
+
)
|
|
633
|
+
microservice.create
|
|
634
|
+
microservice.deploy(gem_path, variables)
|
|
635
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
636
|
+
|
|
637
|
+
# DecomCmdLog Microservice
|
|
638
|
+
microservice_name = "#{@scope}__DECOMCMDLOG__#{@name}"
|
|
639
|
+
microservice = MicroserviceModel.new(
|
|
640
|
+
name: microservice_name,
|
|
641
|
+
folder_name: @folder_name,
|
|
642
|
+
cmd: ["ruby", "log_microservice.rb", microservice_name],
|
|
643
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
644
|
+
options: [
|
|
645
|
+
["RAW_OR_DECOM", "DECOM"],
|
|
646
|
+
["CMD_OR_TLM", "CMD"],
|
|
647
|
+
["CYCLE_TIME", @cmd_decom_log_cycle_time],
|
|
648
|
+
["CYCLE_SIZE", @cmd_decom_log_cycle_size]
|
|
649
|
+
],
|
|
650
|
+
topics: decom_command_topic_list,
|
|
651
|
+
target_names: [@name],
|
|
652
|
+
plugin: @plugin,
|
|
653
|
+
needs_dependencies: @needs_dependencies,
|
|
654
|
+
scope: @scope
|
|
655
|
+
)
|
|
656
|
+
microservice.create
|
|
657
|
+
microservice.deploy(gem_path, variables)
|
|
658
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
unless packet_topic_list.empty?
|
|
662
|
+
# PacketLog Microservice
|
|
663
|
+
microservice_name = "#{@scope}__PACKETLOG__#{@name}"
|
|
664
|
+
microservice = MicroserviceModel.new(
|
|
665
|
+
name: microservice_name,
|
|
666
|
+
folder_name: @folder_name,
|
|
667
|
+
cmd: ["ruby", "log_microservice.rb", microservice_name],
|
|
668
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
669
|
+
options: [
|
|
670
|
+
["RAW_OR_DECOM", "RAW"],
|
|
671
|
+
["CMD_OR_TLM", "TLM"],
|
|
672
|
+
["CYCLE_TIME", @tlm_log_cycle_time],
|
|
673
|
+
["CYCLE_SIZE", @tlm_log_cycle_size]
|
|
674
|
+
],
|
|
675
|
+
topics: packet_topic_list,
|
|
676
|
+
target_names: [@name],
|
|
677
|
+
plugin: @plugin,
|
|
678
|
+
needs_dependencies: @needs_dependencies,
|
|
679
|
+
scope: @scope
|
|
680
|
+
)
|
|
681
|
+
microservice.create
|
|
682
|
+
microservice.deploy(gem_path, variables)
|
|
683
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
684
|
+
|
|
685
|
+
# DecomLog Microservice
|
|
686
|
+
microservice_name = "#{@scope}__DECOMLOG__#{@name}"
|
|
687
|
+
microservice = MicroserviceModel.new(
|
|
688
|
+
name: microservice_name,
|
|
689
|
+
folder_name: @folder_name,
|
|
690
|
+
cmd: ["ruby", "log_microservice.rb", microservice_name],
|
|
691
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
692
|
+
options: [
|
|
693
|
+
["RAW_OR_DECOM", "DECOM"],
|
|
694
|
+
["CMD_OR_TLM", "TLM"],
|
|
695
|
+
["CYCLE_TIME", @tlm_decom_log_cycle_time],
|
|
696
|
+
["CYCLE_SIZE", @tlm_decom_log_cycle_size]
|
|
697
|
+
],
|
|
698
|
+
topics: decom_topic_list,
|
|
699
|
+
target_names: [@name],
|
|
700
|
+
plugin: @plugin,
|
|
701
|
+
needs_dependencies: @needs_dependencies,
|
|
702
|
+
scope: @scope
|
|
703
|
+
)
|
|
704
|
+
microservice.create
|
|
705
|
+
microservice.deploy(gem_path, variables)
|
|
706
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
707
|
+
|
|
708
|
+
# Decommutation Microservice
|
|
709
|
+
microservice_name = "#{@scope}__DECOM__#{@name}"
|
|
710
|
+
microservice = MicroserviceModel.new(
|
|
711
|
+
name: microservice_name,
|
|
712
|
+
folder_name: @folder_name,
|
|
713
|
+
cmd: ["ruby", "decom_microservice.rb", microservice_name],
|
|
714
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
715
|
+
topics: packet_topic_list,
|
|
716
|
+
target_names: [@name],
|
|
717
|
+
plugin: @plugin,
|
|
718
|
+
needs_dependencies: @needs_dependencies,
|
|
719
|
+
scope: @scope
|
|
720
|
+
)
|
|
721
|
+
microservice.create
|
|
722
|
+
microservice.deploy(gem_path, variables)
|
|
723
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
724
|
+
|
|
725
|
+
# Reducer Microservice
|
|
726
|
+
microservice_name = "#{@scope}__REDUCER__#{@name}"
|
|
727
|
+
microservice = MicroserviceModel.new(
|
|
728
|
+
name: microservice_name,
|
|
729
|
+
folder_name: @folder_name,
|
|
730
|
+
cmd: ["ruby", "reducer_microservice.rb", microservice_name],
|
|
731
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
732
|
+
topics: decom_topic_list,
|
|
733
|
+
plugin: @plugin,
|
|
734
|
+
needs_dependencies: @needs_dependencies,
|
|
735
|
+
scope: @scope
|
|
736
|
+
)
|
|
737
|
+
microservice.create
|
|
738
|
+
microservice.deploy(gem_path, variables)
|
|
739
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
if @cmd_log_retain_time or @cmd_decom_log_retain_time or @tlm_log_retain_time or @tlm_decom_log_retain_time or
|
|
743
|
+
@reduced_minute_log_retain_time or @reduced_hour_log_retain_time or @reduced_day_log_retain_time
|
|
744
|
+
# Cleanup Microservice
|
|
745
|
+
microservice_name = "#{@scope}__CLEANUP__#{@name}"
|
|
746
|
+
microservice = MicroserviceModel.new(
|
|
747
|
+
name: microservice_name,
|
|
748
|
+
cmd: ["ruby", "cleanup_microservice.rb", microservice_name],
|
|
749
|
+
work_dir: '/openc3/lib/openc3/microservices',
|
|
750
|
+
plugin: @plugin,
|
|
751
|
+
scope: @scope
|
|
752
|
+
)
|
|
753
|
+
microservice.create
|
|
754
|
+
microservice.deploy(gem_path, variables)
|
|
755
|
+
Logger.info "Configured microservice #{microservice_name}"
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
end
|
|
759
|
+
end
|