Resource Downloader#

Currently, we provide two resource downloader init containers for NGC and for manual uploading. These containers allow you to download the resource files (e.g an avatar USD scene or an Unreal project) onto the persistent volume of the microservice pod. Alternatively, you have the option to create your own init container to download the resources from any remote storage.

NGC Resource Downloader#

NGC is an NVIDIA file storage system. The ngc-resource-downloader init container will download resources from NGC. For that, one or several NGC resource paths can be provided in the params section of the microservice using the resource downloader.

If needed, a secret with the NGC API key can be used to access restricted content on NGC.

# Single resource example (remoteResourcePath is a string)
resourceDownload:
  remoteResourcePath: nvidia/ace/default-avatar-scene:1.0.0
  secretName: ngc-api-key-secret
  image: nvcr.io/nvidia/ace/ngc-resource-downloader:1.1.4

# Multi resources example (remoteResourcePath is a map)
resourceDownload:
  remoteResourcePath:
    unrealEngineProject: "your-org/your-team/ia-unreal-renderer-asset-metahuman-example:0.1.0"
    metahumanPak: "your-org/your-team/ia-unreal-renderer-asset-metahuman-configuration-example:0.1.0"
    scenePak: "your-org/your-team/ia-unreal-renderer-asset-scene-configuration-example:0.1.0"
  secretName: ngc-api-key-secret
  image: nvcr.io/nvidia/ace/ngc-resource-downloader:1.1.4

Before deploying the UCS app, you must create a Kubernetes secret. The secret.yaml configuration should look like the following snippet.

apiVersion: v1
data:
  NGC_CLI_API_KEY: "******"
kind: Secret
metadata:
  name: ngc-api-key-secret
  namespace: animation-pipeline
type: Opaque

Alternatively, when run from docker, the remote resource paths can be provided via ENV variables.

# Single resource example (remoteResourcePath is a string)
REMOTE_RESOURCE_PATH=nvidia/ace/default-avatar-scene:1.0.0
# Multi resources example (remoteResourcePath is a map)
REMOTE_RESOURCE_PATH="{'unrealEngineProject': 'your-org/your-team/ia-unreal-renderer-asset-metahuman-example:0.1.0', 'metahumanPak': 'your-org/your-team/ia-unreal-renderer-asset-metahuman-configuration-example:0.1.0', 'scenePak': 'your-org/your-team/ia-unreal-renderer-asset-scene-configuration-example:0.1.0'}"

$ docker run --rm --name ngc_resource_downloader -v /path/to/your/resource/folder:/mnt/resources -e DESTINATION_RESOURCE_PATH=/mnt/resources -e REMOTE_RESOURCE_PATH=$REMOTE_RESOURCE_PATH -e NGC_CLI_API_KEY=$NGC_CLI_API_KEY nvcr.io/nvidia/ace/ngc-resource-downloader:1.1.4

Prerequisites#

Before you upload assets to NGC space, you have to download & install NGC CLI.

Also, make sure that you have access to NGC and you know your <ORG> and <TEAM> you would like to upload your asset to. If you don’t have access to NGC, reach out to your NVIDIA contact or to the NVIDIA support or use an alternative download method.

Create a Resource in NGC for the Asset#

Use the following command to create a new resource with the name <RESOURCE_NAME> for your asset:

ngc registry resource create <ORG>/<TEAM>/<RESOURCE_NAME> --application OTHER --framework Other --format usda --precision Other --short-desc "Scene asset files for ACE"

For example, to create a resource in <ORG> (your-org-name), <TEAM> (your-ngc-team), <RESOURCE_NAME> (avatar_scene), use:

ngc registry resource create your-org-name/your-ngc-team/avatar_scene --application OTHER --framework Other --format usda --precision Other --short-desc "Scene asset files for ACE"

Uploading a Version to the NGC Resource#

To upload a version (e.g. 1) to the resource, make sure that the asset files are inside a single local folder, e.g. the /exported directory created by the Avatar Configurator including the scene file Avatar_Scene.usd and all the dependencies like textures.

To upload the resource files, provide the local <folder>’s path as an argument to the following command:

ngc registry resource upload-version your-org-name/your-ngc-team/avatar_scene:1 --source <folder>

To download a resource, use:

ngc registry resource download-version "your-org-name/your-ngc-team/avatar_scene:1"

To remove a version, use:

ngc registry resource remove your-org-name/your-ngc-team/avatar_scene:1

Manual Resource Downloader#

This manual-resource-downloader init container waits until the resources have been manually uploaded to the persistent volume. The resources need to be uploaded to the path that is passed in the environment variable DESTINATION_RESOURCE_PATH=<persistent-volume-mount-path>. After the resources have been uploaded, confirm this by adding a file called manual_resource_uploaded.txt.

In the params of the UCS app, no resource path need to be provided, as the upload is completely manual. A secret needs to be provided, even if it is not used. In that case, just create an empty dummy-secret.

resourceDownload:
  remoteResourcePath: ""
  secretName: dummy-secret
  image: nvcr.io/nvidia/ace/manual-resource-downloader:1.0.1

Here is an example with kubectl how resources could be uploaded:

  1. Get the DESTINATION_RESOURCE_PATH environment variable to your local computer.

DESTINATION_RESOURCE_PATH=$(kubectl get pod -n <your-namespace> <your-pod-name> -o jsonpath="{.spec.initContainers[?(@.name=='init')].env[?(@.name=='DESTINATION_RESOURCE_PATH')].value}")
  1. Copy the files from your local computer to the pod to the DESTINATION_RESOURCE_PATH.

cd <your-local-directory>
kubectl cp . -c init -n <your-namespace> <your-pod-name>:$DESTINATION_RESOURCE_PATH
  1. Verify the files are there.

kubectl exec -n <your-namespace> -c init <your-pod-name> -- ls -alh $DESTINATION_RESOURCE_PATH
  1. Create a file called manual_resource_uploaded.txt in the DESTINATION_RESOURCE_PATH to confirm the upload succeeded.

kubectl exec -n <your-namespace> -c init <your-pod-name> -- touch $DESTINATION_RESOURCE_PATH/manual_resource_uploaded.txt
  1. The init container will then complete and the microservice will start.

Create Your Own Resource Downloader#

To create your own init container to download the resources from anywhere you want, you just need to provide a download_resource.sh in the working directory.

The UCS app will then use your init container to download the resources.

  • The remoteResourcePath is available as REMOTE_RESOURCE_PATH environment variable. Note that if a single resource path is provided, the environment variable will be a string containing the resource path whereas when multiple paths are provided the environment variable value will be a map of the form: {'myFirstResource': 'my-first-resource-path', 'mySecondResource': 'my-second-resource-path', 'myThirdResource': 'my-third-resource-path'}

  • The mount path of the persistent volume is available as DESTINATION_RESOURCE_PATH environment variable. In the case when multiple resource paths are provided, every resource should be downloaded in a subdirectory named like the resource key (e.g. myFirstResource).

  • The values in the secret are available as environment variables, exactly as they are stated in the secret.

Here is an extract of the UCS manifest.yaml of an microservice using the resource downloader for illustration purposes.

image: "(($params.resourceDownload.image))"
imagePullPolicy: IfNotPresent
env:
  - name: REMOTE_RESOURCE_PATH
    value: "(($params.resourceDownload.remoteResourcePath))"
  - name: DESTINATION_RESOURCE_PATH
    value: "{{ .persistentVolume.mountPath }}"
envFrom:
  - secretRef:
      name: "(($params.resourceDownload.secretName))"
command: ["/bin/bash", "download_resource.sh"]

Your dockerfile could look something like this. In the download_resource.sh you can freely script the download of the resources.

FROM ubuntu:22.04
WORKDIR /home/my-user
COPY download_resource.sh .
ENTRYPOINT ["/bin/bash", "download_resource.sh"]

Here is an example, how you would add your own init container as params to the UCS app.

# Single resource example (remoteResourcePath is a string)
resourceDownload:
  remoteResourcePath: my-resource-path
  secretName: my-secret
  image: my-resource-downloader:1.2.3

# Multi resources example (remoteResourcePath is a map)
resourceDownload:
  remoteResourcePath:
    myFirstResource: my-first-resource-path
    mySecondResource: my-second-resource-path
    myThirdResource: my-third-resource-path
  secretName: my-secret
  image: my-resource-downloader:1.2.3