sima-cli 2.1.14__tar.gz → 2.1.16__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.
- {sima_cli-2.1.14/sima_cli.egg-info → sima_cli-2.1.16}/PKG-INFO +1 -1
- {sima_cli-2.1.14 → sima_cli-2.1.16}/pyproject.toml +1 -1
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/__version__.py +1 -1
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/cli.py +125 -11
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/discover/discover.py +1 -1
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/metadata_installer.py +56 -7
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/model_zoo/model.py +1 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/playbooks/manager.py +9 -4
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/commands.py +50 -4
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/config.py +5 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/install.py +60 -17
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/neat.py +24 -8
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/utils.py +110 -23
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/elxr.py +97 -33
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/query.py +29 -4
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/updater.py +47 -6
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/container_registries.py +249 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/docker.py +1 -1
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/pcie.py +126 -29
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/vulcan/artifacts.py +55 -5
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/vulcan/commands.py +50 -5
- {sima_cli-2.1.14 → sima_cli-2.1.16/sima_cli.egg-info}/PKG-INFO +1 -1
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli.egg-info/SOURCES.txt +3 -0
- sima_cli-2.1.16/tests/unit/test_cli_update.py +76 -0
- sima_cli-2.1.16/tests/unit/test_cli_update_rerun.py +44 -0
- sima_cli-2.1.16/tests/unit/test_container_registries.py +220 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_docker_utils.py +23 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_elxr_update.py +110 -1
- sima_cli-2.1.16/tests/unit/test_firmware.py +141 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_metadata_installer.py +54 -0
- sima_cli-2.1.16/tests/unit/test_model_zoo.py +48 -0
- sima_cli-2.1.16/tests/unit/test_modelzoo_commands.py +11 -0
- sima_cli-2.1.16/tests/unit/test_pcie.py +171 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_sdk_image_detection.py +287 -31
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_skills_manager.py +30 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_vulcan.py +226 -13
- sima_cli-2.1.14/tests/unit/test_cli_update.py +0 -25
- sima_cli-2.1.14/tests/unit/test_cli_update_rerun.py +0 -20
- sima_cli-2.1.14/tests/unit/test_firmware.py +0 -60
- sima_cli-2.1.14/tests/unit/test_model_zoo.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/LICENSE +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/MANIFEST.in +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/README.md +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/requirements.txt +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/setup.cfg +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/setup.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/__main__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/app_zoo/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/app_zoo/app.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/app_zoo/commands.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/auth/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/auth/auth0.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/auth/devportal.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/auth/login.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/data/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/data/resources_internal.yaml +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/data/resources_public.yaml +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/deploy_only/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/deploy_only/device/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/deploy_only/device/commands.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/deploy_only/mpk/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/deploy_only/mpk/commands.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/discover/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/discover/linuxll.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/download/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/download/downloader.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/compatibility.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/github_assets.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/hostdriver.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/metadata_info.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/metadata_validator.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/optiview.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/package_builder.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/palette.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/install/registry.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/mla/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/mla/meminfo.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/model_zoo/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/network/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/network/network.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/playbooks/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/playbooks/commands.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/cmdexec.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/linux_devkit_network.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/linux_shared_network.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/network_doctor.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/preinstall.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/requirements.json +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/script.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/stop.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/sdk/uninstall.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/serial/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/serial/serial.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/storage/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/storage/nvme.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/storage/sdcard.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/bmaptool.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/bootimg.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/cleanlog.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/local.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/netboot.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/update/remote.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/upgrade/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/upgrade/selfupdate.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/api_common.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/artifactory.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/common.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/config.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/config_loader.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/deprecation.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/device_api.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/disk.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/env.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/errors.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/mpk_api.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/net.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/network.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/pkg_update_check.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/serializers.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/services.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/utils/tag.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli/vulcan/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli.egg-info/dependency_links.txt +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli.egg-info/entry_points.txt +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli.egg-info/requires.txt +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/sima_cli.egg-info/top_level.txt +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/e2e/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/__init__.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_app_zoo.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_appzoo_commands.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_auth.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_auth0.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_cli.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_cli_stdio.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_deprecation.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_download.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_generate_cli_markdown_docs.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_install_stub.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_metadata_validator.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_netboot.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_package_builder.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_pkg_update_check.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_sdk_linux_shared_network.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_sdk_network_doctor.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_sdk_preinstall.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_sdk_uninstall.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_selfupdate.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_skills_commands.py +0 -0
- {sima_cli-2.1.14 → sima_cli-2.1.16}/tests/unit/test_utils.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# sima_cli/__version__.py
|
|
2
|
-
__version__ = "2.1.
|
|
2
|
+
__version__ = "2.1.16"
|
|
@@ -2,6 +2,9 @@ import os
|
|
|
2
2
|
import shutil
|
|
3
3
|
import sys
|
|
4
4
|
import click
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.panel import Panel
|
|
7
|
+
from rich.text import Text
|
|
5
8
|
from sima_cli.utils.env import get_environment_type
|
|
6
9
|
from sima_cli.update.updater import perform_update
|
|
7
10
|
from sima_cli.model_zoo.model import list_models, download_model, describe_model
|
|
@@ -12,7 +15,11 @@ from sima_cli.__version__ import __version__
|
|
|
12
15
|
from sima_cli.utils.config import CONFIG_PATH
|
|
13
16
|
from sima_cli.install.optiview import install_optiview
|
|
14
17
|
from sima_cli.install.hostdriver import install_hostdriver
|
|
15
|
-
from sima_cli.install.metadata_installer import
|
|
18
|
+
from sima_cli.install.metadata_installer import (
|
|
19
|
+
MetadataAccessForbidden,
|
|
20
|
+
install_from_metadata,
|
|
21
|
+
metadata_resolver,
|
|
22
|
+
)
|
|
16
23
|
from sima_cli.serial.serial import connect_serial
|
|
17
24
|
from sima_cli.storage.nvme import nvme_format, nvme_remount
|
|
18
25
|
from sima_cli.storage.sdcard import sdcard_format
|
|
@@ -71,6 +78,19 @@ def _should_rerun_after_update(argv):
|
|
|
71
78
|
return command_name not in (None, "selfupdate", "version")
|
|
72
79
|
|
|
73
80
|
|
|
81
|
+
def _allows_external_prerelease_fallback(argv):
|
|
82
|
+
"""Return whether this invocation explicitly allows update mirror fallback."""
|
|
83
|
+
args = argv[1:]
|
|
84
|
+
return "update" in args and any(arg in ("-f", "--force") for arg in args)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _update_auto_confirm_requested(argv):
|
|
88
|
+
"""Return whether an update invocation requests non-interactive confirmation."""
|
|
89
|
+
return _command_name_from_argv(argv) == "update" and any(
|
|
90
|
+
arg in ("-y", "--yes") for arg in argv[1:]
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
74
94
|
def _rerun_current_command() -> None:
|
|
75
95
|
env = os.environ.copy()
|
|
76
96
|
env["SIMA_CLI_CHECK_FOR_UPDATE"] = "0"
|
|
@@ -82,9 +102,10 @@ def _rerun_current_command() -> None:
|
|
|
82
102
|
# Entry point for the CLI tool using Click's command group decorator
|
|
83
103
|
@click.group(context_settings=dict(help_option_names=["-h", "--help", "-?"], max_content_width=120))
|
|
84
104
|
@click.option('-i', '--internal', is_flag=True, help="Use internal Artifactory resources, Authorized Sima employees only")
|
|
105
|
+
@click.option('-y', '--yes', is_flag=True, help="Assume yes for confirmation prompts.")
|
|
85
106
|
@click.version_option(version=f"{__version__}", message="SiMa CLI version: %(version)s")
|
|
86
107
|
@click.pass_context
|
|
87
|
-
def main(ctx, internal):
|
|
108
|
+
def main(ctx, internal, yes):
|
|
88
109
|
"""
|
|
89
110
|
sima-cli – SiMa Developer Portal CLI Tool
|
|
90
111
|
|
|
@@ -92,8 +113,19 @@ def main(ctx, internal):
|
|
|
92
113
|
--internal Use internal Artifactory resources (can also be set via env variable SIMA_CLI_INTERNAL=1)
|
|
93
114
|
"""
|
|
94
115
|
_configure_stdio_errors()
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
auto_accept_update = yes or _update_auto_confirm_requested(sys.argv)
|
|
117
|
+
previous_auto_accept = os.environ.get("SIMA_CLI_AUTO_ACCEPT_UPDATE")
|
|
118
|
+
if auto_accept_update:
|
|
119
|
+
os.environ["SIMA_CLI_AUTO_ACCEPT_UPDATE"] = "1"
|
|
120
|
+
try:
|
|
121
|
+
if check_for_update('sima-cli') and _should_rerun_after_update(sys.argv):
|
|
122
|
+
_rerun_current_command()
|
|
123
|
+
finally:
|
|
124
|
+
if auto_accept_update:
|
|
125
|
+
if previous_auto_accept is None:
|
|
126
|
+
os.environ.pop("SIMA_CLI_AUTO_ACCEPT_UPDATE", None)
|
|
127
|
+
else:
|
|
128
|
+
os.environ["SIMA_CLI_AUTO_ACCEPT_UPDATE"] = previous_auto_accept
|
|
97
129
|
ctx.ensure_object(dict)
|
|
98
130
|
|
|
99
131
|
os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True)
|
|
@@ -107,13 +139,25 @@ def main(ctx, internal):
|
|
|
107
139
|
click.echo("Refer to the confluence page to find out how to configure internal resource map.")
|
|
108
140
|
exit(0)
|
|
109
141
|
|
|
110
|
-
|
|
142
|
+
internal_reachable = True
|
|
143
|
+
if internal:
|
|
144
|
+
internal_reachable = check_artifactory_reachability()
|
|
145
|
+
|
|
146
|
+
if internal and not internal_reachable and not _allows_external_prerelease_fallback(sys.argv):
|
|
111
147
|
click.secho("❌ You have specified -i or --internal argument to access internal resources, but you can't connect to Artifactory.", fg='red')
|
|
112
148
|
click.secho("Please make sure you are connected to VPN or are on the corporate network.", fg='red')
|
|
113
149
|
exit(0)
|
|
150
|
+
|
|
151
|
+
if internal and not internal_reachable:
|
|
152
|
+
click.secho(
|
|
153
|
+
"⚠️ Internal resources are unreachable. --force allows this update to use the external pre-release mirror.",
|
|
154
|
+
fg="yellow",
|
|
155
|
+
)
|
|
114
156
|
|
|
115
157
|
|
|
116
158
|
ctx.obj["internal"] = internal
|
|
159
|
+
ctx.obj["internal_reachable"] = internal_reachable
|
|
160
|
+
ctx.obj["yes"] = yes
|
|
117
161
|
|
|
118
162
|
env_type, env_subtype = get_environment_type()
|
|
119
163
|
|
|
@@ -230,21 +274,29 @@ def download(ctx, url, dest):
|
|
|
230
274
|
@click.option(
|
|
231
275
|
"-y", "--yes",
|
|
232
276
|
is_flag=True,
|
|
233
|
-
help="
|
|
277
|
+
help="Assume yes for update confirmation prompts."
|
|
234
278
|
)
|
|
235
279
|
@click.option(
|
|
236
280
|
"-p", "--passwd",
|
|
237
281
|
default="edgeai",
|
|
238
282
|
show_default=True,
|
|
239
|
-
help="
|
|
283
|
+
help="Password for remote board SSH or local ELXR sudo authentication."
|
|
240
284
|
)
|
|
241
285
|
@click.option(
|
|
242
|
-
"
|
|
286
|
+
"--flavor",
|
|
243
287
|
type=click.Choice(["headless", "full", "auto"], case_sensitive=False),
|
|
244
288
|
default="auto",
|
|
245
289
|
show_default=True,
|
|
246
290
|
help="Firmware flavor: 'full' image supports NVMe and GUI on Modalix DevKit. This option is deprecated for 2.0 and above"
|
|
247
291
|
)
|
|
292
|
+
@click.option(
|
|
293
|
+
"-f", "--force",
|
|
294
|
+
is_flag=True,
|
|
295
|
+
help=(
|
|
296
|
+
"If the internal mirror is unreachable, fall back to the external pre-release mirror "
|
|
297
|
+
"without signature verification; without --internal, select that mirror directly (ELXR only)."
|
|
298
|
+
)
|
|
299
|
+
)
|
|
248
300
|
@click.option(
|
|
249
301
|
"-t", "--troot_only",
|
|
250
302
|
is_flag=True,
|
|
@@ -258,7 +310,7 @@ def download(ctx, url, dest):
|
|
|
258
310
|
help="For ELXR updates only, validate the update path and print the simaai-ota command without running it."
|
|
259
311
|
)
|
|
260
312
|
@click.pass_context
|
|
261
|
-
def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, troot_only, dryrun):
|
|
313
|
+
def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force, troot_only, dryrun):
|
|
262
314
|
"""
|
|
263
315
|
Update the software on a SiMa DevKit or remote SiMa device.
|
|
264
316
|
|
|
@@ -316,6 +368,18 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, troot_o
|
|
|
316
368
|
|
|
317
369
|
sima-cli update -v 1.7.0 -y
|
|
318
370
|
|
|
371
|
+
# Update ELXR to the latest official release without prompts
|
|
372
|
+
|
|
373
|
+
sima-cli update -y
|
|
374
|
+
|
|
375
|
+
# Update ELXR from the internal mirror without prompts
|
|
376
|
+
|
|
377
|
+
sima-cli -i update -y
|
|
378
|
+
|
|
379
|
+
# Update ELXR from the public pre-release mirror without prompts
|
|
380
|
+
|
|
381
|
+
sima-cli -y update -f -y
|
|
382
|
+
|
|
319
383
|
# Validate ELXR update path without running simaai-ota
|
|
320
384
|
|
|
321
385
|
sima-cli update --dryrun
|
|
@@ -345,15 +409,20 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, troot_o
|
|
|
345
409
|
|
|
346
410
|
# Extract context and run update logic
|
|
347
411
|
internal = ctx.obj.get("internal", False)
|
|
412
|
+
auto_confirm = yes or ctx.obj.get("yes", False)
|
|
413
|
+
force_external_fallback = force and (
|
|
414
|
+
not internal or not ctx.obj.get("internal_reachable", True)
|
|
415
|
+
)
|
|
348
416
|
perform_update(
|
|
349
417
|
version_or_url,
|
|
350
418
|
ip,
|
|
351
419
|
internal,
|
|
352
420
|
passwd=passwd,
|
|
353
|
-
auto_confirm=
|
|
421
|
+
auto_confirm=auto_confirm,
|
|
354
422
|
flavor=flavor,
|
|
355
423
|
troot_only=troot_only,
|
|
356
424
|
dryrun=dryrun,
|
|
425
|
+
force_external_fallback=force_external_fallback,
|
|
357
426
|
)
|
|
358
427
|
|
|
359
428
|
# ----------------------
|
|
@@ -407,7 +476,7 @@ def get_model(ctx, model_name):
|
|
|
407
476
|
@click.argument('model_name')
|
|
408
477
|
@click.pass_context
|
|
409
478
|
def get_model(ctx, model_name):
|
|
410
|
-
"""
|
|
479
|
+
"""Provide information about a specific model."""
|
|
411
480
|
ver = ctx.obj.get("ver")
|
|
412
481
|
internal = ctx.obj.get("internal", False)
|
|
413
482
|
boardtype = ctx.obj.get('boardtype')
|
|
@@ -544,6 +613,37 @@ def bootimg_cmd(ctx, version, boardtype, netboot, devkit_ip, autoflash, fwtype,
|
|
|
544
613
|
SDK_DEPENDENT_COMPONENTS = {"palette", "hostdriver"}
|
|
545
614
|
SDK_INDEPENDENT_COMPONENTS = {"optiview"}
|
|
546
615
|
ALL_COMPONENTS = SDK_DEPENDENT_COMPONENTS | SDK_INDEPENDENT_COMPONENTS
|
|
616
|
+
NEAT_INSTALL_REPOSITORIES = {
|
|
617
|
+
"apps",
|
|
618
|
+
"core",
|
|
619
|
+
"insight",
|
|
620
|
+
"internals",
|
|
621
|
+
"llima",
|
|
622
|
+
"models",
|
|
623
|
+
"sdk",
|
|
624
|
+
"sentinel",
|
|
625
|
+
"sima-cli",
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
def _is_neat_install_target(component: str) -> bool:
|
|
630
|
+
repository = component.lower().split("/", 1)[0].split("@", 1)[0].split(":", 1)[0]
|
|
631
|
+
return repository in NEAT_INSTALL_REPOSITORIES
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
def _show_neat_install_fallback(component: str) -> None:
|
|
635
|
+
Console().print(
|
|
636
|
+
Panel(
|
|
637
|
+
Text.from_markup(
|
|
638
|
+
"The standard install source returned HTTP 403 for this Neat component.\n\n"
|
|
639
|
+
f"Switching to [bold]sima-cli neat install {component}[/bold].\n\n"
|
|
640
|
+
"For Neat organization components, use [bold]sima-cli neat install[/bold] in the future."
|
|
641
|
+
),
|
|
642
|
+
title="Switching to Neat Install",
|
|
643
|
+
border_style="yellow",
|
|
644
|
+
expand=False,
|
|
645
|
+
)
|
|
646
|
+
)
|
|
547
647
|
|
|
548
648
|
@main.command(name="install")
|
|
549
649
|
@click.argument("component", required=False)
|
|
@@ -728,6 +828,20 @@ def install_cmd(
|
|
|
728
828
|
command_name="sima-cli install",
|
|
729
829
|
):
|
|
730
830
|
click.echo("✅ Installation complete.")
|
|
831
|
+
except MetadataAccessForbidden:
|
|
832
|
+
if not _is_neat_install_target(component):
|
|
833
|
+
raise
|
|
834
|
+
_show_neat_install_fallback(component)
|
|
835
|
+
install_vulcan_package(
|
|
836
|
+
target=component,
|
|
837
|
+
environment="production",
|
|
838
|
+
package_type=tag,
|
|
839
|
+
install_dir=install_dir,
|
|
840
|
+
force=force,
|
|
841
|
+
json_output=json_output,
|
|
842
|
+
command_name="sima-cli neat install",
|
|
843
|
+
)
|
|
844
|
+
return None
|
|
731
845
|
except click.ClickException:
|
|
732
846
|
raise
|
|
733
847
|
except Exception as e:
|
|
@@ -236,7 +236,7 @@ def discover_and_render_pcie_devices():
|
|
|
236
236
|
)
|
|
237
237
|
|
|
238
238
|
console.print(pcie_table)
|
|
239
|
-
maybe_run_pcie_throughput_test()
|
|
239
|
+
maybe_run_pcie_throughput_test(pcie_devices)
|
|
240
240
|
|
|
241
241
|
# ─────────────────────────────────────────────────────────────
|
|
242
242
|
# Unified Discovery Orchestration
|
|
@@ -49,6 +49,26 @@ class InstallationPreflightError(click.ClickException):
|
|
|
49
49
|
)
|
|
50
50
|
|
|
51
51
|
|
|
52
|
+
class MetadataAccessForbidden(click.ClickException):
|
|
53
|
+
"""Raised when a metadata request is rejected with HTTP 403."""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _is_http_forbidden_error(exc: BaseException) -> bool:
|
|
57
|
+
current = exc
|
|
58
|
+
seen = set()
|
|
59
|
+
while current is not None and id(current) not in seen:
|
|
60
|
+
seen.add(id(current))
|
|
61
|
+
response = getattr(current, "response", None)
|
|
62
|
+
if getattr(response, "status_code", None) == 403:
|
|
63
|
+
return True
|
|
64
|
+
if getattr(current, "code", None) == 403:
|
|
65
|
+
return True
|
|
66
|
+
if re.search(r"\b403\b", str(current), flags=re.IGNORECASE):
|
|
67
|
+
return True
|
|
68
|
+
current = current.__cause__ or current.__context__
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
|
|
52
72
|
def _ensure_install_dir_writable(install_dir: str, command_name: str = "sima-cli install") -> None:
|
|
53
73
|
target = Path(install_dir or ".").expanduser()
|
|
54
74
|
display_path = Path.cwd() if str(target) == "." else target
|
|
@@ -767,7 +787,12 @@ def selectable_resource_handler(metadata):
|
|
|
767
787
|
return metadata
|
|
768
788
|
|
|
769
789
|
|
|
770
|
-
def _download_and_validate_metadata(
|
|
790
|
+
def _download_and_validate_metadata(
|
|
791
|
+
metadata_url,
|
|
792
|
+
internal=False,
|
|
793
|
+
force=False,
|
|
794
|
+
check_compatibility=True,
|
|
795
|
+
):
|
|
771
796
|
"""
|
|
772
797
|
Downloads (if remote), validates, and parses metadata from a given URL or local file path.
|
|
773
798
|
|
|
@@ -775,6 +800,7 @@ def _download_and_validate_metadata(metadata_url, internal=False, force=False):
|
|
|
775
800
|
metadata_url (str): URL or local path to a metadata.json file
|
|
776
801
|
internal (bool): Whether to use internal mirrors or logic in downloader
|
|
777
802
|
force (bool): whether to ignore compatibility check result
|
|
803
|
+
check_compatibility (bool): whether to enforce platform compatibility
|
|
778
804
|
|
|
779
805
|
Returns:
|
|
780
806
|
tuple: (parsed metadata dict, folder containing the metadata file)
|
|
@@ -811,7 +837,7 @@ def _download_and_validate_metadata(metadata_url, internal=False, force=False):
|
|
|
811
837
|
with open(metadata_path, "r", encoding="utf-8") as f:
|
|
812
838
|
metadata = json.load(f)
|
|
813
839
|
validate_metadata(metadata)
|
|
814
|
-
if _is_platform_compatible(metadata, force)
|
|
840
|
+
if not check_compatibility or force or _is_platform_compatible(metadata, force):
|
|
815
841
|
click.echo("✅ Metadata validated successfully.")
|
|
816
842
|
metadata = selectable_resource_handler(metadata)
|
|
817
843
|
return metadata, os.path.dirname(metadata_path)
|
|
@@ -823,16 +849,22 @@ def _download_and_validate_metadata(metadata_url, internal=False, force=False):
|
|
|
823
849
|
metadata = json.load(f)
|
|
824
850
|
|
|
825
851
|
validate_metadata(metadata)
|
|
826
|
-
if _is_platform_compatible(metadata, force=force)
|
|
852
|
+
if not check_compatibility or force or _is_platform_compatible(metadata, force=force):
|
|
827
853
|
metadata = selectable_resource_handler(metadata)
|
|
828
854
|
click.echo("✅ Metadata validated successfully.")
|
|
829
855
|
return metadata, os.path.dirname(os.path.abspath(metadata_path))
|
|
830
856
|
|
|
857
|
+
return None, None
|
|
858
|
+
|
|
831
859
|
except MetadataValidationError as e:
|
|
832
860
|
click.echo(f"❌ Metadata validation failed: {e}")
|
|
833
861
|
raise click.Abort()
|
|
834
862
|
|
|
835
863
|
except Exception as e:
|
|
864
|
+
if _is_http_forbidden_error(e):
|
|
865
|
+
raise MetadataAccessForbidden(
|
|
866
|
+
f"Access forbidden while retrieving metadata from {metadata_url}"
|
|
867
|
+
) from e
|
|
836
868
|
click.echo(f"❌ Failed to retrieve or parse metadata from {metadata_url}: {e}")
|
|
837
869
|
raise click.Abort()
|
|
838
870
|
|
|
@@ -1178,6 +1210,12 @@ def _get_palette_sdk_version(release_file: Path = Path("/etc/sdk-release")) -> s
|
|
|
1178
1210
|
except OSError:
|
|
1179
1211
|
return ""
|
|
1180
1212
|
|
|
1213
|
+
platform_base = re.search(
|
|
1214
|
+
r"^Platform Base\s*=\s*(\S+)", content, flags=re.MULTILINE
|
|
1215
|
+
)
|
|
1216
|
+
if platform_base:
|
|
1217
|
+
return platform_base.group(1).strip()
|
|
1218
|
+
|
|
1181
1219
|
match = re.search(r"^SDK Version\s*=\s*(\S+)", content, flags=re.MULTILINE)
|
|
1182
1220
|
if not match:
|
|
1183
1221
|
return ""
|
|
@@ -1513,6 +1551,7 @@ def install_from_metadata(
|
|
|
1513
1551
|
install_dir: str = '.',
|
|
1514
1552
|
force: bool = False,
|
|
1515
1553
|
command_name: str = "sima-cli install",
|
|
1554
|
+
download_only: bool = False,
|
|
1516
1555
|
):
|
|
1517
1556
|
_ensure_install_dir_writable(install_dir, command_name=command_name)
|
|
1518
1557
|
|
|
@@ -1526,15 +1565,23 @@ def install_from_metadata(
|
|
|
1526
1565
|
if force:
|
|
1527
1566
|
click.secho('⚠️ --force option was provided, skipping available space and compatibility check, package may not work properly', fg='yellow')
|
|
1528
1567
|
|
|
1529
|
-
metadata, _ = _download_and_validate_metadata(
|
|
1530
|
-
|
|
1531
|
-
|
|
1568
|
+
metadata, _ = _download_and_validate_metadata(
|
|
1569
|
+
metadata_url,
|
|
1570
|
+
internal,
|
|
1571
|
+
force=force,
|
|
1572
|
+
check_compatibility=not download_only,
|
|
1573
|
+
)
|
|
1532
1574
|
if metadata:
|
|
1533
1575
|
print_metadata_summary(metadata=metadata)
|
|
1576
|
+
if not download_only:
|
|
1577
|
+
registry.create_entry(metadata.get('name'), metadata.get('version'), metadata, '')
|
|
1534
1578
|
|
|
1535
1579
|
if _check_whether_disk_is_big_enough(metadata, force) or force:
|
|
1536
|
-
if _is_platform_compatible(metadata, force)
|
|
1580
|
+
if download_only or force or _is_platform_compatible(metadata, force):
|
|
1537
1581
|
local_paths = _download_assets(metadata, metadata_url, install_dir, internal, tag=tag)
|
|
1582
|
+
if download_only:
|
|
1583
|
+
click.echo(f"✅ Download complete. {len(local_paths)} resource(s) saved to: {install_dir}")
|
|
1584
|
+
return local_paths
|
|
1538
1585
|
if len(local_paths) > 0:
|
|
1539
1586
|
_mark_install_script_executable(metadata, install_dir)
|
|
1540
1587
|
_combine_multipart_files(install_dir, local_paths=local_paths)
|
|
@@ -1542,6 +1589,8 @@ def install_from_metadata(
|
|
|
1542
1589
|
_mark_install_script_executable(metadata, install_dir)
|
|
1543
1590
|
_run_installation_script(metadata=metadata, extract_path=install_dir)
|
|
1544
1591
|
|
|
1592
|
+
except MetadataAccessForbidden:
|
|
1593
|
+
raise
|
|
1545
1594
|
except Exception as e:
|
|
1546
1595
|
click.echo(f"❌ Failed to install from metadata URL {metadata_url}: {e}")
|
|
1547
1596
|
exit(1)
|
|
@@ -564,6 +564,7 @@ def _list_available_models_internal(version: str, boardtype: str):
|
|
|
564
564
|
|
|
565
565
|
if action == "Download model":
|
|
566
566
|
_download_model_internal(version, boardtype, selected_model)
|
|
567
|
+
break # return to model selection after the download attempt
|
|
567
568
|
elif action == "Back":
|
|
568
569
|
break # back to model list
|
|
569
570
|
else: # Exit
|
|
@@ -364,9 +364,11 @@ class SkillManager:
|
|
|
364
364
|
return target
|
|
365
365
|
|
|
366
366
|
def _download_repo_archive(self, source: SourceRef, url: str, workdir: Path) -> Path:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
# SCM archive endpoints commonly end in a ref (for example ``develop``
|
|
368
|
+
# or a commit SHA), so the URL path does not carry an archive suffix.
|
|
369
|
+
# Use a known filename instead of asking archive extraction to infer the
|
|
370
|
+
# format from that ref.
|
|
371
|
+
target = workdir / "skills.tar.gz"
|
|
370
372
|
|
|
371
373
|
token = self._normalize_auth_token(os.getenv("GITHUB_TOKEN", "")) if source.scheme == "gh" else ""
|
|
372
374
|
bb_user = os.getenv("BITBUCKET_USERNAME", "").strip()
|
|
@@ -418,7 +420,10 @@ class SkillManager:
|
|
|
418
420
|
repo = source.repo_name
|
|
419
421
|
ref = source.ref
|
|
420
422
|
if source.scheme == "gh":
|
|
421
|
-
|
|
423
|
+
# GitHub's generic codeload endpoint resolves branches, tags, and
|
|
424
|
+
# commit SHAs. refs/heads only works for branches and returns 404
|
|
425
|
+
# for the immutable commit refs used by published packages.
|
|
426
|
+
return f"https://codeload.github.com/{owner}/{repo}/tar.gz/{quote(ref, safe='')}"
|
|
422
427
|
if source.scheme == "bb":
|
|
423
428
|
return f"https://bitbucket.org/{owner}/{repo}/get/{ref}.tar.gz"
|
|
424
429
|
raise SkillError(f"Unsupported repo source: {source.scheme}")
|
|
@@ -13,6 +13,7 @@ Usage:
|
|
|
13
13
|
sima-cli sdk model : go to model container
|
|
14
14
|
sima-cli sdk yocto : go to Yocto container
|
|
15
15
|
sima-cli sdk neat : go to Neat SDK container
|
|
16
|
+
sima-cli sdk ros2 : go to ROS 2 SDK container
|
|
16
17
|
sima-cli sdk elxr : go to elxr container
|
|
17
18
|
"""
|
|
18
19
|
|
|
@@ -42,6 +43,7 @@ from sima_cli.sdk.network_doctor import (
|
|
|
42
43
|
print_network_doctor_report,
|
|
43
44
|
repair_linux_devkit_network,
|
|
44
45
|
)
|
|
46
|
+
from sima_cli.sdk.neat import DEFAULT_INSIGHT_VIDEO_CHANNELS, MAX_INSIGHT_VIDEO_CHANNELS
|
|
45
47
|
from sima_cli.sdk.linux_shared_network import (
|
|
46
48
|
NM_SHARED_DISPATCHER_PATH,
|
|
47
49
|
rollback_linux_shared_devkit_network,
|
|
@@ -67,7 +69,7 @@ def sdk(ctx, version_filter):
|
|
|
67
69
|
|
|
68
70
|
This group provides access to the full SDK 2.0 toolchain, including
|
|
69
71
|
setup, container orchestration, tool-specific shells (MPK, model,
|
|
70
|
-
Yocto, Neat, eLxr), and hybrid `.sima` script execution. These commands are
|
|
72
|
+
Yocto, Neat, ROS 2, eLxr), and hybrid `.sima` script execution. These commands are
|
|
71
73
|
intended for SDK 2.0+ users only.
|
|
72
74
|
|
|
73
75
|
\\c Host platforms only.
|
|
@@ -281,6 +283,13 @@ def launch_sdk_tool(tool: str, cmd, ctx, recover_unavailable: bool = False):
|
|
|
281
283
|
is_flag=True,
|
|
282
284
|
help="Start Neat SDK without Insight UI/video/WebRTC port mappings.",
|
|
283
285
|
)
|
|
286
|
+
@click.option(
|
|
287
|
+
"--insight-video-channels",
|
|
288
|
+
type=click.IntRange(1, MAX_INSIGHT_VIDEO_CHANNELS),
|
|
289
|
+
default=DEFAULT_INSIGHT_VIDEO_CHANNELS,
|
|
290
|
+
show_default=True,
|
|
291
|
+
help="Number of Insight video channels to configure (four exposed ports per channel).",
|
|
292
|
+
)
|
|
284
293
|
@click.option(
|
|
285
294
|
"--no-model-compiler",
|
|
286
295
|
"--no-model-sdk",
|
|
@@ -304,8 +313,15 @@ def launch_sdk_tool(tool: str, cmd, ctx, recover_unavailable: bool = False):
|
|
|
304
313
|
is_flag=True,
|
|
305
314
|
help="Allow setup to install a persistent NetworkManager shared-network repair profile without prompting.",
|
|
306
315
|
)
|
|
316
|
+
@click.option(
|
|
317
|
+
"--image",
|
|
318
|
+
"image_selectors",
|
|
319
|
+
multiple=True,
|
|
320
|
+
default=(),
|
|
321
|
+
help="Start only the SDK image matching this repository:tag or tag (e.g. 'ghcr.io/sima-neat/sdk:latest' or 'latest'). Repeatable; skips the selection prompt.",
|
|
322
|
+
)
|
|
307
323
|
@click.pass_context
|
|
308
|
-
def setup(ctx, yes, noninteractive, devkit, no_insight, no_model_sdk, minimal, workspace, persistent_network_profile):
|
|
324
|
+
def setup(ctx, yes, noninteractive, devkit, no_insight, insight_video_channels, no_model_sdk, minimal, workspace, persistent_network_profile, image_selectors):
|
|
309
325
|
"""Initialize SDK environment and select components to start."""
|
|
310
326
|
devkit_ip = _resolve_devkit_ip(devkit)
|
|
311
327
|
try:
|
|
@@ -314,10 +330,12 @@ def setup(ctx, yes, noninteractive, devkit, no_insight, no_model_sdk, minimal, w
|
|
|
314
330
|
yes_to_all=yes,
|
|
315
331
|
devkit_ip=devkit_ip,
|
|
316
332
|
no_insight=no_insight,
|
|
333
|
+
insight_video_channels=insight_video_channels,
|
|
317
334
|
no_model_sdk=no_model_sdk,
|
|
318
335
|
minimal=minimal,
|
|
319
336
|
workspace=workspace,
|
|
320
337
|
persistent_network_profile=persistent_network_profile,
|
|
338
|
+
image_selectors=image_selectors,
|
|
321
339
|
)
|
|
322
340
|
except subprocess.CalledProcessError as e:
|
|
323
341
|
raise click.ClickException(f"SDK setup failed while running: {' '.join(e.cmd)}") from e
|
|
@@ -335,11 +353,18 @@ def setup(ctx, yes, noninteractive, devkit, no_insight, no_model_sdk, minimal, w
|
|
|
335
353
|
is_flag=True,
|
|
336
354
|
help="Skip confirmation before starting the container."
|
|
337
355
|
)
|
|
356
|
+
@click.option(
|
|
357
|
+
"--image",
|
|
358
|
+
"image_selectors",
|
|
359
|
+
multiple=True,
|
|
360
|
+
default=(),
|
|
361
|
+
help="Start only the SDK image matching this repository:tag or tag (e.g. 'ghcr.io/sima-neat/sdk:latest' or 'latest'). Repeatable; skips the selection prompt.",
|
|
362
|
+
)
|
|
338
363
|
@click.pass_context
|
|
339
|
-
def start(ctx, yes, noninteractive):
|
|
364
|
+
def start(ctx, yes, noninteractive, image_selectors):
|
|
340
365
|
"""Select and start one or more SDK containers."""
|
|
341
366
|
try:
|
|
342
|
-
setup_and_start(noninteractive=noninteractive,start_only=True, yes_to_all=yes)
|
|
367
|
+
setup_and_start(noninteractive=noninteractive, start_only=True, yes_to_all=yes, image_selectors=image_selectors)
|
|
343
368
|
except subprocess.CalledProcessError as e:
|
|
344
369
|
raise click.ClickException(f"SDK start failed while running: {' '.join(e.cmd)}") from e
|
|
345
370
|
except RuntimeError as e:
|
|
@@ -636,6 +661,27 @@ def neat(ctx, cmd):
|
|
|
636
661
|
launch_sdk_tool("neat", cmd, ctx, recover_unavailable=True)
|
|
637
662
|
|
|
638
663
|
|
|
664
|
+
@sdk.command(
|
|
665
|
+
name="ros2",
|
|
666
|
+
context_settings={"ignore_unknown_options": True, "allow_extra_args": True}
|
|
667
|
+
)
|
|
668
|
+
@click.argument("cmd", nargs=-1, type=click.UNPROCESSED)
|
|
669
|
+
@click.pass_context
|
|
670
|
+
def ros2(ctx, cmd):
|
|
671
|
+
"""Launch the ROS 2 SDK workspace environment.
|
|
672
|
+
|
|
673
|
+
Use ``sima-cli sdk -v VERSION ros2`` to select among multiple installed
|
|
674
|
+
versions. CMD is executed in the container; without CMD an interactive
|
|
675
|
+
login shell is opened as the mapped host user.
|
|
676
|
+
|
|
677
|
+
\b
|
|
678
|
+
Examples:
|
|
679
|
+
sima-cli sdk ros2
|
|
680
|
+
sima-cli sdk -v latest ros2 ros2 --help
|
|
681
|
+
"""
|
|
682
|
+
launch_sdk_tool("ros2", cmd, ctx)
|
|
683
|
+
|
|
684
|
+
|
|
639
685
|
@sdk.command(
|
|
640
686
|
name="elxr",
|
|
641
687
|
context_settings={"ignore_unknown_options": True, "allow_extra_args": True}
|
|
@@ -27,6 +27,11 @@ IMAGE_CONFIG = {
|
|
|
27
27
|
"port_mapping_required": False,
|
|
28
28
|
"var-log-folders": ["sima", "supervisor"]
|
|
29
29
|
},
|
|
30
|
+
"ros2": {
|
|
31
|
+
"display": "ROS 2 SDK",
|
|
32
|
+
"privileged": False,
|
|
33
|
+
"port_mapping_required": False
|
|
34
|
+
},
|
|
30
35
|
"modelsdk": {
|
|
31
36
|
"display": "ModelSDK",
|
|
32
37
|
"privileged": False,
|