sima-cli 2.1.16__tar.gz → 2.1.18__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.
Files changed (213) hide show
  1. {sima_cli-2.1.16/sima_cli.egg-info → sima_cli-2.1.18}/PKG-INFO +4 -1
  2. {sima_cli-2.1.16 → sima_cli-2.1.18}/README.md +2 -0
  3. {sima_cli-2.1.16 → sima_cli-2.1.18}/pyproject.toml +2 -1
  4. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/__version__.py +1 -1
  5. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/cli.py +262 -54
  6. sima_cli-2.1.18/sima_cli/cloudex/__init__.py +5 -0
  7. sima_cli-2.1.18/sima_cli/cloudex/client.py +886 -0
  8. sima_cli-2.1.18/sima_cli/cloudex/commands.py +422 -0
  9. sima_cli-2.1.18/sima_cli/cloudex/installer.py +164 -0
  10. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/deploy_only/device/commands.py +1 -1
  11. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/discover/discover.py +91 -9
  12. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/download/downloader.py +2 -0
  13. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/metadata_installer.py +28 -11
  14. sima_cli-2.1.18/sima_cli/models/__init__.py +3 -0
  15. sima_cli-2.1.18/sima_cli/models/client.py +600 -0
  16. sima_cli-2.1.18/sima_cli/models/commands.py +320 -0
  17. sima_cli-2.1.18/sima_cli/models/rendering.py +654 -0
  18. sima_cli-2.1.18/sima_cli/network/network.py +636 -0
  19. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/commands.py +66 -25
  20. sima_cli-2.1.18/sima_cli/sdk/docker_staging.py +22 -0
  21. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/install.py +111 -14
  22. sima_cli-2.1.18/sima_cli/sdk/model_compiler.py +140 -0
  23. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/neat.py +43 -0
  24. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/network_doctor.py +37 -2
  25. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/preinstall.py +123 -5
  26. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/utils.py +444 -130
  27. sima_cli-2.1.18/sima_cli/sdk/vscode_extensions.py +197 -0
  28. sima_cli-2.1.18/sima_cli/update/ab_state.py +111 -0
  29. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/bootimg.py +7 -2
  30. sima_cli-2.1.18/sima_cli/update/emmc.py +68 -0
  31. sima_cli-2.1.18/sima_cli/update/fast_upload.py +79 -0
  32. sima_cli-2.1.18/sima_cli/update/host.py +231 -0
  33. sima_cli-2.1.18/sima_cli/update/netboot.py +1354 -0
  34. sima_cli-2.1.18/sima_cli/update/netboot_artifacts.py +194 -0
  35. sima_cli-2.1.18/sima_cli/update/netboot_device.py +483 -0
  36. sima_cli-2.1.18/sima_cli/update/overlay.py +348 -0
  37. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/query.py +110 -22
  38. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/remote.py +52 -32
  39. sima_cli-2.1.18/sima_cli/update/rootfs.py +90 -0
  40. sima_cli-2.1.18/sima_cli/update/staging.py +76 -0
  41. sima_cli-2.1.18/sima_cli/update/swu.py +691 -0
  42. sima_cli-2.1.18/sima_cli/update/swu_artifacts.py +286 -0
  43. sima_cli-2.1.18/sima_cli/update/swu_certificate.py +57 -0
  44. sima_cli-2.1.18/sima_cli/update/swu_target.py +85 -0
  45. sima_cli-2.1.18/sima_cli/update/uboot_environment.py +108 -0
  46. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/updater.py +139 -32
  47. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/pkg_update_check.py +3 -1
  48. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/vulcan/artifacts.py +1 -0
  49. {sima_cli-2.1.16 → sima_cli-2.1.18/sima_cli.egg-info}/PKG-INFO +4 -1
  50. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli.egg-info/SOURCES.txt +59 -0
  51. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli.egg-info/requires.txt +1 -0
  52. sima_cli-2.1.18/tests/unit/test_ab_overlay.py +124 -0
  53. sima_cli-2.1.18/tests/unit/test_bootimg_defaults.py +37 -0
  54. sima_cli-2.1.18/tests/unit/test_bootimg_recovery.py +118 -0
  55. sima_cli-2.1.18/tests/unit/test_cli_update.py +150 -0
  56. sima_cli-2.1.18/tests/unit/test_cloudex_client.py +647 -0
  57. sima_cli-2.1.18/tests/unit/test_cloudex_commands.py +370 -0
  58. sima_cli-2.1.18/tests/unit/test_cloudex_installer.py +110 -0
  59. sima_cli-2.1.18/tests/unit/test_device_discovery_cloudex.py +113 -0
  60. sima_cli-2.1.18/tests/unit/test_emmc.py +110 -0
  61. sima_cli-2.1.18/tests/unit/test_fast_upload.py +49 -0
  62. sima_cli-2.1.18/tests/unit/test_firmware_creation_order.py +65 -0
  63. sima_cli-2.1.18/tests/unit/test_firmware_layout.py +66 -0
  64. sima_cli-2.1.18/tests/unit/test_firmware_selector.py +64 -0
  65. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_generate_cli_markdown_docs.py +10 -8
  66. sima_cli-2.1.18/tests/unit/test_host_update.py +254 -0
  67. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_install_stub.py +69 -4
  68. sima_cli-2.1.18/tests/unit/test_localized_docs_links.py +23 -0
  69. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_metadata_installer.py +137 -13
  70. sima_cli-2.1.18/tests/unit/test_models.py +1187 -0
  71. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_netboot.py +9 -1
  72. sima_cli-2.1.18/tests/unit/test_netboot_autoflash.py +54 -0
  73. sima_cli-2.1.18/tests/unit/test_netboot_device.py +658 -0
  74. sima_cli-2.1.18/tests/unit/test_netboot_images.py +344 -0
  75. sima_cli-2.1.18/tests/unit/test_netboot_ip_recovery.py +129 -0
  76. sima_cli-2.1.18/tests/unit/test_netboot_mirror.py +191 -0
  77. sima_cli-2.1.18/tests/unit/test_netboot_trootctl.py +96 -0
  78. sima_cli-2.1.18/tests/unit/test_network_custom_static.py +271 -0
  79. sima_cli-2.1.18/tests/unit/test_network_safety.py +152 -0
  80. sima_cli-2.1.18/tests/unit/test_overlay.py +309 -0
  81. sima_cli-2.1.18/tests/unit/test_palette_image_discovery.py +78 -0
  82. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_pkg_update_check.py +25 -0
  83. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_sdk_image_detection.py +895 -60
  84. sima_cli-2.1.18/tests/unit/test_sdk_model_compiler.py +282 -0
  85. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_sdk_network_doctor.py +36 -0
  86. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_sdk_preinstall.py +146 -0
  87. sima_cli-2.1.18/tests/unit/test_swu.py +955 -0
  88. sima_cli-2.1.18/tests/unit/test_swu_certificate.py +208 -0
  89. sima_cli-2.1.18/tests/unit/test_swu_errors.py +162 -0
  90. sima_cli-2.1.18/tests/unit/test_swu_mirror.py +349 -0
  91. sima_cli-2.1.18/tests/unit/test_swu_target.py +58 -0
  92. sima_cli-2.1.18/tests/unit/test_uboot_environment.py +98 -0
  93. sima_cli-2.1.18/tests/unit/test_update_staging.py +111 -0
  94. sima_cli-2.1.18/tests/unit/test_vscode_extension_pins.py +363 -0
  95. sima_cli-2.1.16/sima_cli/network/network.py +0 -307
  96. sima_cli-2.1.16/sima_cli/update/netboot.py +0 -558
  97. sima_cli-2.1.16/tests/unit/test_cli_update.py +0 -76
  98. {sima_cli-2.1.16 → sima_cli-2.1.18}/LICENSE +0 -0
  99. {sima_cli-2.1.16 → sima_cli-2.1.18}/MANIFEST.in +0 -0
  100. {sima_cli-2.1.16 → sima_cli-2.1.18}/requirements.txt +0 -0
  101. {sima_cli-2.1.16 → sima_cli-2.1.18}/setup.cfg +0 -0
  102. {sima_cli-2.1.16 → sima_cli-2.1.18}/setup.py +0 -0
  103. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/__init__.py +0 -0
  104. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/__main__.py +0 -0
  105. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/app_zoo/__init__.py +0 -0
  106. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/app_zoo/app.py +0 -0
  107. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/app_zoo/commands.py +0 -0
  108. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/auth/__init__.py +0 -0
  109. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/auth/auth0.py +0 -0
  110. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/auth/devportal.py +0 -0
  111. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/auth/login.py +0 -0
  112. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/data/__init__.py +0 -0
  113. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/data/resources_internal.yaml +0 -0
  114. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/data/resources_public.yaml +0 -0
  115. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/deploy_only/__init__.py +0 -0
  116. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/deploy_only/device/__init__.py +0 -0
  117. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/deploy_only/mpk/__init__.py +0 -0
  118. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/deploy_only/mpk/commands.py +0 -0
  119. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/discover/__init__.py +0 -0
  120. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/discover/linuxll.py +0 -0
  121. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/download/__init__.py +0 -0
  122. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/__init__.py +0 -0
  123. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/compatibility.py +0 -0
  124. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/github_assets.py +0 -0
  125. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/hostdriver.py +0 -0
  126. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/metadata_info.py +0 -0
  127. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/metadata_validator.py +0 -0
  128. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/optiview.py +0 -0
  129. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/package_builder.py +0 -0
  130. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/palette.py +0 -0
  131. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/install/registry.py +0 -0
  132. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/mla/__init__.py +0 -0
  133. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/mla/meminfo.py +0 -0
  134. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/model_zoo/__init__.py +0 -0
  135. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/model_zoo/model.py +0 -0
  136. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/network/__init__.py +0 -0
  137. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/playbooks/__init__.py +0 -0
  138. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/playbooks/commands.py +0 -0
  139. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/playbooks/manager.py +0 -0
  140. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/__init__.py +0 -0
  141. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/cmdexec.py +0 -0
  142. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/config.py +0 -0
  143. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/linux_devkit_network.py +0 -0
  144. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/linux_shared_network.py +0 -0
  145. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/requirements.json +0 -0
  146. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/script.py +0 -0
  147. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/stop.py +0 -0
  148. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/sdk/uninstall.py +0 -0
  149. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/serial/__init__.py +0 -0
  150. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/serial/serial.py +0 -0
  151. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/storage/__init__.py +0 -0
  152. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/storage/nvme.py +0 -0
  153. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/storage/sdcard.py +0 -0
  154. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/__init__.py +0 -0
  155. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/bmaptool.py +0 -0
  156. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/cleanlog.py +0 -0
  157. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/elxr.py +0 -0
  158. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/update/local.py +0 -0
  159. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/upgrade/__init__.py +0 -0
  160. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/upgrade/selfupdate.py +0 -0
  161. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/__init__.py +0 -0
  162. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/api_common.py +0 -0
  163. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/artifactory.py +0 -0
  164. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/common.py +0 -0
  165. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/config.py +0 -0
  166. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/config_loader.py +0 -0
  167. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/container_registries.py +0 -0
  168. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/deprecation.py +0 -0
  169. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/device_api.py +0 -0
  170. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/disk.py +0 -0
  171. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/docker.py +0 -0
  172. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/env.py +0 -0
  173. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/errors.py +0 -0
  174. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/mpk_api.py +0 -0
  175. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/net.py +0 -0
  176. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/network.py +0 -0
  177. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/pcie.py +0 -0
  178. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/serializers.py +0 -0
  179. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/services.py +0 -0
  180. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/utils/tag.py +0 -0
  181. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/vulcan/__init__.py +0 -0
  182. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli/vulcan/commands.py +0 -0
  183. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli.egg-info/dependency_links.txt +0 -0
  184. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli.egg-info/entry_points.txt +0 -0
  185. {sima_cli-2.1.16 → sima_cli-2.1.18}/sima_cli.egg-info/top_level.txt +0 -0
  186. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/__init__.py +0 -0
  187. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/e2e/__init__.py +0 -0
  188. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/__init__.py +0 -0
  189. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_app_zoo.py +0 -0
  190. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_appzoo_commands.py +0 -0
  191. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_auth.py +0 -0
  192. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_auth0.py +0 -0
  193. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_cli.py +0 -0
  194. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_cli_stdio.py +0 -0
  195. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_cli_update_rerun.py +0 -0
  196. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_container_registries.py +0 -0
  197. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_deprecation.py +0 -0
  198. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_docker_utils.py +0 -0
  199. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_download.py +0 -0
  200. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_elxr_update.py +0 -0
  201. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_firmware.py +0 -0
  202. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_metadata_validator.py +0 -0
  203. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_model_zoo.py +0 -0
  204. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_modelzoo_commands.py +0 -0
  205. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_package_builder.py +0 -0
  206. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_pcie.py +0 -0
  207. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_sdk_linux_shared_network.py +0 -0
  208. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_sdk_uninstall.py +0 -0
  209. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_selfupdate.py +0 -0
  210. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_skills_commands.py +0 -0
  211. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_skills_manager.py +0 -0
  212. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_utils.py +0 -0
  213. {sima_cli-2.1.16 → sima_cli-2.1.18}/tests/unit/test_vulcan.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sima-cli
3
- Version: 2.1.16
3
+ Version: 2.1.18
4
4
  Summary: CLI tool for SiMa Developer Portal to download models, firmware, and apps.
5
5
  Home-page: https://community.sima.ai/
6
6
  Author: SiMa.ai
@@ -21,6 +21,7 @@ Requires-Dist: requests<3.0,>=2.32.4
21
21
  Requires-Dist: tqdm>=4.64
22
22
  Requires-Dist: pyyaml>=6.0
23
23
  Requires-Dist: paramiko>=3.5.1
24
+ Requires-Dist: cryptography>=3.3
24
25
  Requires-Dist: plotext==5.3.2
25
26
  Requires-Dist: rich==14.0.0
26
27
  Requires-Dist: InquirerPy==0.3.4
@@ -34,6 +35,8 @@ Dynamic: requires-python
34
35
 
35
36
  # sima-cli - SiMa Developer Portal CLI Tool
36
37
 
38
+ **Documentation:** [English](docs/sima-cli/index.md) | [한국어](docs/i18n/ko/sima-cli/index.md) | [日本語](docs/i18n/ja/sima-cli/index.md) | [繁體中文](docs/i18n/zh-Hant/sima-cli/index.md) | [Українська](docs/i18n/uk/sima-cli/index.md)
39
+
37
40
  [![Python 3.8](https://img.shields.io/github/actions/workflow/status/sima-neat/sima-cli/vulcan-ci.yml?branch=main&job=Compatibility%20Python%203.8&label=python%203.8)](https://github.com/sima-neat/sima-cli/actions/workflows/vulcan-ci.yml)
38
41
  [![Python 3.9](https://img.shields.io/github/actions/workflow/status/sima-neat/sima-cli/vulcan-ci.yml?branch=main&job=Compatibility%20Python%203.9&label=python%203.9)](https://github.com/sima-neat/sima-cli/actions/workflows/vulcan-ci.yml)
39
42
  [![Python 3.10](https://img.shields.io/github/actions/workflow/status/sima-neat/sima-cli/vulcan-ci.yml?branch=main&job=Compatibility%20Python%203.10&label=python%203.10)](https://github.com/sima-neat/sima-cli/actions/workflows/vulcan-ci.yml)
@@ -1,5 +1,7 @@
1
1
  # sima-cli - SiMa Developer Portal CLI Tool
2
2
 
3
+ **Documentation:** [English](docs/sima-cli/index.md) | [한국어](docs/i18n/ko/sima-cli/index.md) | [日本語](docs/i18n/ja/sima-cli/index.md) | [繁體中文](docs/i18n/zh-Hant/sima-cli/index.md) | [Українська](docs/i18n/uk/sima-cli/index.md)
4
+
3
5
  [![Python 3.8](https://img.shields.io/github/actions/workflow/status/sima-neat/sima-cli/vulcan-ci.yml?branch=main&job=Compatibility%20Python%203.8&label=python%203.8)](https://github.com/sima-neat/sima-cli/actions/workflows/vulcan-ci.yml)
4
6
  [![Python 3.9](https://img.shields.io/github/actions/workflow/status/sima-neat/sima-cli/vulcan-ci.yml?branch=main&job=Compatibility%20Python%203.9&label=python%203.9)](https://github.com/sima-neat/sima-cli/actions/workflows/vulcan-ci.yml)
5
7
  [![Python 3.10](https://img.shields.io/github/actions/workflow/status/sima-neat/sima-cli/vulcan-ci.yml?branch=main&job=Compatibility%20Python%203.10&label=python%203.10)](https://github.com/sima-neat/sima-cli/actions/workflows/vulcan-ci.yml)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sima-cli"
7
- version = "2.1.16"
7
+ version = "2.1.18"
8
8
  description = "CLI tool for SiMa Developer Portal to download models, firmware, and apps."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -27,6 +27,7 @@ dependencies = [
27
27
  "tqdm>=4.64",
28
28
  "pyyaml>=6.0",
29
29
  "paramiko>=3.5.1",
30
+ "cryptography>=3.3",
30
31
  "plotext==5.3.2",
31
32
  "rich==14.0.0",
32
33
  "InquirerPy==0.3.4",
@@ -1,2 +1,2 @@
1
1
  # sima_cli/__version__.py
2
- __version__ = "2.1.16"
2
+ __version__ = "2.1.18"
@@ -1,12 +1,16 @@
1
1
  import os
2
2
  import shutil
3
3
  import sys
4
+ from contextlib import nullcontext, redirect_stdout
5
+ from pathlib import Path
4
6
  import click
5
7
  from rich.console import Console
6
8
  from rich.panel import Panel
7
9
  from rich.text import Text
8
10
  from sima_cli.utils.env import get_environment_type
9
11
  from sima_cli.update.updater import perform_update
12
+ from sima_cli.update.host import install_host_package
13
+ from sima_cli.update.swu import handle_update
10
14
  from sima_cli.model_zoo.model import list_models, download_model, describe_model
11
15
  from sima_cli.app_zoo.app import list_apps, download_app, describe_app
12
16
  from sima_cli.utils.config_loader import internal_resource_exists
@@ -37,6 +41,8 @@ from sima_cli.install.registry import register_packages_commands
37
41
  from sima_cli.upgrade.selfupdate import register_selfupdate_command
38
42
  from sima_cli.playbooks import register_playbook_commands
39
43
  from sima_cli.vulcan import register_vulcan_commands
44
+ from sima_cli.models import register_models_commands
45
+ from sima_cli.cloudex import register_cloudex_commands
40
46
  from sima_cli.vulcan.commands import (
41
47
  ENV_METAVAR,
42
48
  _environment_shortcut_options,
@@ -99,19 +105,7 @@ def _rerun_current_command() -> None:
99
105
  os.execvpe(sys.executable, cmd, env)
100
106
 
101
107
 
102
- # Entry point for the CLI tool using Click's command group decorator
103
- @click.group(context_settings=dict(help_option_names=["-h", "--help", "-?"], max_content_width=120))
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.")
106
- @click.version_option(version=f"{__version__}", message="SiMa CLI version: %(version)s")
107
- @click.pass_context
108
- def main(ctx, internal, yes):
109
- """
110
- sima-cli – SiMa Developer Portal CLI Tool
111
-
112
- Global Options:
113
- --internal Use internal Artifactory resources (can also be set via env variable SIMA_CLI_INTERNAL=1)
114
- """
108
+ def _initialize_main_context(ctx, internal, yes):
115
109
  _configure_stdio_errors()
116
110
  auto_accept_update = yes or _update_auto_confirm_requested(sys.argv)
117
111
  previous_auto_accept = os.environ.get("SIMA_CLI_AUTO_ACCEPT_UPDATE")
@@ -134,26 +128,26 @@ def main(ctx, internal, yes):
134
128
  if not internal:
135
129
  internal = os.getenv("SIMA_CLI_INTERNAL", "0") in ("1", "true", "yes")
136
130
 
137
- if internal and not internal_resource_exists():
138
- click.echo("❌ You have specified -i or --internal argument to access internal resources, but you do not have an internal resource map configured.")
131
+ defer_artifactory_access = ctx.invoked_subcommand == "update" or ctx.meta.get("daily_netboot", False)
132
+ if internal and not internal_resource_exists() and not defer_artifactory_access:
133
+ click.echo("❌ You have specified -i or --internal argument to access internal resources, but you do not have an internal resource map configured.")
139
134
  click.echo("Refer to the confluence page to find out how to configure internal resource map.")
140
- exit(0)
135
+ exit(0)
141
136
 
142
137
  internal_reachable = True
143
138
  if internal:
144
139
  internal_reachable = check_artifactory_reachability()
145
140
 
146
- if internal and not internal_reachable and not _allows_external_prerelease_fallback(sys.argv):
141
+ if internal and not internal_reachable and not defer_artifactory_access and not _allows_external_prerelease_fallback(sys.argv):
147
142
  click.secho("❌ You have specified -i or --internal argument to access internal resources, but you can't connect to Artifactory.", fg='red')
148
143
  click.secho("Please make sure you are connected to VPN or are on the corporate network.", fg='red')
149
144
  exit(0)
150
145
 
151
- if internal and not internal_reachable:
146
+ if internal and not internal_reachable and not defer_artifactory_access:
152
147
  click.secho(
153
148
  "⚠️ Internal resources are unreachable. --force allows this update to use the external pre-release mirror.",
154
149
  fg="yellow",
155
150
  )
156
-
157
151
 
158
152
  ctx.obj["internal"] = internal
159
153
  ctx.obj["internal_reachable"] = internal_reachable
@@ -167,12 +161,62 @@ def main(ctx, internal, yes):
167
161
  click.echo(f"🔧 Environment: {env_type} ({env_subtype})")
168
162
 
169
163
 
164
+ class InspectionAwareGroup(click.Group):
165
+ def parse_args(self, ctx, args):
166
+ # Capture the actual Click arguments (also works with CliRunner), before
167
+ # the root callback can perform a CLI self-update or network login.
168
+ options = args[:args.index('--')] if '--' in args else args
169
+ ctx.meta['daily_netboot'] = (
170
+ _command_name_from_argv(['sima-cli'] + options) == 'bootimg'
171
+ and any(arg in ('--netboot', '-n', '--autoflash', '-a') for arg in options)
172
+ )
173
+ if _command_name_from_argv(['sima-cli'] + options) == 'update' and '--inspect' in options:
174
+ ctx.meta['update_inspect'] = True
175
+ return super().parse_args(ctx, args)
176
+
177
+
178
+ # Entry point for the CLI tool using Click's command group decorator
179
+ @click.group(cls=InspectionAwareGroup, context_settings=dict(help_option_names=["-h", "--help", "-?"], max_content_width=120))
180
+ @click.option('-i', '--internal', is_flag=True, help="Use internal Artifactory resources, Authorized Sima employees only")
181
+ @click.option('-y', '--yes', is_flag=True, help="Assume yes for confirmation prompts.")
182
+ @click.version_option(version=f"{__version__}", message="SiMa CLI version: %(version)s")
183
+ @click.pass_context
184
+ def main(ctx, internal, yes):
185
+ """
186
+ sima-cli – SiMa Developer Portal CLI Tool
187
+
188
+ Global Options:
189
+ --internal Use internal Artifactory resources (can also be set via env variable SIMA_CLI_INTERNAL=1)
190
+ """
191
+ internal = internal or os.getenv("SIMA_CLI_INTERNAL", "0") in ("1", "true", "yes")
192
+ if internal:
193
+ Console(stderr=True).print(Panel(
194
+ Text("Pre-release software may be unstable. Use at your own risk.", style="yellow"),
195
+ title="Pre-release software", border_style="yellow", width=72,
196
+ ))
197
+ if ctx.meta.get('update_inspect'):
198
+ ctx.ensure_object(dict)
199
+ ctx.obj.update(internal=internal, yes=yes)
200
+ return
201
+ # Model Registry JSON must remain parseable on stdout. Route root-level
202
+ # update and environment diagnostics to stderr for this command group.
203
+ output_context = (
204
+ redirect_stdout(sys.stderr)
205
+ if ctx.invoked_subcommand == "models"
206
+ else nullcontext()
207
+ )
208
+ with output_context:
209
+ _initialize_main_context(ctx, internal, yes)
210
+
211
+
170
212
  # ----------------------
171
213
  # SDK Command
172
214
  # ----------------------
173
215
  register_sdk_commands(main)
174
216
  register_playbook_commands(main)
175
217
  register_vulcan_commands(main)
218
+ register_models_commands(main)
219
+ register_cloudex_commands(main)
176
220
 
177
221
 
178
222
  # ----------------------
@@ -274,7 +318,7 @@ def download(ctx, url, dest):
274
318
  @click.option(
275
319
  "-y", "--yes",
276
320
  is_flag=True,
277
- help="Assume yes for update confirmation prompts."
321
+ help="Assume yes for update confirmation prompts and select the newest matching full-system build."
278
322
  )
279
323
  @click.option(
280
324
  "-p", "--passwd",
@@ -294,7 +338,8 @@ def download(ctx, url, dest):
294
338
  is_flag=True,
295
339
  help=(
296
340
  "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)."
341
+ "(eLxr only). eLxr 3.0+ still verifies signed full-system bundles. "
342
+ "On eLxr 2.1, this disables repository signature verification and, without --internal, selects the mirror directly."
298
343
  )
299
344
  )
300
345
  @click.option(
@@ -307,18 +352,40 @@ def download(ctx, url, dest):
307
352
  "--dryrun",
308
353
  is_flag=True,
309
354
  default=False,
310
- help="For ELXR updates only, validate the update path and print the simaai-ota command without running it."
355
+ help="For eLxr updates, validate the update path and show the command without installing."
311
356
  )
357
+ @click.option("--inspect", "inspect_state", is_flag=True, help="Show eLxr 3.0+ A/B slots and overlay customizations without updating (local or --ip).")
358
+ @click.option("--verbose", is_flag=True, help="Show detailed overlay file categories during eLxr 3.0+ inspection or update.")
359
+ @click.option("--signing-cert", metavar="URL_OR_FILE", help="SWUpdate PEM verification certificate: HTTP(S) URL or local file. Defaults to the certificate for the selected channel when configured (eLxr 3.0+).")
360
+ @click.option("--reboot", is_flag=True, help="Reboot after successful eLxr 3.0+ installation; verify remote boot health.")
312
361
  @click.pass_context
313
- def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force, troot_only, dryrun):
362
+ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force, troot_only, dryrun, inspect_state, verbose, reboot, signing_cert):
314
363
  """
315
- Update the software on a SiMa DevKit or remote SiMa device.
364
+ Update a SiMa DevKit, remote device, or Linux PCIe host.
316
365
 
317
366
  This command downloads and applies system software updates across
318
367
  different SiMa environments (Modalix, MLSoC/Davinci, headless images,
319
368
  or remote devices accessible over the network). Updates may be
320
369
  installed directly on the device or pushed from a development host.
321
370
 
371
+ eLxr 3.0+ uses signed full-system SWU bundles. Use --inspect for A/B
372
+ state, --ip for remote updates, and --reboot to reboot after installation.
373
+ The verification certificate is downloaded for the selected channel when configured; use
374
+ --signing-cert URL_OR_FILE for an image signed with your own certificate.
375
+ Developer-portal version lookup for 3.0 is not available yet.
376
+
377
+ Internal mode warns that pre-release software may be unstable and is used
378
+ at your own risk. On eLxr 3.0+, unavailable Artifactory access falls back
379
+ to the public daily platform mirror, including missing login, HTTP 401/403,
380
+ connection failures, timeouts, and server errors. Exact build names select
381
+ directly; partial matches show builds newest first by build number.
382
+
383
+ Mirror downloads verify the indexed size and SHA-256 before signed
384
+ installation. A missing build or failed download stops before installation.
385
+ A connection loss after installation starts requires inspecting the board
386
+ before retrying. Devices running eLxr 2.1.3 retain the APT update flow;
387
+ upgrading those devices to 3.0 requires recovery/provisioning first.
388
+
322
389
  How Version Resolution Works:
323
390
 
324
391
  • If a version string is provided (e.g., ``1.7.0``), sima-cli automatically resolves it to the correct downloadable firmware asset based on channel, flavor, and board type.
@@ -335,6 +402,9 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force,
335
402
 
336
403
  • Remote updates require an accessible IP address (``--ip``)
337
404
 
405
+ • PCIe host updates require Linux and ``-i/--internal``; omit the
406
+ version to choose from the available daily platform builds
407
+
338
408
  Typical Use Cases:
339
409
 
340
410
  • Updating a SiMa DevKit to the latest GA release
@@ -345,6 +415,8 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force,
345
415
 
346
416
  • Running updates from both the device itself or a host PC
347
417
 
418
+ • Installing a daily PCIe host package on a Linux development host
419
+
348
420
  \b
349
421
  Examples:
350
422
 
@@ -368,7 +440,7 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force,
368
440
 
369
441
  sima-cli update -v 1.7.0 -y
370
442
 
371
- # Update ELXR to the latest official release without prompts
443
+ # Update legacy eLxr (<3.0) to the latest official release without prompts
372
444
 
373
445
  sima-cli update -y
374
446
 
@@ -376,11 +448,19 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force,
376
448
 
377
449
  sima-cli -i update -y
378
450
 
379
- # Update ELXR from the public pre-release mirror without prompts
451
+ # Select and install a PCIe host package from the daily build catalog (Linux only)
452
+
453
+ sima-cli -i update
454
+
455
+ # Or install a specific indexed daily platform build
456
+
457
+ sima-cli -i update -v 3.0.0_daily_develop_B1774
458
+
459
+ # Update legacy eLxr (<3.0) from the public pre-release mirror without prompts
380
460
 
381
461
  sima-cli -y update -f -y
382
462
 
383
- # Validate ELXR update path without running simaai-ota
463
+ # Validate the eLxr update path without installing
384
464
 
385
465
  sima-cli update --dryrun
386
466
 
@@ -391,7 +471,54 @@ def update(ctx, version_or_url, version_option, ip, yes, passwd, flavor, force,
391
471
  """
392
472
  # Prioritize explicit --version option over positional argument
393
473
  version_or_url = version_option or version_or_url
474
+ env_type, env_subtype = get_environment_type()
475
+ internal = ctx.obj.get("internal", False)
476
+ auto_confirm = yes or ctx.obj.get("yes", False)
477
+
478
+ device_update_options = (
479
+ dryrun
480
+ or troot_only
481
+ or inspect_state
482
+ or verbose
483
+ or reboot
484
+ or force
485
+ or signing_cert is not None
486
+ or flavor != "auto"
487
+ )
488
+ # A plain update with no remote target means installing the PCIe host
489
+ # package. Device-specific operations continue to the existing dispatcher.
490
+ if env_type == "host" and not ip and not device_update_options:
491
+ if env_subtype != "linux":
492
+ raise click.UsageError("PCIe host updates are only supported on Linux hosts.")
493
+ if not internal:
494
+ raise click.UsageError("Linux PCIe host updates require -i/--internal.")
495
+ install_host_package(version_or_url, auto_confirm=auto_confirm)
496
+ return
497
+
394
498
  is_elxr = is_devkit_running_elxr()
499
+ if inspect_state and (version_or_url or dryrun or force or troot_only or reboot or signing_cert is not None or flavor != 'auto'):
500
+ raise click.UsageError("--inspect cannot be combined with installation options.")
501
+ try:
502
+ if handle_update(version_or_url, ip=ip, passwd=passwd,
503
+ internal=ctx.obj.get("internal", False),
504
+ auto_confirm=yes or ctx.obj.get("yes", False), dryrun=dryrun,
505
+ signing_cert=signing_cert, reboot=reboot, inspect=inspect_state, force=force,
506
+ troot_only=troot_only, flavor=flavor, local_elxr=is_elxr, verbose=verbose):
507
+ return
508
+ except (click.ClickException, click.Abort):
509
+ raise
510
+ except Exception as exc:
511
+ raise click.ClickException(str(exc)) from exc
512
+
513
+ # Legacy updates retain their original access/--force policy after dispatch.
514
+ if ctx.obj.get("internal", False):
515
+ if not internal_resource_exists():
516
+ raise click.ClickException("Internal resources are not configured on this machine.")
517
+ if not ctx.obj.get("internal_reachable", True) and not force:
518
+ raise click.ClickException(
519
+ "Artifactory is unreachable. Connect to VPN or the corporate network. "
520
+ "Automatic daily SWU fallback requires a device already running eLxr 3.0+."
521
+ )
395
522
 
396
523
  if dryrun and not is_elxr:
397
524
  raise click.ClickException("--dryrun is only supported when running update on an ELXR devkit.")
@@ -513,15 +640,24 @@ def show_mla_memory_usage(ctx):
513
640
  # bootimg Command
514
641
  # ----------------------
515
642
  @main.command(name="bootimg")
516
- @click.option("-v", "--version", required=True, help="Firmware version to download and write (e.g., 1.6.0)")
517
- @click.option("-b", "--boardtype", type=click.Choice(["modalix", "mlsoc"], case_sensitive=False), default="mlsoc", show_default=True, help="Target board type.")
518
- @click.option("-t", "--fwtype", type=click.Choice(["yocto", "elxr"], case_sensitive=False), default="yocto", show_default=True, help="Target firmware type.")
643
+ @click.option("-v", "--version", required=False, help="Firmware version to download and write (e.g., 1.6.0)")
644
+ @click.option("-b", "--boardtype", type=click.Choice(["modalix", "mlsoc"], case_sensitive=False), default="modalix", show_default=True, help="Target board type.")
645
+ @click.option("-t", "--fwtype", type=click.Choice(["yocto", "elxr"], case_sensitive=False), default="elxr", show_default=True, help="Target firmware type.")
519
646
  @click.option("-n", "--netboot", is_flag=True, default=False, show_default=True, help="Prepare image for network boot and launch TFTP server.")
520
- @click.option("--devkit-ip", required=False, help="Optional DevKit IP address for pre-netboot version probing.")
647
+ @click.option(
648
+ "--images",
649
+ type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True, path_type=Path),
650
+ help="Directory containing local netboot source images.",
651
+ )
652
+ @click.option("--delete-cache", is_flag=True, help="Delete the managed netboot cache after the session exits.")
653
+ @click.option("-f", "--force", is_flag=True, help="Allow daily mirror fallback if Artifactory is unavailable (internal Modalix eLxr netboot only).")
654
+ @click.option("--recovery", is_flag=True, help="Write eLxr Modalix recovery media for automatic eMMC recovery.")
655
+ @click.option("--devkit", "--devkit-ip", "devkit_ip", required=False, help="DevKit IP for remote netboot; discover and select a DevKit when omitted.")
521
656
  @click.option("-r", "--rootfs", required=False, help="Custom root fs folders (internal use only)")
522
- @click.option("-a", "--autoflash", is_flag=True, default=False, show_default=True, help="Net boot the DevKit and automatically flash the internal storage - TBD")
657
+ @click.option("-a", "--autoflash", is_flag=True, default=False, show_default=True, help="Network boot the selected DevKit, then automatically flash its internal storage once SSH is ready.")
523
658
  @click.pass_context
524
- def bootimg_cmd(ctx, version, boardtype, netboot, devkit_ip, autoflash, fwtype, rootfs):
659
+ def bootimg_cmd(ctx, version, boardtype, netboot, images, delete_cache, devkit_ip,
660
+ autoflash, fwtype, rootfs, recovery=False, force=False):
525
661
  """
526
662
  Prepare a bootable image for the SiMa DevKit.
527
663
 
@@ -530,6 +666,10 @@ def bootimg_cmd(ctx, version, boardtype, netboot, devkit_ip, autoflash, fwtype,
530
666
  network boot environment. It supports both MLSoC- and Modalix-based
531
667
  DevKits, as well as Yocto and eLxr firmware types.
532
668
 
669
+ Matching internal builds appear in aligned Version and Build time (UTC)
670
+ columns, newest first. Build time uses the newest Artifactory archive
671
+ creation timestamp for each version. Unknown timestamps appear last.
672
+
533
673
  Operations Performed:
534
674
 
535
675
  • Download the correct firmware bundle for the selected version
@@ -550,32 +690,78 @@ def bootimg_cmd(ctx, version, boardtype, netboot, devkit_ip, autoflash, fwtype,
550
690
 
551
691
  • Automating eMMC flashing over the network
552
692
 
693
+ Local Images and Cache:
694
+
695
+ • Use ``--images DIRECTORY`` to recursively discover local netboot
696
+ artifacts. eLxr requires a minimal TFTP archive and an eMMC
697
+ ``.img.gz``; Yocto requires a release archive.
698
+
699
+ • The supplied directory remains read-only. Prepared content is cached
700
+ under the platform temporary directory in ``sima-cli/netboot`` and is
701
+ reused by default. ``--delete-cache`` removes only the managed cache
702
+ entry after the session exits.
703
+
553
704
  \b
554
705
  Examples:
555
706
 
556
707
  # Write an SD card image for an MLSoC DevKit
557
708
 
558
- sima-cli bootimg -v 1.6.0 --boardtype mlsoc
709
+ sima-cli bootimg -v 1.6.0 --boardtype mlsoc --fwtype yocto
559
710
 
560
711
  # Set up netboot for a Modalix DevKit
561
712
 
562
- sima-cli bootimg -v 1.6.0 --boardtype modalix --netboot
713
+ sima-cli bootimg -v 3.0.0 --netboot
714
+
715
+ # Select a DevKit for confirmed remote U-Boot setup and reboot
716
+
717
+ sima-cli bootimg -v 3.0.0 --netboot --devkit-ip 192.168.1.20
563
718
 
564
- # Set up netboot and probe an existing DevKit first
719
+ # Allow daily mirror fallback for internal eLxr 3.0+ netboot
565
720
 
566
- sima-cli bootimg -v 2.1.0 --boardtype modalix --netboot --devkit-ip 192.168.1.20
721
+ sima-cli -i bootimg -v 1247 --netboot -f
567
722
 
568
723
  # Prepare an eLxr netboot image for Modalix
569
724
 
570
- sima-cli bootimg -v 2.0.0 --boardtype modalix --fwtype elxr --netboot
725
+ sima-cli bootimg -v 2.0.0 --netboot
726
+
727
+ # Prepare netboot from images already downloaded to a local directory
728
+
729
+ sima-cli bootimg --netboot --boardtype modalix --fwtype elxr --images /path/to/images
730
+
731
+ # Prepare USB/SD recovery media that automatically recovers eMMC
732
+
733
+ sima-cli bootimg -v 3.0.0 --recovery
571
734
 
572
735
  """
573
736
 
737
+ uses_netboot = netboot or autoflash
738
+ if images and not uses_netboot:
739
+ raise click.UsageError("--images requires --netboot or --autoflash.")
740
+ if delete_cache and not uses_netboot:
741
+ raise click.UsageError("--delete-cache requires --netboot or --autoflash.")
742
+ if images and version:
743
+ raise click.UsageError("--images and --version cannot be used together.")
744
+ if images and rootfs:
745
+ raise click.UsageError("--images and --rootfs cannot be used together.")
746
+ if not version and not images:
747
+ raise click.UsageError("Provide --version, or use --images for netboot.")
748
+
749
+ if recovery:
750
+ if netboot or autoflash or rootfs or devkit_ip:
751
+ raise click.UsageError("--recovery cannot be combined with --netboot, --autoflash, --rootfs, or --devkit-ip.")
752
+ if ctx.get_parameter_source("boardtype") == click.core.ParameterSource.DEFAULT:
753
+ boardtype = "modalix"
754
+ if ctx.get_parameter_source("fwtype") == click.core.ParameterSource.DEFAULT:
755
+ fwtype = "elxr"
756
+ if boardtype != "modalix" or fwtype != "elxr":
757
+ raise click.UsageError("--recovery requires --boardtype modalix and --fwtype elxr.")
758
+
574
759
  from sima_cli.update.bootimg import write_image
575
760
  from sima_cli.update.netboot import setup_netboot
576
- from sima_cli.update.remote import get_remote_board_info
577
-
578
761
  internal = ctx.obj.get("internal", False)
762
+ if internal and ctx.meta.get('daily_netboot') and (boardtype != 'modalix' or fwtype != 'elxr'):
763
+ if not internal_resource_exists() or not ctx.obj.get('internal_reachable', True):
764
+ raise click.ClickException('Artifactory is unavailable. Daily netboot fallback requires Modalix eLxr.')
579
765
 
580
766
  click.echo(f"📦 Preparing boot image:")
581
767
  click.echo(f" 🔹 Version : {version}")
@@ -583,26 +769,26 @@ def bootimg_cmd(ctx, version, boardtype, netboot, devkit_ip, autoflash, fwtype,
583
769
  click.echo(f" 🔹 F/W Type : {fwtype}")
584
770
  click.echo(f" 🔹 F/W Flavor: headless")
585
771
  click.echo(f" 🔹 Custom RootFS: {rootfs}")
772
+ click.echo(f" 🔹 Local Images: {images}")
586
773
  click.echo(f" 🔹 DevKit IP : {devkit_ip}")
587
774
 
588
775
  try:
589
- if devkit_ip and (netboot or autoflash):
590
- click.echo(f"🔎 Probing DevKit version at {devkit_ip} ...")
591
- _, remote_version, _, _, _ = get_remote_board_info(devkit_ip)
592
- if not remote_version:
593
- raise click.ClickException(
594
- f"Unable to retrieve remote version from DevKit at {devkit_ip}."
595
- )
596
- click.echo(f"✅ DevKit current version: {remote_version}")
597
-
598
776
  boardtype = boardtype if boardtype != 'mlsoc' else 'davinci'
599
777
  if netboot or autoflash:
600
- setup_netboot(version, boardtype, internal, autoflash, flavor='headless', rootfs=rootfs, swtype=fwtype)
601
- click.echo("✅ Netboot image prepared and TFTP server is running.")
778
+ netboot_options = {}
779
+ if images:
780
+ netboot_options["images"] = str(images)
781
+ if delete_cache:
782
+ netboot_options["delete_cache"] = True
783
+ setup_netboot(
784
+ version, boardtype, internal, autoflash, flavor='headless',
785
+ rootfs=rootfs, swtype=fwtype, allow_daily_fallback=force,
786
+ devkit=devkit_ip, **netboot_options,
787
+ )
788
+ click.echo("✅ Netboot session ended and the TFTP server is stopped.")
602
789
  else:
603
- write_image(version, boardtype, fwtype, internal, flavor='headless')
790
+ write_image(version, boardtype, fwtype, internal, flavor='headless', recovery=recovery)
604
791
  click.echo("✅ Boot image successfully written.")
605
- click.echo("✅ Boot image successfully written.")
606
792
  except Exception as e:
607
793
  click.echo(f"❌ Failed to write boot image: {e}", err=True)
608
794
  ctx.exit(1)
@@ -616,6 +802,7 @@ ALL_COMPONENTS = SDK_DEPENDENT_COMPONENTS | SDK_INDEPENDENT_COMPONENTS
616
802
  NEAT_INSTALL_REPOSITORIES = {
617
803
  "apps",
618
804
  "core",
805
+ "edgematic-studio",
619
806
  "insight",
620
807
  "internals",
621
808
  "llima",
@@ -881,7 +1068,28 @@ def network_cmd(ctx):
881
1068
  """
882
1069
  Setup Network IP address on the DevKit
883
1070
 
884
- This command only works on the DevKit. It allows user to switch between DHCP and Static (Default addresses) IP.
1071
+ This command only works on the DevKit. Select an interface, then choose DHCP,
1072
+ Default Static IP, or Custom Static IP.
1073
+
1074
+ Custom Static IP prompts for an IPv4 address, such as 192.168.1.50, or an
1075
+ address with a subnet prefix, such as 192.168.1.50/24. A bare address uses
1076
+ the default static profile's prefix. Invalid addresses are rejected;
1077
+ leave the prompt blank to cancel.
1078
+
1079
+ Custom addresses are activated without changing the existing boot
1080
+ configuration. The default static settings are copied into a temporary
1081
+ custom profile with autoconnect disabled on NetworkManager, or a runtime
1082
+ configuration on systemd-networkd. After reboot, the board uses its
1083
+ existing startup configuration. Selecting DHCP or
1084
+ Default Static IP disables the custom configuration.
1085
+ DNS and other default static settings are inherited. If an inherited IPv4
1086
+ gateway is incompatible with the new address, enter a replacement gateway
1087
+ or leave it blank for no gateway. The default profile is not modified.
1088
+
1089
+ Network changes must be made from the DevKit serial console. SSH sessions,
1090
+ including commands launched through sudo, are rejected before configuration
1091
+ changes. A replacement custom profile is activated before the old one is
1092
+ removed.
885
1093
 
886
1094
  """
887
1095
  network_menu()
@@ -0,0 +1,5 @@
1
+ """Experimental CloudEx commands."""
2
+
3
+ from .commands import register_cloudex_commands
4
+
5
+ __all__ = ["register_cloudex_commands"]