Skip to content

Commit 6df6364

Browse files
mocsharptbirdso
andauthored
DevContainer for Holohub (#430)
* Hide cat error when file doesn't exist Signed-off-by: Victor Chang <vicchang@nvidia.com> * DevContainer for Holohub applications Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add readme for Holohub Dev Container Signed-off-by: Victor Chang <vicchang@nvidia.com> * Remove unused packages Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add additional VS Code launch profiles Signed-off-by: Victor Chang <vicchang@nvidia.com> * Refactor launch and vscode to share same docker options Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add instructions for stepping into HSDK code Signed-off-by: Victor Chang <vicchang@nvidia.com> * Fix volme bind argument syntax for DevContainer Signed-off-by: Victor Chang <vicchang@nvidia.com> * Remove preLaunchTask from compound tasks ... - adjust startup delays for dETT app - remove user's home directory if exists Signed-off-by: Victor Chang <vicchang@nvidia.com> * Run in privileged mode on IGX Signed-off-by: Victor Chang <vicchang@nvidia.com> * Fix remove user's home directory command Signed-off-by: Victor Chang <vicchang@nvidia.com> * Fine tune start up delays so the app would start on IGX. - Remove debugpy launch profiles - Group launch profiles by application - Update README Signed-off-by: Victor Chang <vicchang@nvidia.com> * Fix group-add with actual group ID and mount ConncetX devices if available Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add note to clear build cache Signed-off-by: Victor Chang <vicchang@nvidia.com> * Update README with build tips Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add note for codespace and vscode usage Signed-off-by: Victor Chang <vicchang@nvidia.com> * Apply suggestions from code review Co-authored-by: Tom Birdsong <40648863+tbirdso@users.noreply.github.com> Signed-off-by: Victor Chang <mocsharp@users.noreply.github.com> * Install CVCUDA Python wheel Signed-off-by: Victor Chang <vicchang@nvidia.com> * Start dbus service for pythoncpp Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add troubleshooting section Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add cpp build properties and enable Go to Definition on include files Signed-off-by: Victor Chang <vicchang@nvidia.com> * Set presentation options for build tasks Signed-off-by: Victor Chang <vicchang@nvidia.com> * Enable pythoncpp debugger when pkexec exists Signed-off-by: Victor Chang <vicchang@nvidia.com> * README cleanup Signed-off-by: Victor Chang <vicchang@nvidia.com> * Fix command description formatting Signed-off-by: Victor Chang <vicchang@nvidia.com> * Note for cleaning up VSC generated container images Signed-off-by: Victor Chang <vicchang@nvidia.com> * Add python analysis paths Signed-off-by: Victor Chang <vicchang@nvidia.com> --------- Signed-off-by: Victor Chang <vicchang@nvidia.com> Signed-off-by: Victor Chang <mocsharp@users.noreply.github.com> Co-authored-by: Tom Birdsong <40648863+tbirdso@users.noreply.github.com>
1 parent bc7a930 commit 6df6364

File tree

30 files changed

+3003
-409
lines changed

30 files changed

+3003
-409
lines changed

.devcontainer/Dockerfile

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# syntax=docker/dockerfile:1
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
ARG HOLOHUB_BASE_IMAGE
19+
FROM ${HOLOHUB_BASE_IMAGE}
20+
21+
ARG WORKSPACE_DIR=/workspace/holohub
22+
23+
# Keep the user as holoscan since the Holoscan Container already has the user setup
24+
ARG USERNAME=holoscan
25+
ARG USER_UID=1000
26+
ARG USER_GID=$USER_UID
27+
28+
# Remove existing home directory if exists
29+
RUN if [ -d "/home/$USERNAME" ] ; then ls -l /home/$USERNAME && rm -rf /home/$USERNAME ; fi
30+
31+
# Create the user
32+
RUN groupadd --gid $USER_GID $USERNAME \
33+
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
34+
# [Optional] Add sudo support. Omit if you don't need to install software after connecting.
35+
&& apt-get update \
36+
&& apt-get install -y sudo \
37+
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
38+
&& chmod 0440 /etc/sudoers.d/$USERNAME \
39+
&& chown -R $USERNAME /home/$USERNAME
40+
41+
# [Optional] Uncomment this section to install additional vcpkg ports.
42+
# RUN su vscode -c "${VCPKG_ROOT}/vcpkg install <your-port-name-here>"
43+
44+
# Install additional packages
45+
RUN apt-get update \
46+
&& export DEBIAN_FRONTEND=noninteractive \
47+
&& apt-get -y install --no-install-recommends \
48+
build-essential \
49+
ccache \
50+
gdb \
51+
git-lfs \
52+
&& apt-get autoremove -y \
53+
&& apt-get clean -y \
54+
&& rm -rf /var/lib/apt/lists/*
55+
56+
# Set the default user.
57+
# (See https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user)
58+
USER $USERNAME
59+
60+
ENV PYTHONPATH=/usr/local/lib/python3.10/dist-packages:$PYTHONPATH

.devcontainer/README.md

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
# Holohub Dev Containers
2+
3+
Holohub uses [Development Containers](https://containers.dev/) to provide consistent and convenient development environments for [Holoscan](https://developer.nvidia.com/holoscan-sdk) and [Holohub](https://github.com/nvidia-holoscan/holohub). This guide covers using the Holohub Dev Container with [Visual Studio Code](https://code.visualstudio.com/).
4+
5+
> 💡 Note: This guide is specific to the Linux development environment and is tested on Ubuntu 22.04 LTS.
6+
7+
> 💡 Note: This Dev Container does not support [Github Codespaces](https://github.com/features/codespaces) and does not support the *Open Folder in Dev Container* feature from VS Code. Please use the following guide to start the Holohub Dev Container.
8+
9+
## Prerequisites
10+
11+
- [NVIDIA CUDA Toolkit](https://developer.nvidia.com/cuda-downloads)
12+
- [Docker](https://docs.docker.com/engine/install/)
13+
- [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
14+
- [VS Code](https://code.visualstudio.com/) with the [Dev Container Extension Pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
15+
- Install [Dev Container Extension Pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) via the command line
16+
```bash
17+
code --install-extension ms-vscode-remote.remote-containers
18+
```
19+
20+
### Steps
21+
22+
1. Clone the Repository
23+
```bash
24+
git clone git@github.com:nvidia-holoscan/holohub.git
25+
```
26+
2. Open the cloned directory in the terminal.
27+
28+
3. Launch a Dev Container with the `./dev_container` script as follows:
29+
30+
```bash
31+
./dev_container vscode
32+
```
33+
34+
The above command starts a new Dev Container for Holohub using the default [Dockerfile](../Dockerfile).
35+
36+
37+
4. VS Code will build and initialize the selected Dev Container. This can take a few minutes for the first time.
38+
39+
5. Once initialized, a new VS Code window will open with the following prompts. Click **Yes** and **Trust Folder & Continue** to continue the Dev Container build process.
40+
41+
![VS Code External Application](./static/vscode-prompt-ext-app.png) ![VS Code Trust Directory](./static/vscode-prompt-trust.png)
42+
43+
6. When ready, the Holohub directory is mirrored into the container under `/workspace/holohub` to preserve any changes.
44+
45+
> 💡 Note: VS Code creates a new container image for each Dev Container instance. To clean up the container images, run the following command in the terminal:
46+
> ```bash
47+
> docker images --format '{{.Repository}}:{{.Tag}}' | grep '^vsc-holohub' | xargs -r docker rmi
48+
> ```
49+
50+
51+
### Debugging Holohub Applications
52+
53+
Most Holohub applications are pre-configured with one or more launch profiles. Click the **Run & Debug** tab and select the application you want to run/debug from the dropdown.
54+
55+
> 💡 Note: Some applications requires special instructions for debugging. Please refer to the [Application-Specific Dockerfile](#application-specific-dockerfile) for more information.
56+
57+
#### Debugging Multi-Fragment Applications
58+
59+
To debug multi-fragment applications, find and locate launch profiles prefixed with `(compound)`.
60+
61+
For example, the [Distributed Endoscopy Tool Tracking](../applications/endoscopy_tool_tracking_distributed/) application is configured with `(compound) endoscopy_tool_tracking_distributed/cpp` and `(compound) endoscopy_tool_tracking_distributed/python` launch profiles.
62+
63+
Each of these compound launch profiles links to three pre-configured launch profiles, one for each fragment (`video_in`, `inference`, and `viz`):
64+
65+
- `(compound) endoscopy_tool_tracking_distributed/cpp`
66+
- `(gdb) endoscopy_tool_tracking_distributed/cpp - video_in fragment`
67+
- `(gdb) endoscopy_tool_tracking_distributed/cpp - inference fragment`
68+
- `(gdb) endoscopy_tool_tracking_distributed/cpp - viz fragment`
69+
- `(compound) endoscopy_tool_tracking_distributed/python`
70+
- `(gdb) endoscopy_tool_tracking_distributed/python - video_in fragment`
71+
- `(gdb) endoscopy_tool_tracking_distributed/python - inference fragment`
72+
- `(gdb) endoscopy_tool_tracking_distributed/python - viz fragment`
73+
74+
When you start debugging with one of these compound launch profiles, VS Code starts three terminals to build the application, one terminal per fragment. After each terminal completes the build process, VS Code launches another terminal to start the fragment. This compound task feature lets us launch and debug all three fragments simultaneously.
75+
76+
> 💡 Tip: If VS Code does not launch all three debugger terminals, close all terminals first, then start the compound launch profile again. If the problem persists, try adjusting the start-up delays in the [tasks.json](../.vscode/tasks.json) file. Refer to the [troubleshooting](#troubleshooting) section for more information.
77+
78+
79+
> 💡 Note: Launch profiles prefixed with `(compound)` for Python applications default to `debugpy` debugger, which only allows debugging of Python code. To debug both Python and C++ code, modify the compound launch profile in the [launch.json](../.vscode/launch.json) and change `(debugpy)` to `(pythoncpp)`.
80+
81+
82+
83+
84+
#### Step into Holoscan Source Code
85+
86+
The Holohub Dev Container derives from the [Holoscan NGC Container](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/containers/holoscan), which supports debugging of Holoscan source code in C++ and Python. To simplify the process, add the Holoscan source code to the workspace by clicking the **Add Folder to Workspace** menu item from the **File** menu.. Enter `/workspace/holoscan-sdk/` in the **Add Folder to Workspace** dialog box. If VS Code prompts you to reload the window, please do so. Expect to see both the *holohub* and *holoscan-sdk* folders appear under the Explorer tab.
87+
88+
![alt text](static/vscode-explorer.png)
89+
90+
**Let's give it a try:**
91+
92+
Expand the **holoscan-sdk** folder and open `application.cpp` file from `src/core/` directory.
93+
Please scroll down to find the `void Application::run()` function and set a breakpoint inside the function.
94+
95+
With any launch profile prefixed with `gdb` or `pythoncpp`, hit F5 to start a new debugging session. Expect the debugger to hit the breakpoint in the `Application::run()` function.
96+
97+
> 💡 Important: [Holoscan NGC Container](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/containers/holoscan) version 2.3.0 or later version is required to enable debugging of Holoscan source code.
98+
99+
> ⚠️ Warning: Build error may occur when switching between building inside and outside the Dev Container. When this happens, execute the following command to clear the build cache:
100+
>
101+
> ```bash
102+
> ./run clear_cache
103+
> ```
104+
105+
> ⚠️ Warning: Build error may occur if an application provides its own Dockerfile with additional dependencies. In this case, refer to the [Application-Specific Dockerfile](#application-specific-dockerfile) section to launch a new Dev Container session with the appropriate Docker image.
106+
107+
## Advanced Options
108+
109+
### Application-Specific Dockerfile
110+
111+
For Holohub applications that bundle with a Dockerfile with additional dependencies and tools, pass the application's name to the `./dev_container` script.
112+
113+
**Usage:**
114+
115+
```bash
116+
./dev_container vscode <application_name> [--language [cpp|python]]
117+
```
118+
119+
Take the [endoscopy_depth_estimation](../applications/endoscopy_depth_estimation) application as an example. The command will launch a Dev Container using [applications/endoscopy_depth_estimation/Dockerfile](../applications/endoscopy_depth_estimation/Dockerfile) as the base image that builds `OpenCV`:
120+
121+
```bash
122+
./dev_container vscode endoscopy_depth_estimation
123+
```
124+
125+
The `language` argument is optional with `cpp` as default. This argument allows you to use a language-specific Dockerfile when available.
126+
127+
128+
### Custom Base Image/Dockerfile
129+
130+
The `./dev_container vscode` script can launch a Dev Container using a custom base image and/or Dockerfile.
131+
132+
**Usage:**
133+
134+
```bash
135+
./dev_container vscode --base_img <image>
136+
```
137+
138+
For example, if an application is designed for Holoscan 1.0 on NVIDIA IGX Orin with integrated GPU, you may want to use Holsocan 1.0.3 as the base image with iGPU support:
139+
140+
```bash
141+
./devcontainer vscode --base_img nvcr.io/nvidia/clara-holoscan/holoscan:v1.0.3-igpu
142+
```
143+
144+
In addition, if you have a custom Dockerfile that you would like to use on top of the base image, you may pass it to the `./dev_container` script as follows:
145+
146+
147+
```bash
148+
./devcontainer vscode --base_img nvcr.io/nvidia/clara-holoscan/holoscan:v1.0.3-igpu --docker_file /path/to/my/Dockerfile
149+
```
150+
151+
Refer to the [Add a Custom Dockerfile](#add-a-custom-dev-container) section if you have your own Dockerfile.
152+
153+
```Dockerfile
154+
ARG BASE_IMAGE
155+
156+
FROM ${BASE_IMAGE} AS base
157+
```
158+
159+
### Additional Options
160+
161+
Use the `-h` or `--help` option to see all available options for the `./dev_container` script:
162+
163+
```bash
164+
$ ./dev_container vscode -h
165+
166+
Launch VSCode in DevContainer
167+
168+
Launch a VSCode instance in a Docker container with the development environment.
169+
Usage: ./dev_container vscode <application_name> [options]
170+
171+
Options:
172+
application_name: Name of an existing Holohub application found in the applications folder.
173+
If specified and exists: the application-provided DevContainer configuration is used.
174+
Otherwise, the top-level DevContainer configuration.
175+
--base_img: Fully qualified base image name, e.g. holoscan-sdk-dev:latest
176+
--docker_file: Path to Dockerfile to use for building container.
177+
Defaults to:
178+
- Application-provided "Dockerfile", if it exists;
179+
- Otherwise the top-level HoloHub "Dockerfile"
180+
--language : Specify the app language implementation to run.
181+
Some applications provide both `cpp` and `python` implementations.
182+
--docker_opts : Additional options to pass to the Docker launch
183+
```
184+
185+
## Contributing
186+
187+
> 💡 Note: See [CONTRIBUTING.md](../CONTRIBUTING.md) for details on how to contribute to Holohub. This section describes adding a custom Dockerfile and Dev Container for a Holohub application.
188+
189+
### Add a Custom Dockerfile
190+
191+
The following steps allow the `./devcontainer vscode` script to find your custom `Dockerfile`:
192+
193+
- Create a new `Dockerfile` in your application's root directory or a language-specific directory:
194+
195+
```bash
196+
applications/my_application/
197+
├── Dockerfile # option 1: put the Dockefile in the root of the application's directory
198+
├── cpp
199+
│ └── Dockerfile # option 2: put the Dockerfile in a language-specific directory
200+
└── python
201+
└── Dockerfile # option 2: same as above
202+
```
203+
- Include the following at the top of your custom `Dockerfile`:
204+
205+
```Dockerfile
206+
ARG BASE_IMAGE
207+
FROM ${BASE_IMAGE} as base
208+
```
209+
210+
### Add a Custom Dev Container
211+
212+
Using the following steps enables the `./devcontainer vscode` script to find your custom Dev Container:
213+
214+
- Create a new directory in the `.devcontainer/` directory (same directory as this README file) with a name that matches the name of your application.
215+
- Create `devcontainer.json` and `Dockerfile` in the new directory:
216+
217+
```bash
218+
.devcontainer/
219+
│ └── my_application/
220+
│ ├── devcontainer.json
221+
│ └── Dockerfile
222+
└── applications/
223+
└── my_application/
224+
225+
```
226+
227+
## Troubleshooting
228+
229+
### Compound Launch Profile Issues
230+
231+
A compound launch profile may not launch all the linked launch profiles. For an example, look at the `(compound) endoscopy_tool_tracking_distributed/python` launch profile.
232+
233+
This profile links to three launch profiles, one for each fragment: `inference`, `inference`, and `viz`.
234+
235+
1. `(debugpy) endoscopy_tool_tracking_distributed/python - video_in fragment`
236+
2. `(debugpy) endoscopy_tool_tracking_distributed/python - inference fragment`
237+
3. `(debugpy) endoscopy_tool_tracking_distributed/python - viz fragment`
238+
239+
The second launch profile, the `inference` fragment, has `preLaunchTask` configured with the `Build endoscopy_tool_tracking_distributed (delay 3s)` task, which can be found in the [tasks.json](../.vscode/tasks.json) file. This task depends on another task called `Delay Task (3s)` with a bash command `sleep 3` via the `dependsOn` property. This delay task allows the `Build endoscopy_tool_tracking_distributed (delay 3s)` task to put a delay before building the application and enable VS Code to start a terminal session properly. Similarly, the `viz` fragment has a delay of 5 seconds configured. These default values may not work in all scenarios; adjust the sleep value to match your needs.
240+
241+
### Build Errors
242+
243+
When switching between Dev Container and other build environments, the build may fail with the following error:
244+
245+
```bash
246+
CMake Error: The current CMakeCache.txt directory /workspace/holohub/build/endoscopy_tool_tracking_distributed/CMakeCache.txt is different than the directory /home/host/github/holohub/build/endoscopy_tool_tracking_distributed where CMakeCache.txt was created.
247+
```
248+
249+
When this error occurs, run the clear cache command in the terminal or from VS Code Command Palette:
250+
251+
Terminal: `./run clear_cache`
252+
VS Code Command Pallette (`CTRL+SHIFT+P`): `Tasks: Run Task` -> `Clear Build Cache`.
253+
254+
255+
## Resources
256+
257+
- [Developing inside a Container](https://code.visualstudio.com/docs/devcontainers/containers)
258+
- [containers.dev](https://containers.dev/)
259+
- [NVIDIA Holoscan Containers](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/containers/holoscan)
260+
- [Debugging in Visual Studio Code](https://code.visualstudio.com/docs/editor/debugging)

0 commit comments

Comments
 (0)