openc3 7.3.0 → 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 +138 -0
- data/bin/pipuninstall +0 -0
- data/bin/uvinstall +10 -3
- 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 +0 -0
- data/data/config/microservice.yaml +5 -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 +0 -0
- 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 +0 -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 +0 -0
- data/data/config/unknown.yaml +0 -0
- data/data/config/widgets.yaml +6 -0
- data/data/xtce_schemas/SpaceSystem_20180204.xsd +0 -0
- data/data/xtce_schemas/xml.xsd +0 -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 +0 -0
- 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 +0 -0
- 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 +0 -0
- data/lib/openc3/api/limits_api.rb +0 -0
- 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 +0 -0
- 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 +4 -3
- 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 +0 -0
- 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 +20 -4
- 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 -0
- 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 +0 -0
- 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 +5 -0
- 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 +72 -25
- 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 +11 -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 +0 -0
- 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 +12 -9
- 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 +178 -19
- 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 +9 -22
- 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 +9 -2
- 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 +4 -4
- 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 +51 -26
- 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 +30 -25
- 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 +1 -0
- 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 +64 -22
- 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 +0 -0
- data/lib/openc3/packets/json_packet.rb +0 -0
- data/lib/openc3/packets/limits.rb +0 -0
- data/lib/openc3/packets/limits_response.rb +0 -0
- data/lib/openc3/packets/packet.rb +4 -0
- 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 +0 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +0 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +0 -0
- data/lib/openc3/packets/structure.rb +7 -1
- data/lib/openc3/packets/structure_item.rb +0 -0
- data/lib/openc3/packets/telemetry.rb +0 -0
- 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 +0 -0
- data/lib/openc3/script/critical_cmd.rb +0 -0
- data/lib/openc3/script/exceptions.rb +0 -0
- data/lib/openc3/script/extract.rb +0 -0
- 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 +218 -145
- 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 +0 -0
- 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 +0 -0
- 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 +2 -2
- 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 +0 -0
- 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 +32 -6
- 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 +0 -0
- data/lib/openc3/utilities/rubygems_url.rb +39 -0
- data/lib/openc3/utilities/running_script.rb +24 -55
- data/lib/openc3/utilities/s3_autoload.rb +5 -5
- data/lib/openc3/utilities/script.rb +12 -8
- 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 +5 -5
- 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 +0 -0
- 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 +36 -9
|
@@ -148,7 +148,7 @@ module OpenC3
|
|
|
148
148
|
Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'protocol_cmd' => JSON.generate(data, allow_nan: true) }, '*', 100, db_shard: db_shard)
|
|
149
149
|
end
|
|
150
150
|
|
|
151
|
-
def self.inject_tlm(interface_name, target_name, packet_name, item_hash = nil, type: :CONVERTED, stored: false, timeout: nil, scope:)
|
|
151
|
+
def self.inject_tlm(interface_name, target_name, packet_name, item_hash = nil, type: :CONVERTED, stored: false, timeout: nil, received_time: nil, scope:)
|
|
152
152
|
interface_name = interface_name.upcase
|
|
153
153
|
db_shard = _db_shard_for_interface(interface_name, scope: scope)
|
|
154
154
|
|
|
@@ -162,6 +162,7 @@ module OpenC3
|
|
|
162
162
|
data['item_hash'] = item_hash
|
|
163
163
|
data['type'] = type
|
|
164
164
|
data['stored'] = stored
|
|
165
|
+
data['received_time'] = received_time unless received_time.nil?
|
|
165
166
|
cmd_id = Topic.write_topic("{#{scope}__CMD}INTERFACE__#{interface_name}", { 'inject_tlm' => JSON.generate(data, allow_nan: true) }, '*', 100, db_shard: db_shard)
|
|
166
167
|
time = Time.now
|
|
167
168
|
while (Time.now - time) < timeout
|
|
@@ -211,7 +212,12 @@ module OpenC3
|
|
|
211
212
|
while (Time.now - time) < timeout
|
|
212
213
|
Topic.read_topics([ack_topic], db_shard: db_shard) do |_topic, _msg_id, msg_hash, _redis|
|
|
213
214
|
if msg_hash["id"] == cmd_id
|
|
214
|
-
|
|
215
|
+
begin
|
|
216
|
+
return JSON.parse(msg_hash["result"], :allow_nan => true, :create_additions => true)
|
|
217
|
+
rescue JSON::ParserError
|
|
218
|
+
# The microservice returns a plain error message rather than JSON if details raises
|
|
219
|
+
raise "interface_details failed: #{msg_hash['result']}"
|
|
220
|
+
end
|
|
215
221
|
end
|
|
216
222
|
end
|
|
217
223
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -170,7 +170,12 @@ module OpenC3
|
|
|
170
170
|
while (Time.now - time) < timeout
|
|
171
171
|
Topic.read_topics([ack_topic], db_shard: db_shard) do |_topic, _msg_id, msg_hash, _redis|
|
|
172
172
|
if msg_hash["id"] == cmd_id
|
|
173
|
-
|
|
173
|
+
begin
|
|
174
|
+
return JSON.parse(msg_hash["result"], :allow_nan => true, :create_additions => true)
|
|
175
|
+
rescue JSON::ParserError
|
|
176
|
+
# The microservice returns a plain error message rather than JSON if details raises
|
|
177
|
+
raise "router_details failed: #{msg_hash['result']}"
|
|
178
|
+
end
|
|
174
179
|
end
|
|
175
180
|
end
|
|
176
181
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/topics/topic.rb
CHANGED
|
File without changes
|
|
@@ -28,7 +28,7 @@ module OpenC3
|
|
|
28
28
|
# OpenC3 COSMOS Core authentication code
|
|
29
29
|
class OpenC3Authentication
|
|
30
30
|
def initialize()
|
|
31
|
-
password = ENV
|
|
31
|
+
password = ENV.fetch('OPENC3_API_PASSWORD', nil)
|
|
32
32
|
if password.nil?
|
|
33
33
|
raise OpenC3AuthenticationError, "Authentication requires environment variable OPENC3_API_PASSWORD"
|
|
34
34
|
end
|
|
@@ -172,8 +172,8 @@ module OpenC3
|
|
|
172
172
|
if ENV['OPENC3_API_USER'] and ENV['OPENC3_API_PASSWORD']
|
|
173
173
|
# Username and password
|
|
174
174
|
data = {
|
|
175
|
-
'username' => ENV
|
|
176
|
-
'password' => ENV
|
|
175
|
+
'username' => ENV.fetch('OPENC3_API_USER', nil),
|
|
176
|
+
'password' => ENV.fetch('OPENC3_API_PASSWORD', nil),
|
|
177
177
|
'client_id' => client_id,
|
|
178
178
|
'grant_type' => 'password',
|
|
179
179
|
'scope' => openid_scope
|
|
@@ -189,7 +189,7 @@ module OpenC3
|
|
|
189
189
|
@refresh_expires_at = current_time + oath['refresh_expires_in'] - REFRESH_OFFSET_SECONDS
|
|
190
190
|
else
|
|
191
191
|
# Offline Access Token
|
|
192
|
-
@refresh_token ||= ENV
|
|
192
|
+
@refresh_token ||= ENV.fetch('OPENC3_API_TOKEN', nil)
|
|
193
193
|
_refresh_token(current_time)
|
|
194
194
|
end
|
|
195
195
|
end
|
|
File without changes
|
|
@@ -99,9 +99,9 @@ module OpenC3
|
|
|
99
99
|
# Apply bucket policy to grant ScriptRunner user access to config and logs buckets
|
|
100
100
|
# This provides reduced permissions compared to the root user for security
|
|
101
101
|
def ensure_scriptrunner_policy(config_bucket, logs_bucket)
|
|
102
|
-
sr_username = ENV
|
|
102
|
+
sr_username = ENV.fetch('OPENC3_SR_BUCKET_USERNAME', nil)
|
|
103
103
|
return unless sr_username
|
|
104
|
-
return if sr_username == ENV
|
|
104
|
+
return if sr_username == ENV.fetch('OPENC3_BUCKET_USERNAME', nil) # Same as root, no policy needed
|
|
105
105
|
|
|
106
106
|
# Policy for config bucket - read targets, read/write targets_modified
|
|
107
107
|
# Note: versitygw expects Principal as comma-separated raw usernames
|
|
@@ -23,7 +23,7 @@ module OpenC3
|
|
|
23
23
|
def self.getClient
|
|
24
24
|
raise 'OPENC3_CLOUD environment variable is required' unless ENV['OPENC3_CLOUD']
|
|
25
25
|
# Base is AwsBucket which works with S3-compatible storage (versitygw), Enterprise implements additional
|
|
26
|
-
bucket_class = ENV
|
|
26
|
+
bucket_class = ENV.fetch('OPENC3_CLOUD', 'local').capitalize + 'Bucket'
|
|
27
27
|
klass = OpenC3.require_class('openc3/utilities/'+bucket_class.class_name_to_filename)
|
|
28
28
|
klass.new
|
|
29
29
|
end
|
|
@@ -163,16 +163,24 @@ class BucketFileCache
|
|
|
163
163
|
|
|
164
164
|
@current_disk_usage = 0
|
|
165
165
|
@queued_bucket_files = []
|
|
166
|
+
# Mirrors @queued_bucket_files as bucket_path => true. Membership is checked
|
|
167
|
+
# once per file close in unreserve() and once per entry in age_out_files(),
|
|
168
|
+
# both of which are O(cache size) linear scans against the bare Array.
|
|
169
|
+
@queued_path_hash = {}
|
|
166
170
|
@bucket_file_hash = {}
|
|
167
171
|
bucket_file = nil
|
|
168
172
|
|
|
173
|
+
# NOTE: check_time must be initialized outside the loop or it is pushed
|
|
174
|
+
# forward on every iteration and the age out check below never fires
|
|
175
|
+
check_time = Time.now + CHECK_TIME_SECONDS # Check for aged out files periodically
|
|
176
|
+
|
|
169
177
|
@thread = Thread.new do
|
|
170
178
|
client = OpenC3::Bucket.getClient()
|
|
171
179
|
while true
|
|
172
|
-
check_time = Time.now + CHECK_TIME_SECONDS # Check for aged out files periodically
|
|
173
180
|
if @queued_bucket_files.length > 0 and @current_disk_usage < MAX_DISK_USAGE
|
|
174
181
|
@@mutex.synchronize do
|
|
175
182
|
bucket_file = @queued_bucket_files.shift
|
|
183
|
+
@queued_path_hash.delete(bucket_file.bucket_path) if bucket_file
|
|
176
184
|
end
|
|
177
185
|
begin
|
|
178
186
|
retrieved = bucket_file.retrieve(client)
|
|
@@ -187,18 +195,7 @@ class BucketFileCache
|
|
|
187
195
|
# Nothing to do or disk full
|
|
188
196
|
if Time.now > check_time
|
|
189
197
|
check_time = Time.now + CHECK_TIME_SECONDS
|
|
190
|
-
|
|
191
|
-
removed_files = []
|
|
192
|
-
@bucket_file_hash.each do |bucket_path, bucket_file|
|
|
193
|
-
deleted = bucket_file.age_check
|
|
194
|
-
if deleted
|
|
195
|
-
removed_files << bucket_path
|
|
196
|
-
@current_disk_usage -= bucket_file.size
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
removed_files.each do |bucket_path|
|
|
200
|
-
@bucket_file_hash.delete(bucket_path)
|
|
201
|
-
end
|
|
198
|
+
age_out_files()
|
|
202
199
|
end
|
|
203
200
|
sleep(1)
|
|
204
201
|
end
|
|
@@ -216,8 +213,9 @@ class BucketFileCache
|
|
|
216
213
|
return instance().reserve(bucket_path)
|
|
217
214
|
end
|
|
218
215
|
|
|
219
|
-
|
|
220
|
-
|
|
216
|
+
# @param bucket_file_or_path [BucketFile|String] BucketFile or its bucket path
|
|
217
|
+
def self.unreserve(bucket_file_or_path)
|
|
218
|
+
return instance().unreserve(bucket_file_or_path)
|
|
221
219
|
end
|
|
222
220
|
|
|
223
221
|
def hint(bucket_paths)
|
|
@@ -236,30 +234,65 @@ class BucketFileCache
|
|
|
236
234
|
retrieved = bucket_file.reserve
|
|
237
235
|
@current_disk_usage += bucket_file.size if retrieved
|
|
238
236
|
@queued_bucket_files.delete(bucket_file)
|
|
237
|
+
@queued_path_hash.delete(bucket_path)
|
|
239
238
|
return bucket_file
|
|
240
239
|
end
|
|
241
240
|
end
|
|
242
241
|
|
|
243
|
-
|
|
242
|
+
# Callers hold the BucketFile returned by reserve() but the cache is keyed by
|
|
243
|
+
# bucket path, so accept either and normalize to the path.
|
|
244
|
+
# @param bucket_file_or_path [BucketFile|String] BucketFile or its bucket path
|
|
245
|
+
def unreserve(bucket_file_or_path)
|
|
246
|
+
if bucket_file_or_path.is_a?(BucketFile)
|
|
247
|
+
released = bucket_file_or_path
|
|
248
|
+
bucket_path = released.bucket_path
|
|
249
|
+
else
|
|
250
|
+
released = nil
|
|
251
|
+
bucket_path = bucket_file_or_path
|
|
252
|
+
end
|
|
244
253
|
@@mutex.synchronize do
|
|
245
254
|
bucket_file = @bucket_file_hash[bucket_path]
|
|
246
|
-
if bucket_file
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
255
|
+
return if bucket_file.nil?
|
|
256
|
+
# Releasing to zero drops the entry, so the next reserve of the same path
|
|
257
|
+
# builds a new BucketFile. A BucketFile that is no longer the entry for
|
|
258
|
+
# its path was therefore already released, and releasing it again would
|
|
259
|
+
# decrement its replacement and delete a local file another reader still
|
|
260
|
+
# has open. Only the current owner of the path may release it.
|
|
261
|
+
return unless released.nil? or released.equal?(bucket_file)
|
|
262
|
+
|
|
263
|
+
bucket_file.unreserve
|
|
264
|
+
if bucket_file.reservation_count <= 0 and !@queued_path_hash[bucket_path]
|
|
265
|
+
@current_disk_usage -= bucket_file.size
|
|
266
|
+
@bucket_file_hash.delete(bucket_path)
|
|
252
267
|
end
|
|
253
268
|
end
|
|
254
269
|
end
|
|
255
270
|
|
|
256
271
|
# Private
|
|
257
272
|
|
|
273
|
+
# Delete the local copy of any file that is old and no longer reserved.
|
|
274
|
+
# Files still waiting in the download queue are skipped because the download
|
|
275
|
+
# thread would re-add their size to @current_disk_usage after removal.
|
|
276
|
+
def age_out_files
|
|
277
|
+
@@mutex.synchronize do
|
|
278
|
+
@bucket_file_hash.delete_if do |bucket_path, bucket_file|
|
|
279
|
+
next false if @queued_path_hash[bucket_path]
|
|
280
|
+
if bucket_file.age_check
|
|
281
|
+
@current_disk_usage -= bucket_file.size
|
|
282
|
+
true
|
|
283
|
+
else
|
|
284
|
+
false
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
258
290
|
def create_bucket_file(bucket_path)
|
|
259
291
|
bucket_file = @bucket_file_hash[bucket_path]
|
|
260
292
|
unless bucket_file
|
|
261
293
|
bucket_file = BucketFile.new(bucket_path)
|
|
262
294
|
@queued_bucket_files << bucket_file
|
|
295
|
+
@queued_path_hash[bucket_path] = true
|
|
263
296
|
@bucket_file_hash[bucket_path] = bucket_file
|
|
264
297
|
end
|
|
265
298
|
return bucket_file
|
|
File without changes
|
|
@@ -25,8 +25,7 @@ module OpenC3
|
|
|
25
25
|
DIRECTORY_TIMESTAMP_FORMAT = "%Y%m%d"
|
|
26
26
|
|
|
27
27
|
def self.bucket_load(*args, scope: $openc3_scope)
|
|
28
|
-
scope = ENV
|
|
29
|
-
scope = 'DEFAULT' unless scope
|
|
28
|
+
scope = ENV.fetch('OPENC3_SCOPE', 'DEFAULT') unless scope
|
|
30
29
|
path = args[0]
|
|
31
30
|
|
|
32
31
|
# Only support TARGET files
|
|
@@ -93,7 +92,7 @@ module OpenC3
|
|
|
93
92
|
# this to work with really large files. Otherwise the entire file has
|
|
94
93
|
# to be held in memory!
|
|
95
94
|
File.open(filename, 'rb') do |file|
|
|
96
|
-
client.put_object(bucket: ENV
|
|
95
|
+
client.put_object(bucket: ENV.fetch('OPENC3_LOGS_BUCKET', nil), key: bucket_key, body: file, metadata: metadata)
|
|
97
96
|
end
|
|
98
97
|
rescue => err
|
|
99
98
|
# Try to upload file three times
|
|
@@ -104,7 +103,7 @@ module OpenC3
|
|
|
104
103
|
retry
|
|
105
104
|
end
|
|
106
105
|
|
|
107
|
-
Logger.debug "wrote #{ENV
|
|
106
|
+
Logger.debug "wrote #{ENV.fetch('OPENC3_LOGS_BUCKET', nil)}/#{bucket_key}"
|
|
108
107
|
|
|
109
108
|
File.delete(orig_filename) if orig_filename
|
|
110
109
|
File.delete(filename)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is distributed in the hope that it will be useful,
|
|
7
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
9
|
+
# See LICENSE.md for more details.
|
|
10
|
+
#
|
|
11
|
+
# This file may also be used under the terms of a commercial license
|
|
12
|
+
# if purchased from OpenC3, Inc.
|
|
13
|
+
|
|
14
|
+
module OpenC3
|
|
15
|
+
# Shared predicates describing which parts of the user-writable config overlay
|
|
16
|
+
# (targets_modified) a non-admin may write.
|
|
17
|
+
#
|
|
18
|
+
# The cmd_tlm overlay (targets_modified/<TARGET>/cmd_tlm/...) is loaded by
|
|
19
|
+
# System.setup_targets and processed by PacketConfig, which evaluates
|
|
20
|
+
# GENERIC_READ_CONVERSION / GENERIC_WRITE_CONVERSION blocks as code in the
|
|
21
|
+
# decom microservices. Writing it is therefore an admin operation, matching the
|
|
22
|
+
# tier COSMOS requires everywhere else code is introduced (plugin install).
|
|
23
|
+
# Only the server-side dynamic-packet mechanism (TargetModel#dynamic_update)
|
|
24
|
+
# writes that area without going through an API request.
|
|
25
|
+
#
|
|
26
|
+
# Every API writer that can reach the overlay must consult these predicates:
|
|
27
|
+
# - storage_controller#get_upload_presigned_request / delete (presigned S3 upload)
|
|
28
|
+
# - tables_controller#save / save_as / generate / destroy (Table -> TargetFile)
|
|
29
|
+
# - scripts_controller#create / destroy (Script -> TargetFile)
|
|
30
|
+
module ConfigOverlay
|
|
31
|
+
# Config bucket areas a non-admin is allowed to write at all
|
|
32
|
+
NON_ADMIN_AREAS = ['targets_modified', 'tmp'].freeze
|
|
33
|
+
|
|
34
|
+
# Target subdirectory whose contents are executed as code
|
|
35
|
+
CODE_AREA = 'cmd_tlm'
|
|
36
|
+
|
|
37
|
+
# Split a path into segments, or nil if the path is not canonical.
|
|
38
|
+
#
|
|
39
|
+
# Positional segment checks (parts[1], parts[3]) can be bypassed by a path
|
|
40
|
+
# the object store normalizes differently, so empty '//' segments, '.'/'..'
|
|
41
|
+
# segments, and leading/trailing slashes yield nil and every caller fails
|
|
42
|
+
# closed (requires admin) on nil.
|
|
43
|
+
def self.canonical_parts(path)
|
|
44
|
+
return nil if path.nil? || path.empty?
|
|
45
|
+
return nil if path.start_with?('/') || path.end_with?('/')
|
|
46
|
+
parts = path.split('/')
|
|
47
|
+
return nil if parts.any? { |part| part.empty? || part == '.' || part == '..' }
|
|
48
|
+
parts
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# True if the overlay-relative name targets the cmd_tlm subtree, i.e. writing
|
|
52
|
+
# it requires admin. Name is relative to targets_modified/, e.g.
|
|
53
|
+
# "<TARGET>/cmd_tlm/tlm.txt". Fails closed (true) on non-canonical names.
|
|
54
|
+
def self.cmd_tlm_overlay?(name)
|
|
55
|
+
parts = canonical_parts(name)
|
|
56
|
+
return true if parts.nil?
|
|
57
|
+
# parts: <TARGET> / <area> / ...
|
|
58
|
+
parts[1] == CODE_AREA
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# True if the given config bucket key is an overlay path a non-admin may
|
|
62
|
+
# write. Key is the full bucket key, e.g.
|
|
63
|
+
# "<SCOPE>/targets_modified/<TARGET>/screens/x.txt". Fails closed (false) on
|
|
64
|
+
# non-canonical keys.
|
|
65
|
+
def self.non_admin_writable_key?(key)
|
|
66
|
+
parts = canonical_parts(key)
|
|
67
|
+
return false if parts.nil?
|
|
68
|
+
# parts: <SCOPE> / <area> / <TARGET> / <subdir> / ...
|
|
69
|
+
area = parts[1]
|
|
70
|
+
return false unless NON_ADMIN_AREAS.include?(area)
|
|
71
|
+
return false if area == 'targets_modified' && parts[3] == CODE_AREA
|
|
72
|
+
true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
File without changes
|
data/lib/openc3/utilities/crc.rb
CHANGED
|
@@ -75,18 +75,22 @@ module OpenC3
|
|
|
75
75
|
@bit_size = 8
|
|
76
76
|
pack = 'C'
|
|
77
77
|
filter_mask = 0xFF
|
|
78
|
+
right_shift = 0
|
|
78
79
|
when 'OpenC3::Crc16'
|
|
79
80
|
@bit_size = 16
|
|
80
81
|
pack = 'S'
|
|
81
82
|
filter_mask = 0xFFFF
|
|
83
|
+
right_shift = 8
|
|
82
84
|
when 'OpenC3::Crc32'
|
|
83
85
|
@bit_size = 32
|
|
84
86
|
pack = 'I'
|
|
85
87
|
filter_mask = 0xFFFFFFFF
|
|
88
|
+
right_shift = 24
|
|
86
89
|
when 'OpenC3::Crc64'
|
|
87
90
|
@bit_size = 64
|
|
88
91
|
pack = 'Q'
|
|
89
92
|
filter_mask = 0xFFFFFFFFFFFFFFFF
|
|
93
|
+
right_shift = 56
|
|
90
94
|
end
|
|
91
95
|
if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
|
|
92
96
|
(0..255).each do |index|
|
|
@@ -96,6 +100,29 @@ module OpenC3
|
|
|
96
100
|
(0..255).each do |index|
|
|
97
101
|
@table << (compute_table_entry(index, @bit_size) & filter_mask)
|
|
98
102
|
end
|
|
103
|
+
|
|
104
|
+
@filter_mask = filter_mask
|
|
105
|
+
@right_shift = right_shift
|
|
106
|
+
@bit_reverse = method("bit_reverse_#{@bit_size}")
|
|
107
|
+
|
|
108
|
+
# A reflected (least-significant-bit first) table avoids reversing each
|
|
109
|
+
# input byte in calc. CRC32 and CRC64 get three additional tables so
|
|
110
|
+
# their common reflected forms can process four bytes per Ruby loop.
|
|
111
|
+
if @reflect
|
|
112
|
+
reflected_table = Array.new(256) do |index|
|
|
113
|
+
@bit_reverse.call(@table[BIT_REVERSE_TABLE[index]])
|
|
114
|
+
end
|
|
115
|
+
@reflected_tables = [reflected_table]
|
|
116
|
+
if @bit_size >= 32
|
|
117
|
+
3.times do
|
|
118
|
+
previous_table = @reflected_tables[-1]
|
|
119
|
+
@reflected_tables << Array.new(256) do |index|
|
|
120
|
+
value = previous_table[index]
|
|
121
|
+
(value >> 8) ^ reflected_table[value & 0xFF]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
99
126
|
end
|
|
100
127
|
end
|
|
101
128
|
|
|
@@ -140,47 +167,47 @@ module OpenC3
|
|
|
140
167
|
|
|
141
168
|
if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
|
|
142
169
|
def calc(data, seed = @seed)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
case @bit_size
|
|
146
|
-
when 8
|
|
147
|
-
right_shift = 0
|
|
148
|
-
filter_mask = 0xFF
|
|
149
|
-
final_bit_reverse = method(:bit_reverse_8)
|
|
150
|
-
when 16
|
|
151
|
-
right_shift = 8
|
|
152
|
-
filter_mask = 0xFFFF
|
|
153
|
-
final_bit_reverse = method(:bit_reverse_16)
|
|
154
|
-
when 32
|
|
155
|
-
right_shift = 24
|
|
156
|
-
filter_mask = 0xFFFFFFFF
|
|
157
|
-
final_bit_reverse = method(:bit_reverse_32)
|
|
158
|
-
when 64
|
|
159
|
-
right_shift = 56
|
|
160
|
-
filter_mask = 0xFFFFFFFFFFFFFFFF
|
|
161
|
-
final_bit_reverse = method(:bit_reverse_64)
|
|
162
|
-
end
|
|
170
|
+
seed = @seed if seed.nil?
|
|
163
171
|
|
|
164
172
|
if @reflect
|
|
165
|
-
|
|
166
|
-
|
|
173
|
+
crc = @bit_reverse.call(seed)
|
|
174
|
+
reflected_table = @reflected_tables[0]
|
|
175
|
+
index = 0
|
|
176
|
+
|
|
177
|
+
if @bit_size >= 32
|
|
178
|
+
table1 = @reflected_tables[1]
|
|
179
|
+
table2 = @reflected_tables[2]
|
|
180
|
+
table3 = @reflected_tables[3]
|
|
181
|
+
word_count = data.bytesize / 4
|
|
182
|
+
unless word_count.zero?
|
|
183
|
+
data.unpack("V#{word_count}").each do |word|
|
|
184
|
+
value = crc ^ word
|
|
185
|
+
crc = (value >> 32) ^
|
|
186
|
+
table3[value & 0xFF] ^
|
|
187
|
+
table2[(value >> 8) & 0xFF] ^
|
|
188
|
+
table1[(value >> 16) & 0xFF] ^
|
|
189
|
+
reflected_table[(value >> 24) & 0xFF]
|
|
190
|
+
end
|
|
191
|
+
index = word_count * 4
|
|
192
|
+
end
|
|
167
193
|
end
|
|
168
194
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return final_bit_reverse.call(crc)
|
|
195
|
+
while index < data.bytesize
|
|
196
|
+
crc = (crc >> 8) ^ reflected_table[(crc ^ data.getbyte(index)) & 0xFF]
|
|
197
|
+
index += 1
|
|
173
198
|
end
|
|
199
|
+
|
|
200
|
+
return @xor ? crc ^ @filter_mask : crc
|
|
174
201
|
else
|
|
202
|
+
crc = seed
|
|
203
|
+
table = @table
|
|
204
|
+
filter_mask = @filter_mask
|
|
205
|
+
right_shift = @right_shift
|
|
175
206
|
data.each_byte do |byte|
|
|
176
|
-
crc = ((crc << 8) & filter_mask) ^
|
|
207
|
+
crc = ((crc << 8) & filter_mask) ^ table[(crc >> right_shift) ^ byte]
|
|
177
208
|
end
|
|
178
209
|
|
|
179
|
-
|
|
180
|
-
return crc ^ filter_mask
|
|
181
|
-
else
|
|
182
|
-
return crc
|
|
183
|
-
end
|
|
210
|
+
return @xor ? crc ^ filter_mask : crc
|
|
184
211
|
end
|
|
185
212
|
end
|
|
186
213
|
end
|
data/lib/openc3/utilities/csv.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -99,7 +99,7 @@ module OpenC3
|
|
|
99
99
|
|
|
100
100
|
Dir.each_child(path) do |filename|
|
|
101
101
|
full_path = "#{path}/#{filename}"
|
|
102
|
-
|
|
102
|
+
unless File.directory?(full_path)
|
|
103
103
|
if File.extname(filename) == '.gem'
|
|
104
104
|
gems << full_path
|
|
105
105
|
elsif filename == 'plugin_instance.json'
|
|
@@ -283,7 +283,7 @@ module OpenC3
|
|
|
283
283
|
return if DEFAULT_PLUGINS.include?(gem_name)
|
|
284
284
|
puts "Updating local plugin files: #{full_folder_path}"
|
|
285
285
|
FileUtils.mkdir_p(full_folder_path)
|
|
286
|
-
gems
|
|
286
|
+
gems = scan_plugin_dir(full_folder_path).first
|
|
287
287
|
gems.each do |gem|
|
|
288
288
|
File.delete(gem)
|
|
289
289
|
end
|
|
@@ -377,7 +377,7 @@ module OpenC3
|
|
|
377
377
|
end
|
|
378
378
|
end
|
|
379
379
|
|
|
380
|
-
def self.put_target_file(path, io_or_string, scope:)
|
|
380
|
+
def self.put_target_file(path, io_or_string, scope:) # NOSONAR - scope: is part of the caller-facing signature
|
|
381
381
|
full_folder_path = "#{OPENC3_LOCAL_MODE_PATH}/#{path}"
|
|
382
382
|
return unless File.expand_path(full_folder_path).start_with?(OPENC3_LOCAL_MODE_PATH)
|
|
383
383
|
FileUtils.mkdir_p(File.dirname(full_folder_path))
|
|
@@ -468,16 +468,42 @@ module OpenC3
|
|
|
468
468
|
end
|
|
469
469
|
|
|
470
470
|
def self.sync_settings()
|
|
471
|
+
# The files are authoritative here, unlike the OPENC3_SETTING_* env var
|
|
472
|
+
# seeding done by `openc3cli initsettings`. An Admin Console edit is
|
|
473
|
+
# mirrored straight back into the file by set_setting, so the file is
|
|
474
|
+
# already the edited value and applying it reverts nothing. Skipping a
|
|
475
|
+
# setting that already exists would instead mean a file was never applied
|
|
476
|
+
# at all: localinit runs after the first plugin load creates the scope,
|
|
477
|
+
# and that seeds source_url, rubygems_url, pypi_url, news_feed and
|
|
478
|
+
# system_health, so those five always exist by the time this runs.
|
|
479
|
+
#
|
|
480
|
+
# Because initsettings runs before localinit, a local mode file wins over
|
|
481
|
+
# OPENC3_SETTING_<NAME> for the same setting.
|
|
482
|
+
#
|
|
483
|
+
# A file that won't coerce is reported and skipped rather than raising,
|
|
484
|
+
# for the same reason `initsettings` doesn't abort: one bad settings file
|
|
485
|
+
# shouldn't stop the rest of localinit.
|
|
486
|
+
problems = []
|
|
471
487
|
scopes = ScopeModel.names()
|
|
472
488
|
scopes.each do |scope|
|
|
473
489
|
Dir["#{OPENC3_LOCAL_MODE_PATH}/#{scope}/settings/*.json"].each do |config|
|
|
474
490
|
name = File.basename(config, ".json")
|
|
491
|
+
# save_setting writes a boolean as the JSON text "true"/"false", so
|
|
492
|
+
# convert it back rather than storing the file contents verbatim -
|
|
493
|
+
# the string "false" is truthy in the frontend. Settings that hold
|
|
494
|
+
# JSON text (classification_banner, astro) stay strings, which is
|
|
495
|
+
# what their components JSON.parse.
|
|
496
|
+
begin
|
|
497
|
+
data = SettingModel.coerce(name, File.read(config))
|
|
498
|
+
rescue StandardError => error
|
|
499
|
+
problems << "#{config}: #{error.message}"
|
|
500
|
+
next
|
|
501
|
+
end
|
|
475
502
|
puts "Syncing setting #{name}"
|
|
476
|
-
# Anything can be stored in settings so read and set directly
|
|
477
|
-
data = File.read(config)
|
|
478
503
|
SettingModel.set({ name: name, data: data }, scope: scope)
|
|
479
504
|
end
|
|
480
505
|
end
|
|
506
|
+
problems.each { |problem| puts "ERROR: #{problem}" }
|
|
481
507
|
end
|
|
482
508
|
|
|
483
509
|
def self.save_setting(scope, name, data)
|
|
@@ -582,7 +608,7 @@ module OpenC3
|
|
|
582
608
|
# Both files exist - Handled earlier
|
|
583
609
|
else
|
|
584
610
|
# Local is missing remote file
|
|
585
|
-
if not ENV
|
|
611
|
+
if not ENV.fetch('OPENC3_LOCAL_MODE_SECONDARY', nil) and ENV.fetch('OPENC3_LOCAL_MODE_SYNC_REMOVE', nil)
|
|
586
612
|
delete_remote(bucket, key)
|
|
587
613
|
else
|
|
588
614
|
# Go ahead and copy down to get in sync
|
|
@@ -42,39 +42,61 @@ module OpenC3
|
|
|
42
42
|
|
|
43
43
|
@@mutex = Mutex.new
|
|
44
44
|
@@instance = nil
|
|
45
|
-
@@scope = ENV
|
|
45
|
+
@@scope = ENV.fetch('OPENC3_SCOPE', 'DEFAULT')
|
|
46
46
|
|
|
47
|
-
#
|
|
47
|
+
# Levels in increasing severity. Logging at a level prints that level
|
|
48
|
+
# and everything above it, e.g. WARN prints WARN, ERROR and FATAL.
|
|
48
49
|
DEBUG = ::Logger::DEBUG
|
|
49
|
-
# INFO prints INFO, DEBUG messages
|
|
50
50
|
INFO = ::Logger::INFO
|
|
51
|
-
# WARN prints WARN, INFO, DEBUG messages
|
|
52
51
|
WARN = ::Logger::WARN
|
|
53
|
-
# ERROR prints ERROR, WARN, INFO, DEBUG messages
|
|
54
52
|
ERROR = ::Logger::ERROR
|
|
55
|
-
# FATAL prints FATAL, ERROR, WARN, INFO, DEBUG messages
|
|
56
53
|
FATAL = ::Logger::FATAL
|
|
57
54
|
|
|
55
|
+
# Level names as they appear in log messages and OPENC3_LOG_LEVEL
|
|
58
56
|
DEBUG_LEVEL = 'DEBUG'
|
|
59
57
|
INFO_LEVEL = 'INFO'
|
|
60
58
|
WARN_LEVEL = 'WARN'
|
|
61
59
|
ERROR_LEVEL = 'ERROR'
|
|
62
60
|
FATAL_LEVEL = 'FATAL'
|
|
63
61
|
|
|
62
|
+
LEVELS = {
|
|
63
|
+
DEBUG_LEVEL => DEBUG,
|
|
64
|
+
INFO_LEVEL => INFO,
|
|
65
|
+
WARN_LEVEL => WARN,
|
|
66
|
+
ERROR_LEVEL => ERROR,
|
|
67
|
+
FATAL_LEVEL => FATAL
|
|
68
|
+
}.freeze
|
|
69
|
+
|
|
64
70
|
# Types
|
|
65
71
|
LOG = 'log'
|
|
66
72
|
NOTIFICATION = 'notification'
|
|
67
73
|
ALERT = 'alert'
|
|
68
74
|
EPHEMERAL = 'ephemeral'
|
|
69
75
|
|
|
76
|
+
# @return [Integer] Level named by the OPENC3_LOG_LEVEL env var.
|
|
77
|
+
# INFO if the var is unset or isn't a level name.
|
|
78
|
+
def self.default_level
|
|
79
|
+
level = ENV.fetch('OPENC3_LOG_LEVEL', '')
|
|
80
|
+
name = level.to_s.strip.upcase
|
|
81
|
+
return INFO if name.empty?
|
|
82
|
+
|
|
83
|
+
LEVELS.fetch(name) do
|
|
84
|
+
unless @warned_bad_level
|
|
85
|
+
@warned_bad_level = true
|
|
86
|
+
$stderr.puts "OPENC3_LOG_LEVEL '#{level}' is not one of #{LEVELS.keys.join(', ')}, using INFO"
|
|
87
|
+
end
|
|
88
|
+
INFO
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
70
92
|
# @param level [Integer] The initial logging level
|
|
71
|
-
def initialize(level = Logger
|
|
93
|
+
def initialize(level = Logger.default_level)
|
|
72
94
|
@stdout = true
|
|
73
95
|
@level = level
|
|
74
96
|
@detail_string = nil
|
|
75
97
|
@container_name = Socket.gethostname
|
|
76
98
|
@microservice_name = nil
|
|
77
|
-
@no_store = ENV
|
|
99
|
+
@no_store = ENV.fetch('OPENC3_NO_STORE', nil)
|
|
78
100
|
end
|
|
79
101
|
|
|
80
102
|
# Only set the microservice name once (to help with multi microservices)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|