amd-node-scraper 1.1.2__tar.gz → 1.1.4__tar.gz
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.
- amd_node_scraper-1.1.4/.github/ISSUE_TEMPLATE/bug_report.yml +72 -0
- amd_node_scraper-1.1.4/.github/ISSUE_TEMPLATE/config.yml +8 -0
- amd_node_scraper-1.1.4/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
- amd_node_scraper-1.1.4/.github/pull_request_template.md +12 -0
- amd_node_scraper-1.1.4/.github/scripts/plugin_convention_warnings.py +261 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.github/workflows/update-plugin-docs.yml +3 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.pre-commit-config.yaml +9 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/CONTRIBUTING.md +11 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/PKG-INFO +79 -19
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/README.md +78 -18
- amd_node_scraper-1.1.4/SECURITY.md +34 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/amd_node_scraper.egg-info/PKG-INFO +79 -19
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/amd_node_scraper.egg-info/SOURCES.txt +30 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/PLUGIN_DOC.md +269 -193
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/generate_plugin_doc_bundle.py +196 -37
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/base/regexanalyzer.py +25 -7
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/__init__.py +20 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/cli.py +169 -59
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/compare_runs.py +7 -3
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/dynamicparserbuilder.py +108 -11
- amd_node_scraper-1.1.4/nodescraper/cli/embed.py +86 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/helper.py +45 -21
- amd_node_scraper-1.1.4/nodescraper/cli/host_cli_embed.py +84 -0
- amd_node_scraper-1.1.4/nodescraper/cli/invocation.py +117 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/redfish/redfish_connection.py +12 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/datacollectortask.py +24 -3
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/dataplugin.py +23 -6
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/event.py +22 -1
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/systeminfo.py +2 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/taskresult.py +15 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/timerangeargs.py +10 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/pluginexecutor.py +25 -14
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/pluginregistry.py +55 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/amdsmi/amdsmi_analyzer.py +44 -55
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/amdsmi/amdsmi_collector.py +8 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/amdsmi/amdsmidata.py +176 -0
- amd_node_scraper-1.1.4/nodescraper/plugins/inband/amdsmi/analyzer_args.py +117 -0
- {amd_node_scraper-1.1.2/nodescraper/plugins/inband/nic → amd_node_scraper-1.1.4/nodescraper/plugins/inband/amdsmi}/collector_args.py +13 -6
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/bios/analyzer_args.py +8 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/analyzer_args.py +16 -4
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/device_enumeration/analyzer_args.py +13 -4
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dimm/collector_args.py +6 -1
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dkms/analyzer_args.py +12 -3
- amd_node_scraper-1.1.4/nodescraper/plugins/inband/dmesg/analyzer_args.py +64 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/collector_args.py +13 -3
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/dmesg_analyzer.py +110 -10
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/analyzer_args.py +10 -8
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/collector_args.py +6 -1
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel/analyzer_args.py +12 -3
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel_module/analyzer_args.py +10 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/memory/analyzer_args.py +10 -2
- {amd_node_scraper-1.1.2/nodescraper/plugins/inband/dmesg → amd_node_scraper-1.1.4/nodescraper/plugins/inband/network}/analyzer_args.py +11 -8
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/network/collector_args.py +10 -2
- amd_node_scraper-1.1.4/nodescraper/plugins/inband/network/network_analyzer.py +123 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/network/network_plugin.py +7 -1
- amd_node_scraper-1.1.4/nodescraper/plugins/inband/nic/collector_args.py +47 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nic/nic_collector.py +170 -167
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/os/analyzer_args.py +8 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/package/analyzer_args.py +16 -5
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/pcie/analyzer_args.py +20 -7
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/analyzer_args.py +10 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/collector_args.py +7 -1
- amd_node_scraper-1.1.4/nodescraper/plugins/inband/rdma/rdma_analyzer.py +96 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rdma/rdma_collector.py +65 -4
- amd_node_scraper-1.1.4/nodescraper/plugins/inband/rdma/rdmadata.py +439 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rocm/analyzer_args.py +12 -4
- {amd_node_scraper-1.1.2/nodescraper/plugins/inband/amdsmi → amd_node_scraper-1.1.4/nodescraper/plugins/inband/rocm}/collector_args.py +7 -4
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/analyzer_args.py +20 -5
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/collector_args.py +5 -1
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/analyzer_args.py +14 -5
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/collector_args.py +9 -3
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sysctl/analyzer_args.py +35 -11
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_endpoint/collector_args.py +27 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_endpoint/endpoint_analyzer.py +2 -2
- amd_node_scraper-1.1.4/nodescraper/plugins/ooband/redfish_endpoint/endpoint_collector.py +258 -0
- amd_node_scraper-1.1.2/nodescraper/plugins/inband/rocm/collector_args.py → amd_node_scraper-1.1.4/nodescraper/plugins/regex_search/__init__.py +28 -32
- amd_node_scraper-1.1.4/nodescraper/plugins/regex_search/analyzer_args.py +50 -0
- amd_node_scraper-1.1.4/nodescraper/plugins/regex_search/regex_search_analyzer.py +102 -0
- amd_node_scraper-1.1.4/nodescraper/plugins/regex_search/regex_search_data.py +107 -0
- amd_node_scraper-1.1.4/nodescraper/plugins/regex_search/regex_search_plugin.py +76 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/typeutils.py +4 -1
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/conftest.py +17 -1
- amd_node_scraper-1.1.4/test/functional/fixtures/redfish_endpoint_plugin_config_full_args.json +26 -0
- amd_node_scraper-1.1.4/test/functional/fixtures/regex_search_multi_logs/app_error.log +3 -0
- amd_node_scraper-1.1.4/test/functional/fixtures/regex_search_multi_logs/no_errors.log +2 -0
- amd_node_scraper-1.1.4/test/functional/fixtures/regex_search_multi_logs/storage_warn.log +3 -0
- amd_node_scraper-1.1.4/test/functional/fixtures/regex_search_sample.log +4 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_cli_describe.py +28 -3
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_cli_help.py +32 -0
- amd_node_scraper-1.1.4/test/functional/test_cli_no_console_log.py +50 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_fabrics_plugin.py +3 -5
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_network_plugin.py +4 -7
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_nic_plugin.py +3 -5
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_pcie_plugin.py +5 -9
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_plugin_configs.py +20 -28
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_rdma_plugin.py +3 -5
- amd_node_scraper-1.1.4/test/functional/test_redfish_endpoint_plugin.py +390 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_reference_config_workflow.py +2 -2
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_sys_settings_plugin.py +3 -3
- amd_node_scraper-1.1.4/test/unit/cli/test_build_global_argument_parser.py +18 -0
- amd_node_scraper-1.1.4/test/unit/cli/test_cli_embed_api.py +63 -0
- amd_node_scraper-1.1.4/test/unit/cli/test_cli_no_console_stdout.py +152 -0
- amd_node_scraper-1.1.4/test/unit/cli/test_host_cli_embed.py +71 -0
- amd_node_scraper-1.1.4/test/unit/cli/test_plugin_configs_cli.py +37 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_cli.py +19 -0
- amd_node_scraper-1.1.4/test/unit/framework/test_connection_manager_entrypoints.py +67 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_datacollector.py +27 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_plugin_executor.py +17 -0
- amd_node_scraper-1.1.4/test/unit/plugin/fixtures/rdma_statistic_example_data.json +598 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_amdsmi_analyzer.py +48 -9
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_dmesg_analyzer.py +238 -0
- amd_node_scraper-1.1.4/test/unit/plugin/test_network_analyzer.py +314 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_rdma_analyzer.py +110 -77
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_rdma_collector.py +126 -4
- amd_node_scraper-1.1.4/test/unit/plugin/test_redfish_endpoint_collector.py +388 -0
- amd_node_scraper-1.1.4/test/unit/plugin/test_regex_search_analyzer.py +190 -0
- amd_node_scraper-1.1.2/nodescraper/plugins/inband/amdsmi/analyzer_args.py +0 -50
- amd_node_scraper-1.1.2/nodescraper/plugins/inband/rdma/rdma_analyzer.py +0 -186
- amd_node_scraper-1.1.2/nodescraper/plugins/inband/rdma/rdmadata.py +0 -104
- amd_node_scraper-1.1.2/nodescraper/plugins/ooband/redfish_endpoint/endpoint_collector.py +0 -86
- amd_node_scraper-1.1.2/test/functional/test_redfish_endpoint_plugin.py +0 -114
- amd_node_scraper-1.1.2/test/unit/plugin/fixtures/rdma_statistic_example_data.json +0 -826
- amd_node_scraper-1.1.2/test/unit/plugin/test_redfish_endpoint_collector.py +0 -145
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.github/CODEOWNERS +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.github/workflows/code_quality_checks.yml +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.github/workflows/functional-test.yml +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.github/workflows/release-trusted-publisher.yml +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.github/workflows/unit-test.yml +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.gitignore +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/.mypy.ini +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/EXTENDING.md +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/LICENSE +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/amd_node_scraper.egg-info/dependency_links.txt +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/amd_node_scraper.egg-info/entry_points.txt +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/amd_node_scraper.egg-info/requires.txt +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/amd_node_scraper.egg-info/top_level.txt +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/dev-setup.sh +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/README.md +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/ext_nodescraper_plugins/sample/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/ext_nodescraper_plugins/sample/sample_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/ext_nodescraper_plugins/sample/sample_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/ext_nodescraper_plugins/sample/sample_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/ext_nodescraper_plugins/sample/sample_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/docs/node-scraper-external/pyproject.toml +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/base/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/base/inbandcollectortask.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/base/inbanddataplugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/base/oobanddataplugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/base/redfishcollectortask.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/constants.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/cli/inputargtypes.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/configbuilder.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/configregistry.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/configs/node_status.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/inband/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/inband/inband.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/inband/inbandlocal.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/inband/inbandmanager.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/inband/inbandremote.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/inband/sshparams.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/redfish/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/redfish/redfish_manager.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/redfish/redfish_oem_diag.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/redfish/redfish_params.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/connection/redfish/redfish_path.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/constants.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/eventcategory.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/eventpriority.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/executionstatus.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/osfamily.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/systeminteraction.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/systemlocation.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/enums/taskstate.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/generictypes.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/helpers/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/connectionmanager.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/dataanalyzertask.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/resultcollator.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/task.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/interfaces/taskresulthook.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/analyzerargs.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/collectorargs.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/connectionconfig.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/datamodel.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/datapluginresult.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/pluginconfig.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/models/pluginresult.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/amdsmi/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/amdsmi/amdsmi_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/amdsmi/cper.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/bios/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/bios/bios_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/bios/bios_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/bios/bios_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/bios/biosdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/cmdline_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/cmdline_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/cmdline_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/cmdlineconfig.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/cmdline/cmdlinedata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/device_enumeration/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/device_enumeration/device_enumeration_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/device_enumeration/device_enumeration_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/device_enumeration/device_enumeration_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/device_enumeration/deviceenumdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dimm/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dimm/dimm_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dimm/dimm_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dimm/dimmdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dkms/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dkms/dkms_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dkms/dkms_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dkms/dkms_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dkms/dkmsdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/dmesg_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/dmesg_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/dmesgdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/dmesg/run_compare.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/fabrics/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/fabrics/fabrics_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/fabrics/fabrics_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/fabrics/fabricsdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/journal_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/journal_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/journal_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/journal/journaldata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel/kernel_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel/kernel_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel/kernel_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel/kerneldata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel_module/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel_module/kernel_module_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel_module/kernel_module_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel_module/kernel_module_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/kernel_module/kernel_module_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/memory/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/memory/memory_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/memory/memory_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/memory/memory_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/memory/memorydata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/network/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/network/network_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/network/networkdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nic/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nic/analyzer_args.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nic/nic_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nic/nic_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nic/nic_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nvme/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nvme/nvme_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nvme/nvme_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/nvme/nvmedata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/os/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/os/os_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/os/os_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/os/os_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/os/osdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/package/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/package/package_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/package/package_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/package/package_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/package/packagedata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/pcie/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/pcie/pcie_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/pcie/pcie_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/pcie/pcie_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/pcie/pcie_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/process_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/process_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/process_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/process/processdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rdma/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rdma/rdma_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rocm/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rocm/rocm_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rocm/rocm_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rocm/rocm_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/rocm/rocmdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/storage_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/storage_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/storage_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/storage/storagedata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/sys_settings_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/sys_settings_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/sys_settings_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sys_settings/sys_settings_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sysctl/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sysctl/sysctl_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sysctl/sysctl_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sysctl/sysctl_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/sysctl/sysctldata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/syslog/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/syslog/syslog_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/syslog/syslog_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/syslog/syslogdata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/uptime/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/uptime/uptime_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/uptime/uptime_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/inband/uptime/uptimedata.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_endpoint/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_endpoint/analyzer_args.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_endpoint/endpoint_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_endpoint/endpoint_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/analyzer_args.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/collector_args.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/oem_diag_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/oem_diag_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/oem_diag_data.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/plugins/ooband/redfish_oem_diag/oem_diag_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/resultcollators/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/resultcollators/tablesummary.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/taskresulthooks/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/taskresulthooks/filesystemloghook.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/nodescraper/utils.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/pyproject.toml +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/pytest.ini +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/setup.cfg +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/setup.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/__init__.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/bios_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/cmdline_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/dimm_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/dkms_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/dmesg_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/dmesg_plugin_config_custom_regex.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/dmesg_sample.log +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/dmesg_sample_with_collapsing.log +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/fabrics_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/journal_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/kernel_module_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/kernel_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/memory_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/network_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/nic_plugin_config_full_analyzer_args.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/niccli_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/nvme_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/os_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/package_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/pcie_plugin_advanced_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/pcie_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/process_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/rdma_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/redfish_connection_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/redfish_endpoint_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/rocm_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/storage_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/sys_settings_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/sysctl_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/syslog_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/fixtures/uptime_plugin_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_plugin_registry.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/functional/test_run_plugins.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/conftest.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/connection/redfish/test_redfish_oem_diag.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/common/shared_utils.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/compare_runs_sysctl/run1/sysctl_plugin/sysctl_collector/result.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/compare_runs_sysctl/run1/sysctl_plugin/sysctl_collector/sysctldatamodel.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/compare_runs_sysctl/run2/sysctl_plugin/sysctl_collector/result.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/compare_runs_sysctl/run2/sysctl_plugin/sysctl_collector/sysctldatamodel.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/example.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/example_config.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/invalid.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/log_dir/collector/biosdatamodel.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/fixtures/log_dir/collector/result.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_analyzerargs.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_cli_helper.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_compare_runs.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_config_builder.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_config_registry.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_dataanalyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_dataplugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_file_artifact.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_regexanalyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/framework/test_type_utils.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/fixtures/package_commands.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/fixtures/rdma_link_example_data.json +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_amdsmi_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_analyzer_args_build_from_model.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_bios_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_bios_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_cmdline_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_cmdline_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_device_enumeration_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_device_enumeration_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_dimms_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_dkms_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_dkms_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_dmesg_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_fabrics_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_journal_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_kernel_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_kernel_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_kernel_module_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_kernel_module_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_memory_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_memory_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_network_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_niccli_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_nvme_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_os_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_os_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_package_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_package_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_process_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_process_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_redfish_endpoint_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_redfish_endpoint_plugin.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_redfish_oem_diag_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_redfish_oem_diag_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_rocm_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_rocm_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_storage_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_storage_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_sys_settings_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_sys_settings_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_sysctl_analyzer.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_sysctl_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_syslog_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/plugin/test_uptime_collector.py +0 -0
- {amd_node_scraper-1.1.2 → amd_node_scraper-1.1.4}/test/unit/test_version.py +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a reproducible problem with Node Scraper
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to report a bug. Please include enough detail to reproduce the issue.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: summary
|
|
12
|
+
attributes:
|
|
13
|
+
label: Summary
|
|
14
|
+
description: What happened and what did you expect to happen?
|
|
15
|
+
placeholder: Clear and concise description of the bug.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: steps
|
|
20
|
+
attributes:
|
|
21
|
+
label: Steps to reproduce
|
|
22
|
+
description: Minimal, concrete steps to reproduce the issue.
|
|
23
|
+
placeholder: |
|
|
24
|
+
1. ...
|
|
25
|
+
2. ...
|
|
26
|
+
3. ...
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: logs
|
|
31
|
+
attributes:
|
|
32
|
+
label: CLI output / logs
|
|
33
|
+
description: Paste relevant output (redact secrets/tokens/hosts as needed).
|
|
34
|
+
render: shell
|
|
35
|
+
validations:
|
|
36
|
+
required: false
|
|
37
|
+
- type: input
|
|
38
|
+
id: version
|
|
39
|
+
attributes:
|
|
40
|
+
label: Version
|
|
41
|
+
description: Output of `node-scraper --version` (or the git commit hash).
|
|
42
|
+
placeholder: "e.g. 0.6.1"
|
|
43
|
+
validations:
|
|
44
|
+
required: false
|
|
45
|
+
- type: dropdown
|
|
46
|
+
id: install_method
|
|
47
|
+
attributes:
|
|
48
|
+
label: Install method
|
|
49
|
+
options:
|
|
50
|
+
- PyPI (pip install amd-node-scraper)
|
|
51
|
+
- Editable install from source (pip install -e .)
|
|
52
|
+
- Other
|
|
53
|
+
validations:
|
|
54
|
+
required: false
|
|
55
|
+
- type: input
|
|
56
|
+
id: python
|
|
57
|
+
attributes:
|
|
58
|
+
label: Python version
|
|
59
|
+
placeholder: "e.g. 3.11.8"
|
|
60
|
+
validations:
|
|
61
|
+
required: false
|
|
62
|
+
- type: textarea
|
|
63
|
+
id: environment
|
|
64
|
+
attributes:
|
|
65
|
+
label: Environment
|
|
66
|
+
description: OS, target system type (LOCAL/REMOTE), and anything else relevant.
|
|
67
|
+
placeholder: |
|
|
68
|
+
OS:
|
|
69
|
+
Target:
|
|
70
|
+
Notes:
|
|
71
|
+
validations:
|
|
72
|
+
required: false
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Questions
|
|
4
|
+
url: https://github.com/amd/node-scraper/issues
|
|
5
|
+
about: If you're not sure it's a bug/feature request yet, start with an issue and add details.
|
|
6
|
+
- name: Security reports
|
|
7
|
+
url: https://github.com/amd/node-scraper/security/policy
|
|
8
|
+
about: Please report security issues privately (see SECURITY.md).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an enhancement or new capability
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for the suggestion. Please describe the problem you're trying to solve and what success looks like.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem / motivation
|
|
14
|
+
description: What problem are you trying to solve?
|
|
15
|
+
placeholder: "I want to..."
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: proposal
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed solution
|
|
22
|
+
description: What would you like Node Scraper to do?
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: alternatives
|
|
27
|
+
attributes:
|
|
28
|
+
label: Alternatives considered
|
|
29
|
+
description: What else have you tried or considered?
|
|
30
|
+
validations:
|
|
31
|
+
required: false
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: scope
|
|
34
|
+
attributes:
|
|
35
|
+
label: Scope / impact
|
|
36
|
+
description: What plugins/OSes/environments would this affect?
|
|
37
|
+
validations:
|
|
38
|
+
required: false
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
-
|
|
3
|
+
|
|
4
|
+
## Test plan
|
|
5
|
+
- [ ] `pytest test/unit`
|
|
6
|
+
- [ ] `pytest test/functional` (if applicable)
|
|
7
|
+
- [ ] `pre-commit run --all-files`
|
|
8
|
+
|
|
9
|
+
## Checklist
|
|
10
|
+
- [ ] Added/updated tests (or explained why not)
|
|
11
|
+
- [ ] Updated docs/README if behavior changed
|
|
12
|
+
- [ ] No secrets or credentials committed
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Checks conventions under ``nodescraper/plugins`` (stderr warnings only; non-blocking).
|
|
3
|
+
|
|
4
|
+
1. **Command strings in collectors/analyzers** , for ``Collector``
|
|
5
|
+
or ``Analyzer`` classes: a *class-level* assignment to a string (or f-string) that
|
|
6
|
+
looks like a shell/CLI invocation must use the name ``CMD`` or
|
|
7
|
+
``CMD_<suffix>`` (e.g. ``CMD_LIST``). Names starting with ``_`` and names
|
|
8
|
+
listed in ``_CMD_CHECK_SKIP_NAMES`` are ignored; see
|
|
9
|
+
``_looks_like_shell_command_literal`` for what counts as command-like.
|
|
10
|
+
|
|
11
|
+
2. **Args models** — In ``collector_args.py`` and ``analyzer_args.py``,
|
|
12
|
+
for classes named ``*Args`` that subclass ``BaseModel``, ``CollectorArgs``,
|
|
13
|
+
``AnalyzerArgs``, or another ``*Args``: each public field should assign
|
|
14
|
+
``pydantic.Field(...)`` with a non-empty ``description=`` (for help/CLI
|
|
15
|
+
text). ``ClassVar`` fields, ``_``-prefixed names, and ``model_config`` are
|
|
16
|
+
skipped.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import ast
|
|
22
|
+
import re
|
|
23
|
+
import sys
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
_REPO_ROOT = Path(__file__).resolve().parent.parent.parent
|
|
27
|
+
PLUGIN_ROOT = _REPO_ROOT / "nodescraper" / "plugins"
|
|
28
|
+
|
|
29
|
+
# Class-level names in collectors/analyzers that are not shell-command strings.
|
|
30
|
+
_CMD_CHECK_SKIP_NAMES = frozenset(
|
|
31
|
+
{
|
|
32
|
+
"AMD_SMI_EXE",
|
|
33
|
+
"DATA_MODEL",
|
|
34
|
+
"SUPPORTED_OS_FAMILY",
|
|
35
|
+
"COLLECTOR",
|
|
36
|
+
"ANALYZER",
|
|
37
|
+
"COLLECTOR_ARGS",
|
|
38
|
+
"ANALYZER_ARGS",
|
|
39
|
+
"TYPE_CHECKING",
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _is_stringish(expr: ast.expr) -> bool:
|
|
45
|
+
if isinstance(expr, ast.Constant) and isinstance(expr.value, str):
|
|
46
|
+
return True
|
|
47
|
+
if isinstance(expr, ast.JoinedStr):
|
|
48
|
+
return True
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _stringish_preview(expr: ast.expr) -> str | None:
|
|
53
|
+
"""Best-effort static string for command-like heuristics (f-strings may be partial)."""
|
|
54
|
+
if isinstance(expr, ast.Constant) and isinstance(expr.value, str):
|
|
55
|
+
return expr.value
|
|
56
|
+
if isinstance(expr, ast.JoinedStr):
|
|
57
|
+
parts: list[str] = []
|
|
58
|
+
for elt in expr.values:
|
|
59
|
+
if isinstance(elt, ast.Constant) and isinstance(elt.value, str):
|
|
60
|
+
parts.append(elt.value)
|
|
61
|
+
else:
|
|
62
|
+
parts.append("\x00") # dynamic segment
|
|
63
|
+
return "".join(parts) if parts else ""
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _looks_like_shell_command_literal(s: str) -> bool:
|
|
68
|
+
"""True if this class-level string is plausibly a shell/CLI invocation (not IDs, tokens, paths)."""
|
|
69
|
+
s = s.strip()
|
|
70
|
+
if not s:
|
|
71
|
+
return False
|
|
72
|
+
if re.fullmatch(r"0x[0-9a-fA-F]+", s):
|
|
73
|
+
return False
|
|
74
|
+
# OS / config tokens such as PRETTY_NAME, VERSION_ID
|
|
75
|
+
if re.fullmatch(r"[A-Z][A-Z0-9_]+", s):
|
|
76
|
+
return False
|
|
77
|
+
# Filenames / simple paths (no shell metacharacters)
|
|
78
|
+
if "." in s and not re.search(r"[\s|;&$`]", s):
|
|
79
|
+
return False
|
|
80
|
+
if re.search(r"[\s|;&$`<>]", s):
|
|
81
|
+
return True
|
|
82
|
+
# Typical one-word inband commands: uptime, sysctl, dmesg, amd-smi, etc.
|
|
83
|
+
if re.fullmatch(r"[a-z][a-z0-9_.-]*", s, flags=re.IGNORECASE):
|
|
84
|
+
return True
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _base_name(node: ast.expr) -> str | None:
|
|
89
|
+
if isinstance(node, ast.Name):
|
|
90
|
+
return node.id
|
|
91
|
+
if isinstance(node, ast.Subscript):
|
|
92
|
+
return _base_name(node.value)
|
|
93
|
+
if isinstance(node, ast.Attribute):
|
|
94
|
+
return node.attr
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _is_collector_or_analyzer_class(cls: ast.ClassDef) -> bool:
|
|
99
|
+
return cls.name.endswith("Collector") or cls.name.endswith("Analyzer")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _field_call_name(func: ast.expr) -> bool:
|
|
103
|
+
if isinstance(func, ast.Name) and func.id == "Field":
|
|
104
|
+
return True
|
|
105
|
+
if isinstance(func, ast.Attribute) and func.attr == "Field":
|
|
106
|
+
return True
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _field_has_nonempty_description(call: ast.Call) -> bool:
|
|
111
|
+
for kw in call.keywords:
|
|
112
|
+
if kw.arg != "description" or kw.value is None:
|
|
113
|
+
continue
|
|
114
|
+
v = kw.value
|
|
115
|
+
if isinstance(v, ast.Constant) and isinstance(v.value, str) and v.value.strip():
|
|
116
|
+
return True
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _check_cmd_prefixes(path: Path, tree: ast.Module) -> list[str]:
|
|
121
|
+
"""Rule #1: warn when a command-like class attr is not ``CMD`` / ``CMD_*``."""
|
|
122
|
+
msgs: list[str] = []
|
|
123
|
+
for node in tree.body:
|
|
124
|
+
# Keeps only classes whose names end with Collector or Analyzer (e.g. ProcessCollector, PcieAnalyzer).
|
|
125
|
+
if not isinstance(node, ast.ClassDef) or not _is_collector_or_analyzer_class(node):
|
|
126
|
+
continue
|
|
127
|
+
for stmt in node.body:
|
|
128
|
+
if not isinstance(stmt, ast.Assign) or len(stmt.targets) != 1:
|
|
129
|
+
continue
|
|
130
|
+
t = stmt.targets[0]
|
|
131
|
+
if not isinstance(t, ast.Name):
|
|
132
|
+
continue
|
|
133
|
+
name = t.id
|
|
134
|
+
if name.startswith("_") or name in _CMD_CHECK_SKIP_NAMES:
|
|
135
|
+
continue
|
|
136
|
+
if not _is_stringish(stmt.value):
|
|
137
|
+
continue
|
|
138
|
+
preview = _stringish_preview(stmt.value)
|
|
139
|
+
if preview is None or not _looks_like_shell_command_literal(preview):
|
|
140
|
+
continue
|
|
141
|
+
if name == "CMD" or name.startswith("CMD_"):
|
|
142
|
+
continue
|
|
143
|
+
msgs.append(
|
|
144
|
+
f"{path}:{stmt.lineno}: [{node.name}] command-like class attribute {name!r} "
|
|
145
|
+
"should be renamed to CMD or to start with CMD_."
|
|
146
|
+
)
|
|
147
|
+
return msgs
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _is_args_class(cls: ast.ClassDef) -> bool:
|
|
151
|
+
if not cls.name.endswith("Args"):
|
|
152
|
+
return False
|
|
153
|
+
if not cls.bases:
|
|
154
|
+
return False
|
|
155
|
+
for b in cls.bases:
|
|
156
|
+
bn = _base_name(b)
|
|
157
|
+
if bn in ("BaseModel", "CollectorArgs", "AnalyzerArgs"):
|
|
158
|
+
return True
|
|
159
|
+
if bn and bn.endswith("Args"):
|
|
160
|
+
return True
|
|
161
|
+
return False
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _annotation_mentions_classvar(ann: ast.expr | None) -> bool:
|
|
165
|
+
if ann is None:
|
|
166
|
+
return False
|
|
167
|
+
if isinstance(ann, ast.Name) and ann.id == "ClassVar":
|
|
168
|
+
return True
|
|
169
|
+
if isinstance(ann, ast.Subscript):
|
|
170
|
+
return _annotation_mentions_classvar(ann.value)
|
|
171
|
+
if isinstance(ann, ast.Attribute) and ann.attr == "ClassVar":
|
|
172
|
+
return True
|
|
173
|
+
if isinstance(ann, ast.BinOp) and isinstance(ann.op, ast.BitOr):
|
|
174
|
+
return _annotation_mentions_classvar(ann.left) or _annotation_mentions_classvar(ann.right)
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _check_args_fields(path: Path, tree: ast.Module) -> list[str]:
|
|
179
|
+
"""Rule #2: warn when Args fields lack ``Field`` with a non-empty ``description``."""
|
|
180
|
+
msgs: list[str] = []
|
|
181
|
+
for node in tree.body:
|
|
182
|
+
if not isinstance(node, ast.ClassDef) or not _is_args_class(node):
|
|
183
|
+
continue
|
|
184
|
+
for stmt in node.body:
|
|
185
|
+
if isinstance(stmt, ast.AnnAssign):
|
|
186
|
+
if _annotation_mentions_classvar(stmt.annotation):
|
|
187
|
+
continue
|
|
188
|
+
if not isinstance(stmt.target, ast.Name):
|
|
189
|
+
continue
|
|
190
|
+
field_name = stmt.target.id
|
|
191
|
+
if field_name.startswith("_") or field_name in ("model_config",):
|
|
192
|
+
continue
|
|
193
|
+
if stmt.value is None:
|
|
194
|
+
msgs.append(
|
|
195
|
+
f"{path}:{stmt.lineno}: [{node.name}] {field_name}: "
|
|
196
|
+
"use Field(..., description='...') for every Args field."
|
|
197
|
+
)
|
|
198
|
+
continue
|
|
199
|
+
if isinstance(stmt.value, ast.Call) and _field_call_name(stmt.value.func):
|
|
200
|
+
if not _field_has_nonempty_description(stmt.value):
|
|
201
|
+
msgs.append(
|
|
202
|
+
f"{path}:{stmt.lineno}: [{node.name}] {field_name}: "
|
|
203
|
+
"Field(...) must include a non-empty description= for help text."
|
|
204
|
+
)
|
|
205
|
+
else:
|
|
206
|
+
msgs.append(
|
|
207
|
+
f"{path}:{stmt.lineno}: [{node.name}] {field_name}: "
|
|
208
|
+
"must assign pydantic Field(...) with description=."
|
|
209
|
+
)
|
|
210
|
+
elif isinstance(stmt, ast.Assign) and len(stmt.targets) == 1:
|
|
211
|
+
t = stmt.targets[0]
|
|
212
|
+
if not isinstance(t, ast.Name):
|
|
213
|
+
continue
|
|
214
|
+
field_name = t.id
|
|
215
|
+
if field_name.startswith("_") or field_name in ("model_config",):
|
|
216
|
+
continue
|
|
217
|
+
val = stmt.value
|
|
218
|
+
if isinstance(val, ast.Call) and _field_call_name(val.func):
|
|
219
|
+
if not _field_has_nonempty_description(val):
|
|
220
|
+
msgs.append(
|
|
221
|
+
f"{path}:{stmt.lineno}: [{node.name}] {field_name}: "
|
|
222
|
+
"Field(...) must include a non-empty description= for help text."
|
|
223
|
+
)
|
|
224
|
+
return msgs
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def main() -> None:
|
|
228
|
+
if not PLUGIN_ROOT.is_dir():
|
|
229
|
+
sys.stderr.write(f"warning: plugins directory not found: {PLUGIN_ROOT}\n")
|
|
230
|
+
return
|
|
231
|
+
|
|
232
|
+
all_msgs: list[str] = []
|
|
233
|
+
for path in sorted(PLUGIN_ROOT.rglob("*.py")):
|
|
234
|
+
rel = path.relative_to(_REPO_ROOT)
|
|
235
|
+
name = path.name
|
|
236
|
+
try:
|
|
237
|
+
src = path.read_text(encoding="utf-8")
|
|
238
|
+
tree = ast.parse(src, filename=str(path))
|
|
239
|
+
except (OSError, SyntaxError) as e:
|
|
240
|
+
all_msgs.append(f"{rel}: could not parse: {e}")
|
|
241
|
+
continue
|
|
242
|
+
|
|
243
|
+
if "collector" in name and name.endswith(".py"):
|
|
244
|
+
all_msgs.extend(_check_cmd_prefixes(rel, tree))
|
|
245
|
+
if "analyzer" in name and name.endswith(".py"):
|
|
246
|
+
all_msgs.extend(_check_cmd_prefixes(rel, tree))
|
|
247
|
+
|
|
248
|
+
if name == "collector_args.py" or name == "analyzer_args.py":
|
|
249
|
+
all_msgs.extend(_check_args_fields(rel, tree))
|
|
250
|
+
|
|
251
|
+
if all_msgs:
|
|
252
|
+
sys.stderr.write("plugin convention warnings (commit not blocked):\n")
|
|
253
|
+
for m in all_msgs:
|
|
254
|
+
sys.stderr.write(f" WARNING: {m}\n")
|
|
255
|
+
else:
|
|
256
|
+
sys.stdout.write("Success: no plugin convention warnings.\n")
|
|
257
|
+
sys.exit(0)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
if __name__ == "__main__":
|
|
261
|
+
main()
|
|
@@ -38,7 +38,8 @@ jobs:
|
|
|
38
38
|
source venv/bin/activate
|
|
39
39
|
python docs/generate_plugin_doc_bundle.py \
|
|
40
40
|
--package nodescraper.plugins.inband \
|
|
41
|
-
--output docs/PLUGIN_DOC.md
|
|
41
|
+
--output docs/PLUGIN_DOC.md \
|
|
42
|
+
--update-readme-help
|
|
42
43
|
|
|
43
44
|
- name: Clean pre-commit cache
|
|
44
45
|
run: |
|
|
@@ -50,7 +51,7 @@ jobs:
|
|
|
50
51
|
run: |
|
|
51
52
|
source venv/bin/activate
|
|
52
53
|
pre-commit install-hooks || true
|
|
53
|
-
pre-commit run --files docs/PLUGIN_DOC.md || true
|
|
54
|
+
pre-commit run --files docs/PLUGIN_DOC.md README.md || true
|
|
54
55
|
|
|
55
56
|
- name: Create Pull Request
|
|
56
57
|
uses: peter-evans/create-pull-request@v6
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: plugin-convention-warnings
|
|
5
|
+
name: plugin convention warnings (non-blocking)
|
|
6
|
+
entry: python3 .github/scripts/plugin_convention_warnings.py
|
|
7
|
+
language: system
|
|
8
|
+
pass_filenames: false
|
|
9
|
+
always_run: true
|
|
10
|
+
verbose: true
|
|
2
11
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
12
|
rev: v5.0.0
|
|
4
13
|
hooks:
|
|
@@ -90,3 +90,14 @@ You can also run hooks manually:
|
|
|
90
90
|
# Run all hooks on all files
|
|
91
91
|
pre-commit run --all-files
|
|
92
92
|
```
|
|
93
|
+
|
|
94
|
+
### Plugin conventions
|
|
95
|
+
|
|
96
|
+
We follow a few plugin design conventions so that
|
|
97
|
+
generation and downstream doc tooling run cleanly—for example, naming
|
|
98
|
+
command strings on `*Collector` / `*Analyzer` classes as `CMD` or `CMD_*`, and
|
|
99
|
+
using `pydantic.Field(..., description=...)` on args models. The
|
|
100
|
+
`plugin-convention-warnings` hook in pre-commit runs
|
|
101
|
+
[`.github/scripts/plugin_convention_warnings.py`](.github/scripts/plugin_convention_warnings.py)
|
|
102
|
+
to flag violations (warnings only); read the script’s module docstring for the
|
|
103
|
+
exact rules.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: amd-node-scraper
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.4
|
|
4
4
|
Summary: A framework for automated error detection and data collection
|
|
5
5
|
Project-URL: homepage, https://github.com/amd/node-scraper
|
|
6
6
|
Project-URL: documentation, https://github.com/amd/node-scraper
|
|
@@ -32,6 +32,7 @@ system debug.
|
|
|
32
32
|
|
|
33
33
|
## Table of Contents
|
|
34
34
|
- [Installation](#installation)
|
|
35
|
+
- [Install from PyPI](#install-from-pypi)
|
|
35
36
|
- [Install From Source](#install-from-source)
|
|
36
37
|
- [CLI Usage](#cli-usage)
|
|
37
38
|
- [Execution Methods](#execution-methods)
|
|
@@ -42,7 +43,6 @@ system debug.
|
|
|
42
43
|
- ['run-plugins' sub command](#run-plugins-sub-command)
|
|
43
44
|
- ['gen-plugin-config' sub command](#gen-plugin-config-sub-command)
|
|
44
45
|
- ['compare-runs' subcommand](#compare-runs-subcommand)
|
|
45
|
-
- ['show-redfish-oem-allowable' subcommand](#show-redfish-oem-allowable-subcommand)
|
|
46
46
|
- ['summary' sub command](#summary-sub-command)
|
|
47
47
|
- [Configs](#configs)
|
|
48
48
|
- [Global args](#global-args)
|
|
@@ -53,6 +53,19 @@ system debug.
|
|
|
53
53
|
invoked by collectors** -> See [docs/PLUGIN_DOC.md](docs/PLUGIN_DOC.md)
|
|
54
54
|
|
|
55
55
|
## Installation
|
|
56
|
+
### Install from PyPI
|
|
57
|
+
Node Scraper is published on [PyPI](https://pypi.org/project/amd-node-scraper/) as **amd-node-scraper**. Install it with Python 3.9 or newer:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
pip install amd-node-scraper
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Use a virtual environment if you prefer. After installation, confirm the CLI is available:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
node-scraper --help
|
|
67
|
+
```
|
|
68
|
+
|
|
56
69
|
### Install From Source
|
|
57
70
|
Node Scraper requires Python 3.9+ for installation. After cloning this repository,
|
|
58
71
|
call dev-setup.sh script with 'source'. This script creates an editable install of Node Scraper in
|
|
@@ -87,46 +100,71 @@ Sets up pre-commit hooks for code quality checks. On Debian/Ubuntu, you may need
|
|
|
87
100
|
The Node Scraper CLI can be used to run Node Scraper plugins on a target system. The following CLI
|
|
88
101
|
options are available:
|
|
89
102
|
|
|
103
|
+
<!-- node-scraper -h start -->
|
|
90
104
|
```sh
|
|
91
|
-
usage:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
105
|
+
usage: cli.py [-h] [--version] [--sys-name STRING]
|
|
106
|
+
[--sys-location {LOCAL,REMOTE}]
|
|
107
|
+
[--sys-interaction-level {PASSIVE,INTERACTIVE,DISRUPTIVE}]
|
|
108
|
+
[--sys-sku STRING] [--sys-platform STRING]
|
|
109
|
+
[--plugin-configs LIST] [--system-config STRING]
|
|
110
|
+
[--connection-config STRING] [--log-path STRING]
|
|
111
|
+
[--log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}]
|
|
112
|
+
[--no-console-log] [--gen-reference-config] [--skip-sudo]
|
|
113
|
+
{summary,run-plugins,describe,gen-plugin-config,compare-runs,show-redfish-oem-allowable}
|
|
114
|
+
...
|
|
95
115
|
|
|
96
116
|
node scraper CLI
|
|
97
117
|
|
|
98
118
|
positional arguments:
|
|
99
|
-
{summary,run-plugins,describe,gen-plugin-config}
|
|
119
|
+
{summary,run-plugins,describe,gen-plugin-config,compare-runs,show-redfish-oem-allowable}
|
|
100
120
|
Subcommands
|
|
101
121
|
summary Generates summary csv file
|
|
102
122
|
run-plugins Run a series of plugins
|
|
103
123
|
describe Display details on a built-in config or plugin
|
|
104
124
|
gen-plugin-config Generate a config for a plugin or list of plugins
|
|
125
|
+
compare-runs Compare datamodels from two run log directories
|
|
126
|
+
show-redfish-oem-allowable
|
|
127
|
+
Fetch OEM diagnostic allowable types from Redfish
|
|
128
|
+
LogService (for oem_diagnostic_types_allowable)
|
|
105
129
|
|
|
106
130
|
options:
|
|
107
131
|
-h, --help show this help message and exit
|
|
108
|
-
--
|
|
132
|
+
--version show program's version number and exit
|
|
133
|
+
--sys-name STRING System name (default: <current hostname>)
|
|
109
134
|
--sys-location {LOCAL,REMOTE}
|
|
110
135
|
Location of target system (default: LOCAL)
|
|
111
136
|
--sys-interaction-level {PASSIVE,INTERACTIVE,DISRUPTIVE}
|
|
112
|
-
Specify system interaction level, used to determine
|
|
137
|
+
Specify system interaction level, used to determine
|
|
138
|
+
the type of actions that plugins can perform (default:
|
|
139
|
+
INTERACTIVE)
|
|
113
140
|
--sys-sku STRING Manually specify SKU of system (default: None)
|
|
114
141
|
--sys-platform STRING
|
|
115
142
|
Specify system platform (default: None)
|
|
116
|
-
--plugin-configs
|
|
117
|
-
built-in
|
|
143
|
+
--plugin-configs LIST
|
|
144
|
+
Comma-separated built-in names and/or plugin config
|
|
145
|
+
JSON paths (e.g. --plugin-
|
|
146
|
+
configs=NodeStatus,/path/c.json). Built-ins:
|
|
147
|
+
NodeStatus, AllPlugins (default: None)
|
|
118
148
|
--system-config STRING
|
|
119
149
|
Path to system config json (default: None)
|
|
120
150
|
--connection-config STRING
|
|
121
151
|
Path to connection config json (default: None)
|
|
122
|
-
--log-path STRING Specifies local path for node scraper logs, use 'None'
|
|
152
|
+
--log-path STRING Specifies local path for node scraper logs, use 'None'
|
|
153
|
+
to disable logging (default: .)
|
|
123
154
|
--log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}
|
|
124
155
|
Change python log level (default: INFO)
|
|
156
|
+
--no-console-log Write logs only to nodescraper.log under the run
|
|
157
|
+
directory; do not print to stdout. If no run log
|
|
158
|
+
directory would be created (e.g. --log-path None),
|
|
159
|
+
uses ./scraper_logs_<host>_<timestamp>/ like the
|
|
160
|
+
default layout. (default: False)
|
|
125
161
|
--gen-reference-config
|
|
126
|
-
Generate reference config from system. Writes to
|
|
127
|
-
|
|
128
|
-
|
|
162
|
+
Generate reference config from system. Writes to
|
|
163
|
+
./reference_config.json. (default: False)
|
|
164
|
+
--skip-sudo Skip plugins that require sudo permissions (default:
|
|
165
|
+
False)
|
|
129
166
|
```
|
|
167
|
+
<!-- node-scraper -h end -->
|
|
130
168
|
|
|
131
169
|
### Execution Methods
|
|
132
170
|
|
|
@@ -328,6 +366,16 @@ You can extend the built-in error detection with custom regex patterns. Create a
|
|
|
328
366
|
"event_category": "SW_DRIVER",
|
|
329
367
|
"event_priority": 4
|
|
330
368
|
}
|
|
369
|
+
],
|
|
370
|
+
"priority_override_rules": [
|
|
371
|
+
{
|
|
372
|
+
"message": "Application Crash",
|
|
373
|
+
"new_priority": "ERROR"
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"event_category": "SW_DRIVER",
|
|
377
|
+
"new_priority": "WARNING"
|
|
378
|
+
}
|
|
331
379
|
]
|
|
332
380
|
}
|
|
333
381
|
}
|
|
@@ -339,7 +387,7 @@ You can extend the built-in error detection with custom regex patterns. Create a
|
|
|
339
387
|
Save this to `dmesg_custom_config.json` and run:
|
|
340
388
|
|
|
341
389
|
```sh
|
|
342
|
-
node-scraper --plugin-configs
|
|
390
|
+
node-scraper --plugin-configs=dmesg_custom_config.json run-plugins DmesgPlugin
|
|
343
391
|
```
|
|
344
392
|
|
|
345
393
|
#### **'compare-runs' subcommand**
|
|
@@ -529,9 +577,21 @@ A plugin config can be used to compare the system data against the config specif
|
|
|
529
577
|
Built-in configs include **NodeStatus** (a subset of plugins) and **AllPlugins** (runs every
|
|
530
578
|
registered plugin with default arguments—useful for generating a reference config from the full system).
|
|
531
579
|
|
|
580
|
+
**NodeStatus plus additional plugins** — built-in configs merge with plugins named after `run-plugins`.
|
|
581
|
+
Values are comma-separated; pass as **`--plugin-configs=…`** or **`--plugin-configs` …** (same as other
|
|
582
|
+
optional flags), e.g. `--plugin-configs=NodeStatus,/path/extra.json`.
|
|
583
|
+
Examples:
|
|
584
|
+
```sh
|
|
585
|
+
node-scraper --plugin-configs=NodeStatus run-plugins PciePlugin
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
```sh
|
|
589
|
+
node-scraper --log-path ./logs --plugin-configs=NodeStatus run-plugins PciePlugin
|
|
590
|
+
```
|
|
591
|
+
|
|
532
592
|
Using a JSON file:
|
|
533
593
|
```sh
|
|
534
|
-
node-scraper --plugin-configs
|
|
594
|
+
node-scraper --plugin-configs=plugin_config.json
|
|
535
595
|
```
|
|
536
596
|
Here is an example of a comprehensive plugin config that specifies analyzer args for each plugin:
|
|
537
597
|
```json
|
|
@@ -593,7 +653,7 @@ data.
|
|
|
593
653
|
|
|
594
654
|
**Run all registered plugins (AllPlugins config):**
|
|
595
655
|
```sh
|
|
596
|
-
node-scraper --plugin-
|
|
656
|
+
node-scraper --plugin-configs=AllPlugins
|
|
597
657
|
|
|
598
658
|
```
|
|
599
659
|
|
|
@@ -627,7 +687,7 @@ This will generate the following config:
|
|
|
627
687
|
```
|
|
628
688
|
This config can later be used on a different platform for comparison, using the steps at #2:
|
|
629
689
|
```sh
|
|
630
|
-
node-scraper --plugin-configs
|
|
690
|
+
node-scraper --plugin-configs=reference_config.json
|
|
631
691
|
|
|
632
692
|
```
|
|
633
693
|
|