diff --git a/apis/apps/v1alpha1/nebulacluster_common.go b/apis/apps/v1alpha1/nebulacluster_common.go index 43da4559..927089e9 100644 --- a/apis/apps/v1alpha1/nebulacluster_common.go +++ b/apis/apps/v1alpha1/nebulacluster_common.go @@ -22,6 +22,7 @@ import ( "os" "strconv" "strings" + "time" kruisev1beta1 "github.com/openkruise/kruise-api/apps/v1beta1" appsv1 "k8s.io/api/apps/v1" @@ -49,6 +50,8 @@ const ( AgentPortNameGRPC = "grpc" DefaultAgentImage = "vesoft/nebula-agent" DefaultAlpineImage = "vesoft/nebula-alpine:latest" + CoredumpMountPath = "/usr/local/nebula/coredump" + CoredumpSubPath = "coredump" ZoneSuffix = "zone" ) @@ -319,6 +322,10 @@ func storageDataVolume(componentType string, index int) string { return dataVolume(componentType) } +func coredumpVolume(componentType string) string { + return componentType + "-coredump" +} + func parseStorageRequest(res corev1.ResourceList) (corev1.ResourceRequirements, error) { if res == nil { return corev1.ResourceRequirements{}, nil @@ -344,6 +351,62 @@ func logVolumeExists(componentType string, volumes []corev1.Volume) bool { return false } +func generateCoredumpVolume(componentType string) corev1.Volume { + return corev1.Volume{ + Name: coredumpVolume(componentType), + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: coredumpVolume(componentType), + }, + }, + } +} + +func generateCoredumpVolumeClaim(nc *NebulaCluster, componentType string) (*corev1.PersistentVolumeClaim, error) { + coredumpSC, coredumpRes := getCoredumpStorageClass(nc), getCoredumpStorageResources(nc) + coredumpReq, err := parseStorageRequest(coredumpRes.Requests) + if err != nil { + return nil, fmt.Errorf("cannot parse storage request for %s coredump volume, error: %v", componentType, err) + } + + return &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: coredumpVolume(componentType), + }, + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, + Resources: coredumpReq, + StorageClassName: coredumpSC, + }, + }, nil +} + +func getCoredumpStorageClass(nc *NebulaCluster) *string { + if nc.Spec.CoredumpPreservation == nil { + return nil + } + scName := nc.Spec.CoredumpPreservation.VolumeSpecs.StorageClassName + if scName == nil || *scName == "" { + return nil + } + return scName +} + +func getCoredumpStorageResources(nc *NebulaCluster) *corev1.ResourceRequirements { + if nc.Spec.CoredumpPreservation == nil { + return nil + } + return nc.Spec.CoredumpPreservation.VolumeSpecs.Resources.DeepCopy() +} + +func generateCoredumpVolumeMount(componentType string) corev1.VolumeMount { + return corev1.VolumeMount{ + Name: coredumpVolume(componentType), + MountPath: CoredumpMountPath, + SubPath: CoredumpSubPath, + } +} + func generateLogContainer(c NebulaClusterComponent) corev1.Container { nc := c.GetNebulaCluster() componentType := c.ComponentType().String() @@ -592,6 +655,53 @@ echo "export NODE_ZONE=${NODE_ZONE}" > /node/zone return container } +func genCoredumpPresInitContainer(nc *NebulaCluster, componentType string) corev1.Container { + script := ` +set -exo pipefail + +ulimit -c unlimited +echo "${MOUNT_PATH}/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern + +` + image := DefaultAlpineImage + if nc.Spec.AlpineImage != nil { + image = pointer.StringDeref(nc.Spec.AlpineImage, "") + } + + container := corev1.Container{ + Name: "coredump-preservation-init", + Image: image, + Command: []string{"/bin/sh", "-c"}, + Args: []string{`echo "$SCRIPT" > /tmp/coredump-setup-script && sh /tmp/coredump-setup-script`}, + Env: []corev1.EnvVar{ + { + Name: "MOUNT_PATH", + Value: CoredumpMountPath, + }, + { + Name: "SCRIPT", + Value: script, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: coredumpVolume(componentType), + MountPath: CoredumpMountPath, + SubPath: CoredumpSubPath, + }, + }, + SecurityContext: &corev1.SecurityContext{ + Privileged: pointer.Bool(true), + }, + } + + imagePullPolicy := nc.Spec.ImagePullPolicy + if imagePullPolicy != nil { + container.ImagePullPolicy = *imagePullPolicy + } + return container +} + func generateInitContainers(c NebulaClusterComponent) []corev1.Container { containers := c.ComponentSpec().InitContainers() nc := c.GetNebulaCluster() @@ -599,10 +709,114 @@ func generateInitContainers(c NebulaClusterComponent) []corev1.Container { nodeLabelsContainer := genNodeLabelsContainer(nc) containers = append(containers, nodeLabelsContainer) } + if nc.Spec.CoredumpPreservation != nil { + coreDumpPresInitContainer := genCoredumpPresInitContainer(nc, c.ComponentType().String()) + containers = append(containers, coreDumpPresInitContainer) + } containers = append(containers, genDynamicFlagsContainer(c)) return containers } +func generateCoredumpManagementContainer(nc *NebulaCluster, componentType, timeToKeep string) corev1.Container { + script := ` +set -eo pipefail + +if [ ! -d "${COREDUMP_DIR}" ]; then + echo "Error: Directory ${COREDUMP_DIR} does not exist." + exit 1 +fi + +# Function to log a message (Kubernetes pod logs capture stdout) +log_message() { + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" +} + +# Initialize the list of existing coredumps +if [ ! -f "${COREDUMP_LIST}" ]; then + find "${COREDUMP_DIR}" -type f -name 'core*' > "${COREDUMP_LIST}" +fi + +# Monitor for new coredumps and delete expired coredumps indefinitely +while true; do + # Detect new coredumps + find "${COREDUMP_DIR}" -type f -name 'core*' > ${CURR_COREDUMP_LIST} + new_coredumps=$(comm -13 "${COREDUMP_LIST}" ${CURR_COREDUMP_LIST}) + + if [ -n "$new_coredumps" ]; then + for coredump in $new_coredumps; do + log_message "New coredump detected: $coredump" + done + # Update the list of known coredumps + mv ${CURR_COREDUMP_LIST} "${COREDUMP_LIST}" + fi + + # Delete expired coredumps + first_loop=1 + while read file; do + if [ $first_loop -eq 1 ]; then + log_message "Cleaning up coredumps older than ${MINS} minutes from directory ${COREDUMP_DIR}" + first_loop=0 + fi + log_message "Cleaning up coredump $file" + rm "$file" + done < <(find "${COREDUMP_DIR}" -type f -name "core*" -mmin +$((MINS-1))) + + if [ $first_loop -eq 0 ]; then + log_message "Coredump cleanup completed." + fi + + # Sleep for a few seconds before checking again + sleep 5 +done +` + image := DefaultAlpineImage + if nc.Spec.AlpineImage != nil { + image = pointer.StringDeref(nc.Spec.AlpineImage, "") + } + + container := corev1.Container{ + Name: "coredump-management", + Image: image, + Command: []string{"/bin/sh", "-c"}, + Args: []string{`echo "$SCRIPT" > /tmp/coredump-management-script && sh /tmp/coredump-management-script`}, + Env: []corev1.EnvVar{ + { + Name: "SCRIPT", + Value: script, + }, + { + Name: "COREDUMP_DIR", + Value: CoredumpMountPath, + }, + { + Name: "COREDUMP_LIST", + Value: "/tmp/coredump_list.txt", + }, + { + Name: "CURR_COREDUMP_LIST", + Value: "/tmp/current_coredump_list.txt", + }, + { + Name: "MINS", + Value: timeToKeep, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: coredumpVolume(componentType), + MountPath: CoredumpMountPath, + SubPath: CoredumpSubPath, + }, + }, + } + + imagePullPolicy := nc.Spec.ImagePullPolicy + if imagePullPolicy != nil { + container.ImagePullPolicy = *imagePullPolicy + } + return container +} + func generateNebulaContainers(c NebulaClusterComponent, cm *corev1.ConfigMap, dynamicFlags map[string]string) ([]corev1.Container, error) { componentType := c.ComponentType().String() nc := c.GetNebulaCluster() @@ -755,6 +969,20 @@ done logContainer := generateLogContainer(c) containers = append(containers, logContainer) } + if nc.Spec.CoredumpPreservation != nil { + maxTimeKept, err := time.ParseDuration(pointer.StringDeref(nc.Spec.CoredumpPreservation.MaxTimeKept, "0")) + if err != nil { + return nil, fmt.Errorf("error parsing maximum time to keep for coredumps for %v: %v", componentType, err) + } + + maxTimeKeptMin := maxTimeKept.Minutes() + if maxTimeKeptMin < 1 { + return nil, fmt.Errorf("invalid maximum time to keep %v for coredumps for %v. Maximum time to keep must be at least 1 minute", maxTimeKept, componentType) + } + + coredumpManagementContainer := generateCoredumpManagementContainer(nc, componentType, fmt.Sprintf("%.0f", maxTimeKeptMin)) + containers = append(containers, coredumpManagementContainer) + } containers = mergeSidecarContainers(containers, c.ComponentSpec().SidecarContainers()) diff --git a/apis/apps/v1alpha1/nebulacluster_graphd.go b/apis/apps/v1alpha1/nebulacluster_graphd.go index 52b9895b..e015a128 100644 --- a/apis/apps/v1alpha1/nebulacluster_graphd.go +++ b/apis/apps/v1alpha1/nebulacluster_graphd.go @@ -202,6 +202,10 @@ func (c *graphdComponent) GenerateVolumeMounts() []corev1.VolumeMount { mounts = append(mounts, certMounts...) } + if c.nc.Spec.CoredumpPreservation != nil { + mounts = append(mounts, generateCoredumpVolumeMount(componentType)) + } + return mounts } @@ -268,33 +272,46 @@ func (c *graphdComponent) GenerateVolumes() []corev1.Volume { volumes = append(volumes, certVolumes...) } + if c.baseComponent.nc.Spec.CoredumpPreservation != nil { + volumes = append(volumes, generateCoredumpVolume(componentType)) + } + return volumes } func (c *graphdComponent) GenerateVolumeClaim() ([]corev1.PersistentVolumeClaim, error) { - if c.nc.Spec.Graphd.LogVolumeClaim == nil { - return nil, nil - } - componentType := c.ComponentType().String() - logSC, logRes := c.GetLogStorageClass(), c.GetLogStorageResources() - storageRequest, err := parseStorageRequest(logRes.Requests) - if err != nil { - return nil, fmt.Errorf("cannot parse storage request for %s, error: %v", componentType, err) - } + claims := make([]corev1.PersistentVolumeClaim, 0) - claims := []corev1.PersistentVolumeClaim{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: logVolume(componentType), - }, - Spec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, - Resources: storageRequest, - StorageClassName: logSC, + if c.nc.Spec.Graphd.LogVolumeClaim != nil { + logSC, logRes := c.GetLogStorageClass(), c.GetLogStorageResources() + storageRequest, err := parseStorageRequest(logRes.Requests) + if err != nil { + return nil, fmt.Errorf("cannot parse storage request for %s, error: %v", componentType, err) + } + + claims = []corev1.PersistentVolumeClaim{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: logVolume(componentType), + }, + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, + Resources: storageRequest, + StorageClassName: logSC, + }, }, - }, + } } + + if c.nc.Spec.CoredumpPreservation != nil { + coredumpVolumeClaim, err := generateCoredumpVolumeClaim(c.nc, componentType) + if err != nil { + return nil, fmt.Errorf("cannot generate graphd coredump volume claim, error: %v", err) + } + claims = append(claims, *coredumpVolumeClaim) + } + return claims, nil } diff --git a/apis/apps/v1alpha1/nebulacluster_metad.go b/apis/apps/v1alpha1/nebulacluster_metad.go index a9798464..74e15893 100644 --- a/apis/apps/v1alpha1/nebulacluster_metad.go +++ b/apis/apps/v1alpha1/nebulacluster_metad.go @@ -234,6 +234,10 @@ func (c *metadComponent) GenerateVolumeMounts() []corev1.VolumeMount { mounts = append(mounts, certMounts...) } + if c.nc.Spec.CoredumpPreservation != nil { + mounts = append(mounts, generateCoredumpVolumeMount(componentType)) + } + return mounts } @@ -326,6 +330,10 @@ func (c *metadComponent) GenerateVolumes() []corev1.Volume { volumes = append(volumes, certVolumes...) } + if c.baseComponent.nc.Spec.CoredumpPreservation != nil { + volumes = append(volumes, generateCoredumpVolume(componentType)) + } + return volumes } @@ -373,6 +381,14 @@ func (c *metadComponent) GenerateVolumeClaim() ([]corev1.PersistentVolumeClaim, }) } + if c.nc.Spec.CoredumpPreservation != nil { + coredumpVolumeClaim, err := generateCoredumpVolumeClaim(c.nc, componentType) + if err != nil { + return nil, fmt.Errorf("cannot generate metad coredump volume claim, error: %v", err) + } + claims = append(claims, *coredumpVolumeClaim) + } + return claims, nil } diff --git a/apis/apps/v1alpha1/nebulacluster_storaged.go b/apis/apps/v1alpha1/nebulacluster_storaged.go index e0e3ecfb..9a010b71 100644 --- a/apis/apps/v1alpha1/nebulacluster_storaged.go +++ b/apis/apps/v1alpha1/nebulacluster_storaged.go @@ -223,6 +223,10 @@ func (c *storagedComponent) GenerateVolumeMounts() []corev1.VolumeMount { mounts = append(mounts, certMounts...) } + if c.nc.Spec.CoredumpPreservation != nil { + mounts = append(mounts, generateCoredumpVolumeMount(componentType)) + } + return mounts } @@ -302,6 +306,10 @@ func (c *storagedComponent) GenerateVolumes() []corev1.Volume { volumes = append(volumes, certVolumes...) } + if c.baseComponent.nc.Spec.CoredumpPreservation != nil { + volumes = append(volumes, generateCoredumpVolume(componentType)) + } + return volumes } @@ -334,6 +342,14 @@ func (c *storagedComponent) GenerateVolumeClaim() ([]corev1.PersistentVolumeClai }) } + if c.nc.Spec.CoredumpPreservation != nil { + coredumpVolumeClaim, err := generateCoredumpVolumeClaim(c.nc, componentType) + if err != nil { + return nil, fmt.Errorf("cannot generate graphd coredump volume claim, error: %v", err) + } + claims = append(claims, *coredumpVolumeClaim) + } + return claims, nil } diff --git a/apis/apps/v1alpha1/nebulacluster_types.go b/apis/apps/v1alpha1/nebulacluster_types.go index 35d2c513..7aa0eea0 100644 --- a/apis/apps/v1alpha1/nebulacluster_types.go +++ b/apis/apps/v1alpha1/nebulacluster_types.go @@ -121,6 +121,19 @@ type NebulaClusterSpec struct { // +optional AlpineImage *string `json:"alpineImage,omitempty"` + + // +optional + CoredumpPreservation *CoredumpPreservSpec `json:"coredumpPreservation,omitempty"` +} + +// CoredumpPreservSpec defines the specs for coredump preservation +type CoredumpPreservSpec struct { + // VolumeSpecs specifies the size and storage class of the coredump volume + VolumeSpecs *StorageClaim `json:"volumeSpecs,omitempty"` + + // MaxTimeKept specifies how long we want to keep the coredumps for. + // It should be a string representing a time.Duration and has to be at least 1 minute. + MaxTimeKept *string `json:"maxTimeKept,omitempty"` } // NebulaClusterStatus defines the observed state of NebulaCluster diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index a505ae8f..ea13356c 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* Copyright 2023 Vesoft Inc. @@ -409,6 +408,31 @@ func (in *ConsoleSpec) DeepCopy() *ConsoleSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CoredumpPreservSpec) DeepCopyInto(out *CoredumpPreservSpec) { + *out = *in + if in.VolumeSpecs != nil { + in, out := &in.VolumeSpecs, &out.VolumeSpecs + *out = new(StorageClaim) + (*in).DeepCopyInto(*out) + } + if in.MaxTimeKept != nil { + in, out := &in.MaxTimeKept, &out.MaxTimeKept + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoredumpPreservSpec. +func (in *CoredumpPreservSpec) DeepCopy() *CoredumpPreservSpec { + if in == nil { + return nil + } + out := new(CoredumpPreservSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CronBackupSpec) DeepCopyInto(out *CronBackupSpec) { *out = *in @@ -929,6 +953,11 @@ func (in *NebulaClusterSpec) DeepCopyInto(out *NebulaClusterSpec) { *out = new(string) **out = **in } + if in.CoredumpPreservation != nil { + in, out := &in.CoredumpPreservation, &out.CoredumpPreservation + *out = new(CoredumpPreservSpec) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebulaClusterSpec. @@ -1219,7 +1248,8 @@ func (in *RestoreStatus) DeepCopyInto(out *RestoreStatus) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]*nebula.HostAddr, len(*in)) for i := range *in { if (*in)[i] != nil { @@ -1240,7 +1270,8 @@ func (in *RestoreStatus) DeepCopyInto(out *RestoreStatus) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make(map[string]string, len(*in)) for key, val := range *in { (*out)[key] = val diff --git a/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go b/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go index 659547cc..63fca62b 100644 --- a/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go +++ b/apis/autoscaling/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* Copyright 2023 Vesoft Inc. diff --git a/charts/nebula-cluster/templates/nebula-cluster.yaml b/charts/nebula-cluster/templates/nebula-cluster.yaml index 0d98c5c7..0fd16137 100644 --- a/charts/nebula-cluster/templates/nebula-cluster.yaml +++ b/charts/nebula-cluster/templates/nebula-cluster.yaml @@ -326,3 +326,15 @@ spec: {{ toYaml . | nindent 4 }} {{- end }} {{- end }} + {{- if .Values.nebula.coredumpPreservation.enable }} + coredumpPreservation: + maxTimeKept: {{ .Values.nebula.coredumpPreservation.maxTimeKept }} + volumeSpecs: + resources: + requests: + storage: {{ .Values.nebula.coredumpPreservation.volumeSize }} + {{- if .Values.nebula.storageClassName }} + storageClassName: {{ .Values.nebula.storageClassName }} + {{- end }} + {{- end }} + diff --git a/charts/nebula-cluster/values.yaml b/charts/nebula-cluster/values.yaml index 1bafd5f8..392edf33 100644 --- a/charts/nebula-cluster/values.yaml +++ b/charts/nebula-cluster/values.yaml @@ -155,6 +155,11 @@ nebula: sslCerts: {} + coredumpPreservation: + maxTimeKept: 72h + enable: true + volumeSize: 5Gi + # Note: for all 3 components, specifying positive integers for both minAvailable and maxUnavailable will result in minAvailable being used. # Please specify any negitive interger for minAvailable (i.e. -1) and a positive integer for maxUnavailable to use maxUnavailable instead. pdb: diff --git a/charts/nebula-operator/crds/nebulaclusters.yaml b/charts/nebula-operator/crds/nebulaclusters.yaml index a48727f5..5a945f15 100644 --- a/charts/nebula-operator/crds/nebulaclusters.yaml +++ b/charts/nebula-operator/crds/nebulaclusters.yaml @@ -4,7 +4,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.11.3 - creationTimestamp: null name: nebulaclusters.apps.nebula-graph.io spec: group: apps.nebula-graph.io @@ -574,6 +573,47 @@ spec: version: type: string type: object + coredumpPreservation: + properties: + maxTimeKept: + type: string + volumeSpecs: + properties: + resources: + properties: + claims: + items: + properties: + name: + 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 + storageClassName: + type: string + type: object + type: object enableAutoFailover: type: boolean enableBR: @@ -1270,6 +1310,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1374,6 +1415,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1557,6 +1599,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1687,6 +1730,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1773,6 +1817,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -2152,6 +2197,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -2256,6 +2302,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -2439,6 +2486,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4000,6 +4048,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4104,6 +4153,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4287,6 +4337,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4417,6 +4468,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4535,6 +4587,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4935,6 +4988,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -5039,6 +5093,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -5222,6 +5277,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -6838,6 +6894,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -6942,6 +6999,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7125,6 +7183,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7264,6 +7323,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7382,6 +7442,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7778,6 +7839,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7882,6 +7944,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -8065,6 +8128,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -9719,6 +9783,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -9823,6 +9888,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10006,6 +10072,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10136,6 +10203,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10254,6 +10322,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10650,6 +10719,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10754,6 +10824,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10937,6 +11008,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port diff --git a/config/crd/bases/apps.nebula-graph.io_nebulaclusters.yaml b/config/crd/bases/apps.nebula-graph.io_nebulaclusters.yaml index a48727f5..5a945f15 100644 --- a/config/crd/bases/apps.nebula-graph.io_nebulaclusters.yaml +++ b/config/crd/bases/apps.nebula-graph.io_nebulaclusters.yaml @@ -4,7 +4,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.11.3 - creationTimestamp: null name: nebulaclusters.apps.nebula-graph.io spec: group: apps.nebula-graph.io @@ -574,6 +573,47 @@ spec: version: type: string type: object + coredumpPreservation: + properties: + maxTimeKept: + type: string + volumeSpecs: + properties: + resources: + properties: + claims: + items: + properties: + name: + 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 + storageClassName: + type: string + type: object + type: object enableAutoFailover: type: boolean enableBR: @@ -1270,6 +1310,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1374,6 +1415,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1557,6 +1599,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1687,6 +1730,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1773,6 +1817,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -2152,6 +2197,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -2256,6 +2302,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -2439,6 +2486,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4000,6 +4048,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4104,6 +4153,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4287,6 +4337,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4417,6 +4468,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4535,6 +4587,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -4935,6 +4988,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -5039,6 +5093,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -5222,6 +5277,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -6838,6 +6894,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -6942,6 +6999,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7125,6 +7183,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7264,6 +7323,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7382,6 +7442,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7778,6 +7839,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -7882,6 +7944,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -8065,6 +8128,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -9719,6 +9783,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -9823,6 +9888,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10006,6 +10072,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10136,6 +10203,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10254,6 +10322,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10650,6 +10719,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10754,6 +10824,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -10937,6 +11008,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port