lager-cli 0.28.3__tar.gz → 0.28.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.
Files changed (221) hide show
  1. {lager_cli-0.28.3/lager_cli.egg-info → lager_cli-0.28.4}/PKG-INFO +1 -1
  2. {lager_cli-0.28.3 → lager_cli-0.28.4}/__init__.py +1 -1
  3. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/update.py +215 -115
  4. {lager_cli-0.28.3 → lager_cli-0.28.4/lager_cli.egg-info}/PKG-INFO +1 -1
  5. {lager_cli-0.28.3 → lager_cli-0.28.4}/LICENSE +0 -0
  6. {lager_cli-0.28.3 → lager_cli-0.28.4}/MANIFEST.in +0 -0
  7. {lager_cli-0.28.3 → lager_cli-0.28.4}/README.md +0 -0
  8. {lager_cli-0.28.3 → lager_cli-0.28.4}/__main__.py +0 -0
  9. {lager_cli-0.28.3 → lager_cli-0.28.4}/address_utils.py +0 -0
  10. {lager_cli-0.28.3 → lager_cli-0.28.4}/battery/__init__.py +0 -0
  11. {lager_cli-0.28.3 → lager_cli-0.28.4}/battery/battery_tui.py +0 -0
  12. {lager_cli-0.28.3 → lager_cli-0.28.4}/battery/websocket_client.py +0 -0
  13. {lager_cli-0.28.3 → lager_cli-0.28.4}/box_storage.py +0 -0
  14. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/__init__.py +0 -0
  15. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/__init__.py +0 -0
  16. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/_host_ops.py +0 -0
  17. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/_mount_prep.py +0 -0
  18. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/_pip_validation.py +0 -0
  19. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/_shim_verbs.py +0 -0
  20. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/_ssh.py +0 -0
  21. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/authorize.py +0 -0
  22. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/box_group.py +0 -0
  23. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/boxes.py +0 -0
  24. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/config.py +0 -0
  25. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/diagnose.py +0 -0
  26. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/dut.py +0 -0
  27. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/hello.py +0 -0
  28. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/instruments.py +0 -0
  29. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/labjack_pins.py +0 -0
  30. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/lock.py +0 -0
  31. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/net_tui.py +0 -0
  32. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/nets.py +0 -0
  33. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/box/ssh.py +0 -0
  34. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/__init__.py +0 -0
  35. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/ble.py +0 -0
  36. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/blufi.py +0 -0
  37. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/i2c.py +0 -0
  38. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/router.py +0 -0
  39. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/spi.py +0 -0
  40. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/uart.py +0 -0
  41. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/usb.py +0 -0
  42. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/websocket_client.py +0 -0
  43. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/communication/wifi.py +0 -0
  44. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/__init__.py +0 -0
  45. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/arm.py +0 -0
  46. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/__init__.py +0 -0
  47. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/commands.py +0 -0
  48. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/gdb.py +0 -0
  49. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/net_cache.py +0 -0
  50. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/service_client.py +0 -0
  51. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/service_helper.py +0 -0
  52. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/debug/tunnel.py +0 -0
  53. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/devenv.py +0 -0
  54. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/development/python.py +0 -0
  55. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/__init__.py +0 -0
  56. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/adc.py +0 -0
  57. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/dac.py +0 -0
  58. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/energy.py +0 -0
  59. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/gpi.py +0 -0
  60. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/gpo.py +0 -0
  61. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/logic.py +0 -0
  62. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/scope.py +0 -0
  63. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/thermocouple.py +0 -0
  64. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/measurement/watt.py +0 -0
  65. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/power/__init__.py +0 -0
  66. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/power/battery.py +0 -0
  67. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/power/eload.py +0 -0
  68. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/power/solar.py +0 -0
  69. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/power/supply.py +0 -0
  70. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/__init__.py +0 -0
  71. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/binaries.py +0 -0
  72. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/defaults.py +0 -0
  73. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/exec_.py +0 -0
  74. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/install.py +0 -0
  75. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/install_wheel.py +0 -0
  76. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/logs.py +0 -0
  77. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/uninstall.py +0 -0
  78. {lager_cli-0.28.3 → lager_cli-0.28.4}/commands/utility/webcam.py +0 -0
  79. {lager_cli-0.28.3 → lager_cli-0.28.4}/config.py +0 -0
  80. {lager_cli-0.28.3 → lager_cli-0.28.4}/context/__init__.py +0 -0
  81. {lager_cli-0.28.3 → lager_cli-0.28.4}/context/ci_detection.py +0 -0
  82. {lager_cli-0.28.3 → lager_cli-0.28.4}/context/constants.py +0 -0
  83. {lager_cli-0.28.3 → lager_cli-0.28.4}/context/core.py +0 -0
  84. {lager_cli-0.28.3 → lager_cli-0.28.4}/context/error_handlers.py +0 -0
  85. {lager_cli-0.28.3 → lager_cli-0.28.4}/context/session.py +0 -0
  86. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/__init__.py +0 -0
  87. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/group_usage.py +0 -0
  88. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/matchers.py +0 -0
  89. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/net_group.py +0 -0
  90. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/net_helpers.py +0 -0
  91. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/net_storage.py +0 -0
  92. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/param_types.py +0 -0
  93. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/ssh_utils.py +0 -0
  94. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/utils.py +0 -0
  95. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/version_skew.py +0 -0
  96. {lager_cli-0.28.3 → lager_cli-0.28.4}/core/ws_diagnose.py +0 -0
  97. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/__init__.py +0 -0
  98. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/scripts/__init__.py +0 -0
  99. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/scripts/convert_to_sparse_checkout.sh +0 -0
  100. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/scripts/setup_and_deploy_box.sh +0 -0
  101. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/scripts/setup_ssh_key.sh +0 -0
  102. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/security/__init__.py +0 -0
  103. {lager_cli-0.28.3 → lager_cli-0.28.4}/deployment/security/secure_box_firewall.sh +0 -0
  104. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/__init__.py +0 -0
  105. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/common/__init__.py +0 -0
  106. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/common/construct_utils.py +0 -0
  107. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/common/exceptions.py +0 -0
  108. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/common/py3compat.py +0 -0
  109. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/common/utils.py +0 -0
  110. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/construct/__init__.py +0 -0
  111. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/construct/adapters.py +0 -0
  112. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/construct/core.py +0 -0
  113. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/construct/debug.py +0 -0
  114. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/construct/macros.py +0 -0
  115. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/__init__.py +0 -0
  116. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/abbrevtable.py +0 -0
  117. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/aranges.py +0 -0
  118. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/callframe.py +0 -0
  119. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/compileunit.py +0 -0
  120. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/constants.py +0 -0
  121. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/descriptions.py +0 -0
  122. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/die.py +0 -0
  123. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/dwarf_expr.py +0 -0
  124. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/dwarfinfo.py +0 -0
  125. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/enums.py +0 -0
  126. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/lineprogram.py +0 -0
  127. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/locationlists.py +0 -0
  128. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/namelut.py +0 -0
  129. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/ranges.py +0 -0
  130. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/dwarf/structs.py +0 -0
  131. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/ehabi/__init__.py +0 -0
  132. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/ehabi/constants.py +0 -0
  133. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/ehabi/decoder.py +0 -0
  134. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/ehabi/ehabiinfo.py +0 -0
  135. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/ehabi/structs.py +0 -0
  136. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/__init__.py +0 -0
  137. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/constants.py +0 -0
  138. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/descriptions.py +0 -0
  139. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/dynamic.py +0 -0
  140. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/elffile.py +0 -0
  141. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/enums.py +0 -0
  142. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/gnuversions.py +0 -0
  143. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/hash.py +0 -0
  144. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/notes.py +0 -0
  145. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/relocation.py +0 -0
  146. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/sections.py +0 -0
  147. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/segments.py +0 -0
  148. {lager_cli-0.28.3 → lager_cli-0.28.4}/elftools/elf/structs.py +0 -0
  149. {lager_cli-0.28.3 → lager_cli-0.28.4}/errors.py +0 -0
  150. {lager_cli-0.28.3 → lager_cli-0.28.4}/exceptions.py +0 -0
  151. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/__init__.py +0 -0
  152. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/box_config.py +0 -0
  153. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/__init__.py +0 -0
  154. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/ble.py +0 -0
  155. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/blufi.py +0 -0
  156. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/i2c.py +0 -0
  157. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/router.py +0 -0
  158. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/spi.py +0 -0
  159. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/uart.py +0 -0
  160. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/communication/wifi.py +0 -0
  161. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/custom_devices.py +0 -0
  162. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/device/__init__.py +0 -0
  163. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/device/arm.py +0 -0
  164. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/device/hello.py +0 -0
  165. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/device/usb.py +0 -0
  166. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/device/webcam.py +0 -0
  167. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/__init__.py +0 -0
  168. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/adc.py +0 -0
  169. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/dac.py +0 -0
  170. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/energy.py +0 -0
  171. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/gpio.py +0 -0
  172. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/scope.py +0 -0
  173. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/scope_stream.py +0 -0
  174. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/thermocouple.py +0 -0
  175. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/measurement/watt.py +0 -0
  176. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/net.py +0 -0
  177. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/power/__init__.py +0 -0
  178. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/power/battery.py +0 -0
  179. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/power/eload.py +0 -0
  180. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/power/enable_disable.py +0 -0
  181. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/power/solar.py +0 -0
  182. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/power/supply.py +0 -0
  183. {lager_cli-0.28.3 → lager_cli-0.28.4}/impl/query_instruments.py +0 -0
  184. {lager_cli-0.28.3 → lager_cli-0.28.4}/lager_cli.egg-info/SOURCES.txt +0 -0
  185. {lager_cli-0.28.3 → lager_cli-0.28.4}/lager_cli.egg-info/dependency_links.txt +0 -0
  186. {lager_cli-0.28.3 → lager_cli-0.28.4}/lager_cli.egg-info/entry_points.txt +0 -0
  187. {lager_cli-0.28.3 → lager_cli-0.28.4}/lager_cli.egg-info/requires.txt +0 -0
  188. {lager_cli-0.28.3 → lager_cli-0.28.4}/lager_cli.egg-info/top_level.txt +0 -0
  189. {lager_cli-0.28.3 → lager_cli-0.28.4}/main.py +0 -0
  190. {lager_cli-0.28.3 → lager_cli-0.28.4}/pyproject.toml +0 -0
  191. {lager_cli-0.28.3 → lager_cli-0.28.4}/safe_unpickle.py +0 -0
  192. {lager_cli-0.28.3 → lager_cli-0.28.4}/setup.cfg +0 -0
  193. {lager_cli-0.28.3 → lager_cli-0.28.4}/setup.py +0 -0
  194. {lager_cli-0.28.3 → lager_cli-0.28.4}/simple_hdlc.py +0 -0
  195. {lager_cli-0.28.3 → lager_cli-0.28.4}/sort_utils.py +0 -0
  196. {lager_cli-0.28.3 → lager_cli-0.28.4}/status.py +0 -0
  197. {lager_cli-0.28.3 → lager_cli-0.28.4}/supply/__init__.py +0 -0
  198. {lager_cli-0.28.3 → lager_cli-0.28.4}/supply/supply_tui.py +0 -0
  199. {lager_cli-0.28.3 → lager_cli-0.28.4}/supply/websocket_client.py +0 -0
  200. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/__init__.py +0 -0
  201. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/core/__init__.py +0 -0
  202. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/core/executor.py +0 -0
  203. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/main.py +0 -0
  204. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/ui/__init__.py +0 -0
  205. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/ui/completer.py +0 -0
  206. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/ui/display.py +0 -0
  207. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/ui/logo.py +0 -0
  208. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/ui/repl.py +0 -0
  209. {lager_cli-0.28.3 → lager_cli-0.28.4}/terminal/ui/themes.py +0 -0
  210. {lager_cli-0.28.3 → lager_cli-0.28.4}/tests/test_box_lager_imports.py +0 -0
  211. {lager_cli-0.28.3 → lager_cli-0.28.4}/tests/test_box_storage.py +0 -0
  212. {lager_cli-0.28.3 → lager_cli-0.28.4}/tests/test_io_imports.py +0 -0
  213. {lager_cli-0.28.3 → lager_cli-0.28.4}/update_check.py +0 -0
  214. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/CRC16.py +0 -0
  215. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/CRC16DNP.py +0 -0
  216. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/CRC16Kermit.py +0 -0
  217. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/CRC16SICK.py +0 -0
  218. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/CRC32.py +0 -0
  219. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/CRCCCITT.py +0 -0
  220. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/PyCRC/__init__.py +0 -0
  221. {lager_cli-0.28.3 → lager_cli-0.28.4}/vendor/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: lager-cli
3
- Version: 0.28.3
3
+ Version: 0.28.4
4
4
  Summary: Lager CLI - Box and Docker connectivity
5
5
  Home-page: https://github.com/lagerdata/lager
6
6
  Author: Lager Data
@@ -7,4 +7,4 @@ Lager CLI
7
7
  A Command Line Interface for Lager Data
8
8
  """
9
9
 
10
- __version__ = '0.28.3'
10
+ __version__ = '0.28.4'
@@ -16,6 +16,7 @@ import subprocess
16
16
  import threading
17
17
  import time
18
18
  import sys
19
+ import uuid
19
20
  from ...box_storage import (
20
21
  auto_lock_acquire_for_command,
21
22
  get_box_user,
@@ -698,6 +699,40 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
698
699
  time.sleep(5)
699
700
  return False
700
701
 
702
+ def store_build_hash(hash_value):
703
+ """Persist the docker-build-inputs hash to /etc/lager/build-hash.
704
+
705
+ Returns True on success, False on failure (caller decides whether to
706
+ warn). Retries up to 3 times with backoff, like write_box_version_file.
707
+
708
+ The file is bind-mounted from the host into the container and can end up
709
+ owned by www-data (the container's runtime user); the SSH user
710
+ (lagerdata) is not in that group, so a plain `echo > /etc/lager/build-hash`
711
+ fails with EACCES and — when the write was unchecked — left a stale hash
712
+ that made every subsequent `lager update` rebuild needlessly. Step 10 has
713
+ already `chmod 777`'d /etc/lager, so we write a temp file in that dir and
714
+ `mv -f` it over the target: unlinking the old file needs only
715
+ directory-write (granted by 777), and the replacement is owned by
716
+ lagerdata, so future runs can overwrite it directly. Same-filesystem mv
717
+ is an atomic rename. The mktemp template's trailing X's must stay at the
718
+ end of the name.
719
+ """
720
+ if not hash_value:
721
+ return True
722
+ write_cmd = (
723
+ 'tmp=$(mktemp /etc/lager/.build-hash.XXXXXX) && '
724
+ f'printf "%s\\n" "{hash_value}" > "$tmp" && '
725
+ 'chmod 644 "$tmp" && '
726
+ 'mv -f "$tmp" /etc/lager/build-hash'
727
+ )
728
+ for attempt in range(3):
729
+ result = run_ssh_command_with_output(write_cmd, timeout_secs=30)
730
+ if result.returncode == 0:
731
+ return True
732
+ if attempt < 2:
733
+ time.sleep(5)
734
+ return False
735
+
701
736
  # Step 2: Inspect box state — one SSH round-trip gathers every read-only
702
737
  # fact the rest of the flow needs (git-repo check, remote URL, layout,
703
738
  # current commit, docker-build cache inputs, udev/sudoers state, on-box
@@ -1143,6 +1178,25 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1143
1178
  # or half-installed toolchain behind on the retry.
1144
1179
  must_wipe_image = hash_mismatch or force
1145
1180
 
1181
+ # Privileged box-state operations (udev rules, modprobe blacklist,
1182
+ # sudoers-owner fix, box-config sudoers bootstrap) are COLLECTED here and
1183
+ # applied together in a single interactive `ssh -t` session further down.
1184
+ # Each is a no-op on a correctly-provisioned box (the probe already told us
1185
+ # what's in sync); when one IS needed and the box lacks the passwordless
1186
+ # sudoers grant, batching them means the sudo password is requested at most
1187
+ # once per run instead of once per step (each used to open its own `ssh -t`
1188
+ # session, and sudo's per-tty credential cache doesn't carry across them).
1189
+ # A run that needs no privileged work never opens the session -> 0 prompts.
1190
+ # Per-run unique results path: a static /tmp name could be left behind by a
1191
+ # crashed run (or another user) and, since /tmp is sticky, our `rm -f` then
1192
+ # fails and the append is denied — making every job misreport as FAILED. A
1193
+ # uuid suffix also avoids the predictable-path risk on a shared box.
1194
+ _priv_results_path = f'/tmp/lager_priv_results_{uuid.uuid4().hex}'
1195
+ priv_jobs = [] # each: {'name': str, 'snippet': shell str, 'render': fn(ok)}
1196
+
1197
+ def enqueue_priv(name, snippet, render):
1198
+ priv_jobs.append({'name': name, 'snippet': snippet, 'render': render})
1199
+
1146
1200
  # Step 5: udev rules. The probe already located the source dir and diffed
1147
1201
  # its 99-instrument.rules against the installed copy, so we only touch the
1148
1202
  # box when an install/update is actually needed.
@@ -1170,6 +1224,12 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1170
1224
  # to (GROUP="lager"); the getent guard keeps the groupadd off the
1171
1225
  # common path so provisioned boxes stay within the passwordless
1172
1226
  # sudoers grant and see no password prompt.
1227
+ # The `&&` chain means a non-zero exit already implies one of the
1228
+ # sudo steps failed, so no separate post-install verify is needed.
1229
+ # The "lager" group is what the instrument rules grant device access
1230
+ # to (GROUP="lager"); the getent guard keeps the groupadd off the
1231
+ # common path so provisioned boxes stay within the passwordless
1232
+ # sudoers grant. Queued for the single privileged session below.
1173
1233
  install_cmd = (
1174
1234
  f'cp {udev_src_path}/99-instrument.rules /tmp/ && '
1175
1235
  '{ getent group lager >/dev/null || sudo /usr/sbin/groupadd lager; } && '
@@ -1180,32 +1240,20 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1180
1240
  'sudo /bin/rm -f /tmp/99-instrument.rules'
1181
1241
  )
1182
1242
 
1183
- # Interactive mode so a sudo password prompt can appear. pause()/
1184
- # resume() stop the 1s progress re-render from overwriting the prompt.
1185
- if not verbose and progress:
1186
- progress.pause()
1187
- click.echo('Installing udev rules (may require sudo password)...')
1188
- elif verbose:
1189
- click.echo()
1190
-
1191
- result = run_ssh_command_interactive(install_cmd, allow_sudo_prompt=True)
1192
-
1193
- if not verbose and progress:
1194
- progress.resume()
1195
- elif verbose:
1196
- click.echo()
1243
+ def _render_udev(ok, _src=udev_src_path):
1244
+ log('Installing udev rules...', nl=False)
1245
+ if ok:
1246
+ log_status('OK', 'green')
1247
+ else:
1248
+ log_status('FAILED', 'red')
1249
+ if verbose:
1250
+ click.echo(' Could not install udev rules — likely a sudoers permission issue.', err=True)
1251
+ click.echo(f' Manual fix: ssh {ssh_host}, then:', err=True)
1252
+ click.echo(' sudo groupadd -f lager', err=True)
1253
+ click.echo(f' sudo cp {_src}/99-instrument.rules /etc/udev/rules.d/', err=True)
1254
+ click.echo(' sudo udevadm control --reload-rules && sudo udevadm trigger', err=True)
1197
1255
 
1198
- log('Installing udev rules...', nl=False)
1199
- if result.returncode == 0:
1200
- log_status('OK', 'green')
1201
- else:
1202
- log_status('FAILED', 'red')
1203
- if verbose:
1204
- click.echo(' Could not install udev rules — likely a sudoers permission issue.', err=True)
1205
- click.echo(f' Manual fix: ssh {ssh_host}, then:', err=True)
1206
- click.echo(' sudo groupadd -f lager', err=True)
1207
- click.echo(f' sudo cp {udev_src_path}/99-instrument.rules /etc/udev/rules.d/', err=True)
1208
- click.echo(' sudo udevadm control --reload-rules && sudo udevadm trigger', err=True)
1256
+ enqueue_priv('udev', install_cmd, _render_udev)
1209
1257
 
1210
1258
  # Step 5b: modprobe.d blacklists (0.20.0+: usbtmc blacklist for USB-TMC
1211
1259
  # instrument drivers). Same shape as the udev step above — probe diffed
@@ -1260,48 +1308,31 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1260
1308
  else:
1261
1309
  log_status('update needed', 'yellow')
1262
1310
 
1311
+ # Install, then best-effort unload so the blacklist takes effect
1312
+ # without a reboot (EBUSY if a USB-TMC instrument is in use — tolerated
1313
+ # via `|| true`, so the job's success reflects the cp/chmod, not the
1314
+ # unload). Queued for the single privileged session below.
1263
1315
  install_cmd = (
1264
1316
  f'cp {mp_src_path}/blacklist-usbtmc.conf /tmp/ && '
1265
1317
  'sudo /bin/cp /tmp/blacklist-usbtmc.conf /etc/modprobe.d/ && '
1266
1318
  'sudo /bin/chmod 644 /etc/modprobe.d/blacklist-usbtmc.conf && '
1267
- 'sudo /bin/rm -f /tmp/blacklist-usbtmc.conf; '
1268
- # Try to unload immediately so the change takes effect without a
1269
- # reboot. Fails with EBUSY if a USB-TMC instrument is in use; we
1270
- # tolerate that and note a reboot is needed.
1271
- 'if lsmod | grep -q "^usbtmc"; then '
1272
- ' sudo /sbin/modprobe -r usbtmc 2>/dev/null && '
1273
- ' echo "LAGER_MP_UNLOAD=OK" || echo "LAGER_MP_UNLOAD=BUSY"; '
1274
- 'else echo "LAGER_MP_UNLOAD=NOT_LOADED"; fi'
1319
+ 'sudo /bin/rm -f /tmp/blacklist-usbtmc.conf && '
1320
+ '{ ! lsmod | grep -q "^usbtmc" || sudo /sbin/modprobe -r usbtmc 2>/dev/null || true; }'
1275
1321
  )
1276
1322
 
1277
- if not verbose and progress:
1278
- progress.pause()
1279
- click.echo('Installing modprobe.d blacklists (may require sudo password)...')
1280
- elif verbose:
1281
- click.echo()
1282
-
1283
- result = run_ssh_command_interactive(install_cmd, allow_sudo_prompt=True)
1284
-
1285
- if not verbose and progress:
1286
- progress.resume()
1287
- elif verbose:
1288
- click.echo()
1323
+ def _render_modprobe(ok, _src=mp_src_path):
1324
+ log('Installing modprobe.d blacklists...', nl=False)
1325
+ if ok:
1326
+ log_status('OK', 'green')
1327
+ else:
1328
+ log_status('FAILED', 'red')
1329
+ if verbose:
1330
+ click.echo(' Could not install modprobe.d blacklist — likely a sudoers permission issue.', err=True)
1331
+ click.echo(f' Manual fix: ssh {ssh_host}, then:', err=True)
1332
+ click.echo(f' sudo cp {_src}/blacklist-usbtmc.conf /etc/modprobe.d/', err=True)
1333
+ click.echo(' sudo modprobe -r usbtmc # optional: takes effect immediately', err=True)
1289
1334
 
1290
- log('Installing modprobe.d blacklists...', nl=False)
1291
- if result.returncode == 0:
1292
- log_status('OK', 'green')
1293
- if verbose:
1294
- if 'LAGER_MP_UNLOAD=BUSY' in (result.stdout or ''):
1295
- click.echo(' Note: usbtmc still loaded (instrument in use); reboot the box to fully apply.', err=True)
1296
- elif 'LAGER_MP_UNLOAD=OK' in (result.stdout or ''):
1297
- click.echo(' usbtmc kernel module unloaded; blacklist now in effect.')
1298
- else:
1299
- log_status('FAILED', 'red')
1300
- if verbose:
1301
- click.echo(' Could not install modprobe.d blacklist — likely a sudoers permission issue.', err=True)
1302
- click.echo(f' Manual fix: ssh {ssh_host}, then:', err=True)
1303
- click.echo(f' sudo cp {mp_src_path}/blacklist-usbtmc.conf /etc/modprobe.d/', err=True)
1304
- click.echo(' sudo modprobe -r usbtmc # optional: takes effect immediately', err=True)
1335
+ enqueue_priv('modprobe', install_cmd, _render_modprobe)
1305
1336
 
1306
1337
  # Step 6: sudoers ownership. /etc/sudoers.d/lagerdata-udev must be
1307
1338
  # root-owned or sudo refuses it; the probe gave us the owner uid.
@@ -1317,30 +1348,21 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1317
1348
  else:
1318
1349
  log_status(f'fixing (owned by uid {sudoers_owner})', 'yellow')
1319
1350
 
1320
- if not verbose and progress:
1321
- progress.pause()
1322
- click.echo('Fixing sudoers ownership (may require sudo password)...')
1323
- elif verbose:
1324
- click.echo()
1351
+ def _render_sudoers(ok):
1352
+ log('Fixing sudoers ownership...', nl=False)
1353
+ if ok:
1354
+ log_status('OK', 'green')
1355
+ else:
1356
+ log_status('FAILED', 'red')
1357
+ if verbose:
1358
+ click.echo(' Warning: could not fix sudoers ownership; sudo may not work correctly.', err=True)
1325
1359
 
1326
- fix_result = run_ssh_command_interactive(
1360
+ enqueue_priv(
1361
+ 'sudoers_owner',
1327
1362
  'sudo chown root:root /etc/sudoers.d/lagerdata-udev',
1328
- allow_sudo_prompt=True
1363
+ _render_sudoers,
1329
1364
  )
1330
1365
 
1331
- if not verbose and progress:
1332
- progress.resume()
1333
- elif verbose:
1334
- click.echo()
1335
-
1336
- log('Fixing sudoers ownership...', nl=False)
1337
- if fix_result.returncode == 0:
1338
- log_status('OK', 'green')
1339
- else:
1340
- log_status('FAILED', 'red')
1341
- if verbose:
1342
- click.echo(' Warning: could not fix sudoers ownership; sudo may not work correctly.', err=True)
1343
-
1344
1366
  # Step 7: passwordless sudo for `lager box config apply`.
1345
1367
  #
1346
1368
  # `lager box config apply` needs root on the host for apt-get install,
@@ -1359,12 +1381,6 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1359
1381
  else:
1360
1382
  log_status('needs bootstrap', 'yellow')
1361
1383
 
1362
- if not verbose and progress:
1363
- progress.pause()
1364
- click.echo('Installing box-config sudoers rule (may require sudo password)...')
1365
- elif verbose:
1366
- click.echo()
1367
-
1368
1384
  boxcfg_sudoers_cmd = (
1369
1385
  "printf '%s\\n' "
1370
1386
  "'lagerdata ALL=(root) NOPASSWD: SETENV: /usr/bin/apt-get' "
@@ -1379,18 +1395,17 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1379
1395
  "&& sudo chmod 644 /etc/lager/.boxcfg-sudoers-v2"
1380
1396
  )
1381
1397
 
1382
- boxcfg_install_result = run_ssh_command_interactive(
1383
- boxcfg_sudoers_cmd,
1384
- allow_sudo_prompt=True,
1385
- )
1386
-
1387
- if not verbose and progress:
1388
- progress.resume()
1389
- elif verbose:
1390
- click.echo()
1391
-
1392
- log('Installing box-config sudoers...', nl=False)
1393
- if boxcfg_install_result.returncode == 0:
1398
+ def _render_boxcfg(ok):
1399
+ log('Installing box-config sudoers...', nl=False)
1400
+ if not ok:
1401
+ log_status('FAILED', 'yellow')
1402
+ if verbose:
1403
+ click.echo(
1404
+ ' Warning: box-config sudoers rule could not be installed. '
1405
+ '`lager box config apply` will need manual sudoers setup on this box.',
1406
+ err=True,
1407
+ )
1408
+ return
1394
1409
  # `sudo tee` succeeds even if the sudoers content is malformed,
1395
1410
  # so this functional re-check is genuinely needed (unlike the
1396
1411
  # udev path above, where the `&&` chain is self-verifying).
@@ -1407,14 +1422,55 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1407
1422
  'Check /etc/sudoers.d/lager-box-config syntax on the box.',
1408
1423
  err=True,
1409
1424
  )
1410
- else:
1411
- log_status('FAILED', 'yellow')
1412
- if verbose:
1413
- click.echo(
1414
- ' Warning: box-config sudoers rule could not be installed. '
1415
- '`lager box config apply` will need manual sudoers setup on this box.',
1416
- err=True,
1417
- )
1425
+
1426
+ enqueue_priv('boxcfg', boxcfg_sudoers_cmd, _render_boxcfg)
1427
+
1428
+ # Apply all queued privileged operations in ONE interactive `ssh -t`
1429
+ # session, so the sudo password (on a box without the passwordless grant)
1430
+ # is requested at most once for the whole run. We can't read the interactive
1431
+ # session's stdout (it streams to the terminal so the prompt is visible), so
1432
+ # each job records `<name>=OK|FAIL` to a results file that we read back over
1433
+ # the normal captured channel and hand to each job's render() for the same
1434
+ # per-step status output as before. A box that needs nothing skips this
1435
+ # entirely and never prompts.
1436
+ if priv_jobs:
1437
+ wrapped = [f'rm -f {_priv_results_path}']
1438
+ for job in priv_jobs:
1439
+ # Subshell so one job's failure doesn't abort the rest; record the
1440
+ # outcome regardless. The first sudo in this single tty prompts (if
1441
+ # needed); subsequent sudos reuse the cached credential.
1442
+ wrapped.append(
1443
+ f'if ( {job["snippet"]} ); then '
1444
+ f'echo "{job["name"]}=OK" >> {_priv_results_path}; '
1445
+ f'else echo "{job["name"]}=FAIL" >> {_priv_results_path}; fi'
1446
+ )
1447
+ combined_priv_cmd = '\n'.join(wrapped)
1448
+
1449
+ if not verbose and progress:
1450
+ progress.pause()
1451
+ click.echo('Applying box settings (may require the sudo password once)...')
1452
+ elif verbose:
1453
+ click.echo()
1454
+
1455
+ run_ssh_command_interactive(combined_priv_cmd, allow_sudo_prompt=True)
1456
+
1457
+ if not verbose and progress:
1458
+ progress.resume()
1459
+ elif verbose:
1460
+ click.echo()
1461
+
1462
+ # Read back per-job results over the captured channel, then clean up.
1463
+ priv_read = run_ssh_command_with_output(
1464
+ f'cat {_priv_results_path} 2>/dev/null; rm -f {_priv_results_path}'
1465
+ )
1466
+ priv_results = {}
1467
+ for line in (priv_read.stdout or '').splitlines():
1468
+ if '=' in line:
1469
+ k, _, v = line.partition('=')
1470
+ priv_results[k.strip()] = v.strip()
1471
+
1472
+ for job in priv_jobs:
1473
+ job['render'](priv_results.get(job['name']) == 'OK')
1418
1474
 
1419
1475
  # No git updates, no box/→root flatten work, and the docker-build inputs
1420
1476
  # match what's already cached: a second consecutive `lager update` would
@@ -1523,6 +1579,42 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1523
1579
  )
1524
1580
  log_status('OK', 'green')
1525
1581
 
1582
+ # BuildKit preflight. box.Dockerfile uses a `# syntax=` directive and
1583
+ # `RUN --mount=type=cache` cache mounts that keep the cargo (defmt-print)
1584
+ # compile and pip wheel work warm across rebuilds — turning a from-scratch
1585
+ # rebuild from ~20 min into a few minutes. These require BuildKit: Docker
1586
+ # >= 23 enables it by default and 18.09+ honors DOCKER_BUILDKIT=1, while a
1587
+ # legacy builder errors on `--mount`. Probe once and fail fast with an
1588
+ # actionable message rather than wasting a long build that dies on a
1589
+ # confusing parse error minutes in.
1590
+ def _docker_supports_buildkit():
1591
+ probe = run_ssh_command_with_output(
1592
+ "docker buildx version >/dev/null 2>&1 && echo BUILDX || "
1593
+ "docker version --format '{{.Server.Version}}' 2>/dev/null",
1594
+ timeout_secs=20,
1595
+ )
1596
+ out = (probe.stdout or '').strip()
1597
+ if 'BUILDX' in out:
1598
+ return True, out
1599
+ try:
1600
+ parts = out.split('-')[0].split('.')
1601
+ ver = (int(parts[0]), int(parts[1]) if len(parts) > 1 else 0)
1602
+ return ver >= (18, 9), out
1603
+ except (ValueError, IndexError):
1604
+ return False, out
1605
+
1606
+ buildkit_ok, docker_ver = _docker_supports_buildkit()
1607
+ if not buildkit_ok:
1608
+ if progress:
1609
+ progress.finish(success=False)
1610
+ log_error(
1611
+ "Error: this box's Docker does not support BuildKit, which the box "
1612
+ "image now requires (RUN --mount cache mounts). Detected: "
1613
+ f"{docker_ver or 'unknown'}. Upgrade Docker to >= 23 (or install the "
1614
+ "docker-buildx-plugin) on the box, then re-run `lager update`."
1615
+ )
1616
+ ctx.exit(1)
1617
+
1526
1618
  # Step 9: Rebuild Docker container (the slow part)
1527
1619
  if progress:
1528
1620
  progress.update("Building container...")
@@ -1536,7 +1628,7 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1536
1628
  ssh_cmd.extend(_ssh_mux_opts)
1537
1629
  ssh_cmd.extend([ssh_host,
1538
1630
  'cd ~/box/lager && '
1539
- 'docker build -f docker/box.Dockerfile -t lager .'])
1631
+ 'DOCKER_BUILDKIT=1 docker build -f docker/box.Dockerfile -t lager .'])
1540
1632
 
1541
1633
  build_output_lines = []
1542
1634
  if verbose:
@@ -1590,14 +1682,10 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1590
1682
  if verbose:
1591
1683
  click.secho(' Build complete', fg='green')
1592
1684
 
1593
- # Record the build-inputs hash so the next run can decide whether to
1594
- # invalidate the cache automatically. Best-efforta failure here just
1595
- # means the next update may rebuild unnecessarily.
1596
- if new_build_hash:
1597
- run_ssh_command_with_output(
1598
- f'echo "{new_build_hash}" > /etc/lager/build-hash',
1599
- timeout_secs=15,
1600
- )
1685
+ # The build-inputs hash is persisted later (after Step 10 ensures
1686
+ # /etc/lager is world-writable) via store_build_hashwriting it here, to a
1687
+ # possibly www-data-owned file, failed silently and left a stale hash that
1688
+ # forced a rebuild on every subsequent run.
1601
1689
 
1602
1690
  # Reclaim disk from *superseded* images while preserving the build cache.
1603
1691
  #
@@ -1655,6 +1743,18 @@ def _update_logic(ctx, *, box, yes, version, verbose, check, force=False):
1655
1743
  ctx.exit(1)
1656
1744
  log_status('OK', 'green')
1657
1745
 
1746
+ # Persist the build-inputs hash now that /etc/lager is world-writable (Step
1747
+ # 10). This is what lets the next run's cache-validity check short-circuit to
1748
+ # the no-op fast path instead of rebuilding; a stale hash defeats it. Unlike
1749
+ # the old unchecked write, store_build_hash verifies success and we surface a
1750
+ # visible warning on failure rather than silently leaving a stale hash.
1751
+ if new_build_hash and not store_build_hash(new_build_hash):
1752
+ click.secho(
1753
+ 'Warning: could not persist build hash to /etc/lager/build-hash; '
1754
+ 'the next `lager update` may rebuild even when nothing changed.',
1755
+ fg='yellow', err=True,
1756
+ )
1757
+
1658
1758
  # Write the version file BEFORE the container restart (SSH is stable here).
1659
1759
  # A version tag (v0.3.14 / 0.3.14) is used directly. For a branch target
1660
1760
  # we ask the box for the closest preceding `vX.Y.Z` tag at HEAD via
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: lager-cli
3
- Version: 0.28.3
3
+ Version: 0.28.4
4
4
  Summary: Lager CLI - Box and Docker connectivity
5
5
  Home-page: https://github.com/lagerdata/lager
6
6
  Author: Lager Data
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes