From 7a2b22792ae85804abb9f7748f2463e880f71156 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 4 Jun 2025 19:53:12 -0700 Subject: [PATCH 01/34] feat: rebase kubernetes overwrites Overview: Add the ability for a user to overwrite the entrypoint and PVCs in the sdk. DEP-157 Details: It is the first iteration of the feature. A more generic approach will be developed. --- .../dynamocomponentdeployment_types.go | 8 ++ .../dynamocomponentdeployment_controller.go | 109 +++++++++++++----- deploy/sdk/src/dynamo/sdk/cli/build.py | 12 ++ 3 files changed, 102 insertions(+), 27 deletions(-) diff --git a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go index 046a87f9c7..03f81d9345 100644 --- a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go +++ b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go @@ -80,6 +80,9 @@ type DynamoComponentDeploymentSharedSpec struct { LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty"` ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty"` Replicas *int32 `json:"replicas,omitempty"` + + // Kubernetes overwrites for the deployment + KubernetesOverwrites *KubernetesOverwrites `json:"kubernetesOverwrites,omitempty"` } type RunMode struct { @@ -108,6 +111,11 @@ type IngressSpec struct { IngressControllerClassName *string `json:"ingressControllerClassName,omitempty"` } +type KubernetesOverwrites struct { + Entrypoint *string `json:"entrypoint,omitempty"` + PVCSettings map[string]*PVC `json:"pvcSettings,omitempty"` +} + // DynamoComponentDeploymentStatus defines the observed state of DynamoComponentDeployment type DynamoComponentDeploymentStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index 76d72a88e1..e0dc634bd9 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -1337,6 +1337,69 @@ func getDynamoComponentRepositoryNameAndDynamoComponentVersion(dynamoComponent * return } +func buildPVCVolumesAndMounts( + component *v1alpha1.DynamoComponentDeployment, +) (volumes []corev1.Volume, mounts []corev1.VolumeMount) { + used := map[string]bool{} + + // addPVC adds a volume and corresponding volume mount to the pod spec based on the provided PVC configuration. + addPVC := func(volumeName string, pvc *v1alpha1.PVC) { + if pvc == nil || pvc.Name == nil { + return + } + claimName := *pvc.Name + mountPath := "/mnt/default" + if pvc.MountPoint != nil && *pvc.MountPoint != "" { + mountPath = *pvc.MountPoint + } + volume := corev1.Volume{ + Name: volumeName, + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: claimName, + }, + }, + } + mount := corev1.VolumeMount{ + Name: volumeName, + MountPath: mountPath, + } + if used[volumeName] { + for i, v := range volumes { + if v.Name == volumeName { + volumes[i] = volume + break + } + } + for i, m := range mounts { + if m.Name == volumeName { + mounts[i] = mount + break + } + } + } else { + volumes = append(volumes, volume) + mounts = append(mounts, mount) + used[volumeName] = true + } + } + + // Handle default PVC + if component.Spec.PVC != nil { + volumeName := getPvcName(component, component.Spec.PVC.Name) + addPVC(volumeName, component.Spec.PVC) + } + + // Handle overwrites + if ow := component.Spec.KubernetesOverwrites; ow != nil && ow.PVCSettings != nil { + for volumeName, pvc := range ow.PVCSettings { + addPVC(volumeName, pvc) + } + } + + return volumes, mounts +} + //nolint:gocyclo,nakedret func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx context.Context, opt generateResourceOption) (podTemplateSpec *corev1.PodTemplateSpec, err error) { podLabels := r.getKubeLabels(opt.dynamoComponentDeployment, opt.dynamoComponent) @@ -1499,33 +1562,10 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex sharedMemorySizeLimit.SetMilli(memoryLimit.MilliValue() / 2) } - volumes = append(volumes, corev1.Volume{ - Name: KubeValueNameSharedMemory, - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{ - Medium: corev1.StorageMediumMemory, - SizeLimit: &sharedMemorySizeLimit, - }, - }, - }) - volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: KubeValueNameSharedMemory, - MountPath: "/dev/shm", - }) - if opt.dynamoComponentDeployment.Spec.PVC != nil { - volumes = append(volumes, corev1.Volume{ - Name: getPvcName(opt.dynamoComponentDeployment, opt.dynamoComponentDeployment.Spec.PVC.Name), - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: getPvcName(opt.dynamoComponentDeployment, opt.dynamoComponentDeployment.Spec.PVC.Name), - }, - }, - }) - volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: getPvcName(opt.dynamoComponentDeployment, opt.dynamoComponentDeployment.Spec.PVC.Name), - MountPath: *opt.dynamoComponentDeployment.Spec.PVC.MountPoint, - }) - } + // Handle default PVC settings. Apply overwrites if the name matches, add otherwise. + pvcVolumes, pvcMounts := buildPVCVolumesAndMounts(opt.dynamoComponentDeployment) + volumes = append(volumes, pvcVolumes...) + volumeMounts = append(volumeMounts, pvcMounts...) imageName := opt.dynamoComponent.GetImage() if imageName == "" { @@ -1653,6 +1693,21 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex container.SecurityContext.RunAsUser = &[]int64{0}[0] } + if opt.dynamoComponentDeployment.Spec.KubernetesOverwrites != nil { + overwrites := opt.dynamoComponentDeployment.Spec.KubernetesOverwrites + + // Handle Entrypoint overwrite. Entrypoint needs to be renamed to Command. + if overwrites.Entrypoint != nil { + parts := strings.Fields(*overwrites.Entrypoint) + if len(parts) > 0 { + container.Command = []string{parts[0]} + if len(parts) > 1 { + container.Args = parts[1:] + } + } + } + } + containers = append(containers, container) debuggerImage := "python:3.12-slim" diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index 35df1f0c73..2ee478c6e4 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -116,6 +116,7 @@ class ServiceInfo(BaseModel): module_path: str class_name: str config: ServiceConfig + kubernetes_overwrites: t.Optional[t.Dict[str, t.Any]] = None @classmethod def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: @@ -145,12 +146,16 @@ def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: http_exposed=len(api_endpoints) > 0, api_endpoints=api_endpoints, ) + kubernetes_overwrites = None + if hasattr(service, "kubernetes_overwrites") and service.kubernetes_overwrites: + kubernetes_overwrites = service.kubernetes_overwrites.model_dump() return cls( name=name, module_path=service.__module__, class_name=service_class.__name__, config=config, + kubernetes_overwrites=kubernetes_overwrites, ) @@ -225,6 +230,13 @@ def to_dict(self) -> t.Dict[str, t.Any]: service_dict["config"]["api_endpoints"] = service["config"][ "api_endpoints" ] + + # Add kubernetes overwrites if available + if service.get("kubernetes_overwrites"): + service_dict["config"]["kubernetes_overwrites"] = service[ + "kubernetes_overwrites" + ] + services_dict.append(service_dict) result["services"] = services_dict return result From 0dad02568e381c3e935e8dc99d9711e28ac8d5cf Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 6 Jun 2025 13:13:54 -0700 Subject: [PATCH 02/34] Changes per Julien --- .../operator/api/dynamo/common/common.go | 4 + .../dynamocomponentdeployment_types.go | 11 +- ...nvidia.com_dynamocomponentdeployments.yaml | 1244 +++++++++++++++-- .../bases/nvidia.com_dynamocomponents.yaml | 984 ++++++++++++- .../nvidia.com_dynamographdeployments.yaml | 1244 +++++++++++++++-- deploy/cloud/operator/config/rbac/role.yaml | 15 - deploy/cloud/operator/go.mod | 1 + deploy/cloud/operator/go.sum | 2 + .../dynamocomponentdeployment_controller.go | 151 +- deploy/sdk/src/dynamo/sdk/cli/build.py | 16 +- examples/hello_world/hello_world.py | 1 + 11 files changed, 3320 insertions(+), 353 deletions(-) diff --git a/deploy/cloud/operator/api/dynamo/common/common.go b/deploy/cloud/operator/api/dynamo/common/common.go index 0596d1d927..287060d69e 100644 --- a/deploy/cloud/operator/api/dynamo/common/common.go +++ b/deploy/cloud/operator/api/dynamo/common/common.go @@ -62,4 +62,8 @@ type ExtraPodSpec struct { Containers []corev1.Container `json:"containers,omitempty"` ServiceAccountName string `json:"serviceAccountName,omitempty"` PriorityClassName string `json:"priorityClassName,omitempty"` + + Volumes []corev1.Volume `json:"volumes,omitempty"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` + PVCClaims []corev1.PersistentVolumeClaim `json:"pvcClaims,omitempty"` } diff --git a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go index 03f81d9345..b75d4bacde 100644 --- a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go +++ b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go @@ -66,7 +66,7 @@ type DynamoComponentDeploymentSharedSpec struct { Autoscaling *Autoscaling `json:"autoscaling,omitempty"` Envs []corev1.EnvVar `json:"envs,omitempty"` EnvFromSecret *string `json:"envFromSecret,omitempty"` - PVC *PVC `json:"pvc,omitempty"` + PVC map[string]*PVC `json:"pvcSettings,omitempty"` RunMode *RunMode `json:"runMode,omitempty"` ExternalServices map[string]ExternalService `json:"externalServices,omitempty"` @@ -81,8 +81,8 @@ type DynamoComponentDeploymentSharedSpec struct { ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty"` Replicas *int32 `json:"replicas,omitempty"` - // Kubernetes overwrites for the deployment - KubernetesOverwrites *KubernetesOverwrites `json:"kubernetesOverwrites,omitempty"` + // +optional + Entrypoint *string `json:"entrypoint,omitempty"` } type RunMode struct { @@ -111,11 +111,6 @@ type IngressSpec struct { IngressControllerClassName *string `json:"ingressControllerClassName,omitempty"` } -type KubernetesOverwrites struct { - Entrypoint *string `json:"entrypoint,omitempty"` - PVCSettings map[string]*PVC `json:"pvcSettings,omitempty"` -} - // DynamoComponentDeploymentStatus defines the observed state of DynamoComponentDeployment type DynamoComponentDeploymentStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml index b0360c0bf0..bf11527974 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml @@ -1,18 +1,3 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -397,6 +382,8 @@ spec: type: string dynamoTag: type: string + entrypoint: + type: string envFromSecret: type: string envs: @@ -1612,6 +1599,172 @@ spec: type: object priorityClassName: type: string + pvcClaims: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array schedulerName: type: string serviceAccountName: @@ -1686,140 +1839,945 @@ spec: - whenUnsatisfiable type: object type: array - type: object - ingress: - properties: - annotations: - additionalProperties: - type: string - type: object - enabled: - type: boolean - host: - type: string - hostPrefix: - type: string - hostSuffix: - type: string - ingressControllerClassName: - type: string - labels: - additionalProperties: - type: string - type: object - tls: - properties: - secretName: - type: string - type: object - useVirtualService: - type: boolean - virtualServiceGateway: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: + volumeMounts: + items: + properties: + mountPath: type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: properties: - name: + fsType: type: string - value: + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: type: string required: - - name - - value + - volumeID type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - pvc: - properties: - create: - type: boolean - mountPoint: - type: string - name: - type: string - size: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - storageClass: - type: string - volumeAccessMode: - type: string + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + enabled: + type: boolean + host: + type: string + hostPrefix: + type: string + hostSuffix: + type: string + ingressControllerClassName: + type: string + labels: + additionalProperties: + type: string + type: object + tls: + properties: + secretName: + type: string + type: object + useVirtualService: + type: boolean + virtualServiceGateway: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + pvcSettings: + additionalProperties: + properties: + create: + type: boolean + mountPoint: + type: string + name: + type: string + size: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClass: + type: string + volumeAccessMode: + type: string + type: object type: object readinessProbe: properties: diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml index a39a1b05b3..a453f615d6 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml @@ -1,18 +1,3 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -1332,6 +1317,172 @@ spec: type: object priorityClassName: type: string + pvcClaims: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array schedulerName: type: string serviceAccountName: @@ -1406,6 +1557,809 @@ spec: - whenUnsatisfiable type: object type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array type: object imagePullSecrets: items: diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml index d5a67d2493..ce6d2ae16a 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml @@ -1,18 +1,3 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -452,6 +437,8 @@ spec: type: object dynamoNamespace: type: string + entrypoint: + type: string envFromSecret: type: string envs: @@ -1667,6 +1654,172 @@ spec: type: object priorityClassName: type: string + pvcClaims: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + required: + - status + type: object + phase: + type: string + type: object + type: object + type: array schedulerName: type: string serviceAccountName: @@ -1741,140 +1894,945 @@ spec: - whenUnsatisfiable type: object type: array - type: object - ingress: - properties: - annotations: - additionalProperties: - type: string - type: object - enabled: - type: boolean - host: - type: string - hostPrefix: - type: string - hostSuffix: - type: string - ingressControllerClassName: - type: string - labels: - additionalProperties: - type: string - type: object - tls: - properties: - secretName: - type: string - type: object - useVirtualService: - type: boolean - virtualServiceGateway: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: + volumeMounts: + items: + properties: + mountPath: type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: properties: - name: + fsType: type: string - value: + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: type: string required: - - name - - value + - volumeID type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - pvc: - properties: - create: - type: boolean - mountPoint: - type: string - name: - type: string - size: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - storageClass: - type: string - volumeAccessMode: - type: string + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + ingress: + properties: + annotations: + additionalProperties: + type: string + type: object + enabled: + type: boolean + host: + type: string + hostPrefix: + type: string + hostSuffix: + type: string + ingressControllerClassName: + type: string + labels: + additionalProperties: + type: string + type: object + tls: + properties: + secretName: + type: string + type: object + useVirtualService: + type: boolean + virtualServiceGateway: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + pvcSettings: + additionalProperties: + properties: + create: + type: boolean + mountPoint: + type: string + name: + type: string + size: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClass: + type: string + volumeAccessMode: + type: string + type: object type: object readinessProbe: properties: diff --git a/deploy/cloud/operator/config/rbac/role.yaml b/deploy/cloud/operator/config/rbac/role.yaml index 694d247800..3f4c7196ba 100644 --- a/deploy/cloud/operator/config/rbac/role.yaml +++ b/deploy/cloud/operator/config/rbac/role.yaml @@ -1,18 +1,3 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/deploy/cloud/operator/go.mod b/deploy/cloud/operator/go.mod index b9049f4d0c..d67210ee0f 100644 --- a/deploy/cloud/operator/go.mod +++ b/deploy/cloud/operator/go.mod @@ -96,6 +96,7 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mattn/go-shellwords v1.0.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect diff --git a/deploy/cloud/operator/go.sum b/deploy/cloud/operator/go.sum index f8ff3373f6..771ce503f3 100644 --- a/deploy/cloud/operator/go.sum +++ b/deploy/cloud/operator/go.sum @@ -156,6 +156,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index e0dc634bd9..b5420a6e9d 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -61,6 +61,8 @@ import ( leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1" volcanov1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1" + + "github.com/mattn/go-shellwords" ) const ( @@ -1339,19 +1341,53 @@ func getDynamoComponentRepositoryNameAndDynamoComponentVersion(dynamoComponent * func buildPVCVolumesAndMounts( component *v1alpha1.DynamoComponentDeployment, -) (volumes []corev1.Volume, mounts []corev1.VolumeMount) { + sharedMemorySizeLimit resource.Quantity, +) (volumes []corev1.Volume, mounts []corev1.VolumeMount /* claims []corev1.PersistentVolumeClaim */) { + + // Keep track for overwrites. used := map[string]bool{} + // Helper: create PVC object from your custom PVC struct + createClaim := func(volumeName string, pvc *v1alpha1.PVC) *corev1.PersistentVolumeClaim { + if pvc == nil || pvc.Create == nil || !*pvc.Create { + return nil + } + claimName := getPvcName(component, pvc.Name) + storageClassName := pvc.StorageClass + return &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: claimName, + }, + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: []corev1.PersistentVolumeAccessMode{pvc.VolumeAccessMode}, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceStorage: pvc.Size, + }, + }, + StorageClassName: &storageClassName, + }, + } + } + // addPVC adds a volume and corresponding volume mount to the pod spec based on the provided PVC configuration. - addPVC := func(volumeName string, pvc *v1alpha1.PVC) { - if pvc == nil || pvc.Name == nil { + addPVC := func(crd metav1.Object, volumeName string, pvc *v1alpha1.PVC) { + if pvc == nil { + return + } + + // Use getPvcName to fall back to CRD name if pvc.Name is nil + claimName := getPvcName(crd, pvc.Name) + if claimName == "" { return } - claimName := *pvc.Name - mountPath := "/mnt/default" + + // Fallback mountPath if not provided + mountPath := fmt.Sprintf("/mnt/%s", volumeName) if pvc.MountPoint != nil && *pvc.MountPoint != "" { mountPath = *pvc.MountPoint } + volume := corev1.Volume{ Name: volumeName, VolumeSource: corev1.VolumeSource{ @@ -1360,10 +1396,12 @@ func buildPVCVolumesAndMounts( }, }, } + mount := corev1.VolumeMount{ Name: volumeName, MountPath: mountPath, } + if used[volumeName] { for i, v := range volumes { if v.Name == volumeName { @@ -1382,26 +1420,96 @@ func buildPVCVolumesAndMounts( mounts = append(mounts, mount) used[volumeName] = true } + + // TODO ? + // if claim := createClaim(volumeName, pvc); claim != nil { + // claims = append(claims, *claim) + // } } - // Handle default PVC + // Add Shared Memory Volume. + volumes = append(volumes, corev1.Volume{ + Name: KubeValueNameSharedMemory, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: corev1.StorageMediumMemory, + SizeLimit: &sharedMemorySizeLimit, + }, + }, + }) + mounts = append(mounts, corev1.VolumeMount{ + Name: KubeValueNameSharedMemory, + MountPath: "/dev/shm", + }) + + // Add standard PVC(s) if component.Spec.PVC != nil { - volumeName := getPvcName(component, component.Spec.PVC.Name) - addPVC(volumeName, component.Spec.PVC) + for volumeName, pvc := range component.Spec.PVC { + addPVC(component, volumeName, pvc) + } + } + // Add PVC overrides and extras. + if component.Spec.ExtraPodSpec != nil { + extra := component.Spec.ExtraPodSpec + + // Add Volumes from ExtraPodSpec. + for _, vol := range extra.Volumes { + if used[vol.Name] { + // Overwrite existing volume with same name + for i := range volumes { + if volumes[i].Name == vol.Name { + volumes[i] = vol + break + } + } + } else { + volumes = append(volumes, vol) + used[vol.Name] = true + } + } + + // Add VolumeMounts from ExtraPodSpec + for _, mount := range extra.VolumeMounts { + if used[mount.Name] { + // Overwrite existing mount with same name + for i := range mounts { + if mounts[i].Name == mount.Name { + mounts[i] = mount + break + } + } + } else { + mounts = append(mounts, mount) + used[mount.Name] = true + } + } - // Handle overwrites - if ow := component.Spec.KubernetesOverwrites; ow != nil && ow.PVCSettings != nil { - for volumeName, pvc := range ow.PVCSettings { - addPVC(volumeName, pvc) + // TODO: not sure about the claims in the overwrites. + // Add PVCClaims from ExtraPodSpec + for _, claim := range extra.PVCClaims { + if used[claim.Name] { + // Overwrite existing claim with same name + for i := range claims { + if claims[i].Name == claim.Name { + claims[i] = claim + break + } + } + } else { + claims = append(claims, claim) + used[claim.Name] = true + } } + } - return volumes, mounts + return volumes, mounts /*. claims */ } //nolint:gocyclo,nakedret func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx context.Context, opt generateResourceOption) (podTemplateSpec *corev1.PodTemplateSpec, err error) { + logger := log.FromContext(ctx) podLabels := r.getKubeLabels(opt.dynamoComponentDeployment, opt.dynamoComponent) if opt.isStealingTrafficDebugModeEnabled { podLabels[commonconsts.KubeLabelDynamoDeploymentTargetType] = DeploymentTargetTypeDebug @@ -1556,14 +1664,13 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex return nil, err } + // Handle default PVC settings. Apply overwrites if the name matches, add otherwise. sharedMemorySizeLimit := resource.MustParse("64Mi") memoryLimit := resources.Limits[corev1.ResourceMemory] if !memoryLimit.IsZero() { sharedMemorySizeLimit.SetMilli(memoryLimit.MilliValue() / 2) } - - // Handle default PVC settings. Apply overwrites if the name matches, add otherwise. - pvcVolumes, pvcMounts := buildPVCVolumesAndMounts(opt.dynamoComponentDeployment) + pvcVolumes, pvcMounts := buildPVCVolumesAndMounts(opt.dynamoComponentDeployment, sharedMemorySizeLimit) volumes = append(volumes, pvcVolumes...) volumeMounts = append(volumeMounts, pvcMounts...) @@ -1693,13 +1800,15 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex container.SecurityContext.RunAsUser = &[]int64{0}[0] } - if opt.dynamoComponentDeployment.Spec.KubernetesOverwrites != nil { - overwrites := opt.dynamoComponentDeployment.Spec.KubernetesOverwrites + if opt.dynamoComponentDeployment.Spec.Entrypoint != nil { + entrypoint := opt.dynamoComponentDeployment.Spec.Entrypoint // Handle Entrypoint overwrite. Entrypoint needs to be renamed to Command. - if overwrites.Entrypoint != nil { - parts := strings.Fields(*overwrites.Entrypoint) - if len(parts) > 0 { + if entrypoint != nil { + parts, err := shellwords.Parse(*entrypoint) + if err != nil { + logger.Error(err, "failed to parse entrypoint string") + } else if len(parts) > 0 { container.Command = []string{parts[0]} if len(parts) > 1 { container.Args = parts[1:] diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index 2ee478c6e4..7a5cb208a7 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -116,7 +116,7 @@ class ServiceInfo(BaseModel): module_path: str class_name: str config: ServiceConfig - kubernetes_overwrites: t.Optional[t.Dict[str, t.Any]] = None + kubernetes_overrides: t.Optional[t.Dict[str, t.Any]] = None @classmethod def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: @@ -146,16 +146,16 @@ def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: http_exposed=len(api_endpoints) > 0, api_endpoints=api_endpoints, ) - kubernetes_overwrites = None - if hasattr(service, "kubernetes_overwrites") and service.kubernetes_overwrites: - kubernetes_overwrites = service.kubernetes_overwrites.model_dump() + kubernetes_overrides = None + if hasattr(service, "kubernetes_overrides") and service.kubernetes_overrides: + kubernetes_overrides = service.kubernetes_overrides.model_dump() return cls( name=name, module_path=service.__module__, class_name=service_class.__name__, config=config, - kubernetes_overwrites=kubernetes_overwrites, + kubernetes_overrides=kubernetes_overrides, ) @@ -232,9 +232,9 @@ def to_dict(self) -> t.Dict[str, t.Any]: ] # Add kubernetes overwrites if available - if service.get("kubernetes_overwrites"): - service_dict["config"]["kubernetes_overwrites"] = service[ - "kubernetes_overwrites" + if service.get("kubernetes_overrides"): + service_dict["config"]["kubernetes_overrides"] = service[ + "kubernetes_overrides" ] services_dict.append(service_dict) diff --git a/examples/hello_world/hello_world.py b/examples/hello_world/hello_world.py index 3e3b384b7f..c44ea7fca8 100644 --- a/examples/hello_world/hello_world.py +++ b/examples/hello_world/hello_world.py @@ -71,6 +71,7 @@ class ResponseType(BaseModel): resources={"cpu": 1, "memory": "500Mi"}, workers=2, image=DYNAMO_IMAGE, + kubernetes_overrides={"entrypoint": "sh -c 'echo hello from anna'"}, ) class Backend: def __init__(self) -> None: From f4eb61e7035ef38a2ef1538ab2bfecc29794b551 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 6 Jun 2025 15:27:17 -0700 Subject: [PATCH 03/34] remove claim related stuff for now --- .../dynamocomponentdeployment_controller.go | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index b5420a6e9d..551ae3ae8b 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -33,6 +33,7 @@ import ( corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" "emperror.dev/errors" dynamoCommon "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/dynamo/common" @@ -1347,28 +1348,29 @@ func buildPVCVolumesAndMounts( // Keep track for overwrites. used := map[string]bool{} + // TODO use constructPVC() from common? // Helper: create PVC object from your custom PVC struct - createClaim := func(volumeName string, pvc *v1alpha1.PVC) *corev1.PersistentVolumeClaim { - if pvc == nil || pvc.Create == nil || !*pvc.Create { - return nil - } - claimName := getPvcName(component, pvc.Name) - storageClassName := pvc.StorageClass - return &corev1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: claimName, - }, - Spec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{pvc.VolumeAccessMode}, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceStorage: pvc.Size, - }, - }, - StorageClassName: &storageClassName, - }, - } - } + // createClaim := func(volumeName string, pvc *v1alpha1.PVC) *corev1.PersistentVolumeClaim { + // if pvc == nil || pvc.Create == nil || *pvc.Name == "" || !*pvc.Create { + // return nil + // } + // claimName := getPvcName(component, pvc.Name) + // storageClassName := pvc.StorageClass + // return &corev1.PersistentVolumeClaim{ + // ObjectMeta: metav1.ObjectMeta{ + // Name: claimName, + // }, + // Spec: corev1.PersistentVolumeClaimSpec{ + // AccessModes: []corev1.PersistentVolumeAccessMode{pvc.VolumeAccessMode}, + // Resources: corev1.VolumeResourceRequirements{ + // Requests: corev1.ResourceList{ + // corev1.ResourceStorage: pvc.Size, + // }, + // }, + // StorageClassName: &storageClassName, + // }, + // } + // } // addPVC adds a volume and corresponding volume mount to the pod spec based on the provided PVC configuration. addPVC := func(crd metav1.Object, volumeName string, pvc *v1alpha1.PVC) { @@ -1403,6 +1405,7 @@ func buildPVCVolumesAndMounts( } if used[volumeName] { + klog.Warningf("PVC volume %q was already added; overwriting with new configuration", volumeName) for i, v := range volumes { if v.Name == volumeName { volumes[i] = volume From 82838a5a24a4090efedd871eddc3b62a1d2a4873 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 6 Jun 2025 16:03:42 -0700 Subject: [PATCH 04/34] cleanup --- .../operator/api/dynamo/common/common.go | 6 +- .../dynamo/common/zz_generated.deepcopy.go | 21 +++++ .../api/v1alpha1/zz_generated.deepcopy.go | 20 ++++- .../dynamocomponentdeployment_controller.go | 85 ++++++++++--------- 4 files changed, 86 insertions(+), 46 deletions(-) diff --git a/deploy/cloud/operator/api/dynamo/common/common.go b/deploy/cloud/operator/api/dynamo/common/common.go index 287060d69e..5cb697fa9c 100644 --- a/deploy/cloud/operator/api/dynamo/common/common.go +++ b/deploy/cloud/operator/api/dynamo/common/common.go @@ -63,7 +63,7 @@ type ExtraPodSpec struct { ServiceAccountName string `json:"serviceAccountName,omitempty"` PriorityClassName string `json:"priorityClassName,omitempty"` - Volumes []corev1.Volume `json:"volumes,omitempty"` - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` - PVCClaims []corev1.PersistentVolumeClaim `json:"pvcClaims,omitempty"` + Volumes []corev1.Volume `json:"volumes,omitempty"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` + PVCClaims []corev1.PersistentVolumeClaim `json:"pvcClaims,omitempty"` } diff --git a/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go b/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go index a125300ab6..c612d05bf6 100644 --- a/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go +++ b/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go @@ -151,6 +151,27 @@ func (in *ExtraPodSpec) DeepCopyInto(out *ExtraPodSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PVCClaims != nil { + in, out := &in.PVCClaims, &out.PVCClaims + *out = make([]v1.PersistentVolumeClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtraPodSpec. diff --git a/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go b/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go index 722675a091..9cd78b7378 100644 --- a/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go @@ -263,8 +263,19 @@ func (in *DynamoComponentDeploymentSharedSpec) DeepCopyInto(out *DynamoComponent } if in.PVC != nil { in, out := &in.PVC, &out.PVC - *out = new(PVC) - (*in).DeepCopyInto(*out) + *out = make(map[string]*PVC, len(*in)) + for key, val := range *in { + var outVal *PVC + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(PVC) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } } if in.RunMode != nil { in, out := &in.RunMode, &out.RunMode @@ -304,6 +315,11 @@ func (in *DynamoComponentDeploymentSharedSpec) DeepCopyInto(out *DynamoComponent *out = new(int32) **out = **in } + if in.Entrypoint != nil { + in, out := &in.Entrypoint, &out.Entrypoint + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamoComponentDeploymentSharedSpec. diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index 551ae3ae8b..ea017fe6aa 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -247,7 +247,7 @@ func (r *DynamoComponentDeploymentReconciler) Reconcile(ctx context.Context, req modified := false // Reconcile PVC - _, err = r.reconcilePVC(ctx, dynamoComponentDeployment) + err = r.reconcilePVC(ctx, dynamoComponentDeployment) if err != nil { logs.Error(err, "Unable to create PVC", "crd", req.NamespacedName) return ctrl.Result{}, err @@ -814,39 +814,42 @@ func IsDeploymentReady(deployment *appsv1.Deployment) bool { return false } -func (r *DynamoComponentDeploymentReconciler) reconcilePVC(ctx context.Context, crd *v1alpha1.DynamoComponentDeployment) (*corev1.PersistentVolumeClaim, error) { +func (r *DynamoComponentDeploymentReconciler) reconcilePVC(ctx context.Context, crd *v1alpha1.DynamoComponentDeployment) error { logger := log.FromContext(ctx) if crd.Spec.PVC == nil { - return nil, nil - } - pvcConfig := *crd.Spec.PVC - pvc := &corev1.PersistentVolumeClaim{} - pvcName := types.NamespacedName{Name: getPvcName(crd, pvcConfig.Name), Namespace: crd.GetNamespace()} - err := r.Get(ctx, pvcName, pvc) - if err != nil && client.IgnoreNotFound(err) != nil { - logger.Error(err, "Unable to retrieve PVC", "crd", crd.GetName()) - return nil, err + return nil } + for name, pvcConfig := range crd.Spec.PVC { + pvc := &corev1.PersistentVolumeClaim{} + pvcName := types.NamespacedName{Name: getPvcName(crd, pvcConfig.Name), Namespace: crd.GetNamespace()} - // If PVC does not exist, create a new one - if err != nil { - if pvcConfig.Create == nil || !*pvcConfig.Create { - logger.Error(err, "Unknown PVC", "pvc", pvc.Name) - return nil, err - } - pvc = constructPVC(crd, pvcConfig) - if err := controllerutil.SetControllerReference(crd, pvc, r.Client.Scheme()); err != nil { - logger.Error(err, "Failed to set controller reference", "pvc", pvc.Name) - return nil, err + err := r.Get(ctx, pvcName, pvc) + if err != nil && client.IgnoreNotFound(err) != nil { + logger.Error(err, "Unable to retrieve PVC", "crd", crd.GetName(), "pvcKey", name) + return err } - err = r.Create(ctx, pvc) + + // If PVC does not exist, create a new one if err != nil { - logger.Error(err, "Failed to create pvc", "pvc", pvc.Name) - return nil, err + if pvcConfig.Create == nil || !*pvcConfig.Create { + logger.Error(err, "Unknown PVC", "pvc", pvc.Name, "pvcKey", name) + return err + } + pvc = constructPVC(crd, *pvcConfig) + if err := controllerutil.SetControllerReference(crd, pvc, r.Client.Scheme()); err != nil { + logger.Error(err, "Failed to set controller reference", "pvc", pvc.Name, "pvcKey", name) + return err + } + err = r.Create(ctx, pvc) + if err != nil { + logger.Error(err, "Failed to create pvc", "pvc", pvc.Name, "pvcKey", name) + return err + } + logger.Info("PVC created", "pvc", pvcName, "pvcKey", name) } - logger.Info("PVC created", "pvc", pvcName) } - return pvc, nil + + return nil } func (r *DynamoComponentDeploymentReconciler) setStatusConditions(ctx context.Context, req ctrl.Request, conditions ...metav1.Condition) (dynamoComponentDeployment *v1alpha1.DynamoComponentDeployment, err error) { @@ -1380,7 +1383,7 @@ func buildPVCVolumesAndMounts( // Use getPvcName to fall back to CRD name if pvc.Name is nil claimName := getPvcName(crd, pvc.Name) - if claimName == "" { + if claimName == "" || (pvc.Name != nil && *pvc.Name == "") { return } @@ -1490,20 +1493,20 @@ func buildPVCVolumesAndMounts( // TODO: not sure about the claims in the overwrites. // Add PVCClaims from ExtraPodSpec - for _, claim := range extra.PVCClaims { - if used[claim.Name] { - // Overwrite existing claim with same name - for i := range claims { - if claims[i].Name == claim.Name { - claims[i] = claim - break - } - } - } else { - claims = append(claims, claim) - used[claim.Name] = true - } - } + // for _, claim := range extra.PVCClaims { + // if used[claim.Name] { + // // Overwrite existing claim with same name + // for i := range claims { + // if claims[i].Name == claim.Name { + // claims[i] = claim + // break + // } + // } + // } else { + // claims = append(claims, claim) + // used[claim.Name] = true + // } + // } } From a36b5939a862122592d6dc74682bd66d26066de6 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Mon, 9 Jun 2025 18:27:54 -0700 Subject: [PATCH 05/34] Dead-end changes --- container/run.sh | 2 ++ deploy/cloud/helm/README.md | 2 +- deploy/sdk/src/dynamo/sdk/cli/build.py | 36 ++++++++++++------- .../sdk/src/dynamo/sdk/core/runner/dynamo.py | 12 +++++++ deploy/sdk/src/dynamo/sdk/lib/loader.py | 3 +- examples/hello_world/hello_world.py | 3 +- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/container/run.sh b/container/run.sh index 602b507996..fe07dc8b7d 100755 --- a/container/run.sh +++ b/container/run.sh @@ -230,6 +230,8 @@ get_options() { VOLUME_MOUNTS+=" -v ${SOURCE_DIR}/..:/workspace " VOLUME_MOUNTS+=" -v /tmp:/tmp " VOLUME_MOUNTS+=" -v /mnt/:/mnt " + VOLUME_MOUNTS+=" -v /var/run/docker.sock:/var/run/docker.sock " + if [ -z "$HF_CACHE" ]; then HF_CACHE=$DEFAULT_HF_CACHE diff --git a/deploy/cloud/helm/README.md b/deploy/cloud/helm/README.md index b21df1cb3b..14b18e5c63 100644 --- a/deploy/cloud/helm/README.md +++ b/deploy/cloud/helm/README.md @@ -86,7 +86,7 @@ kubectl get storageclass 1. Set the required environment variables: ```bash -export PROJECT_ROOT=($pwd) +export PROJECT_ROOT=$(pwd) export DOCKER_USERNAME= export DOCKER_PASSWORD= export DOCKER_SERVER= diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index 7a5cb208a7..3c646fbfe4 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -107,6 +107,7 @@ class ServiceConfig(BaseModel): dynamo: t.Dict[str, t.Any] = Field(default_factory=dict) http_exposed: bool = False api_endpoints: t.List[str] = Field(default_factory=list) + kubernetes_overrides: t.Optional[t.Dict[str, t.Any]] = None class ServiceInfo(BaseModel): @@ -116,7 +117,6 @@ class ServiceInfo(BaseModel): module_path: str class_name: str config: ServiceConfig - kubernetes_overrides: t.Optional[t.Dict[str, t.Any]] = None @classmethod def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: @@ -135,6 +135,20 @@ def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: image is not None ), "Please set DYNAMO_IMAGE environment variable or image field in service config" + print( + f"!!! Creating ServiceConfig for {name}: hasattr(service.config, kubernetes_overrides) = {hasattr(service.config, 'kubernetes_overrides')}" + ) + print(f"!!! service.config.model_dump() = {service.config.model_dump()}") + kubernetes_overrides = None + if ( + hasattr(service, "kubernetes_overrides") + and service.kubernetes_overrides is not None + ): + print("!kubernetes_overrides exist") + kubernetes_overrides = service.kubernetes_overrides.model_dump() + else: + print("!kubernetes_overrides DOES NOT exist") + # Create config config = ServiceConfig( name=name, @@ -145,17 +159,15 @@ def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: dynamo=service.config.dynamo.model_dump(), http_exposed=len(api_endpoints) > 0, api_endpoints=api_endpoints, + kubernetes_overrides=kubernetes_overrides, + # service.config.model_dump().get("kubernetes_overrides") ) - kubernetes_overrides = None - if hasattr(service, "kubernetes_overrides") and service.kubernetes_overrides: - kubernetes_overrides = service.kubernetes_overrides.model_dump() return cls( name=name, module_path=service.__module__, class_name=service_class.__name__, config=config, - kubernetes_overrides=kubernetes_overrides, ) @@ -221,6 +233,9 @@ def to_dict(self) -> t.Dict[str, t.Any]: "workers": service["config"]["workers"], "image": service["config"]["image"], "dynamo": service["config"]["dynamo"], + "kubernetes_overrides": service["config"].get( + "kubernetes_overrides" + ), # Add kubernetes_overrides. }, } @@ -231,12 +246,6 @@ def to_dict(self) -> t.Dict[str, t.Any]: "api_endpoints" ] - # Add kubernetes overwrites if available - if service.get("kubernetes_overrides"): - service_dict["config"]["kubernetes_overrides"] = service[ - "kubernetes_overrides" - ] - services_dict.append(service_dict) result["services"] = services_dict return result @@ -306,6 +315,9 @@ def dynamo_service( from dynamo.sdk.lib.loader import find_and_load_service dyn_svc = find_and_load_service(build_config.service, working_dir=build_ctx) + print(f"!!! dyn_svc type = {type(dyn_svc)}") + print(f"!!! dyn_svc.inner type = {type(dyn_svc.inner)}") + # Clean up unused edges LinkedServices.remove_unused_edges() dyn_svc.inject_config() @@ -318,6 +330,7 @@ def create( build_ctx: str, version: t.Optional[str] = None, ) -> Package: + """Create a package from a build config.""" dyn_svc = cls.dynamo_service(build_config, build_ctx) # Get service name for package @@ -332,7 +345,6 @@ def create( tag = Tag(name=package_name, version=version) if version is None: tag = tag.make_new_version() - logger.debug( f'Building Dynamo package "{tag}" from build context "{build_ctx}".' ) diff --git a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py index 44fce99dca..afe3baa9f0 100644 --- a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py +++ b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py @@ -252,6 +252,18 @@ def create_service( ) self._watchers.append(watcher) + # Inject kubernetes_overrides into config if present on service_cls + kubernetes_overrides = getattr(service_cls, "_kubernetes_overrides", None) + if kubernetes_overrides is not None: + logger.debug( + f"Injecting kubernetes_overrides into ServiceConfig for {service_cls.__name__}: {kubernetes_overrides}" + ) + config.kubernetes_overrides = ( + kubernetes_overrides.model_dump() + if hasattr(kubernetes_overrides, "model_dump") + else kubernetes_overrides + ) + # Create and return the service interface return LocalService( inner_cls=service_cls, diff --git a/deploy/sdk/src/dynamo/sdk/lib/loader.py b/deploy/sdk/src/dynamo/sdk/lib/loader.py index 09264264f6..d481d84c8e 100644 --- a/deploy/sdk/src/dynamo/sdk/lib/loader.py +++ b/deploy/sdk/src/dynamo/sdk/lib/loader.py @@ -74,7 +74,8 @@ def find_and_load_service( sys_path_modified = True try: - return _do_import(import_str, working_dir) + service_instance = _do_import(import_str, working_dir) + return service_instance finally: if sys_path_modified and working_dir: logger.debug(f"Removing {working_dir} from sys.path") diff --git a/examples/hello_world/hello_world.py b/examples/hello_world/hello_world.py index c44ea7fca8..2cdbf949b9 100644 --- a/examples/hello_world/hello_world.py +++ b/examples/hello_world/hello_world.py @@ -71,7 +71,7 @@ class ResponseType(BaseModel): resources={"cpu": 1, "memory": "500Mi"}, workers=2, image=DYNAMO_IMAGE, - kubernetes_overrides={"entrypoint": "sh -c 'echo hello from anna'"}, + kubernetes_overrides={"entrypoint": "sh -c 'echo hello from Backend!'"}, ) class Backend: def __init__(self) -> None: @@ -126,6 +126,7 @@ def shutdown(self): @service( dynamo={"namespace": "inference"}, image=DYNAMO_IMAGE, + kubernetes_overrides={"entrypoint": "sh -c 'echo hello from FrontEnd!'"}, ) class Frontend: """A simple frontend HTTP API that forwards requests to the dynamo graph.""" From ecd64c5f0df6f8aa46c5511ea36055853bf9acf3 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 11 Jun 2025 12:17:31 -0700 Subject: [PATCH 06/34] Refactored the python part after rebase --- deploy/sdk/src/dynamo/sdk/cli/build.py | 32 ++++++------------- .../src/dynamo/sdk/core/protocol/interface.py | 1 + .../sdk/src/dynamo/sdk/core/runner/dynamo.py | 27 ++++++++-------- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index 3c646fbfe4..4f33dfd6bc 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -107,7 +107,7 @@ class ServiceConfig(BaseModel): dynamo: t.Dict[str, t.Any] = Field(default_factory=dict) http_exposed: bool = False api_endpoints: t.List[str] = Field(default_factory=list) - kubernetes_overrides: t.Optional[t.Dict[str, t.Any]] = None + kubernetes_overrides: t.Optional[t.Dict[str, t.Any]] = Field(default_factory=dict) class ServiceInfo(BaseModel): @@ -135,20 +135,6 @@ def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: image is not None ), "Please set DYNAMO_IMAGE environment variable or image field in service config" - print( - f"!!! Creating ServiceConfig for {name}: hasattr(service.config, kubernetes_overrides) = {hasattr(service.config, 'kubernetes_overrides')}" - ) - print(f"!!! service.config.model_dump() = {service.config.model_dump()}") - kubernetes_overrides = None - if ( - hasattr(service, "kubernetes_overrides") - and service.kubernetes_overrides is not None - ): - print("!kubernetes_overrides exist") - kubernetes_overrides = service.kubernetes_overrides.model_dump() - else: - print("!kubernetes_overrides DOES NOT exist") - # Create config config = ServiceConfig( name=name, @@ -159,8 +145,7 @@ def from_service(cls, service: ServiceInterface[T]) -> ServiceInfo: dynamo=service.config.dynamo.model_dump(), http_exposed=len(api_endpoints) > 0, api_endpoints=api_endpoints, - kubernetes_overrides=kubernetes_overrides, - # service.config.model_dump().get("kubernetes_overrides") + kubernetes_overrides=service.config.kubernetes_overrides, ) return cls( @@ -233,11 +218,16 @@ def to_dict(self) -> t.Dict[str, t.Any]: "workers": service["config"]["workers"], "image": service["config"]["image"], "dynamo": service["config"]["dynamo"], - "kubernetes_overrides": service["config"].get( - "kubernetes_overrides" - ), # Add kubernetes_overrides. }, } + # Add kubernetes_overrides if present. + if ( + "kubernetes_overrides" in service["config"] + and service["config"]["kubernetes_overrides"] + ): + service_dict["config"]["kubernetes_overrides"] = service["config"][ + "kubernetes_overrides" + ] # Add HTTP configuration if exposed if service["config"]["http_exposed"]: @@ -315,8 +305,6 @@ def dynamo_service( from dynamo.sdk.lib.loader import find_and_load_service dyn_svc = find_and_load_service(build_config.service, working_dir=build_ctx) - print(f"!!! dyn_svc type = {type(dyn_svc)}") - print(f"!!! dyn_svc.inner type = {type(dyn_svc.inner)}") # Clean up unused edges LinkedServices.remove_unused_edges() diff --git a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py index 1ad18d1ac2..f3c3f6add2 100644 --- a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py +++ b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py @@ -83,6 +83,7 @@ class ServiceConfig(BaseModel): image: str | None = None envs: List[Env] | None = None labels: Dict[str, str] | None = None + kubernetes_overrides: Dict[str, Any] | None = None class DynamoEndpointInterface(ABC): diff --git a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py index afe3baa9f0..b982d9758d 100644 --- a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py +++ b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py @@ -252,19 +252,20 @@ def create_service( ) self._watchers.append(watcher) - # Inject kubernetes_overrides into config if present on service_cls - kubernetes_overrides = getattr(service_cls, "_kubernetes_overrides", None) - if kubernetes_overrides is not None: - logger.debug( - f"Injecting kubernetes_overrides into ServiceConfig for {service_cls.__name__}: {kubernetes_overrides}" - ) - config.kubernetes_overrides = ( - kubernetes_overrides.model_dump() - if hasattr(kubernetes_overrides, "model_dump") - else kubernetes_overrides - ) - - # Create and return the service interface + # I should not need the below. It is already in the config=ServiceConfig. + # # Inject kubernetes_overrides into config if present on service_cls + # kubernetes_overrides = getattr(service_cls, "_kubernetes_overrides", None) + # if kubernetes_overrides is not None: + # logger.debug( + # f"Injecting kubernetes_overrides into ServiceConfig for {service_cls.__name__}: {kubernetes_overrides}" + # ) + # config.kubernetes_overrides = ( + # kubernetes_overrides.model_dump() + # if hasattr(kubernetes_overrides, "model_dump") + # else kubernetes_overrides + # ) + + # Create and return the se rvice interface return LocalService( inner_cls=service_cls, config=config, From ea1271dc22fcb3a222534a0cb7737427f30ef926 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 11 Jun 2025 14:17:59 -0700 Subject: [PATCH 07/34] Move overrides into the extraPodSpecMainContainer --- container/run.sh | 2 +- .../operator/api/dynamo/common/common.go | 5 +- .../dynamocomponentdeployment_types.go | 3 - .../nvidia.com_dynamographdeployments.yaml | 73 +++++ deploy/cloud/operator/config/rbac/role.yaml | 15 + deploy/cloud/operator/go.mod | 1 - deploy/cloud/operator/go.sum | 2 - .../controller/dynamocomponent_controller.go | 10 + .../dynamocomponentdeployment_controller.go | 283 ++++-------------- deploy/sdk/src/dynamo/sdk/cli/build.py | 1 + .../sdk/src/dynamo/sdk/core/runner/dynamo.py | 13 - 11 files changed, 163 insertions(+), 245 deletions(-) diff --git a/container/run.sh b/container/run.sh index fe07dc8b7d..de99308c14 100755 --- a/container/run.sh +++ b/container/run.sh @@ -230,7 +230,7 @@ get_options() { VOLUME_MOUNTS+=" -v ${SOURCE_DIR}/..:/workspace " VOLUME_MOUNTS+=" -v /tmp:/tmp " VOLUME_MOUNTS+=" -v /mnt/:/mnt " - VOLUME_MOUNTS+=" -v /var/run/docker.sock:/var/run/docker.sock " + VOLUME_MOUNTS+=" -v /var/run/docker.sock:/var/run/docker.sock " if [ -z "$HF_CACHE" ]; then diff --git a/deploy/cloud/operator/api/dynamo/common/common.go b/deploy/cloud/operator/api/dynamo/common/common.go index 5cb697fa9c..75e7e8d19c 100644 --- a/deploy/cloud/operator/api/dynamo/common/common.go +++ b/deploy/cloud/operator/api/dynamo/common/common.go @@ -62,8 +62,5 @@ type ExtraPodSpec struct { Containers []corev1.Container `json:"containers,omitempty"` ServiceAccountName string `json:"serviceAccountName,omitempty"` PriorityClassName string `json:"priorityClassName,omitempty"` - - Volumes []corev1.Volume `json:"volumes,omitempty"` - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` - PVCClaims []corev1.PersistentVolumeClaim `json:"pvcClaims,omitempty"` + MainContainer *corev1.Container `json:"mainContainer,omitempty"` } diff --git a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go index b75d4bacde..dc5ebe7af9 100644 --- a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go +++ b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go @@ -80,9 +80,6 @@ type DynamoComponentDeploymentSharedSpec struct { LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty"` ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty"` Replicas *int32 `json:"replicas,omitempty"` - - // +optional - Entrypoint *string `json:"entrypoint,omitempty"` } type RunMode struct { diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml index ce6d2ae16a..7f9c4ed143 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml @@ -2954,6 +2954,79 @@ spec: type: object serviceName: type: string + mainContainer: + type: object + properties: + name: + type: string + image: + type: string + command: + type: array + items: + type: string + args: + type: array + items: + type: string + workingDir: + type: string + ports: + type: array + items: + type: object + properties: + name: + type: string + containerPort: + type: integer + protocol: + type: string + envFrom: + type: array + items: + type: object + env: + type: array + items: + type: object + resources: + type: object + volumeMounts: + type: array + items: + type: object + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + livenessProbe: + type: object + readinessProbe: + type: object + startupProbe: + type: object + lifecycle: + type: object + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + imagePullPolicy: + type: string + securityContext: + type: object type: object type: object required: diff --git a/deploy/cloud/operator/config/rbac/role.yaml b/deploy/cloud/operator/config/rbac/role.yaml index 3f4c7196ba..694d247800 100644 --- a/deploy/cloud/operator/config/rbac/role.yaml +++ b/deploy/cloud/operator/config/rbac/role.yaml @@ -1,3 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/deploy/cloud/operator/go.mod b/deploy/cloud/operator/go.mod index d67210ee0f..b9049f4d0c 100644 --- a/deploy/cloud/operator/go.mod +++ b/deploy/cloud/operator/go.mod @@ -96,7 +96,6 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mattn/go-shellwords v1.0.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect diff --git a/deploy/cloud/operator/go.sum b/deploy/cloud/operator/go.sum index 771ce503f3..f8ff3373f6 100644 --- a/deploy/cloud/operator/go.sum +++ b/deploy/cloud/operator/go.sum @@ -156,8 +156,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go index 9728ea9323..0046d3d5a6 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go @@ -70,6 +70,7 @@ import ( dynamoCommon "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/dynamo/common" "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/dynamo/schemas" nvidiacomv1alpha1 "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/v1alpha1" + "dario.cat/mergo" ) // DynamoComponentReconciler reconciles a DynamoComponent object @@ -1315,6 +1316,15 @@ echo "Done" pod.Spec.Tolerations = globalExtraPodSpec.Tolerations pod.Spec.TopologySpreadConstraints = globalExtraPodSpec.TopologySpreadConstraints pod.Spec.ServiceAccountName = globalExtraPodSpec.ServiceAccountName + + // Apply MainContainer override if specified + if globalExtraPodSpec.MainContainer != nil && len(pod.Spec.Containers) > 0 { + // Merge the main container configuration + mainContainer := &pod.Spec.Containers[0] + if err := mergo.Merge(mainContainer, globalExtraPodSpec.MainContainer, mergo.WithOverride); err != nil { + return nil, fmt.Errorf("failed to merge main container configuration: %v", err) + } + } } if opt.DynamoComponent.Spec.ImageBuilderExtraPodSpec != nil { diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index ea017fe6aa..d16461a7c9 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -33,7 +33,6 @@ import ( corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/klog/v2" "emperror.dev/errors" dynamoCommon "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/dynamo/common" @@ -62,8 +61,6 @@ import ( leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1" volcanov1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1" - - "github.com/mattn/go-shellwords" ) const ( @@ -247,7 +244,7 @@ func (r *DynamoComponentDeploymentReconciler) Reconcile(ctx context.Context, req modified := false // Reconcile PVC - err = r.reconcilePVC(ctx, dynamoComponentDeployment) + _, err = r.reconcilePVC(ctx, dynamoComponentDeployment) if err != nil { logs.Error(err, "Unable to create PVC", "crd", req.NamespacedName) return ctrl.Result{}, err @@ -814,42 +811,39 @@ func IsDeploymentReady(deployment *appsv1.Deployment) bool { return false } -func (r *DynamoComponentDeploymentReconciler) reconcilePVC(ctx context.Context, crd *v1alpha1.DynamoComponentDeployment) error { +func (r *DynamoComponentDeploymentReconciler) reconcilePVC(ctx context.Context, crd *v1alpha1.DynamoComponentDeployment) (*corev1.PersistentVolumeClaim, error) { logger := log.FromContext(ctx) if crd.Spec.PVC == nil { - return nil + return nil, nil + } + pvcConfig := *crd.Spec.PVC + pvc := &corev1.PersistentVolumeClaim{} + pvcName := types.NamespacedName{Name: getPvcName(crd, pvcConfig.Name), Namespace: crd.GetNamespace()} + err := r.Get(ctx, pvcName, pvc) + if err != nil && client.IgnoreNotFound(err) != nil { + logger.Error(err, "Unable to retrieve PVC", "crd", crd.GetName()) + return nil, err } - for name, pvcConfig := range crd.Spec.PVC { - pvc := &corev1.PersistentVolumeClaim{} - pvcName := types.NamespacedName{Name: getPvcName(crd, pvcConfig.Name), Namespace: crd.GetNamespace()} - err := r.Get(ctx, pvcName, pvc) - if err != nil && client.IgnoreNotFound(err) != nil { - logger.Error(err, "Unable to retrieve PVC", "crd", crd.GetName(), "pvcKey", name) - return err + // If PVC does not exist, create a new one + if err != nil { + if pvcConfig.Create == nil || !*pvcConfig.Create { + logger.Error(err, "Unknown PVC", "pvc", pvc.Name) + return nil, err } - - // If PVC does not exist, create a new one + pvc = constructPVC(crd, pvcConfig) + if err := controllerutil.SetControllerReference(crd, pvc, r.Client.Scheme()); err != nil { + logger.Error(err, "Failed to set controller reference", "pvc", pvc.Name) + return nil, err + } + err = r.Create(ctx, pvc) if err != nil { - if pvcConfig.Create == nil || !*pvcConfig.Create { - logger.Error(err, "Unknown PVC", "pvc", pvc.Name, "pvcKey", name) - return err - } - pvc = constructPVC(crd, *pvcConfig) - if err := controllerutil.SetControllerReference(crd, pvc, r.Client.Scheme()); err != nil { - logger.Error(err, "Failed to set controller reference", "pvc", pvc.Name, "pvcKey", name) - return err - } - err = r.Create(ctx, pvc) - if err != nil { - logger.Error(err, "Failed to create pvc", "pvc", pvc.Name, "pvcKey", name) - return err - } - logger.Info("PVC created", "pvc", pvcName, "pvcKey", name) + logger.Error(err, "Failed to create pvc", "pvc", pvc.Name) + return nil, err } + logger.Info("PVC created", "pvc", pvcName) } - - return nil + return pvc, nil } func (r *DynamoComponentDeploymentReconciler) setStatusConditions(ctx context.Context, req ctrl.Request, conditions ...metav1.Condition) (dynamoComponentDeployment *v1alpha1.DynamoComponentDeployment, err error) { @@ -1343,179 +1337,8 @@ func getDynamoComponentRepositoryNameAndDynamoComponentVersion(dynamoComponent * return } -func buildPVCVolumesAndMounts( - component *v1alpha1.DynamoComponentDeployment, - sharedMemorySizeLimit resource.Quantity, -) (volumes []corev1.Volume, mounts []corev1.VolumeMount /* claims []corev1.PersistentVolumeClaim */) { - - // Keep track for overwrites. - used := map[string]bool{} - - // TODO use constructPVC() from common? - // Helper: create PVC object from your custom PVC struct - // createClaim := func(volumeName string, pvc *v1alpha1.PVC) *corev1.PersistentVolumeClaim { - // if pvc == nil || pvc.Create == nil || *pvc.Name == "" || !*pvc.Create { - // return nil - // } - // claimName := getPvcName(component, pvc.Name) - // storageClassName := pvc.StorageClass - // return &corev1.PersistentVolumeClaim{ - // ObjectMeta: metav1.ObjectMeta{ - // Name: claimName, - // }, - // Spec: corev1.PersistentVolumeClaimSpec{ - // AccessModes: []corev1.PersistentVolumeAccessMode{pvc.VolumeAccessMode}, - // Resources: corev1.VolumeResourceRequirements{ - // Requests: corev1.ResourceList{ - // corev1.ResourceStorage: pvc.Size, - // }, - // }, - // StorageClassName: &storageClassName, - // }, - // } - // } - - // addPVC adds a volume and corresponding volume mount to the pod spec based on the provided PVC configuration. - addPVC := func(crd metav1.Object, volumeName string, pvc *v1alpha1.PVC) { - if pvc == nil { - return - } - - // Use getPvcName to fall back to CRD name if pvc.Name is nil - claimName := getPvcName(crd, pvc.Name) - if claimName == "" || (pvc.Name != nil && *pvc.Name == "") { - return - } - - // Fallback mountPath if not provided - mountPath := fmt.Sprintf("/mnt/%s", volumeName) - if pvc.MountPoint != nil && *pvc.MountPoint != "" { - mountPath = *pvc.MountPoint - } - - volume := corev1.Volume{ - Name: volumeName, - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: claimName, - }, - }, - } - - mount := corev1.VolumeMount{ - Name: volumeName, - MountPath: mountPath, - } - - if used[volumeName] { - klog.Warningf("PVC volume %q was already added; overwriting with new configuration", volumeName) - for i, v := range volumes { - if v.Name == volumeName { - volumes[i] = volume - break - } - } - for i, m := range mounts { - if m.Name == volumeName { - mounts[i] = mount - break - } - } - } else { - volumes = append(volumes, volume) - mounts = append(mounts, mount) - used[volumeName] = true - } - - // TODO ? - // if claim := createClaim(volumeName, pvc); claim != nil { - // claims = append(claims, *claim) - // } - } - - // Add Shared Memory Volume. - volumes = append(volumes, corev1.Volume{ - Name: KubeValueNameSharedMemory, - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{ - Medium: corev1.StorageMediumMemory, - SizeLimit: &sharedMemorySizeLimit, - }, - }, - }) - mounts = append(mounts, corev1.VolumeMount{ - Name: KubeValueNameSharedMemory, - MountPath: "/dev/shm", - }) - - // Add standard PVC(s) - if component.Spec.PVC != nil { - for volumeName, pvc := range component.Spec.PVC { - addPVC(component, volumeName, pvc) - } - - } - // Add PVC overrides and extras. - if component.Spec.ExtraPodSpec != nil { - extra := component.Spec.ExtraPodSpec - - // Add Volumes from ExtraPodSpec. - for _, vol := range extra.Volumes { - if used[vol.Name] { - // Overwrite existing volume with same name - for i := range volumes { - if volumes[i].Name == vol.Name { - volumes[i] = vol - break - } - } - } else { - volumes = append(volumes, vol) - used[vol.Name] = true - } - } - - // Add VolumeMounts from ExtraPodSpec - for _, mount := range extra.VolumeMounts { - if used[mount.Name] { - // Overwrite existing mount with same name - for i := range mounts { - if mounts[i].Name == mount.Name { - mounts[i] = mount - break - } - } - } else { - mounts = append(mounts, mount) - used[mount.Name] = true - } - } - - // TODO: not sure about the claims in the overwrites. - // Add PVCClaims from ExtraPodSpec - // for _, claim := range extra.PVCClaims { - // if used[claim.Name] { - // // Overwrite existing claim with same name - // for i := range claims { - // if claims[i].Name == claim.Name { - // claims[i] = claim - // break - // } - // } - // } else { - // claims = append(claims, claim) - // used[claim.Name] = true - // } - // } - - } - - return volumes, mounts /*. claims */ -} - //nolint:gocyclo,nakedret func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx context.Context, opt generateResourceOption) (podTemplateSpec *corev1.PodTemplateSpec, err error) { - logger := log.FromContext(ctx) podLabels := r.getKubeLabels(opt.dynamoComponentDeployment, opt.dynamoComponent) if opt.isStealingTrafficDebugModeEnabled { podLabels[commonconsts.KubeLabelDynamoDeploymentTargetType] = DeploymentTargetTypeDebug @@ -1670,15 +1493,39 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex return nil, err } - // Handle default PVC settings. Apply overwrites if the name matches, add otherwise. sharedMemorySizeLimit := resource.MustParse("64Mi") memoryLimit := resources.Limits[corev1.ResourceMemory] if !memoryLimit.IsZero() { sharedMemorySizeLimit.SetMilli(memoryLimit.MilliValue() / 2) } - pvcVolumes, pvcMounts := buildPVCVolumesAndMounts(opt.dynamoComponentDeployment, sharedMemorySizeLimit) - volumes = append(volumes, pvcVolumes...) - volumeMounts = append(volumeMounts, pvcMounts...) + + volumes = append(volumes, corev1.Volume{ + Name: KubeValueNameSharedMemory, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: corev1.StorageMediumMemory, + SizeLimit: &sharedMemorySizeLimit, + }, + }, + }) + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: KubeValueNameSharedMemory, + MountPath: "/dev/shm", + }) + if opt.dynamoComponentDeployment.Spec.PVC != nil { + volumes = append(volumes, corev1.Volume{ + Name: getPvcName(opt.dynamoComponentDeployment, opt.dynamoComponentDeployment.Spec.PVC.Name), + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: getPvcName(opt.dynamoComponentDeployment, opt.dynamoComponentDeployment.Spec.PVC.Name), + }, + }, + }) + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: getPvcName(opt.dynamoComponentDeployment, opt.dynamoComponentDeployment.Spec.PVC.Name), + MountPath: *opt.dynamoComponentDeployment.Spec.PVC.MountPoint, + }) + } imageName := opt.dynamoComponent.GetImage() if imageName == "" { @@ -1806,20 +1653,14 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex container.SecurityContext.RunAsUser = &[]int64{0}[0] } - if opt.dynamoComponentDeployment.Spec.Entrypoint != nil { - entrypoint := opt.dynamoComponentDeployment.Spec.Entrypoint - - // Handle Entrypoint overwrite. Entrypoint needs to be renamed to Command. - if entrypoint != nil { - parts, err := shellwords.Parse(*entrypoint) - if err != nil { - logger.Error(err, "failed to parse entrypoint string") - } else if len(parts) > 0 { - container.Command = []string{parts[0]} - if len(parts) > 1 { - container.Args = parts[1:] - } - } + // For now only overwrite the command and args. + extraPodSpecMainContainer := opt.dynamoComponentDeployment.Spec.ExtraPodSpec.MainContainer + if extraPodSpecMainContainer != nil { + if len(extraPodSpecMainContainer.Command) > 0 { + container.Command = extraPodSpecMainContainer.Command + } + if len(extraPodSpecMainContainer.Args) > 0 { + container.Args = extraPodSpecMainContainer.Args } } diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index 4f33dfd6bc..ba1d9fe94c 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -333,6 +333,7 @@ def create( tag = Tag(name=package_name, version=version) if version is None: tag = tag.make_new_version() + logger.debug( f'Building Dynamo package "{tag}" from build context "{build_ctx}".' ) diff --git a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py index b982d9758d..3140133049 100644 --- a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py +++ b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py @@ -252,19 +252,6 @@ def create_service( ) self._watchers.append(watcher) - # I should not need the below. It is already in the config=ServiceConfig. - # # Inject kubernetes_overrides into config if present on service_cls - # kubernetes_overrides = getattr(service_cls, "_kubernetes_overrides", None) - # if kubernetes_overrides is not None: - # logger.debug( - # f"Injecting kubernetes_overrides into ServiceConfig for {service_cls.__name__}: {kubernetes_overrides}" - # ) - # config.kubernetes_overrides = ( - # kubernetes_overrides.model_dump() - # if hasattr(kubernetes_overrides, "model_dump") - # else kubernetes_overrides - # ) - # Create and return the se rvice interface return LocalService( inner_cls=service_cls, From 16fe7889736bd029b3b34d68fdaa31efc48fcfb3 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 11 Jun 2025 14:29:55 -0700 Subject: [PATCH 08/34] Cleanup after moving the overrides. --- .../v1alpha1/dynamocomponentdeployment_types.go | 2 +- .../controller/dynamocomponent_controller.go | 10 ---------- .../dynamocomponentdeployment_controller.go | 16 +++++++++------- deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py | 2 +- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go index dc5ebe7af9..046a87f9c7 100644 --- a/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go +++ b/deploy/cloud/operator/api/v1alpha1/dynamocomponentdeployment_types.go @@ -66,7 +66,7 @@ type DynamoComponentDeploymentSharedSpec struct { Autoscaling *Autoscaling `json:"autoscaling,omitempty"` Envs []corev1.EnvVar `json:"envs,omitempty"` EnvFromSecret *string `json:"envFromSecret,omitempty"` - PVC map[string]*PVC `json:"pvcSettings,omitempty"` + PVC *PVC `json:"pvc,omitempty"` RunMode *RunMode `json:"runMode,omitempty"` ExternalServices map[string]ExternalService `json:"externalServices,omitempty"` diff --git a/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go index 0046d3d5a6..9728ea9323 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go @@ -70,7 +70,6 @@ import ( dynamoCommon "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/dynamo/common" "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/dynamo/schemas" nvidiacomv1alpha1 "github.com/ai-dynamo/dynamo/deploy/cloud/operator/api/v1alpha1" - "dario.cat/mergo" ) // DynamoComponentReconciler reconciles a DynamoComponent object @@ -1316,15 +1315,6 @@ echo "Done" pod.Spec.Tolerations = globalExtraPodSpec.Tolerations pod.Spec.TopologySpreadConstraints = globalExtraPodSpec.TopologySpreadConstraints pod.Spec.ServiceAccountName = globalExtraPodSpec.ServiceAccountName - - // Apply MainContainer override if specified - if globalExtraPodSpec.MainContainer != nil && len(pod.Spec.Containers) > 0 { - // Merge the main container configuration - mainContainer := &pod.Spec.Containers[0] - if err := mergo.Merge(mainContainer, globalExtraPodSpec.MainContainer, mergo.WithOverride); err != nil { - return nil, fmt.Errorf("failed to merge main container configuration: %v", err) - } - } } if opt.DynamoComponent.Spec.ImageBuilderExtraPodSpec != nil { diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index d16461a7c9..56b59b104f 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -1654,13 +1654,15 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex } // For now only overwrite the command and args. - extraPodSpecMainContainer := opt.dynamoComponentDeployment.Spec.ExtraPodSpec.MainContainer - if extraPodSpecMainContainer != nil { - if len(extraPodSpecMainContainer.Command) > 0 { - container.Command = extraPodSpecMainContainer.Command - } - if len(extraPodSpecMainContainer.Args) > 0 { - container.Args = extraPodSpecMainContainer.Args + if opt.dynamoComponentDeployment.Spec.ExtraPodSpec != nil { + extraPodSpecMainContainer := opt.dynamoComponentDeployment.Spec.ExtraPodSpec.MainContainer + if extraPodSpecMainContainer != nil { + if len(extraPodSpecMainContainer.Command) > 0 { + container.Command = extraPodSpecMainContainer.Command + } + if len(extraPodSpecMainContainer.Args) > 0 { + container.Args = extraPodSpecMainContainer.Args + } } } diff --git a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py index 3140133049..44fce99dca 100644 --- a/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py +++ b/deploy/sdk/src/dynamo/sdk/core/runner/dynamo.py @@ -252,7 +252,7 @@ def create_service( ) self._watchers.append(watcher) - # Create and return the se rvice interface + # Create and return the service interface return LocalService( inner_cls=service_cls, config=config, From 8d4d91f7f14222a5b118181d64c6b55221a27c89 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 11 Jun 2025 14:41:38 -0700 Subject: [PATCH 09/34] rerun make manifests --- .../dynamo/common/zz_generated.deepcopy.go | 24 +- .../api/v1alpha1/zz_generated.deepcopy.go | 20 +- ...nvidia.com_dynamocomponentdeployments.yaml | 1679 +++++++--------- .../bases/nvidia.com_dynamocomponents.yaml | 1567 ++++++--------- .../nvidia.com_dynamographdeployments.yaml | 1744 +++++++---------- deploy/cloud/operator/config/rbac/role.yaml | 15 - 6 files changed, 2024 insertions(+), 3025 deletions(-) diff --git a/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go b/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go index c612d05bf6..8f3b94abc0 100644 --- a/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go +++ b/deploy/cloud/operator/api/dynamo/common/zz_generated.deepcopy.go @@ -151,26 +151,10 @@ func (in *ExtraPodSpec) DeepCopyInto(out *ExtraPodSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]v1.Volume, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.VolumeMounts != nil { - in, out := &in.VolumeMounts, &out.VolumeMounts - *out = make([]v1.VolumeMount, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.PVCClaims != nil { - in, out := &in.PVCClaims, &out.PVCClaims - *out = make([]v1.PersistentVolumeClaim, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + if in.MainContainer != nil { + in, out := &in.MainContainer, &out.MainContainer + *out = new(v1.Container) + (*in).DeepCopyInto(*out) } } diff --git a/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go b/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go index 9cd78b7378..722675a091 100644 --- a/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/deploy/cloud/operator/api/v1alpha1/zz_generated.deepcopy.go @@ -263,19 +263,8 @@ func (in *DynamoComponentDeploymentSharedSpec) DeepCopyInto(out *DynamoComponent } if in.PVC != nil { in, out := &in.PVC, &out.PVC - *out = make(map[string]*PVC, len(*in)) - for key, val := range *in { - var outVal *PVC - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = new(PVC) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } + *out = new(PVC) + (*in).DeepCopyInto(*out) } if in.RunMode != nil { in, out := &in.RunMode, &out.RunMode @@ -315,11 +304,6 @@ func (in *DynamoComponentDeploymentSharedSpec) DeepCopyInto(out *DynamoComponent *out = new(int32) **out = **in } - if in.Entrypoint != nil { - in, out := &in.Entrypoint, &out.Entrypoint - *out = new(string) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamoComponentDeploymentSharedSpec. diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml index bf11527974..7d44d531ee 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml @@ -382,8 +382,6 @@ spec: type: string dynamoTag: type: string - entrypoint: - type: string envFromSecret: type: string envs: @@ -1593,1053 +1591,762 @@ spec: - name type: object type: array - nodeSelector: - additionalProperties: - type: string - type: object - priorityClassName: - type: string - pvcClaims: - items: - properties: - apiVersion: + mainContainer: + properties: + args: + items: type: string - kind: + type: array + x-kubernetes-list-type: atomic + command: + items: type: string - metadata: + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name type: object - spec: + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: + configMapRef: properties: - apiGroup: - type: string - kind: - type: string name: + default: "" type: string - required: - - kind - - name + optional: + type: boolean type: object x-kubernetes-map-type: atomic - dataSourceRef: + prefix: + type: string + secretRef: properties: - apiGroup: - type: string - kind: - type: string name: + default: "" type: string - namespace: - type: string - required: - - kind - - name + optional: + type: boolean type: object - resources: - properties: - limits: - additionalProperties: + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - status: - properties: - accessModes: - items: + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" type: string - type: array - x-kubernetes-list-type: atomic - allocatedResourceStatuses: - additionalProperties: + required: + - port + type: object + httpGet: + properties: + host: type: string - type: object - x-kubernetes-map-type: granular - allocatedResources: - additionalProperties: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - capacity: - additionalProperties: + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - conditions: - items: - properties: - lastProbeTime: - format: date-time - type: string - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - required: - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - currentVolumeAttributesClassName: + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: type: string - modifyVolumeStatus: - properties: - status: - type: string - targetVolumeAttributesClassName: - type: string - required: - - status - type: object - phase: - type: string - type: object - type: object - type: array - schedulerName: - type: string - serviceAccountName: - type: string - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - format: int32 - type: integer - minDomains: - format: int32 - type: integer - nodeAffinityPolicy: - type: string - nodeTaintsPolicy: - type: string - topologyKey: - type: string - whenUnsatisfiable: - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: + hostPort: format: int32 type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - default: ext4 - type: string - kind: - type: string - readOnly: - default: false - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: - type: string - shareName: - type: string - required: - - secretName - - shareName - type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: - properties: - fsType: + name: type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: + protocol: + default: TCP type: string required: - - volumeID - type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean + - containerPort type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: - properties: - name: - default: "" + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: type: string - volumeName: + value: type: string + required: + - name + - value type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - items: + type: array + x-kubernetes-list-type: atomic + path: type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - image: - properties: - pullPolicy: - type: string - reference: - type: string - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - default: default - type: string - lun: - format: int32 - type: integer - portals: - items: + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - clusterTrustBundle: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - name: - type: string - optional: - type: boolean - path: - type: string - signerName: - type: string - required: - - path - type: object - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - default: /etc/ceph/keyring + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: type: string - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd + restartPolicy: type: string - readOnly: - type: boolean - secretRef: + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: properties: name: - default: "" type: string + request: + type: string + required: + - name type: object - x-kubernetes-map-type: atomic - user: - default: admin + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: type: string required: - - image - - monitors + - devicePath + - name type: object - scaleIO: + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: properties: - fsType: - default: xfs + mountPath: type: string - gateway: + mountPropagation: type: string - protectionDomain: + name: type: string readOnly: type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - default: ThinProvisioned + recursiveReadOnly: type: string - storagePool: + subPath: type: string - system: - type: string - volumeName: + subPathExpr: type: string required: - - gateway - - secretRef - - system + - mountPath + - name type: object - secret: + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + schedulerName: + type: string + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: properties: - defaultMode: - format: int32 - type: integer - items: + matchExpressions: items: properties: key: type: string - mode: - format: int32 - type: integer - path: + operator: type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic required: - key - - path + - operator type: object type: array x-kubernetes-list-type: atomic - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string + matchLabels: + additionalProperties: + type: string type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string required: - - name + - maxSkew + - topologyKey + - whenUnsatisfiable type: object type: array type: object @@ -2758,26 +2465,24 @@ spec: format: int32 type: integer type: object - pvcSettings: - additionalProperties: - properties: - create: - type: boolean - mountPoint: - type: string - name: - type: string - size: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - storageClass: - type: string - volumeAccessMode: - type: string - type: object + pvc: + properties: + create: + type: boolean + mountPoint: + type: string + name: + type: string + size: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClass: + type: string + volumeAccessMode: + type: string type: object readinessProbe: properties: diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml index a453f615d6..a0d3f8e862 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml @@ -1311,178 +1311,690 @@ spec: - name type: object type: array - nodeSelector: - additionalProperties: - type: string - type: object - priorityClassName: - type: string - pvcClaims: - items: - properties: - apiVersion: + mainContainer: + properties: + args: + items: type: string - kind: + type: array + x-kubernetes-list-type: atomic + command: + items: type: string - metadata: + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name type: object - spec: + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: + configMapRef: properties: - apiGroup: - type: string - kind: - type: string name: + default: "" type: string - required: - - kind - - name + optional: + type: boolean type: object x-kubernetes-map-type: atomic - dataSourceRef: + prefix: + type: string + secretRef: properties: - apiGroup: - type: string - kind: - type: string name: + default: "" type: string - namespace: - type: string - required: - - kind - - name + optional: + type: boolean type: object - resources: - properties: - limits: - additionalProperties: + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: type: string - volumeMode: + hostPort: + format: int32 + type: integer + name: type: string - volumeName: + protocol: + default: TCP type: string + required: + - containerPort type: object - status: - properties: - accessModes: - items: + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" type: string - type: array - x-kubernetes-list-type: atomic - allocatedResourceStatuses: - additionalProperties: + required: + - port + type: object + httpGet: + properties: + host: type: string - type: object - x-kubernetes-map-type: granular - allocatedResources: - additionalProperties: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - capacity: - additionalProperties: + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - conditions: - items: - properties: - lastProbeTime: - format: date-time - type: string - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - required: - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - currentVolumeAttributesClassName: + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: type: string - modifyVolumeStatus: + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: properties: - status: + name: type: string - targetVolumeAttributesClassName: + request: type: string required: - - status + - name type: object - phase: + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: type: string + name: + type: string + required: + - devicePath + - name type: object - type: object - type: array + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string schedulerName: type: string serviceAccountName: @@ -1557,809 +2069,6 @@ spec: - whenUnsatisfiable type: object type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - default: ext4 - type: string - kind: - type: string - readOnly: - default: false - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: - type: string - shareName: - type: string - required: - - secretName - - shareName - type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - type: string - required: - - volumeID - type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: - type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: - type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - image: - properties: - pullPolicy: - type: string - reference: - type: string - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - default: default - type: string - lun: - format: int32 - type: integer - portals: - items: - type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - clusterTrustBundle: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - name: - type: string - optional: - type: boolean - path: - type: string - signerName: - type: string - required: - - path - type: object - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - default: /etc/ceph/keyring - type: string - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin - type: string - required: - - image - - monitors - type: object - scaleIO: - properties: - fsType: - default: xfs - type: string - gateway: - type: string - protectionDomain: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - default: ThinProvisioned - type: string - storagePool: - type: string - system: - type: string - volumeName: - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array type: object imagePullSecrets: items: diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml index 7f9c4ed143..2a0e3e334e 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml @@ -437,8 +437,6 @@ spec: type: object dynamoNamespace: type: string - entrypoint: - type: string envFromSecret: type: string envs: @@ -1648,1053 +1646,762 @@ spec: - name type: object type: array - nodeSelector: - additionalProperties: - type: string - type: object - priorityClassName: - type: string - pvcClaims: - items: - properties: - apiVersion: + mainContainer: + properties: + args: + items: type: string - kind: + type: array + x-kubernetes-list-type: atomic + command: + items: type: string - metadata: + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name type: object - spec: + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: + configMapRef: properties: - apiGroup: - type: string - kind: - type: string name: + default: "" type: string - required: - - kind - - name + optional: + type: boolean type: object x-kubernetes-map-type: atomic - dataSourceRef: + prefix: + type: string + secretRef: properties: - apiGroup: - type: string - kind: - type: string name: + default: "" type: string - namespace: - type: string - required: - - kind - - name + optional: + type: boolean type: object - resources: - properties: - limits: - additionalProperties: + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - status: - properties: - accessModes: - items: + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" type: string - type: array - x-kubernetes-list-type: atomic - allocatedResourceStatuses: - additionalProperties: + required: + - port + type: object + httpGet: + properties: + host: type: string - type: object - x-kubernetes-map-type: granular - allocatedResources: - additionalProperties: + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - capacity: - additionalProperties: + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: anyOf: - type: integer - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - type: object - conditions: - items: - properties: - lastProbeTime: - format: date-time - type: string - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - required: - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - currentVolumeAttributesClassName: + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: type: string - modifyVolumeStatus: - properties: - status: - type: string - targetVolumeAttributesClassName: - type: string - required: - - status - type: object - phase: - type: string - type: object - type: object - type: array - schedulerName: - type: string - serviceAccountName: - type: string - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - format: int32 - type: integer - minDomains: - format: int32 - type: integer - nodeAffinityPolicy: - type: string - nodeTaintsPolicy: - type: string - topologyKey: - type: string - whenUnsatisfiable: - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: + hostPort: format: int32 type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - default: ext4 - type: string - kind: - type: string - readOnly: - default: false - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: + name: type: string - shareName: + protocol: + default: TCP type: string required: - - secretName - - shareName + - containerPort type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - default: "" + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: properties: - fsType: + resourceName: type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: + restartPolicy: type: string required: - - volumeID + - resourceName + - restartPolicy type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: properties: name: - default: "" type: string + request: + type: string + required: + - name type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: + type: type: string - type: array - x-kubernetes-list-type: atomic - wwids: - items: + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: + role: type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - image: - properties: - pullPolicy: - type: string - reference: - type: string - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - default: default - type: string - lun: - format: int32 - type: integer - portals: - items: + type: type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - clusterTrustBundle: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - name: - type: string - optional: - type: boolean - path: - type: string - signerName: - type: string - required: - - path - type: object - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - default: /etc/ceph/keyring - type: string - monitors: - items: + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: type: string required: - - image - - monitors + - devicePath + - name type: object - scaleIO: + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: properties: - fsType: - default: xfs + mountPath: type: string - gateway: + mountPropagation: type: string - protectionDomain: + name: type: string readOnly: type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - default: ThinProvisioned + recursiveReadOnly: type: string - storagePool: + subPath: type: string - system: - type: string - volumeName: + subPathExpr: type: string required: - - gateway - - secretRef - - system + - mountPath + - name type: object - secret: + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + schedulerName: + type: string + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: properties: - defaultMode: - format: int32 - type: integer - items: + matchExpressions: items: properties: key: type: string - mode: - format: int32 - type: integer - path: + operator: type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic required: - key - - path + - operator type: object type: array x-kubernetes-list-type: atomic - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string + matchLabels: + additionalProperties: + type: string type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string required: - - name + - maxSkew + - topologyKey + - whenUnsatisfiable type: object type: array type: object @@ -2813,26 +2520,24 @@ spec: format: int32 type: integer type: object - pvcSettings: - additionalProperties: - properties: - create: - type: boolean - mountPoint: - type: string - name: - type: string - size: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - storageClass: - type: string - volumeAccessMode: - type: string - type: object + pvc: + properties: + create: + type: boolean + mountPoint: + type: string + name: + type: string + size: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClass: + type: string + volumeAccessMode: + type: string type: object readinessProbe: properties: @@ -2954,79 +2659,6 @@ spec: type: object serviceName: type: string - mainContainer: - type: object - properties: - name: - type: string - image: - type: string - command: - type: array - items: - type: string - args: - type: array - items: - type: string - workingDir: - type: string - ports: - type: array - items: - type: object - properties: - name: - type: string - containerPort: - type: integer - protocol: - type: string - envFrom: - type: array - items: - type: object - env: - type: array - items: - type: object - resources: - type: object - volumeMounts: - type: array - items: - type: object - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - livenessProbe: - type: object - readinessProbe: - type: object - startupProbe: - type: object - lifecycle: - type: object - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - imagePullPolicy: - type: string - securityContext: - type: object type: object type: object required: diff --git a/deploy/cloud/operator/config/rbac/role.yaml b/deploy/cloud/operator/config/rbac/role.yaml index 694d247800..3f4c7196ba 100644 --- a/deploy/cloud/operator/config/rbac/role.yaml +++ b/deploy/cloud/operator/config/rbac/role.yaml @@ -1,18 +1,3 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole From 2ad84afada3c82dc20c7066fc14e1a6018b84bbf Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 11 Jun 2025 15:01:54 -0700 Subject: [PATCH 10/34] correct the manifest generation --- deploy/sdk/src/dynamo/sdk/cli/build.py | 25 ++++++++++++++++++++----- examples/hello_world/hello_world.py | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index ba1d9fe94c..ecb8f41378 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -22,6 +22,7 @@ import inspect import logging import os +import shlex import shutil import subprocess import sys @@ -225,9 +226,25 @@ def to_dict(self) -> t.Dict[str, t.Any]: "kubernetes_overrides" in service["config"] and service["config"]["kubernetes_overrides"] ): - service_dict["config"]["kubernetes_overrides"] = service["config"][ - "kubernetes_overrides" - ] + # Map kubernetes_overrides fields to mainContainer if present. + kube_overrides = service["config"]["kubernetes_overrides"] + main_container = {} + + entrypoint = kube_overrides.get("entrypoint") + if entrypoint: + main_container["command"] = shlex.split(entrypoint) + + cmd = kube_overrides.get("cmd") + if cmd: + if isinstance(cmd, str): + main_container["args"] = shlex.split(cmd) + else: + main_container["args"] = cmd + + if main_container: + service_dict["config"]["extraPodSpec"] = { + "mainContainer": main_container + } # Add HTTP configuration if exposed if service["config"]["http_exposed"]: @@ -235,7 +252,6 @@ def to_dict(self) -> t.Dict[str, t.Any]: service_dict["config"]["api_endpoints"] = service["config"][ "api_endpoints" ] - services_dict.append(service_dict) result["services"] = services_dict return result @@ -305,7 +321,6 @@ def dynamo_service( from dynamo.sdk.lib.loader import find_and_load_service dyn_svc = find_and_load_service(build_config.service, working_dir=build_ctx) - # Clean up unused edges LinkedServices.remove_unused_edges() dyn_svc.inject_config() diff --git a/examples/hello_world/hello_world.py b/examples/hello_world/hello_world.py index 2cdbf949b9..3358b9d7ce 100644 --- a/examples/hello_world/hello_world.py +++ b/examples/hello_world/hello_world.py @@ -71,7 +71,7 @@ class ResponseType(BaseModel): resources={"cpu": 1, "memory": "500Mi"}, workers=2, image=DYNAMO_IMAGE, - kubernetes_overrides={"entrypoint": "sh -c 'echo hello from Backend!'"}, + kubernetes_overrides={"entrypoint": "sh -c", "cmd": "echo hello from Backend!"}, ) class Backend: def __init__(self) -> None: From 457db96f99038fcce44af36da9a2302c662d5cff Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Wed, 11 Jun 2025 23:59:55 -0700 Subject: [PATCH 11/34] fixed a bug with args --- .../dynamocomponentdeployment_controller.go | 9 +++++++-- docs/examples/hello_world.md | 11 +++++++++-- examples/hello_world/hello_world.py | 6 ++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index 56b59b104f..2db10fb4c0 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -1560,7 +1560,7 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex Name: "main", Image: imageName, Command: []string{"sh", "-c"}, - Args: []string{strings.Join(args, " ")}, + Args: args, LivenessProbe: livenessProbe, ReadinessProbe: readinessProbe, Resources: resources, @@ -1661,7 +1661,12 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex container.Command = extraPodSpecMainContainer.Command } if len(extraPodSpecMainContainer.Args) > 0 { - container.Args = extraPodSpecMainContainer.Args + // Special case: if command is "sh -c", we must collapse args into a single string + if len(container.Command) == 2 && container.Command[0] == "sh" && container.Command[1] == "-c" { + container.Args = []string{strings.Join(extraPodSpecMainContainer.Args, " ")} + } else { + container.Args = extraPodSpecMainContainer.Args + } } } } diff --git a/docs/examples/hello_world.md b/docs/examples/hello_world.md index a0e62c31ef..774efbd57d 100644 --- a/docs/examples/hello_world.md +++ b/docs/examples/hello_world.md @@ -95,12 +95,19 @@ This example can be deployed to a Kubernetes cluster using [Dynamo Cloud](../../ You must have first followed the instructions in [deploy/cloud/helm/README.md](https://github.com/ai-dynamo/dynamo/blob/main/deploy/cloud/helm/README.md) to create your Dynamo cloud deployment. -### Deployment Steps +### Deployment Steps For your Hello World graph. For detailed deployment instructions, please refer to the [Operator Deployment Guide](../../docs/guides/dynamo_deploy/operator_deployment.md). The following are the specific commands for the hello world example: ```bash -# Set your project root directory +Make sure your dynamo cloud deploy.sh script from the prior step finished successfully and setup port forwaring in another window +per its suggestion. + +kubectl port-forward svc/...-dynamo-api-store :80 -n $NAMESPACE + + +# Set your dynamo root directory +cd export PROJECT_ROOT=$(pwd) # Configure environment variables (see operator_deployment.md for details) diff --git a/examples/hello_world/hello_world.py b/examples/hello_world/hello_world.py index 3358b9d7ce..625058e733 100644 --- a/examples/hello_world/hello_world.py +++ b/examples/hello_world/hello_world.py @@ -71,7 +71,6 @@ class ResponseType(BaseModel): resources={"cpu": 1, "memory": "500Mi"}, workers=2, image=DYNAMO_IMAGE, - kubernetes_overrides={"entrypoint": "sh -c", "cmd": "echo hello from Backend!"}, ) class Backend: def __init__(self) -> None: @@ -126,7 +125,10 @@ def shutdown(self): @service( dynamo={"namespace": "inference"}, image=DYNAMO_IMAGE, - kubernetes_overrides={"entrypoint": "sh -c 'echo hello from FrontEnd!'"}, + kubernetes_overrides={ + "entrypoint": "sh -c", + "cmd": "echo hello from FrontEnd!; sleep 99999", + }, ) class Frontend: """A simple frontend HTTP API that forwards requests to the dynamo graph.""" From a8060504cdf786a5e95c8f2456b1d7585bab371b Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 01:16:30 -0700 Subject: [PATCH 12/34] bring back licenses --- .../nvidia.com_dynamocomponentdeployments.yaml | 15 +++++++++++++++ .../crd/bases/nvidia.com_dynamocomponents.yaml | 14 ++++++++++++++ .../bases/nvidia.com_dynamographdeployments.yaml | 14 ++++++++++++++ deploy/cloud/operator/config/rbac/role.yaml | 16 ++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml index 7d44d531ee..0dc3b1caec 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponentdeployments.yaml @@ -1,3 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml index a0d3f8e862..837b590c02 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamocomponents.yaml @@ -1,3 +1,17 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition diff --git a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml index 2a0e3e334e..0c3e0d8bf7 100644 --- a/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml +++ b/deploy/cloud/operator/config/crd/bases/nvidia.com_dynamographdeployments.yaml @@ -1,3 +1,17 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition diff --git a/deploy/cloud/operator/config/rbac/role.yaml b/deploy/cloud/operator/config/rbac/role.yaml index 3f4c7196ba..c6983c5f29 100644 --- a/deploy/cloud/operator/config/rbac/role.yaml +++ b/deploy/cloud/operator/config/rbac/role.yaml @@ -1,3 +1,19 @@ + +# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole From 6542ad34c17c21340612a831071a1a156e2da591 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 09:57:20 -0700 Subject: [PATCH 13/34] Copy crds to deploy/cloud/helm/crds/template --- ...nvidia.com_dynamocomponentdeployments.yaml | 680 ++++++++++++++++- .../nvidia.com_dynamocomponents.yaml | 681 +++++++++++++++++- .../nvidia.com_dynamographdeployments.yaml | 681 +++++++++++++++++- deploy/cloud/helm/deploy.sh | 1 + deploy/cloud/operator/config/rbac/role.yaml | 1 - 5 files changed, 2035 insertions(+), 9 deletions(-) diff --git a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml index 3c8d5c5738..0dc3b1caec 100644 --- a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml +++ b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml @@ -19,8 +19,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 - # never delete this resource with helm delete - helm.sh/resource-policy: keep name: dynamocomponentdeployments.nvidia.com spec: group: nvidia.com @@ -1608,6 +1606,684 @@ spec: - name type: object type: array + mainContainer: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object nodeSelector: additionalProperties: type: string diff --git a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml index 6455afdd39..837b590c02 100644 --- a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml +++ b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml @@ -12,15 +12,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 - # never delete this resource with helm delete - helm.sh/resource-policy: keep name: dynamocomponents.nvidia.com spec: group: nvidia.com @@ -1328,6 +1325,684 @@ spec: - name type: object type: array + mainContainer: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object nodeSelector: additionalProperties: type: string diff --git a/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml b/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml index 6520e9deeb..0c3e0d8bf7 100644 --- a/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml +++ b/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml @@ -12,15 +12,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 - # never delete this resource with helm delete - helm.sh/resource-policy: keep name: dynamographdeployments.nvidia.com spec: group: nvidia.com @@ -1663,6 +1660,684 @@ spec: - name type: object type: array + mainContainer: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object nodeSelector: additionalProperties: type: string diff --git a/deploy/cloud/helm/deploy.sh b/deploy/cloud/helm/deploy.sh index 1ce42c6641..930224e290 100755 --- a/deploy/cloud/helm/deploy.sh +++ b/deploy/cloud/helm/deploy.sh @@ -172,5 +172,6 @@ $HELM_CMD upgrade --install $RELEASE_NAME platform/ \ -f generated-values.yaml \ --create-namespace \ --namespace ${NAMESPACE} + --timeout 10m0s echo "Helm chart deployment complete" diff --git a/deploy/cloud/operator/config/rbac/role.yaml b/deploy/cloud/operator/config/rbac/role.yaml index c6983c5f29..694d247800 100644 --- a/deploy/cloud/operator/config/rbac/role.yaml +++ b/deploy/cloud/operator/config/rbac/role.yaml @@ -1,4 +1,3 @@ - # SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # From 42663721752d83603a18970c688c44bd32a93259 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 11:29:38 -0700 Subject: [PATCH 14/34] Brign back helm.sh/resource-policy: keep --- .../crds/templates/nvidia.com_dynamocomponentdeployments.yaml | 2 ++ .../cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml | 3 +++ .../helm/crds/templates/nvidia.com_dynamographdeployments.yaml | 3 +++ deploy/cloud/helm/deploy.sh | 2 +- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml index 0dc3b1caec..1ecdd6d1a3 100644 --- a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml +++ b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponentdeployments.yaml @@ -19,6 +19,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 + # never delete this resource with helm delete + helm.sh/resource-policy: keep name: dynamocomponentdeployments.nvidia.com spec: group: nvidia.com diff --git a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml index 837b590c02..2f0d95566b 100644 --- a/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml +++ b/deploy/cloud/helm/crds/templates/nvidia.com_dynamocomponents.yaml @@ -12,12 +12,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 + # never delete this resource with helm delete + helm.sh/resource-policy: keep name: dynamocomponents.nvidia.com spec: group: nvidia.com diff --git a/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml b/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml index 0c3e0d8bf7..8ced1faf52 100644 --- a/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml +++ b/deploy/cloud/helm/crds/templates/nvidia.com_dynamographdeployments.yaml @@ -12,12 +12,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.4 + # never delete this resource with helm delete + helm.sh/resource-policy: keep name: dynamographdeployments.nvidia.com spec: group: nvidia.com diff --git a/deploy/cloud/helm/deploy.sh b/deploy/cloud/helm/deploy.sh index 930224e290..0ccf23ebda 100755 --- a/deploy/cloud/helm/deploy.sh +++ b/deploy/cloud/helm/deploy.sh @@ -171,7 +171,7 @@ echo "Installing/upgrading helm chart..." $HELM_CMD upgrade --install $RELEASE_NAME platform/ \ -f generated-values.yaml \ --create-namespace \ - --namespace ${NAMESPACE} + --namespace ${NAMESPACE} \ --timeout 10m0s echo "Helm chart deployment complete" From 4d8520c33e8e658cdd1628ebc9249136c42f4719 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 16:09:16 -0700 Subject: [PATCH 15/34] add comments --- deploy/cloud/helm/deploy.sh | 3 +-- .../dynamocomponentdeployment_controller.go | 12 +++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/deploy/cloud/helm/deploy.sh b/deploy/cloud/helm/deploy.sh index 0ccf23ebda..1ce42c6641 100755 --- a/deploy/cloud/helm/deploy.sh +++ b/deploy/cloud/helm/deploy.sh @@ -171,7 +171,6 @@ echo "Installing/upgrading helm chart..." $HELM_CMD upgrade --install $RELEASE_NAME platform/ \ -f generated-values.yaml \ --create-namespace \ - --namespace ${NAMESPACE} \ - --timeout 10m0s + --namespace ${NAMESPACE} echo "Helm chart deployment complete" diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index 2db10fb4c0..9028d85fd4 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -1339,6 +1339,7 @@ func getDynamoComponentRepositoryNameAndDynamoComponentVersion(dynamoComponent * //nolint:gocyclo,nakedret func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx context.Context, opt generateResourceOption) (podTemplateSpec *corev1.PodTemplateSpec, err error) { + logs := log.FromContext(ctx) podLabels := r.getKubeLabels(opt.dynamoComponentDeployment, opt.dynamoComponent) if opt.isStealingTrafficDebugModeEnabled { podLabels[commonconsts.KubeLabelDynamoDeploymentTargetType] = DeploymentTargetTypeDebug @@ -1655,20 +1656,29 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex // For now only overwrite the command and args. if opt.dynamoComponentDeployment.Spec.ExtraPodSpec != nil { + logs.Info("ExtraPodSpec is present in DynamoComponentDeployment.Spec.ExtraPodSpec") extraPodSpecMainContainer := opt.dynamoComponentDeployment.Spec.ExtraPodSpec.MainContainer if extraPodSpecMainContainer != nil { + logs.Info("ExtraPodSpec.MainContainer is specified (checking for overrides on container '" + container.Name + "')") if len(extraPodSpecMainContainer.Command) > 0 { + logs.Info("Overriding container '" + container.Name + "' Command with: " + strings.Join(extraPodSpecMainContainer.Command, " ")) container.Command = extraPodSpecMainContainer.Command } if len(extraPodSpecMainContainer.Args) > 0 { + logs.Info("ExtraPodSpec.MainContainer.Args is present for container '" + container.Name + "'") // Special case: if command is "sh -c", we must collapse args into a single string if len(container.Command) == 2 && container.Command[0] == "sh" && container.Command[1] == "-c" { - container.Args = []string{strings.Join(extraPodSpecMainContainer.Args, " ")} + joinedArgs := strings.Join(extraPodSpecMainContainer.Args, " ") + logs.Info("Special case detected for container '" + container.Name + "': Command is 'sh -c'; collapsing Args to: " + joinedArgs) + container.Args = []string{joinedArgs} } else { + logs.Info("Overriding container '" + container.Name + "' Args with: " + strings.Join(extraPodSpecMainContainer.Args, " ")) container.Args = extraPodSpecMainContainer.Args } } } + } else { + logs.Info("No ExtraPodSpec provided in DynamoComponentDeployment.Spec.ExtraPodSpec for container '" + container.Name + "'") } containers = append(containers, container) From f57694848829f5c5bcdabb80d0837a95edc0bd65 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 18:35:43 -0700 Subject: [PATCH 16/34] add DynamoGraphDeploymentController changes --- .../dynamographdeployment_controller.go | 14 ++++++++++++++ deploy/cloud/operator/internal/dynamo/graph.go | 17 +++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go index 4b8d03bced..6ebd40b460 100644 --- a/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go @@ -19,6 +19,7 @@ package controller import ( "context" + "encoding/json" "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -125,6 +126,19 @@ func (r *DynamoGraphDeploymentReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{}, err } + for _, service := range dynamoGraphConfig.Services { + if service.Config.ExtraPodSpec != nil { + extraPodSpecBytes, err := json.MarshalIndent(service.Config.ExtraPodSpec, "", " ") + if err != nil { + logger.Error(err, "failed to marshal ExtraPodSpec for logging", "service", service.Name) + } else { + logger.Info("Parsed ExtraPodSpec for service", "service", service.Name, "ExtraPodSpec", string(extraPodSpecBytes)) + } + } else { + logger.Info("No ExtraPodSpec found for service", "service", service.Name) + } + } + // generate the dynamoComponentsDeployments from the config dynamoComponentsDeployments, err := dynamo.GenerateDynamoComponentsDeployments(ctx, dynamoDeployment, dynamoGraphConfig, r.generateDefaultIngressSpec(dynamoDeployment)) if err != nil { diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index aac37e3376..59cc553265 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -75,14 +75,15 @@ type Autoscaling struct { } type Config struct { - Dynamo *DynamoConfig `yaml:"dynamo,omitempty"` - Resources *Resources `yaml:"resources,omitempty"` - Traffic *Traffic `yaml:"traffic,omitempty"` - Autoscaling *Autoscaling `yaml:"autoscaling,omitempty"` - HttpExposed bool `yaml:"http_exposed,omitempty"` - ApiEndpoints []string `yaml:"api_endpoints,omitempty"` - Workers *int32 `yaml:"workers,omitempty"` - TotalGpus *int32 `yaml:"total_gpus,omitempty"` + Dynamo *DynamoConfig `yaml:"dynamo,omitempty"` + Resources *Resources `yaml:"resources,omitempty"` + Traffic *Traffic `yaml:"traffic,omitempty"` + Autoscaling *Autoscaling `yaml:"autoscaling,omitempty"` + HttpExposed bool `yaml:"http_exposed,omitempty"` + ApiEndpoints []string `yaml:"api_endpoints,omitempty"` + Workers *int32 `yaml:"workers,omitempty"` + TotalGpus *int32 `yaml:"total_gpus,omitempty"` + ExtraPodSpec *common.ExtraPodSpec `yaml:"extraPodSpec,omitempty"` } type ServiceConfig struct { From 3194e3b5c48ee5fa937fab93d2b02c47bffc9e4b Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 20:31:44 -0700 Subject: [PATCH 17/34] Fix the parsing of the ExtraPodSpec --- deploy/cloud/operator/internal/dynamo/graph.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index 59cc553265..b5d31de980 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -361,6 +361,18 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD return nil, err } } + + // propagate generic pod-level overrides + if service.Config.ExtraPodSpec != nil { + if deployment.Spec.ExtraPodSpec == nil { + deployment.Spec.ExtraPodSpec = new(common.ExtraPodSpec) + } + if err := mergo.Merge(deployment.Spec.ExtraPodSpec, + service.Config.ExtraPodSpec, mergo.WithOverride); err != nil { + return nil, fmt.Errorf("merge extraPodSpec: %w", err) + } + } + deployment.Spec.Autoscaling = &v1alpha1.Autoscaling{ Enabled: false, } From ec45e87cbfe0ca5da7a382e8959b89c2b198a4d3 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Thu, 12 Jun 2025 21:17:51 -0700 Subject: [PATCH 18/34] fix up the overrides --- .../cloud/operator/internal/dynamo/graph.go | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index b5d31de980..b4f63faba9 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -285,6 +285,7 @@ func SetLwsAnnotations(serviceArgs *ServiceArgs, deployment *v1alpha1.DynamoComp // GenerateDynamoComponentsDeployments generates a map of DynamoComponentDeployments from a DynamoGraphConfig func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphDeployment *v1alpha1.DynamoGraphDeployment, config *DynamoGraphConfig, ingressSpec *v1alpha1.IngressSpec) (map[string]*v1alpha1.DynamoComponentDeployment, error) { + logger := log.FromContext(ctx) dynamoServices := make(map[string]string) deployments := make(map[string]*v1alpha1.DynamoComponentDeployment) graphDynamoNamespace := "" @@ -362,14 +363,34 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD } } - // propagate generic pod-level overrides - if service.Config.ExtraPodSpec != nil { + // Override command and args if provided. + if service.Config.ExtraPodSpec != nil && service.Config.ExtraPodSpec.MainContainer != nil { if deployment.Spec.ExtraPodSpec == nil { deployment.Spec.ExtraPodSpec = new(common.ExtraPodSpec) } - if err := mergo.Merge(deployment.Spec.ExtraPodSpec, - service.Config.ExtraPodSpec, mergo.WithOverride); err != nil { - return nil, fmt.Errorf("merge extraPodSpec: %w", err) + + commandIsSet := len(service.Config.ExtraPodSpec.MainContainer.Command) > 0 + argsIsSet := len(service.Config.ExtraPodSpec.MainContainer.Args) > 0 + + if commandIsSet || argsIsSet { + deployment.Spec.ExtraPodSpec.MainContainer = &corev1.Container{} + + if commandIsSet { + deployment.Spec.ExtraPodSpec.MainContainer.Command = service.Config.ExtraPodSpec.MainContainer.Command + } + + if argsIsSet { + deployment.Spec.ExtraPodSpec.MainContainer.Args = service.Config.ExtraPodSpec.MainContainer.Args + } + + extraPodSpecBytes, err := json.MarshalIndent(deployment.Spec.ExtraPodSpec.MainContainer, "", " ") + if err != nil { + logger.Error(err, "failed to marshal deployment.Spec.ExtraPodSpec.MainContainer for logging", "service", service.Name) + } else { + logger.Info("Copied MainContainer Command/Args", "service", service.Name, "MainContainer", string(extraPodSpecBytes)) + } + } else { + logger.Info("Skipping MainContainer because both Command and Args are empty", "service", service.Name) } } From 40b13cd00fbbc4c41c25daa45adc3fd38cbcfd11 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 12:00:44 -0700 Subject: [PATCH 19/34] Move the ExtraPodSpec Overrides --- deploy/cloud/operator/internal/dynamo/graph.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index b4f63faba9..4bf6836590 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -363,6 +363,14 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD } } + // override the component config with the component config that is in the parent deployment + if configOverride, ok := parentDynamoGraphDeployment.Spec.Services[service.Name]; ok { + err := mergo.Merge(&deployment.Spec.DynamoComponentDeploymentSharedSpec, configOverride.DynamoComponentDeploymentSharedSpec, mergo.WithOverride) + if err != nil { + return nil, err + } + } + // Override command and args if provided. if service.Config.ExtraPodSpec != nil && service.Config.ExtraPodSpec.MainContainer != nil { if deployment.Spec.ExtraPodSpec == nil { @@ -402,13 +410,6 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD deployment.Spec.Autoscaling.MinReplicas = service.Config.Autoscaling.MinReplicas deployment.Spec.Autoscaling.MaxReplicas = service.Config.Autoscaling.MaxReplicas } - // override the component config with the component config that is in the parent deployment - if configOverride, ok := parentDynamoGraphDeployment.Spec.Services[service.Name]; ok { - err := mergo.Merge(&deployment.Spec.DynamoComponentDeploymentSharedSpec, configOverride.DynamoComponentDeploymentSharedSpec, mergo.WithOverride) - if err != nil { - return nil, err - } - } // merge the envs from the parent deployment with the envs from the service if len(parentDynamoGraphDeployment.Spec.Envs) > 0 { deployment.Spec.Envs = mergeEnvs(parentDynamoGraphDeployment.Spec.Envs, deployment.Spec.Envs) From 0a227b1889898f3e2465daa3dd8eee76f2c78da1 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 12:10:25 -0700 Subject: [PATCH 20/34] proper naming for sharedSpec --- deploy/cloud/operator/internal/dynamo/graph.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index 4bf6836590..b7d2466f61 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -373,27 +373,27 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD // Override command and args if provided. if service.Config.ExtraPodSpec != nil && service.Config.ExtraPodSpec.MainContainer != nil { - if deployment.Spec.ExtraPodSpec == nil { - deployment.Spec.ExtraPodSpec = new(common.ExtraPodSpec) + if deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec == nil { + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec = new(common.ExtraPodSpec) } commandIsSet := len(service.Config.ExtraPodSpec.MainContainer.Command) > 0 argsIsSet := len(service.Config.ExtraPodSpec.MainContainer.Args) > 0 if commandIsSet || argsIsSet { - deployment.Spec.ExtraPodSpec.MainContainer = &corev1.Container{} + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer = &corev1.Container{} if commandIsSet { - deployment.Spec.ExtraPodSpec.MainContainer.Command = service.Config.ExtraPodSpec.MainContainer.Command + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer.Command = service.Config.ExtraPodSpec.MainContainer.Command } if argsIsSet { - deployment.Spec.ExtraPodSpec.MainContainer.Args = service.Config.ExtraPodSpec.MainContainer.Args + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer.Args = service.Config.ExtraPodSpec.MainContainer.Args } - extraPodSpecBytes, err := json.MarshalIndent(deployment.Spec.ExtraPodSpec.MainContainer, "", " ") + extraPodSpecBytes, err := json.MarshalIndent(deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer, "", " ") if err != nil { - logger.Error(err, "failed to marshal deployment.Spec.ExtraPodSpec.MainContainer for logging", "service", service.Name) + logger.Error(err, "failed to marshal deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer for logging", "service", service.Name) } else { logger.Info("Copied MainContainer Command/Args", "service", service.Name, "MainContainer", string(extraPodSpecBytes)) } From 190507823a34a041dd66e9a6010f76fe8931bdf1 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 12:40:49 -0700 Subject: [PATCH 21/34] move the override override the component config with the component config that is in the parent deployment should be after autoscaling. --- deploy/cloud/operator/internal/dynamo/graph.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index b7d2466f61..8215a9375d 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -363,6 +363,15 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD } } + deployment.Spec.Autoscaling = &v1alpha1.Autoscaling{ + Enabled: false, + } + if service.Config.Autoscaling != nil { + deployment.Spec.Autoscaling.Enabled = true + deployment.Spec.Autoscaling.MinReplicas = service.Config.Autoscaling.MinReplicas + deployment.Spec.Autoscaling.MaxReplicas = service.Config.Autoscaling.MaxReplicas + } + // override the component config with the component config that is in the parent deployment if configOverride, ok := parentDynamoGraphDeployment.Spec.Services[service.Name]; ok { err := mergo.Merge(&deployment.Spec.DynamoComponentDeploymentSharedSpec, configOverride.DynamoComponentDeploymentSharedSpec, mergo.WithOverride) @@ -402,14 +411,6 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD } } - deployment.Spec.Autoscaling = &v1alpha1.Autoscaling{ - Enabled: false, - } - if service.Config.Autoscaling != nil { - deployment.Spec.Autoscaling.Enabled = true - deployment.Spec.Autoscaling.MinReplicas = service.Config.Autoscaling.MinReplicas - deployment.Spec.Autoscaling.MaxReplicas = service.Config.Autoscaling.MaxReplicas - } // merge the envs from the parent deployment with the envs from the service if len(parentDynamoGraphDeployment.Spec.Envs) > 0 { deployment.Spec.Envs = mergeEnvs(parentDynamoGraphDeployment.Spec.Envs, deployment.Spec.Envs) From f0f2861dbacc70300f5a5d91c1184fd34a5e84d0 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 12:42:25 -0700 Subject: [PATCH 22/34] revert default args --- .../internal/controller/dynamocomponentdeployment_controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index 9028d85fd4..20b0a01d4b 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -1561,7 +1561,7 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex Name: "main", Image: imageName, Command: []string{"sh", "-c"}, - Args: args, + Args: []string{strings.Join(args, " ")}, LivenessProbe: livenessProbe, ReadinessProbe: readinessProbe, Resources: resources, From 731269a47ab02b729948f176eaa28f6264265852 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 14:10:46 -0700 Subject: [PATCH 23/34] change the parsing library for yaml case --- ATTRIBUTIONS-Go.md | 12 +++--- deploy/cloud/operator/go.mod | 2 +- deploy/cloud/operator/go.sum | 4 +- .../controller/dynamocomponent_controller.go | 2 +- .../cloud/operator/internal/dynamo/graph.go | 39 +++++++++++++------ 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/ATTRIBUTIONS-Go.md b/ATTRIBUTIONS-Go.md index 8235410816..29ca0ea3be 100644 --- a/ATTRIBUTIONS-Go.md +++ b/ATTRIBUTIONS-Go.md @@ -1484,7 +1484,7 @@ Subdependencies: * `golang.org/x/net` * `golang.org/x/text` * `gopkg.in/inf.v0` -* `gopkg.in/yaml.v2` +* `github.com/goccy/go-yaml` * `k8s.io/klog/v2` * `k8s.io/utils` * `sigs.k8s.io/json` @@ -3179,7 +3179,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ``` -### gopkg.in/yaml.v2 +### github.com/goccy/go-yaml License Identifier: Apache-2.0 License Text: @@ -4864,7 +4864,7 @@ Subdependencies: * `google.golang.org/genproto/googleapis/api` * `google.golang.org/genproto/googleapis/rpc` * `google.golang.org/protobuf` -* `gopkg.in/yaml.v2` +* `github.com/goccy/go-yaml` ### github.com/dustin/go-humanize @@ -8180,7 +8180,7 @@ Subdependencies: * `golang.org/x/text` * `google.golang.org/genproto/googleapis/rpc` * `gopkg.in/inf.v0` -* `gopkg.in/yaml.v2` +* `github.com/goccy/go-yaml` * `k8s.io/klog/v2` * `k8s.io/utils` * `sigs.k8s.io/json` @@ -9056,7 +9056,7 @@ Subdependencies: * `google.golang.org/genproto/googleapis/api` * `google.golang.org/protobuf` * `gopkg.in/inf.v0` -* `gopkg.in/yaml.v2` +* `github.com/goccy/go-yaml` * `gopkg.in/yaml.v3` * `k8s.io/api` * `k8s.io/klog/v2` @@ -22970,7 +22970,7 @@ Subdependencies: * `google.golang.org/protobuf` * `gopkg.in/evanphx/json-patch.v4` * `gopkg.in/inf.v0` -* `gopkg.in/yaml.v2` +* `github.com/goccy/go-yaml` * `gopkg.in/yaml.v3` * `k8s.io/component-base` * `k8s.io/gengo/v2` diff --git a/deploy/cloud/operator/go.mod b/deploy/cloud/operator/go.mod index b9049f4d0c..c09729b3d2 100644 --- a/deploy/cloud/operator/go.mod +++ b/deploy/cloud/operator/go.mod @@ -11,6 +11,7 @@ require ( github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.9.1 github.com/bsm/gomega v1.27.10 github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 + github.com/goccy/go-yaml v1.18.0 github.com/google/go-cmp v0.7.0 github.com/google/go-containerregistry v0.20.5 github.com/huandu/xstrings v1.4.0 @@ -22,7 +23,6 @@ require ( github.com/sergeymakinen/go-quote v1.1.0 github.com/sirupsen/logrus v1.9.3 go.etcd.io/etcd/client/v3 v3.5.16 - gopkg.in/yaml.v2 v2.4.0 istio.io/api v1.23.1 istio.io/client-go v1.23.1 k8s.io/api v0.32.3 diff --git a/deploy/cloud/operator/go.sum b/deploy/cloud/operator/go.sum index f8ff3373f6..ce7d4ea1e2 100644 --- a/deploy/cloud/operator/go.sum +++ b/deploy/cloud/operator/go.sum @@ -111,6 +111,8 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -310,8 +312,6 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go index 9728ea9323..4df86d2a9a 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponent_controller.go @@ -40,6 +40,7 @@ import ( "github.com/apparentlymart/go-shquot/shquot" "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" + "github.com/goccy/go-yaml" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/google" @@ -49,7 +50,6 @@ import ( "github.com/rs/xid" "github.com/sergeymakinen/go-quote/unix" "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index 8215a9375d..ec903381d1 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -42,7 +42,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "github.com/ai-dynamo/dynamo/deploy/cloud/operator/internal/archive" - "gopkg.in/yaml.v2" + "github.com/goccy/go-yaml" ) const ( @@ -237,7 +237,25 @@ func ParseDynamoGraphConfig(ctx context.Context, yamlContent *bytes.Buffer) (*Dy logger := log.FromContext(ctx) logger.Info("trying to parse dynamo graph config", "yamlContent", yamlContent.String()) err := yaml.Unmarshal(yamlContent.Bytes(), &config) - return &config, err + if err != nil { + return nil, err + } + + // Add debug logging for ExtraPodSpec + for _, service := range config.Services { + if service.Config.ExtraPodSpec != nil { + extraPodSpecBytes, err := json.MarshalIndent(service.Config.ExtraPodSpec, "", " ") + if err != nil { + logger.Error(err, "failed to marshal ExtraPodSpec for logging", "service", service.Name) + } else { + logger.Info("Parsed ExtraPodSpec for service", "service", service.Name, "ExtraPodSpec", string(extraPodSpecBytes)) + } + } else { + logger.Info("No ExtraPodSpec found for service", "service", service.Name) + } + } + + return &config, nil } func ParseDynDeploymentConfig(ctx context.Context, jsonContent []byte) (DynDeploymentConfig, error) { @@ -371,15 +389,6 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD deployment.Spec.Autoscaling.MinReplicas = service.Config.Autoscaling.MinReplicas deployment.Spec.Autoscaling.MaxReplicas = service.Config.Autoscaling.MaxReplicas } - - // override the component config with the component config that is in the parent deployment - if configOverride, ok := parentDynamoGraphDeployment.Spec.Services[service.Name]; ok { - err := mergo.Merge(&deployment.Spec.DynamoComponentDeploymentSharedSpec, configOverride.DynamoComponentDeploymentSharedSpec, mergo.WithOverride) - if err != nil { - return nil, err - } - } - // Override command and args if provided. if service.Config.ExtraPodSpec != nil && service.Config.ExtraPodSpec.MainContainer != nil { if deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec == nil { @@ -411,6 +420,14 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD } } + // override the component config with the component config that is in the parent deployment + if configOverride, ok := parentDynamoGraphDeployment.Spec.Services[service.Name]; ok { + err := mergo.Merge(&deployment.Spec.DynamoComponentDeploymentSharedSpec, configOverride.DynamoComponentDeploymentSharedSpec, mergo.WithOverride) + if err != nil { + return nil, err + } + } + // merge the envs from the parent deployment with the envs from the service if len(parentDynamoGraphDeployment.Spec.Envs) > 0 { deployment.Spec.Envs = mergeEnvs(parentDynamoGraphDeployment.Spec.Envs, deployment.Spec.Envs) From 8e0e249e041eb7a71745077952972815a804e09f Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 16:39:21 -0700 Subject: [PATCH 24/34] replace parsing lib and remove comments --- .../dynamocomponentdeployment_controller.go | 5 ---- .../dynamographdeployment_controller.go | 14 --------- .../cloud/operator/internal/dynamo/graph.go | 29 +------------------ docs/examples/hello_world.md | 2 +- examples/hello_world/hello_world.py | 9 +++--- 5 files changed, 7 insertions(+), 52 deletions(-) diff --git a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go index 20b0a01d4b..4c49ba8d35 100644 --- a/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamocomponentdeployment_controller.go @@ -1656,16 +1656,13 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex // For now only overwrite the command and args. if opt.dynamoComponentDeployment.Spec.ExtraPodSpec != nil { - logs.Info("ExtraPodSpec is present in DynamoComponentDeployment.Spec.ExtraPodSpec") extraPodSpecMainContainer := opt.dynamoComponentDeployment.Spec.ExtraPodSpec.MainContainer if extraPodSpecMainContainer != nil { - logs.Info("ExtraPodSpec.MainContainer is specified (checking for overrides on container '" + container.Name + "')") if len(extraPodSpecMainContainer.Command) > 0 { logs.Info("Overriding container '" + container.Name + "' Command with: " + strings.Join(extraPodSpecMainContainer.Command, " ")) container.Command = extraPodSpecMainContainer.Command } if len(extraPodSpecMainContainer.Args) > 0 { - logs.Info("ExtraPodSpec.MainContainer.Args is present for container '" + container.Name + "'") // Special case: if command is "sh -c", we must collapse args into a single string if len(container.Command) == 2 && container.Command[0] == "sh" && container.Command[1] == "-c" { joinedArgs := strings.Join(extraPodSpecMainContainer.Args, " ") @@ -1677,8 +1674,6 @@ func (r *DynamoComponentDeploymentReconciler) generatePodTemplateSpec(ctx contex } } } - } else { - logs.Info("No ExtraPodSpec provided in DynamoComponentDeployment.Spec.ExtraPodSpec for container '" + container.Name + "'") } containers = append(containers, container) diff --git a/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go b/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go index 6ebd40b460..4b8d03bced 100644 --- a/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go +++ b/deploy/cloud/operator/internal/controller/dynamographdeployment_controller.go @@ -19,7 +19,6 @@ package controller import ( "context" - "encoding/json" "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -126,19 +125,6 @@ func (r *DynamoGraphDeploymentReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{}, err } - for _, service := range dynamoGraphConfig.Services { - if service.Config.ExtraPodSpec != nil { - extraPodSpecBytes, err := json.MarshalIndent(service.Config.ExtraPodSpec, "", " ") - if err != nil { - logger.Error(err, "failed to marshal ExtraPodSpec for logging", "service", service.Name) - } else { - logger.Info("Parsed ExtraPodSpec for service", "service", service.Name, "ExtraPodSpec", string(extraPodSpecBytes)) - } - } else { - logger.Info("No ExtraPodSpec found for service", "service", service.Name) - } - } - // generate the dynamoComponentsDeployments from the config dynamoComponentsDeployments, err := dynamo.GenerateDynamoComponentsDeployments(ctx, dynamoDeployment, dynamoGraphConfig, r.generateDefaultIngressSpec(dynamoDeployment)) if err != nil { diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index ec903381d1..d17bcbb784 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -237,25 +237,7 @@ func ParseDynamoGraphConfig(ctx context.Context, yamlContent *bytes.Buffer) (*Dy logger := log.FromContext(ctx) logger.Info("trying to parse dynamo graph config", "yamlContent", yamlContent.String()) err := yaml.Unmarshal(yamlContent.Bytes(), &config) - if err != nil { - return nil, err - } - - // Add debug logging for ExtraPodSpec - for _, service := range config.Services { - if service.Config.ExtraPodSpec != nil { - extraPodSpecBytes, err := json.MarshalIndent(service.Config.ExtraPodSpec, "", " ") - if err != nil { - logger.Error(err, "failed to marshal ExtraPodSpec for logging", "service", service.Name) - } else { - logger.Info("Parsed ExtraPodSpec for service", "service", service.Name, "ExtraPodSpec", string(extraPodSpecBytes)) - } - } else { - logger.Info("No ExtraPodSpec found for service", "service", service.Name) - } - } - - return &config, nil + return &config, err } func ParseDynDeploymentConfig(ctx context.Context, jsonContent []byte) (DynDeploymentConfig, error) { @@ -408,15 +390,6 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD if argsIsSet { deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer.Args = service.Config.ExtraPodSpec.MainContainer.Args } - - extraPodSpecBytes, err := json.MarshalIndent(deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer, "", " ") - if err != nil { - logger.Error(err, "failed to marshal deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer for logging", "service", service.Name) - } else { - logger.Info("Copied MainContainer Command/Args", "service", service.Name, "MainContainer", string(extraPodSpecBytes)) - } - } else { - logger.Info("Skipping MainContainer because both Command and Args are empty", "service", service.Name) } } diff --git a/docs/examples/hello_world.md b/docs/examples/hello_world.md index 774efbd57d..4081a4778d 100644 --- a/docs/examples/hello_world.md +++ b/docs/examples/hello_world.md @@ -124,7 +124,7 @@ cd $PROJECT_ROOT/examples/hello_world DYNAMO_TAG=$(dynamo build hello_world:Frontend | grep "Successfully built" | awk '{ print $3 }' | sed 's/\.$//') # Deploy to Kubernetes -export DEPLOYMENT_NAME=ci-hw +export DEPLOYMENT_NAME=fixlib dynamo deployment create $DYNAMO_TAG -n $DEPLOYMENT_NAME ``` diff --git a/examples/hello_world/hello_world.py b/examples/hello_world/hello_world.py index 625058e733..2570180513 100644 --- a/examples/hello_world/hello_world.py +++ b/examples/hello_world/hello_world.py @@ -125,10 +125,11 @@ def shutdown(self): @service( dynamo={"namespace": "inference"}, image=DYNAMO_IMAGE, - kubernetes_overrides={ - "entrypoint": "sh -c", - "cmd": "echo hello from FrontEnd!; sleep 99999", - }, + # Example of kubernetes overrides if needed. + # kubernetes_overrides={ + # "entrypoint": "sh -c", + # "cmd": "echo hello from FrontEnd!", + # }, ) class Frontend: """A simple frontend HTTP API that forwards requests to the dynamo graph.""" From a664e2e86f7a3c7903aeec205bcb2b990be96f82 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 16:45:59 -0700 Subject: [PATCH 25/34] Cleanup. --- deploy/cloud/operator/internal/dynamo/graph.go | 1 - deploy/sdk/src/dynamo/sdk/lib/loader.py | 3 +-- docs/examples/hello_world.md | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index d17bcbb784..0b2bc1ed89 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -400,7 +400,6 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD return nil, err } } - // merge the envs from the parent deployment with the envs from the service if len(parentDynamoGraphDeployment.Spec.Envs) > 0 { deployment.Spec.Envs = mergeEnvs(parentDynamoGraphDeployment.Spec.Envs, deployment.Spec.Envs) diff --git a/deploy/sdk/src/dynamo/sdk/lib/loader.py b/deploy/sdk/src/dynamo/sdk/lib/loader.py index d481d84c8e..09264264f6 100644 --- a/deploy/sdk/src/dynamo/sdk/lib/loader.py +++ b/deploy/sdk/src/dynamo/sdk/lib/loader.py @@ -74,8 +74,7 @@ def find_and_load_service( sys_path_modified = True try: - service_instance = _do_import(import_str, working_dir) - return service_instance + return _do_import(import_str, working_dir) finally: if sys_path_modified and working_dir: logger.debug(f"Removing {working_dir} from sys.path") diff --git a/docs/examples/hello_world.md b/docs/examples/hello_world.md index 4081a4778d..774efbd57d 100644 --- a/docs/examples/hello_world.md +++ b/docs/examples/hello_world.md @@ -124,7 +124,7 @@ cd $PROJECT_ROOT/examples/hello_world DYNAMO_TAG=$(dynamo build hello_world:Frontend | grep "Successfully built" | awk '{ print $3 }' | sed 's/\.$//') # Deploy to Kubernetes -export DEPLOYMENT_NAME=fixlib +export DEPLOYMENT_NAME=ci-hw dynamo deployment create $DYNAMO_TAG -n $DEPLOYMENT_NAME ``` From 6fb1cbe1d62d17511d30b902dffce77813d9c52c Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 17:10:52 -0700 Subject: [PATCH 26/34] remove logger --- deploy/cloud/operator/internal/dynamo/graph.go | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index 0b2bc1ed89..2e22321c24 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -285,7 +285,6 @@ func SetLwsAnnotations(serviceArgs *ServiceArgs, deployment *v1alpha1.DynamoComp // GenerateDynamoComponentsDeployments generates a map of DynamoComponentDeployments from a DynamoGraphConfig func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphDeployment *v1alpha1.DynamoGraphDeployment, config *DynamoGraphConfig, ingressSpec *v1alpha1.IngressSpec) (map[string]*v1alpha1.DynamoComponentDeployment, error) { - logger := log.FromContext(ctx) dynamoServices := make(map[string]string) deployments := make(map[string]*v1alpha1.DynamoComponentDeployment) graphDynamoNamespace := "" From 81a841aa96b2c2e5a23af0dba29a6b27002456ab Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 18:02:33 -0700 Subject: [PATCH 27/34] Use BaseModel for KubernetesOverrides. --- deploy/sdk/src/dynamo/sdk/cli/build.py | 4 +++- deploy/sdk/src/dynamo/sdk/core/protocol/interface.py | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index ecb8f41378..bfacc75cc2 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -41,6 +41,7 @@ from dynamo.sdk import DYNAMO_IMAGE from dynamo.sdk.core.protocol.interface import ( DynamoTransport, + KubernetesOverrides, LinkedServices, ServiceInterface, ) @@ -108,7 +109,7 @@ class ServiceConfig(BaseModel): dynamo: t.Dict[str, t.Any] = Field(default_factory=dict) http_exposed: bool = False api_endpoints: t.List[str] = Field(default_factory=list) - kubernetes_overrides: t.Optional[t.Dict[str, t.Any]] = Field(default_factory=dict) + kubernetes_overrides: KubernetesOverrides | None = None class ServiceInfo(BaseModel): @@ -208,6 +209,7 @@ class ManifestInfo(BaseModel): def to_dict(self) -> t.Dict[str, t.Any]: """Convert to dictionary for YAML serialization.""" result = self.model_dump() + print(f"result={result}") # Convert ServiceInfo objects to dictionaries services_dict = [] for service in result["services"]: diff --git a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py index f3c3f6add2..683b9b83d7 100644 --- a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py +++ b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py @@ -74,6 +74,13 @@ class ResourceConfig(BaseModel): gpu: str = Field(default="0") +class KubernetesOverrides(BaseModel): + """Class for kubernetes overrides from the sdk to limit to supported fields.""" + + entrypoint: str | None = None + cmd: str | None = None + + class ServiceConfig(BaseModel): """Base service configuration that can be extended by adapters""" @@ -83,7 +90,7 @@ class ServiceConfig(BaseModel): image: str | None = None envs: List[Env] | None = None labels: Dict[str, str] | None = None - kubernetes_overrides: Dict[str, Any] | None = None + kubernetes_overrides: KubernetesOverrides | None = None class DynamoEndpointInterface(ABC): From d25c54ead3608955622097cb49dc6918752b2e43 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 18:17:04 -0700 Subject: [PATCH 28/34] Add a go test for overrides. --- .../operator/internal/dynamo/graph_test.go | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/deploy/cloud/operator/internal/dynamo/graph_test.go b/deploy/cloud/operator/internal/dynamo/graph_test.go index 610ff8c138..d48aa6a16c 100644 --- a/deploy/cloud/operator/internal/dynamo/graph_test.go +++ b/deploy/cloud/operator/internal/dynamo/graph_test.go @@ -1402,6 +1402,69 @@ func TestGenerateDynamoComponentsDeployments(t *testing.T) { }, wantErr: false, }, + { + name: "Test GenerateDynamoComponentsDeployments with ExtraPodSpec.MainContainer Command and Args", + args: args{ + parentDynamoGraphDeployment: &v1alpha1.DynamoGraphDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dynamographdeployment", + Namespace: "default", + }, + Spec: v1alpha1.DynamoGraphDeploymentSpec{ + DynamoGraph: "dynamocomponent:ac4e234", + }, + }, + config: &DynamoGraphConfig{ + DynamoTag: "dynamocomponent:MyServiceWithOverrides", + Services: []ServiceConfig{ + { + Name: "service1", + Dependencies: []map[string]string{}, + Config: Config{ + ExtraPodSpec: &common.ExtraPodSpec{ + MainContainer: &corev1.Container{ + Command: []string{"sh", "-c"}, + Args: []string{"echo hello world", "sleep 99999"}, + }, + }, + }, + }, + }, + }, + ingressSpec: &v1alpha1.IngressSpec{}, + }, + want: map[string]*v1alpha1.DynamoComponentDeployment{ + "service1": { + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dynamographdeployment-service1", + Namespace: "default", + Labels: map[string]string{ + commonconsts.KubeLabelDynamoComponent: "service1", + }, + }, + Spec: v1alpha1.DynamoComponentDeploymentSpec{ + DynamoComponent: "dynamocomponent:ac4e234", + DynamoTag: "dynamocomponent:MyServiceWithOverrides", + DynamoComponentDeploymentSharedSpec: v1alpha1.DynamoComponentDeploymentSharedSpec{ + ServiceName: "service1", + Autoscaling: &v1alpha1.Autoscaling{ + Enabled: false, + }, + Labels: map[string]string{ + commonconsts.KubeLabelDynamoComponent: "service1", + }, + ExtraPodSpec: &common.ExtraPodSpec{ + MainContainer: &corev1.Container{ + Command: []string{"sh", "-c"}, + Args: []string{"echo hello world", "sleep 99999"}, + }, + }, + }, + }, + }, + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 45b0b5fc51fa8c7e88a1fd1e57cdc2f99f448334 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 18:34:45 -0700 Subject: [PATCH 29/34] refactor GenerateDynamoComponentsDeployments --- .../cloud/operator/internal/dynamo/graph.go | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index 2e22321c24..a2fdeafd51 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -376,20 +376,10 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec = new(common.ExtraPodSpec) } - commandIsSet := len(service.Config.ExtraPodSpec.MainContainer.Command) > 0 - argsIsSet := len(service.Config.ExtraPodSpec.MainContainer.Args) > 0 - - if commandIsSet || argsIsSet { - deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer = &corev1.Container{} - - if commandIsSet { - deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer.Command = service.Config.ExtraPodSpec.MainContainer.Command - } - - if argsIsSet { - deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec.MainContainer.Args = service.Config.ExtraPodSpec.MainContainer.Args - } - } + overrideExtraPodSpecMainContainer( + service.Config.ExtraPodSpec, + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec, + ) } // override the component config with the component config that is in the parent deployment @@ -551,3 +541,28 @@ func mergeEnvs(common, specific []corev1.EnvVar) []corev1.EnvVar { } return merged } + +func overrideExtraPodSpecMainContainer(src *common.ExtraPodSpec, dst *common.ExtraPodSpec) { + if src == nil || src.MainContainer == nil { + return + } + + commandIsSet := len(src.MainContainer.Command) > 0 + argsIsSet := len(src.MainContainer.Args) > 0 + + if !commandIsSet && !argsIsSet { + return + } + + if dst == nil { + panic("overrideExtraPodSpecMainContainer: dst must not be nil") + } + + dst.MainContainer = &corev1.Container{} + if commandIsSet { + dst.MainContainer.Command = src.MainContainer.Command + } + if argsIsSet { + dst.MainContainer.Args = src.MainContainer.Args + } +} From 89c6a14b3d565019bef2ee48f4ddd773f0753e08 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Fri, 13 Jun 2025 20:30:12 -0700 Subject: [PATCH 30/34] fix the help func --- .../cloud/operator/internal/dynamo/graph.go | 27 ++++++++++--------- deploy/sdk/src/dynamo/sdk/cli/build.py | 1 - 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index a2fdeafd51..c6b8a0a8c5 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -376,10 +376,11 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec = new(common.ExtraPodSpec) } - overrideExtraPodSpecMainContainer( - service.Config.ExtraPodSpec, - deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec, - ) + err := overrideExtraPodSpecMainContainer(service.Config.ExtraPodSpec, &deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec) + if err != nil { + return nil, err + } + } // override the component config with the component config that is in the parent deployment @@ -542,27 +543,29 @@ func mergeEnvs(common, specific []corev1.EnvVar) []corev1.EnvVar { return merged } -func overrideExtraPodSpecMainContainer(src *common.ExtraPodSpec, dst *common.ExtraPodSpec) { +func overrideExtraPodSpecMainContainer(src *common.ExtraPodSpec, dst **common.ExtraPodSpec) error { if src == nil || src.MainContainer == nil { - return + return nil } commandIsSet := len(src.MainContainer.Command) > 0 argsIsSet := len(src.MainContainer.Args) > 0 if !commandIsSet && !argsIsSet { - return + return nil } - if dst == nil { - panic("overrideExtraPodSpecMainContainer: dst must not be nil") + if *dst == nil { + *dst = new(common.ExtraPodSpec) } - dst.MainContainer = &corev1.Container{} + (*dst).MainContainer = &corev1.Container{} if commandIsSet { - dst.MainContainer.Command = src.MainContainer.Command + (*dst).MainContainer.Command = src.MainContainer.Command } if argsIsSet { - dst.MainContainer.Args = src.MainContainer.Args + (*dst).MainContainer.Args = src.MainContainer.Args } + + return nil } diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index bfacc75cc2..9187ba9c53 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -209,7 +209,6 @@ class ManifestInfo(BaseModel): def to_dict(self) -> t.Dict[str, t.Any]: """Convert to dictionary for YAML serialization.""" result = self.model_dump() - print(f"result={result}") # Convert ServiceInfo objects to dictionaries services_dict = [] for service in result["services"]: From dbb901a788ac7455ba6a3d42af29139c4160d38c Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Sat, 14 Jun 2025 10:47:23 -0700 Subject: [PATCH 31/34] Streamline the ExtraPodEverrides Change type for overriodes in python --- .../cloud/operator/internal/dynamo/graph.go | 38 ++++--------------- .../operator/internal/dynamo/graph_test.go | 4 +- deploy/sdk/src/dynamo/sdk/cli/build.py | 5 ++- .../src/dynamo/sdk/core/protocol/interface.py | 4 +- examples/hello_world/hello_world.py | 4 +- 5 files changed, 17 insertions(+), 38 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index c6b8a0a8c5..b5a3f7d043 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -370,17 +370,20 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD deployment.Spec.Autoscaling.MinReplicas = service.Config.Autoscaling.MinReplicas deployment.Spec.Autoscaling.MaxReplicas = service.Config.Autoscaling.MaxReplicas } - // Override command and args if provided. + // Override properties from the ExtraPodSpec (i.e. command and args) if provided. if service.Config.ExtraPodSpec != nil && service.Config.ExtraPodSpec.MainContainer != nil { if deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec == nil { deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec = new(common.ExtraPodSpec) } - - err := overrideExtraPodSpecMainContainer(service.Config.ExtraPodSpec, &deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec) + err := mergo.Merge( + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec, + service.Config.ExtraPodSpec, + mergo.WithOverride, + mergo.WithOverwriteWithEmptyValue, + ) if err != nil { return nil, err } - } // override the component config with the component config that is in the parent deployment @@ -542,30 +545,3 @@ func mergeEnvs(common, specific []corev1.EnvVar) []corev1.EnvVar { } return merged } - -func overrideExtraPodSpecMainContainer(src *common.ExtraPodSpec, dst **common.ExtraPodSpec) error { - if src == nil || src.MainContainer == nil { - return nil - } - - commandIsSet := len(src.MainContainer.Command) > 0 - argsIsSet := len(src.MainContainer.Args) > 0 - - if !commandIsSet && !argsIsSet { - return nil - } - - if *dst == nil { - *dst = new(common.ExtraPodSpec) - } - - (*dst).MainContainer = &corev1.Container{} - if commandIsSet { - (*dst).MainContainer.Command = src.MainContainer.Command - } - if argsIsSet { - (*dst).MainContainer.Args = src.MainContainer.Args - } - - return nil -} diff --git a/deploy/cloud/operator/internal/dynamo/graph_test.go b/deploy/cloud/operator/internal/dynamo/graph_test.go index d48aa6a16c..6345fa5909 100644 --- a/deploy/cloud/operator/internal/dynamo/graph_test.go +++ b/deploy/cloud/operator/internal/dynamo/graph_test.go @@ -1421,7 +1421,7 @@ func TestGenerateDynamoComponentsDeployments(t *testing.T) { Name: "service1", Dependencies: []map[string]string{}, Config: Config{ - ExtraPodSpec: &common.ExtraPodSpec{ + ExtraPodSpec: &compounaiCommon.ExtraPodSpec{ MainContainer: &corev1.Container{ Command: []string{"sh", "-c"}, Args: []string{"echo hello world", "sleep 99999"}, @@ -1453,7 +1453,7 @@ func TestGenerateDynamoComponentsDeployments(t *testing.T) { Labels: map[string]string{ commonconsts.KubeLabelDynamoComponent: "service1", }, - ExtraPodSpec: &common.ExtraPodSpec{ + ExtraPodSpec: &compounaiCommon.ExtraPodSpec{ MainContainer: &corev1.Container{ Command: []string{"sh", "-c"}, Args: []string{"echo hello world", "sleep 99999"}, diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index 9187ba9c53..f7b9dd2e7b 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -233,7 +233,10 @@ def to_dict(self) -> t.Dict[str, t.Any]: entrypoint = kube_overrides.get("entrypoint") if entrypoint: - main_container["command"] = shlex.split(entrypoint) + if isinstance(entrypoint, str): + main_container["command"] = shlex.split(entrypoint) + else: + main_container["command"] = entrypoint cmd = kube_overrides.get("cmd") if cmd: diff --git a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py index 683b9b83d7..25fcc8345c 100644 --- a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py +++ b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py @@ -77,8 +77,8 @@ class ResourceConfig(BaseModel): class KubernetesOverrides(BaseModel): """Class for kubernetes overrides from the sdk to limit to supported fields.""" - entrypoint: str | None = None - cmd: str | None = None + entrypoint: List[str] | None = None + cmd: List[str] | None = None class ServiceConfig(BaseModel): diff --git a/examples/hello_world/hello_world.py b/examples/hello_world/hello_world.py index 2570180513..5961953060 100644 --- a/examples/hello_world/hello_world.py +++ b/examples/hello_world/hello_world.py @@ -127,8 +127,8 @@ def shutdown(self): image=DYNAMO_IMAGE, # Example of kubernetes overrides if needed. # kubernetes_overrides={ - # "entrypoint": "sh -c", - # "cmd": "echo hello from FrontEnd!", + # "entrypoint": ["sh -c"], + # "cmd": ["echo hello from FrontEnd!"], # }, ) class Frontend: From bbe4d0ab7413325a42ee39db639ed4a03002003c Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Sat, 14 Jun 2025 11:03:55 -0700 Subject: [PATCH 32/34] validations on KubernetesOverrides --- .../sdk/src/dynamo/sdk/core/protocol/interface.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py index 25fcc8345c..fddb530266 100644 --- a/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py +++ b/deploy/sdk/src/dynamo/sdk/core/protocol/interface.py @@ -21,7 +21,7 @@ from typing import Any, Dict, Generic, List, Optional, Set, Tuple, Type, TypeVar from fastapi import FastAPI -from pydantic import BaseModel, ConfigDict, Field +from pydantic import BaseModel, ConfigDict, Field, field_validator from .deployment import Env @@ -77,9 +77,20 @@ class ResourceConfig(BaseModel): class KubernetesOverrides(BaseModel): """Class for kubernetes overrides from the sdk to limit to supported fields.""" + model_config = ConfigDict(extra="forbid") + entrypoint: List[str] | None = None cmd: List[str] | None = None + @field_validator("entrypoint", "cmd", mode="before") + @classmethod + def _coerce_str_to_list(cls, v): + if v is None or isinstance(v, list): + return v + if isinstance(v, str): + return [v] + raise TypeError("Must be str or list[str]") + class ServiceConfig(BaseModel): """Base service configuration that can be extended by adapters""" From 438916b65837670412c395529526a03b44e41e38 Mon Sep 17 00:00:00 2001 From: Anna Tchernych Date: Sat, 14 Jun 2025 12:18:52 -0700 Subject: [PATCH 33/34] Simplify GenerateDynamoComponentsDeployments fix build.py --- .../cloud/operator/internal/dynamo/graph.go | 35 ++++++++++++------- deploy/sdk/src/dynamo/sdk/cli/build.py | 4 +-- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/deploy/cloud/operator/internal/dynamo/graph.go b/deploy/cloud/operator/internal/dynamo/graph.go index b5a3f7d043..0bac9a3bef 100644 --- a/deploy/cloud/operator/internal/dynamo/graph.go +++ b/deploy/cloud/operator/internal/dynamo/graph.go @@ -370,20 +370,10 @@ func GenerateDynamoComponentsDeployments(ctx context.Context, parentDynamoGraphD deployment.Spec.Autoscaling.MinReplicas = service.Config.Autoscaling.MinReplicas deployment.Spec.Autoscaling.MaxReplicas = service.Config.Autoscaling.MaxReplicas } + // Override properties from the ExtraPodSpec (i.e. command and args) if provided. - if service.Config.ExtraPodSpec != nil && service.Config.ExtraPodSpec.MainContainer != nil { - if deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec == nil { - deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec = new(common.ExtraPodSpec) - } - err := mergo.Merge( - deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec, - service.Config.ExtraPodSpec, - mergo.WithOverride, - mergo.WithOverwriteWithEmptyValue, - ) - if err != nil { - return nil, err - } + if err := mergeExtraPodSpec(deployment, &service.Config); err != nil { + return nil, err } // override the component config with the component config that is in the parent deployment @@ -545,3 +535,22 @@ func mergeEnvs(common, specific []corev1.EnvVar) []corev1.EnvVar { } return merged } + +// mergeExtraPodSpec merges the ExtraPodSpec from service config into the deployment spec +func mergeExtraPodSpec(deployment *v1alpha1.DynamoComponentDeployment, serviceConfig *Config) error { + if serviceConfig.ExtraPodSpec != nil && serviceConfig.ExtraPodSpec.MainContainer != nil { + if deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec == nil { + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec = new(common.ExtraPodSpec) + } + err := mergo.Merge( + deployment.Spec.DynamoComponentDeploymentSharedSpec.ExtraPodSpec, + serviceConfig.ExtraPodSpec, + mergo.WithOverride, + mergo.WithOverwriteWithEmptyValue, + ) + if err != nil { + return err + } + } + return nil +} diff --git a/deploy/sdk/src/dynamo/sdk/cli/build.py b/deploy/sdk/src/dynamo/sdk/cli/build.py index f7b9dd2e7b..3590e7ac35 100644 --- a/deploy/sdk/src/dynamo/sdk/cli/build.py +++ b/deploy/sdk/src/dynamo/sdk/cli/build.py @@ -236,14 +236,14 @@ def to_dict(self) -> t.Dict[str, t.Any]: if isinstance(entrypoint, str): main_container["command"] = shlex.split(entrypoint) else: - main_container["command"] = entrypoint + main_container["command"] = shlex.split(entrypoint[0]) cmd = kube_overrides.get("cmd") if cmd: if isinstance(cmd, str): main_container["args"] = shlex.split(cmd) else: - main_container["args"] = cmd + main_container["args"] = shlex.split(cmd[0]) if main_container: service_dict["config"]["extraPodSpec"] = { From 7b0e22cd6080c8be1a91680bcc56ddeec9a17a8a Mon Sep 17 00:00:00 2001 From: atchernych Date: Mon, 16 Jun 2025 10:12:25 -0700 Subject: [PATCH 34/34] Update run.sh revert changes to run.sh Signed-off-by: atchernych --- container/run.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/container/run.sh b/container/run.sh index de99308c14..602b507996 100755 --- a/container/run.sh +++ b/container/run.sh @@ -230,8 +230,6 @@ get_options() { VOLUME_MOUNTS+=" -v ${SOURCE_DIR}/..:/workspace " VOLUME_MOUNTS+=" -v /tmp:/tmp " VOLUME_MOUNTS+=" -v /mnt/:/mnt " - VOLUME_MOUNTS+=" -v /var/run/docker.sock:/var/run/docker.sock " - if [ -z "$HF_CACHE" ]; then HF_CACHE=$DEFAULT_HF_CACHE