openc3 7.2.1 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Guardfile +0 -0
- data/LICENSE.md +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/bin/openc3cli +235 -6
- data/bin/pipinstall +5 -4
- data/bin/pipuninstall +5 -1
- data/bin/uvinstall +156 -0
- data/data/config/_array_params.yaml +0 -0
- data/data/config/_canvas_values.yaml +0 -0
- data/data/config/_graph_params.yaml +0 -0
- data/data/config/_id_items.yaml +0 -0
- data/data/config/_id_params.yaml +0 -0
- data/data/config/_interfaces.yaml +0 -0
- data/data/config/_items.yaml +0 -0
- data/data/config/_params.yaml +0 -0
- data/data/config/command.yaml +0 -0
- data/data/config/command_modifiers.yaml +2 -0
- data/data/config/command_telemetry.yaml +0 -0
- data/data/config/conversions.yaml +0 -0
- data/data/config/graph_settings.yaml +0 -0
- data/data/config/interface_modifiers.yaml +103 -1
- data/data/config/item_modifiers.yaml +2 -1
- data/data/config/microservice.yaml +9 -2
- data/data/config/param_item_modifiers.yaml +0 -0
- data/data/config/parameter_modifiers.yaml +0 -0
- data/data/config/plugins.yaml +0 -0
- data/data/config/processors.yaml +0 -0
- data/data/config/protocols.yaml +0 -0
- data/data/config/screen.yaml +2 -1
- data/data/config/settings.yaml +0 -0
- data/data/config/table_manager.yaml +0 -0
- data/data/config/table_parameter_modifiers.yaml +0 -0
- data/data/config/target.yaml +21 -0
- data/data/config/target_config.yaml +0 -0
- data/data/config/telemetry.yaml +0 -0
- data/data/config/telemetry_modifiers.yaml +2 -0
- data/data/config/tool.yaml +3 -1
- data/data/config/unknown.yaml +0 -0
- data/data/config/widgets.yaml +22 -3
- data/data/xtce_schemas/SpaceSystem_20180204.xsd +5918 -0
- data/data/xtce_schemas/xml.xsd +116 -0
- data/ext/openc3/ext/array/array.c +0 -0
- data/ext/openc3/ext/array/extconf.rb +0 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +0 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +0 -0
- data/ext/openc3/ext/burst_protocol/burst_protocol.c +6 -0
- data/ext/openc3/ext/burst_protocol/extconf.rb +0 -0
- data/ext/openc3/ext/config_parser/config_parser.c +0 -0
- data/ext/openc3/ext/config_parser/extconf.rb +0 -0
- data/ext/openc3/ext/crc/crc.c +0 -0
- data/ext/openc3/ext/crc/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +0 -0
- data/ext/openc3/ext/packet/extconf.rb +0 -0
- data/ext/openc3/ext/packet/packet.c +0 -0
- data/ext/openc3/ext/platform/extconf.rb +0 -0
- data/ext/openc3/ext/platform/platform.c +4 -1
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +0 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +0 -0
- data/ext/openc3/ext/string/extconf.rb +0 -0
- data/ext/openc3/ext/string/string.c +0 -0
- data/ext/openc3/ext/structure/structure.c +49 -17
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +0 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +0 -0
- data/ext/openc3/ext/telemetry/extconf.rb +0 -0
- data/ext/openc3/ext/telemetry/telemetry.c +1 -1
- data/lib/cosmos.rb +0 -0
- data/lib/cosmosc2.rb +0 -0
- data/lib/openc3/accessors/accessor.rb +0 -0
- data/lib/openc3/accessors/binary_accessor.rb +63 -9
- data/lib/openc3/accessors/cbor_accessor.rb +0 -0
- data/lib/openc3/accessors/form_accessor.rb +0 -0
- data/lib/openc3/accessors/html_accessor.rb +0 -0
- data/lib/openc3/accessors/http_accessor.rb +0 -0
- data/lib/openc3/accessors/json_accessor.rb +0 -0
- data/lib/openc3/accessors/template_accessor.rb +2 -2
- data/lib/openc3/accessors/xml_accessor.rb +0 -0
- data/lib/openc3/accessors.rb +0 -0
- data/lib/openc3/api/README.md +0 -0
- data/lib/openc3/api/api.rb +0 -0
- data/lib/openc3/api/authorized_api.rb +0 -0
- data/lib/openc3/api/calendar_api.rb +0 -0
- data/lib/openc3/api/cmd_api.rb +1 -1
- data/lib/openc3/api/config_api.rb +0 -0
- data/lib/openc3/api/interface_api.rb +2 -2
- data/lib/openc3/api/limits_api.rb +27 -13
- data/lib/openc3/api/metrics_api.rb +1 -1
- data/lib/openc3/api/offline_access_api.rb +1 -1
- data/lib/openc3/api/router_api.rb +3 -3
- data/lib/openc3/api/settings_api.rb +22 -18
- data/lib/openc3/api/stash_api.rb +1 -1
- data/lib/openc3/api/target_api.rb +0 -0
- data/lib/openc3/api/tlm_api.rb +5 -4
- data/lib/openc3/bridge/bridge.rb +0 -0
- data/lib/openc3/bridge/bridge_config.rb +0 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +0 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +0 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +0 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +0 -0
- data/lib/openc3/config/config_parser.rb +78 -17
- data/lib/openc3/config/meta_config_parser.rb +0 -0
- data/lib/openc3/conversions/bit_reverse_conversion.rb +0 -0
- data/lib/openc3/conversions/conversion.rb +0 -0
- data/lib/openc3/conversions/generic_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_read_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_write_conversion.rb +0 -0
- data/lib/openc3/conversions/object_read_conversion.rb +0 -0
- data/lib/openc3/conversions/object_write_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/processor_conversion.rb +0 -0
- data/lib/openc3/conversions/received_count_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions.rb +0 -0
- data/lib/openc3/core_ext/array.rb +0 -0
- data/lib/openc3/core_ext/binding.rb +0 -0
- data/lib/openc3/core_ext/class.rb +0 -0
- data/lib/openc3/core_ext/exception.rb +0 -0
- data/lib/openc3/core_ext/faraday.rb +0 -0
- data/lib/openc3/core_ext/file.rb +0 -0
- data/lib/openc3/core_ext/io.rb +0 -0
- data/lib/openc3/core_ext/kernel.rb +0 -0
- data/lib/openc3/core_ext/math.rb +0 -0
- data/lib/openc3/core_ext/matrix.rb +0 -0
- data/lib/openc3/core_ext/objectspace.rb +0 -0
- data/lib/openc3/core_ext/openc3_io.rb +0 -0
- data/lib/openc3/core_ext/range.rb +0 -0
- data/lib/openc3/core_ext/socket.rb +0 -0
- data/lib/openc3/core_ext/string.rb +0 -0
- data/lib/openc3/core_ext/stringio.rb +0 -0
- data/lib/openc3/core_ext/tempfile.rb +0 -0
- data/lib/openc3/core_ext/time.rb +0 -0
- data/lib/openc3/core_ext.rb +0 -0
- data/lib/openc3/ext/.keep +0 -0
- data/lib/openc3/interfaces/file_interface.rb +0 -0
- data/lib/openc3/interfaces/http_client_interface.rb +1 -1
- data/lib/openc3/interfaces/http_server_interface.rb +0 -0
- data/lib/openc3/interfaces/interface.rb +5 -4
- data/lib/openc3/interfaces/mqtt_interface.rb +0 -0
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +2 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +27 -0
- data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/cobs_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +4 -4
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +0 -0
- data/lib/openc3/interfaces/serial_interface.rb +2 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +0 -0
- data/lib/openc3/interfaces/stream_interface.rb +0 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +2 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -0
- data/lib/openc3/interfaces/udp_interface.rb +16 -5
- data/lib/openc3/interfaces.rb +0 -0
- data/lib/openc3/io/buffered_file.rb +0 -0
- data/lib/openc3/io/io_multiplexer.rb +0 -0
- data/lib/openc3/io/json_api.rb +3 -2
- data/lib/openc3/io/json_api_object.rb +0 -0
- data/lib/openc3/io/json_drb.rb +44 -12
- data/lib/openc3/io/json_drb_object.rb +0 -0
- data/lib/openc3/io/json_drb_rack.rb +0 -0
- data/lib/openc3/io/json_rpc.rb +0 -2
- data/lib/openc3/io/posix_serial_driver.rb +0 -0
- data/lib/openc3/io/serial_driver.rb +0 -0
- data/lib/openc3/io/stderr.rb +0 -0
- data/lib/openc3/io/stdout.rb +0 -0
- data/lib/openc3/io/udp_sockets.rb +38 -8
- data/lib/openc3/io/win32_serial_driver.rb +1 -0
- data/lib/openc3/logs/buffered_packet_log_reader.rb +0 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +0 -0
- data/lib/openc3/logs/log_writer.rb +43 -7
- data/lib/openc3/logs/packet_log_constants.rb +0 -0
- data/lib/openc3/logs/packet_log_reader.rb +23 -2
- data/lib/openc3/logs/packet_log_writer.rb +6 -2
- data/lib/openc3/logs/stream_log.rb +1 -1
- data/lib/openc3/logs/stream_log_pair.rb +0 -0
- data/lib/openc3/logs/text_log_writer.rb +0 -0
- data/lib/openc3/logs.rb +0 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/decom_common.rb +0 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -0
- data/lib/openc3/microservices/interface_decom_common.rb +2 -1
- data/lib/openc3/microservices/interface_microservice.rb +73 -26
- data/lib/openc3/microservices/log_microservice.rb +0 -0
- data/lib/openc3/microservices/microservice.rb +3 -3
- data/lib/openc3/microservices/multi_microservice.rb +1 -1
- data/lib/openc3/microservices/periodic_microservice.rb +2 -2
- data/lib/openc3/microservices/plugin_microservice.rb +0 -0
- data/lib/openc3/microservices/queue_microservice.rb +0 -0
- data/lib/openc3/microservices/router_microservice.rb +0 -0
- data/lib/openc3/microservices/scope_cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/text_log_microservice.rb +0 -0
- data/lib/openc3/migrations/20220420190000_log_stuff.rb +0 -0
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +0 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +0 -0
- data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +0 -0
- data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +0 -0
- data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +0 -0
- data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +0 -0
- data/lib/openc3/migrations/20250108060000_news_feed.rb +0 -0
- data/lib/openc3/migrations/20250402000000_periodic_only_default.rb +0 -0
- data/lib/openc3/migrations/20260203000000_remove_store_id.rb +0 -0
- data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +0 -0
- data/lib/openc3/migrations/20260701000000_updated_at_to_int.rb +0 -0
- data/lib/openc3/migrations/20260704000000_default_bridge.rb +38 -0
- data/lib/openc3/migrations/20260731000000_system_health_json.rb +52 -0
- data/lib/openc3/models/activity_model.rb +0 -0
- data/lib/openc3/models/auth_model.rb +35 -7
- data/lib/openc3/models/bridge_model.rb +133 -0
- data/lib/openc3/models/config_keyword_model.rb +63 -0
- data/lib/openc3/models/cvt_model.rb +5 -5
- data/lib/openc3/models/db_sharded_model.rb +0 -0
- data/lib/openc3/models/environment_model.rb +0 -0
- data/lib/openc3/models/gem_model.rb +13 -10
- data/lib/openc3/models/host_interface_microservice_model.rb +114 -0
- data/lib/openc3/models/info_model.rb +0 -0
- data/lib/openc3/models/interface_model.rb +179 -20
- data/lib/openc3/models/interface_status_model.rb +0 -0
- data/lib/openc3/models/metadata_model.rb +0 -0
- data/lib/openc3/models/metric_model.rb +0 -0
- data/lib/openc3/models/microservice_model.rb +26 -18
- data/lib/openc3/models/microservice_status_model.rb +0 -0
- data/lib/openc3/models/migration_model.rb +0 -0
- data/lib/openc3/models/model.rb +0 -0
- data/lib/openc3/models/news_model.rb +0 -0
- data/lib/openc3/models/note_model.rb +0 -0
- data/lib/openc3/models/offline_access_model.rb +0 -0
- data/lib/openc3/models/ping_model.rb +0 -0
- data/lib/openc3/models/plugin_model.rb +211 -50
- data/lib/openc3/models/plugin_store_model.rb +0 -0
- data/lib/openc3/models/process_status_model.rb +0 -0
- data/lib/openc3/models/python_package_model.rb +211 -15
- data/lib/openc3/models/queue_model.rb +0 -0
- data/lib/openc3/models/reaction_model.rb +0 -0
- data/lib/openc3/models/reingest_job_model.rb +0 -0
- data/lib/openc3/models/router_model.rb +0 -0
- data/lib/openc3/models/router_status_model.rb +0 -0
- data/lib/openc3/models/scope_model.rb +85 -56
- data/lib/openc3/models/script_engine_model.rb +0 -0
- data/lib/openc3/models/script_status_model.rb +0 -0
- data/lib/openc3/models/secret_model.rb +0 -0
- data/lib/openc3/models/setting_model.rb +546 -3
- data/lib/openc3/models/sorted_model.rb +0 -0
- data/lib/openc3/models/stash_model.rb +0 -0
- data/lib/openc3/models/target_model.rb +210 -31
- data/lib/openc3/models/timeline_model.rb +0 -0
- data/lib/openc3/models/tool_config_model.rb +0 -0
- data/lib/openc3/models/tool_model.rb +34 -20
- data/lib/openc3/models/trigger_group_model.rb +0 -0
- data/lib/openc3/models/trigger_model.rb +20 -0
- data/lib/openc3/models/widget_model.rb +0 -0
- data/lib/openc3/operators/microservice_operator.rb +79 -8
- data/lib/openc3/operators/operator.rb +4 -4
- data/lib/openc3/packets/binary_accessor.rb +0 -0
- data/lib/openc3/packets/command_validator.rb +0 -0
- data/lib/openc3/packets/commands.rb +4 -4
- data/lib/openc3/packets/json_packet.rb +0 -0
- data/lib/openc3/packets/limits.rb +15 -7
- data/lib/openc3/packets/limits_response.rb +0 -0
- data/lib/openc3/packets/packet.rb +5 -1
- data/lib/openc3/packets/packet_config.rb +0 -0
- data/lib/openc3/packets/packet_item.rb +0 -0
- data/lib/openc3/packets/packet_item_limits.rb +0 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +0 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +0 -0
- data/lib/openc3/packets/parsers/state_parser.rb +1 -1
- data/lib/openc3/packets/parsers/xtce_converter.rb +183 -103
- data/lib/openc3/packets/parsers/xtce_parser.rb +71 -23
- data/lib/openc3/packets/structure.rb +9 -3
- data/lib/openc3/packets/structure_item.rb +0 -0
- data/lib/openc3/packets/telemetry.rb +3 -3
- data/lib/openc3/processors/processor.rb +2 -0
- data/lib/openc3/processors/statistics_processor.rb +0 -0
- data/lib/openc3/processors/watermark_processor.rb +0 -0
- data/lib/openc3/processors.rb +0 -0
- data/lib/openc3/script/api_shared.rb +0 -0
- data/lib/openc3/script/autonomic.rb +12 -12
- data/lib/openc3/script/calendar.rb +0 -0
- data/lib/openc3/script/commands.rb +1 -1
- data/lib/openc3/script/critical_cmd.rb +0 -0
- data/lib/openc3/script/exceptions.rb +0 -0
- data/lib/openc3/script/extract.rb +20 -25
- data/lib/openc3/script/limits.rb +0 -0
- data/lib/openc3/script/metadata.rb +0 -0
- data/lib/openc3/script/packages.rb +0 -0
- data/lib/openc3/script/plugins.rb +0 -0
- data/lib/openc3/script/queue.rb +0 -0
- data/lib/openc3/script/screen.rb +0 -0
- data/lib/openc3/script/script.rb +2 -2
- data/lib/openc3/script/script_runner.rb +0 -0
- data/lib/openc3/script/storage.rb +4 -4
- data/lib/openc3/script/suite.rb +0 -0
- data/lib/openc3/script/suite_results.rb +0 -0
- data/lib/openc3/script/suite_runner.rb +26 -0
- data/lib/openc3/script/tables.rb +0 -0
- data/lib/openc3/script/telemetry.rb +9 -3
- data/lib/openc3/script/web_socket_api.rb +247 -134
- data/lib/openc3/script.rb +0 -0
- data/lib/openc3/script_engines/script_engine.rb +0 -0
- data/lib/openc3/streams/mqtt_stream.rb +0 -0
- data/lib/openc3/streams/serial_stream.rb +0 -0
- data/lib/openc3/streams/stream.rb +0 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +0 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +0 -0
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -0
- data/lib/openc3/subpacketizers/subpacketizer.rb +0 -0
- data/lib/openc3/system/system.rb +0 -0
- data/lib/openc3/system/target.rb +0 -0
- data/lib/openc3/system.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +7 -0
- data/lib/openc3/tools/table_manager/table.rb +0 -0
- data/lib/openc3/tools/table_manager/table_config.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +0 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +0 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +0 -0
- data/lib/openc3/tools/test_runner/test.rb +0 -0
- data/lib/openc3/top_level.rb +1 -1
- data/lib/openc3/topics/autonomic_topic.rb +0 -0
- data/lib/openc3/topics/calendar_topic.rb +0 -0
- data/lib/openc3/topics/command_decom_topic.rb +16 -1
- data/lib/openc3/topics/command_topic.rb +0 -0
- data/lib/openc3/topics/config_topic.rb +0 -0
- data/lib/openc3/topics/decom_interface_topic.rb +2 -1
- data/lib/openc3/topics/interface_topic.rb +8 -2
- data/lib/openc3/topics/limits_event_topic.rb +1 -1
- data/lib/openc3/topics/notebook_topic.rb +0 -0
- data/lib/openc3/topics/queue_topic.rb +0 -0
- data/lib/openc3/topics/router_topic.rb +6 -1
- data/lib/openc3/topics/system_events_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_topic.rb +0 -0
- data/lib/openc3/topics/timeline_topic.rb +0 -0
- data/lib/openc3/topics/topic.rb +0 -0
- data/lib/openc3/utilities/authentication.rb +4 -4
- data/lib/openc3/utilities/authorization.rb +0 -0
- data/lib/openc3/utilities/aws_bucket.rb +12 -4
- data/lib/openc3/utilities/bucket.rb +1 -1
- data/lib/openc3/utilities/bucket_file_cache.rb +55 -22
- data/lib/openc3/utilities/bucket_require.rb +0 -0
- data/lib/openc3/utilities/bucket_utilities.rb +3 -4
- data/lib/openc3/utilities/cli_generator.rb +0 -0
- data/lib/openc3/utilities/cmd_log.rb +0 -0
- data/lib/openc3/utilities/config_overlay.rb +75 -0
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +0 -0
- data/lib/openc3/utilities/crc.rb +59 -32
- data/lib/openc3/utilities/csv.rb +5 -5
- data/lib/openc3/utilities/ctrf.rb +0 -0
- data/lib/openc3/utilities/env_helper.rb +0 -0
- data/lib/openc3/utilities/local_bucket.rb +0 -0
- data/lib/openc3/utilities/local_mode.rb +36 -7
- data/lib/openc3/utilities/logger.rb +30 -8
- data/lib/openc3/utilities/message_log.rb +0 -0
- data/lib/openc3/utilities/metric.rb +0 -0
- data/lib/openc3/utilities/migration.rb +0 -0
- data/lib/openc3/utilities/open_telemetry.rb +0 -0
- data/lib/openc3/utilities/process_manager.rb +0 -0
- data/lib/openc3/utilities/pypi_url.rb +0 -0
- data/lib/openc3/utilities/python_proxy.rb +0 -0
- data/lib/openc3/utilities/python_venv.rb +135 -0
- data/lib/openc3/utilities/quaternion.rb +0 -0
- data/lib/openc3/utilities/questdb_client.rb +0 -0
- data/lib/openc3/utilities/redis_secrets.rb +0 -0
- data/lib/openc3/utilities/reingest_job.rb +0 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +5 -1
- data/lib/openc3/utilities/rubygems_url.rb +39 -0
- data/lib/openc3/utilities/running_script.rb +119 -95
- data/lib/openc3/utilities/s3_autoload.rb +5 -5
- data/lib/openc3/utilities/script.rb +52 -12
- data/lib/openc3/utilities/secrets.rb +48 -3
- data/lib/openc3/utilities/simulated_target.rb +0 -0
- data/lib/openc3/utilities/sleeper.rb +0 -0
- data/lib/openc3/utilities/store.rb +0 -0
- data/lib/openc3/utilities/store_autoload.rb +2 -2
- data/lib/openc3/utilities/store_queued.rb +0 -0
- data/lib/openc3/utilities/target_file.rb +18 -1
- data/lib/openc3/utilities/thread_manager.rb +0 -0
- data/lib/openc3/utilities/throttle.rb +0 -0
- data/lib/openc3/utilities/zip.rb +0 -0
- data/lib/openc3/utilities.rb +0 -0
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3/win32/excel.rb +0 -0
- data/lib/openc3/win32/win32.rb +0 -0
- data/lib/openc3/win32/win32_main.rb +0 -0
- data/lib/openc3.rb +2 -2
- data/tasks/gemfile_stats.rake +0 -0
- data/tasks/spec.rake +0 -0
- data/templates/command_validator/command_validator.py +0 -0
- data/templates/command_validator/command_validator.rb +0 -0
- data/templates/conversion/conversion.py +0 -0
- data/templates/conversion/conversion.rb +0 -0
- data/templates/limits_response/response.py +0 -0
- data/templates/limits_response/response.rb +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.py +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -0
- data/templates/plugin/.gitignore +0 -0
- data/templates/plugin/LICENSE.md +0 -0
- data/templates/plugin/README.md +0 -0
- data/templates/plugin/Rakefile +0 -0
- data/templates/plugin/plugin.gemspec +1 -1
- data/templates/plugin/plugin.txt +0 -0
- data/templates/processor/processor.py +1 -1
- data/templates/processor/processor.rb +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- data/templates/target/targets/TARGET/lib/target.py +0 -0
- data/templates/target/targets/TARGET/lib/target.rb +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.py +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.rb +0 -0
- data/templates/target/targets/TARGET/public/README.txt +0 -0
- data/templates/target/targets/TARGET/screens/status.txt +0 -0
- data/templates/target/targets/TARGET/target.txt +0 -0
- data/templates/tool_angular/.editorconfig +0 -0
- data/templates/tool_angular/.gitignore +0 -0
- data/templates/tool_angular/.vscode/extensions.json +0 -0
- data/templates/tool_angular/.vscode/launch.json +0 -0
- data/templates/tool_angular/.vscode/tasks.json +0 -0
- data/templates/tool_angular/angular.json +0 -0
- data/templates/tool_angular/extra-webpack.config.js +0 -0
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_angular/src/app/app-routing.module.ts +0 -0
- data/templates/tool_angular/src/app/app.component.html +0 -0
- data/templates/tool_angular/src/app/app.component.scss +0 -0
- data/templates/tool_angular/src/app/app.component.spec.ts +0 -0
- data/templates/tool_angular/src/app/app.component.ts +0 -0
- data/templates/tool_angular/src/app/app.module.ts +0 -0
- data/templates/tool_angular/src/app/custom-overlay-container.ts +0 -0
- data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +0 -0
- data/templates/tool_angular/src/app/openc3-api.d.ts +0 -0
- data/templates/tool_angular/src/assets/.gitkeep +0 -0
- data/templates/tool_angular/src/environments/environment.prod.ts +0 -0
- data/templates/tool_angular/src/environments/environment.ts +0 -0
- data/templates/tool_angular/src/favicon.ico +0 -0
- data/templates/tool_angular/src/index.html +0 -0
- data/templates/tool_angular/src/main.single-spa.ts +0 -0
- data/templates/tool_angular/src/single-spa/asset-url.ts +0 -0
- data/templates/tool_angular/src/single-spa/single-spa-props.ts +0 -0
- data/templates/tool_angular/src/styles.scss +0 -0
- data/templates/tool_angular/tsconfig.app.json +0 -0
- data/templates/tool_angular/tsconfig.json +0 -0
- data/templates/tool_angular/tsconfig.spec.json +0 -0
- data/templates/tool_react/.eslintrc +0 -0
- data/templates/tool_react/.gitignore +0 -0
- data/templates/tool_react/.prettierignore +0 -0
- data/templates/tool_react/babel.config.json +0 -0
- data/templates/tool_react/jest.config.js +0 -0
- data/templates/tool_react/package.json +1 -1
- data/templates/tool_react/src/openc3-tool_name.js +0 -0
- data/templates/tool_react/src/root.component.js +0 -0
- data/templates/tool_react/src/root.component.test.js +0 -0
- data/templates/tool_react/webpack.config.js +0 -0
- data/templates/tool_svelte/.gitignore +0 -0
- data/templates/tool_svelte/.prettierignore +0 -0
- data/templates/tool_svelte/.prettierrc.js +0 -0
- data/templates/tool_svelte/babel.config.js +0 -0
- data/templates/tool_svelte/build/smui.css +0 -0
- data/templates/tool_svelte/jest.config.js +0 -0
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_svelte/rollup.config.js +0 -0
- data/templates/tool_svelte/src/App.svelte +0 -0
- data/templates/tool_svelte/src/App.test.js +0 -0
- data/templates/tool_svelte/src/theme/_smui-theme.scss +0 -0
- data/templates/tool_svelte/src/tool_name.js +0 -0
- data/templates/tool_vue/.env.standalone +0 -0
- data/templates/tool_vue/.gitignore +0 -0
- data/templates/tool_vue/.prettierrc.cjs +0 -0
- data/templates/tool_vue/eslint.config.mjs +0 -0
- data/templates/tool_vue/jsconfig.json +0 -0
- data/templates/tool_vue/package.json +3 -3
- data/templates/tool_vue/src/App.vue +0 -0
- data/templates/tool_vue/src/main.js +0 -0
- data/templates/tool_vue/src/router.js +0 -0
- data/templates/tool_vue/src/tools/tool_name/tool_name.vue +0 -0
- data/templates/tool_vue/vite.config.js +1 -1
- data/templates/widget/.prettierrc.cjs +0 -0
- data/templates/widget/LICENSE.md +0 -0
- data/templates/widget/Rakefile +0 -0
- data/templates/widget/package.json +2 -2
- data/templates/widget/src/Widget.vue +0 -0
- data/templates/widget/vite.config.js +0 -0
- metadata +40 -11
- data/templates/tool_vue/.nycrc +0 -3
- data/templates/widget/.nycrc +0 -3
|
@@ -28,6 +28,7 @@ require 'openc3/utilities/script'
|
|
|
28
28
|
require 'openc3/utilities/store'
|
|
29
29
|
require 'openc3/utilities/store_queued'
|
|
30
30
|
require 'openc3/utilities/bucket_require'
|
|
31
|
+
require 'openc3/utilities/python_venv'
|
|
31
32
|
require 'openc3/models/offline_access_model'
|
|
32
33
|
require 'openc3/models/environment_model'
|
|
33
34
|
require 'openc3/models/script_engine_model'
|
|
@@ -36,7 +37,7 @@ require 'fileutils'
|
|
|
36
37
|
|
|
37
38
|
if not defined? RAILS_ROOT
|
|
38
39
|
if ENV['RAILS_ROOT']
|
|
39
|
-
RAILS_ROOT = ENV
|
|
40
|
+
RAILS_ROOT = ENV.fetch('RAILS_ROOT')
|
|
40
41
|
elsif defined? Rails
|
|
41
42
|
RAILS_ROOT = Rails.root
|
|
42
43
|
else
|
|
@@ -432,11 +433,11 @@ class RunningScript
|
|
|
432
433
|
self.class.message_log
|
|
433
434
|
end
|
|
434
435
|
|
|
435
|
-
def self.spawn(scope, name, suite_runner = nil, disconnect = false, environment = nil, user_full_name = nil, username = nil, line_no = nil, end_line_no = nil)
|
|
436
|
+
def self.spawn(scope, name, suite_runner = nil, disconnect = false, environment = nil, user_full_name = nil, username = nil, line_no = nil, end_line_no = nil, python_venv = nil)
|
|
436
437
|
extension = File.extname(name).to_s.downcase
|
|
437
438
|
script_engine = nil
|
|
438
439
|
if extension == '.py'
|
|
439
|
-
process_name = ENV
|
|
440
|
+
process_name = ENV.fetch('OPENC3_PYTHON_BIN', '/openc3/python/.venv/bin/python')
|
|
440
441
|
runner_path = File.join(RAILS_ROOT, 'scripts', 'run_script.py')
|
|
441
442
|
elsif extension == '.rb'
|
|
442
443
|
process_name = 'ruby'
|
|
@@ -449,7 +450,7 @@ class RunningScript
|
|
|
449
450
|
if script_engine_model
|
|
450
451
|
script_engine = script_engine_model.filename
|
|
451
452
|
if File.extname(script_engine).to_s.downcase == '.py'
|
|
452
|
-
process_name = ENV
|
|
453
|
+
process_name = ENV.fetch('OPENC3_PYTHON_BIN', '/openc3/python/.venv/bin/python')
|
|
453
454
|
runner_path = File.join(RAILS_ROOT, 'scripts', 'run_script.py')
|
|
454
455
|
else
|
|
455
456
|
process_name = 'ruby'
|
|
@@ -468,103 +469,126 @@ class RunningScript
|
|
|
468
469
|
user_full_name ||= 'Anonymous'
|
|
469
470
|
start_time = Time.now.utc.iso8601
|
|
470
471
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
status_environment[env['key']] = env['value']
|
|
487
|
-
end
|
|
488
|
-
# Load the script specific ENV vars set by the GUI
|
|
489
|
-
# These can override the previously defined global env vars
|
|
490
|
-
if environment
|
|
491
|
-
environment.each do |env|
|
|
472
|
+
begin
|
|
473
|
+
process = ChildProcess.build(process_name, runner_path.to_s, running_script_id.to_s, scope)
|
|
474
|
+
process.io.inherit! # Helps with debugging
|
|
475
|
+
script_cwd = File.join(RAILS_ROOT, 'tmp', "script_#{running_script_id}")
|
|
476
|
+
FileUtils.mkdir_p(script_cwd)
|
|
477
|
+
process.cwd = script_cwd
|
|
478
|
+
|
|
479
|
+
# Check for offline access token
|
|
480
|
+
model = nil
|
|
481
|
+
model = OpenC3::OfflineAccessModel.get_model(name: username, scope: scope) if username != 'Anonymous'
|
|
482
|
+
|
|
483
|
+
# Load the global environment variables
|
|
484
|
+
status_environment = {}
|
|
485
|
+
values = OpenC3::EnvironmentModel.all(scope: scope).values
|
|
486
|
+
values.each do |env|
|
|
492
487
|
process.environment[env['key']] = env['value']
|
|
493
488
|
status_environment[env['key']] = env['value']
|
|
494
489
|
end
|
|
495
|
-
|
|
490
|
+
# Load the script specific ENV vars set by the GUI
|
|
491
|
+
# These can override the previously defined global env vars
|
|
492
|
+
if environment
|
|
493
|
+
environment.each do |env|
|
|
494
|
+
process.environment[env['key']] = env['value']
|
|
495
|
+
status_environment[env['key']] = env['value']
|
|
496
|
+
end
|
|
497
|
+
end
|
|
496
498
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
499
|
+
script_status = OpenC3::ScriptStatusModel.new(
|
|
500
|
+
name: running_script_id.to_s, # Unique id for this script
|
|
501
|
+
state: 'spawning', # State will be spawning until the script is running
|
|
502
|
+
shard: 0, # Future enhancement of script runner shards
|
|
503
|
+
filename: name, # Initial filename never changes
|
|
504
|
+
current_filename: name, # Current filename updates while we are running
|
|
505
|
+
line_no: 0, # 0 means not running yet
|
|
506
|
+
start_line_no: line_no || 1, # Line number to start running the script
|
|
507
|
+
end_line_no: end_line_no || nil, # Line number to stop running the script
|
|
508
|
+
username: username, # username of the person who started the script
|
|
509
|
+
user_full_name: user_full_name, # full name of the person who started the script
|
|
510
|
+
start_time: start_time, # Time the script started ISO format
|
|
511
|
+
end_time: nil, # Time the script ended ISO format
|
|
512
|
+
disconnect: disconnect, # Disconnect is set to true if the script is running in a disconnected mode
|
|
513
|
+
environment: status_environment, # hash of environment variables set for the script
|
|
514
|
+
suite_runner: suite_runner ? suite_runner : nil, # current suite information if any
|
|
515
|
+
errors: nil, # array of errors that occurred during the script run
|
|
516
|
+
pid: nil, # pid of the script process - set by the script itself when it starts
|
|
517
|
+
script_engine: script_engine, # script engine filename
|
|
518
|
+
updated_at: nil, # Set by create/update
|
|
519
|
+
scope: scope # Scope of the script
|
|
520
|
+
)
|
|
521
|
+
script_status.create()
|
|
522
|
+
|
|
523
|
+
# Set proper secrets for running script
|
|
524
|
+
process.environment['SECRET_KEY_BASE'] = nil
|
|
525
|
+
process.environment['OPENC3_REDIS_USERNAME'] = ENV.fetch('OPENC3_SR_REDIS_USERNAME', nil)
|
|
526
|
+
process.environment['OPENC3_REDIS_PASSWORD'] = ENV.fetch('OPENC3_SR_REDIS_PASSWORD', nil)
|
|
527
|
+
process.environment['OPENC3_BUCKET_USERNAME'] = ENV.fetch('OPENC3_SR_BUCKET_USERNAME', nil)
|
|
528
|
+
process.environment['OPENC3_BUCKET_PASSWORD'] = ENV.fetch('OPENC3_SR_BUCKET_PASSWORD', nil)
|
|
529
|
+
process.environment['OPENC3_SR_REDIS_USERNAME'] = nil
|
|
530
|
+
process.environment['OPENC3_SR_REDIS_PASSWORD'] = nil
|
|
531
|
+
process.environment['OPENC3_SR_BUCKET_USERNAME'] = nil
|
|
532
|
+
process.environment['OPENC3_SR_BUCKET_PASSWORD'] = nil
|
|
533
|
+
process.environment['OPENC3_API_CLIENT'] = ENV.fetch('OPENC3_API_CLIENT', nil)
|
|
534
|
+
if model and model.offline_access_token
|
|
535
|
+
auth = OpenC3::OpenC3KeycloakAuthentication.new(ENV.fetch('OPENC3_KEYCLOAK_URL', nil))
|
|
536
|
+
valid_token = auth.get_token_from_refresh_token(model.offline_access_token)
|
|
537
|
+
if valid_token
|
|
538
|
+
process.environment['OPENC3_API_TOKEN'] = model.offline_access_token
|
|
539
|
+
else
|
|
540
|
+
model.offline_access_token = nil
|
|
541
|
+
model.update
|
|
542
|
+
raise "offline_access token invalid for script"
|
|
543
|
+
end
|
|
537
544
|
else
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
545
|
+
process.environment['OPENC3_API_USER'] = ENV.fetch('OPENC3_API_USER', nil)
|
|
546
|
+
if ENV['OPENC3_SERVICE_PASSWORD']
|
|
547
|
+
process.environment['OPENC3_API_PASSWORD'] = ENV.fetch('OPENC3_SERVICE_PASSWORD')
|
|
548
|
+
else
|
|
549
|
+
raise "No authentication available for script"
|
|
550
|
+
end
|
|
541
551
|
end
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
process.environment
|
|
546
|
-
|
|
547
|
-
|
|
552
|
+
process.environment['GEM_HOME'] = ENV.fetch('GEM_HOME', nil)
|
|
553
|
+
|
|
554
|
+
python_venv_dir = OpenC3::PythonVenv.configure_for_script(
|
|
555
|
+
process.environment, name: name, scope: scope, python_venv: python_venv
|
|
556
|
+
)
|
|
557
|
+
unless python_venv_dir
|
|
558
|
+
system_venv = File.dirname(ENV.fetch('OPENC3_PYTHON_BIN', '/openc3/python/.venv/bin/python')).chomp('/bin')
|
|
559
|
+
process.environment['VIRTUAL_ENV'] = system_venv
|
|
560
|
+
process.environment['PYTHONUSERBASE'] = ENV.fetch('PYTHONUSERBASE', OpenC3::PythonVenv::DEFAULT_PYTHONUSERBASE)
|
|
561
|
+
# Deliberately nil when PYTHONPATH is unset rather than defaulting to
|
|
562
|
+
# something like '.', which would put the script's own working directory
|
|
563
|
+
# on the import path and let a local file shadow a real module.
|
|
564
|
+
process.environment['PYTHONPATH'] = ENV.fetch('PYTHONPATH', nil)
|
|
548
565
|
end
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
# Spawned process should not be controlled by same Bundler constraints as spawning process
|
|
556
|
-
ENV.each do |key, _value|
|
|
557
|
-
if key =~ /^BUNDLE/
|
|
558
|
-
process.environment[key] = nil
|
|
566
|
+
|
|
567
|
+
# Spawned process should not be controlled by same Bundler constraints as spawning process
|
|
568
|
+
ENV.each do |key, _value|
|
|
569
|
+
if key =~ /^BUNDLE/
|
|
570
|
+
process.environment[key] = nil
|
|
571
|
+
end
|
|
559
572
|
end
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
process.environment['RAILS_ROOT'] = RAILS_ROOT
|
|
573
|
+
process.environment['RUBYOPT'] = nil # Removes loading bundler setup
|
|
574
|
+
process.environment['OPENC3_SCOPE'] = scope
|
|
575
|
+
process.environment['RAILS_ROOT'] = RAILS_ROOT
|
|
564
576
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
577
|
+
process.detach = true
|
|
578
|
+
process.start
|
|
579
|
+
running_script_id
|
|
580
|
+
rescue => e
|
|
581
|
+
begin
|
|
582
|
+
# Clean up the orphaned script status record so the script
|
|
583
|
+
# does not remain stuck in 'spawning' state forever.
|
|
584
|
+
# Guard against nil in case the error occurred before these were assigned.
|
|
585
|
+
script_status.destroy() if script_status
|
|
586
|
+
FileUtils.rm_rf(script_cwd) if script_cwd
|
|
587
|
+
rescue => cleanup_error
|
|
588
|
+
OpenC3::Logger.error("Failed to cleanup after spawn failure: #{cleanup_error.message}")
|
|
589
|
+
end
|
|
590
|
+
raise e
|
|
591
|
+
end
|
|
568
592
|
end
|
|
569
593
|
|
|
570
594
|
def initialize(script_status)
|
|
@@ -601,7 +625,7 @@ class RunningScript
|
|
|
601
625
|
|
|
602
626
|
# Retrieve file
|
|
603
627
|
@body = ::Script.body(@script_status.scope, @script_status.filename)
|
|
604
|
-
raise "Script not found: #{@script_status.filename}" if @body.nil?
|
|
628
|
+
raise "Script not found during initialization: #{@script_status.filename}" if @body.nil?
|
|
605
629
|
breakpoints = @@breakpoints[@script_status.filename]&.filter { |_, present| present }&.map { |line_number, _| line_number - 1 } # -1 because frontend lines are 0-indexed
|
|
606
630
|
breakpoints ||= []
|
|
607
631
|
running_script_anycable_publish("running-script-channel:#{@script_status.id}", { type: :file, filename: @script_status.filename, scope: @script_status.scope, text: @body.to_utf8, breakpoints: breakpoints })
|
|
@@ -1476,7 +1500,7 @@ class RunningScript
|
|
|
1476
1500
|
running_script_anycable_publish("running-script-channel:#{@script_status.id}", { type: :file, filename: filename, text: @body.to_utf8, breakpoints: breakpoints })
|
|
1477
1501
|
else
|
|
1478
1502
|
text = ::Script.body(@script_status.scope, filename)
|
|
1479
|
-
raise "Script not found: #{filename}" if text.nil?
|
|
1503
|
+
raise "Script not found during load/require: #{filename}" if text.nil?
|
|
1480
1504
|
@@file_cache[filename] = text
|
|
1481
1505
|
@body = text
|
|
1482
1506
|
running_script_anycable_publish("running-script-channel:#{@script_status.id}", { type: :file, filename: filename, text: @body.to_utf8, breakpoints: breakpoints })
|
|
@@ -1501,7 +1525,7 @@ class RunningScript
|
|
|
1501
1525
|
$stdout = OpenC3::Stdout.instance
|
|
1502
1526
|
$stderr = OpenC3::Stderr.instance
|
|
1503
1527
|
OpenC3::Logger.stdout = true
|
|
1504
|
-
OpenC3::Logger.level = OpenC3::Logger
|
|
1528
|
+
OpenC3::Logger.level = OpenC3::Logger.default_level
|
|
1505
1529
|
end
|
|
1506
1530
|
|
|
1507
1531
|
def output_thread
|
|
@@ -3,9 +3,9 @@ require 'aws-sdk-s3'
|
|
|
3
3
|
if ENV['OPENC3_CLOUD'] == 'local'
|
|
4
4
|
Aws.config.update(
|
|
5
5
|
s3: {
|
|
6
|
-
endpoint: ENV
|
|
7
|
-
access_key_id: ENV
|
|
8
|
-
secret_access_key: ENV
|
|
6
|
+
endpoint: ENV.fetch('OPENC3_BUCKET_URL', nil) || (ENV['OPENC3_DEVEL'] ? 'http://127.0.0.1:9000' : 'http://openc3-buckets:9000'),
|
|
7
|
+
access_key_id: ENV.fetch('OPENC3_BUCKET_USERNAME', nil),
|
|
8
|
+
secret_access_key: ENV.fetch('OPENC3_BUCKET_PASSWORD', nil),
|
|
9
9
|
force_path_style: true,
|
|
10
10
|
region: 'us-east-1',
|
|
11
11
|
# Disable automatic checksum calculation for S3-compatible backends (versitygw)
|
|
@@ -20,9 +20,9 @@ if ENV['OPENC3_CLOUD'] == 'local'
|
|
|
20
20
|
else # AWS
|
|
21
21
|
Aws.config.update(
|
|
22
22
|
s3: {
|
|
23
|
-
endpoint: "https://s3.#{ENV
|
|
23
|
+
endpoint: "https://s3.#{ENV.fetch('AWS_REGION', nil)}.amazonaws.com",
|
|
24
24
|
force_path_style: true,
|
|
25
|
-
region: ENV
|
|
25
|
+
region: ENV.fetch('AWS_REGION', nil)
|
|
26
26
|
}
|
|
27
27
|
)
|
|
28
28
|
end
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
require 'tempfile'
|
|
19
19
|
require 'openc3/utilities/target_file'
|
|
20
|
+
require 'openc3/utilities/python_venv'
|
|
20
21
|
require 'openc3/utilities/running_script'
|
|
21
22
|
require 'openc3/script/suite'
|
|
22
23
|
require 'openc3/script/suite_runner'
|
|
@@ -25,34 +26,64 @@ require 'openc3/tools/test_runner/test'
|
|
|
25
26
|
OpenC3.require_file 'openc3/utilities/store'
|
|
26
27
|
|
|
27
28
|
class Script < OpenC3::TargetFile
|
|
29
|
+
# Script lifecycle states and the transitions allowed from each state
|
|
30
|
+
LIFECYCLE_STATES = %w(development review approved)
|
|
31
|
+
LIFECYCLE_TRANSITIONS = {
|
|
32
|
+
'development' => %w(review approved),
|
|
33
|
+
'review' => %w(development approved),
|
|
34
|
+
'approved' => %w(review development),
|
|
35
|
+
}
|
|
36
|
+
|
|
28
37
|
def self.all(scope, target = nil)
|
|
29
38
|
super(scope, nil, target: target) # No path matchers
|
|
30
39
|
end
|
|
31
40
|
|
|
32
41
|
def self.lock(scope, name, username)
|
|
33
|
-
|
|
34
|
-
OpenC3::Store.hset("#{scope}__script-locks", name, username)
|
|
42
|
+
OpenC3::Store.hset("#{scope}__script-locks", strip_modified(name), username)
|
|
35
43
|
end
|
|
36
44
|
|
|
37
45
|
def self.unlock(scope, name)
|
|
38
|
-
|
|
39
|
-
OpenC3::Store.hdel("#{scope}__script-locks", name)
|
|
46
|
+
OpenC3::Store.hdel("#{scope}__script-locks", strip_modified(name))
|
|
40
47
|
end
|
|
41
48
|
|
|
42
49
|
def self.locked?(scope, name)
|
|
43
|
-
|
|
44
|
-
locked_by = OpenC3::Store.hget("#{scope}__script-locks", name)
|
|
50
|
+
locked_by = OpenC3::Store.hget("#{scope}__script-locks", strip_modified(name))
|
|
45
51
|
locked_by ||= false
|
|
46
52
|
locked_by
|
|
47
53
|
end
|
|
48
54
|
|
|
49
55
|
def self.get_breakpoints(scope, name)
|
|
50
|
-
breakpoints = OpenC3::Store.hget("#{scope}__script-breakpoints", name
|
|
56
|
+
breakpoints = OpenC3::Store.hget("#{scope}__script-breakpoints", strip_modified(name))
|
|
51
57
|
return JSON.parse(breakpoints, allow_nan: true, create_additions: true) if breakpoints
|
|
52
58
|
[]
|
|
53
59
|
end
|
|
54
60
|
|
|
55
|
-
def self.
|
|
61
|
+
def self.temp_file?(name)
|
|
62
|
+
strip_modified(name).start_with?("#{TEMP_FOLDER}/")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.lifecycle_enabled?
|
|
66
|
+
defined?(::VersionStore) && ::VersionStore.enabled?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.lifecycle(scope, name)
|
|
70
|
+
return { 'state' => 'development', 'history' => [] } if temp_file?(name)
|
|
71
|
+
return { 'state' => 'development', 'history' => [] } unless lifecycle_enabled?
|
|
72
|
+
::VersionStore.lifecycle(scope: scope, name: strip_modified(name))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# current: the caller-known current state; pass it to avoid a redundant git
|
|
76
|
+
# read when the controller has already fetched it for transition validation.
|
|
77
|
+
def self.set_lifecycle(scope, name, state, username, comment, current: nil)
|
|
78
|
+
raise "Cannot set lifecycle on temporary files" if temp_file?(name)
|
|
79
|
+
raise "Script lifecycle requires the version history store" unless lifecycle_enabled?
|
|
80
|
+
name = strip_modified(name)
|
|
81
|
+
current ||= lifecycle(scope, name)['state']
|
|
82
|
+
::VersionStore.set_lifecycle(scope: scope, name: name, from: current, to: state,
|
|
83
|
+
username: username, comment: comment)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.process_suite(name, contents, new_process: true, username: nil, scope:, python_venv: nil)
|
|
56
87
|
python = false
|
|
57
88
|
python = true if File.extname(name) == '.py'
|
|
58
89
|
|
|
@@ -119,10 +150,19 @@ class Script < OpenC3::TargetFile
|
|
|
119
150
|
end
|
|
120
151
|
end
|
|
121
152
|
process.environment['GEM_HOME'] = ENV['GEM_HOME'] || '/gems'
|
|
122
|
-
process.environment['PYTHONUSERBASE'] = ENV['PYTHONUSERBASE'] ||
|
|
153
|
+
process.environment['PYTHONUSERBASE'] = ENV['PYTHONUSERBASE'] || OpenC3::PythonVenv::DEFAULT_PYTHONUSERBASE
|
|
123
154
|
# Preserve PYTHONPATH to ensure Python can find both UV venv and user packages
|
|
124
155
|
process.environment['PYTHONPATH'] = ENV['PYTHONPATH'] || '.'
|
|
125
156
|
|
|
157
|
+
# Suite analysis executes Python in a separate process before the script
|
|
158
|
+
# itself is started. Give that process the same plugin venv visibility as
|
|
159
|
+
# RunningScript so imports used while defining a suite can be resolved.
|
|
160
|
+
if python
|
|
161
|
+
OpenC3::PythonVenv.configure_for_script(
|
|
162
|
+
process.environment, name: name, scope: scope, python_venv: python_venv
|
|
163
|
+
)
|
|
164
|
+
end
|
|
165
|
+
|
|
126
166
|
# Spawned process should not be controlled by same Bundler constraints as spawning process
|
|
127
167
|
ENV.each do |key, _value|
|
|
128
168
|
if key =~ /^BUNDLE/
|
|
@@ -189,7 +229,6 @@ class Script < OpenC3::TargetFile
|
|
|
189
229
|
def self.delete_temp(scope)
|
|
190
230
|
files = super(scope)
|
|
191
231
|
files.each do |name|
|
|
192
|
-
# Remove any breakpoints associated with the temp files
|
|
193
232
|
OpenC3::Store.hdel("#{scope}__script-breakpoints", "#{TEMP_FOLDER}/#{File.basename(name)}")
|
|
194
233
|
end
|
|
195
234
|
end
|
|
@@ -208,13 +247,14 @@ class Script < OpenC3::TargetFile
|
|
|
208
247
|
user_full_name = nil,
|
|
209
248
|
username = nil,
|
|
210
249
|
line_no = nil,
|
|
211
|
-
end_line_no = nil
|
|
250
|
+
end_line_no = nil,
|
|
251
|
+
python_venv = nil
|
|
212
252
|
)
|
|
213
253
|
# Verify the script exists before spawning a run. Without this check a run
|
|
214
254
|
# is started and the missing file only surfaces as a runtime error inside
|
|
215
255
|
# the spawned process. Returning nil lets the caller return a 404.
|
|
216
256
|
return nil unless Script.body(scope, name)
|
|
217
|
-
RunningScript.spawn(scope, name, suite_runner, disconnect, environment, user_full_name, username, line_no, end_line_no)
|
|
257
|
+
RunningScript.spawn(scope, name, suite_runner, disconnect, environment, user_full_name, username, line_no, end_line_no, python_venv)
|
|
218
258
|
end
|
|
219
259
|
|
|
220
260
|
def self.instrumented(filename, text)
|
|
@@ -15,13 +15,58 @@ ENV['OPENC3_SECRET_BACKEND'] ||= 'redis'
|
|
|
15
15
|
|
|
16
16
|
module OpenC3
|
|
17
17
|
class Secrets
|
|
18
|
+
# Default base directory that FILE type secret paths must reside under.
|
|
19
|
+
# FILE type secrets are written by the operator (or mounted by Kubernetes)
|
|
20
|
+
# and then read back by the microservice, so the path is a destination we
|
|
21
|
+
# control, not an arbitrary file on the host.
|
|
22
|
+
DEFAULT_SECRET_FILE_DIR = '/tmp'
|
|
23
|
+
|
|
18
24
|
def initialize
|
|
19
25
|
@local_secrets = {}
|
|
20
26
|
end
|
|
21
27
|
|
|
28
|
+
# Base directory that FILE type secret paths must reside under
|
|
29
|
+
def self.secret_file_dir
|
|
30
|
+
dir = ENV.fetch('OPENC3_SECRET_FILE_DIR', nil)
|
|
31
|
+
dir = DEFAULT_SECRET_FILE_DIR if dir.nil? or dir.empty?
|
|
32
|
+
dir
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Validates a FILE type secret path. The path must expand to a location
|
|
36
|
+
# strictly inside Secrets.secret_file_dir. This prevents a plugin
|
|
37
|
+
# configuration such as 'SECRET FILE KEY /root/.ssh/id_rsa' or
|
|
38
|
+
# 'SECRET FILE KEY /tmp/../etc/shadow' from reading or overwriting arbitrary
|
|
39
|
+
# files as the OpenC3 process user.
|
|
40
|
+
#
|
|
41
|
+
# @param path [String] Path from a SECRET FILE definition
|
|
42
|
+
# @return [String] The validated absolute path
|
|
43
|
+
def self.validate_file_path(path)
|
|
44
|
+
raise ArgumentError, "Secret file path must be a String but is a #{path.class}" unless path.is_a?(String)
|
|
45
|
+
raise ArgumentError, "Secret file path must not be blank" if path.strip.empty?
|
|
46
|
+
raise ArgumentError, "Secret file path must not contain a null byte" if path.include?("\x00")
|
|
47
|
+
|
|
48
|
+
# expand_path collapses '..' and '.', expands '~', and makes a relative path
|
|
49
|
+
# absolute, so the comparison below can't be walked out of. This is
|
|
50
|
+
# deliberately a purely lexical check: it does not touch the filesystem, so
|
|
51
|
+
# a path validates identically at plugin install time (cmd-tlm-api) and at
|
|
52
|
+
# write time (openc3-operator), which are separate containers. Symlinks are
|
|
53
|
+
# rejected by the operator when it writes the secret.
|
|
54
|
+
base = File.expand_path(secret_file_dir)
|
|
55
|
+
absolute = File.expand_path(path)
|
|
56
|
+
unless absolute.start_with?(base + File::SEPARATOR)
|
|
57
|
+
raise ArgumentError, "Secret file path '#{path}' must be under '#{base}'"
|
|
58
|
+
end
|
|
59
|
+
absolute
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @return true if path is inside base, or is base itself
|
|
63
|
+
def self.path_contained?(base, path)
|
|
64
|
+
path == base or path.start_with?(base.end_with?(File::SEPARATOR) ? base : base + File::SEPARATOR)
|
|
65
|
+
end
|
|
66
|
+
|
|
22
67
|
def self.getClient
|
|
23
68
|
raise 'OPENC3_SECRET_BACKEND environment variable is required' unless ENV['OPENC3_SECRET_BACKEND']
|
|
24
|
-
secrets_class = ENV
|
|
69
|
+
secrets_class = ENV.fetch('OPENC3_SECRET_BACKEND').capitalize + 'Secrets'
|
|
25
70
|
klass = OpenC3.require_class('openc3/utilities/' + secrets_class.class_name_to_filename)
|
|
26
71
|
klass.new
|
|
27
72
|
end
|
|
@@ -50,9 +95,9 @@ module OpenC3
|
|
|
50
95
|
type, key, data, _secret_store = secret
|
|
51
96
|
case type
|
|
52
97
|
when 'ENV'
|
|
53
|
-
@local_secrets[key] = ENV
|
|
98
|
+
@local_secrets[key] = ENV.fetch(data, nil)
|
|
54
99
|
when 'FILE'
|
|
55
|
-
@local_secrets[key] = File.read(data)
|
|
100
|
+
@local_secrets[key] = File.read(Secrets.validate_file_path(data))
|
|
56
101
|
else
|
|
57
102
|
raise "Unknown secret type: #{type}"
|
|
58
103
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -116,8 +116,8 @@ module OpenC3
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def initialize(pool_size = 10, db_shard: 0)
|
|
119
|
-
@redis_username = ENV
|
|
120
|
-
@redis_key = ENV
|
|
119
|
+
@redis_username = ENV.fetch('OPENC3_REDIS_USERNAME', nil)
|
|
120
|
+
@redis_key = ENV.fetch('OPENC3_REDIS_PASSWORD', nil)
|
|
121
121
|
hostname = ENV['OPENC3_REDIS_HOSTNAME'].to_s.gsub("SHARDNUM", db_shard.to_s)
|
|
122
122
|
@redis_url = "redis://#{hostname}:#{ENV.fetch('OPENC3_REDIS_PORT', 6379)}"
|
|
123
123
|
@redis_pool = StoreConnectionPool.new(size: pool_size) { build_redis() }
|
|
File without changes
|
|
@@ -21,6 +21,16 @@ module OpenC3
|
|
|
21
21
|
# Matches ScriptRunner.vue const TEMP_FOLDER
|
|
22
22
|
TEMP_FOLDER = '__TEMP__'
|
|
23
23
|
|
|
24
|
+
# self.all appends '*' to a name to mark it as modified on the server. The
|
|
25
|
+
# marker is display-only, so every path in and out of the bucket strips it.
|
|
26
|
+
#
|
|
27
|
+
# Strip only '*' at the end of a file name. '*' is a legal S3 object key character
|
|
28
|
+
# and is allowed by FileOpenSaveDialog's filename charset, so files named that
|
|
29
|
+
# way exist in the field and have to stay addressable.
|
|
30
|
+
def self.strip_modified(name)
|
|
31
|
+
name.sub(/\*$/, '')
|
|
32
|
+
end
|
|
33
|
+
|
|
24
34
|
def self.all(scope, path_matchers, target: nil)
|
|
25
35
|
target = target.upcase if target
|
|
26
36
|
|
|
@@ -89,7 +99,7 @@ module OpenC3
|
|
|
89
99
|
end
|
|
90
100
|
|
|
91
101
|
def self.body(scope, name)
|
|
92
|
-
name = name
|
|
102
|
+
name = strip_modified(name) # Remove '*' that indicates modified
|
|
93
103
|
# First try opening a potentially modified version by looking for the modified target
|
|
94
104
|
if ENV['OPENC3_LOCAL_MODE']
|
|
95
105
|
local_file = OpenC3::LocalMode.open_local_file(name, scope: scope)
|
|
@@ -122,6 +132,10 @@ module OpenC3
|
|
|
122
132
|
|
|
123
133
|
def self.create(scope, name, text, content_type: 'text/plain')
|
|
124
134
|
return false unless text
|
|
135
|
+
# A trailing '*' here is the display-only modified marker leaking in from a
|
|
136
|
+
# file listing, not a name any caller means to write. Remove it to avoid
|
|
137
|
+
# creating a file with a '*' in the name.
|
|
138
|
+
name = strip_modified(name)
|
|
125
139
|
if ENV['OPENC3_LOCAL_MODE']
|
|
126
140
|
OpenC3::LocalMode.put_target_file("#{scope}/targets_modified/#{name}", text, scope: scope)
|
|
127
141
|
end
|
|
@@ -146,6 +160,9 @@ module OpenC3
|
|
|
146
160
|
end
|
|
147
161
|
|
|
148
162
|
def self.destroy(scope, name)
|
|
163
|
+
# Match body/create so deleting a name taken straight from a listing
|
|
164
|
+
# removes the file the user actually picked
|
|
165
|
+
name = strip_modified(name)
|
|
149
166
|
if ENV['OPENC3_LOCAL_MODE']
|
|
150
167
|
OpenC3::LocalMode.delete_local("#{scope}/targets_modified/#{name}")
|
|
151
168
|
end
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/utilities/zip.rb
CHANGED
|
File without changes
|
data/lib/openc3/utilities.rb
CHANGED
|
File without changes
|
data/lib/openc3/version.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
2
|
|
|
3
|
-
OPENC3_VERSION = '7.
|
|
3
|
+
OPENC3_VERSION = '7.4.0'
|
|
4
4
|
module OpenC3
|
|
5
5
|
module Version
|
|
6
6
|
MAJOR = '7'
|
|
7
|
-
MINOR = '
|
|
8
|
-
PATCH = '
|
|
7
|
+
MINOR = '4'
|
|
8
|
+
PATCH = '0'
|
|
9
9
|
OTHER = ''
|
|
10
|
-
BUILD = '
|
|
10
|
+
BUILD = 'ed0cb44ca3c661eaf2babb77664d0063c955c68c'
|
|
11
11
|
end
|
|
12
|
-
VERSION = '7.
|
|
13
|
-
GEM_VERSION = '7.
|
|
12
|
+
VERSION = '7.4.0'
|
|
13
|
+
GEM_VERSION = '7.4.0'
|
|
14
14
|
end
|
data/lib/openc3/win32/excel.rb
CHANGED
|
File without changes
|
data/lib/openc3/win32/win32.rb
CHANGED
|
File without changes
|
|
File without changes
|
data/lib/openc3.rb
CHANGED
|
@@ -30,9 +30,9 @@ $VERBOSE = saved_verbose
|
|
|
30
30
|
# Add OpenC3 bin folder to PATH
|
|
31
31
|
require 'openc3/core_ext/kernel'
|
|
32
32
|
if Kernel.is_windows?
|
|
33
|
-
ENV['PATH'] = File.join(File.dirname(__FILE__), '../bin') + ';' + ENV
|
|
33
|
+
ENV['PATH'] = File.join(File.dirname(__FILE__), '../bin') + ';' + ENV.fetch('PATH')
|
|
34
34
|
else
|
|
35
|
-
ENV['PATH'] = File.join(File.dirname(__FILE__), '../bin') + ':' + ENV
|
|
35
|
+
ENV['PATH'] = File.join(File.dirname(__FILE__), '../bin') + ':' + ENV.fetch('PATH')
|
|
36
36
|
end
|
|
37
37
|
require 'openc3/ext/platform' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
|
|
38
38
|
require 'openc3/version'
|
data/tasks/gemfile_stats.rake
CHANGED
|
File without changes
|
data/tasks/spec.rake
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|