Unverified Commit 591f4d56 authored by julienmancuso's avatar julienmancuso Committed by GitHub
Browse files

fix: add fields documentation in CRDs (#2447)

parent a3d624a7
...@@ -58,7 +58,8 @@ ensure-yq: ...@@ -58,7 +58,8 @@ ensure-yq:
.PHONY: manifests .PHONY: manifests
manifests: controller-gen ensure-yq ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. manifests: controller-gen ensure-yq ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd:maxDescLen=0 webhook paths="./..." output:crd:artifacts:config=config/crd/bases # Use a large maxDescLen to ensure all field comments are included as OpenAPI descriptions
$(CONTROLLER_GEN) rbac:roleName=manager-role crd:maxDescLen=100000 webhook paths="./..." output:crd:artifacts:config=config/crd/bases
echo "Removing name from mainContainer required fields" echo "Removing name from mainContainer required fields"
for file in config/crd/bases/*.yaml; do \ for file in config/crd/bases/*.yaml; do \
yq eval '(.. | select(has("mainContainer")) | .mainContainer.required) |= (. - ["name"])' -i --indent 2 $$file || exit 1; \ yq eval '(.. | select(has("mainContainer")) | .mainContainer.required) |= (. - ["name"])' -i --indent 2 $$file || exit 1; \
...@@ -96,6 +97,7 @@ manifests: controller-gen ensure-yq ## Generate WebhookConfiguration, ClusterRol ...@@ -96,6 +97,7 @@ manifests: controller-gen ensure-yq ## Generate WebhookConfiguration, ClusterRol
yq eval '.metadata.annotations."helm.sh/resource-policy" = "keep"' -i "$$file"; \ yq eval '.metadata.annotations."helm.sh/resource-policy" = "keep"' -i "$$file"; \
fi; \ fi; \
done done
cp config/crd/bases/*.yaml ../helm/crds/templates/
.PHONY: generate .PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
......
...@@ -23,9 +23,11 @@ import ( ...@@ -23,9 +23,11 @@ import (
) )
type ResourceItem struct { type ResourceItem struct {
CPU string `json:"cpu,omitempty"` CPU string `json:"cpu,omitempty"`
Memory string `json:"memory,omitempty"` Memory string `json:"memory,omitempty"`
GPU string `json:"gpu,omitempty"` // GPU is the number of GPUs to request per node.
GPU string `json:"gpu,omitempty"`
// Nodes is the number of nodes to request. Total number of GPUs will be GPU * Nodes.
Nodes string `json:"nodes,omitempty"` Nodes string `json:"nodes,omitempty"`
Custom map[string]string `json:"custom,omitempty"` Custom map[string]string `json:"custom,omitempty"`
} }
......
...@@ -38,6 +38,8 @@ const ( ...@@ -38,6 +38,8 @@ const (
// DynamoComponentDeploymentSpec defines the desired state of DynamoComponentDeployment // DynamoComponentDeploymentSpec defines the desired state of DynamoComponentDeployment
type DynamoComponentDeploymentSpec struct { type DynamoComponentDeploymentSpec struct {
// DynamoComponent selects the Dynamo component from the archive to deploy.
// Typically corresponds to a component defined in the packaged Dynamo artifacts.
DynamoComponent string `json:"dynamoComponent,omitempty"` DynamoComponent string `json:"dynamoComponent,omitempty"`
// contains the tag of the DynamoComponent: for example, "my_package:MyService" // contains the tag of the DynamoComponent: for example, "my_package:MyService"
DynamoTag string `json:"dynamoTag,omitempty"` DynamoTag string `json:"dynamoTag,omitempty"`
...@@ -46,6 +48,8 @@ type DynamoComponentDeploymentSpec struct { ...@@ -46,6 +48,8 @@ type DynamoComponentDeploymentSpec struct {
// +kubebuilder:validation:Enum=sglang;vllm;trtllm // +kubebuilder:validation:Enum=sglang;vllm;trtllm
BackendFramework string `json:"backendFramework,omitempty"` BackendFramework string `json:"backendFramework,omitempty"`
// DynamoComponentDeploymentSharedSpec embeds common deployment and runtime
// settings that apply to the component (resources, scaling, ingress, etc.).
DynamoComponentDeploymentSharedSpec `json:",inline"` DynamoComponentDeploymentSharedSpec `json:",inline"`
} }
...@@ -57,61 +61,79 @@ type DynamoComponentDeploymentSharedSpec struct { ...@@ -57,61 +61,79 @@ type DynamoComponentDeploymentSharedSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file // Important: Run "make" to regenerate code after modifying this file
// Annotations to add to generated Kubernetes resources for this component
// (such as Pod, Service, and Ingress when applicable).
Annotations map[string]string `json:"annotations,omitempty"` Annotations map[string]string `json:"annotations,omitempty"`
Labels map[string]string `json:"labels,omitempty"` // Labels to add to generated Kubernetes resources for this component.
Labels map[string]string `json:"labels,omitempty"`
// contains the name of the service // contains the name of the component
ServiceName string `json:"serviceName,omitempty"` ServiceName string `json:"serviceName,omitempty"`
// ComponentType indicates the role of this component (for example, "main").
ComponentType string `json:"componentType,omitempty"` ComponentType string `json:"componentType,omitempty"`
// dynamo namespace of the service (allows to override the dynamo namespace of the service defined in annotations inside the dynamo archive) // dynamo namespace of the service (allows to override the dynamo namespace of the service defined in annotations inside the dynamo archive)
DynamoNamespace *string `json:"dynamoNamespace,omitempty"` DynamoNamespace *string `json:"dynamoNamespace,omitempty"`
Resources *dynamoCommon.Resources `json:"resources,omitempty"` // Resources requested and limits for this component, including CPU, memory,
Autoscaling *Autoscaling `json:"autoscaling,omitempty"` // GPUs/devices, and any runtime-specific resources.
Envs []corev1.EnvVar `json:"envs,omitempty"` Resources *dynamoCommon.Resources `json:"resources,omitempty"`
EnvFromSecret *string `json:"envFromSecret,omitempty"` // Autoscaling config for this component (replica range, target utilization, etc.).
PVC *PVC `json:"pvc,omitempty"` Autoscaling *Autoscaling `json:"autoscaling,omitempty"`
RunMode *RunMode `json:"runMode,omitempty"` // Envs defines additional environment variables to inject into the component containers.
ExternalServices map[string]ExternalService `json:"externalServices,omitempty"` Envs []corev1.EnvVar `json:"envs,omitempty"`
// EnvFromSecret references a Secret whose key/value pairs will be exposed as
// environment variables in the component containers.
EnvFromSecret *string `json:"envFromSecret,omitempty"`
// PVC config describing volumes to be mounted by the component.
PVC *PVC `json:"pvc,omitempty"`
// Ingress config to expose the component outside the cluster (or through a service mesh).
Ingress *IngressSpec `json:"ingress,omitempty"` Ingress *IngressSpec `json:"ingress,omitempty"`
// +optional // +optional
// ExtraPodMetadata adds labels/annotations to the created Pods.
ExtraPodMetadata *dynamoCommon.ExtraPodMetadata `json:"extraPodMetadata,omitempty"` ExtraPodMetadata *dynamoCommon.ExtraPodMetadata `json:"extraPodMetadata,omitempty"`
// +optional // +optional
// ExtraPodSpec merges additional fields into the generated PodSpec for advanced
// customization (tolerations, node selectors, affinity, etc.).
ExtraPodSpec *dynamoCommon.ExtraPodSpec `json:"extraPodSpec,omitempty"` ExtraPodSpec *dynamoCommon.ExtraPodSpec `json:"extraPodSpec,omitempty"`
LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty"` // LivenessProbe to detect and restart unhealthy containers.
LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty"`
// ReadinessProbe to signal when the container is ready to receive traffic.
ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty"` ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty"`
Replicas *int32 `json:"replicas,omitempty"` // Replicas is the desired number of Pods for this component when autoscaling is not used.
} Replicas *int32 `json:"replicas,omitempty"`
type RunMode struct {
Standalone *bool `json:"standalone,omitempty"`
}
type ExternalService struct {
DeploymentSelectorKey string `json:"deploymentSelectorKey,omitempty"`
DeploymentSelectorValue string `json:"deploymentSelectorValue,omitempty"`
} }
type IngressTLSSpec struct { type IngressTLSSpec struct {
// SecretName is the name of a Kubernetes Secret containing the TLS certificate and key.
SecretName string `json:"secretName,omitempty"` SecretName string `json:"secretName,omitempty"`
} }
type IngressSpec struct { type IngressSpec struct {
Enabled bool `json:"enabled,omitempty"` // Enabled exposes the component through an ingress or virtual service when true.
Host string `json:"host,omitempty"` Enabled bool `json:"enabled,omitempty"`
UseVirtualService bool `json:"useVirtualService,omitempty"` // Host is the base host name to route external traffic to this component.
VirtualServiceGateway *string `json:"virtualServiceGateway,omitempty"` Host string `json:"host,omitempty"`
HostPrefix *string `json:"hostPrefix,omitempty"` // UseVirtualService indicates whether to configure a service-mesh VirtualService instead of a standard Ingress.
Annotations map[string]string `json:"annotations,omitempty"` UseVirtualService bool `json:"useVirtualService,omitempty"`
Labels map[string]string `json:"labels,omitempty"` // VirtualServiceGateway optionally specifies the gateway name to attach the VirtualService to.
TLS *IngressTLSSpec `json:"tls,omitempty"` VirtualServiceGateway *string `json:"virtualServiceGateway,omitempty"`
HostSuffix *string `json:"hostSuffix,omitempty"` // HostPrefix is an optional prefix added before the host.
IngressControllerClassName *string `json:"ingressControllerClassName,omitempty"` HostPrefix *string `json:"hostPrefix,omitempty"`
// Annotations to set on the generated Ingress/VirtualService resources.
Annotations map[string]string `json:"annotations,omitempty"`
// Labels to set on the generated Ingress/VirtualService resources.
Labels map[string]string `json:"labels,omitempty"`
// TLS holds the TLS configuration used by the Ingress/VirtualService.
TLS *IngressTLSSpec `json:"tls,omitempty"`
// HostSuffix is an optional suffix appended after the host.
HostSuffix *string `json:"hostSuffix,omitempty"`
// IngressControllerClassName selects the ingress controller class (e.g., "nginx").
IngressControllerClassName *string `json:"ingressControllerClassName,omitempty"`
} }
func (i *IngressSpec) IsVirtualServiceEnabled() bool { func (i *IngressSpec) IsVirtualServiceEnabled() bool {
...@@ -125,8 +147,12 @@ func (i *IngressSpec) IsVirtualServiceEnabled() bool { ...@@ -125,8 +147,12 @@ func (i *IngressSpec) IsVirtualServiceEnabled() bool {
type DynamoComponentDeploymentStatus struct { type DynamoComponentDeploymentStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file // Important: Run "make" to regenerate code after modifying this file
// Conditions captures the latest observed state of the component (including
// availability and readiness) using standard Kubernetes condition types.
Conditions []metav1.Condition `json:"conditions"` Conditions []metav1.Condition `json:"conditions"`
// PodSelector contains the labels that can be used to select Pods belonging to
// this component deployment.
PodSelector map[string]string `json:"podSelector,omitempty"` PodSelector map[string]string `json:"podSelector,omitempty"`
} }
...@@ -143,7 +169,9 @@ type DynamoComponentDeployment struct { ...@@ -143,7 +169,9 @@ type DynamoComponentDeployment struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DynamoComponentDeploymentSpec `json:"spec,omitempty"` // Spec defines the desired state for this Dynamo component deployment.
Spec DynamoComponentDeploymentSpec `json:"spec,omitempty"`
// Status reflects the current observed state of the component deployment.
Status DynamoComponentDeploymentStatus `json:"status,omitempty"` Status DynamoComponentDeploymentStatus `json:"status,omitempty"`
} }
......
...@@ -29,25 +29,30 @@ import ( ...@@ -29,25 +29,30 @@ import (
// DynamoGraphDeploymentSpec defines the desired state of DynamoGraphDeployment. // DynamoGraphDeploymentSpec defines the desired state of DynamoGraphDeployment.
type DynamoGraphDeploymentSpec struct { type DynamoGraphDeploymentSpec struct {
// required // DynamoGraph selects the graph (workflow/topology) to deploy. This must match
// a graph name packaged with the Dynamo archive.
DynamoGraph string `json:"dynamoGraph,omitempty"` DynamoGraph string `json:"dynamoGraph,omitempty"`
// optional // Services allows per-service overrides of the component deployment settings.
// key is the name of the service defined in DynamoComponent // - key: name of the service defined by the DynamoComponent
// value is the DynamoComponentDeployment override for that service // - value: overrides for that service
// if not set, the DynamoComponentDeployment will be used as is // If not set for a service, the default DynamoComponentDeployment values are used.
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional
Services map[string]*DynamoComponentDeploymentOverridesSpec `json:"services,omitempty"` Services map[string]*DynamoComponentDeploymentOverridesSpec `json:"services,omitempty"`
// Environment variables to be set in the deployment // Envs are environment variables applied to all services in the graph unless
// overridden by service-specific configuration.
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional
Envs []corev1.EnvVar `json:"envs,omitempty"` Envs []corev1.EnvVar `json:"envs,omitempty"`
// BackendFramework specifies the backend framework (e.g., "sglang", "vllm", "trtllm") // BackendFramework specifies the backend framework (e.g., "sglang", "vllm", "trtllm").
// +kubebuilder:validation:Enum=sglang;vllm;trtllm // +kubebuilder:validation:Enum=sglang;vllm;trtllm
BackendFramework string `json:"backendFramework,omitempty"` BackendFramework string `json:"backendFramework,omitempty"`
} }
// DynamoGraphDeploymentStatus defines the observed state of DynamoGraphDeployment. // DynamoGraphDeploymentStatus defines the observed state of DynamoGraphDeployment.
type DynamoGraphDeploymentStatus struct { type DynamoGraphDeploymentStatus struct {
State string `json:"state,omitempty"` // State is a high-level textual status of the graph deployment lifecycle.
State string `json:"state,omitempty"`
// Conditions contains the latest observed conditions of the graph deployment.
// The slice is merged by type on patch updates.
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
} }
...@@ -59,7 +64,9 @@ type DynamoGraphDeployment struct { ...@@ -59,7 +64,9 @@ type DynamoGraphDeployment struct {
metav1.TypeMeta `json:",inline"` metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DynamoGraphDeploymentSpec `json:"spec,omitempty"` // Spec defines the desired state for this graph deployment.
Spec DynamoGraphDeploymentSpec `json:"spec,omitempty"`
// Status reflects the current observed state of this graph deployment.
Status DynamoGraphDeploymentStatus `json:"status,omitempty"` Status DynamoGraphDeploymentStatus `json:"status,omitempty"`
} }
......
...@@ -238,18 +238,6 @@ func (in *DynamoComponentDeploymentSharedSpec) DeepCopyInto(out *DynamoComponent ...@@ -238,18 +238,6 @@ func (in *DynamoComponentDeploymentSharedSpec) DeepCopyInto(out *DynamoComponent
*out = new(PVC) *out = new(PVC)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.RunMode != nil {
in, out := &in.RunMode, &out.RunMode
*out = new(RunMode)
(*in).DeepCopyInto(*out)
}
if in.ExternalServices != nil {
in, out := &in.ExternalServices, &out.ExternalServices
*out = make(map[string]ExternalService, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Ingress != nil { if in.Ingress != nil {
in, out := &in.Ingress, &out.Ingress in, out := &in.Ingress, &out.Ingress
*out = new(IngressSpec) *out = new(IngressSpec)
...@@ -456,21 +444,6 @@ func (in *DynamoGraphDeploymentStatus) DeepCopy() *DynamoGraphDeploymentStatus { ...@@ -456,21 +444,6 @@ func (in *DynamoGraphDeploymentStatus) DeepCopy() *DynamoGraphDeploymentStatus {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalService) DeepCopyInto(out *ExternalService) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalService.
func (in *ExternalService) DeepCopy() *ExternalService {
if in == nil {
return nil
}
out := new(ExternalService)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { func (in *IngressSpec) DeepCopyInto(out *IngressSpec) {
*out = *in *out = *in
...@@ -570,23 +543,3 @@ func (in *PVC) DeepCopy() *PVC { ...@@ -570,23 +543,3 @@ func (in *PVC) DeepCopy() *PVC {
in.DeepCopyInto(out) in.DeepCopyInto(out)
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RunMode) DeepCopyInto(out *RunMode) {
*out = *in
if in.Standalone != nil {
in, out := &in.Standalone, &out.Standalone
*out = new(bool)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunMode.
func (in *RunMode) DeepCopy() *RunMode {
if in == nil {
return nil
}
out := new(RunMode)
in.DeepCopyInto(out)
return out
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment