holoscan-cli 3.1.0__py3-none-any.whl → 3.3.0__py3-none-any.whl

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.

Potentially problematic release.


This version of holoscan-cli might be problematic. Click here for more details.

@@ -15,7 +15,6 @@
15
15
  import argparse
16
16
  import os
17
17
  from pathlib import Path
18
-
19
18
  from .constants import SDK
20
19
  from .enum_types import Platform, PlatformConfiguration, SdkType
21
20
 
@@ -155,3 +154,18 @@ def valid_sdk_type(sdk_str: str) -> SdkType:
155
154
  raise argparse.ArgumentTypeError(f"{sdk_str} is not a valid option for --sdk.")
156
155
 
157
156
  return SdkType(sdk_str)
157
+
158
+
159
+ def valid_host_ip(host_ip: str) -> str:
160
+ """Helper type checking and type converting method for ArgumentParser.add_argument
161
+ to convert check valid host:ip format.
162
+
163
+ Args:
164
+ host_ip: host ip string
165
+ """
166
+
167
+ host, ip = host_ip.split(":")
168
+ if host == "" or ip == "":
169
+ raise argparse.ArgumentTypeError(f"Invalid valid for --add-host: '{host_ip}'")
170
+
171
+ return host_ip
@@ -172,6 +172,7 @@ def docker_run(
172
172
  platform_config: str,
173
173
  shared_memory_size: str = "1GB",
174
174
  is_root: bool = False,
175
+ remove: bool = False,
175
176
  ):
176
177
  """Creates and runs a Docker container
177
178
 
@@ -351,6 +352,7 @@ def docker_run(
351
352
  ulimits,
352
353
  devices,
353
354
  group_adds,
355
+ remove,
354
356
  )
355
357
  else:
356
358
  _start_container(
@@ -368,6 +370,7 @@ def docker_run(
368
370
  ulimits,
369
371
  devices,
370
372
  group_adds,
373
+ remove,
371
374
  )
372
375
 
373
376
 
@@ -386,6 +389,7 @@ def _start_container(
386
389
  ulimits,
387
390
  devices,
388
391
  group_adds,
392
+ remove,
389
393
  ):
390
394
  container = docker.container.create(
391
395
  image_name,
@@ -394,7 +398,7 @@ def _start_container(
394
398
  hostname=name,
395
399
  name=name,
396
400
  networks=[network],
397
- remove=True,
401
+ remove=False,
398
402
  shm_size=shared_memory_size,
399
403
  user=user,
400
404
  volumes=volumes,
@@ -441,7 +445,18 @@ def _start_container(
441
445
  except Exception:
442
446
  print(str(log[1]))
443
447
 
444
- logger.info(f"Container '{container_name}'({container_id}) exited.")
448
+ exit_code = container.state.exit_code
449
+ logger.info(
450
+ f"Container '{container_name}'({container_id}) exited with code {exit_code}."
451
+ )
452
+
453
+ if remove:
454
+ container.remove()
455
+
456
+ if exit_code != 0:
457
+ raise RuntimeError(
458
+ f"Container '{container_name}'({container_id}) exited with code {exit_code}."
459
+ )
445
460
 
446
461
 
447
462
  def _enter_terminal(
@@ -457,6 +472,7 @@ def _enter_terminal(
457
472
  ulimits,
458
473
  devices,
459
474
  group_adds,
475
+ remove,
460
476
  ):
461
477
  print("\n\nEntering terminal...")
462
478
  print(
@@ -475,7 +491,7 @@ def _enter_terminal(
475
491
  interactive=True,
476
492
  name=name,
477
493
  networks=[network],
478
- remove=True,
494
+ remove=remove,
479
495
  shm_size=shared_memory_size,
480
496
  tty=True,
481
497
  user=user,
@@ -76,6 +76,8 @@ class PackagingArguments:
76
76
  self.build_parameters.cmake_args = args.cmake_args
77
77
  self.build_parameters.includes = args.includes
78
78
  self.build_parameters.additional_libs = args.additional_libs
79
+ self.build_parameters.add_hosts = args.add_hosts
80
+ self.build_parameters.input_data = args.input_data
79
81
 
80
82
  models = Models()
81
83
  platform = Platform(self._artifact_sources)
@@ -58,6 +58,8 @@ class BuilderBase:
58
58
  self._copy_model_files()
59
59
  self._copy_docs()
60
60
  self._copy_libs()
61
+ self._copy_input_data()
62
+
61
63
  _ = self._write_dockerignore()
62
64
  _ = self._copy_script()
63
65
 
@@ -88,7 +90,6 @@ class BuilderBase:
88
90
  Returns:
89
91
  PlatformBuildResults: build results
90
92
  """
91
- self.print_build_info(platform_parameters)
92
93
  builder = create_and_get_builder(Constants.LOCAL_BUILDX_BUILDER_NAME)
93
94
 
94
95
  build_result = PlatformBuildResults(platform_parameters)
@@ -117,9 +118,15 @@ class BuilderBase:
117
118
  "tags": [platform_parameters.tag],
118
119
  }
119
120
 
121
+ if self._build_parameters.add_hosts:
122
+ builds["add_hosts"] = {}
123
+ for host in self._build_parameters.add_hosts:
124
+ host_name, host_ip = host.split(":")
125
+ builds["add_hosts"][host_name] = host_ip
126
+
120
127
  export_to_tar_ball = False
121
128
  if self._build_parameters.tarball_output is not None:
122
- build_result.tarball_filenaem = str(
129
+ build_result.tarball_filename = str(
123
130
  self._build_parameters.tarball_output
124
131
  / f"{platform_parameters.tag}{Constants.TARBALL_FILE_EXTENSION}"
125
132
  ).replace(":", "-")
@@ -134,7 +141,7 @@ class BuilderBase:
134
141
  builds["output"] = {
135
142
  # type=oci cannot be loaded by docker: https://github.com/docker/buildx/issues/59
136
143
  "type": "docker",
137
- "dest": build_result.tarball_filenaem,
144
+ "dest": build_result.tarball_filename,
138
145
  }
139
146
  else:
140
147
  build_result.succeeded = False
@@ -155,21 +162,24 @@ class BuilderBase:
155
162
  f"Building Holoscan Application Package: tag={platform_parameters.tag}"
156
163
  )
157
164
 
165
+ self.print_build_info(platform_parameters)
166
+
158
167
  try:
159
168
  build_docker_image(**builds)
160
169
  build_result.succeeded = True
161
170
  if export_to_tar_ball:
162
171
  try:
163
172
  self._logger.info(
164
- f"Saving {platform_parameters.tag} to {build_result.tarball_filenaem}..."
173
+ f"Saving {platform_parameters.tag} to {build_result.tarball_filename}..."
165
174
  )
166
175
  docker_export_tarball(
167
- build_result.tarball_filenaem, platform_parameters.tag
176
+ build_result.tarball_filename, platform_parameters.tag
168
177
  )
169
178
  except Exception as ex:
170
179
  build_result.error = f"Error saving tarball: {ex}"
171
180
  build_result.succeeded = False
172
- except Exception:
181
+ except Exception as e:
182
+ print(e)
173
183
  build_result.succeeded = False
174
184
  build_result.error = (
175
185
  "Error building image: see Docker output for additional details."
@@ -177,6 +187,13 @@ class BuilderBase:
177
187
 
178
188
  return build_result
179
189
 
190
+ def _copy_input_data(self):
191
+ """Copy input data to temporary location"""
192
+ if self._build_parameters.input_data is not None:
193
+ shutil.copytree(
194
+ self._build_parameters.input_data, os.path.join(self._temp_dir, "input")
195
+ )
196
+
180
197
  def print_build_info(self, platform_parameters):
181
198
  """Print build information for the platform."""
182
199
  self._logger.info(
@@ -378,18 +395,27 @@ class PythonAppBuilder(BuilderBase):
378
395
  os.makedirs(pip_folder, exist_ok=True)
379
396
  pip_requirements_path = os.path.join(pip_folder, "requirements.txt")
380
397
 
398
+ # Build requirements content first
399
+ requirements_content = []
400
+ if self._build_parameters.requirements_file_path is not None:
401
+ with open(self._build_parameters.requirements_file_path) as lr:
402
+ requirements_content.extend(lr)
403
+ requirements_content.append("")
404
+
405
+ if self._build_parameters.pip_packages:
406
+ requirements_content.extend(self._build_parameters.pip_packages)
407
+
408
+ # Write all content at once
381
409
  with open(pip_requirements_path, "w") as requirements_file:
382
- # Use local requirements.txt packages if provided, otherwise use sdk provided packages
383
- if self._build_parameters.requirements_file_path is not None:
384
- with open(self._build_parameters.requirements_file_path) as lr:
385
- for line in lr:
386
- requirements_file.write(line)
387
- requirements_file.writelines("\n")
388
-
389
- if self._build_parameters.pip_packages:
390
- requirements_file.writelines(
391
- "\n".join(self._build_parameters.pip_packages)
392
- )
410
+ requirements_file.writelines(requirements_content)
411
+ self._logger.debug(
412
+ "================ Begin requirements.txt ================"
413
+ )
414
+ for req in requirements_content:
415
+ self._logger.debug(f" {req.strip()}")
416
+ self._logger.debug(
417
+ "================ End requirements.txt =================="
418
+ )
393
419
 
394
420
  def _copy_sdk_file(self, sdk_file: Optional[Path]):
395
421
  if sdk_file is not None and os.path.isfile(sdk_file):
@@ -19,6 +19,7 @@ from argparse import ArgumentParser, _SubParsersAction
19
19
  from packaging.version import Version
20
20
 
21
21
  from ..common.argparse_types import (
22
+ valid_host_ip,
22
23
  valid_dir_path,
23
24
  valid_existing_dir_path,
24
25
  valid_existing_path,
@@ -43,6 +44,14 @@ def create_package_parser(
43
44
  help="Holoscan application path: Python application directory with __main__.py, "
44
45
  "Python file, C++ source directory with CMakeLists.txt, or path to an executable.",
45
46
  )
47
+
48
+ parser.add_argument(
49
+ "--add",
50
+ action="append",
51
+ dest="additional_libs",
52
+ type=valid_existing_dir_path,
53
+ help="include additional library files, python files into the application directory.",
54
+ )
46
55
  parser.add_argument(
47
56
  "--config",
48
57
  "-c",
@@ -69,13 +78,6 @@ def create_package_parser(
69
78
  help="target platform(s) for the build output separated by comma. "
70
79
  f"Valid values: {str.join(', ', SDK.PLATFORMS)}.",
71
80
  )
72
- parser.add_argument(
73
- "--add",
74
- action="append",
75
- dest="additional_libs",
76
- type=valid_existing_dir_path,
77
- help="include additional library files, python files into the application directory.",
78
- )
79
81
  parser.add_argument(
80
82
  "--timeout", type=int, help="override default application timeout"
81
83
  )
@@ -84,6 +86,13 @@ def create_package_parser(
84
86
  )
85
87
 
86
88
  advanced_group = parser.add_argument_group(title="advanced build options")
89
+ advanced_group.add_argument(
90
+ "--add-host",
91
+ action="append",
92
+ dest="add_hosts",
93
+ type=valid_host_ip,
94
+ help="Add a custom host-to-IP mapping (format: host:ip).",
95
+ )
87
96
  advanced_group.add_argument(
88
97
  "--base-image",
89
98
  type=str,
@@ -94,13 +103,6 @@ def create_package_parser(
94
103
  type=str,
95
104
  help="container image name for building the C++ application.",
96
105
  )
97
- advanced_group.add_argument(
98
- "--includes",
99
- nargs="*",
100
- default=[],
101
- choices=["debug", "holoviz", "torch", "onnx"],
102
- help="additional packages to include in the container.",
103
- )
104
106
  advanced_group.add_argument(
105
107
  "--build-cache",
106
108
  type=valid_dir_path,
@@ -119,6 +121,18 @@ def create_package_parser(
119
121
  "If not specified, the packager downloads "
120
122
  "the SDK file from the internet based on the SDK version.",
121
123
  )
124
+ advanced_group.add_argument(
125
+ "--includes",
126
+ nargs="*",
127
+ default=[],
128
+ choices=["debug", "holoviz", "torch", "onnx"],
129
+ help="additional packages to include in the container.",
130
+ )
131
+ advanced_group.add_argument(
132
+ "--input-data",
133
+ type=valid_dir_path,
134
+ help="sample input data to be embedded in the container.",
135
+ )
122
136
  advanced_group.add_argument(
123
137
  "--monai-deploy-sdk-file",
124
138
  type=valid_existing_path,
@@ -139,18 +153,18 @@ def create_package_parser(
139
153
  help="SDK for building the application: Holoscan or MONAI-Deploy. "
140
154
  f"Valid values: {str.join(', ', SDK.SDKS)}.",
141
155
  )
142
- advanced_group.add_argument(
143
- "--source",
144
- type=str,
145
- help="override Debian package, build container image and run container image from a "
146
- "JSON formatted file or a secured web server (HTTPS).",
147
- )
148
156
  advanced_group.add_argument(
149
157
  "--sdk-version",
150
158
  type=Version,
151
159
  help="set the version of the SDK that is used to build and package the application. "
152
160
  "If not specified, the packager attempts to detect the installed version.",
153
161
  )
162
+ advanced_group.add_argument(
163
+ "--source",
164
+ type=str,
165
+ help="override Debian package, build container image and run container image from a "
166
+ "JSON formatted file or a secured web server (HTTPS).",
167
+ )
154
168
 
155
169
  output_group = parser.add_argument_group(title="output options")
156
170
  output_group.add_argument(
@@ -103,7 +103,7 @@ def _package_application(args: Namespace):
103
103
  f"""\nPlatform: {result.parameters.platform.value}/{result.parameters.platform_config.value}
104
104
  Status: Succeeded
105
105
  Docker Tag: {result.docker_tag if result.docker_tag is not None else "N/A"}
106
- Tarball: {result.tarball_filenaem}""" # noqa: E501
106
+ Tarball: {result.tarball_filename}""" # noqa: E501
107
107
  )
108
108
  else:
109
109
  print(
@@ -16,7 +16,7 @@ import logging
16
16
  import os
17
17
  import platform
18
18
  from pathlib import Path
19
- from typing import Any, Optional
19
+ from typing import Any, List, Optional
20
20
 
21
21
  from ..common.constants import SDK, Constants, DefaultValues
22
22
  from ..common.dockerutils import parse_docker_image_name_and_tag
@@ -205,7 +205,7 @@ class PlatformBuildResults:
205
205
  def __init__(self, parameters: PlatformParameters):
206
206
  self._parameters = parameters
207
207
  self._docker_tag: Optional[str] = None
208
- self._tarball_filenaem: Optional[str] = None
208
+ self._tarball_filename: Optional[str] = None
209
209
  self._succeeded = False
210
210
  self._error: Optional[str] = None
211
211
 
@@ -230,12 +230,12 @@ class PlatformBuildResults:
230
230
  self._docker_tag = value
231
231
 
232
232
  @property
233
- def tarball_filenaem(self) -> Optional[str]:
234
- return self._tarball_filenaem
233
+ def tarball_filename(self) -> Optional[str]:
234
+ return self._tarball_filename
235
235
 
236
- @tarball_filenaem.setter
237
- def tarball_filenaem(self, value: Optional[str]):
238
- self._tarball_filenaem = value
236
+ @tarball_filename.setter
237
+ def tarball_filename(self, value: Optional[str]):
238
+ self._tarball_filename = value
239
239
 
240
240
  @property
241
241
  def succeeded(self) -> bool:
@@ -277,8 +277,9 @@ class PackageBuildParameters:
277
277
  self._data["tarball_output"] = None
278
278
  self._data["cmake_args"] = ""
279
279
  self._data["includes"] = []
280
+ self._data["input_data"] = None
280
281
  self._data["additional_lib_paths"] = ""
281
-
282
+ self._data["add_hosts"] = []
282
283
  self._data["application_directory"] = None
283
284
  self._data["application_type"] = None
284
285
  self._data["application"] = None
@@ -529,6 +530,14 @@ class PackageBuildParameters:
529
530
  def monai_deploy_app_sdk_version(self, value: str):
530
531
  self._data["monai_deploy_app_sdk_version"] = value
531
532
 
533
+ @property
534
+ def add_hosts(self) -> List[str]:
535
+ return self._data["add_hosts"]
536
+
537
+ @add_hosts.setter
538
+ def add_hosts(self, value: List[str]):
539
+ self._data["add_hosts"] = value
540
+
532
541
  @property
533
542
  def includes(self) -> str:
534
543
  return self._data["includes"]
@@ -537,6 +546,14 @@ class PackageBuildParameters:
537
546
  def includes(self, value: str):
538
547
  self._data["includes"] = value
539
548
 
549
+ @property
550
+ def input_data(self) -> Path:
551
+ return self._data["input_data"]
552
+
553
+ @input_data.setter
554
+ def input_data(self, value: Path):
555
+ self._data["input_data"] = value
556
+
540
557
  @property
541
558
  def additional_lib_paths(self) -> str:
542
559
  """
@@ -63,7 +63,7 @@ ARG LIBTORCH_VERSION=2.5.0_24.08
63
63
  RUN apt update && \
64
64
  apt-get install -y --no-install-recommends --no-install-suggests \
65
65
  bzip2 \
66
- libopenmpi3=4.1.2-* \
66
+ libopenmpi3t64=4.1.6-* \
67
67
  && rm -rf /var/lib/apt/lists/*
68
68
 
69
69
  # Download libtorch
@@ -197,15 +197,15 @@ RUN apt-get update \
197
197
  # Install Holoviz dependencies
198
198
  RUN apt-get update \
199
199
  && apt-get install --no-install-recommends --no-install-suggests --allow-downgrades --allow-change-held-packages -y \
200
- libvulkan1="1.3.204.1-*" \
200
+ libvulkan1="1.3.275.0-*" \
201
201
  # X11 support \
202
- libgl1="1.4.0-*" \
202
+ libgl1="1.7.0-*" \
203
203
  # Wayland support \
204
- libwayland-client0="1.20.0-*" \
205
- libwayland-egl1="1.20.0-*" \
206
- libxkbcommon0="1.4.0-*" \
207
- libdecor-0-plugin-1-cairo="0.1.0-*" \
208
- libegl1="1.4.0-*" \
204
+ libwayland-client0="1.22.0-*" \
205
+ libwayland-egl1="1.22.0-*" \
206
+ libxkbcommon0="1.6.0-*" \
207
+ libdecor-0-plugin-1-cairo="0.2.2-*" \
208
+ libegl1="1.7.0-*" \
209
209
  && rm -rf /var/lib/apt/lists/*
210
210
  # End install Holoviz dependencies
211
211
  {% endif %}
@@ -213,8 +213,8 @@ RUN apt-get update \
213
213
 
214
214
  {% if 'torch' in includes %}
215
215
  # Install torch dependencies
216
- ENV PYTHON_VERSION=3.10.6-1~22.04
217
- ENV PYTHON_PIP_VERSION=22.0.2+dfsg-*
216
+ ENV PYTHON_VERSION=3.12.3-*
217
+ ENV PYTHON_PIP_VERSION=24.0+dfsg-*
218
218
 
219
219
  RUN apt update \
220
220
  && apt-get install -y --no-install-recommends --no-install-suggests \
@@ -223,13 +223,13 @@ RUN apt update \
223
223
  python3=${PYTHON_VERSION} \
224
224
  python3-venv=${PYTHON_VERSION} \
225
225
  python3-pip=${PYTHON_PIP_VERSION} \
226
- libjpeg-turbo8="2.1.2-*" \
227
- libnuma1="2.0.14-*" \
228
- libhwloc15="2.7.0-*" \
229
- libopenblas0="0.3.20+ds-*" \
226
+ libjpeg-turbo8="2.1.5-*" \
227
+ libnuma1="2.0.18-*" \
228
+ libhwloc15="2.10.0-*" \
229
+ libopenblas0="0.3.26+ds-*" \
230
230
  libevent-core-2.1-7 \
231
231
  libevent-pthreads-2.1-7 \
232
- cuda-cupti-12-6 \
232
+ cuda-cupti-12-8 \
233
233
  libcudnn9-cuda-12 \
234
234
  && rm -rf /var/lib/apt/lists/*
235
235
 
@@ -248,7 +248,8 @@ ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/sbsa-linux-gnu/
248
248
 
249
249
  # mkl - dependency for libtorch plugin on x86_64 (match pytorch container version)
250
250
  RUN if [ "{{ cuda_deb_arch }}" = "x86_64" ]; then \
251
- python3 -m pip install --no-cache-dir \
251
+ rm -rf /usr/lib/python3.12/EXTERNALLY-MANAGED \
252
+ && python3 -m pip install --no-cache-dir \
252
253
  mkl==2021.1.1 \
253
254
  && \
254
255
  # Clean up duplicate libraries from mkl/tbb python wheel install which makes copies for symlinks.
@@ -291,10 +292,10 @@ COPY --from=onnx-dependencies ${ONNX_RUNTIME} ${ONNX_RUNTIME}
291
292
  {% if gpu_type == "dgpu" %}
292
293
  RUN apt-get update \
293
294
  && apt-get install --no-install-recommends --no-install-suggests --allow-downgrades -y \
294
- libnvinfer10="10.3.*+cuda12.5" \
295
- libnvinfer-plugin10="10.3.*+cuda12.5" \
296
- libnvonnxparsers10="10.3.*+cuda12.5" \
297
- libcusparselt0="0.6.3.2-*" \
295
+ libnvinfer10="10.9.0.34-1+cuda12.8" \
296
+ libnvinfer-plugin10="10.9.0.34-1+cuda12.8" \
297
+ libnvonnxparsers10="10.9.0.34-1+cuda12.8" \
298
+ libcusparselt0="0.7.1.0-*" \
298
299
  libcudnn9-cuda-12 \
299
300
  && rm -rf /var/lib/apt/lists/* \
300
301
  && rm -f /usr/lib/*/libcudnn*train.so*
@@ -316,8 +317,8 @@ HEALTHCHECK --interval=10s --timeout=1s \
316
317
  {% if application_type == 'PythonModule' or application_type == 'PythonFile' %}
317
318
  {% if not 'torch' in includes %}
318
319
  # If torch is installed, we can skip installing Python
319
- ENV PYTHON_VERSION=3.10.6-1~22.04
320
- ENV PYTHON_PIP_VERSION=22.0.2+dfsg-*
320
+ ENV PYTHON_VERSION=3.12.3-*
321
+ ENV PYTHON_PIP_VERSION=24.0+dfsg-*
321
322
 
322
323
  RUN apt update \
323
324
  && apt-get install -y --no-install-recommends --no-install-suggests \
@@ -387,11 +388,11 @@ RUN apt-get install -y --no-install-recommends --no-install-suggests \
387
388
  # Requires libnuma on aarch64
388
389
  RUN apt update \
389
390
  && apt-get install -y --no-install-recommends --no-install-suggests \
390
- libnuma1="2.0.14-*" \
391
+ libnuma1="2.0.18-*" \
391
392
  && rm -rf /var/lib/apt/lists/*
392
393
  {% endif %}
393
394
 
394
-
395
+ RUN if id "ubuntu" >/dev/null 2>&1; then touch /var/mail/ubuntu && chown ubuntu /var/mail/ubuntu && userdel -r ubuntu; fi
395
396
  RUN groupadd -f -g $GID $UNAME
396
397
  RUN useradd -rm -d /home/$UNAME -s /bin/bash -g $GID -G sudo -u $UID $UNAME
397
398
  RUN chown -R holoscan {{ working_dir }} && \
@@ -405,6 +406,9 @@ WORKDIR {{ working_dir }}
405
406
  COPY ./tools {{ working_dir }}/tools
406
407
  RUN chmod +x {{ working_dir }}/tools
407
408
 
409
+ # Remove EXTERNALLY-MANAGED directory
410
+ RUN rm -rf /usr/lib/python3.12/EXTERNALLY-MANAGED
411
+
408
412
  # Set the working directory
409
413
  WORKDIR {{ working_dir }}
410
414
 
@@ -476,4 +480,8 @@ ENV PYTHONPATH=$PYTHONPATH:{{ additional_lib_paths }}:{{ lib_dir }}
476
480
 
477
481
  {% endif %}
478
482
 
483
+ {% if input_data != None %}
484
+ COPY ./input $HOLOSCAN_INPUT_PATH
485
+ {% endif %}
486
+
479
487
  ENTRYPOINT ["/var/holoscan/tools"]
@@ -380,6 +380,7 @@ main() {
380
380
  info "Launching application ${command} ${args:1}..."
381
381
  eval ${command} "$@"
382
382
  exit_code=$?
383
+ info "Application exited with ${exit_code}."
383
384
  if [ $exit_code -ne 0 ] && [ -f /.dockerenv ] && [ "$HOLOSCAN_HOSTING_SERVICE" != "HOLOSCAN_RUN" ]; then
384
385
  newline
385
386
  c_echo "================================================================================================"
@@ -92,6 +92,14 @@ def create_run_parser(
92
92
  "between 10000 and 32767 that is not currently in use.",
93
93
  )
94
94
 
95
+ parser.add_argument(
96
+ "--rm",
97
+ dest="rm",
98
+ action="store_true",
99
+ default=False,
100
+ help="remove the container after it exits.",
101
+ )
102
+
95
103
  advanced_group = parser.add_argument_group(title="advanced run options")
96
104
 
97
105
  advanced_group.add_argument(
@@ -121,6 +121,7 @@ def _run_app(args: Namespace, app_info: dict, pkg_info: dict):
121
121
  worker_address: Optional[str] = args.worker_address if args.worker_address else None
122
122
  render: bool = args.render
123
123
  user: str = f"{args.uid}:{args.gid}"
124
+ remove: bool = args.rm
124
125
  hostname: Optional[str] = "driver" if driver else None
125
126
  terminal: bool = args.terminal
126
127
  platform_config: str = pkg_info.get("platformConfig")
@@ -174,6 +175,7 @@ def _run_app(args: Namespace, app_info: dict, pkg_info: dict):
174
175
  platform_config,
175
176
  shared_memory_size,
176
177
  args.uid == 0,
178
+ remove,
177
179
  )
178
180
 
179
181
 
@@ -266,10 +268,7 @@ def _pkg_specific_dependency_verification(pkg_info: dict) -> bool:
266
268
  Returns:
267
269
  True if all dependencies are satisfied, otherwise False.
268
270
  """
269
- if (
270
- os.path.exists("/.dockerenv")
271
- or os.environ.get("HOLOSCAN_SKIP_NVIDIA_CTK_CHECK") is not None
272
- ):
271
+ if os.path.exists("/.dockerenv"):
273
272
  logger.info("--> Skipping nvidia-ctk check inside Docker...\n")
274
273
  return True
275
274
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: holoscan-cli
3
- Version: 3.1.0
3
+ Version: 3.3.0
4
4
  Summary: Command line interface for packaging and running Holoscan applications.
5
5
  License: Apache-2.0
6
6
  Keywords: AI,holoscan,medical,streaming,HPC,nvidia,docker,container
@@ -24,7 +24,7 @@ Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
26
  Classifier: Typing :: Typed
27
- Requires-Dist: Jinja2 (>=3.1.5,<4.0.0)
27
+ Requires-Dist: Jinja2 (>=3.1.6,<4.0.0)
28
28
  Requires-Dist: packaging (>=23.1,<24.0)
29
29
  Requires-Dist: pip (>22.0.2)
30
30
  Requires-Dist: psutil (>=6.0.0,<7.0.0)
@@ -1,9 +1,9 @@
1
1
  holoscan_cli/__init__.py,sha256=caPPFDAjPzNIAzHAtpWRuWy9GshNEetcN8FQiMmNsQQ,1092
2
2
  holoscan_cli/__main__.py,sha256=sOdEmgaajrtrtVeg39MuW15BU8moal9Vz2HDcWZM__U,4891
3
- holoscan_cli/common/argparse_types.py,sha256=4AYiQbQlHNx0RBrZyi9Fmy0A5VEJByLAbpv4oS9QQVo,5553
3
+ holoscan_cli/common/argparse_types.py,sha256=KXbg09yaB73SyorWV0tLYRl-e8gydmzZVnuOlr-_kd0,5948
4
4
  holoscan_cli/common/artifact_sources.py,sha256=LIz2OFZmCJNRCn5_qkyncEaEjwwpAbzZzBAlE3tnSjs,5728
5
5
  holoscan_cli/common/constants.py,sha256=4yXMmz-PzHth5Qy4zt4E5bvpG6eQN3KQrjhyagRFDGw,4866
6
- holoscan_cli/common/dockerutils.py,sha256=-gNdxzLh-nQWI-hJUQI-O5BM9OeqJkNa5R3DvVQXu2Q,17318
6
+ holoscan_cli/common/dockerutils.py,sha256=lbDt_TCB8b74FRJljvpV3s_zVD-E4FoH2-3rI8O_BbM,17684
7
7
  holoscan_cli/common/enum_types.py,sha256=qdqMum01uM0-qrF2jyk1GYGoh76xBJsBUX9cvxVbVtA,1711
8
8
  holoscan_cli/common/exceptions.py,sha256=ubN33Av69Xm_CUVC_5DeKx_zO8qfIc_T-_S18xDQguE,2999
9
9
  holoscan_cli/common/sdk_utils.py,sha256=uDMOM_Jq3SnzDROrFERc8krDS6-BkhOebKV2h9I_-0Y,6659
@@ -13,27 +13,27 @@ holoscan_cli/nics/__init__.py,sha256=IMHmlnYvJxjlJGi1UxwRG0deK4w9M7-_WWDoCqKcjJE
13
13
  holoscan_cli/nics/nics.py,sha256=xcpo8uwQDJ7-46rPR-BEAWkyKHZOZ19gl9ahuxLNphs,1258
14
14
  holoscan_cli/package-source.json,sha256=-Cheb17hJqV7-CJktvj9RATIM_oA00k6_VPpFkIlPAc,1326
15
15
  holoscan_cli/packager/__init__.py,sha256=8uVz-FlG2vJV7Cz8ICOajioBbI9An5h-dRtSrkMCXZo,744
16
- holoscan_cli/packager/arguments.py,sha256=h29zdNctHjGm5s9MihNa4VtrcyXpR8rn4wmKFyBtHXw,5739
16
+ holoscan_cli/packager/arguments.py,sha256=Ko98jIOURjcybM7ty3CSzHWWc67gm4wvVOj2GZtgADI,5855
17
17
  holoscan_cli/packager/config_reader.py,sha256=oE0Tnp7v9dh_qAj6nPap-_R-YGLpYKGh09_FSV9oqVA,7352
18
- holoscan_cli/packager/container_builder.py,sha256=3y9UniwXK-lCBDZVvtrdqqpG00LwGrnk1Xr7w1CjCRg,17669
18
+ holoscan_cli/packager/container_builder.py,sha256=bGGcN2YjRFfvJiLsL_DjznomwkPtrdjcVnTteMz9NX0,18560
19
19
  holoscan_cli/packager/manifest_files.py,sha256=jueQMgZzQ9DhP2KGC1YdndDNwJl3ECunEKicBb3Z9Mc,5957
20
20
  holoscan_cli/packager/models.py,sha256=t3HXROo-obN5iNjKOkp8JvL6WuGP4QSRVZzET6V1wmI,3758
21
- holoscan_cli/packager/package_command.py,sha256=woveQzQ3DSmygwUCy66QuWi49mq31sibWAfzrljdfew,6357
22
- holoscan_cli/packager/packager.py,sha256=2Rykbb7pD3Ve0p_H0F0xNHr3J-moliTm8CNIhDWkRxI,4728
23
- holoscan_cli/packager/parameters.py,sha256=ipxOuCMnbq5OzdmGnehxIElXX6YS_ZofqQH3CZgr22s,18693
21
+ holoscan_cli/packager/package_command.py,sha256=U3hu0mA8dWyZwN7zzm7hptam8tJDJeG4jLMGLTg7Lqk,6743
22
+ holoscan_cli/packager/packager.py,sha256=tUM5k-tlvUMq-LzAokub77s_D_6NDJlnRkXSZIuYnmk,4728
23
+ holoscan_cli/packager/parameters.py,sha256=fSox76djvwV0Qf9q66FJIVbJheYQjtVpxMKCTnaAEQI,19166
24
24
  holoscan_cli/packager/platforms.py,sha256=H9AMr83YkW_Vx8cpp6qJLDCLqa2lcVnSAfkKc6vl6iU,16721
25
- holoscan_cli/packager/templates/Dockerfile.jinja2,sha256=BMNWtv0n1F6lP5H7RiKb8iUVZTtHvDgQCSHC_PpuBgE,16982
25
+ holoscan_cli/packager/templates/Dockerfile.jinja2,sha256=UyRNcZhNWVRj1qaEav0HgIzuepoYhUL4CPaJQ0oZJog,17329
26
26
  holoscan_cli/packager/templates/dockerignore,sha256=zzBkA9eWgPW4KWyObuYjp13bv_m24AnFUgoENGNhMcY,1755
27
- holoscan_cli/packager/templates/tools.sh,sha256=q-LT31TfUPiSS6IWrESDJcR_F8dCU0Tnl8w3xTbaW6M,13509
27
+ holoscan_cli/packager/templates/tools.sh,sha256=DnBs-XGWmxSz4XyspSMYwBajDXqUWQgUYD0HxtDw-88,13566
28
28
  holoscan_cli/py.typed,sha256=Z4hkVtwnqwhmVXOMES05WQZWjt4_rFEuditXTouPUJQ,684
29
29
  holoscan_cli/runner/__init__.py,sha256=N3dOMkOWT3adYk_pRKqn2zYgZjVCkpn5u7xatA9_aWQ,738
30
30
  holoscan_cli/runner/resources.py,sha256=R7wLnfwsG67jJD6U8d_gvteycsLPPDfWDYimAmnC-N4,5996
31
- holoscan_cli/runner/run_command.py,sha256=5QKK70xng36LtYyPHz43YrocTLUxDh6h6UNTeHuIaSQ,7148
32
- holoscan_cli/runner/runner.py,sha256=1imprOaey_RYdNwwtXWTL9IfqyG3Z_DB82FInSo1YUk,10566
31
+ holoscan_cli/runner/run_command.py,sha256=CnSyyq0y9rv6kkRtSOi3kOGHuRDLv2RDQ3JUWZ6U-YE,7320
32
+ holoscan_cli/runner/runner.py,sha256=9TqvzBL5z1boGQXvlBiPiuuMDMg7dQlo40YXO1Le604,10521
33
33
  holoscan_cli/version/__init__.py,sha256=1pf-RBR16STdFXsh82bYly_lUyv1MgxuczbLOTDJRto,743
34
34
  holoscan_cli/version/version.py,sha256=FL4DUcQ2FA4eyvL8YjR2rcdPCduMnbTBhLNeXlESLsI,1738
35
- holoscan_cli-3.1.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
36
- holoscan_cli-3.1.0.dist-info/METADATA,sha256=OqmahGLJJDu652yOqvDA1a-bNIFS83DffuL6uZOgLAs,3978
37
- holoscan_cli-3.1.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
38
- holoscan_cli-3.1.0.dist-info/entry_points.txt,sha256=ZbJklrhFtmmhqcGvGizL_4Pf9FTRgmZ11LblKPbj8yo,95
39
- holoscan_cli-3.1.0.dist-info/RECORD,,
35
+ holoscan_cli-3.3.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
36
+ holoscan_cli-3.3.0.dist-info/METADATA,sha256=7H1jRE5ZdeDudMnE-Hshj9DkSKG0nvNCOodgOXMOVQM,3978
37
+ holoscan_cli-3.3.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
38
+ holoscan_cli-3.3.0.dist-info/entry_points.txt,sha256=ZbJklrhFtmmhqcGvGizL_4Pf9FTRgmZ11LblKPbj8yo,95
39
+ holoscan_cli-3.3.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.2
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any