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.
- holoscan_cli/common/argparse_types.py +15 -1
- holoscan_cli/common/dockerutils.py +19 -3
- holoscan_cli/packager/arguments.py +2 -0
- holoscan_cli/packager/container_builder.py +43 -17
- holoscan_cli/packager/package_command.py +34 -20
- holoscan_cli/packager/packager.py +1 -1
- holoscan_cli/packager/parameters.py +25 -8
- holoscan_cli/packager/templates/Dockerfile.jinja2 +32 -24
- holoscan_cli/packager/templates/tools.sh +1 -0
- holoscan_cli/runner/run_command.py +8 -0
- holoscan_cli/runner/runner.py +3 -4
- {holoscan_cli-3.1.0.dist-info → holoscan_cli-3.3.0.dist-info}/METADATA +2 -2
- {holoscan_cli-3.1.0.dist-info → holoscan_cli-3.3.0.dist-info}/RECORD +16 -16
- {holoscan_cli-3.1.0.dist-info → holoscan_cli-3.3.0.dist-info}/WHEEL +1 -1
- {holoscan_cli-3.1.0.dist-info → holoscan_cli-3.3.0.dist-info}/LICENSE +0 -0
- {holoscan_cli-3.1.0.dist-info → holoscan_cli-3.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -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=
|
|
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
|
-
|
|
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=
|
|
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.
|
|
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.
|
|
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.
|
|
173
|
+
f"Saving {platform_parameters.tag} to {build_result.tarball_filename}..."
|
|
165
174
|
)
|
|
166
175
|
docker_export_tarball(
|
|
167
|
-
build_result.
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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.
|
|
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.
|
|
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
|
|
234
|
-
return self.
|
|
233
|
+
def tarball_filename(self) -> Optional[str]:
|
|
234
|
+
return self._tarball_filename
|
|
235
235
|
|
|
236
|
-
@
|
|
237
|
-
def
|
|
238
|
-
self.
|
|
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
|
-
|
|
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.
|
|
200
|
+
libvulkan1="1.3.275.0-*" \
|
|
201
201
|
# X11 support \
|
|
202
|
-
libgl1="1.
|
|
202
|
+
libgl1="1.7.0-*" \
|
|
203
203
|
# Wayland support \
|
|
204
|
-
libwayland-client0="1.
|
|
205
|
-
libwayland-egl1="1.
|
|
206
|
-
libxkbcommon0="1.
|
|
207
|
-
libdecor-0-plugin-1-cairo="0.
|
|
208
|
-
libegl1="1.
|
|
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.
|
|
217
|
-
ENV PYTHON_PIP_VERSION=
|
|
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.
|
|
227
|
-
libnuma1="2.0.
|
|
228
|
-
libhwloc15="2.
|
|
229
|
-
libopenblas0="0.3.
|
|
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-
|
|
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
|
-
|
|
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.
|
|
295
|
-
libnvinfer-plugin10="10.
|
|
296
|
-
libnvonnxparsers10="10.
|
|
297
|
-
libcusparselt0="0.
|
|
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.
|
|
320
|
-
ENV PYTHON_PIP_VERSION=
|
|
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.
|
|
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(
|
holoscan_cli/runner/runner.py
CHANGED
|
@@ -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.
|
|
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.
|
|
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=
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
22
|
-
holoscan_cli/packager/packager.py,sha256=
|
|
23
|
-
holoscan_cli/packager/parameters.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
32
|
-
holoscan_cli/runner/runner.py,sha256=
|
|
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.
|
|
36
|
-
holoscan_cli-3.
|
|
37
|
-
holoscan_cli-3.
|
|
38
|
-
holoscan_cli-3.
|
|
39
|
-
holoscan_cli-3.
|
|
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,,
|
|
File without changes
|
|
File without changes
|