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
|
@@ -0,0 +1,114 @@
|
|
|
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
|
+
require 'openc3/models/model'
|
|
15
|
+
|
|
16
|
+
module OpenC3
|
|
17
|
+
# Captures the information openc3-app needs to spawn a COSMOS interface on the
|
|
18
|
+
# host computer (outside Docker) so it can reach hardware such as serial ports
|
|
19
|
+
# that aren't available inside a container. A host microservice performs raw
|
|
20
|
+
# data transfer and basic functionality only; complex processing (protocols,
|
|
21
|
+
# target definitions) stays on the Docker side of COSMOS. The host side speaks
|
|
22
|
+
# Iroh back to openc3-app which forwards the data into COSMOS through the named
|
|
23
|
+
# bridge_microservice relay.
|
|
24
|
+
#
|
|
25
|
+
# This model is written by InterfaceModel#deploy for bridged interfaces (those
|
|
26
|
+
# configured with the BRIDGE keyword) and read by openc3-app. It is deliberately
|
|
27
|
+
# kept separate from MicroserviceModel so it is NOT run by the normal COSMOS
|
|
28
|
+
# microservice operator.
|
|
29
|
+
class HostInterfaceMicroserviceModel < Model
|
|
30
|
+
PRIMARY_KEY = 'openc3_host_interface_microservices'
|
|
31
|
+
|
|
32
|
+
# The real interface class and its parameters, e.g. ['serial_interface.py', ...]
|
|
33
|
+
attr_accessor :config_params
|
|
34
|
+
attr_accessor :work_dir
|
|
35
|
+
attr_accessor :env
|
|
36
|
+
attr_accessor :options
|
|
37
|
+
attr_accessor :secret_options
|
|
38
|
+
attr_accessor :protocols
|
|
39
|
+
attr_accessor :secrets
|
|
40
|
+
attr_accessor :container
|
|
41
|
+
attr_accessor :needs_dependencies
|
|
42
|
+
# The bridge (bridge_microservice relay) this host interface routes through.
|
|
43
|
+
attr_accessor :bridge_name
|
|
44
|
+
# The Iroh ALPN stream name (the interface name) used to route data back to
|
|
45
|
+
# openc3-app and on to the matching COSMOS bridge_interface.
|
|
46
|
+
attr_accessor :stream
|
|
47
|
+
|
|
48
|
+
# NOTE: The following three class methods are reimplemented (like other
|
|
49
|
+
# scoped models) so the ModelController and Model class methods work.
|
|
50
|
+
def self.get(name:, scope:)
|
|
51
|
+
super("#{scope}__#{PRIMARY_KEY}", name: name)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.names(scope:)
|
|
55
|
+
super("#{scope}__#{PRIMARY_KEY}")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.all(scope:)
|
|
59
|
+
super("#{scope}__#{PRIMARY_KEY}")
|
|
60
|
+
end
|
|
61
|
+
# END NOTE
|
|
62
|
+
|
|
63
|
+
def initialize(
|
|
64
|
+
name:,
|
|
65
|
+
bridge_name:,
|
|
66
|
+
stream:,
|
|
67
|
+
config_params: [],
|
|
68
|
+
work_dir: '.',
|
|
69
|
+
env: {},
|
|
70
|
+
options: [],
|
|
71
|
+
secret_options: [],
|
|
72
|
+
protocols: [],
|
|
73
|
+
secrets: [],
|
|
74
|
+
container: nil,
|
|
75
|
+
needs_dependencies: false,
|
|
76
|
+
updated_at: nil,
|
|
77
|
+
plugin: nil,
|
|
78
|
+
scope:
|
|
79
|
+
)
|
|
80
|
+
super("#{scope}__#{PRIMARY_KEY}", name: name, updated_at: updated_at, plugin: plugin, scope: scope)
|
|
81
|
+
@bridge_name = bridge_name
|
|
82
|
+
@stream = stream
|
|
83
|
+
@config_params = config_params
|
|
84
|
+
@work_dir = work_dir
|
|
85
|
+
@env = env
|
|
86
|
+
@options = options
|
|
87
|
+
@secret_options = secret_options
|
|
88
|
+
@protocols = protocols
|
|
89
|
+
@secrets = secrets
|
|
90
|
+
@container = container
|
|
91
|
+
@needs_dependencies = needs_dependencies
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def as_json(*a)
|
|
95
|
+
{
|
|
96
|
+
'name' => @name,
|
|
97
|
+
'scope' => @scope,
|
|
98
|
+
'bridge_name' => @bridge_name,
|
|
99
|
+
'stream' => @stream,
|
|
100
|
+
'config_params' => @config_params,
|
|
101
|
+
'work_dir' => @work_dir,
|
|
102
|
+
'env' => @env,
|
|
103
|
+
'options' => @options,
|
|
104
|
+
'secret_options' => @secret_options,
|
|
105
|
+
'protocols' => @protocols,
|
|
106
|
+
'secrets' => @secrets.as_json(*a),
|
|
107
|
+
'container' => @container,
|
|
108
|
+
'needs_dependencies' => @needs_dependencies,
|
|
109
|
+
'plugin' => @plugin,
|
|
110
|
+
'updated_at' => @updated_at
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
File without changes
|
|
@@ -16,11 +16,16 @@
|
|
|
16
16
|
# if purchased from OpenC3, Inc.
|
|
17
17
|
|
|
18
18
|
require 'openc3/models/model'
|
|
19
|
+
require 'openc3/models/config_keyword_model'
|
|
19
20
|
require 'openc3/models/microservice_model'
|
|
21
|
+
require 'openc3/models/bridge_model'
|
|
22
|
+
require 'openc3/models/host_interface_microservice_model'
|
|
20
23
|
require 'openc3/models/target_model'
|
|
21
24
|
|
|
22
25
|
module OpenC3
|
|
23
26
|
class InterfaceModel < Model
|
|
27
|
+
include ConfigKeywordModel
|
|
28
|
+
|
|
24
29
|
INTERFACES_PRIMARY_KEY = 'openc3_interfaces'
|
|
25
30
|
ROUTERS_PRIMARY_KEY = 'openc3_routers'
|
|
26
31
|
|
|
@@ -36,7 +41,10 @@ module OpenC3
|
|
|
36
41
|
attr_accessor :disable_disconnect
|
|
37
42
|
attr_accessor :options
|
|
38
43
|
attr_accessor :secret_options
|
|
44
|
+
attr_accessor :bridge_options
|
|
45
|
+
attr_accessor :bridge_secret_options
|
|
39
46
|
attr_accessor :protocols
|
|
47
|
+
attr_accessor :bridge_protocols
|
|
40
48
|
attr_accessor :interfaces
|
|
41
49
|
attr_accessor :log_stream
|
|
42
50
|
attr_accessor :needs_dependencies
|
|
@@ -49,6 +57,7 @@ module OpenC3
|
|
|
49
57
|
attr_accessor :prefix
|
|
50
58
|
attr_accessor :shard
|
|
51
59
|
attr_accessor :db_shard
|
|
60
|
+
attr_accessor :bridge_name
|
|
52
61
|
|
|
53
62
|
# NOTE: The following three class methods are used by the ModelController
|
|
54
63
|
# and are reimplemented to enable various Model class methods to work
|
|
@@ -111,6 +120,9 @@ module OpenC3
|
|
|
111
120
|
options: [],
|
|
112
121
|
secret_options: [],
|
|
113
122
|
protocols: [],
|
|
123
|
+
bridge_options: [],
|
|
124
|
+
bridge_secret_options: [],
|
|
125
|
+
bridge_protocols: [],
|
|
114
126
|
log_stream: nil,
|
|
115
127
|
updated_at: nil,
|
|
116
128
|
plugin: nil,
|
|
@@ -124,6 +136,7 @@ module OpenC3
|
|
|
124
136
|
prefix: nil,
|
|
125
137
|
shard: 0,
|
|
126
138
|
db_shard: 0,
|
|
139
|
+
bridge_name: nil,
|
|
127
140
|
scope:
|
|
128
141
|
)
|
|
129
142
|
if self.class._get_type == 'INTERFACE'
|
|
@@ -157,7 +170,10 @@ module OpenC3
|
|
|
157
170
|
@disable_disconnect = disable_disconnect
|
|
158
171
|
@options = options
|
|
159
172
|
@secret_options = secret_options
|
|
173
|
+
@bridge_options = bridge_options
|
|
174
|
+
@bridge_secret_options = bridge_secret_options
|
|
160
175
|
@protocols = protocols
|
|
176
|
+
@bridge_protocols = bridge_protocols
|
|
161
177
|
@log_stream = log_stream
|
|
162
178
|
@needs_dependencies = needs_dependencies
|
|
163
179
|
@cmd = cmd
|
|
@@ -180,6 +196,7 @@ module OpenC3
|
|
|
180
196
|
@prefix = prefix
|
|
181
197
|
@shard = shard.to_i # to_i to handle nil
|
|
182
198
|
@db_shard = db_shard.to_i # to_i to handle nil
|
|
199
|
+
@bridge_name = bridge_name&.to_s&.upcase
|
|
183
200
|
@secrets = secrets
|
|
184
201
|
end
|
|
185
202
|
|
|
@@ -238,6 +255,9 @@ module OpenC3
|
|
|
238
255
|
'options' => @options,
|
|
239
256
|
'secret_options' => @secret_options,
|
|
240
257
|
'protocols' => @protocols,
|
|
258
|
+
'bridge_options' => @bridge_options,
|
|
259
|
+
'bridge_secret_options' => @bridge_secret_options,
|
|
260
|
+
'bridge_protocols' => @bridge_protocols,
|
|
241
261
|
'log_stream' => @log_stream,
|
|
242
262
|
'plugin' => @plugin,
|
|
243
263
|
'needs_dependencies' => @needs_dependencies,
|
|
@@ -250,6 +270,7 @@ module OpenC3
|
|
|
250
270
|
'prefix' => @prefix,
|
|
251
271
|
'shard' => @shard,
|
|
252
272
|
'db_shard' => @db_shard,
|
|
273
|
+
'bridge_name' => @bridge_name,
|
|
253
274
|
'updated_at' => @updated_at
|
|
254
275
|
}
|
|
255
276
|
end
|
|
@@ -277,6 +298,8 @@ module OpenC3
|
|
|
277
298
|
|
|
278
299
|
# Handles Interface/Router specific configuration keywords
|
|
279
300
|
def handle_config(parser, keyword, parameters)
|
|
301
|
+
type = self.class._get_type
|
|
302
|
+
|
|
280
303
|
case keyword
|
|
281
304
|
when 'MAP_TARGET'
|
|
282
305
|
usage = "#{keyword} <Target Name> <ENABLED/DISABLED>"
|
|
@@ -334,6 +357,14 @@ module OpenC3
|
|
|
334
357
|
parser.verify_num_parameters(2, nil, "#{keyword} <Option Name> <Option Value 1> <Option Value 2 (optional)> <etc>")
|
|
335
358
|
@options << parameters.dup
|
|
336
359
|
|
|
360
|
+
when 'BRIDGE_OPTION'
|
|
361
|
+
if type == 'INTERFACE'
|
|
362
|
+
parser.verify_num_parameters(2, nil, "#{keyword} <Option Name> <Option Value 1> <Option Value 2 (optional)> <etc>")
|
|
363
|
+
@bridge_options << parameters.dup
|
|
364
|
+
else
|
|
365
|
+
raise ConfigParser::Error.new(parser, "BRIDGE_OPTION not supported for Router: #{keyword} #{parameters.join(" ")}")
|
|
366
|
+
end
|
|
367
|
+
|
|
337
368
|
when 'PROTOCOL'
|
|
338
369
|
usage = "#{keyword} <READ WRITE READ_WRITE> <protocol filename or classname> <Protocol specific parameters>"
|
|
339
370
|
parser.verify_num_parameters(2, nil, usage)
|
|
@@ -343,6 +374,19 @@ module OpenC3
|
|
|
343
374
|
|
|
344
375
|
@protocols << parameters.dup
|
|
345
376
|
|
|
377
|
+
when 'BRIDGE_PROTOCOL'
|
|
378
|
+
if type == 'INTERFACE'
|
|
379
|
+
usage = "#{keyword} <READ WRITE READ_WRITE> <protocol filename or classname> <Protocol specific parameters>"
|
|
380
|
+
parser.verify_num_parameters(2, nil, usage)
|
|
381
|
+
unless %w(READ WRITE READ_WRITE).include? parameters[0].upcase
|
|
382
|
+
raise parser.error("Invalid protocol type: #{parameters[0]}", usage)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
@bridge_protocols << parameters.dup
|
|
386
|
+
else
|
|
387
|
+
raise ConfigParser::Error.new(parser, "BRIDGE_PROTOCOL not supported for Router: #{keyword} #{parameters.join(" ")}")
|
|
388
|
+
end
|
|
389
|
+
|
|
346
390
|
when 'DONT_LOG'
|
|
347
391
|
Logger.warn "DONT_LOG is deprecated and does nothing."
|
|
348
392
|
|
|
@@ -352,6 +396,7 @@ module OpenC3
|
|
|
352
396
|
|
|
353
397
|
when 'SECRET'
|
|
354
398
|
parser.verify_num_parameters(3, 5, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path> <Option Name (Optional)> <Secret Store Name (Optional)>")
|
|
399
|
+
validate_secret(parser, keyword, parameters)
|
|
355
400
|
@secrets << parameters[0..2]
|
|
356
401
|
if ConfigParser.handle_nil(parameters[3])
|
|
357
402
|
# Option Name, Secret Name
|
|
@@ -359,29 +404,26 @@ module OpenC3
|
|
|
359
404
|
end
|
|
360
405
|
@secrets[-1] << ConfigParser.handle_nil(parameters[4])
|
|
361
406
|
|
|
407
|
+
when 'BRIDGE_SECRET'
|
|
408
|
+
if type == 'INTERFACE'
|
|
409
|
+
parser.verify_num_parameters(3, 5, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path> <Option Name (Optional)> <Secret Store Name (Optional)>")
|
|
410
|
+
validate_secret(parser, keyword, parameters)
|
|
411
|
+
@secrets << parameters[0..2]
|
|
412
|
+
if ConfigParser.handle_nil(parameters[3])
|
|
413
|
+
# Option Name, Secret Name
|
|
414
|
+
@bridge_secret_options << [parameters[3], parameters[1]]
|
|
415
|
+
end
|
|
416
|
+
@secrets[-1] << ConfigParser.handle_nil(parameters[4])
|
|
417
|
+
else
|
|
418
|
+
raise ConfigParser::Error.new(parser, "BRIDGE_SECRET not supported for Router: #{keyword} #{parameters.join(" ")}")
|
|
419
|
+
end
|
|
420
|
+
|
|
362
421
|
when 'ENV'
|
|
363
422
|
parser.verify_num_parameters(2, 2, "#{keyword} <Key> <Value>")
|
|
364
423
|
@env[parameters[0]] = parameters[1]
|
|
365
424
|
|
|
366
425
|
when 'PORT'
|
|
367
|
-
|
|
368
|
-
parser.verify_num_parameters(1, 2, usage)
|
|
369
|
-
begin
|
|
370
|
-
@ports << [Integer(parameters[0])]
|
|
371
|
-
rescue # In case Integer fails
|
|
372
|
-
raise ConfigParser::Error.new(parser, "Port must be an integer: #{parameters[0]}", usage)
|
|
373
|
-
end
|
|
374
|
-
protocol = ConfigParser.handle_nil(parameters[1])
|
|
375
|
-
if protocol
|
|
376
|
-
# Per https://kubernetes.io/docs/concepts/services-networking/service/#protocol-support
|
|
377
|
-
if %w(TCP UDP SCTP).include?(protocol.upcase)
|
|
378
|
-
@ports[-1] << protocol.upcase
|
|
379
|
-
else
|
|
380
|
-
raise ConfigParser::Error.new(parser, "Unknown port protocol: #{parameters[1]}", usage)
|
|
381
|
-
end
|
|
382
|
-
else
|
|
383
|
-
@ports[-1] << 'TCP'
|
|
384
|
-
end
|
|
426
|
+
parse_port(parser, keyword, parameters)
|
|
385
427
|
|
|
386
428
|
when 'WORK_DIR'
|
|
387
429
|
parser.verify_num_parameters(1, 1, "#{keyword} <Dir>")
|
|
@@ -404,8 +446,17 @@ module OpenC3
|
|
|
404
446
|
@shard = Integer(parameters[0])
|
|
405
447
|
|
|
406
448
|
when 'DB_SHARD'
|
|
407
|
-
parser.verify_num_parameters(1, 1, "#{keyword} <
|
|
449
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <DB_Shard Number Starting from 0>")
|
|
408
450
|
@db_shard = Integer(parameters[0])
|
|
451
|
+
|
|
452
|
+
when 'BRIDGE'
|
|
453
|
+
if type == 'INTERFACE'
|
|
454
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Bridge Name>")
|
|
455
|
+
@bridge_name = parameters[0].to_s.upcase
|
|
456
|
+
else
|
|
457
|
+
raise ConfigParser::Error.new(parser, "BRIDGE not supported for Router: #{keyword} #{parameters.join(" ")}")
|
|
458
|
+
end
|
|
459
|
+
|
|
409
460
|
else
|
|
410
461
|
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Interface/Router: #{keyword} #{parameters.join(" ")}")
|
|
411
462
|
|
|
@@ -418,6 +469,11 @@ module OpenC3
|
|
|
418
469
|
def deploy(gem_path, variables, validate_only: false)
|
|
419
470
|
type = self.class._get_type
|
|
420
471
|
microservice_name = "#{@scope}__#{type}__#{@name}"
|
|
472
|
+
# A bridged interface runs on the host (openc3-app) rather than in Docker.
|
|
473
|
+
# COSMOS runs a bridge_interface tunnel + a shared bridge_microservice relay
|
|
474
|
+
# and hands the real interface's spawn info to openc3-app. See deploy_bridge.
|
|
475
|
+
return deploy_bridge(gem_path, variables, microservice_name, type, validate_only: validate_only) if @bridge_name
|
|
476
|
+
|
|
421
477
|
microservice = MicroserviceModel.new(
|
|
422
478
|
name: microservice_name,
|
|
423
479
|
work_dir: @work_dir,
|
|
@@ -444,6 +500,92 @@ module OpenC3
|
|
|
444
500
|
microservice
|
|
445
501
|
end
|
|
446
502
|
|
|
503
|
+
# Deploy a bridged interface. This splits the interface across the Docker
|
|
504
|
+
# side of COSMOS (bridge_interface tunnel + protocols/target processing) and
|
|
505
|
+
# the host side (openc3-app spawns the real interface for raw data transfer):
|
|
506
|
+
# 1. A COSMOS interface_microservice that builds a bridge_interface tunnel
|
|
507
|
+
# (InterfaceModel#build substitutes BridgeInterface when bridge_name is
|
|
508
|
+
# set) and connects to the named bridge_microservice relay.
|
|
509
|
+
# 2. A shared bridge_microservice relay (one per bridge_name) that this
|
|
510
|
+
# interface's stream (ALPN stream/<name>) is added to.
|
|
511
|
+
# 3. A HostInterfaceMicroserviceModel holding the real interface's spawn info for
|
|
512
|
+
# openc3-app to run the interface on the host.
|
|
513
|
+
def deploy_bridge(gem_path, variables, microservice_name, type, validate_only: false)
|
|
514
|
+
# The COSMOS side runs the Python interface_microservice which builds a
|
|
515
|
+
# BridgeInterface (see InterfaceModel#build). It keeps this interface's
|
|
516
|
+
# protocols and target mapping; the raw device I/O is tunneled to the host.
|
|
517
|
+
cmd = [BridgeModel.bridge_python_bin, "#{type.downcase}_microservice.py", microservice_name]
|
|
518
|
+
microservice = MicroserviceModel.new(
|
|
519
|
+
name: microservice_name,
|
|
520
|
+
work_dir: BridgeModel::BRIDGE_WORK_DIR,
|
|
521
|
+
cmd: cmd,
|
|
522
|
+
env: @env,
|
|
523
|
+
ports: @ports,
|
|
524
|
+
container: @container,
|
|
525
|
+
target_names: @target_names,
|
|
526
|
+
plugin: @plugin,
|
|
527
|
+
needs_dependencies: @needs_dependencies,
|
|
528
|
+
secrets: @secrets,
|
|
529
|
+
prefix: @prefix,
|
|
530
|
+
shard: @shard,
|
|
531
|
+
db_shard: @db_shard,
|
|
532
|
+
scope: @scope
|
|
533
|
+
)
|
|
534
|
+
unless validate_only
|
|
535
|
+
@target_names.each { |target_name| ensure_target_exists(target_name) }
|
|
536
|
+
check_bridge_relay()
|
|
537
|
+
microservice.create
|
|
538
|
+
microservice.deploy(gem_path, variables)
|
|
539
|
+
create_host_interface_microservice()
|
|
540
|
+
ConfigTopic.write({ kind: 'created', type: type.downcase, name: @name, plugin: @plugin }, scope: @scope)
|
|
541
|
+
Logger.info "Configured bridged #{type.downcase} microservice #{microservice_name} (bridge #{@bridge_name})"
|
|
542
|
+
end
|
|
543
|
+
microservice
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# Name of the shared bridge_microservice relay for a given bridge name.
|
|
547
|
+
def bridge_relay_name
|
|
548
|
+
"#{@scope}__BRIDGE__#{@bridge_name}"
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
# Verify the shared bridge_microservice relay for @bridge_name exists.
|
|
552
|
+
# Multiple bridged interfaces sharing a bridge name all route through the
|
|
553
|
+
# same relay. The relay discovers which streams to advertise by querying the
|
|
554
|
+
# HostInterfaceMicroserviceModels for its bridge (see bridge_microservice.py), so we
|
|
555
|
+
# deliberately do NOT push this interface's stream onto the relay as an
|
|
556
|
+
# OPTION: mutating (updating) the relay's MicroserviceModel would make the
|
|
557
|
+
# operator respawn the relay every time a bridged interface is added or
|
|
558
|
+
# removed. Leaving the model untouched lets the relay adapt live instead.
|
|
559
|
+
def check_bridge_relay
|
|
560
|
+
relay = MicroserviceModel.get_model(name: bridge_relay_name, scope: @scope)
|
|
561
|
+
raise "Bridge #{@bridge_name} does not exist" unless relay
|
|
562
|
+
relay
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
# Capture the real interface's spawn info for openc3-app. The host side does
|
|
566
|
+
# raw data transfer only, so protocols and target definitions are omitted;
|
|
567
|
+
# the connection options and secrets needed to open the device are included.
|
|
568
|
+
def create_host_interface_microservice
|
|
569
|
+
host = HostInterfaceMicroserviceModel.new(
|
|
570
|
+
name: @name,
|
|
571
|
+
bridge_name: @bridge_name,
|
|
572
|
+
stream: @name,
|
|
573
|
+
config_params: @config_params,
|
|
574
|
+
work_dir: @work_dir,
|
|
575
|
+
env: @env,
|
|
576
|
+
options: @bridge_options,
|
|
577
|
+
secret_options: @bridge_secret_options,
|
|
578
|
+
protocols: @bridge_protocols,
|
|
579
|
+
secrets: @secrets,
|
|
580
|
+
container: @container,
|
|
581
|
+
needs_dependencies: @needs_dependencies,
|
|
582
|
+
plugin: @plugin,
|
|
583
|
+
scope: @scope
|
|
584
|
+
)
|
|
585
|
+
host.create(force: true)
|
|
586
|
+
host
|
|
587
|
+
end
|
|
588
|
+
|
|
447
589
|
# Destroys the deployed MicroserviceModel which triggers the operator to kill
|
|
448
590
|
# the microservice. Also directly destroys the Interface/RouterStatusModel in
|
|
449
591
|
# an ensure block. The microservice stop() no longer recreates the status
|
|
@@ -469,6 +611,23 @@ module OpenC3
|
|
|
469
611
|
status_model.destroy if status_model
|
|
470
612
|
rescue Exception => error
|
|
471
613
|
Logger.error("Error destroying #{type&.downcase || 'unknown'} status model #{@name} in scope #{@scope} due to #{error}")
|
|
614
|
+
ensure
|
|
615
|
+
undeploy_bridge if @bridge_name
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
# Clean up the host-side pieces of a bridged interface by destroying its
|
|
620
|
+
# HostInterfaceMicroserviceModel. The shared bridge_microservice relay is left
|
|
621
|
+
# untouched: it discovers its streams by querying the HostInterfaceMicroserviceModels,
|
|
622
|
+
# so removing this one makes the relay drop the stream's ALPN on its own.
|
|
623
|
+
# (Mutating the relay's MicroserviceModel here would respawn it.) The relay
|
|
624
|
+
# itself is destroyed with its BridgeModel, not per-interface.
|
|
625
|
+
def undeploy_bridge
|
|
626
|
+
begin
|
|
627
|
+
host = HostInterfaceMicroserviceModel.get_model(name: @name, scope: @scope)
|
|
628
|
+
host.destroy if host
|
|
629
|
+
rescue Exception => error
|
|
630
|
+
Logger.error("Error destroying HostInterfaceMicroservice model #{@name} in scope #{@scope} due to #{error}")
|
|
472
631
|
end
|
|
473
632
|
end
|
|
474
633
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -17,12 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
require 'openc3/top_level'
|
|
19
19
|
require 'openc3/models/model'
|
|
20
|
+
require 'openc3/models/config_keyword_model'
|
|
20
21
|
require 'openc3/models/metric_model'
|
|
21
22
|
require 'openc3/topics/config_topic'
|
|
22
23
|
require 'openc3/utilities/bucket'
|
|
24
|
+
require 'openc3/utilities/python_venv'
|
|
23
25
|
|
|
24
26
|
module OpenC3
|
|
25
27
|
class MicroserviceModel < Model
|
|
28
|
+
include ConfigKeywordModel
|
|
29
|
+
|
|
26
30
|
PRIMARY_KEY = 'openc3_microservices'
|
|
27
31
|
|
|
28
32
|
attr_accessor :cmd
|
|
@@ -146,16 +150,15 @@ module OpenC3
|
|
|
146
150
|
python_bin = ENV['OPENC3_PYTHON_BIN'] || '/openc3/python/.venv/bin/python'
|
|
147
151
|
result = { 'OPENC3_PYTHON_BIN' => python_bin }
|
|
148
152
|
if @needs_dependencies && @plugin
|
|
149
|
-
|
|
150
|
-
candidate
|
|
151
|
-
if File.directory?(candidate)
|
|
153
|
+
candidate = PythonVenv.plugin_venv_path(scope: @scope, plugin_name: @plugin)
|
|
154
|
+
if candidate
|
|
152
155
|
result['VIRTUAL_ENV'] = candidate
|
|
153
156
|
result['PYTHONUSERBASE'] = candidate
|
|
154
157
|
site_packages = Dir.glob("#{candidate}/lib/python*/site-packages").first
|
|
155
158
|
result['PYTHONPATH'] = site_packages
|
|
156
159
|
else
|
|
157
160
|
result['VIRTUAL_ENV'] = nil
|
|
158
|
-
result['PYTHONUSERBASE'] =
|
|
161
|
+
result['PYTHONUSERBASE'] = PythonVenv::DEFAULT_PYTHONUSERBASE
|
|
159
162
|
end
|
|
160
163
|
end
|
|
161
164
|
result
|
|
@@ -196,24 +199,7 @@ module OpenC3
|
|
|
196
199
|
parser.verify_num_parameters(1, 1, "#{keyword} <Dir>")
|
|
197
200
|
@work_dir = parameters[0]
|
|
198
201
|
when 'PORT'
|
|
199
|
-
|
|
200
|
-
parser.verify_num_parameters(1, 2, usage)
|
|
201
|
-
begin
|
|
202
|
-
@ports << [Integer(parameters[0])]
|
|
203
|
-
rescue # In case Integer fails
|
|
204
|
-
raise ConfigParser::Error.new(parser, "Port must be an integer: #{parameters[0]}", usage)
|
|
205
|
-
end
|
|
206
|
-
protocol = ConfigParser.handle_nil(parameters[1])
|
|
207
|
-
if protocol
|
|
208
|
-
# Per https://kubernetes.io/docs/concepts/services-networking/service/#protocol-support
|
|
209
|
-
if %w(TCP UDP SCTP).include?(protocol.upcase)
|
|
210
|
-
@ports[-1] << protocol.upcase
|
|
211
|
-
else
|
|
212
|
-
raise ConfigParser::Error.new(parser, "Unknown port protocol: #{parameters[1]}", usage)
|
|
213
|
-
end
|
|
214
|
-
else
|
|
215
|
-
@ports[-1] << 'TCP'
|
|
216
|
-
end
|
|
202
|
+
parse_port(parser, keyword, parameters)
|
|
217
203
|
when 'TOPIC'
|
|
218
204
|
parser.verify_num_parameters(1, 1, "#{keyword} <Topic Name>")
|
|
219
205
|
@topics << parameters[0]
|
|
@@ -244,6 +230,7 @@ module OpenC3
|
|
|
244
230
|
@container = parameters[0]
|
|
245
231
|
when 'SECRET'
|
|
246
232
|
parser.verify_num_parameters(3, 4, "#{keyword} <Secret Type: ENV or FILE> <Secret Name> <Environment Variable Name or File Path> <Secret Store Name (Optional)>")
|
|
233
|
+
validate_secret(parser, keyword, parameters)
|
|
247
234
|
if ConfigParser.handle_nil(parameters[3])
|
|
248
235
|
@secrets << parameters.dup
|
|
249
236
|
else
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/models/model.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -19,9 +19,11 @@ require 'rubygems'
|
|
|
19
19
|
require 'rubygems/package'
|
|
20
20
|
require 'openc3'
|
|
21
21
|
require 'openc3/utilities/bucket'
|
|
22
|
+
require 'openc3/utilities/python_venv'
|
|
22
23
|
require 'openc3/utilities/store'
|
|
23
24
|
require 'openc3/config/config_parser'
|
|
24
25
|
require 'openc3/models/model'
|
|
26
|
+
require 'openc3/models/scope_model'
|
|
25
27
|
require 'openc3/models/gem_model'
|
|
26
28
|
require 'openc3/models/target_model'
|
|
27
29
|
require 'openc3/models/interface_model'
|
|
@@ -291,7 +293,12 @@ module OpenC3
|
|
|
291
293
|
uv_args = [plugin_venv_name, gem_path] + pypi_args
|
|
292
294
|
output, status = Open3.capture2e("/openc3/bin/uvinstall", *uv_args)
|
|
293
295
|
puts output
|
|
294
|
-
|
|
296
|
+
if status.success?
|
|
297
|
+
# A plugin that declares openc3 itself would shadow the system
|
|
298
|
+
# library once its site-packages goes on PYTHONPATH, so drop it
|
|
299
|
+
# here rather than let the wrong client reach a running script.
|
|
300
|
+
PythonVenv.purge_reserved_packages(File.join('/gems', 'plugin_venvs', plugin_venv_name, '.venv'))
|
|
301
|
+
else
|
|
295
302
|
Logger.warn "UV per-plugin install failed, falling back to shared pipinstall"
|
|
296
303
|
uv_installed = false
|
|
297
304
|
end
|
|
@@ -596,7 +603,7 @@ module OpenC3
|
|
|
596
603
|
Logger.error("Failed to retrieve pypi_url: #{e.formatted}")
|
|
597
604
|
ensure
|
|
598
605
|
if pypi_url.nil?
|
|
599
|
-
pypi_url = ENV
|
|
606
|
+
pypi_url = ENV.fetch('PYPI_URL', nil)
|
|
600
607
|
pypi_url += '/simple' if pypi_url
|
|
601
608
|
pypi_url ||= PypiUrl::DEFAULT
|
|
602
609
|
end
|
|
File without changes
|
|
File without changes
|
|
@@ -188,7 +188,7 @@ module OpenC3
|
|
|
188
188
|
end
|
|
189
189
|
|
|
190
190
|
def self.get(name)
|
|
191
|
-
path = "#{ENV
|
|
191
|
+
path = "#{ENV.fetch('PYTHONUSERBASE', nil)}/cache"
|
|
192
192
|
FileUtils.mkdir_p(path) unless Dir.exist?(path)
|
|
193
193
|
result = Pathname.new(path).children.select { |c| c.file? and File.basename(c, File.extname(c)) == name }
|
|
194
194
|
if result.length > 0
|
|
@@ -200,8 +200,8 @@ module OpenC3
|
|
|
200
200
|
def self.put(package_file_path, package_install: true, scope:, plugin: nil)
|
|
201
201
|
if File.file?(package_file_path)
|
|
202
202
|
package_filename = File.basename(package_file_path)
|
|
203
|
-
FileUtils.mkdir_p("#{ENV
|
|
204
|
-
cache_path = "#{ENV
|
|
203
|
+
FileUtils.mkdir_p("#{ENV.fetch('PYTHONUSERBASE')}/cache") unless Dir.exist?("#{ENV.fetch('PYTHONUSERBASE')}/cache")
|
|
204
|
+
cache_path = "#{ENV.fetch('PYTHONUSERBASE')}/cache/#{File.basename(package_file_path)}"
|
|
205
205
|
FileUtils.cp(package_file_path, cache_path)
|
|
206
206
|
|
|
207
207
|
# Copy uploaded .whl files to the UV uploads directory so they appear
|
|
@@ -244,7 +244,7 @@ module OpenC3
|
|
|
244
244
|
ensure
|
|
245
245
|
if pypi_url.nil?
|
|
246
246
|
# If Redis isn't running try the ENV, then simply pypi.org/simple
|
|
247
|
-
pypi_url = ENV
|
|
247
|
+
pypi_url = ENV.fetch('PYPI_URL', nil)
|
|
248
248
|
if pypi_url
|
|
249
249
|
pypi_url += '/simple'
|
|
250
250
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|