openc3 7.2.1 → 7.4.0
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/Gemfile +1 -1
- data/Guardfile +0 -0
- data/LICENSE.md +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/bin/openc3cli +235 -6
- data/bin/pipinstall +5 -4
- data/bin/pipuninstall +5 -1
- data/bin/uvinstall +156 -0
- data/data/config/_array_params.yaml +0 -0
- data/data/config/_canvas_values.yaml +0 -0
- data/data/config/_graph_params.yaml +0 -0
- data/data/config/_id_items.yaml +0 -0
- data/data/config/_id_params.yaml +0 -0
- data/data/config/_interfaces.yaml +0 -0
- data/data/config/_items.yaml +0 -0
- data/data/config/_params.yaml +0 -0
- data/data/config/command.yaml +0 -0
- data/data/config/command_modifiers.yaml +2 -0
- data/data/config/command_telemetry.yaml +0 -0
- data/data/config/conversions.yaml +0 -0
- data/data/config/graph_settings.yaml +0 -0
- data/data/config/interface_modifiers.yaml +103 -1
- data/data/config/item_modifiers.yaml +2 -1
- data/data/config/microservice.yaml +9 -2
- data/data/config/param_item_modifiers.yaml +0 -0
- data/data/config/parameter_modifiers.yaml +0 -0
- data/data/config/plugins.yaml +0 -0
- data/data/config/processors.yaml +0 -0
- data/data/config/protocols.yaml +0 -0
- data/data/config/screen.yaml +2 -1
- data/data/config/settings.yaml +0 -0
- data/data/config/table_manager.yaml +0 -0
- data/data/config/table_parameter_modifiers.yaml +0 -0
- data/data/config/target.yaml +21 -0
- data/data/config/target_config.yaml +0 -0
- data/data/config/telemetry.yaml +0 -0
- data/data/config/telemetry_modifiers.yaml +2 -0
- data/data/config/tool.yaml +3 -1
- data/data/config/unknown.yaml +0 -0
- data/data/config/widgets.yaml +22 -3
- data/data/xtce_schemas/SpaceSystem_20180204.xsd +5918 -0
- data/data/xtce_schemas/xml.xsd +116 -0
- data/ext/openc3/ext/array/array.c +0 -0
- data/ext/openc3/ext/array/extconf.rb +0 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +0 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +0 -0
- data/ext/openc3/ext/burst_protocol/burst_protocol.c +6 -0
- data/ext/openc3/ext/burst_protocol/extconf.rb +0 -0
- data/ext/openc3/ext/config_parser/config_parser.c +0 -0
- data/ext/openc3/ext/config_parser/extconf.rb +0 -0
- data/ext/openc3/ext/crc/crc.c +0 -0
- data/ext/openc3/ext/crc/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +0 -0
- data/ext/openc3/ext/packet/extconf.rb +0 -0
- data/ext/openc3/ext/packet/packet.c +0 -0
- data/ext/openc3/ext/platform/extconf.rb +0 -0
- data/ext/openc3/ext/platform/platform.c +4 -1
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +0 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +0 -0
- data/ext/openc3/ext/string/extconf.rb +0 -0
- data/ext/openc3/ext/string/string.c +0 -0
- data/ext/openc3/ext/structure/structure.c +49 -17
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +0 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +0 -0
- data/ext/openc3/ext/telemetry/extconf.rb +0 -0
- data/ext/openc3/ext/telemetry/telemetry.c +1 -1
- data/lib/cosmos.rb +0 -0
- data/lib/cosmosc2.rb +0 -0
- data/lib/openc3/accessors/accessor.rb +0 -0
- data/lib/openc3/accessors/binary_accessor.rb +63 -9
- data/lib/openc3/accessors/cbor_accessor.rb +0 -0
- data/lib/openc3/accessors/form_accessor.rb +0 -0
- data/lib/openc3/accessors/html_accessor.rb +0 -0
- data/lib/openc3/accessors/http_accessor.rb +0 -0
- data/lib/openc3/accessors/json_accessor.rb +0 -0
- data/lib/openc3/accessors/template_accessor.rb +2 -2
- data/lib/openc3/accessors/xml_accessor.rb +0 -0
- data/lib/openc3/accessors.rb +0 -0
- data/lib/openc3/api/README.md +0 -0
- data/lib/openc3/api/api.rb +0 -0
- data/lib/openc3/api/authorized_api.rb +0 -0
- data/lib/openc3/api/calendar_api.rb +0 -0
- data/lib/openc3/api/cmd_api.rb +1 -1
- data/lib/openc3/api/config_api.rb +0 -0
- data/lib/openc3/api/interface_api.rb +2 -2
- data/lib/openc3/api/limits_api.rb +27 -13
- data/lib/openc3/api/metrics_api.rb +1 -1
- data/lib/openc3/api/offline_access_api.rb +1 -1
- data/lib/openc3/api/router_api.rb +3 -3
- data/lib/openc3/api/settings_api.rb +22 -18
- data/lib/openc3/api/stash_api.rb +1 -1
- data/lib/openc3/api/target_api.rb +0 -0
- data/lib/openc3/api/tlm_api.rb +5 -4
- data/lib/openc3/bridge/bridge.rb +0 -0
- data/lib/openc3/bridge/bridge_config.rb +0 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +0 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +0 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +0 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +0 -0
- data/lib/openc3/config/config_parser.rb +78 -17
- data/lib/openc3/config/meta_config_parser.rb +0 -0
- data/lib/openc3/conversions/bit_reverse_conversion.rb +0 -0
- data/lib/openc3/conversions/conversion.rb +0 -0
- data/lib/openc3/conversions/generic_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_read_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_write_conversion.rb +0 -0
- data/lib/openc3/conversions/object_read_conversion.rb +0 -0
- data/lib/openc3/conversions/object_write_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/processor_conversion.rb +0 -0
- data/lib/openc3/conversions/received_count_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions.rb +0 -0
- data/lib/openc3/core_ext/array.rb +0 -0
- data/lib/openc3/core_ext/binding.rb +0 -0
- data/lib/openc3/core_ext/class.rb +0 -0
- data/lib/openc3/core_ext/exception.rb +0 -0
- data/lib/openc3/core_ext/faraday.rb +0 -0
- data/lib/openc3/core_ext/file.rb +0 -0
- data/lib/openc3/core_ext/io.rb +0 -0
- data/lib/openc3/core_ext/kernel.rb +0 -0
- data/lib/openc3/core_ext/math.rb +0 -0
- data/lib/openc3/core_ext/matrix.rb +0 -0
- data/lib/openc3/core_ext/objectspace.rb +0 -0
- data/lib/openc3/core_ext/openc3_io.rb +0 -0
- data/lib/openc3/core_ext/range.rb +0 -0
- data/lib/openc3/core_ext/socket.rb +0 -0
- data/lib/openc3/core_ext/string.rb +0 -0
- data/lib/openc3/core_ext/stringio.rb +0 -0
- data/lib/openc3/core_ext/tempfile.rb +0 -0
- data/lib/openc3/core_ext/time.rb +0 -0
- data/lib/openc3/core_ext.rb +0 -0
- data/lib/openc3/ext/.keep +0 -0
- data/lib/openc3/interfaces/file_interface.rb +0 -0
- data/lib/openc3/interfaces/http_client_interface.rb +1 -1
- data/lib/openc3/interfaces/http_server_interface.rb +0 -0
- data/lib/openc3/interfaces/interface.rb +5 -4
- data/lib/openc3/interfaces/mqtt_interface.rb +0 -0
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +2 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +27 -0
- data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/cobs_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +4 -4
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +0 -0
- data/lib/openc3/interfaces/serial_interface.rb +2 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +0 -0
- data/lib/openc3/interfaces/stream_interface.rb +0 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +2 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -0
- data/lib/openc3/interfaces/udp_interface.rb +16 -5
- data/lib/openc3/interfaces.rb +0 -0
- data/lib/openc3/io/buffered_file.rb +0 -0
- data/lib/openc3/io/io_multiplexer.rb +0 -0
- data/lib/openc3/io/json_api.rb +3 -2
- data/lib/openc3/io/json_api_object.rb +0 -0
- data/lib/openc3/io/json_drb.rb +44 -12
- data/lib/openc3/io/json_drb_object.rb +0 -0
- data/lib/openc3/io/json_drb_rack.rb +0 -0
- data/lib/openc3/io/json_rpc.rb +0 -2
- data/lib/openc3/io/posix_serial_driver.rb +0 -0
- data/lib/openc3/io/serial_driver.rb +0 -0
- data/lib/openc3/io/stderr.rb +0 -0
- data/lib/openc3/io/stdout.rb +0 -0
- data/lib/openc3/io/udp_sockets.rb +38 -8
- data/lib/openc3/io/win32_serial_driver.rb +1 -0
- data/lib/openc3/logs/buffered_packet_log_reader.rb +0 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +0 -0
- data/lib/openc3/logs/log_writer.rb +43 -7
- data/lib/openc3/logs/packet_log_constants.rb +0 -0
- data/lib/openc3/logs/packet_log_reader.rb +23 -2
- data/lib/openc3/logs/packet_log_writer.rb +6 -2
- data/lib/openc3/logs/stream_log.rb +1 -1
- data/lib/openc3/logs/stream_log_pair.rb +0 -0
- data/lib/openc3/logs/text_log_writer.rb +0 -0
- data/lib/openc3/logs.rb +0 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/decom_common.rb +0 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -0
- data/lib/openc3/microservices/interface_decom_common.rb +2 -1
- data/lib/openc3/microservices/interface_microservice.rb +73 -26
- data/lib/openc3/microservices/log_microservice.rb +0 -0
- data/lib/openc3/microservices/microservice.rb +3 -3
- data/lib/openc3/microservices/multi_microservice.rb +1 -1
- data/lib/openc3/microservices/periodic_microservice.rb +2 -2
- data/lib/openc3/microservices/plugin_microservice.rb +0 -0
- data/lib/openc3/microservices/queue_microservice.rb +0 -0
- data/lib/openc3/microservices/router_microservice.rb +0 -0
- data/lib/openc3/microservices/scope_cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/text_log_microservice.rb +0 -0
- data/lib/openc3/migrations/20220420190000_log_stuff.rb +0 -0
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +0 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +0 -0
- data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +0 -0
- data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +0 -0
- data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +0 -0
- data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +0 -0
- data/lib/openc3/migrations/20250108060000_news_feed.rb +0 -0
- data/lib/openc3/migrations/20250402000000_periodic_only_default.rb +0 -0
- data/lib/openc3/migrations/20260203000000_remove_store_id.rb +0 -0
- data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +0 -0
- data/lib/openc3/migrations/20260701000000_updated_at_to_int.rb +0 -0
- data/lib/openc3/migrations/20260704000000_default_bridge.rb +38 -0
- data/lib/openc3/migrations/20260731000000_system_health_json.rb +52 -0
- data/lib/openc3/models/activity_model.rb +0 -0
- data/lib/openc3/models/auth_model.rb +35 -7
- data/lib/openc3/models/bridge_model.rb +133 -0
- data/lib/openc3/models/config_keyword_model.rb +63 -0
- data/lib/openc3/models/cvt_model.rb +5 -5
- data/lib/openc3/models/db_sharded_model.rb +0 -0
- data/lib/openc3/models/environment_model.rb +0 -0
- data/lib/openc3/models/gem_model.rb +13 -10
- data/lib/openc3/models/host_interface_microservice_model.rb +114 -0
- data/lib/openc3/models/info_model.rb +0 -0
- data/lib/openc3/models/interface_model.rb +179 -20
- data/lib/openc3/models/interface_status_model.rb +0 -0
- data/lib/openc3/models/metadata_model.rb +0 -0
- data/lib/openc3/models/metric_model.rb +0 -0
- data/lib/openc3/models/microservice_model.rb +26 -18
- data/lib/openc3/models/microservice_status_model.rb +0 -0
- data/lib/openc3/models/migration_model.rb +0 -0
- data/lib/openc3/models/model.rb +0 -0
- data/lib/openc3/models/news_model.rb +0 -0
- data/lib/openc3/models/note_model.rb +0 -0
- data/lib/openc3/models/offline_access_model.rb +0 -0
- data/lib/openc3/models/ping_model.rb +0 -0
- data/lib/openc3/models/plugin_model.rb +211 -50
- data/lib/openc3/models/plugin_store_model.rb +0 -0
- data/lib/openc3/models/process_status_model.rb +0 -0
- data/lib/openc3/models/python_package_model.rb +211 -15
- data/lib/openc3/models/queue_model.rb +0 -0
- data/lib/openc3/models/reaction_model.rb +0 -0
- data/lib/openc3/models/reingest_job_model.rb +0 -0
- data/lib/openc3/models/router_model.rb +0 -0
- data/lib/openc3/models/router_status_model.rb +0 -0
- data/lib/openc3/models/scope_model.rb +85 -56
- data/lib/openc3/models/script_engine_model.rb +0 -0
- data/lib/openc3/models/script_status_model.rb +0 -0
- data/lib/openc3/models/secret_model.rb +0 -0
- data/lib/openc3/models/setting_model.rb +546 -3
- data/lib/openc3/models/sorted_model.rb +0 -0
- data/lib/openc3/models/stash_model.rb +0 -0
- data/lib/openc3/models/target_model.rb +210 -31
- data/lib/openc3/models/timeline_model.rb +0 -0
- data/lib/openc3/models/tool_config_model.rb +0 -0
- data/lib/openc3/models/tool_model.rb +34 -20
- data/lib/openc3/models/trigger_group_model.rb +0 -0
- data/lib/openc3/models/trigger_model.rb +20 -0
- data/lib/openc3/models/widget_model.rb +0 -0
- data/lib/openc3/operators/microservice_operator.rb +79 -8
- data/lib/openc3/operators/operator.rb +4 -4
- data/lib/openc3/packets/binary_accessor.rb +0 -0
- data/lib/openc3/packets/command_validator.rb +0 -0
- data/lib/openc3/packets/commands.rb +4 -4
- data/lib/openc3/packets/json_packet.rb +0 -0
- data/lib/openc3/packets/limits.rb +15 -7
- data/lib/openc3/packets/limits_response.rb +0 -0
- data/lib/openc3/packets/packet.rb +5 -1
- data/lib/openc3/packets/packet_config.rb +0 -0
- data/lib/openc3/packets/packet_item.rb +0 -0
- data/lib/openc3/packets/packet_item_limits.rb +0 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +0 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +0 -0
- data/lib/openc3/packets/parsers/state_parser.rb +1 -1
- data/lib/openc3/packets/parsers/xtce_converter.rb +183 -103
- data/lib/openc3/packets/parsers/xtce_parser.rb +71 -23
- data/lib/openc3/packets/structure.rb +9 -3
- data/lib/openc3/packets/structure_item.rb +0 -0
- data/lib/openc3/packets/telemetry.rb +3 -3
- data/lib/openc3/processors/processor.rb +2 -0
- data/lib/openc3/processors/statistics_processor.rb +0 -0
- data/lib/openc3/processors/watermark_processor.rb +0 -0
- data/lib/openc3/processors.rb +0 -0
- data/lib/openc3/script/api_shared.rb +0 -0
- data/lib/openc3/script/autonomic.rb +12 -12
- data/lib/openc3/script/calendar.rb +0 -0
- data/lib/openc3/script/commands.rb +1 -1
- data/lib/openc3/script/critical_cmd.rb +0 -0
- data/lib/openc3/script/exceptions.rb +0 -0
- data/lib/openc3/script/extract.rb +20 -25
- data/lib/openc3/script/limits.rb +0 -0
- data/lib/openc3/script/metadata.rb +0 -0
- data/lib/openc3/script/packages.rb +0 -0
- data/lib/openc3/script/plugins.rb +0 -0
- data/lib/openc3/script/queue.rb +0 -0
- data/lib/openc3/script/screen.rb +0 -0
- data/lib/openc3/script/script.rb +2 -2
- data/lib/openc3/script/script_runner.rb +0 -0
- data/lib/openc3/script/storage.rb +4 -4
- data/lib/openc3/script/suite.rb +0 -0
- data/lib/openc3/script/suite_results.rb +0 -0
- data/lib/openc3/script/suite_runner.rb +26 -0
- data/lib/openc3/script/tables.rb +0 -0
- data/lib/openc3/script/telemetry.rb +9 -3
- data/lib/openc3/script/web_socket_api.rb +247 -134
- data/lib/openc3/script.rb +0 -0
- data/lib/openc3/script_engines/script_engine.rb +0 -0
- data/lib/openc3/streams/mqtt_stream.rb +0 -0
- data/lib/openc3/streams/serial_stream.rb +0 -0
- data/lib/openc3/streams/stream.rb +0 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +0 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +0 -0
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -0
- data/lib/openc3/subpacketizers/subpacketizer.rb +0 -0
- data/lib/openc3/system/system.rb +0 -0
- data/lib/openc3/system/target.rb +0 -0
- data/lib/openc3/system.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +7 -0
- data/lib/openc3/tools/table_manager/table.rb +0 -0
- data/lib/openc3/tools/table_manager/table_config.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +0 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +0 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +0 -0
- data/lib/openc3/tools/test_runner/test.rb +0 -0
- data/lib/openc3/top_level.rb +1 -1
- data/lib/openc3/topics/autonomic_topic.rb +0 -0
- data/lib/openc3/topics/calendar_topic.rb +0 -0
- data/lib/openc3/topics/command_decom_topic.rb +16 -1
- data/lib/openc3/topics/command_topic.rb +0 -0
- data/lib/openc3/topics/config_topic.rb +0 -0
- data/lib/openc3/topics/decom_interface_topic.rb +2 -1
- data/lib/openc3/topics/interface_topic.rb +8 -2
- data/lib/openc3/topics/limits_event_topic.rb +1 -1
- data/lib/openc3/topics/notebook_topic.rb +0 -0
- data/lib/openc3/topics/queue_topic.rb +0 -0
- data/lib/openc3/topics/router_topic.rb +6 -1
- data/lib/openc3/topics/system_events_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_topic.rb +0 -0
- data/lib/openc3/topics/timeline_topic.rb +0 -0
- data/lib/openc3/topics/topic.rb +0 -0
- data/lib/openc3/utilities/authentication.rb +4 -4
- data/lib/openc3/utilities/authorization.rb +0 -0
- data/lib/openc3/utilities/aws_bucket.rb +12 -4
- data/lib/openc3/utilities/bucket.rb +1 -1
- data/lib/openc3/utilities/bucket_file_cache.rb +55 -22
- data/lib/openc3/utilities/bucket_require.rb +0 -0
- data/lib/openc3/utilities/bucket_utilities.rb +3 -4
- data/lib/openc3/utilities/cli_generator.rb +0 -0
- data/lib/openc3/utilities/cmd_log.rb +0 -0
- data/lib/openc3/utilities/config_overlay.rb +75 -0
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +0 -0
- data/lib/openc3/utilities/crc.rb +59 -32
- data/lib/openc3/utilities/csv.rb +5 -5
- data/lib/openc3/utilities/ctrf.rb +0 -0
- data/lib/openc3/utilities/env_helper.rb +0 -0
- data/lib/openc3/utilities/local_bucket.rb +0 -0
- data/lib/openc3/utilities/local_mode.rb +36 -7
- data/lib/openc3/utilities/logger.rb +30 -8
- data/lib/openc3/utilities/message_log.rb +0 -0
- data/lib/openc3/utilities/metric.rb +0 -0
- data/lib/openc3/utilities/migration.rb +0 -0
- data/lib/openc3/utilities/open_telemetry.rb +0 -0
- data/lib/openc3/utilities/process_manager.rb +0 -0
- data/lib/openc3/utilities/pypi_url.rb +0 -0
- data/lib/openc3/utilities/python_proxy.rb +0 -0
- data/lib/openc3/utilities/python_venv.rb +135 -0
- data/lib/openc3/utilities/quaternion.rb +0 -0
- data/lib/openc3/utilities/questdb_client.rb +0 -0
- data/lib/openc3/utilities/redis_secrets.rb +0 -0
- data/lib/openc3/utilities/reingest_job.rb +0 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +5 -1
- data/lib/openc3/utilities/rubygems_url.rb +39 -0
- data/lib/openc3/utilities/running_script.rb +119 -95
- data/lib/openc3/utilities/s3_autoload.rb +5 -5
- data/lib/openc3/utilities/script.rb +52 -12
- data/lib/openc3/utilities/secrets.rb +48 -3
- data/lib/openc3/utilities/simulated_target.rb +0 -0
- data/lib/openc3/utilities/sleeper.rb +0 -0
- data/lib/openc3/utilities/store.rb +0 -0
- data/lib/openc3/utilities/store_autoload.rb +2 -2
- data/lib/openc3/utilities/store_queued.rb +0 -0
- data/lib/openc3/utilities/target_file.rb +18 -1
- data/lib/openc3/utilities/thread_manager.rb +0 -0
- data/lib/openc3/utilities/throttle.rb +0 -0
- data/lib/openc3/utilities/zip.rb +0 -0
- data/lib/openc3/utilities.rb +0 -0
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3/win32/excel.rb +0 -0
- data/lib/openc3/win32/win32.rb +0 -0
- data/lib/openc3/win32/win32_main.rb +0 -0
- data/lib/openc3.rb +2 -2
- data/tasks/gemfile_stats.rake +0 -0
- data/tasks/spec.rake +0 -0
- data/templates/command_validator/command_validator.py +0 -0
- data/templates/command_validator/command_validator.rb +0 -0
- data/templates/conversion/conversion.py +0 -0
- data/templates/conversion/conversion.rb +0 -0
- data/templates/limits_response/response.py +0 -0
- data/templates/limits_response/response.rb +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.py +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -0
- data/templates/plugin/.gitignore +0 -0
- data/templates/plugin/LICENSE.md +0 -0
- data/templates/plugin/README.md +0 -0
- data/templates/plugin/Rakefile +0 -0
- data/templates/plugin/plugin.gemspec +1 -1
- data/templates/plugin/plugin.txt +0 -0
- data/templates/processor/processor.py +1 -1
- data/templates/processor/processor.rb +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- data/templates/target/targets/TARGET/lib/target.py +0 -0
- data/templates/target/targets/TARGET/lib/target.rb +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.py +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.rb +0 -0
- data/templates/target/targets/TARGET/public/README.txt +0 -0
- data/templates/target/targets/TARGET/screens/status.txt +0 -0
- data/templates/target/targets/TARGET/target.txt +0 -0
- data/templates/tool_angular/.editorconfig +0 -0
- data/templates/tool_angular/.gitignore +0 -0
- data/templates/tool_angular/.vscode/extensions.json +0 -0
- data/templates/tool_angular/.vscode/launch.json +0 -0
- data/templates/tool_angular/.vscode/tasks.json +0 -0
- data/templates/tool_angular/angular.json +0 -0
- data/templates/tool_angular/extra-webpack.config.js +0 -0
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_angular/src/app/app-routing.module.ts +0 -0
- data/templates/tool_angular/src/app/app.component.html +0 -0
- data/templates/tool_angular/src/app/app.component.scss +0 -0
- data/templates/tool_angular/src/app/app.component.spec.ts +0 -0
- data/templates/tool_angular/src/app/app.component.ts +0 -0
- data/templates/tool_angular/src/app/app.module.ts +0 -0
- data/templates/tool_angular/src/app/custom-overlay-container.ts +0 -0
- data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +0 -0
- data/templates/tool_angular/src/app/openc3-api.d.ts +0 -0
- data/templates/tool_angular/src/assets/.gitkeep +0 -0
- data/templates/tool_angular/src/environments/environment.prod.ts +0 -0
- data/templates/tool_angular/src/environments/environment.ts +0 -0
- data/templates/tool_angular/src/favicon.ico +0 -0
- data/templates/tool_angular/src/index.html +0 -0
- data/templates/tool_angular/src/main.single-spa.ts +0 -0
- data/templates/tool_angular/src/single-spa/asset-url.ts +0 -0
- data/templates/tool_angular/src/single-spa/single-spa-props.ts +0 -0
- data/templates/tool_angular/src/styles.scss +0 -0
- data/templates/tool_angular/tsconfig.app.json +0 -0
- data/templates/tool_angular/tsconfig.json +0 -0
- data/templates/tool_angular/tsconfig.spec.json +0 -0
- data/templates/tool_react/.eslintrc +0 -0
- data/templates/tool_react/.gitignore +0 -0
- data/templates/tool_react/.prettierignore +0 -0
- data/templates/tool_react/babel.config.json +0 -0
- data/templates/tool_react/jest.config.js +0 -0
- data/templates/tool_react/package.json +1 -1
- data/templates/tool_react/src/openc3-tool_name.js +0 -0
- data/templates/tool_react/src/root.component.js +0 -0
- data/templates/tool_react/src/root.component.test.js +0 -0
- data/templates/tool_react/webpack.config.js +0 -0
- data/templates/tool_svelte/.gitignore +0 -0
- data/templates/tool_svelte/.prettierignore +0 -0
- data/templates/tool_svelte/.prettierrc.js +0 -0
- data/templates/tool_svelte/babel.config.js +0 -0
- data/templates/tool_svelte/build/smui.css +0 -0
- data/templates/tool_svelte/jest.config.js +0 -0
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_svelte/rollup.config.js +0 -0
- data/templates/tool_svelte/src/App.svelte +0 -0
- data/templates/tool_svelte/src/App.test.js +0 -0
- data/templates/tool_svelte/src/theme/_smui-theme.scss +0 -0
- data/templates/tool_svelte/src/tool_name.js +0 -0
- data/templates/tool_vue/.env.standalone +0 -0
- data/templates/tool_vue/.gitignore +0 -0
- data/templates/tool_vue/.prettierrc.cjs +0 -0
- data/templates/tool_vue/eslint.config.mjs +0 -0
- data/templates/tool_vue/jsconfig.json +0 -0
- data/templates/tool_vue/package.json +3 -3
- data/templates/tool_vue/src/App.vue +0 -0
- data/templates/tool_vue/src/main.js +0 -0
- data/templates/tool_vue/src/router.js +0 -0
- data/templates/tool_vue/src/tools/tool_name/tool_name.vue +0 -0
- data/templates/tool_vue/vite.config.js +1 -1
- data/templates/widget/.prettierrc.cjs +0 -0
- data/templates/widget/LICENSE.md +0 -0
- data/templates/widget/Rakefile +0 -0
- data/templates/widget/package.json +2 -2
- data/templates/widget/src/Widget.vue +0 -0
- data/templates/widget/vite.config.js +0 -0
- metadata +40 -11
- data/templates/tool_vue/.nycrc +0 -3
- data/templates/widget/.nycrc +0 -3
|
@@ -30,6 +30,7 @@ require 'openc3/topics/config_topic'
|
|
|
30
30
|
require 'openc3/system'
|
|
31
31
|
require 'openc3/utilities/local_mode'
|
|
32
32
|
require 'openc3/utilities/bucket'
|
|
33
|
+
require 'openc3/utilities/target_file'
|
|
33
34
|
require 'openc3/utilities/zip'
|
|
34
35
|
require 'fileutils'
|
|
35
36
|
require 'ostruct'
|
|
@@ -50,6 +51,7 @@ module OpenC3
|
|
|
50
51
|
ERB_EXTENSIONS = %w(.txt .rb .py .json .yaml .yml)
|
|
51
52
|
ITEM_MAP_CACHE_TIMEOUT = 10.0
|
|
52
53
|
PACKET_CACHE_TIMEOUT = 10.0
|
|
54
|
+
MAX_COLUMN_HEADER_LENGTH = 127 # QuestDB column header limit for item/param names
|
|
53
55
|
@@item_map_cache = {}
|
|
54
56
|
@@packet_cache = {}
|
|
55
57
|
@@packet_cache_mutex = Mutex.new
|
|
@@ -76,6 +78,7 @@ module OpenC3
|
|
|
76
78
|
attr_accessor :tlm_log_retain_time
|
|
77
79
|
attr_accessor :cmd_decom_retain_time
|
|
78
80
|
attr_accessor :tlm_decom_retain_time
|
|
81
|
+
attr_accessor :decom_flush_period
|
|
79
82
|
attr_accessor :cleanup_poll_time
|
|
80
83
|
attr_accessor :needs_dependencies
|
|
81
84
|
attr_accessor :target_microservices
|
|
@@ -103,49 +106,123 @@ module OpenC3
|
|
|
103
106
|
targets = self.all(scope: scope)
|
|
104
107
|
targets.each { |_target_name, target| target['modified'] = false }
|
|
105
108
|
|
|
109
|
+
modified_targets = []
|
|
106
110
|
if ENV['OPENC3_LOCAL_MODE']
|
|
107
|
-
modified_targets
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if targets.has_key?(target_name)
|
|
117
|
-
targets[target_name]['modified'] = true
|
|
118
|
-
end
|
|
119
|
-
end
|
|
111
|
+
modified_targets += OpenC3::LocalMode.modified_targets(scope: scope)
|
|
112
|
+
end
|
|
113
|
+
# Always list the bucket, even in local mode, since the local directory
|
|
114
|
+
# only holds what COSMOS itself wrote there
|
|
115
|
+
modified_targets += Bucket.getClient().list_files(bucket: ENV['OPENC3_CONFIG_BUCKET'], path: "#{scope}/targets_modified/", only_directories: true)
|
|
116
|
+
modified_targets.each do |target_name|
|
|
117
|
+
# A target could have been deleted without removing the modified files
|
|
118
|
+
# Thus we have to check for the existence of the target_name key
|
|
119
|
+
targets[target_name]['modified'] = true if targets[target_name]
|
|
120
120
|
end
|
|
121
121
|
# Sort (which turns hash to array) and return hash
|
|
122
122
|
# This enables a consistent listing of the targets
|
|
123
123
|
targets.sort.to_h
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
# Splits a plugin instance name ("openc3-cosmos-demo-7.2.0.gem__0") into
|
|
127
|
+
# [base_name, version] (["openc3-cosmos-demo", "7.2.0"]), or nil when the
|
|
128
|
+
# name doesn't carry a version segment. Drops the "__N" install-instance
|
|
129
|
+
# suffix and the ".gem" extension first.
|
|
130
|
+
def self.plugin_name_version(plugin_instance)
|
|
131
|
+
return nil if plugin_instance.nil? || plugin_instance.empty?
|
|
132
|
+
gem = plugin_instance.split('__')[0].sub(/\.gem\z/, '')
|
|
133
|
+
parts = gem.split('-')
|
|
134
|
+
return nil if parts.length < 2
|
|
135
|
+
[parts[0..-2].join('-'), parts[-1]]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# "name version" of the plugin that installed this target (e.g.
|
|
139
|
+
# "openc3-cosmos-demo 7.2.0"), derived from the plugin instance name
|
|
140
|
+
# ("openc3-cosmos-demo-7.2.0.gem__0"), or nil if unavailable. Used to
|
|
141
|
+
# annotate the Version History baseline with the file's origin.
|
|
142
|
+
def self.plugin_version_label(target_name, scope:)
|
|
143
|
+
model = get(name: target_name, scope: scope)
|
|
144
|
+
name, version = plugin_name_version(model && model['plugin'])
|
|
145
|
+
return nil unless name
|
|
146
|
+
"#{name} #{version}"
|
|
147
|
+
rescue
|
|
148
|
+
nil
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Version-stripped plugin base name that owns this target, e.g.
|
|
152
|
+
# "openc3-cosmos-demo" from instance "openc3-cosmos-demo-7.2.0.gem__0".
|
|
153
|
+
# Used as the per-plugin Version History repo key: stable across upgrades
|
|
154
|
+
# (only the version segment changes), so history survives version bumps.
|
|
155
|
+
# Returns nil when the target has no owning plugin (e.g. a hand-created
|
|
156
|
+
# target); callers fall back to a no-plugin bucket.
|
|
157
|
+
def self.plugin_base_name(target_name, scope:)
|
|
158
|
+
model = get(name: target_name, scope: scope)
|
|
159
|
+
name, _version = plugin_name_version(model && model['plugin'])
|
|
160
|
+
name
|
|
161
|
+
rescue
|
|
162
|
+
nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Uninstall-only: remove a plugin's entire Version History repo. Called
|
|
166
|
+
# from the CLI uninstall path with the plugin instance name; upgrade reuses
|
|
167
|
+
# the repo and must never call this. No-op in Core builds (or whenever
|
|
168
|
+
# OPENC3_VERSION_HISTORY_DIR is unset) since VersionStore is absent or
|
|
169
|
+
# disabled. Best-effort: a failure here must not abort the uninstall.
|
|
170
|
+
def self.destroy_script_versions(plugin_instance_name, scope:)
|
|
171
|
+
name, _version = plugin_name_version(plugin_instance_name)
|
|
172
|
+
return unless name
|
|
173
|
+
begin
|
|
174
|
+
require 'openc3-enterprise/utilities/version_store'
|
|
175
|
+
rescue LoadError
|
|
176
|
+
return
|
|
177
|
+
end
|
|
178
|
+
::VersionStore.destroy_repo(scope: scope, plugin: name)
|
|
179
|
+
rescue => e
|
|
180
|
+
Logger.warn("destroy_script_versions failed for #{scope}/#{plugin_instance_name}: #{e.message}")
|
|
181
|
+
end
|
|
182
|
+
|
|
126
183
|
# Given target's modified file list
|
|
184
|
+
# Returns the modified files as names relative to the scope,
|
|
185
|
+
# i.e. "INST/procedures/new.rb"
|
|
127
186
|
def self.modified_files(target_name, scope:)
|
|
128
187
|
modified = []
|
|
129
188
|
|
|
130
189
|
if ENV['OPENC3_LOCAL_MODE']
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
# The trailing slash is important!
|
|
136
|
-
prefix: "#{scope}/targets_modified/#{target_name}/",
|
|
137
|
-
)
|
|
138
|
-
resp.each do |item|
|
|
139
|
-
# Results look like DEFAULT/targets_modified/INST/procedures/new.rb
|
|
140
|
-
# so split on '/' and ignore the first two values
|
|
141
|
-
modified << item.key.split('/')[2..-1].join('/')
|
|
190
|
+
# LocalMode reports target relative paths, i.e. "procedures/new.rb",
|
|
191
|
+
# so add the target name to match the bucket listing below
|
|
192
|
+
modified += OpenC3::LocalMode.modified_files(target_name, scope: scope).map do |file_path|
|
|
193
|
+
"#{target_name}/#{file_path}"
|
|
142
194
|
end
|
|
143
195
|
end
|
|
196
|
+
# Always list the bucket, even in local mode. The local directory only
|
|
197
|
+
# holds what COSMOS itself wrote there, so a file placed directly in the
|
|
198
|
+
# bucket is modified but has no local copy.
|
|
199
|
+
resp = Bucket.getClient().list_objects(
|
|
200
|
+
bucket: ENV['OPENC3_CONFIG_BUCKET'],
|
|
201
|
+
# The trailing slash is important!
|
|
202
|
+
prefix: "#{scope}/targets_modified/#{target_name}/",
|
|
203
|
+
)
|
|
204
|
+
resp.each do |item|
|
|
205
|
+
# Results look like DEFAULT/targets_modified/INST/procedures/new.rb
|
|
206
|
+
# so split on '/' and ignore the first two values
|
|
207
|
+
modified << item.key.split('/')[2..-1].join('/')
|
|
208
|
+
end
|
|
144
209
|
# Sort to enable a consistent listing of the modified files
|
|
145
|
-
modified.sort
|
|
210
|
+
modified.uniq.sort
|
|
146
211
|
end
|
|
147
212
|
|
|
148
|
-
|
|
213
|
+
# files: optional list of specific modified files to delete, each a name
|
|
214
|
+
# relative to scope ("TARGET/sub/path", matching modified_files output).
|
|
215
|
+
# When given, only those files are removed (used by plugin upgrade to drop
|
|
216
|
+
# some modified files while keeping others); when nil, every modified file
|
|
217
|
+
# for the target is removed (the original behavior).
|
|
218
|
+
def self.delete_modified(target_name, scope:, files: nil)
|
|
219
|
+
if files && !files.empty?
|
|
220
|
+
files.each do |name|
|
|
221
|
+
# TargetFile.destroy handles both local mode and the bucket.
|
|
222
|
+
OpenC3::TargetFile.destroy(scope, name)
|
|
223
|
+
end
|
|
224
|
+
return
|
|
225
|
+
end
|
|
149
226
|
if ENV['OPENC3_LOCAL_MODE']
|
|
150
227
|
OpenC3::LocalMode.delete_modified(target_name, scope: scope)
|
|
151
228
|
end
|
|
@@ -224,7 +301,7 @@ module OpenC3
|
|
|
224
301
|
|
|
225
302
|
# Assume it exists and just try to get it to avoid an extra call to Store.exist?
|
|
226
303
|
json = store_for_target(target_name, scope: scope).hget("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name)
|
|
227
|
-
raise "Packet '#{target_name} #{packet_name}' does not exist" if json.nil?
|
|
304
|
+
raise "Packet definition '#{target_name} #{packet_name}' does not exist" if json.nil?
|
|
228
305
|
|
|
229
306
|
packet = JSON.parse(json, allow_nan: true, create_additions: true)
|
|
230
307
|
|
|
@@ -245,7 +322,7 @@ module OpenC3
|
|
|
245
322
|
# @return [Array<Hash>] All packet hashes under the target_name
|
|
246
323
|
def self.packets(target_name, type: :TLM, scope:)
|
|
247
324
|
raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
|
|
248
|
-
raise "Target '#{target_name}' does not exist for scope: #{scope}" unless get(name: target_name, scope: scope)
|
|
325
|
+
raise "Target '#{target_name}' does not exist for scope: #{scope} (TargetModel)" unless get(name: target_name, scope: scope)
|
|
249
326
|
|
|
250
327
|
result = []
|
|
251
328
|
packets = store_for_target(target_name, scope: scope).hgetall("#{scope}__openc3#{type.to_s.downcase}__#{target_name}")
|
|
@@ -281,7 +358,7 @@ module OpenC3
|
|
|
281
358
|
def self.packet_item(target_name, packet_name, item_name, type: :TLM, scope:)
|
|
282
359
|
packet = packet(target_name, packet_name, type: type, scope: scope)
|
|
283
360
|
item = packet['items'].find { |item| item['name'] == item_name.to_s }
|
|
284
|
-
raise "Item '#{packet['target_name']} #{packet['packet_name']} #{item_name}' does not exist" unless item
|
|
361
|
+
raise "Item '#{packet['target_name']} #{packet['packet_name']} #{item_name}' does not exist (TargetModel)" unless item
|
|
285
362
|
item
|
|
286
363
|
end
|
|
287
364
|
|
|
@@ -400,6 +477,7 @@ module OpenC3
|
|
|
400
477
|
tlm_log_retain_time: nil,
|
|
401
478
|
cmd_decom_retain_time: nil,
|
|
402
479
|
tlm_decom_retain_time: nil,
|
|
480
|
+
decom_flush_period: 5.0,
|
|
403
481
|
cleanup_poll_time: 3600,
|
|
404
482
|
needs_dependencies: false,
|
|
405
483
|
target_microservices: {},
|
|
@@ -428,6 +506,7 @@ module OpenC3
|
|
|
428
506
|
@tlm_log_retain_time = tlm_log_retain_time
|
|
429
507
|
@cmd_decom_retain_time = cmd_decom_retain_time
|
|
430
508
|
@tlm_decom_retain_time = tlm_decom_retain_time
|
|
509
|
+
@decom_flush_period = decom_flush_period
|
|
431
510
|
@cleanup_poll_time = cleanup_poll_time
|
|
432
511
|
@needs_dependencies = needs_dependencies
|
|
433
512
|
@target_microservices = target_microservices
|
|
@@ -461,6 +540,7 @@ module OpenC3
|
|
|
461
540
|
'tlm_log_retain_time' => @tlm_log_retain_time,
|
|
462
541
|
'cmd_decom_retain_time' => @cmd_decom_retain_time,
|
|
463
542
|
'tlm_decom_retain_time' => @tlm_decom_retain_time,
|
|
543
|
+
'decom_flush_period' => @decom_flush_period,
|
|
464
544
|
'cleanup_poll_time' => @cleanup_poll_time,
|
|
465
545
|
'needs_dependencies' => @needs_dependencies,
|
|
466
546
|
'target_microservices' => @target_microservices.as_json(),
|
|
@@ -515,6 +595,9 @@ module OpenC3
|
|
|
515
595
|
if @tlm_decom_retain_time and !@tlm_decom_retain_time.match?(/^\d+[hdwMy]$/)
|
|
516
596
|
raise ConfigParser::Error.new(parser, "TLM_DECOM_RETAIN_TIME must be a number followed by h, d, w, M, or y (e.g., 24h, 7d, 1y)")
|
|
517
597
|
end
|
|
598
|
+
when 'DECOM_FLUSH_PERIOD'
|
|
599
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Flush period in seconds>")
|
|
600
|
+
@decom_flush_period = Float(parameters[0])
|
|
518
601
|
when 'REDUCED_MINUTE_LOG_RETAIN_TIME', 'REDUCED_HOUR_LOG_RETAIN_TIME', 'REDUCED_DAY_LOG_RETAIN_TIME', 'REDUCED_LOG_RETAIN_TIME'
|
|
519
602
|
# DEPRECATED
|
|
520
603
|
when 'REDUCER_DISABLE', 'REDUCER_DISABLED', 'REDUCER_MAX_CPU_UTILIZATION', 'REDUCED_MAX_CPU_UTILIZATION'
|
|
@@ -576,11 +659,23 @@ module OpenC3
|
|
|
576
659
|
return nil
|
|
577
660
|
end
|
|
578
661
|
|
|
579
|
-
|
|
662
|
+
# upgrade_context (plugin upgrades only) drives two modes, both keyed by
|
|
663
|
+
# the deployed file name "TARGET/sub/path" (matches modified_files output):
|
|
664
|
+
# { diff_collector: [] } — dry run (with validate_only): append the names
|
|
665
|
+
# of modified files whose live content differs from the rendered plugin
|
|
666
|
+
# content. Read-only; used to warn before an upgrade.
|
|
667
|
+
# { username:, plugin: "name version", version_files: [<name>...] } — for
|
|
668
|
+
# each listed file with a modified copy: record the modified copy in
|
|
669
|
+
# Version History, drop the shadow so the plugin content becomes current,
|
|
670
|
+
# then commit the incoming content as a plugin-upgrade version.
|
|
671
|
+
# nil (the default and Core builds without VersionStore) = no-op.
|
|
672
|
+
def deploy(gem_path, variables, validate_only: false, upgrade_context: nil)
|
|
580
673
|
variables["target_name"] = @name
|
|
581
674
|
start_path = "/targets/#{@folder_name}/"
|
|
582
675
|
temp_dir = Dir.mktmpdir
|
|
583
676
|
found = false
|
|
677
|
+
diff_collector = upgrade_context && upgrade_context[:diff_collector]
|
|
678
|
+
versioning = !validate_only && upgrade_context && upgrade_context[:version_files] && version_store_available?
|
|
584
679
|
begin
|
|
585
680
|
target_path = gem_path + start_path + "**/*"
|
|
586
681
|
Dir.glob(target_path) do |filename|
|
|
@@ -616,15 +711,30 @@ module OpenC3
|
|
|
616
711
|
File.open(local_path, 'wb') { |file| file.write(data) }
|
|
617
712
|
found = true
|
|
618
713
|
@bucket.put_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: key, body: data) unless validate_only
|
|
714
|
+
|
|
715
|
+
# Plugin upgrade: either collect this file into the diff (dry run) or
|
|
716
|
+
# take it from the plugin while preserving the modified copy in
|
|
717
|
+
# Version History. Both skip files with no modified copy.
|
|
718
|
+
name = "#{@name}/#{target_folder_path}"
|
|
719
|
+
if diff_collector
|
|
720
|
+
collect_modified_diff(name, data, diff_collector)
|
|
721
|
+
elsif versioning && upgrade_context[:version_files].include?(name)
|
|
722
|
+
apply_upgrade_version(name, data, upgrade_context)
|
|
723
|
+
end
|
|
619
724
|
end
|
|
620
725
|
raise "No target files found at #{target_path}" unless found
|
|
621
726
|
|
|
622
727
|
target_folder = File.join(temp_dir, @name)
|
|
623
728
|
# Build a System for just this target
|
|
624
729
|
system = System.new([@name], temp_dir)
|
|
730
|
+
check_column_header_lengths(system)
|
|
625
731
|
if variables["xtce_output"]
|
|
626
732
|
puts "Converting target #{@name} to .xtce files in #{variables["xtce_output"]}/#{@name}"
|
|
627
|
-
|
|
733
|
+
if variables['time_association_name'].to_s.empty?
|
|
734
|
+
puts " No packet time item given, so no TimeAssociation will be written."
|
|
735
|
+
else
|
|
736
|
+
puts " Using mnemonic '#{variables['time_association_name']}' as the packet time item."
|
|
737
|
+
end
|
|
628
738
|
system.packet_config.to_xtce(variables["xtce_output"], variables['time_association_name'])
|
|
629
739
|
end
|
|
630
740
|
unless validate_only
|
|
@@ -638,6 +748,74 @@ module OpenC3
|
|
|
638
748
|
end
|
|
639
749
|
end
|
|
640
750
|
|
|
751
|
+
# Version History is an Enterprise feature. The plugin deploy runs in the
|
|
752
|
+
# cmd-tlm-api process, which (unlike script-runner-api) doesn't otherwise
|
|
753
|
+
# require the store, so lazily load it on demand. Returns false in Core
|
|
754
|
+
# builds where the Enterprise gem isn't present.
|
|
755
|
+
def version_store_available?
|
|
756
|
+
return true if defined?(::VersionStore)
|
|
757
|
+
require 'openc3-enterprise/utilities/version_store'
|
|
758
|
+
defined?(::VersionStore) ? true : false
|
|
759
|
+
rescue LoadError
|
|
760
|
+
false
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
# See deploy/upgrade_context. Reads the modified shadow directly (not
|
|
764
|
+
# TargetFile.body, which would fall back to the just-overwritten pristine
|
|
765
|
+
# copy), commits it, removes it, then commits the incoming plugin content.
|
|
766
|
+
# Best-effort: a versioning failure must not abort the plugin upgrade.
|
|
767
|
+
def apply_upgrade_version(name, new_data, ctx)
|
|
768
|
+
modified_key = "#{@scope}/targets_modified/#{name}"
|
|
769
|
+
resp = @bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: modified_key)
|
|
770
|
+
return unless resp && resp.body
|
|
771
|
+
old_body = resp.body.read
|
|
772
|
+
# Nothing actually changed — the modification already matches the plugin.
|
|
773
|
+
# Leave the (identical) shadow in place and create no version churn.
|
|
774
|
+
return if old_body.b == new_data.b
|
|
775
|
+
old_body = old_body.force_encoding('UTF-8') unless File.extname(name) == '.bin'
|
|
776
|
+
# Preserve the pre-upgrade (user-modified) content as a version.
|
|
777
|
+
# Idempotent: a no-op when it already matches the latest version.
|
|
778
|
+
::VersionStore.commit(scope: @scope, name: name, text: old_body)
|
|
779
|
+
# Drop the modified shadow so the plugin file (already written to
|
|
780
|
+
# targets/) becomes the live content.
|
|
781
|
+
OpenC3::TargetFile.destroy(@scope, name)
|
|
782
|
+
# Commit the incoming plugin content as a plugin-upgrade version,
|
|
783
|
+
# attributed to the installing user.
|
|
784
|
+
::VersionStore.commit(scope: @scope, name: name, text: new_data,
|
|
785
|
+
username: ctx[:username], source: 'plugin-upgrade', plugin: ctx[:plugin])
|
|
786
|
+
rescue => e
|
|
787
|
+
Logger.warn("Version History upgrade capture failed for #{@scope}/#{name}: #{e.message}")
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
# Dry-run companion to apply_upgrade_version: append name to collector when
|
|
791
|
+
# a modified copy exists and differs (by bytes) from the rendered plugin
|
|
792
|
+
# content. Read-only.
|
|
793
|
+
def collect_modified_diff(name, new_data, collector)
|
|
794
|
+
resp = @bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: "#{@scope}/targets_modified/#{name}")
|
|
795
|
+
return unless resp && resp.body
|
|
796
|
+
collector << name if resp.body.read.b != new_data.b
|
|
797
|
+
rescue => e
|
|
798
|
+
Logger.warn("Modified diff check failed for #{@scope}/#{name}: #{e.message}")
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
def check_column_header_lengths(system)
|
|
802
|
+
too_long = []
|
|
803
|
+
[system.packet_config.telemetry, system.packet_config.commands].each do |packets_by_target|
|
|
804
|
+
packets_by_target.each do |target_name, packets|
|
|
805
|
+
packets.each do |packet_name, packet|
|
|
806
|
+
packet.sorted_items.each do |item|
|
|
807
|
+
if item.name.length > MAX_COLUMN_HEADER_LENGTH
|
|
808
|
+
too_long << "#{target_name} #{packet_name} #{item.name} (#{item.name.length})"
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
end
|
|
812
|
+
end
|
|
813
|
+
end
|
|
814
|
+
unless too_long.empty?
|
|
815
|
+
raise "Item / parameter names must be #{MAX_COLUMN_HEADER_LENGTH} characters or less (QuestDB column header limit). The following are too long:\n #{too_long.join("\n ")}"
|
|
816
|
+
end
|
|
817
|
+
end
|
|
818
|
+
|
|
641
819
|
def undeploy
|
|
642
820
|
prefix = "#{@scope}/targets/#{@name}/"
|
|
643
821
|
objects = @bucket.list_objects(bucket: ENV['OPENC3_CONFIG_BUCKET'], prefix: prefix)
|
|
@@ -1032,6 +1210,7 @@ module OpenC3
|
|
|
1032
1210
|
options = []
|
|
1033
1211
|
options << ["CMD_DECOM_RETAIN_TIME", @cmd_decom_retain_time] if @cmd_decom_retain_time
|
|
1034
1212
|
options << ["TLM_DECOM_RETAIN_TIME", @tlm_decom_retain_time] if @tlm_decom_retain_time
|
|
1213
|
+
options << ["DECOM_FLUSH_PERIOD", @decom_flush_period] if @decom_flush_period
|
|
1035
1214
|
microservice = MicroserviceModel.new(
|
|
1036
1215
|
name: microservice_name,
|
|
1037
1216
|
folder_name: @folder_name,
|
|
File without changes
|
|
File without changes
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# if purchased from OpenC3, Inc.
|
|
17
17
|
|
|
18
18
|
require 'openc3/models/model'
|
|
19
|
+
require 'openc3/topics/config_topic'
|
|
19
20
|
# require 'openc3/models/scope_model' # Circular require
|
|
20
21
|
require 'openc3/utilities/bucket'
|
|
21
22
|
require 'openc3/utilities/bucket_utilities'
|
|
@@ -25,6 +26,13 @@ module OpenC3
|
|
|
25
26
|
class ToolModel < Model
|
|
26
27
|
PRIMARY_KEY = 'openc3_tools'
|
|
27
28
|
|
|
29
|
+
# Tools are global to the entire COSMOS installation and are always stored
|
|
30
|
+
# in the DEFAULT scope. The frontend navigation always requests the tool
|
|
31
|
+
# list from DEFAULT, so a tool installed into any other scope would be
|
|
32
|
+
# inaccessible. Every scope parameter in this class is therefore ignored
|
|
33
|
+
# and replaced with TOOL_SCOPE.
|
|
34
|
+
TOOL_SCOPE = 'DEFAULT'
|
|
35
|
+
|
|
28
36
|
attr_accessor :folder_name
|
|
29
37
|
attr_accessor :icon
|
|
30
38
|
attr_accessor :url
|
|
@@ -39,21 +47,24 @@ module OpenC3
|
|
|
39
47
|
|
|
40
48
|
# NOTE: The following three class methods are used by the ModelController
|
|
41
49
|
# and are reimplemented to enable various Model class methods to work
|
|
50
|
+
# NOTE: scope is deprecated since 7.3.0 as tools always live in the DEFAULT scope, see TOOL_SCOPE
|
|
42
51
|
def self.get(name:, scope: nil)
|
|
43
|
-
super("#{
|
|
52
|
+
super("#{TOOL_SCOPE}__#{PRIMARY_KEY}", name: name)
|
|
44
53
|
end
|
|
45
54
|
|
|
55
|
+
# NOTE: scope is deprecated since 7.3.0 as tools always live in the DEFAULT scope, see TOOL_SCOPE
|
|
46
56
|
def self.names(scope: nil)
|
|
47
57
|
array = []
|
|
48
|
-
all(
|
|
58
|
+
all().each do |name, _tool|
|
|
49
59
|
array << name
|
|
50
60
|
end
|
|
51
61
|
array
|
|
52
62
|
end
|
|
53
63
|
|
|
64
|
+
# NOTE: scope is deprecated since 7.3.0 as tools always live in the DEFAULT scope, see TOOL_SCOPE
|
|
54
65
|
def self.all(scope: nil)
|
|
55
66
|
ordered_array = []
|
|
56
|
-
tools = unordered_all(
|
|
67
|
+
tools = unordered_all()
|
|
57
68
|
tools.each do |_name, tool|
|
|
58
69
|
ordered_array << tool
|
|
59
70
|
end
|
|
@@ -65,14 +76,10 @@ module OpenC3
|
|
|
65
76
|
ordered_hash
|
|
66
77
|
end
|
|
67
78
|
|
|
79
|
+
# Tools only exist in the DEFAULT scope. Kept for backwards compatibility
|
|
80
|
+
# with the ToolsController importmap endpoint.
|
|
68
81
|
def self.all_scopes
|
|
69
|
-
|
|
70
|
-
scopes = OpenC3::ScopeModel.all
|
|
71
|
-
scopes.each do |key, _scope|
|
|
72
|
-
tools = unordered_all(scope: key)
|
|
73
|
-
result.merge!(tools)
|
|
74
|
-
end
|
|
75
|
-
result
|
|
82
|
+
unordered_all()
|
|
76
83
|
end
|
|
77
84
|
|
|
78
85
|
# Called by the PluginModel to allow this class to validate it's top-level keyword: "TOOL"
|
|
@@ -80,7 +87,8 @@ module OpenC3
|
|
|
80
87
|
case keyword
|
|
81
88
|
when 'TOOL'
|
|
82
89
|
parser.verify_num_parameters(2, 2, "TOOL <Folder Name> <Name>")
|
|
83
|
-
|
|
90
|
+
# NOTE: scope is intentionally ignored, see TOOL_SCOPE
|
|
91
|
+
return self.new(folder_name: parameters[0], name: parameters[1], plugin: plugin, needs_dependencies: needs_dependencies, scope: TOOL_SCOPE)
|
|
84
92
|
else
|
|
85
93
|
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Tool: #{keyword} #{parameters.join(" ")}")
|
|
86
94
|
end
|
|
@@ -89,8 +97,10 @@ module OpenC3
|
|
|
89
97
|
|
|
90
98
|
# The ToolsTab.vue calls the ToolsController which uses this method to reorder the tools
|
|
91
99
|
# Position is index in the list starting with 0 = first
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
# NOTE: scope is deprecated since 7.3.0 as tools always live in the DEFAULT scope, see TOOL_SCOPE
|
|
101
|
+
def self.set_position(name:, position:, scope: nil)
|
|
102
|
+
tool_scope = TOOL_SCOPE
|
|
103
|
+
moving = from_json(get(name: name, scope: tool_scope), scope: tool_scope)
|
|
94
104
|
old_pos = moving.position
|
|
95
105
|
new_pos = position
|
|
96
106
|
direction = :down
|
|
@@ -101,8 +111,8 @@ module OpenC3
|
|
|
101
111
|
end
|
|
102
112
|
|
|
103
113
|
# Go through all the tools and reorder
|
|
104
|
-
all(scope:
|
|
105
|
-
tool_model = from_json(tool, scope:
|
|
114
|
+
all(scope: tool_scope).each do |_tool_name, tool|
|
|
115
|
+
tool_model = from_json(tool, scope: tool_scope)
|
|
106
116
|
# Update the requested model to the new position
|
|
107
117
|
if tool_model.name == name
|
|
108
118
|
tool_model.position = position
|
|
@@ -134,9 +144,11 @@ module OpenC3
|
|
|
134
144
|
needs_dependencies: false,
|
|
135
145
|
disable_erb: nil,
|
|
136
146
|
import_map_items: nil,
|
|
137
|
-
scope:
|
|
147
|
+
scope: nil # NOTE: deprecated since 7.3.0 as tools are always created in the DEFAULT scope, see TOOL_SCOPE
|
|
138
148
|
)
|
|
139
|
-
|
|
149
|
+
# Tools are always created in the DEFAULT scope regardless of the scope
|
|
150
|
+
# the plugin is being installed into, see TOOL_SCOPE
|
|
151
|
+
super("#{TOOL_SCOPE}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at, scope: TOOL_SCOPE)
|
|
140
152
|
@folder_name = folder_name
|
|
141
153
|
@icon = icon
|
|
142
154
|
@url = url
|
|
@@ -156,14 +168,15 @@ module OpenC3
|
|
|
156
168
|
end
|
|
157
169
|
|
|
158
170
|
def create(update: false, force: false, queued: false)
|
|
159
|
-
tools = self.class.all(
|
|
171
|
+
tools = self.class.all()
|
|
160
172
|
|
|
161
173
|
# Make sure a tool with this folder_name doesn't already exist
|
|
174
|
+
# NOTE: Tools are global (TOOL_SCOPE) so this check is across all scopes
|
|
162
175
|
unless update
|
|
163
176
|
if @folder_name
|
|
164
177
|
tools.each do |_tool_name, tool|
|
|
165
178
|
if tool['folder_name'] == @folder_name
|
|
166
|
-
raise "Tool with folder_name #{@folder_name} already exists at create"
|
|
179
|
+
raise "Tool with folder_name #{@folder_name} already exists at create. Tools are global to the entire COSMOS installation and can only be installed once."
|
|
167
180
|
end
|
|
168
181
|
end
|
|
169
182
|
end
|
|
@@ -308,8 +321,9 @@ module OpenC3
|
|
|
308
321
|
##################################################
|
|
309
322
|
|
|
310
323
|
# Returns the list of tools or the default OpenC3 tool set if no tools have been created
|
|
324
|
+
# NOTE: scope is deprecated since 7.3.0 as tools always live in the DEFAULT scope, see TOOL_SCOPE
|
|
311
325
|
def self.unordered_all(scope: nil)
|
|
312
|
-
tools = Store.hgetall("#{
|
|
326
|
+
tools = Store.hgetall("#{TOOL_SCOPE}__#{PRIMARY_KEY}")
|
|
313
327
|
tools.each do |key, value|
|
|
314
328
|
tools[key] = JSON.parse(value, allow_nan: true, create_additions: true)
|
|
315
329
|
end
|
|
File without changes
|
|
@@ -50,6 +50,7 @@ module OpenC3
|
|
|
50
50
|
STRING_TYPE = 'string'.freeze
|
|
51
51
|
REGEX_TYPE = 'regex'.freeze
|
|
52
52
|
TRIGGER_TYPE = 'trigger'.freeze
|
|
53
|
+
ITEM_VALUE_TYPES = ['RAW', 'CONVERTED', 'FORMATTED', 'WITH_UNITS'].freeze
|
|
53
54
|
|
|
54
55
|
def self.create_unique_name(group:, scope:)
|
|
55
56
|
trigger_names = self.names(group: group, scope: scope)
|
|
@@ -180,6 +181,24 @@ module OpenC3
|
|
|
180
181
|
end
|
|
181
182
|
end
|
|
182
183
|
|
|
184
|
+
# Validate the items hold a legal valueType and reference telemetry items
|
|
185
|
+
# which actually exist. Only called on create and update, never from initialize.
|
|
186
|
+
# Anything which can reject an already persisted trigger must live here rather than
|
|
187
|
+
# in validate_operand, because validate_operand runs on every from_json
|
|
188
|
+
def validate_trigger_items
|
|
189
|
+
{'left' => @left, 'right' => @right}.each do |side, operand|
|
|
190
|
+
next unless operand.is_a?(Hash) and operand['type'] == ITEM_TYPE
|
|
191
|
+
unless ITEM_VALUE_TYPES.include?(operand['valueType'])
|
|
192
|
+
raise TriggerInputError.new "invalid #{side} operand, valueType '#{operand['valueType']}' must be one of #{ITEM_VALUE_TYPES}"
|
|
193
|
+
end
|
|
194
|
+
begin
|
|
195
|
+
TargetModel.packet_item(operand['target'], operand['packet'], operand['item'], scope: @scope)
|
|
196
|
+
rescue StandardError => e
|
|
197
|
+
raise TriggerInputError.new "invalid #{side} trigger: #{e.message}"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
183
202
|
# Validate that all root triggers exist, but do not persist dependent changes yet.
|
|
184
203
|
# Returns the list of root trigger models that need updating.
|
|
185
204
|
def validate_roots
|
|
@@ -207,6 +226,7 @@ module OpenC3
|
|
|
207
226
|
unless Store.hget(@primary_key, @name).nil?
|
|
208
227
|
raise TriggerInputError.new "existing trigger found: '#{@name}'"
|
|
209
228
|
end
|
|
229
|
+
validate_trigger_items()
|
|
210
230
|
models = validate_roots()
|
|
211
231
|
@updated_at = Time.now.to_nsec_from_epoch
|
|
212
232
|
Store.hset(@primary_key, @name, JSON.generate(as_json, allow_nan: true))
|
|
File without changes
|