Microservice Manifest#

The full manifest of the UCS microservice is below:

# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.

type: msapplication
specVersion: 2.5.0
name: ucf.svc.ia-unreal-renderer-microservice
chartName: ia-unreal-renderer-microservice
displayName: Unreal Renderer Microservice
description: Unreal Renderer Microservice
version: 0.1.0
category:
  functional: ""
  industry: ""
tags: []
keywords: []
nSpectId: NSPECT-3FW6-K0LU

publish: false

egress-endpoints:
  - name: anim-source
    description: "Animation data input gRPC stream"
    protocol: TCP
    scheme: grpc
    mandatory: False
    data-flow: in
  - name: prop-api
    description: "Propagate the stream add/remove api calls to another component"
    protocol: TCP
    scheme: http
    mandatory: False
    data-flow: out

ingress-endpoints:
  - name: http-api
    description: HTTP API
    protocol: TCP
    scheme: http
    mandatory: True
    data-flow: in

params:
  httpServer:
  #> description: HTTP API server configuration
  #> type: object
    port: 8021
    #> description: The port where the HTTP API server is served.
    #> type: integer
  signallingServer:
  #> description: The signalling server configuration
  #> type: object
    streamerPort: 8888
    #> description: The port that the Signalling and Web Server listens to for incoming connections from the Unreal Engine application.
    #> type: integer
    httpPort: 8080
    #> description: The port that the Signalling and Web Server uses for HTTP connections with client browsers.
    #> type: integer
    httpNodePort: 30080
    #> description: The node port that the Signalling and Web Server uses for HTTP connections with client browsers.
    #> type: integer
    peerConnectionOptions: |
      {
        "iceServers":[
          {
            "urls": ["turn:127.0.0.1:3478"],
            "username": "user",
            "credential": "password"
          }
        ], 
        "iceTransportPolicy": "relay"
      }
    #> description: Specifies the hostnames or IP addresses of any STUN and TURN servers you want the Unreal Engine application and browser to query when they need to discover their own external IP addresses.
    #> type: string
  unrealEngine:
  #> description: Unreal Engine configuration.
  #> type: object
    version: 5.3
    #> description: The short release number of the Unreal Engine used in the UE application, e.g. "5.3".
    #> type: number
  resourceDownload:
  #> description: Parameters for the resource download init container to specify how and where the UE resources are downloaded.
  #> type: object
    remoteResourcePath:
    #> description: A map of resources to download. Will be provided as "REMOTE_RESOURCE_PATH" env variable to the resource download init container.
    #> type: object
      unrealEngineProject: ""
      #> description: The remote path to the Unreal Engine packed project.
      #> type: string
      #> flags: mandatory
      metahumanPak: ""
      #> description: [Optional] The remote path to the packed MetaHuman PAK file to replace the MetaHuman assets in the project.
      #> type: string
      scenePak: ""
      #> description: [Optional] The remote path to the packed scene PAK file to replace the scene assets in the project.
      #> type: string
    destination: "/home/unreal-renderer"
    #> description: The folder, where the remote resources are downloaded to.
    #> type: string
    secretName: ""
    #> description: Name of the secret, that will be mounted into the resource download init container to provide credentials. E.g. for NGC the "NGC_CLI_API_KEY".
    #> type: string
    image: ""
    #> description: Name of the image for the resource download init container. E.g. "nvcr.io/eevaigoeixww/ace-ea/ngc-resource-downloader:1.1.4"
    #> type: string
    persistentVolumeSize: "5000Mi"
    #> description: The size of the volume required to store the UE resources and all its dependencies.
    #> type: string
  window:
  #> description: Rendering window parameters.
  #> type: object
    width: 1280
    #> description: The rendered video width.
    #> type: integer
    height: 720
    #> description: The rendered video height.
    #> type: integer
  deployment:
  #> description: Kubernetes deployment related parameters.
  #> type: object
    memoryRequest: "1Gi"
    #> description: Resource memory request for container.
    #> type: string
    memoryLimit: "4Gi"
    #> description: Resource memory limit for container.
    #> type: string
    gpuDisableAlloc: false
    #> description: When set to true, the GPU allocation is switched from hardcoded to dynamic.
    #> type: boolean
    gpuAllocLimit: 1
    #> description: Controls how many replicas run on a single GPU.
    #> type: integer
    additionalStartupArgs: ""
    #> description: Provide additional arguments that are passed to the startup command (e.g. -logcmds="LogACERuntime VeryVerbose").
    #> type: string
  propagateApi:
  #> description: Propagate API calls to another component.
  #> type: object
    route: /ue/
    #> description: API route, where the other component servers their API (http://<host>:<port>/<route>).
    #> type: string
  acePluginConfig:
  #> description: ACE plugin configurations.
  #> type: object
    numConnectionAttempts: 900
    #> description: Max number of connection attempts to the animation data source microservice.
    #> type: integer
    timeBetweenRetrySeconds: 1.0
    #> description: Time between connection retries to the animation data source microservice (seconds).
    #> type: number
    bufferLengthInSeconds: 0.1
    #> description: How many seconds of received animation data to buffer before beginning playback.
    #> type: number

tests:
  - name: dummy
    app: tests/dev/dummy.yaml
    params: tests/dev/dummy-params.yaml
    ciTrigger: false
    timeout: 10
    duration: 10
    installPreReqs: true  # Wether to install foundational services
    namespace: default  # Kubernetes namespace
    gpuNodeLabels: ""
    watchAllPods: true # OR set to false and set list of pods to watch below
    watchPods: []
    testerPods:  # At least one tester pod is required
    - name: renderer-deployment  # Name of the test pod
      startSignature: ".*"  # Signature to look for in the logs indicating start of tests. Regex is accepted
      endSignature: "Connected to SS ws://"  # Signature to look for in the logs indicating end of tests. Regex is accepted
      errorSignatures:  # Signatures that indicate test failures.  Regex is accepted
      - <REGEX1>
      - <REGEX2>


---

spec:
  - name: deployment
    type: ucf.k8s.app.deployment
    parameters:
      apptype: statefull
      statefulSetServiceName: service
      extraSpecs:
        podManagementPolicy: Parallel

  - name: init
    type: ucf.k8s.initcontainer
    parameters:
      image: "(($params.resourceDownload.image))"
      imagePullPolicy: IfNotPresent
      env:
        - name: REMOTE_RESOURCE_PATH
          value: "(($params.resourceDownload.remoteResourcePath))"
        - name: DESTINATION_RESOURCE_PATH
          value: "(($params.resourceDownload.destination))"
      envFrom:
        - secretRef:
            name: "(($params.resourceDownload.secretName))"
      volumeMounts:
      - name: asset-volume
        mountPath: "(($params.resourceDownload.destination))"

  - name: "ms"
    type: ucf.k8s.container
    parameters:
      env:
        - name: IAUEMS_HTTP_SERVER_PORT
          value: "(($params.httpServer.port))"
        - name: IAUEMS_SIGNALLING_SERVER_STREAMER_HOST
          value: "localhost"
        - name: IAUEMS_SIGNALLING_SERVER_STREAMER_PORT
          value: "(($params.signallingServer.streamerPort))"
        - name: IAUEMS_RESOURCE_DOWNLOAD_DESTINATION
          value: "(($params.resourceDownload.destination))"
        - name: IAUEMS_WINDOW_WIDTH
          value: "(($params.window.width))"
        - name: IAUEMS_WINDOW_HEIGHT
          value: "(($params.window.height))"
        - name: IAUEMS_PROPAGATE_API_ROUTE
          value: "(($params.propagateApi.route))"
        - name: IAUEMS_ACE_PLUGIN_CONFIG_NUM_CONNECTION_ATTEMPTS
          value: "(($params.acePluginConfig.numConnectionAttempts))"
        - name: IAUEMS_ACE_PLUGIN_CONFIG_TIME_BETWEEN_RETRY_SECONDS
          value: "(($params.acePluginConfig.timeBetweenRetrySeconds))"
        - name: IAUEMS_ACE_PLUGIN_CONFIG_BUFFER_LENGTH_IN_SECONDS
          value: "(($params.acePluginConfig.bufferLengthInSeconds))"
        - name: IAUEMS_ANIM_SOURCE_HOST
          value: "$egress.anim-source.address"
        - name: IAUEMS_ANIM_SOURCE_PORT
          value: "$egress.anim-source.port"
        - name: IAUEMS_PROP_API_HOST
          value: "$egress.prop-api.address"
        - name: IAUEMS_PROP_API_PORT
          value: "$egress.prop-api.port"
        - name: IAUEMS_DEPLOYMENT_ADDITIONAL_STARTUP_ARGS
          value: "(($params.deployment.additionalStartupArgs))"
        - name: IAUEMS_STREAMER_ID
          valueFrom:
            fieldRef:
              fieldPath: metadata.uid
          # https://jirasw.nvidia.com/browse/TOK-2549
        - name: CUDA_DISABLE_CONTROL
          value: "1"
        - name: GPU_DISABLE_ALLOC
          value: "(($params.deployment.gpuDisableAlloc))"
          # https://jirasw.nvidia.com/browse/TOK-2658
        - name: GPU_ALLOC_LIMIT
          value: "(($params.deployment.gpuAllocLimit))"
      image:
        repository: "nvcr.io/eevaigoeixww/ace-ea/ia-unreal-renderer-microservice"
        tag: "0.1.0"
        pullPolicy: IfNotPresent
      volumeMounts:
      - name: asset-volume
        mountPath: "(($params.resourceDownload.destination))"
      ports:
        - containerPort: $params.httpServer.port
          protocol: TCP
          name: http-api
      resources:
        requests:
          memory: $params.deployment.memoryRequest
        limits:
          memory: $params.deployment.memoryLimit
      # livenessProbe:
      #   httpGet:
      #     path: /health
      #     port: http-api
      # readinessProbe:
      #   httpGet:
      #     path: /health
      #     port: http-api
      
  - name: "signalling"
    type: ucf.k8s.container
    parameters:
      env:
        - name: IAUEMS_SIGNALLING_SERVER_STREAMER_PORT
          value: "(($params.signallingServer.streamerPort))"
        - name: IAUEMS_SIGNALLING_SERVER_HTTP_PORT
          value: "(($params.signallingServer.httpPort))"
        - name: IAUEMS_SIGNALLING_SERVER_PEER_CONNECTION_OPTIONS
          value: "(($params.signallingServer.peerConnectionOptions))"
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
      image:
        repository: "ghcr.io/epicgames/pixel-streaming-signalling-server"
        tag: "(($params.unrealEngine.version))"
        pullPolicy: IfNotPresent
      args: 
        - "--PublicIp=$(MY_POD_IP)"
        - "--StreamerPort=$(IAUEMS_SIGNALLING_SERVER_STREAMER_PORT)"
        - "--HttpPort=$(IAUEMS_SIGNALLING_SERVER_HTTP_PORT)"
        - "--peerConnectionOptions=$(IAUEMS_SIGNALLING_SERVER_PEER_CONNECTION_OPTIONS)"
      ports:
        - containerPort: $params.signallingServer.streamerPort
          protocol: TCP
          name: streamer
        - containerPort: $params.signallingServer.httpPort
          protocol: TCP
          name: web-server
      # livenessProbe:
      #   tcpSocket:
      #     port: web-server
      # readinessProbe:
      #   tcpSocket:
      #     port: web-server

  - name: restartPolicy
    type: ucf.k8s.restartPolicy
    parameters:
      policy: Always # Always / OnFailure / Never

  - name: podSecurityContext
    type: ucf.k8s.podSecurityContext
    parameters:
      runAsGroup: 1000
      runAsUser: 1000

  - name: service
    type: ucf.k8s.service
    parameters:
      # type: NodePort
      ports:
        - port: $params.httpServer.port
          targetPort: http-api
          # nodePort: 31700
          protocol: TCP
          name: http-api

  - name: nodeport
    type: ucf.k8s.service
    parameters:
      type: NodePort
      ports:
        - port: $params.signallingServer.httpPort
          targetPort: web-server
          nodePort: $params.signallingServer.httpNodePort
          protocol: TCP
          name: web-server

  - name: metrics
    type: ucf.crd.podMonitor
    parameters:
      portName: metrics
      path: /metrics

  - name: assets
    type: ucf.k8s.pvc
    parameters:
      annotations:
        helm.sh/resource-policy: "keep"
      spec:
        storageClassName: mdx-local-path
        accessModes: [ReadWriteOnce]
        resources:
          requests:
            storage: $params.resourceDownload.persistentVolumeSize

  - name: asset-volume
    type: ucf.k8s.volume
    parameters:
      persistentVolumeClaim:
        claimName: "ia-unreal-renderer-microservice-assets"