From 77b448a3f583cdda1b295bb2ebced070144d2b51 Mon Sep 17 00:00:00 2001 From: tianhr <344527078@qq.com> Date: Wed, 2 Sep 2026 14:37:17 +0800 Subject: [PATCH 1/5] feat/sync-agents --- .../agents.kruise.io_poolautoscalers.yaml | 340 +++++++++++++ .../crds/agents.kruise.io_sandboxclaims.yaml | 16 +- agents/crds/agents.kruise.io_sandboxes.yaml | 325 +++++++++++- agents/crds/agents.kruise.io_sandboxsets.yaml | 312 +++++++++++- .../agents.kruise.io_sandboxtemplates.yaml | 284 +++++++++++ agents/v1alpha1/annotations.go | 17 +- agents/v1alpha1/poolautoscaler_types.go | 246 ++++++++++ agents/v1alpha1/sandbox_types.go | 260 +++++++++- agents/v1alpha1/sandboxclaim_types.go | 19 +- agents/v1alpha1/sandboxset_types.go | 64 ++- agents/v1alpha1/sandboxtemplate_types.go | 15 + agents/v1alpha1/zz_generated.deepcopy.go | 463 ++++++++++++++++++ .../typed/agents/v1alpha1/agents_client.go | 5 + .../v1alpha1/fake/fake_agents_client.go | 4 + .../v1alpha1/fake/fake_poolautoscaler.go | 52 ++ .../agents/v1alpha1/generated_expansion.go | 2 + .../typed/agents/v1alpha1/poolautoscaler.go | 70 +++ .../agents/v1alpha1/interface.go | 7 + .../agents/v1alpha1/poolautoscaler.go | 102 ++++ client/informers/externalversions/generic.go | 2 + .../agents/v1alpha1/expansion_generated.go | 8 + .../listers/agents/v1alpha1/poolautoscaler.go | 70 +++ .../client/v2/models/PoolAutoscaler.java | 9 + .../client/v2/models/PoolAutoscalerSpec.java | 113 +++++ .../v2/models/PoolAutoscalerStatus.java | 140 ++++++ .../client/v2/models/SandboxSetSpec.java | 43 +- .../client/v2/models/SandboxSetStatus.java | 5 +- .../agents/client/v2/models/SandboxSpec.java | 52 +- .../client/v2/models/SandboxStatus.java | 19 +- .../client/v2/models/SandboxTemplateSpec.java | 40 +- .../poolautoscalerspec/CapacityPolicy.java | 84 ++++ .../poolautoscalerspec/CronPolicies.java | 78 +++ .../poolautoscalerspec/ScaleTargetRef.java | 75 +++ .../capacitypolicy/ScaleDown.java | 33 ++ .../capacitypolicy/ScaleUp.java | 33 ++ .../AppliedCronPolicies.java | 43 ++ .../poolautoscalerstatus/Conditions.java | 141 ++++++ .../poolautoscalerstatus/CurrentCapacity.java | 25 + .../inplaceupdate/Resources.java | 20 +- .../sandboxsetspec/AutoPausePolicy.java | 40 ++ .../v2/models/sandboxsetspec/Probes.java | 218 +++++++++ .../models/sandboxsetspec/ScaleStrategy.java | 24 +- .../sandboxsetspec/autopausepolicy/Pause.java | 25 + .../autopausepolicy/Resume.java | 45 ++ .../pause/WhenProbedIdleState.java | 70 +++ .../resume/OnIngressTraffic.java | 35 ++ .../resume/WhenProbedScheduleTime.java | 85 ++++ .../v2/models/sandboxsetspec/probes/Exec.java | 28 ++ .../v2/models/sandboxsetspec/probes/Grpc.java | 44 ++ .../models/sandboxsetspec/probes/HttpGet.java | 93 ++++ .../sandboxsetspec/probes/TcpSocket.java | 43 ++ .../probes/httpget/HttpHeaders.java | 43 ++ .../models/sandboxspec/AutoPausePolicy.java | 40 ++ .../client/v2/models/sandboxspec/Probes.java | 218 +++++++++ .../sandboxspec/autopausepolicy/Pause.java | 25 + .../sandboxspec/autopausepolicy/Resume.java | 45 ++ .../pause/WhenProbedIdleState.java | 70 +++ .../resume/OnIngressTraffic.java | 35 ++ .../resume/WhenProbedScheduleTime.java | 85 ++++ .../v2/models/sandboxspec/probes/Exec.java | 28 ++ .../v2/models/sandboxspec/probes/Grpc.java | 44 ++ .../v2/models/sandboxspec/probes/HttpGet.java | 93 ++++ .../models/sandboxspec/probes/TcpSocket.java | 43 ++ .../probes/httpget/HttpHeaders.java | 43 ++ .../v2/models/sandboxstatus/Schedules.java | 65 +++ .../sandboxtemplatespec/AutoPausePolicy.java | 40 ++ .../v2/models/sandboxtemplatespec/Probes.java | 218 +++++++++ .../autopausepolicy/Pause.java | 25 + .../autopausepolicy/Resume.java | 45 ++ .../pause/WhenProbedIdleState.java | 70 +++ .../resume/OnIngressTraffic.java | 35 ++ .../resume/WhenProbedScheduleTime.java | 85 ++++ .../sandboxtemplatespec/probes/Exec.java | 28 ++ .../sandboxtemplatespec/probes/Grpc.java | 44 ++ .../sandboxtemplatespec/probes/HttpGet.java | 93 ++++ .../sandboxtemplatespec/probes/TcpSocket.java | 43 ++ .../probes/httpget/HttpHeaders.java | 43 ++ .../openkruise/agents/models/checkpoint.py | 2 +- k8s/python/openkruise/agents/models/commit.py | 2 +- .../agents/models/globalsecurityprofile.py | 2 +- .../agents/models/globaltrafficpolicy.py | 2 +- .../agents/models/poolautoscaler.py | 327 +++++++++++++ .../openkruise/agents/models/sandbox.py | 387 ++++++++++++++- .../openkruise/agents/models/sandboxclaim.py | 18 +- .../openkruise/agents/models/sandboxset.py | 372 +++++++++++++- .../agents/models/sandboxtemplate.py | 341 ++++++++++++- .../agents/models/sandboxupdateops.py | 2 +- .../agents/models/securityprofile.py | 2 +- .../openkruise/agents/models/trafficpolicy.py | 2 +- 89 files changed, 7411 insertions(+), 80 deletions(-) create mode 100644 agents/crds/agents.kruise.io_poolautoscalers.yaml create mode 100644 agents/v1alpha1/poolautoscaler_types.go create mode 100644 client/clientset/versioned/typed/agents/v1alpha1/fake/fake_poolautoscaler.go create mode 100644 client/clientset/versioned/typed/agents/v1alpha1/poolautoscaler.go create mode 100644 client/informers/externalversions/agents/v1alpha1/poolautoscaler.go create mode 100644 client/listers/agents/v1alpha1/poolautoscaler.go create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscaler.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerSpec.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerStatus.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CapacityPolicy.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CronPolicies.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/ScaleTargetRef.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleDown.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleUp.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/AppliedCronPolicies.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/Conditions.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/CurrentCapacity.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/AutoPausePolicy.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Pause.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Resume.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/pause/WhenProbedIdleState.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/OnIngressTraffic.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/WhenProbedScheduleTime.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Exec.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Grpc.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/HttpGet.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/TcpSocket.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/httpget/HttpHeaders.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/AutoPausePolicy.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Pause.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Resume.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/pause/WhenProbedIdleState.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/OnIngressTraffic.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/WhenProbedScheduleTime.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Exec.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Grpc.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/HttpGet.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/TcpSocket.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/httpget/HttpHeaders.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/AutoPausePolicy.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Pause.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Resume.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/pause/WhenProbedIdleState.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/OnIngressTraffic.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/WhenProbedScheduleTime.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Exec.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Grpc.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/HttpGet.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/TcpSocket.java create mode 100644 k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/httpget/HttpHeaders.java create mode 100644 k8s/python/openkruise/agents/models/poolautoscaler.py diff --git a/agents/crds/agents.kruise.io_poolautoscalers.yaml b/agents/crds/agents.kruise.io_poolautoscalers.yaml new file mode 100644 index 0000000..27d3f34 --- /dev/null +++ b/agents/crds/agents.kruise.io_poolautoscalers.yaml @@ -0,0 +1,340 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + name: poolautoscalers.agents.kruise.io +spec: + group: agents.kruise.io + names: + kind: PoolAutoscaler + listKind: PoolAutoscalerList + plural: poolautoscalers + shortNames: + - pa + singular: poolautoscaler + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.scaleTargetRef.name + name: Reference + type: string + - jsonPath: .spec.minReplicas + name: MinReplicas + type: integer + - jsonPath: .spec.maxReplicas + name: MaxReplicas + type: integer + - jsonPath: .status.currentReplicas + name: CurrentReplicas + type: integer + - jsonPath: .status.desiredReplicas + name: DesiredReplicas + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + PoolAutoscaler is the configuration for a warming pool autoscaler, + which automatically manages the replica count of the warming pool + based on the policies specified. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired behavior of the autoscaler. + properties: + capacityPolicy: + description: CapacityPolicy defines the capacity configuration of + the target resource pool. + properties: + scaleDown: + description: ScaleDown is the scaling rule for scaling down. + properties: + stabilizationWindowSeconds: + description: |- + StabilizationWindowSeconds is the cooldown period after any scale action before + a scale in this direction is allowed. This is a cooldown model: the first scale + action is immediate, subsequent actions must wait for the window to elapse since + the most recent scale action (in either direction). + Must be >= 60 and <= 3600 (one hour) when set. + Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + least the process-wide Sandbox Pending timeout plus 10 seconds. + Scale-down defaults to 300 seconds when omitted. + format: int32 + maximum: 3600 + minimum: 60 + type: integer + type: object + scaleUp: + description: ScaleUp is the scaling rule for scaling up. + properties: + stabilizationWindowSeconds: + description: |- + StabilizationWindowSeconds is the cooldown period after any scale action before + a scale in this direction is allowed. This is a cooldown model: the first scale + action is immediate, subsequent actions must wait for the window to elapse since + the most recent scale action (in either direction). + Must be >= 60 and <= 3600 (one hour) when set. + Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + least the process-wide Sandbox Pending timeout plus 10 seconds. + Scale-down defaults to 300 seconds when omitted. + format: int32 + maximum: 3600 + minimum: 60 + type: integer + type: object + targetAvailable: + anyOf: + - type: integer + - type: string + description: |- + TargetAvailable is the desired available replicas. + Can be an absolute number (ex: 5) or a percentage of current replicas (ex: 70%). + When the pool is empty, a percentage target is bootstrapped against + maxReplicas so the pool can seed its initial idle capacity. + x-kubernetes-int-or-string: true + tolerance: + anyOf: + - type: integer + - type: string + description: |- + Tolerance is the tolerance between the watermark and desired value under which + no updates are made to the desired number of replicas. + Can be an absolute number (ex: 5) or a percentage (ex: 10%). + If not set, defaults to 10%. + A percentage tolerance is always resolved against the target value: + when targetAvailable is also a percentage, both percentages are combined + first and applied to the pool size; when targetAvailable is an absolute + number, the percentage tolerance is applied to that resolved target + (e.g. targetAvailable=5 with tolerance=10% yields watermarks [4, 6]). + x-kubernetes-int-or-string: true + required: + - targetAvailable + type: object + cronPolicies: + description: |- + CronPolicies is a list of potential cron scaling policies which can be used during scaling. + When both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority. + items: + description: CronScalingPolicy defines the cron-based scaling configuration + for the resource pool. + properties: + name: + description: Name is used to specify the scaling policy. + type: string + schedule: + description: |- + Schedule is a cron expression that defines when this policy should be executed. + Supports standard cron format with 5 fields (minute hour day month weekday). + type: string + targetReplicas: + description: TargetReplicas is the desired replicas when this + policy executes. + format: int32 + minimum: 0 + type: integer + timeZone: + description: |- + TimeZone is the time zone name for the given schedule, e.g. "Asia/Shanghai", "UTC". + If not specified, this will default to the time zone of the autoscaler controller manager process. + type: string + required: + - name + - schedule + - targetReplicas + type: object + type: array + maxReplicas: + description: |- + MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. + It cannot be less than minReplicas. + format: int32 + minimum: 1 + type: integer + minReplicas: + default: 0 + description: |- + MinReplicas is the lower limit for the number of replicas to which the autoscaler + can scale down. It defaults to 0 pods. + format: int32 + minimum: 0 + type: integer + scaleTargetRef: + description: |- + ScaleTargetRef points to the target warming pool to scale, and is used to select the pods for which instance status + should be collected, as well as to actually change the replica count. + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + enum: + - SandboxSet + type: string + name: + description: 'Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + required: + - kind + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent executions. + Defaults to false. + type: boolean + required: + - maxReplicas + - scaleTargetRef + type: object + x-kubernetes-validations: + - message: minReplicas must not be greater than maxReplicas + rule: self.minReplicas <= self.maxReplicas + status: + description: Status is the current information about the autoscaler. + properties: + appliedCronPolicies: + description: AppliedCronPolicies is the execution status of cron policies. + items: + description: CronScalingPolicyStatus records the last schedule time + for a cron policy. + properties: + lastScheduleTime: + description: LastScheduleTime is the last time the policy was + successfully scheduled. + format: date-time + type: string + name: + description: Name is the cron policy name. + type: string + required: + - name + type: object + type: array + conditions: + description: Conditions is the set of conditions required for this + autoscaler to scale its target. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentCapacity: + description: CurrentCapacity is the last read state of the capacity + used by this autoscaler. + properties: + available: + description: Available is current number of available pods managed + by this autoscaler. + format: int32 + type: integer + required: + - available + type: object + currentReplicas: + description: CurrentReplicas is current number of replicas of pods + managed by this autoscaler. + format: int32 + type: integer + desiredReplicas: + description: DesiredReplicas is the desired number of replicas of + pods managed by this autoscaler. + format: int32 + type: integer + lastScaleTime: + description: LastScaleTime is the last time the PoolAutoscaler scaled + the number of pods. + format: date-time + type: string + observedGeneration: + description: ObservedGeneration is the most recent generation observed + by this autoscaler. + format: int64 + type: integer + suspended: + description: Suspended indicates whether the autoscaler is currently + suspended. + type: boolean + required: + - currentReplicas + - desiredReplicas + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/agents/crds/agents.kruise.io_sandboxclaims.yaml b/agents/crds/agents.kruise.io_sandboxclaims.yaml index 5c32430..199889d 100644 --- a/agents/crds/agents.kruise.io_sandboxclaims.yaml +++ b/agents/crds/agents.kruise.io_sandboxclaims.yaml @@ -135,8 +135,12 @@ spec: x-kubernetes-int-or-string: true description: |- Limits specifies the target resource limits for each container. - Only CPU is supported for now. The container's original limit must already be set; - otherwise the value is ignored. + Only CPU and memory are supported; other resource names are rejected. + The container's original limit must already be set; otherwise the value is ignored. + A limit must not be lower than the target request of the same resource. + Memory may only be increased: a target lower than the container's current memory is rejected. + Memory resize may restart the container when the pod template declares + resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. The new value must not change the Pod's QoS class; otherwise the claim will be rejected. type: object requests: @@ -148,8 +152,12 @@ spec: x-kubernetes-int-or-string: true description: |- Requests specifies the target resource requests for each container. - Only CPU is supported for now. The container's original request must already be set; - otherwise the value is ignored. + Only CPU and memory are supported; other resource names are rejected. + The container's original request must already be set; otherwise the value is ignored. + A request must not exceed the target limit of the same resource. + Memory may only be increased: a target lower than the container's current memory is rejected. + Memory resize may restart the container when the pod template declares + resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. The new value must not change the Pod's QoS class; otherwise the claim will be rejected. type: object type: object diff --git a/agents/crds/agents.kruise.io_sandboxes.yaml b/agents/crds/agents.kruise.io_sandboxes.yaml index ab372fe..f09f399 100644 --- a/agents/crds/agents.kruise.io_sandboxes.yaml +++ b/agents/crds/agents.kruise.io_sandboxes.yaml @@ -63,8 +63,118 @@ spec: spec: description: spec defines the desired state of Sandbox properties: + autoPausePolicy: + description: |- + AutoPausePolicy defines when the sandbox controller pauses or resumes + the sandbox. Probe-driven rules reference probes declared in + Spec.Probes and read their results (mirrored from + Pod.Status.Conditions to SandboxStatus.Conditions); the + OnIngressTraffic resume rule is event-driven and does not require a + probe. + properties: + pause: + description: Pause defines the pause policy for the sandbox. + properties: + whenProbedIdleState: + description: |- + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + properties: + messageRegex: + description: |- + MessageRegex is a regular expression matched against the probe's + Condition message (stdout). When the message matches, the Agent is + considered inactive. When it does not match, the Agent is considered + active and the sandbox stays Running. + type: string + probe: + description: |- + Probe is the name of the probe to evaluate for pause decisions. + Must match a probe name in Spec.Probes. + type: string + thresholdDuration: + description: |- + ThresholdDuration is the minimum time the probe's Condition message + must continuously match MessageRegex before the sandbox is paused. + Measured from the Condition's lastTransitionTime. + + It is required: pausing as soon as a single probe report matches would + drop the smoothing this rule exists for, so there is no meaningful + default and an unset value is a misconfiguration rather than + "pause immediately". + type: string + required: + - messageRegex + - probe + - thresholdDuration + type: object + type: object + resume: + description: Resume defines the resume policy for the sandbox. + properties: + onIngressTraffic: + description: |- + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + properties: + pauseTimeout: + description: |- + PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + gateway writes Spec.PauseTime = now + PauseTimeout atomically with + Spec.Paused = false, so the woken sandbox has running time before its + next auto-pause. It applies only to auto-pause sandboxes (those that + already carry Spec.PauseTime); never-timeout and shutdown-only + sandboxes keep their timeout mode unchanged. + When absent or non-positive, a traffic wake does not re-arm auto-pause: + the woken sandbox keeps running until it is paused or deleted again. + A positive value is subject to the resume timeout floor + (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + the floor are raised to it so the fresh PauseTime cannot expire while + the sandbox is still resuming. + type: string + type: object + whenProbedScheduleTime: + description: |- + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + properties: + leadTime: + default: 5m + description: |- + LeadTime is the duration before the parsed timestamp at which the + sandbox should be resumed. For example, if the probe reports the + next scheduled task at time T and LeadTime is 5m, the sandbox is + resumed at T - 5m. + type: string + probe: + description: |- + Probe is the name of the probe to evaluate for resume decisions. + Must match a probe name in Spec.Probes. + type: string + timeFormat: + default: unix + description: |- + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + enum: + - unix + - datetime + type: string + required: + - probe + type: object + type: object + type: object lifecycle: - description: Lifecycle defines lifecycle hooks for sandbox upgrade. + description: Lifecycle defines lifecycle hooks for sandbox. properties: postUpgrade: description: |- @@ -163,6 +273,187 @@ spec: type: string type: array x-kubernetes-list-type: atomic + probes: + description: |- + Probes defines a list of named probes that run periodically while the sandbox + is Running. Each probe writes its result to a Pod Status Condition with + type "agents.kruise.io/". Probes are generic — their semantics (e.g., + "activity detection" vs "cron task detection") are defined by + AutoPausePolicy.Pause/Resume, not by the probe itself. + + Probe execution is delegated to the agent-runtime sidecar via the + PodProbeMarker Serverless protocol (kruise.io/podprobe annotation). + The controller reads results from Pod.Status.Conditions and mirrors + them to SandboxStatus.Conditions for observability. + items: + description: |- + Probe defines a named probe that writes its result to a Pod Condition. + Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. + are directly accessible. Currently only exec probes are supported; + other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported + in the future as needed. + properties: + containerName: + description: |- + ContainerName specifies which container to execute the probe in. + If empty, defaults to the first container in the pod spec. + type: string + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this probe within the sandbox. + Probe results are written to a Condition with type "agents.kruise.io/". + type: string + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + required: + - name + type: object + type: array runtimes: description: Runtimes - Runtime configuration for sandbox object items: @@ -337,6 +628,38 @@ spec: sandboxIp: description: SandboxIp is the ip address allocated to the sandbox. type: string + schedules: + description: |- + Schedules contains upcoming scheduled pause/resume events. + Only populated when Spec.AutoPausePolicy.Pause/Resume is configured. + items: + description: |- + Schedule tracks the upcoming pause/resume timing for the auto-pause controller. + Reason indicates which rule produced the current schedule, NextPauseTime is the + next expected pause time, and NextResumeTime is the next expected resume time. + Both times are cleared once the corresponding action is triggered. + properties: + nextPauseTime: + description: |- + NextPauseTime is when the sandbox is expected to be paused, computed from + the pause policy once the probed idle threshold is about to be reached. + It is cleared after a pause is triggered. + format: date-time + type: string + nextResumeTime: + description: |- + NextResumeTime is when the sandbox is expected to be resumed, computed from + the resume policy's probed schedule time. It is cleared after a resume is triggered. + format: date-time + type: string + reason: + description: |- + Reason indicates which auto-pause rule triggered this schedule entry. + Examples: "probedIdle" (pause triggered by WhenProbedIdleState), + "probedSchedule" (resume triggered by WhenProbedScheduleTime). + type: string + type: object + type: array updateRevision: description: UpdateRevision is the template-hash calculated from `spec.template`. type: string diff --git a/agents/crds/agents.kruise.io_sandboxsets.yaml b/agents/crds/agents.kruise.io_sandboxsets.yaml index 66ea116..2c2fe59 100644 --- a/agents/crds/agents.kruise.io_sandboxsets.yaml +++ b/agents/crds/agents.kruise.io_sandboxsets.yaml @@ -61,6 +61,117 @@ spec: spec: description: spec defines the desired state of SandboxSet properties: + autoPausePolicy: + description: |- + AutoPausePolicy defines the pause/resume decision rules for sandboxes + created from this SandboxSet. Probe-driven rules reference probes by + name (so they are normally set together with spec.probes); the + OnIngressTraffic resume rule is event-driven and does not require a + probe. The policy is copied verbatim onto each created Sandbox and is + part of the update revision hash, so changing it triggers a rolling + update of already-created pool sandboxes. + properties: + pause: + description: Pause defines the pause policy for the sandbox. + properties: + whenProbedIdleState: + description: |- + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + properties: + messageRegex: + description: |- + MessageRegex is a regular expression matched against the probe's + Condition message (stdout). When the message matches, the Agent is + considered inactive. When it does not match, the Agent is considered + active and the sandbox stays Running. + type: string + probe: + description: |- + Probe is the name of the probe to evaluate for pause decisions. + Must match a probe name in Spec.Probes. + type: string + thresholdDuration: + description: |- + ThresholdDuration is the minimum time the probe's Condition message + must continuously match MessageRegex before the sandbox is paused. + Measured from the Condition's lastTransitionTime. + + It is required: pausing as soon as a single probe report matches would + drop the smoothing this rule exists for, so there is no meaningful + default and an unset value is a misconfiguration rather than + "pause immediately". + type: string + required: + - messageRegex + - probe + - thresholdDuration + type: object + type: object + resume: + description: Resume defines the resume policy for the sandbox. + properties: + onIngressTraffic: + description: |- + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + properties: + pauseTimeout: + description: |- + PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + gateway writes Spec.PauseTime = now + PauseTimeout atomically with + Spec.Paused = false, so the woken sandbox has running time before its + next auto-pause. It applies only to auto-pause sandboxes (those that + already carry Spec.PauseTime); never-timeout and shutdown-only + sandboxes keep their timeout mode unchanged. + When absent or non-positive, a traffic wake does not re-arm auto-pause: + the woken sandbox keeps running until it is paused or deleted again. + A positive value is subject to the resume timeout floor + (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + the floor are raised to it so the fresh PauseTime cannot expire while + the sandbox is still resuming. + type: string + type: object + whenProbedScheduleTime: + description: |- + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + properties: + leadTime: + default: 5m + description: |- + LeadTime is the duration before the parsed timestamp at which the + sandbox should be resumed. For example, if the probe reports the + next scheduled task at time T and LeadTime is 5m, the sandbox is + resumed at T - 5m. + type: string + probe: + description: |- + Probe is the name of the probe to evaluate for resume decisions. + Must match a probe name in Spec.Probes. + type: string + timeFormat: + default: unix + description: |- + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + enum: + - unix + - datetime + type: string + required: + - probe + type: object + type: object + type: object pauseStrategy: description: |- PauseStrategy configures how sandboxes created from this SandboxSet are @@ -92,6 +203,182 @@ spec: type: string type: array x-kubernetes-list-type: atomic + probes: + description: |- + Probes defines the named probes that sandboxes created from this SandboxSet + run while they are Running. It is copied verbatim onto each created Sandbox + and is part of the update revision hash, so changing it triggers a rolling + update of already-created pool sandboxes. + items: + description: |- + Probe defines a named probe that writes its result to a Pod Condition. + Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. + are directly accessible. Currently only exec probes are supported; + other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported + in the future as needed. + properties: + containerName: + description: |- + ContainerName specifies which container to execute the probe in. + If empty, defaults to the first container in the pod spec. + type: string + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this probe within the sandbox. + Probe results are written to a Condition with type "agents.kruise.io/". + type: string + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic replicas: description: Replicas is the number of unused sandboxes, including available and creating ones. @@ -118,10 +405,24 @@ spec: - type: integer - type: string description: |- - The maximum number of sandboxes that can be unavailable for scaled sandboxes. - This field can control the changes rate of replicas for SandboxSet so as to minimize the impact for users' service. - The scale will fail if the number of unavailable sandboxes were greater than this MaxUnavailable at scaling up. - MaxUnavailable works only when scaling up. + MaxUnavailable caps concurrent physical scale-up operations and serves as + the startup budget for the ScalingLimited condition. It can be an absolute + number (ex: 5) or a percentage of desired pods (ex: 10%); percentages are + rounded up against spec.replicas. If unset or invalid, the controller uses + the base (equivalent to 100%, i.e. no cap). Scale-down is unaffected. + + The physical scale-up budget is charged by startup blockers: sandboxes + whose Ready condition is False with reason PodCreateFailed or + StartContainerFailed, sandboxes stuck in Creating/ResourcePending past the + configured --max-pending-timeout, and sandbox creations that have been + issued but are not yet observed by the controller (they release their slot + once observed as healthy Creating sandboxes). Healthy observed Creating + sandboxes do NOT count against the budget. + + The ScalingLimited condition becomes True with reason + StartupBudgetExhausted when failed plus pending-timeout sandboxes exhaust + the resolved startup budget. + MaxUnavailable works only for scale-up. x-kubernetes-int-or-string: true type: object template: @@ -268,7 +569,8 @@ spec: updateRevision: description: |- UpdateRevision is the FNV-32 hash computed from spec.template, - spec.persistentContents, spec.runtimes, and spec.pauseStrategy. + spec.persistentContents, spec.runtimes, spec.pauseStrategy, + spec.probes, and spec.autoPausePolicy. It represents the latest desired template version. type: string updatedAvailableReplicas: diff --git a/agents/crds/agents.kruise.io_sandboxtemplates.yaml b/agents/crds/agents.kruise.io_sandboxtemplates.yaml index 2b81e3f..69017a1 100644 --- a/agents/crds/agents.kruise.io_sandboxtemplates.yaml +++ b/agents/crds/agents.kruise.io_sandboxtemplates.yaml @@ -42,6 +42,114 @@ spec: spec: description: spec defines the desired state of SandboxSet properties: + autoPausePolicy: + description: |- + AutoPausePolicy defines the pause/resume decision rules for sandboxes + created from this template. It is only informational when a SandboxSet uses + spec.templateRef: SandboxSetSpec.AutoPausePolicy always takes precedence and + is what actually reaches created Sandboxes. + properties: + pause: + description: Pause defines the pause policy for the sandbox. + properties: + whenProbedIdleState: + description: |- + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + properties: + messageRegex: + description: |- + MessageRegex is a regular expression matched against the probe's + Condition message (stdout). When the message matches, the Agent is + considered inactive. When it does not match, the Agent is considered + active and the sandbox stays Running. + type: string + probe: + description: |- + Probe is the name of the probe to evaluate for pause decisions. + Must match a probe name in Spec.Probes. + type: string + thresholdDuration: + description: |- + ThresholdDuration is the minimum time the probe's Condition message + must continuously match MessageRegex before the sandbox is paused. + Measured from the Condition's lastTransitionTime. + + It is required: pausing as soon as a single probe report matches would + drop the smoothing this rule exists for, so there is no meaningful + default and an unset value is a misconfiguration rather than + "pause immediately". + type: string + required: + - messageRegex + - probe + - thresholdDuration + type: object + type: object + resume: + description: Resume defines the resume policy for the sandbox. + properties: + onIngressTraffic: + description: |- + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + properties: + pauseTimeout: + description: |- + PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + gateway writes Spec.PauseTime = now + PauseTimeout atomically with + Spec.Paused = false, so the woken sandbox has running time before its + next auto-pause. It applies only to auto-pause sandboxes (those that + already carry Spec.PauseTime); never-timeout and shutdown-only + sandboxes keep their timeout mode unchanged. + When absent or non-positive, a traffic wake does not re-arm auto-pause: + the woken sandbox keeps running until it is paused or deleted again. + A positive value is subject to the resume timeout floor + (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + the floor are raised to it so the fresh PauseTime cannot expire while + the sandbox is still resuming. + type: string + type: object + whenProbedScheduleTime: + description: |- + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + properties: + leadTime: + default: 5m + description: |- + LeadTime is the duration before the parsed timestamp at which the + sandbox should be resumed. For example, if the probe reports the + next scheduled task at time T and LeadTime is 5m, the sandbox is + resumed at T - 5m. + type: string + probe: + description: |- + Probe is the name of the probe to evaluate for resume decisions. + Must match a probe name in Spec.Probes. + type: string + timeFormat: + default: unix + description: |- + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + enum: + - unix + - datetime + type: string + required: + - probe + type: object + type: object + type: object pauseStrategy: description: |- PauseStrategy configures how sandboxes created from this template are @@ -73,6 +181,182 @@ spec: type: string type: array x-kubernetes-list-type: atomic + probes: + description: |- + Probes defines the named probes that sandboxes created from this template + run while they are Running. It is only informational when a SandboxSet uses + spec.templateRef: SandboxSetSpec.Probes always takes precedence and is what + actually reaches created Sandboxes. + items: + description: |- + Probe defines a named probe that writes its result to a Pod Condition. + Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. + are directly accessible. Currently only exec probes are supported; + other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported + in the future as needed. + properties: + containerName: + description: |- + ContainerName specifies which container to execute the probe in. + If empty, defaults to the first container in the pod spec. + type: string + exec: + description: Exec specifies a command to execute in the container. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies a GRPC HealthCheckRequest. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + default: "" + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies an HTTP GET request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this probe within the sandbox. + Probe results are written to a Condition with type "agents.kruise.io/". + type: string + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies a connection to a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic runtimes: description: Runtimes - Runtime configuration for sandbox object items: diff --git a/agents/v1alpha1/annotations.go b/agents/v1alpha1/annotations.go index f284b30..b6bb174 100644 --- a/agents/v1alpha1/annotations.go +++ b/agents/v1alpha1/annotations.go @@ -79,16 +79,6 @@ const ( // SandboxHashImmutablePart represents the key of sandbox hash than exclude immutable part of sandbox // e.g. metadata, image and resources SandboxHashImmutablePart = "sandbox.agents.kruise.io/hash-immutable-part" - - // AnnotationWakeOnTraffic enables wake-on-traffic for a paused sandbox. - // When set to "true", the sandbox-gateway will attempt to resume the sandbox - // by patching Spec.Paused=false when traffic arrives. - AnnotationWakeOnTraffic = InternalPrefix + "wake-on-traffic" - - // AnnotationWakeTimeoutSeconds stores the auto-pause timeout (in seconds) to - // apply when the sandbox is woken by traffic. The gateway reads this to set - // ResumeOptions.Timeout.PauseTime, re-arming auto-pause after wake. - AnnotationWakeTimeoutSeconds = InternalPrefix + "wake-timeout-seconds" ) // E2B annotations @@ -114,3 +104,10 @@ const ( // patches the template and removes this annotation to trigger the actual // pod replacement. const AnnotationUpgradeResumeTrigger = InternalPrefix + "upgrade-resume-trigger" + +// AnnotationPodProbe is the annotation key used by the PodProbeMarker Serverless +// protocol. The sandbox controller writes probe definitions to this annotation +// on the Pod, and the agent-runtime sidecar reads them, executes the probes, +// and writes results to Pod.Status.Conditions. +// See: https://openkruise.io/docs/user-manuals/podprobemarker#support-for-serverless-scenarios +const AnnotationPodProbe = "kruise.io/podprobe" diff --git a/agents/v1alpha1/poolautoscaler_types.go b/agents/v1alpha1/poolautoscaler_types.go new file mode 100644 index 0000000..db34bda --- /dev/null +++ b/agents/v1alpha1/poolautoscaler_types.go @@ -0,0 +1,246 @@ +/* +Copyright 2026. + +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. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// CrossVersionObjectReference contains enough information to let you identify the referred resource. +type CrossVersionObjectReference struct { + // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +required + // +kubebuilder:validation:Enum=SandboxSet + Kind string `json:"kind"` + // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + // +required + Name string `json:"name"` + // API version of the referent + // +optional + APIVersion string `json:"apiVersion,omitempty"` +} + +// PoolAutoscalerSpec describes the desired functionality of the PoolAutoscaler. +// +kubebuilder:validation:XValidation:rule="self.minReplicas <= self.maxReplicas",message="minReplicas must not be greater than maxReplicas" +type PoolAutoscalerSpec struct { + // ScaleTargetRef points to the target warming pool to scale, and is used to select the pods for which instance status + // should be collected, as well as to actually change the replica count. + // +required + ScaleTargetRef CrossVersionObjectReference `json:"scaleTargetRef"` + + // MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. + // It cannot be less than minReplicas. + // +required + // +kubebuilder:validation:Minimum=1 + MaxReplicas int32 `json:"maxReplicas"` + + // MinReplicas is the lower limit for the number of replicas to which the autoscaler + // can scale down. It defaults to 0 pods. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=0 + MinReplicas int32 `json:"minReplicas"` + + // CronPolicies is a list of potential cron scaling policies which can be used during scaling. + // When both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority. + // +optional + CronPolicies []CronScalingPolicy `json:"cronPolicies,omitempty"` + + // CapacityPolicy defines the capacity configuration of the target resource pool. + // +optional + CapacityPolicy *CapacityPolicy `json:"capacityPolicy,omitempty"` + + // Suspend tells the controller to suspend subsequent executions. + // Defaults to false. + // +optional + Suspend *bool `json:"suspend,omitempty"` +} + +// CronScalingPolicy defines the cron-based scaling configuration for the resource pool. +type CronScalingPolicy struct { + // Name is used to specify the scaling policy. + // +required + Name string `json:"name"` + + // TimeZone is the time zone name for the given schedule, e.g. "Asia/Shanghai", "UTC". + // If not specified, this will default to the time zone of the autoscaler controller manager process. + // +optional + TimeZone *string `json:"timeZone,omitempty"` + + // Schedule is a cron expression that defines when this policy should be executed. + // Supports standard cron format with 5 fields (minute hour day month weekday). + // +required + Schedule string `json:"schedule"` + + // TargetReplicas is the desired replicas when this policy executes. + // +required + // +kubebuilder:validation:Minimum=0 + TargetReplicas int32 `json:"targetReplicas"` +} + +// CapacityPolicy defines the capacity configuration of the target resource pool. +type CapacityPolicy struct { + // TargetAvailable is the desired available replicas. + // Can be an absolute number (ex: 5) or a percentage of current replicas (ex: 70%). + // When the pool is empty, a percentage target is bootstrapped against + // maxReplicas so the pool can seed its initial idle capacity. + // +required + TargetAvailable intstr.IntOrString `json:"targetAvailable"` + + // Tolerance is the tolerance between the watermark and desired value under which + // no updates are made to the desired number of replicas. + // Can be an absolute number (ex: 5) or a percentage (ex: 10%). + // If not set, defaults to 10%. + // A percentage tolerance is always resolved against the target value: + // when targetAvailable is also a percentage, both percentages are combined + // first and applied to the pool size; when targetAvailable is an absolute + // number, the percentage tolerance is applied to that resolved target + // (e.g. targetAvailable=5 with tolerance=10% yields watermarks [4, 6]). + // +optional + Tolerance *intstr.IntOrString `json:"tolerance,omitempty"` + + // ScaleUp is the scaling rule for scaling up. + // +optional + ScaleUp *CapacityScalingRules `json:"scaleUp,omitempty"` + + // ScaleDown is the scaling rule for scaling down. + // +optional + ScaleDown *CapacityScalingRules `json:"scaleDown,omitempty"` +} + +// CapacityScalingRules configures the scaling behavior for one direction. +type CapacityScalingRules struct { + // StabilizationWindowSeconds is the cooldown period after any scale action before + // a scale in this direction is allowed. This is a cooldown model: the first scale + // action is immediate, subsequent actions must wait for the window to elapse since + // the most recent scale action (in either direction). + // Must be >= 60 and <= 3600 (one hour) when set. + // Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + // least the process-wide Sandbox Pending timeout plus 10 seconds. + // Scale-down defaults to 300 seconds when omitted. + // +optional + // +kubebuilder:validation:Minimum=60 + // +kubebuilder:validation:Maximum=3600 + StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty"` +} + +// PoolAutoscalerStatus describes the current status of a pool autoscaler. +type PoolAutoscalerStatus struct { + // ObservedGeneration is the most recent generation observed by this autoscaler. + // +optional + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + + // LastScaleTime is the last time the PoolAutoscaler scaled the number of pods. + // +optional + LastScaleTime *metav1.Time `json:"lastScaleTime,omitempty"` + + // CurrentReplicas is current number of replicas of pods managed by this autoscaler. + CurrentReplicas int32 `json:"currentReplicas"` + + // DesiredReplicas is the desired number of replicas of pods managed by this autoscaler. + DesiredReplicas int32 `json:"desiredReplicas"` + + // Suspended indicates whether the autoscaler is currently suspended. + // +optional + Suspended bool `json:"suspended,omitempty"` + + // AppliedCronPolicies is the execution status of cron policies. + // +optional + AppliedCronPolicies []CronScalingPolicyStatus `json:"appliedCronPolicies,omitempty"` + + // CurrentCapacity is the last read state of the capacity used by this autoscaler. + // +optional + CurrentCapacity CapacityStatus `json:"currentCapacity,omitempty"` + + // Conditions is the set of conditions required for this autoscaler to scale its target. + // +optional + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// CronScalingPolicyStatus records the last schedule time for a cron policy. +type CronScalingPolicyStatus struct { + // Name is the cron policy name. + Name string `json:"name"` + + // LastScheduleTime is the last time the policy was successfully scheduled. + // +optional + LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"` +} + +// CapacityStatus records the current capacity observed by the autoscaler. +type CapacityStatus struct { + // Available is current number of available pods managed by this autoscaler. + Available int32 `json:"available"` +} + +// PoolAutoscalerConditionType are the valid conditions of a PoolAutoscaler. +type PoolAutoscalerConditionType string + +const ( + // ScalingActive indicates that the autoscaler is able to scale. + ScalingActive PoolAutoscalerConditionType = "ScalingActive" + // AbleToScale indicates that the autoscaler is able to calculate and set scale. + AbleToScale PoolAutoscalerConditionType = "AbleToScale" + // ScalingLimited indicates that the autoscaler is constrained by min/max bounds. + ScalingLimited PoolAutoscalerConditionType = "ScalingLimited" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:path=poolautoscalers,shortName={pa},singular=poolautoscaler +// +kubebuilder:storageversion +// +kubebuilder:printcolumn:name="Reference",type="string",JSONPath=".spec.scaleTargetRef.name" +// +kubebuilder:printcolumn:name="MinReplicas",type="integer",JSONPath=".spec.minReplicas" +// +kubebuilder:printcolumn:name="MaxReplicas",type="integer",JSONPath=".spec.maxReplicas" +// +kubebuilder:printcolumn:name="CurrentReplicas",type="integer",JSONPath=".status.currentReplicas" +// +kubebuilder:printcolumn:name="DesiredReplicas",type="integer",JSONPath=".status.desiredReplicas" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// PoolAutoscaler is the configuration for a warming pool autoscaler, +// which automatically manages the replica count of the warming pool +// based on the policies specified. +type PoolAutoscaler struct { + metav1.TypeMeta `json:",inline"` + + // +optional + metav1.ObjectMeta `json:"metadata,omitempty,omitzero"` + + // Spec defines the desired behavior of the autoscaler. + // +optional + Spec PoolAutoscalerSpec `json:"spec,omitempty"` + + // Status is the current information about the autoscaler. + // +optional + Status PoolAutoscalerStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// PoolAutoscalerList contains a list of PoolAutoscaler. +type PoolAutoscalerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PoolAutoscaler `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PoolAutoscaler{}, &PoolAutoscalerList{}) +} diff --git a/agents/v1alpha1/sandbox_types.go b/agents/v1alpha1/sandbox_types.go index 73a9414..f18f1b6 100644 --- a/agents/v1alpha1/sandbox_types.go +++ b/agents/v1alpha1/sandbox_types.go @@ -74,10 +74,32 @@ type SandboxSpec struct { // +kubebuilder:validation:Format="date-time" PauseTime *metav1.Time `json:"pauseTime,omitempty"` - // Lifecycle defines lifecycle hooks for sandbox upgrade. + // Lifecycle defines lifecycle hooks for sandbox. // +optional Lifecycle *SandboxLifecycle `json:"lifecycle,omitempty"` + // Probes defines a list of named probes that run periodically while the sandbox + // is Running. Each probe writes its result to a Pod Status Condition with + // type "agents.kruise.io/". Probes are generic — their semantics (e.g., + // "activity detection" vs "cron task detection") are defined by + // AutoPausePolicy.Pause/Resume, not by the probe itself. + // + // Probe execution is delegated to the agent-runtime sidecar via the + // PodProbeMarker Serverless protocol (kruise.io/podprobe annotation). + // The controller reads results from Pod.Status.Conditions and mirrors + // them to SandboxStatus.Conditions for observability. + // +optional + Probes []Probe `json:"probes,omitempty"` + + // AutoPausePolicy defines when the sandbox controller pauses or resumes + // the sandbox. Probe-driven rules reference probes declared in + // Spec.Probes and read their results (mirrored from + // Pod.Status.Conditions to SandboxStatus.Conditions); the + // OnIngressTraffic resume rule is event-driven and does not require a + // probe. + // +optional + AutoPausePolicy *AutoPausePolicy `json:"autoPausePolicy,omitempty"` + // UpgradePolicy defines the upgrade strategy for the sandbox. // +optional UpgradePolicy *SandboxUpgradePolicy `json:"upgradePolicy,omitempty"` @@ -188,7 +210,7 @@ type HibernateStrategy struct { Type HibernateStrategyType `json:"type,omitempty"` } -// SandboxLifecycle defines lifecycle hooks for sandbox upgrade. +// SandboxLifecycle defines lifecycle hooks for sandbox. type SandboxLifecycle struct { // PreUpgrade is the action executed before the upgrade. // It is typically used to backup workspace data. @@ -201,6 +223,179 @@ type SandboxLifecycle struct { PostUpgrade *UpgradeAction `json:"postUpgrade,omitempty"` } +// Probe defines a named probe that writes its result to a Pod Condition. +// Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. +// are directly accessible. Currently only exec probes are supported; +// other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported +// in the future as needed. +type Probe struct { + // Name is the unique identifier for this probe within the sandbox. + // Probe results are written to a Condition with type "agents.kruise.io/". + // +kubebuilder:validation:Required + Name string `json:"name"` + + // ContainerName specifies which container to execute the probe in. + // If empty, defaults to the first container in the pod spec. + // +optional + ContainerName string `json:"containerName,omitempty"` + + // Probe embeds corev1.Probe inline. Currently only exec, periodSeconds, + // timeoutSeconds, and failureThreshold are actively used. + // + // The real corev1.Probe schema is generated into the CRD so the apiserver + // rejects unknown fields and out-of-range values at write time. Handlers + // other than exec pass the schema but are rejected by the controller, which + // reports the error on the ProbeValid condition. + // +optional + v1.Probe `json:",inline"` +} + +// AutoPausePolicy defines when the sandbox controller pauses or resumes the +// sandbox. Probe-driven rules (WhenProbedIdleState, WhenProbedScheduleTime) +// reference probes declared in Spec.Probes and read their results (mirrored +// from Pod.Status.Conditions to SandboxStatus.Conditions); the +// OnIngressTraffic resume rule is event-driven and does not require a probe. +// When set, the sandbox controller evaluates the rules. +// +optional +type AutoPausePolicy struct { + // Pause defines the pause policy for the sandbox. + // +optional + Pause *PausePolicy `json:"pause,omitempty"` + + // Resume defines the resume policy for the sandbox. + // +optional + Resume *ResumePolicy `json:"resume,omitempty"` +} + +// PausePolicy defines when to pause the sandbox based on probe results. +type PausePolicy struct { + // WhenProbedIdleState pauses the sandbox when a probe's Condition message + // matches MessageRegex for at least ThresholdDuration. + // +optional + WhenProbedIdleState *ProbedIdleStateRule `json:"whenProbedIdleState,omitempty"` +} + +// ResumePolicy defines when to resume the sandbox. +type ResumePolicy struct { + // WhenProbedScheduleTime resumes the sandbox before a scheduled task + // by parsing the probe's Condition message as a timestamp. + // +optional + WhenProbedScheduleTime *ProbedScheduleTimeRule `json:"whenProbedScheduleTime,omitempty"` + + // OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + // inbound traffic addressed to it while it is paused. Unlike the probed + // rules this one is event-driven: it needs no probe, it produces no + // Status.Schedules entry, and it is executed by the sandbox-gateway rather + // than by the sandbox controller. + // +optional + OnIngressTraffic *IngressTrafficRule `json:"onIngressTraffic,omitempty"` +} + +// ProbedIdleStateRule defines the rule for pausing when a probe reports +// an idle state. The controller reads the referenced probe's Condition and +// matches its message against MessageRegex. When the match persists for at +// least ThresholdDuration (measured from the Condition's lastTransitionTime), +// the sandbox is paused. +type ProbedIdleStateRule struct { + // Probe is the name of the probe to evaluate for pause decisions. + // Must match a probe name in Spec.Probes. + // +kubebuilder:validation:Required + Probe string `json:"probe"` + + // MessageRegex is a regular expression matched against the probe's + // Condition message (stdout). When the message matches, the Agent is + // considered inactive. When it does not match, the Agent is considered + // active and the sandbox stays Running. + // +kubebuilder:validation:Required + MessageRegex string `json:"messageRegex"` + + // ThresholdDuration is the minimum time the probe's Condition message + // must continuously match MessageRegex before the sandbox is paused. + // Measured from the Condition's lastTransitionTime. + // + // It is required: pausing as soon as a single probe report matches would + // drop the smoothing this rule exists for, so there is no meaningful + // default and an unset value is a misconfiguration rather than + // "pause immediately". + // +kubebuilder:validation:Required + ThresholdDuration *metav1.Duration `json:"thresholdDuration"` +} + +// ProbedScheduleTimeRule defines the rule for resuming based on a probed +// schedule time. The controller reads the referenced probe's Condition and +// parses its message as the next event time according to TimeFormat. The +// sandbox is resumed LeadTime before the parsed timestamp. +type ProbedScheduleTimeRule struct { + // Probe is the name of the probe to evaluate for resume decisions. + // Must match a probe name in Spec.Probes. + // +kubebuilder:validation:Required + Probe string `json:"probe"` + + // TimeFormat indicates the format of the probe's Condition message for + // parsing as a timestamp, and defaults to "unix": + // + // unix - seconds since epoch, e.g. "1787040000" + // datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + // + // NextResumeTime is set to the parsed timestamp minus LeadTime. + // +optional + // +kubebuilder:default=unix + // +kubebuilder:validation:Enum=unix;datetime + TimeFormat string `json:"timeFormat,omitempty"` + + // LeadTime is the duration before the parsed timestamp at which the + // sandbox should be resumed. For example, if the probe reports the + // next scheduled task at time T and LeadTime is 5m, the sandbox is + // resumed at T - 5m. + // +optional + // +kubebuilder:default="5m" + LeadTime *metav1.Duration `json:"leadTime,omitempty"` +} + +// IngressTrafficRule defines the rule for resuming a paused sandbox when +// ingress traffic reaches the sandbox-gateway. A non-nil rule enables +// wake-on-traffic; there is no separate enable flag, matching the sibling +// rules where nil means "not configured". +type IngressTrafficRule struct { + // PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + // gateway writes Spec.PauseTime = now + PauseTimeout atomically with + // Spec.Paused = false, so the woken sandbox has running time before its + // next auto-pause. It applies only to auto-pause sandboxes (those that + // already carry Spec.PauseTime); never-timeout and shutdown-only + // sandboxes keep their timeout mode unchanged. + // When absent or non-positive, a traffic wake does not re-arm auto-pause: + // the woken sandbox keeps running until it is paused or deleted again. + // A positive value is subject to the resume timeout floor + // (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + // the floor are raised to it so the fresh PauseTime cannot expire while + // the sandbox is still resuming. + // +optional + PauseTimeout *metav1.Duration `json:"pauseTimeout,omitempty"` +} + +// Schedule tracks the upcoming pause/resume timing for the auto-pause controller. +// Reason indicates which rule produced the current schedule, NextPauseTime is the +// next expected pause time, and NextResumeTime is the next expected resume time. +// Both times are cleared once the corresponding action is triggered. +type Schedule struct { + // Reason indicates which auto-pause rule triggered this schedule entry. + // Examples: "probedIdle" (pause triggered by WhenProbedIdleState), + // "probedSchedule" (resume triggered by WhenProbedScheduleTime). + // +optional + Reason string `json:"reason,omitempty"` + + // NextPauseTime is when the sandbox is expected to be paused, computed from + // the pause policy once the probed idle threshold is about to be reached. + // It is cleared after a pause is triggered. + // +optional + NextPauseTime *metav1.Time `json:"nextPauseTime,omitempty"` + + // NextResumeTime is when the sandbox is expected to be resumed, computed from + // the resume policy's probed schedule time. It is cleared after a resume is triggered. + // +optional + NextResumeTime *metav1.Time `json:"nextResumeTime,omitempty"` +} + // UpgradeAction defines an action to execute during sandbox upgrade. // It supports multiple action types for extensibility. type UpgradeAction struct { @@ -268,6 +463,13 @@ type SandboxStatus struct { // RecycledCount records the number of times this sandbox has been recycled. // +optional RecycledCount int32 `json:"recycledCount,omitempty"` + + // Schedules contains upcoming scheduled pause/resume events. + // Only populated when Spec.AutoPausePolicy.Pause/Resume is configured. + // +optional + // +patchMergeKey=reason + // +patchStrategy=merge + Schedules []Schedule `json:"schedules,omitempty"` } // SandboxPhase is a label for the condition of a pod at the current time. @@ -345,8 +547,51 @@ const ( // SandboxConditionRecycling tracks recycling progress. SandboxConditionRecycling SandboxConditionType = "Recycling" + + // SandboxConditionProbeValid indicates whether the probe configurations in + // Spec.Probes are valid. Invalid probes are skipped (not injected into the Pod) + // and the condition is set to False with the validation error details. + SandboxConditionProbeValid SandboxConditionType = "ProbeValid" +) + +const ( + // ProbeTimeFormatUnix parses a probe message as seconds since epoch. + ProbeTimeFormatUnix = "unix" + // ProbeTimeFormatDatetime parses a probe message as an RFC3339 timestamp. + ProbeTimeFormatDatetime = "datetime" ) +const ( + // ProbeConditionPrefix is the prefix for probe Conditions written to + // SandboxStatus.Conditions. The full type is "agents.kruise.io/". + ProbeConditionPrefix = "agents.kruise.io/" + + // Probe reason constants (written to Pod/Sandbox Conditions by the probe executor). + ProbeReasonSucceeded = "Succeeded" + ProbeReasonTimeout = "Timeout" + ProbeReasonError = "Error" + ProbeReasonUnhealthy = "Unhealthy" + ProbeReasonPending = "Pending" + + // Auto-pause decision reason constants (used for logging and events). + PauseReasonScheduledResume = "ScheduledResume" + PauseReasonProbePaused = "ProbePaused" + PauseReasonAgentActive = "AgentActive" + PauseReasonInactivePending = "InactivePending" + PauseReasonProbeFailed = "ProbeFailed" + PauseReasonProbeUnhealthy = "ProbeUnhealthy" + + // Schedule reason constants (written to SandboxStatus.Schedules). + ScheduleReasonProbedIdle = "probedIdle" + ScheduleReasonProbedSchedule = "probedSchedule" +) + +// ProbeConditionType returns the Condition type that carries the named probe's +// result, on both the Pod and the Sandbox. +func ProbeConditionType(probeName string) string { + return ProbeConditionPrefix + probeName +} + const ( // SandboxConditionReady Reason SandboxReadyReasonPodReady = "PodReady" @@ -376,8 +621,11 @@ const ( SandboxUpgradingReasonSucceeded = "Succeeded" // SandboxConditionPaused Reason - SandboxPausedReasonPending = "Pending" - SandboxPausedReasonImageChanged = "ImageChanged" + SandboxPausedReasonPending = "Pending" + SandboxPausedReasonImageChanged = "ImageChanged" + // SandboxPausedReasonWaitingForExistingCheckpoint indicates that pause is blocked by a Checkpoint created outside the pause flow. + SandboxPausedReasonWaitingForExistingCheckpoint = "WaitingForExistingCheckpoint" + // SandboxPausedReasonCheckpointCreating indicates that the pause flow is creating its own Checkpoint. SandboxPausedReasonCheckpointCreating = "CheckpointCreating" SandboxPausedReasonCheckpointSucceeded = "CheckpointSucceeded" SandboxPausedReasonCheckpointFailed = "CheckpointFailed" @@ -400,6 +648,10 @@ const ( SandboxRecyclingReasonFailed = "RecyclingFailed" SandboxRecyclingReasonTimeout = "RecyclingTimeout" SandboxRecyclingReasonRejected = "RecyclingRejected" + + // SandboxConditionProbeValid Reason + SandboxProbeValidReasonValidationPassed = "ValidationPassed" + SandboxProbeValidReasonValidationFailed = "ValidationFailed" ) // +genclient diff --git a/agents/v1alpha1/sandboxclaim_types.go b/agents/v1alpha1/sandboxclaim_types.go index 136ff3b..324346d 100644 --- a/agents/v1alpha1/sandboxclaim_types.go +++ b/agents/v1alpha1/sandboxclaim_types.go @@ -126,19 +126,26 @@ type SandboxClaimInplaceUpdateOptions struct { Resources *SandboxClaimInplaceUpdateResourcesOptions `json:"resources,omitempty"` } -// SandboxClaimInplaceUpdateResourcesOptions -// TODO: now we only support cpu inplace resize, consider support mem resize in the future. +// SandboxClaimInplaceUpdateResourcesOptions specifies resources for in-place resize. type SandboxClaimInplaceUpdateResourcesOptions struct { // Requests specifies the target resource requests for each container. - // Only CPU is supported for now. The container's original request must already be set; - // otherwise the value is ignored. + // Only CPU and memory are supported; other resource names are rejected. + // The container's original request must already be set; otherwise the value is ignored. + // A request must not exceed the target limit of the same resource. + // Memory may only be increased: a target lower than the container's current memory is rejected. + // Memory resize may restart the container when the pod template declares + // resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. // The new value must not change the Pod's QoS class; otherwise the claim will be rejected. // +optional Requests corev1.ResourceList `json:"requests,omitempty"` // Limits specifies the target resource limits for each container. - // Only CPU is supported for now. The container's original limit must already be set; - // otherwise the value is ignored. + // Only CPU and memory are supported; other resource names are rejected. + // The container's original limit must already be set; otherwise the value is ignored. + // A limit must not be lower than the target request of the same resource. + // Memory may only be increased: a target lower than the container's current memory is rejected. + // Memory resize may restart the container when the pod template declares + // resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. // The new value must not change the Pod's QoS class; otherwise the claim will be rejected. // +optional Limits corev1.ResourceList `json:"limits,omitempty"` diff --git a/agents/v1alpha1/sandboxset_types.go b/agents/v1alpha1/sandboxset_types.go index 0aa8874..c32dd01 100644 --- a/agents/v1alpha1/sandboxset_types.go +++ b/agents/v1alpha1/sandboxset_types.go @@ -24,12 +24,12 @@ import ( // AnnotationsClearedOnRecycle lists all annotation keys that are removed from a // sandbox when it is successfully recycled and returned to the pool. When adding // a new annotation that should be cleared during recycle, append it here to avoid -// missing the recycle in resetMetadataForPool. +// missing the recycle in resetSandboxForPool. // // Note: AnnotationUpdatedMetadataInClaim is handled separately because it is // consumed before deletion to determine user-specified metadata keys. // Annotations from other packages (e.g. identity.AgentKeyTokenRefreshStatus) -// are handled individually in resetMetadataForPool. +// are handled individually in resetSandboxForPool. var AnnotationsClearedOnRecycle = []string{ AnnotationClaimTime, AnnotationLock, @@ -47,8 +47,6 @@ var AnnotationsClearedOnRecycle = []string{ // (header injections, blocks); leaking it across a claim would apply one // tenant's rules — potentially carrying credentials — to another. AnnotationSecurityRules, - AnnotationWakeOnTraffic, - AnnotationWakeTimeoutSeconds, } // InternalKeysPreservedOnCreation lists internal keys (with the InternalPrefix) @@ -76,6 +74,13 @@ const ( SandboxStateDead = "dead" ) +// Reason values reported alongside SandboxState* by utils.GetSandboxState. +// Exported so downstream controllers can match on them without repeating the +// hard-coded string literal. +const ( + SandboxStateReasonResourcePending = "ResourcePending" +) + var SandboxSetControllerKind = GroupVersion.WithKind("SandboxSet") // SandboxSetSpec defines the desired state of SandboxSet @@ -99,6 +104,24 @@ type SandboxSetSpec struct { // +listType=atomic Runtimes []RuntimeConfig `json:"runtimes,omitempty"` + // Probes defines the named probes that sandboxes created from this SandboxSet + // run while they are Running. It is copied verbatim onto each created Sandbox + // and is part of the update revision hash, so changing it triggers a rolling + // update of already-created pool sandboxes. + // +optional + // +listType=atomic + Probes []Probe `json:"probes,omitempty"` + + // AutoPausePolicy defines the pause/resume decision rules for sandboxes + // created from this SandboxSet. Probe-driven rules reference probes by + // name (so they are normally set together with spec.probes); the + // OnIngressTraffic resume rule is event-driven and does not require a + // probe. The policy is copied verbatim onto each created Sandbox and is + // part of the update revision hash, so changing it triggers a rolling + // update of already-created pool sandboxes. + // +optional + AutoPausePolicy *AutoPausePolicy `json:"autoPausePolicy,omitempty"` + EmbeddedSandboxTemplate `json:",inline"` // ScaleStrategy indicates the ScaleStrategy that will be employed to @@ -113,10 +136,24 @@ type SandboxSetSpec struct { // SandboxSetScaleStrategy defines strategies for sandboxes scale. type SandboxSetScaleStrategy struct { - // The maximum number of sandboxes that can be unavailable for scaled sandboxes. - // This field can control the changes rate of replicas for SandboxSet so as to minimize the impact for users' service. - // The scale will fail if the number of unavailable sandboxes were greater than this MaxUnavailable at scaling up. - // MaxUnavailable works only when scaling up. + // MaxUnavailable caps concurrent physical scale-up operations and serves as + // the startup budget for the ScalingLimited condition. It can be an absolute + // number (ex: 5) or a percentage of desired pods (ex: 10%); percentages are + // rounded up against spec.replicas. If unset or invalid, the controller uses + // the base (equivalent to 100%, i.e. no cap). Scale-down is unaffected. + // + // The physical scale-up budget is charged by startup blockers: sandboxes + // whose Ready condition is False with reason PodCreateFailed or + // StartContainerFailed, sandboxes stuck in Creating/ResourcePending past the + // configured --max-pending-timeout, and sandbox creations that have been + // issued but are not yet observed by the controller (they release their slot + // once observed as healthy Creating sandboxes). Healthy observed Creating + // sandboxes do NOT count against the budget. + // + // The ScalingLimited condition becomes True with reason + // StartupBudgetExhausted when failed plus pending-timeout sandboxes exhaust + // the resolved startup budget. + // MaxUnavailable works only for scale-up. MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` } @@ -138,6 +175,14 @@ type SandboxSetUpdateStrategy struct { MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` } +// SandboxSetConditionType is a valid value for SandboxSet conditions. +type SandboxSetConditionType string + +const ( + // SandboxSetConditionScalingLimited indicates whether startup blockers exhaust the scale-up budget. + SandboxSetConditionScalingLimited SandboxSetConditionType = "ScalingLimited" +) + // SandboxSetStatus defines the observed state of SandboxSet. type SandboxSetStatus struct { // observedGeneration is the most recent generation observed for this SandboxSet. It corresponds to the @@ -151,7 +196,8 @@ type SandboxSetStatus struct { AvailableReplicas int32 `json:"availableReplicas"` // UpdateRevision is the FNV-32 hash computed from spec.template, - // spec.persistentContents, spec.runtimes, and spec.pauseStrategy. + // spec.persistentContents, spec.runtimes, spec.pauseStrategy, + // spec.probes, and spec.autoPausePolicy. // It represents the latest desired template version. UpdateRevision string `json:"updateRevision,omitempty"` diff --git a/agents/v1alpha1/sandboxtemplate_types.go b/agents/v1alpha1/sandboxtemplate_types.go index 4909741..e543d8d 100644 --- a/agents/v1alpha1/sandboxtemplate_types.go +++ b/agents/v1alpha1/sandboxtemplate_types.go @@ -51,6 +51,21 @@ type SandboxTemplateSpec struct { // takes precedence and is what actually reaches created Sandboxes. // +optional PauseStrategy *PauseStrategy `json:"pauseStrategy,omitempty"` + + // Probes defines the named probes that sandboxes created from this template + // run while they are Running. It is only informational when a SandboxSet uses + // spec.templateRef: SandboxSetSpec.Probes always takes precedence and is what + // actually reaches created Sandboxes. + // +optional + // +listType=atomic + Probes []Probe `json:"probes,omitempty"` + + // AutoPausePolicy defines the pause/resume decision rules for sandboxes + // created from this template. It is only informational when a SandboxSet uses + // spec.templateRef: SandboxSetSpec.AutoPausePolicy always takes precedence and + // is what actually reaches created Sandboxes. + // +optional + AutoPausePolicy *AutoPausePolicy `json:"autoPausePolicy,omitempty"` } // +genclient diff --git a/agents/v1alpha1/zz_generated.deepcopy.go b/agents/v1alpha1/zz_generated.deepcopy.go index a53287e..4c44bef 100644 --- a/agents/v1alpha1/zz_generated.deepcopy.go +++ b/agents/v1alpha1/zz_generated.deepcopy.go @@ -182,6 +182,31 @@ func (in *AuditWebhook) DeepCopy() *AuditWebhook { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AutoPausePolicy) DeepCopyInto(out *AutoPausePolicy) { + *out = *in + if in.Pause != nil { + in, out := &in.Pause, &out.Pause + *out = new(PausePolicy) + (*in).DeepCopyInto(*out) + } + if in.Resume != nil { + in, out := &in.Resume, &out.Resume + *out = new(ResumePolicy) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoPausePolicy. +func (in *AutoPausePolicy) DeepCopy() *AutoPausePolicy { + if in == nil { + return nil + } + out := new(AutoPausePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BlockAction) DeepCopyInto(out *BlockAction) { *out = *in @@ -224,6 +249,72 @@ func (in *CSIMountConfig) DeepCopy() *CSIMountConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CapacityPolicy) DeepCopyInto(out *CapacityPolicy) { + *out = *in + out.TargetAvailable = in.TargetAvailable + if in.Tolerance != nil { + in, out := &in.Tolerance, &out.Tolerance + *out = new(intstr.IntOrString) + **out = **in + } + if in.ScaleUp != nil { + in, out := &in.ScaleUp, &out.ScaleUp + *out = new(CapacityScalingRules) + (*in).DeepCopyInto(*out) + } + if in.ScaleDown != nil { + in, out := &in.ScaleDown, &out.ScaleDown + *out = new(CapacityScalingRules) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapacityPolicy. +func (in *CapacityPolicy) DeepCopy() *CapacityPolicy { + if in == nil { + return nil + } + out := new(CapacityPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CapacityScalingRules) DeepCopyInto(out *CapacityScalingRules) { + *out = *in + if in.StabilizationWindowSeconds != nil { + in, out := &in.StabilizationWindowSeconds, &out.StabilizationWindowSeconds + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapacityScalingRules. +func (in *CapacityScalingRules) DeepCopy() *CapacityScalingRules { + if in == nil { + return nil + } + out := new(CapacityScalingRules) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CapacityStatus) DeepCopyInto(out *CapacityStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapacityStatus. +func (in *CapacityStatus) DeepCopy() *CapacityStatus { + if in == nil { + return nil + } + out := new(CapacityStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Checkpoint) DeepCopyInto(out *Checkpoint) { *out = *in @@ -519,6 +610,60 @@ func (in *CredentialRef) DeepCopy() *CredentialRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronScalingPolicy) DeepCopyInto(out *CronScalingPolicy) { + *out = *in + if in.TimeZone != nil { + in, out := &in.TimeZone, &out.TimeZone + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronScalingPolicy. +func (in *CronScalingPolicy) DeepCopy() *CronScalingPolicy { + if in == nil { + return nil + } + out := new(CronScalingPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CronScalingPolicyStatus) DeepCopyInto(out *CronScalingPolicyStatus) { + *out = *in + if in.LastScheduleTime != nil { + in, out := &in.LastScheduleTime, &out.LastScheduleTime + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronScalingPolicyStatus. +func (in *CronScalingPolicyStatus) DeepCopy() *CronScalingPolicyStatus { + if in == nil { + return nil + } + out := new(CronScalingPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossVersionObjectReference. +func (in *CrossVersionObjectReference) DeepCopy() *CrossVersionObjectReference { + if in == nil { + return nil + } + out := new(CrossVersionObjectReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EmbeddedSandboxTemplate) DeepCopyInto(out *EmbeddedSandboxTemplate) { *out = *in @@ -739,6 +884,26 @@ func (in *HibernateStrategy) DeepCopy() *HibernateStrategy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressTrafficRule) DeepCopyInto(out *IngressTrafficRule) { + *out = *in + if in.PauseTimeout != nil { + in, out := &in.PauseTimeout, &out.PauseTimeout + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressTrafficRule. +func (in *IngressTrafficRule) DeepCopy() *IngressTrafficRule { + if in == nil { + return nil + } + out := new(IngressTrafficRule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MCPDenyResponse) DeepCopyInto(out *MCPDenyResponse) { *out = *in @@ -816,6 +981,26 @@ func (in *PathMatch) DeepCopy() *PathMatch { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PausePolicy) DeepCopyInto(out *PausePolicy) { + *out = *in + if in.WhenProbedIdleState != nil { + in, out := &in.WhenProbedIdleState, &out.WhenProbedIdleState + *out = new(ProbedIdleStateRule) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PausePolicy. +func (in *PausePolicy) DeepCopy() *PausePolicy { + if in == nil { + return nil + } + out := new(PausePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PauseStrategy) DeepCopyInto(out *PauseStrategy) { *out = *in @@ -865,6 +1050,193 @@ func (in *PodInfo) DeepCopy() *PodInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolAutoscaler) DeepCopyInto(out *PoolAutoscaler) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolAutoscaler. +func (in *PoolAutoscaler) DeepCopy() *PoolAutoscaler { + if in == nil { + return nil + } + out := new(PoolAutoscaler) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PoolAutoscaler) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolAutoscalerList) DeepCopyInto(out *PoolAutoscalerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PoolAutoscaler, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolAutoscalerList. +func (in *PoolAutoscalerList) DeepCopy() *PoolAutoscalerList { + if in == nil { + return nil + } + out := new(PoolAutoscalerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PoolAutoscalerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolAutoscalerSpec) DeepCopyInto(out *PoolAutoscalerSpec) { + *out = *in + out.ScaleTargetRef = in.ScaleTargetRef + if in.CronPolicies != nil { + in, out := &in.CronPolicies, &out.CronPolicies + *out = make([]CronScalingPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CapacityPolicy != nil { + in, out := &in.CapacityPolicy, &out.CapacityPolicy + *out = new(CapacityPolicy) + (*in).DeepCopyInto(*out) + } + if in.Suspend != nil { + in, out := &in.Suspend, &out.Suspend + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolAutoscalerSpec. +func (in *PoolAutoscalerSpec) DeepCopy() *PoolAutoscalerSpec { + if in == nil { + return nil + } + out := new(PoolAutoscalerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolAutoscalerStatus) DeepCopyInto(out *PoolAutoscalerStatus) { + *out = *in + if in.ObservedGeneration != nil { + in, out := &in.ObservedGeneration, &out.ObservedGeneration + *out = new(int64) + **out = **in + } + if in.LastScaleTime != nil { + in, out := &in.LastScaleTime, &out.LastScaleTime + *out = (*in).DeepCopy() + } + if in.AppliedCronPolicies != nil { + in, out := &in.AppliedCronPolicies, &out.AppliedCronPolicies + *out = make([]CronScalingPolicyStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.CurrentCapacity = in.CurrentCapacity + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolAutoscalerStatus. +func (in *PoolAutoscalerStatus) DeepCopy() *PoolAutoscalerStatus { + if in == nil { + return nil + } + out := new(PoolAutoscalerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Probe) DeepCopyInto(out *Probe) { + *out = *in + in.Probe.DeepCopyInto(&out.Probe) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probe. +func (in *Probe) DeepCopy() *Probe { + if in == nil { + return nil + } + out := new(Probe) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProbedIdleStateRule) DeepCopyInto(out *ProbedIdleStateRule) { + *out = *in + if in.ThresholdDuration != nil { + in, out := &in.ThresholdDuration, &out.ThresholdDuration + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbedIdleStateRule. +func (in *ProbedIdleStateRule) DeepCopy() *ProbedIdleStateRule { + if in == nil { + return nil + } + out := new(ProbedIdleStateRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProbedScheduleTimeRule) DeepCopyInto(out *ProbedScheduleTimeRule) { + *out = *in + if in.LeadTime != nil { + in, out := &in.LeadTime, &out.LeadTime + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbedScheduleTimeRule. +func (in *ProbedScheduleTimeRule) DeepCopy() *ProbedScheduleTimeRule { + if in == nil { + return nil + } + out := new(ProbedScheduleTimeRule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *QueryParamMatch) DeepCopyInto(out *QueryParamMatch) { *out = *in @@ -907,6 +1279,31 @@ func (in *RegistryAuth) DeepCopy() *RegistryAuth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResumePolicy) DeepCopyInto(out *ResumePolicy) { + *out = *in + if in.WhenProbedScheduleTime != nil { + in, out := &in.WhenProbedScheduleTime, &out.WhenProbedScheduleTime + *out = new(ProbedScheduleTimeRule) + (*in).DeepCopyInto(*out) + } + if in.OnIngressTraffic != nil { + in, out := &in.OnIngressTraffic, &out.OnIngressTraffic + *out = new(IngressTrafficRule) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResumePolicy. +func (in *ResumePolicy) DeepCopy() *ResumePolicy { + if in == nil { + return nil + } + out := new(ResumePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RuleMatch) DeepCopyInto(out *RuleMatch) { *out = *in @@ -1368,6 +1765,18 @@ func (in *SandboxSetSpec) DeepCopyInto(out *SandboxSetSpec) { *out = make([]RuntimeConfig, len(*in)) copy(*out, *in) } + if in.Probes != nil { + in, out := &in.Probes, &out.Probes + *out = make([]Probe, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AutoPausePolicy != nil { + in, out := &in.AutoPausePolicy, &out.AutoPausePolicy + *out = new(AutoPausePolicy) + (*in).DeepCopyInto(*out) + } in.EmbeddedSandboxTemplate.DeepCopyInto(&out.EmbeddedSandboxTemplate) in.ScaleStrategy.DeepCopyInto(&out.ScaleStrategy) in.UpdateStrategy.DeepCopyInto(&out.UpdateStrategy) @@ -1456,6 +1865,18 @@ func (in *SandboxSpec) DeepCopyInto(out *SandboxSpec) { *out = new(SandboxLifecycle) (*in).DeepCopyInto(*out) } + if in.Probes != nil { + in, out := &in.Probes, &out.Probes + *out = make([]Probe, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AutoPausePolicy != nil { + in, out := &in.AutoPausePolicy, &out.AutoPausePolicy + *out = new(AutoPausePolicy) + (*in).DeepCopyInto(*out) + } if in.UpgradePolicy != nil { in, out := &in.UpgradePolicy, &out.UpgradePolicy *out = new(SandboxUpgradePolicy) @@ -1485,6 +1906,13 @@ func (in *SandboxStatus) DeepCopyInto(out *SandboxStatus) { } } in.PodInfo.DeepCopyInto(&out.PodInfo) + if in.Schedules != nil { + in, out := &in.Schedules, &out.Schedules + *out = make([]Schedule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SandboxStatus. @@ -1610,6 +2038,18 @@ func (in *SandboxTemplateSpec) DeepCopyInto(out *SandboxTemplateSpec) { *out = new(PauseStrategy) (*in).DeepCopyInto(*out) } + if in.Probes != nil { + in, out := &in.Probes, &out.Probes + *out = make([]Probe, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AutoPausePolicy != nil { + in, out := &in.AutoPausePolicy, &out.AutoPausePolicy + *out = new(AutoPausePolicy) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SandboxTemplateSpec. @@ -1770,6 +2210,29 @@ func (in *SandboxUpgradePolicy) DeepCopy() *SandboxUpgradePolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Schedule) DeepCopyInto(out *Schedule) { + *out = *in + if in.NextPauseTime != nil { + in, out := &in.NextPauseTime, &out.NextPauseTime + *out = (*in).DeepCopy() + } + if in.NextResumeTime != nil { + in, out := &in.NextResumeTime, &out.NextResumeTime + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Schedule. +func (in *Schedule) DeepCopy() *Schedule { + if in == nil { + return nil + } + out := new(Schedule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretCredentialRef) DeepCopyInto(out *SecretCredentialRef) { *out = *in diff --git a/client/clientset/versioned/typed/agents/v1alpha1/agents_client.go b/client/clientset/versioned/typed/agents/v1alpha1/agents_client.go index 12f8da5..ef46a82 100644 --- a/client/clientset/versioned/typed/agents/v1alpha1/agents_client.go +++ b/client/clientset/versioned/typed/agents/v1alpha1/agents_client.go @@ -32,6 +32,7 @@ type AgentsV1alpha1Interface interface { CommitsGetter GlobalSecurityProfilesGetter GlobalTrafficPoliciesGetter + PoolAutoscalersGetter SandboxesGetter SandboxClaimsGetter SandboxSetsGetter @@ -62,6 +63,10 @@ func (c *AgentsV1alpha1Client) GlobalTrafficPolicies() GlobalTrafficPolicyInterf return newGlobalTrafficPolicies(c) } +func (c *AgentsV1alpha1Client) PoolAutoscalers(namespace string) PoolAutoscalerInterface { + return newPoolAutoscalers(c, namespace) +} + func (c *AgentsV1alpha1Client) Sandboxes(namespace string) SandboxInterface { return newSandboxes(c, namespace) } diff --git a/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_agents_client.go b/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_agents_client.go index a846f0d..9155b14 100644 --- a/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_agents_client.go +++ b/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_agents_client.go @@ -44,6 +44,10 @@ func (c *FakeAgentsV1alpha1) GlobalTrafficPolicies() v1alpha1.GlobalTrafficPolic return newFakeGlobalTrafficPolicies(c) } +func (c *FakeAgentsV1alpha1) PoolAutoscalers(namespace string) v1alpha1.PoolAutoscalerInterface { + return newFakePoolAutoscalers(c, namespace) +} + func (c *FakeAgentsV1alpha1) Sandboxes(namespace string) v1alpha1.SandboxInterface { return newFakeSandboxes(c, namespace) } diff --git a/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_poolautoscaler.go b/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_poolautoscaler.go new file mode 100644 index 0000000..11dbaca --- /dev/null +++ b/client/clientset/versioned/typed/agents/v1alpha1/fake/fake_poolautoscaler.go @@ -0,0 +1,52 @@ +/* +Copyright 2025 The Kruise Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/openkruise/agents-api/agents/v1alpha1" + agentsv1alpha1 "github.com/openkruise/agents-api/client/clientset/versioned/typed/agents/v1alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakePoolAutoscalers implements PoolAutoscalerInterface +type fakePoolAutoscalers struct { + *gentype.FakeClientWithList[*v1alpha1.PoolAutoscaler, *v1alpha1.PoolAutoscalerList] + Fake *FakeAgentsV1alpha1 +} + +func newFakePoolAutoscalers(fake *FakeAgentsV1alpha1, namespace string) agentsv1alpha1.PoolAutoscalerInterface { + return &fakePoolAutoscalers{ + gentype.NewFakeClientWithList[*v1alpha1.PoolAutoscaler, *v1alpha1.PoolAutoscalerList]( + fake.Fake, + namespace, + v1alpha1.SchemeGroupVersion.WithResource("poolautoscalers"), + v1alpha1.SchemeGroupVersion.WithKind("PoolAutoscaler"), + func() *v1alpha1.PoolAutoscaler { return &v1alpha1.PoolAutoscaler{} }, + func() *v1alpha1.PoolAutoscalerList { return &v1alpha1.PoolAutoscalerList{} }, + func(dst, src *v1alpha1.PoolAutoscalerList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.PoolAutoscalerList) []*v1alpha1.PoolAutoscaler { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha1.PoolAutoscalerList, items []*v1alpha1.PoolAutoscaler) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/client/clientset/versioned/typed/agents/v1alpha1/generated_expansion.go b/client/clientset/versioned/typed/agents/v1alpha1/generated_expansion.go index e93d8ce..582c847 100644 --- a/client/clientset/versioned/typed/agents/v1alpha1/generated_expansion.go +++ b/client/clientset/versioned/typed/agents/v1alpha1/generated_expansion.go @@ -26,6 +26,8 @@ type GlobalSecurityProfileExpansion interface{} type GlobalTrafficPolicyExpansion interface{} +type PoolAutoscalerExpansion interface{} + type SandboxExpansion interface{} type SandboxClaimExpansion interface{} diff --git a/client/clientset/versioned/typed/agents/v1alpha1/poolautoscaler.go b/client/clientset/versioned/typed/agents/v1alpha1/poolautoscaler.go new file mode 100644 index 0000000..f56a577 --- /dev/null +++ b/client/clientset/versioned/typed/agents/v1alpha1/poolautoscaler.go @@ -0,0 +1,70 @@ +/* +Copyright 2025 The Kruise Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + + agentsv1alpha1 "github.com/openkruise/agents-api/agents/v1alpha1" + scheme "github.com/openkruise/agents-api/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// PoolAutoscalersGetter has a method to return a PoolAutoscalerInterface. +// A group's client should implement this interface. +type PoolAutoscalersGetter interface { + PoolAutoscalers(namespace string) PoolAutoscalerInterface +} + +// PoolAutoscalerInterface has methods to work with PoolAutoscaler resources. +type PoolAutoscalerInterface interface { + Create(ctx context.Context, poolAutoscaler *agentsv1alpha1.PoolAutoscaler, opts v1.CreateOptions) (*agentsv1alpha1.PoolAutoscaler, error) + Update(ctx context.Context, poolAutoscaler *agentsv1alpha1.PoolAutoscaler, opts v1.UpdateOptions) (*agentsv1alpha1.PoolAutoscaler, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, poolAutoscaler *agentsv1alpha1.PoolAutoscaler, opts v1.UpdateOptions) (*agentsv1alpha1.PoolAutoscaler, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*agentsv1alpha1.PoolAutoscaler, error) + List(ctx context.Context, opts v1.ListOptions) (*agentsv1alpha1.PoolAutoscalerList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *agentsv1alpha1.PoolAutoscaler, err error) + PoolAutoscalerExpansion +} + +// poolAutoscalers implements PoolAutoscalerInterface +type poolAutoscalers struct { + *gentype.ClientWithList[*agentsv1alpha1.PoolAutoscaler, *agentsv1alpha1.PoolAutoscalerList] +} + +// newPoolAutoscalers returns a PoolAutoscalers +func newPoolAutoscalers(c *AgentsV1alpha1Client, namespace string) *poolAutoscalers { + return &poolAutoscalers{ + gentype.NewClientWithList[*agentsv1alpha1.PoolAutoscaler, *agentsv1alpha1.PoolAutoscalerList]( + "poolautoscalers", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *agentsv1alpha1.PoolAutoscaler { return &agentsv1alpha1.PoolAutoscaler{} }, + func() *agentsv1alpha1.PoolAutoscalerList { return &agentsv1alpha1.PoolAutoscalerList{} }, + ), + } +} diff --git a/client/informers/externalversions/agents/v1alpha1/interface.go b/client/informers/externalversions/agents/v1alpha1/interface.go index d22d350..9aaee79 100644 --- a/client/informers/externalversions/agents/v1alpha1/interface.go +++ b/client/informers/externalversions/agents/v1alpha1/interface.go @@ -32,6 +32,8 @@ type Interface interface { GlobalSecurityProfiles() GlobalSecurityProfileInformer // GlobalTrafficPolicies returns a GlobalTrafficPolicyInformer. GlobalTrafficPolicies() GlobalTrafficPolicyInformer + // PoolAutoscalers returns a PoolAutoscalerInformer. + PoolAutoscalers() PoolAutoscalerInformer // Sandboxes returns a SandboxInformer. Sandboxes() SandboxInformer // SandboxClaims returns a SandboxClaimInformer. @@ -79,6 +81,11 @@ func (v *version) GlobalTrafficPolicies() GlobalTrafficPolicyInformer { return &globalTrafficPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// PoolAutoscalers returns a PoolAutoscalerInformer. +func (v *version) PoolAutoscalers() PoolAutoscalerInformer { + return &poolAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Sandboxes returns a SandboxInformer. func (v *version) Sandboxes() SandboxInformer { return &sandboxInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/client/informers/externalversions/agents/v1alpha1/poolautoscaler.go b/client/informers/externalversions/agents/v1alpha1/poolautoscaler.go new file mode 100644 index 0000000..cfca2a2 --- /dev/null +++ b/client/informers/externalversions/agents/v1alpha1/poolautoscaler.go @@ -0,0 +1,102 @@ +/* +Copyright 2025 The Kruise Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + time "time" + + agentsapiagentsv1alpha1 "github.com/openkruise/agents-api/agents/v1alpha1" + versioned "github.com/openkruise/agents-api/client/clientset/versioned" + internalinterfaces "github.com/openkruise/agents-api/client/informers/externalversions/internalinterfaces" + agentsv1alpha1 "github.com/openkruise/agents-api/client/listers/agents/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// PoolAutoscalerInformer provides access to a shared informer and lister for +// PoolAutoscalers. +type PoolAutoscalerInformer interface { + Informer() cache.SharedIndexInformer + Lister() agentsv1alpha1.PoolAutoscalerLister +} + +type poolAutoscalerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPoolAutoscalerInformer constructs a new informer for PoolAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPoolAutoscalerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPoolAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPoolAutoscalerInformer constructs a new informer for PoolAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPoolAutoscalerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AgentsV1alpha1().PoolAutoscalers(namespace).List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AgentsV1alpha1().PoolAutoscalers(namespace).Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AgentsV1alpha1().PoolAutoscalers(namespace).List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AgentsV1alpha1().PoolAutoscalers(namespace).Watch(ctx, options) + }, + }, client), + &agentsapiagentsv1alpha1.PoolAutoscaler{}, + resyncPeriod, + indexers, + ) +} + +func (f *poolAutoscalerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPoolAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *poolAutoscalerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&agentsapiagentsv1alpha1.PoolAutoscaler{}, f.defaultInformer) +} + +func (f *poolAutoscalerInformer) Lister() agentsv1alpha1.PoolAutoscalerLister { + return agentsv1alpha1.NewPoolAutoscalerLister(f.Informer().GetIndexer()) +} diff --git a/client/informers/externalversions/generic.go b/client/informers/externalversions/generic.go index 1037a53..2174081 100644 --- a/client/informers/externalversions/generic.go +++ b/client/informers/externalversions/generic.go @@ -61,6 +61,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Agents().V1alpha1().GlobalSecurityProfiles().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("globaltrafficpolicies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Agents().V1alpha1().GlobalTrafficPolicies().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("poolautoscalers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Agents().V1alpha1().PoolAutoscalers().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("sandboxes"): return &genericInformer{resource: resource.GroupResource(), informer: f.Agents().V1alpha1().Sandboxes().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("sandboxclaims"): diff --git a/client/listers/agents/v1alpha1/expansion_generated.go b/client/listers/agents/v1alpha1/expansion_generated.go index 70742a5..1413907 100644 --- a/client/listers/agents/v1alpha1/expansion_generated.go +++ b/client/listers/agents/v1alpha1/expansion_generated.go @@ -42,6 +42,14 @@ type GlobalSecurityProfileListerExpansion interface{} // GlobalTrafficPolicyLister. type GlobalTrafficPolicyListerExpansion interface{} +// PoolAutoscalerListerExpansion allows custom methods to be added to +// PoolAutoscalerLister. +type PoolAutoscalerListerExpansion interface{} + +// PoolAutoscalerNamespaceListerExpansion allows custom methods to be added to +// PoolAutoscalerNamespaceLister. +type PoolAutoscalerNamespaceListerExpansion interface{} + // SandboxListerExpansion allows custom methods to be added to // SandboxLister. type SandboxListerExpansion interface{} diff --git a/client/listers/agents/v1alpha1/poolautoscaler.go b/client/listers/agents/v1alpha1/poolautoscaler.go new file mode 100644 index 0000000..0634638 --- /dev/null +++ b/client/listers/agents/v1alpha1/poolautoscaler.go @@ -0,0 +1,70 @@ +/* +Copyright 2025 The Kruise Authors. + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + agentsv1alpha1 "github.com/openkruise/agents-api/agents/v1alpha1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// PoolAutoscalerLister helps list PoolAutoscalers. +// All objects returned here must be treated as read-only. +type PoolAutoscalerLister interface { + // List lists all PoolAutoscalers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*agentsv1alpha1.PoolAutoscaler, err error) + // PoolAutoscalers returns an object that can list and get PoolAutoscalers. + PoolAutoscalers(namespace string) PoolAutoscalerNamespaceLister + PoolAutoscalerListerExpansion +} + +// poolAutoscalerLister implements the PoolAutoscalerLister interface. +type poolAutoscalerLister struct { + listers.ResourceIndexer[*agentsv1alpha1.PoolAutoscaler] +} + +// NewPoolAutoscalerLister returns a new PoolAutoscalerLister. +func NewPoolAutoscalerLister(indexer cache.Indexer) PoolAutoscalerLister { + return &poolAutoscalerLister{listers.New[*agentsv1alpha1.PoolAutoscaler](indexer, agentsv1alpha1.Resource("poolautoscaler"))} +} + +// PoolAutoscalers returns an object that can list and get PoolAutoscalers. +func (s *poolAutoscalerLister) PoolAutoscalers(namespace string) PoolAutoscalerNamespaceLister { + return poolAutoscalerNamespaceLister{listers.NewNamespaced[*agentsv1alpha1.PoolAutoscaler](s.ResourceIndexer, namespace)} +} + +// PoolAutoscalerNamespaceLister helps list and get PoolAutoscalers. +// All objects returned here must be treated as read-only. +type PoolAutoscalerNamespaceLister interface { + // List lists all PoolAutoscalers in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*agentsv1alpha1.PoolAutoscaler, err error) + // Get retrieves the PoolAutoscaler from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*agentsv1alpha1.PoolAutoscaler, error) + PoolAutoscalerNamespaceListerExpansion +} + +// poolAutoscalerNamespaceLister implements the PoolAutoscalerNamespaceLister +// interface. +type poolAutoscalerNamespaceLister struct { + listers.ResourceIndexer[*agentsv1alpha1.PoolAutoscaler] +} diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscaler.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscaler.java new file mode 100644 index 0000000..84d576d --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscaler.java @@ -0,0 +1,9 @@ +package io.openkruise.agents.client.v2.models; + +@io.fabric8.kubernetes.model.annotation.Version(value = "v1alpha1" , storage = true , served = true) +@io.fabric8.kubernetes.model.annotation.Group("agents.kruise.io") +@io.fabric8.kubernetes.model.annotation.Singular("poolautoscaler") +@io.fabric8.kubernetes.model.annotation.Plural("poolautoscalers") +public class PoolAutoscaler extends io.fabric8.kubernetes.client.CustomResource implements io.fabric8.kubernetes.api.model.Namespaced { +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerSpec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerSpec.java new file mode 100644 index 0000000..7947e7a --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerSpec.java @@ -0,0 +1,113 @@ +package io.openkruise.agents.client.v2.models; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"capacityPolicy","cronPolicies","maxReplicas","minReplicas","scaleTargetRef","suspend"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class PoolAutoscalerSpec implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * CapacityPolicy defines the capacity configuration of the target resource pool. + */ + @com.fasterxml.jackson.annotation.JsonProperty("capacityPolicy") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("CapacityPolicy defines the capacity configuration of the target resource pool.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.poolautoscalerspec.CapacityPolicy capacityPolicy; + + public io.openkruise.agents.client.v2.models.poolautoscalerspec.CapacityPolicy getCapacityPolicy() { + return capacityPolicy; + } + + public void setCapacityPolicy(io.openkruise.agents.client.v2.models.poolautoscalerspec.CapacityPolicy capacityPolicy) { + this.capacityPolicy = capacityPolicy; + } + + /** + * CronPolicies is a list of potential cron scaling policies which can be used during scaling. + * When both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority. + */ + @com.fasterxml.jackson.annotation.JsonProperty("cronPolicies") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("CronPolicies is a list of potential cron scaling policies which can be used during scaling.\nWhen both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List cronPolicies; + + public java.util.List getCronPolicies() { + return cronPolicies; + } + + public void setCronPolicies(java.util.List cronPolicies) { + this.cronPolicies = cronPolicies; + } + + /** + * MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. + * It cannot be less than minReplicas. + */ + @com.fasterxml.jackson.annotation.JsonProperty("maxReplicas") + @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Min(1.0) + @com.fasterxml.jackson.annotation.JsonPropertyDescription("MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.\nIt cannot be less than minReplicas.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer maxReplicas; + + public Integer getMaxReplicas() { + return maxReplicas; + } + + public void setMaxReplicas(Integer maxReplicas) { + this.maxReplicas = maxReplicas; + } + + /** + * MinReplicas is the lower limit for the number of replicas to which the autoscaler + * can scale down. It defaults to 0 pods. + */ + @com.fasterxml.jackson.annotation.JsonProperty("minReplicas") + @io.fabric8.generator.annotation.Min(0.0) + @com.fasterxml.jackson.annotation.JsonPropertyDescription("MinReplicas is the lower limit for the number of replicas to which the autoscaler\ncan scale down. It defaults to 0 pods.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer minReplicas = 0; + + public Integer getMinReplicas() { + return minReplicas; + } + + public void setMinReplicas(Integer minReplicas) { + this.minReplicas = minReplicas; + } + + /** + * ScaleTargetRef points to the target warming pool to scale, and is used to select the pods for which instance status + * should be collected, as well as to actually change the replica count. + */ + @com.fasterxml.jackson.annotation.JsonProperty("scaleTargetRef") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ScaleTargetRef points to the target warming pool to scale, and is used to select the pods for which instance status\nshould be collected, as well as to actually change the replica count.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.poolautoscalerspec.ScaleTargetRef scaleTargetRef; + + public io.openkruise.agents.client.v2.models.poolautoscalerspec.ScaleTargetRef getScaleTargetRef() { + return scaleTargetRef; + } + + public void setScaleTargetRef(io.openkruise.agents.client.v2.models.poolautoscalerspec.ScaleTargetRef scaleTargetRef) { + this.scaleTargetRef = scaleTargetRef; + } + + /** + * Suspend tells the controller to suspend subsequent executions. + * Defaults to false. + */ + @com.fasterxml.jackson.annotation.JsonProperty("suspend") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Suspend tells the controller to suspend subsequent executions.\nDefaults to false.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Boolean suspend; + + public Boolean getSuspend() { + return suspend; + } + + public void setSuspend(Boolean suspend) { + this.suspend = suspend; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerStatus.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerStatus.java new file mode 100644 index 0000000..aaf21e8 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/PoolAutoscalerStatus.java @@ -0,0 +1,140 @@ +package io.openkruise.agents.client.v2.models; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"appliedCronPolicies","conditions","currentCapacity","currentReplicas","desiredReplicas","lastScaleTime","observedGeneration","suspended"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class PoolAutoscalerStatus implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * AppliedCronPolicies is the execution status of cron policies. + */ + @com.fasterxml.jackson.annotation.JsonProperty("appliedCronPolicies") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("AppliedCronPolicies is the execution status of cron policies.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List appliedCronPolicies; + + public java.util.List getAppliedCronPolicies() { + return appliedCronPolicies; + } + + public void setAppliedCronPolicies(java.util.List appliedCronPolicies) { + this.appliedCronPolicies = appliedCronPolicies; + } + + /** + * Conditions is the set of conditions required for this autoscaler to scale its target. + */ + @com.fasterxml.jackson.annotation.JsonProperty("conditions") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Conditions is the set of conditions required for this autoscaler to scale its target.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List conditions; + + public java.util.List getConditions() { + return conditions; + } + + public void setConditions(java.util.List conditions) { + this.conditions = conditions; + } + + /** + * CurrentCapacity is the last read state of the capacity used by this autoscaler. + */ + @com.fasterxml.jackson.annotation.JsonProperty("currentCapacity") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("CurrentCapacity is the last read state of the capacity used by this autoscaler.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.poolautoscalerstatus.CurrentCapacity currentCapacity; + + public io.openkruise.agents.client.v2.models.poolautoscalerstatus.CurrentCapacity getCurrentCapacity() { + return currentCapacity; + } + + public void setCurrentCapacity(io.openkruise.agents.client.v2.models.poolautoscalerstatus.CurrentCapacity currentCapacity) { + this.currentCapacity = currentCapacity; + } + + /** + * CurrentReplicas is current number of replicas of pods managed by this autoscaler. + */ + @com.fasterxml.jackson.annotation.JsonProperty("currentReplicas") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("CurrentReplicas is current number of replicas of pods managed by this autoscaler.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer currentReplicas; + + public Integer getCurrentReplicas() { + return currentReplicas; + } + + public void setCurrentReplicas(Integer currentReplicas) { + this.currentReplicas = currentReplicas; + } + + /** + * DesiredReplicas is the desired number of replicas of pods managed by this autoscaler. + */ + @com.fasterxml.jackson.annotation.JsonProperty("desiredReplicas") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("DesiredReplicas is the desired number of replicas of pods managed by this autoscaler.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer desiredReplicas; + + public Integer getDesiredReplicas() { + return desiredReplicas; + } + + public void setDesiredReplicas(Integer desiredReplicas) { + this.desiredReplicas = desiredReplicas; + } + + /** + * LastScaleTime is the last time the PoolAutoscaler scaled the number of pods. + */ + @com.fasterxml.jackson.annotation.JsonProperty("lastScaleTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("LastScaleTime is the last time the PoolAutoscaler scaled the number of pods.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.time.ZonedDateTime lastScaleTime; + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + public java.time.ZonedDateTime getLastScaleTime() { + return lastScaleTime; + } + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]") + public void setLastScaleTime(java.time.ZonedDateTime lastScaleTime) { + this.lastScaleTime = lastScaleTime; + } + + /** + * ObservedGeneration is the most recent generation observed by this autoscaler. + */ + @com.fasterxml.jackson.annotation.JsonProperty("observedGeneration") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ObservedGeneration is the most recent generation observed by this autoscaler.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Long observedGeneration; + + public Long getObservedGeneration() { + return observedGeneration; + } + + public void setObservedGeneration(Long observedGeneration) { + this.observedGeneration = observedGeneration; + } + + /** + * Suspended indicates whether the autoscaler is currently suspended. + */ + @com.fasterxml.jackson.annotation.JsonProperty("suspended") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Suspended indicates whether the autoscaler is currently suspended.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Boolean suspended; + + public Boolean getSuspended() { + return suspended; + } + + public void setSuspended(Boolean suspended) { + this.suspended = suspended; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetSpec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetSpec.java index 04389d3..605ad78 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetSpec.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetSpec.java @@ -1,10 +1,32 @@ package io.openkruise.agents.client.v2.models; @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) -@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pauseStrategy","persistentContents","replicas","runtimes","scaleStrategy","template","templateRef","updateStrategy","volumeClaimTemplates"}) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"autoPausePolicy","pauseStrategy","persistentContents","probes","replicas","runtimes","scaleStrategy","template","templateRef","updateStrategy","volumeClaimTemplates"}) @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) public class SandboxSetSpec implements io.fabric8.kubernetes.api.model.KubernetesResource { + /** + * AutoPausePolicy defines the pause/resume decision rules for sandboxes + * created from this SandboxSet. Probe-driven rules reference probes by + * name (so they are normally set together with spec.probes); the + * OnIngressTraffic resume rule is event-driven and does not require a + * probe. The policy is copied verbatim onto each created Sandbox and is + * part of the update revision hash, so changing it triggers a rolling + * update of already-created pool sandboxes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("autoPausePolicy") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("AutoPausePolicy defines the pause/resume decision rules for sandboxes\ncreated from this SandboxSet. Probe-driven rules reference probes by\nname (so they are normally set together with spec.probes); the\nOnIngressTraffic resume rule is event-driven and does not require a\nprobe. The policy is copied verbatim onto each created Sandbox and is\npart of the update revision hash, so changing it triggers a rolling\nupdate of already-created pool sandboxes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.AutoPausePolicy autoPausePolicy; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.AutoPausePolicy getAutoPausePolicy() { + return autoPausePolicy; + } + + public void setAutoPausePolicy(io.openkruise.agents.client.v2.models.sandboxsetspec.AutoPausePolicy autoPausePolicy) { + this.autoPausePolicy = autoPausePolicy; + } + /** * PauseStrategy configures how sandboxes created from this SandboxSet are * paused when their spec.paused is true. It is copied verbatim onto each @@ -40,6 +62,25 @@ public void setPersistentContents(java.util.List persistentContents) { this.persistentContents = persistentContents; } + /** + * Probes defines the named probes that sandboxes created from this SandboxSet + * run while they are Running. It is copied verbatim onto each created Sandbox + * and is part of the update revision hash, so changing it triggers a rolling + * update of already-created pool sandboxes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probes") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probes defines the named probes that sandboxes created from this SandboxSet\nrun while they are Running. It is copied verbatim onto each created Sandbox\nand is part of the update revision hash, so changing it triggers a rolling\nupdate of already-created pool sandboxes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List probes; + + public java.util.List getProbes() { + return probes; + } + + public void setProbes(java.util.List probes) { + this.probes = probes; + } + /** * Replicas is the number of unused sandboxes, including available and creating ones. */ diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetStatus.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetStatus.java index be93bfe..fc1f2fe 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetStatus.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSetStatus.java @@ -111,11 +111,12 @@ public void setSelector(String selector) { /** * UpdateRevision is the FNV-32 hash computed from spec.template, - * spec.persistentContents, spec.runtimes, and spec.pauseStrategy. + * spec.persistentContents, spec.runtimes, spec.pauseStrategy, + * spec.probes, and spec.autoPausePolicy. * It represents the latest desired template version. */ @com.fasterxml.jackson.annotation.JsonProperty("updateRevision") - @com.fasterxml.jackson.annotation.JsonPropertyDescription("UpdateRevision is the FNV-32 hash computed from spec.template,\nspec.persistentContents, spec.runtimes, and spec.pauseStrategy.\nIt represents the latest desired template version.") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("UpdateRevision is the FNV-32 hash computed from spec.template,\nspec.persistentContents, spec.runtimes, spec.pauseStrategy,\nspec.probes, and spec.autoPausePolicy.\nIt represents the latest desired template version.") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private String updateRevision; diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSpec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSpec.java index 70c038a..7d1f947 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSpec.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxSpec.java @@ -1,15 +1,36 @@ package io.openkruise.agents.client.v2.models; @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) -@com.fasterxml.jackson.annotation.JsonPropertyOrder({"lifecycle","pauseStrategy","pauseTime","paused","persistentContents","runtimes","shutdownTime","template","templateRef","upgradePolicy","volumeClaimTemplates"}) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"autoPausePolicy","lifecycle","pauseStrategy","pauseTime","paused","persistentContents","probes","runtimes","shutdownTime","template","templateRef","upgradePolicy","volumeClaimTemplates"}) @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) public class SandboxSpec implements io.fabric8.kubernetes.api.model.KubernetesResource { /** - * Lifecycle defines lifecycle hooks for sandbox upgrade. + * AutoPausePolicy defines when the sandbox controller pauses or resumes + * the sandbox. Probe-driven rules reference probes declared in + * Spec.Probes and read their results (mirrored from + * Pod.Status.Conditions to SandboxStatus.Conditions); the + * OnIngressTraffic resume rule is event-driven and does not require a + * probe. + */ + @com.fasterxml.jackson.annotation.JsonProperty("autoPausePolicy") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("AutoPausePolicy defines when the sandbox controller pauses or resumes\nthe sandbox. Probe-driven rules reference probes declared in\nSpec.Probes and read their results (mirrored from\nPod.Status.Conditions to SandboxStatus.Conditions); the\nOnIngressTraffic resume rule is event-driven and does not require a\nprobe.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.AutoPausePolicy autoPausePolicy; + + public io.openkruise.agents.client.v2.models.sandboxspec.AutoPausePolicy getAutoPausePolicy() { + return autoPausePolicy; + } + + public void setAutoPausePolicy(io.openkruise.agents.client.v2.models.sandboxspec.AutoPausePolicy autoPausePolicy) { + this.autoPausePolicy = autoPausePolicy; + } + + /** + * Lifecycle defines lifecycle hooks for sandbox. */ @com.fasterxml.jackson.annotation.JsonProperty("lifecycle") - @com.fasterxml.jackson.annotation.JsonPropertyDescription("Lifecycle defines lifecycle hooks for sandbox upgrade.") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Lifecycle defines lifecycle hooks for sandbox.") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private io.openkruise.agents.client.v2.models.sandboxspec.Lifecycle lifecycle; @@ -87,6 +108,31 @@ public void setPersistentContents(java.util.List persistentContents) { this.persistentContents = persistentContents; } + /** + * Probes defines a list of named probes that run periodically while the sandbox + * is Running. Each probe writes its result to a Pod Status Condition with + * type "agents.kruise.io/". Probes are generic — their semantics (e.g., + * "activity detection" vs "cron task detection") are defined by + * AutoPausePolicy.Pause/Resume, not by the probe itself. + * + * Probe execution is delegated to the agent-runtime sidecar via the + * PodProbeMarker Serverless protocol (kruise.io/podprobe annotation). + * The controller reads results from Pod.Status.Conditions and mirrors + * them to SandboxStatus.Conditions for observability. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probes") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probes defines a list of named probes that run periodically while the sandbox\nis Running. Each probe writes its result to a Pod Status Condition with\ntype \"agents.kruise.io/\". Probes are generic — their semantics (e.g.,\n\"activity detection\" vs \"cron task detection\") are defined by\nAutoPausePolicy.Pause/Resume, not by the probe itself.\n\nProbe execution is delegated to the agent-runtime sidecar via the\nPodProbeMarker Serverless protocol (kruise.io/podprobe annotation).\nThe controller reads results from Pod.Status.Conditions and mirrors\nthem to SandboxStatus.Conditions for observability.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List probes; + + public java.util.List getProbes() { + return probes; + } + + public void setProbes(java.util.List probes) { + this.probes = probes; + } + /** * Runtimes - Runtime configuration for sandbox object */ diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxStatus.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxStatus.java index c8ce41a..30d9971 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxStatus.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxStatus.java @@ -1,7 +1,7 @@ package io.openkruise.agents.client.v2.models; @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) -@com.fasterxml.jackson.annotation.JsonPropertyOrder({"conditions","message","nodeName","observedGeneration","phase","podInfo","recycledCount","sandboxIp","updateRevision"}) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"conditions","message","nodeName","observedGeneration","phase","podInfo","recycledCount","sandboxIp","schedules","updateRevision"}) @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) public class SandboxStatus implements io.fabric8.kubernetes.api.model.KubernetesResource { @@ -136,6 +136,23 @@ public void setSandboxIp(String sandboxIp) { this.sandboxIp = sandboxIp; } + /** + * Schedules contains upcoming scheduled pause/resume events. + * Only populated when Spec.AutoPausePolicy.Pause/Resume is configured. + */ + @com.fasterxml.jackson.annotation.JsonProperty("schedules") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Schedules contains upcoming scheduled pause/resume events.\nOnly populated when Spec.AutoPausePolicy.Pause/Resume is configured.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List schedules; + + public java.util.List getSchedules() { + return schedules; + } + + public void setSchedules(java.util.List schedules) { + this.schedules = schedules; + } + /** * UpdateRevision is the template-hash calculated from `spec.template`. */ diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxTemplateSpec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxTemplateSpec.java index 91e10bd..b6e15d0 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxTemplateSpec.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/SandboxTemplateSpec.java @@ -1,10 +1,29 @@ package io.openkruise.agents.client.v2.models; @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) -@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pauseStrategy","persistentContents","runtimes","template","volumeClaimTemplates"}) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"autoPausePolicy","pauseStrategy","persistentContents","probes","runtimes","template","volumeClaimTemplates"}) @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) public class SandboxTemplateSpec implements io.fabric8.kubernetes.api.model.KubernetesResource { + /** + * AutoPausePolicy defines the pause/resume decision rules for sandboxes + * created from this template. It is only informational when a SandboxSet uses + * spec.templateRef: SandboxSetSpec.AutoPausePolicy always takes precedence and + * is what actually reaches created Sandboxes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("autoPausePolicy") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("AutoPausePolicy defines the pause/resume decision rules for sandboxes\ncreated from this template. It is only informational when a SandboxSet uses\nspec.templateRef: SandboxSetSpec.AutoPausePolicy always takes precedence and\nis what actually reaches created Sandboxes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.AutoPausePolicy autoPausePolicy; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.AutoPausePolicy getAutoPausePolicy() { + return autoPausePolicy; + } + + public void setAutoPausePolicy(io.openkruise.agents.client.v2.models.sandboxtemplatespec.AutoPausePolicy autoPausePolicy) { + this.autoPausePolicy = autoPausePolicy; + } + /** * PauseStrategy configures how sandboxes created from this template are * paused when their spec.paused is true. It is only informational when a @@ -40,6 +59,25 @@ public void setPersistentContents(java.util.List persistentContents) { this.persistentContents = persistentContents; } + /** + * Probes defines the named probes that sandboxes created from this template + * run while they are Running. It is only informational when a SandboxSet uses + * spec.templateRef: SandboxSetSpec.Probes always takes precedence and is what + * actually reaches created Sandboxes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probes") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probes defines the named probes that sandboxes created from this template\nrun while they are Running. It is only informational when a SandboxSet uses\nspec.templateRef: SandboxSetSpec.Probes always takes precedence and is what\nactually reaches created Sandboxes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List probes; + + public java.util.List getProbes() { + return probes; + } + + public void setProbes(java.util.List probes) { + this.probes = probes; + } + /** * Runtimes - Runtime configuration for sandbox object */ diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CapacityPolicy.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CapacityPolicy.java new file mode 100644 index 0000000..621882d --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CapacityPolicy.java @@ -0,0 +1,84 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"scaleDown","scaleUp","targetAvailable","tolerance"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class CapacityPolicy implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * ScaleDown is the scaling rule for scaling down. + */ + @com.fasterxml.jackson.annotation.JsonProperty("scaleDown") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ScaleDown is the scaling rule for scaling down.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy.ScaleDown scaleDown; + + public io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy.ScaleDown getScaleDown() { + return scaleDown; + } + + public void setScaleDown(io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy.ScaleDown scaleDown) { + this.scaleDown = scaleDown; + } + + /** + * ScaleUp is the scaling rule for scaling up. + */ + @com.fasterxml.jackson.annotation.JsonProperty("scaleUp") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ScaleUp is the scaling rule for scaling up.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy.ScaleUp scaleUp; + + public io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy.ScaleUp getScaleUp() { + return scaleUp; + } + + public void setScaleUp(io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy.ScaleUp scaleUp) { + this.scaleUp = scaleUp; + } + + /** + * TargetAvailable is the desired available replicas. + * Can be an absolute number (ex: 5) or a percentage of current replicas (ex: 70%). + * When the pool is empty, a percentage target is bootstrapped against + * maxReplicas so the pool can seed its initial idle capacity. + */ + @com.fasterxml.jackson.annotation.JsonProperty("targetAvailable") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TargetAvailable is the desired available replicas.\nCan be an absolute number (ex: 5) or a percentage of current replicas (ex: 70%).\nWhen the pool is empty, a percentage target is bootstrapped against\nmaxReplicas so the pool can seed its initial idle capacity.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString targetAvailable; + + public io.fabric8.kubernetes.api.model.IntOrString getTargetAvailable() { + return targetAvailable; + } + + public void setTargetAvailable(io.fabric8.kubernetes.api.model.IntOrString targetAvailable) { + this.targetAvailable = targetAvailable; + } + + /** + * Tolerance is the tolerance between the watermark and desired value under which + * no updates are made to the desired number of replicas. + * Can be an absolute number (ex: 5) or a percentage (ex: 10%). + * If not set, defaults to 10%. + * A percentage tolerance is always resolved against the target value: + * when targetAvailable is also a percentage, both percentages are combined + * first and applied to the pool size; when targetAvailable is an absolute + * number, the percentage tolerance is applied to that resolved target + * (e.g. targetAvailable=5 with tolerance=10% yields watermarks [4, 6]). + */ + @com.fasterxml.jackson.annotation.JsonProperty("tolerance") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Tolerance is the tolerance between the watermark and desired value under which\nno updates are made to the desired number of replicas.\nCan be an absolute number (ex: 5) or a percentage (ex: 10%).\nIf not set, defaults to 10%.\nA percentage tolerance is always resolved against the target value:\nwhen targetAvailable is also a percentage, both percentages are combined\nfirst and applied to the pool size; when targetAvailable is an absolute\nnumber, the percentage tolerance is applied to that resolved target\n(e.g. targetAvailable=5 with tolerance=10% yields watermarks [4, 6]).") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString tolerance; + + public io.fabric8.kubernetes.api.model.IntOrString getTolerance() { + return tolerance; + } + + public void setTolerance(io.fabric8.kubernetes.api.model.IntOrString tolerance) { + this.tolerance = tolerance; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CronPolicies.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CronPolicies.java new file mode 100644 index 0000000..684e847 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/CronPolicies.java @@ -0,0 +1,78 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"name","schedule","targetReplicas","timeZone"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class CronPolicies implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Name is used to specify the scaling policy. + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is used to specify the scaling policy.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * Schedule is a cron expression that defines when this policy should be executed. + * Supports standard cron format with 5 fields (minute hour day month weekday). + */ + @com.fasterxml.jackson.annotation.JsonProperty("schedule") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Schedule is a cron expression that defines when this policy should be executed.\nSupports standard cron format with 5 fields (minute hour day month weekday).") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String schedule; + + public String getSchedule() { + return schedule; + } + + public void setSchedule(String schedule) { + this.schedule = schedule; + } + + /** + * TargetReplicas is the desired replicas when this policy executes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("targetReplicas") + @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Min(0.0) + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TargetReplicas is the desired replicas when this policy executes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer targetReplicas; + + public Integer getTargetReplicas() { + return targetReplicas; + } + + public void setTargetReplicas(Integer targetReplicas) { + this.targetReplicas = targetReplicas; + } + + /** + * TimeZone is the time zone name for the given schedule, e.g. "Asia/Shanghai", "UTC". + * If not specified, this will default to the time zone of the autoscaler controller manager process. + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeZone") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TimeZone is the time zone name for the given schedule, e.g. \"Asia/Shanghai\", \"UTC\".\nIf not specified, this will default to the time zone of the autoscaler controller manager process.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String timeZone; + + public String getTimeZone() { + return timeZone; + } + + public void setTimeZone(String timeZone) { + this.timeZone = timeZone; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/ScaleTargetRef.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/ScaleTargetRef.java new file mode 100644 index 0000000..231fa31 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/ScaleTargetRef.java @@ -0,0 +1,75 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"apiVersion","kind","name"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class ScaleTargetRef implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * API version of the referent + */ + @com.fasterxml.jackson.annotation.JsonProperty("apiVersion") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("API version of the referent") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String apiVersion; + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public enum Kind { + + @com.fasterxml.jackson.annotation.JsonProperty("SandboxSet") + SANDBOXSET("SandboxSet"); + + java.lang.String value; + + Kind(java.lang.String value) { + this.value = value; + } + + @com.fasterxml.jackson.annotation.JsonValue() + public java.lang.String getValue() { + return value; + } + } + + /** + * Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + @com.fasterxml.jackson.annotation.JsonProperty("kind") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Kind kind; + + public Kind getKind() { + return kind; + } + + public void setKind(Kind kind) { + this.kind = kind; + } + + /** + * Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleDown.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleDown.java new file mode 100644 index 0000000..90561c9 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleDown.java @@ -0,0 +1,33 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"stabilizationWindowSeconds"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class ScaleDown implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * StabilizationWindowSeconds is the cooldown period after any scale action before + * a scale in this direction is allowed. This is a cooldown model: the first scale + * action is immediate, subsequent actions must wait for the window to elapse since + * the most recent scale action (in either direction). + * Must be >= 60 and <= 3600 (one hour) when set. + * Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + * least the process-wide Sandbox Pending timeout plus 10 seconds. + * Scale-down defaults to 300 seconds when omitted. + */ + @com.fasterxml.jackson.annotation.JsonProperty("stabilizationWindowSeconds") + @io.fabric8.generator.annotation.Max(3600.0) + @io.fabric8.generator.annotation.Min(60.0) + @com.fasterxml.jackson.annotation.JsonPropertyDescription("StabilizationWindowSeconds is the cooldown period after any scale action before\na scale in this direction is allowed. This is a cooldown model: the first scale\naction is immediate, subsequent actions must wait for the window to elapse since\nthe most recent scale action (in either direction).\nMust be >= 60 and <= 3600 (one hour) when set.\nScale-up defaults to 60 seconds when omitted and is normalized at runtime to at\nleast the process-wide Sandbox Pending timeout plus 10 seconds.\nScale-down defaults to 300 seconds when omitted.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer stabilizationWindowSeconds; + + public Integer getStabilizationWindowSeconds() { + return stabilizationWindowSeconds; + } + + public void setStabilizationWindowSeconds(Integer stabilizationWindowSeconds) { + this.stabilizationWindowSeconds = stabilizationWindowSeconds; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleUp.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleUp.java new file mode 100644 index 0000000..9543fa3 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerspec/capacitypolicy/ScaleUp.java @@ -0,0 +1,33 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerspec.capacitypolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"stabilizationWindowSeconds"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class ScaleUp implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * StabilizationWindowSeconds is the cooldown period after any scale action before + * a scale in this direction is allowed. This is a cooldown model: the first scale + * action is immediate, subsequent actions must wait for the window to elapse since + * the most recent scale action (in either direction). + * Must be >= 60 and <= 3600 (one hour) when set. + * Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + * least the process-wide Sandbox Pending timeout plus 10 seconds. + * Scale-down defaults to 300 seconds when omitted. + */ + @com.fasterxml.jackson.annotation.JsonProperty("stabilizationWindowSeconds") + @io.fabric8.generator.annotation.Max(3600.0) + @io.fabric8.generator.annotation.Min(60.0) + @com.fasterxml.jackson.annotation.JsonPropertyDescription("StabilizationWindowSeconds is the cooldown period after any scale action before\na scale in this direction is allowed. This is a cooldown model: the first scale\naction is immediate, subsequent actions must wait for the window to elapse since\nthe most recent scale action (in either direction).\nMust be >= 60 and <= 3600 (one hour) when set.\nScale-up defaults to 60 seconds when omitted and is normalized at runtime to at\nleast the process-wide Sandbox Pending timeout plus 10 seconds.\nScale-down defaults to 300 seconds when omitted.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer stabilizationWindowSeconds; + + public Integer getStabilizationWindowSeconds() { + return stabilizationWindowSeconds; + } + + public void setStabilizationWindowSeconds(Integer stabilizationWindowSeconds) { + this.stabilizationWindowSeconds = stabilizationWindowSeconds; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/AppliedCronPolicies.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/AppliedCronPolicies.java new file mode 100644 index 0000000..ca0a330 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/AppliedCronPolicies.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerstatus; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"lastScheduleTime","name"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class AppliedCronPolicies implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * LastScheduleTime is the last time the policy was successfully scheduled. + */ + @com.fasterxml.jackson.annotation.JsonProperty("lastScheduleTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("LastScheduleTime is the last time the policy was successfully scheduled.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.time.ZonedDateTime lastScheduleTime; + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + public java.time.ZonedDateTime getLastScheduleTime() { + return lastScheduleTime; + } + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]") + public void setLastScheduleTime(java.time.ZonedDateTime lastScheduleTime) { + this.lastScheduleTime = lastScheduleTime; + } + + /** + * Name is the cron policy name. + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the cron policy name.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/Conditions.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/Conditions.java new file mode 100644 index 0000000..69b8724 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/Conditions.java @@ -0,0 +1,141 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerstatus; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"lastTransitionTime","message","observedGeneration","reason","status","type"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Conditions implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * lastTransitionTime is the last time the condition transitioned from one status to another. + * This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + */ + @com.fasterxml.jackson.annotation.JsonProperty("lastTransitionTime") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.time.ZonedDateTime lastTransitionTime; + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + public java.time.ZonedDateTime getLastTransitionTime() { + return lastTransitionTime; + } + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]") + public void setLastTransitionTime(java.time.ZonedDateTime lastTransitionTime) { + this.lastTransitionTime = lastTransitionTime; + } + + /** + * message is a human readable message indicating details about the transition. + * This may be an empty string. + */ + @com.fasterxml.jackson.annotation.JsonProperty("message") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("message is a human readable message indicating details about the transition.\nThis may be an empty string.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + /** + * observedGeneration represents the .metadata.generation that the condition was set based upon. + * For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + * with respect to the current state of the instance. + */ + @com.fasterxml.jackson.annotation.JsonProperty("observedGeneration") + @io.fabric8.generator.annotation.Min(0.0) + @com.fasterxml.jackson.annotation.JsonPropertyDescription("observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Long observedGeneration; + + public Long getObservedGeneration() { + return observedGeneration; + } + + public void setObservedGeneration(Long observedGeneration) { + this.observedGeneration = observedGeneration; + } + + /** + * reason contains a programmatic identifier indicating the reason for the condition's last transition. + * Producers of specific condition types may define expected values and meanings for this field, + * and whether the values are considered a guaranteed API. + * The value should be a CamelCase string. + * This field may not be empty. + */ + @com.fasterxml.jackson.annotation.JsonProperty("reason") + @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Pattern("^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String reason; + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public enum Status { + + @com.fasterxml.jackson.annotation.JsonProperty("True") + TRUE("True"), @com.fasterxml.jackson.annotation.JsonProperty("False") + FALSE("False"), @com.fasterxml.jackson.annotation.JsonProperty("Unknown") + UNKNOWN("Unknown"); + + java.lang.String value; + + Status(java.lang.String value) { + this.value = value; + } + + @com.fasterxml.jackson.annotation.JsonValue() + public java.lang.String getValue() { + return value; + } + } + + /** + * status of the condition, one of True, False, Unknown. + */ + @com.fasterxml.jackson.annotation.JsonProperty("status") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("status of the condition, one of True, False, Unknown.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Status status; + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + /** + * type of condition in CamelCase or in foo.example.com/CamelCase. + */ + @com.fasterxml.jackson.annotation.JsonProperty("type") + @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Pattern("^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("type of condition in CamelCase or in foo.example.com/CamelCase.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/CurrentCapacity.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/CurrentCapacity.java new file mode 100644 index 0000000..70fe376 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/poolautoscalerstatus/CurrentCapacity.java @@ -0,0 +1,25 @@ +package io.openkruise.agents.client.v2.models.poolautoscalerstatus; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"available"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class CurrentCapacity implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Available is current number of available pods managed by this autoscaler. + */ + @com.fasterxml.jackson.annotation.JsonProperty("available") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Available is current number of available pods managed by this autoscaler.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer available; + + public Integer getAvailable() { + return available; + } + + public void setAvailable(Integer available) { + this.available = available; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxclaimspec/inplaceupdate/Resources.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxclaimspec/inplaceupdate/Resources.java index 6dd93ec..2525661 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxclaimspec/inplaceupdate/Resources.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxclaimspec/inplaceupdate/Resources.java @@ -7,12 +7,16 @@ public class Resources implements io.fabric8.kubernetes.api.model.KubernetesReso /** * Limits specifies the target resource limits for each container. - * Only CPU is supported for now. The container's original limit must already be set; - * otherwise the value is ignored. + * Only CPU and memory are supported; other resource names are rejected. + * The container's original limit must already be set; otherwise the value is ignored. + * A limit must not be lower than the target request of the same resource. + * Memory may only be increased: a target lower than the container's current memory is rejected. + * Memory resize may restart the container when the pod template declares + * resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. * The new value must not change the Pod's QoS class; otherwise the claim will be rejected. */ @com.fasterxml.jackson.annotation.JsonProperty("limits") - @com.fasterxml.jackson.annotation.JsonPropertyDescription("Limits specifies the target resource limits for each container.\nOnly CPU is supported for now. The container's original limit must already be set;\notherwise the value is ignored.\nThe new value must not change the Pod's QoS class; otherwise the claim will be rejected.") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Limits specifies the target resource limits for each container.\nOnly CPU and memory are supported; other resource names are rejected.\nThe container's original limit must already be set; otherwise the value is ignored.\nA limit must not be lower than the target request of the same resource.\nMemory may only be increased: a target lower than the container's current memory is rejected.\nMemory resize may restart the container when the pod template declares\nresizePolicy: {resourceName: memory, restartPolicy: RestartContainer}.\nThe new value must not change the Pod's QoS class; otherwise the claim will be rejected.") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private java.util.Map limits; @@ -26,12 +30,16 @@ public void setLimits(java.util.Map requests; diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/AutoPausePolicy.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/AutoPausePolicy.java new file mode 100644 index 0000000..c6c29f7 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/AutoPausePolicy.java @@ -0,0 +1,40 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pause","resume"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class AutoPausePolicy implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Pause defines the pause policy for the sandbox. + */ + @com.fasterxml.jackson.annotation.JsonProperty("pause") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Pause defines the pause policy for the sandbox.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.Pause pause; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.Pause getPause() { + return pause; + } + + public void setPause(io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.Pause pause) { + this.pause = pause; + } + + /** + * Resume defines the resume policy for the sandbox. + */ + @com.fasterxml.jackson.annotation.JsonProperty("resume") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Resume defines the resume policy for the sandbox.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.Resume resume; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.Resume getResume() { + return resume; + } + + public void setResume(io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.Resume resume) { + this.resume = resume; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java new file mode 100644 index 0000000..2cc854f --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java @@ -0,0 +1,218 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"containerName","exec","failureThreshold","grpc","httpGet","initialDelaySeconds","name","periodSeconds","successThreshold","tcpSocket","terminationGracePeriodSeconds","timeoutSeconds"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Probes implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * ContainerName specifies which container to execute the probe in. + * If empty, defaults to the first container in the pod spec. + */ + @com.fasterxml.jackson.annotation.JsonProperty("containerName") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ContainerName specifies which container to execute the probe in.\nIf empty, defaults to the first container in the pod spec.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String containerName; + + public String getContainerName() { + return containerName; + } + + public void setContainerName(String containerName) { + this.containerName = containerName; + } + + /** + * Exec specifies a command to execute in the container. + */ + @com.fasterxml.jackson.annotation.JsonProperty("exec") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Exec specifies a command to execute in the container.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.probes.Exec exec; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.probes.Exec getExec() { + return exec; + } + + public void setExec(io.openkruise.agents.client.v2.models.sandboxsetspec.probes.Exec exec) { + this.exec = exec; + } + + /** + * Minimum consecutive failures for the probe to be considered failed after having succeeded. + * Defaults to 3. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("failureThreshold") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Minimum consecutive failures for the probe to be considered failed after having succeeded.\nDefaults to 3. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer failureThreshold; + + public Integer getFailureThreshold() { + return failureThreshold; + } + + public void setFailureThreshold(Integer failureThreshold) { + this.failureThreshold = failureThreshold; + } + + /** + * GRPC specifies a GRPC HealthCheckRequest. + */ + @com.fasterxml.jackson.annotation.JsonProperty("grpc") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("GRPC specifies a GRPC HealthCheckRequest.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.probes.Grpc grpc; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.probes.Grpc getGrpc() { + return grpc; + } + + public void setGrpc(io.openkruise.agents.client.v2.models.sandboxsetspec.probes.Grpc grpc) { + this.grpc = grpc; + } + + /** + * HTTPGet specifies an HTTP GET request to perform. + */ + @com.fasterxml.jackson.annotation.JsonProperty("httpGet") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("HTTPGet specifies an HTTP GET request to perform.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.probes.HttpGet httpGet; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.probes.HttpGet getHttpGet() { + return httpGet; + } + + public void setHttpGet(io.openkruise.agents.client.v2.models.sandboxsetspec.probes.HttpGet httpGet) { + this.httpGet = httpGet; + } + + /** + * Number of seconds after the container has started before liveness probes are initiated. + * More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + */ + @com.fasterxml.jackson.annotation.JsonProperty("initialDelaySeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number of seconds after the container has started before liveness probes are initiated.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer initialDelaySeconds; + + public Integer getInitialDelaySeconds() { + return initialDelaySeconds; + } + + public void setInitialDelaySeconds(Integer initialDelaySeconds) { + this.initialDelaySeconds = initialDelaySeconds; + } + + /** + * Name is the unique identifier for this probe within the sandbox. + * Probe results are written to a Condition with type "agents.kruise.io/". + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the unique identifier for this probe within the sandbox.\nProbe results are written to a Condition with type \"agents.kruise.io/\".") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * How often (in seconds) to perform the probe. + * Default to 10 seconds. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("periodSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("How often (in seconds) to perform the probe.\nDefault to 10 seconds. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer periodSeconds; + + public Integer getPeriodSeconds() { + return periodSeconds; + } + + public void setPeriodSeconds(Integer periodSeconds) { + this.periodSeconds = periodSeconds; + } + + /** + * Minimum consecutive successes for the probe to be considered successful after having failed. + * Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("successThreshold") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Minimum consecutive successes for the probe to be considered successful after having failed.\nDefaults to 1. Must be 1 for liveness and startup. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer successThreshold; + + public Integer getSuccessThreshold() { + return successThreshold; + } + + public void setSuccessThreshold(Integer successThreshold) { + this.successThreshold = successThreshold; + } + + /** + * TCPSocket specifies a connection to a TCP port. + */ + @com.fasterxml.jackson.annotation.JsonProperty("tcpSocket") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TCPSocket specifies a connection to a TCP port.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.probes.TcpSocket tcpSocket; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.probes.TcpSocket getTcpSocket() { + return tcpSocket; + } + + public void setTcpSocket(io.openkruise.agents.client.v2.models.sandboxsetspec.probes.TcpSocket tcpSocket) { + this.tcpSocket = tcpSocket; + } + + /** + * Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + * The grace period is the duration in seconds after the processes running in the pod are sent + * a termination signal and the time when the processes are forcibly halted with a kill signal. + * Set this value longer than the expected cleanup time for your process. + * If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + * value overrides the value provided by the pod spec. + * Value must be non-negative integer. The value zero indicates stop immediately via + * the kill signal (no opportunity to shut down). + * This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + * Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + */ + @com.fasterxml.jackson.annotation.JsonProperty("terminationGracePeriodSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\nThe grace period is the duration in seconds after the processes running in the pod are sent\na termination signal and the time when the processes are forcibly halted with a kill signal.\nSet this value longer than the expected cleanup time for your process.\nIf this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\nvalue overrides the value provided by the pod spec.\nValue must be non-negative integer. The value zero indicates stop immediately via\nthe kill signal (no opportunity to shut down).\nThis is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\nMinimum value is 1. spec.terminationGracePeriodSeconds is used if unset.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Long terminationGracePeriodSeconds; + + public Long getTerminationGracePeriodSeconds() { + return terminationGracePeriodSeconds; + } + + public void setTerminationGracePeriodSeconds(Long terminationGracePeriodSeconds) { + this.terminationGracePeriodSeconds = terminationGracePeriodSeconds; + } + + /** + * Number of seconds after which the probe times out. + * Defaults to 1 second. Minimum value is 1. + * More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeoutSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number of seconds after which the probe times out.\nDefaults to 1 second. Minimum value is 1.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer timeoutSeconds; + + public Integer getTimeoutSeconds() { + return timeoutSeconds; + } + + public void setTimeoutSeconds(Integer timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/ScaleStrategy.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/ScaleStrategy.java index 7adcdb7..e36f223 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/ScaleStrategy.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/ScaleStrategy.java @@ -6,13 +6,27 @@ public class ScaleStrategy implements io.fabric8.kubernetes.api.model.KubernetesResource { /** - * The maximum number of sandboxes that can be unavailable for scaled sandboxes. - * This field can control the changes rate of replicas for SandboxSet so as to minimize the impact for users' service. - * The scale will fail if the number of unavailable sandboxes were greater than this MaxUnavailable at scaling up. - * MaxUnavailable works only when scaling up. + * MaxUnavailable caps concurrent physical scale-up operations and serves as + * the startup budget for the ScalingLimited condition. It can be an absolute + * number (ex: 5) or a percentage of desired pods (ex: 10%); percentages are + * rounded up against spec.replicas. If unset or invalid, the controller uses + * the base (equivalent to 100%, i.e. no cap). Scale-down is unaffected. + * + * The physical scale-up budget is charged by startup blockers: sandboxes + * whose Ready condition is False with reason PodCreateFailed or + * StartContainerFailed, sandboxes stuck in Creating/ResourcePending past the + * configured --max-pending-timeout, and sandbox creations that have been + * issued but are not yet observed by the controller (they release their slot + * once observed as healthy Creating sandboxes). Healthy observed Creating + * sandboxes do NOT count against the budget. + * + * The ScalingLimited condition becomes True with reason + * StartupBudgetExhausted when failed plus pending-timeout sandboxes exhaust + * the resolved startup budget. + * MaxUnavailable works only for scale-up. */ @com.fasterxml.jackson.annotation.JsonProperty("maxUnavailable") - @com.fasterxml.jackson.annotation.JsonPropertyDescription("The maximum number of sandboxes that can be unavailable for scaled sandboxes.\nThis field can control the changes rate of replicas for SandboxSet so as to minimize the impact for users' service.\nThe scale will fail if the number of unavailable sandboxes were greater than this MaxUnavailable at scaling up.\nMaxUnavailable works only when scaling up.") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("MaxUnavailable caps concurrent physical scale-up operations and serves as\nthe startup budget for the ScalingLimited condition. It can be an absolute\nnumber (ex: 5) or a percentage of desired pods (ex: 10%); percentages are\nrounded up against spec.replicas. If unset or invalid, the controller uses\nthe base (equivalent to 100%, i.e. no cap). Scale-down is unaffected.\n\nThe physical scale-up budget is charged by startup blockers: sandboxes\nwhose Ready condition is False with reason PodCreateFailed or\nStartContainerFailed, sandboxes stuck in Creating/ResourcePending past the\nconfigured --max-pending-timeout, and sandbox creations that have been\nissued but are not yet observed by the controller (they release their slot\nonce observed as healthy Creating sandboxes). Healthy observed Creating\nsandboxes do NOT count against the budget.\n\nThe ScalingLimited condition becomes True with reason\nStartupBudgetExhausted when failed plus pending-timeout sandboxes exhaust\nthe resolved startup budget.\nMaxUnavailable works only for scale-up.") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private io.fabric8.kubernetes.api.model.IntOrString maxUnavailable; diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Pause.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Pause.java new file mode 100644 index 0000000..883e9a2 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Pause.java @@ -0,0 +1,25 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"whenProbedIdleState"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Pause implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * WhenProbedIdleState pauses the sandbox when a probe's Condition message + * matches MessageRegex for at least ThresholdDuration. + */ + @com.fasterxml.jackson.annotation.JsonProperty("whenProbedIdleState") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("WhenProbedIdleState pauses the sandbox when a probe's Condition message\nmatches MessageRegex for at least ThresholdDuration.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.pause.WhenProbedIdleState whenProbedIdleState; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.pause.WhenProbedIdleState getWhenProbedIdleState() { + return whenProbedIdleState; + } + + public void setWhenProbedIdleState(io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.pause.WhenProbedIdleState whenProbedIdleState) { + this.whenProbedIdleState = whenProbedIdleState; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Resume.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Resume.java new file mode 100644 index 0000000..1f9d101 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/Resume.java @@ -0,0 +1,45 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"onIngressTraffic","whenProbedScheduleTime"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Resume implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + * inbound traffic addressed to it while it is paused. Unlike the probed + * rules this one is event-driven: it needs no probe, it produces no + * Status.Schedules entry, and it is executed by the sandbox-gateway rather + * than by the sandbox controller. + */ + @com.fasterxml.jackson.annotation.JsonProperty("onIngressTraffic") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("OnIngressTraffic resumes the sandbox when the sandbox-gateway receives\ninbound traffic addressed to it while it is paused. Unlike the probed\nrules this one is event-driven: it needs no probe, it produces no\nStatus.Schedules entry, and it is executed by the sandbox-gateway rather\nthan by the sandbox controller.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume.OnIngressTraffic onIngressTraffic; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume.OnIngressTraffic getOnIngressTraffic() { + return onIngressTraffic; + } + + public void setOnIngressTraffic(io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume.OnIngressTraffic onIngressTraffic) { + this.onIngressTraffic = onIngressTraffic; + } + + /** + * WhenProbedScheduleTime resumes the sandbox before a scheduled task + * by parsing the probe's Condition message as a timestamp. + */ + @com.fasterxml.jackson.annotation.JsonProperty("whenProbedScheduleTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("WhenProbedScheduleTime resumes the sandbox before a scheduled task\nby parsing the probe's Condition message as a timestamp.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume.WhenProbedScheduleTime whenProbedScheduleTime; + + public io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume.WhenProbedScheduleTime getWhenProbedScheduleTime() { + return whenProbedScheduleTime; + } + + public void setWhenProbedScheduleTime(io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume.WhenProbedScheduleTime whenProbedScheduleTime) { + this.whenProbedScheduleTime = whenProbedScheduleTime; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/pause/WhenProbedIdleState.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/pause/WhenProbedIdleState.java new file mode 100644 index 0000000..6ea1f79 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/pause/WhenProbedIdleState.java @@ -0,0 +1,70 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.pause; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"messageRegex","probe","thresholdDuration"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class WhenProbedIdleState implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * MessageRegex is a regular expression matched against the probe's + * Condition message (stdout). When the message matches, the Agent is + * considered inactive. When it does not match, the Agent is considered + * active and the sandbox stays Running. + */ + @com.fasterxml.jackson.annotation.JsonProperty("messageRegex") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("MessageRegex is a regular expression matched against the probe's\nCondition message (stdout). When the message matches, the Agent is\nconsidered inactive. When it does not match, the Agent is considered\nactive and the sandbox stays Running.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String messageRegex; + + public String getMessageRegex() { + return messageRegex; + } + + public void setMessageRegex(String messageRegex) { + this.messageRegex = messageRegex; + } + + /** + * Probe is the name of the probe to evaluate for pause decisions. + * Must match a probe name in Spec.Probes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probe") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probe is the name of the probe to evaluate for pause decisions.\nMust match a probe name in Spec.Probes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String probe; + + public String getProbe() { + return probe; + } + + public void setProbe(String probe) { + this.probe = probe; + } + + /** + * ThresholdDuration is the minimum time the probe's Condition message + * must continuously match MessageRegex before the sandbox is paused. + * Measured from the Condition's lastTransitionTime. + * + * It is required: pausing as soon as a single probe report matches would + * drop the smoothing this rule exists for, so there is no meaningful + * default and an unset value is a misconfiguration rather than + * "pause immediately". + */ + @com.fasterxml.jackson.annotation.JsonProperty("thresholdDuration") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ThresholdDuration is the minimum time the probe's Condition message\nmust continuously match MessageRegex before the sandbox is paused.\nMeasured from the Condition's lastTransitionTime.\n\nIt is required: pausing as soon as a single probe report matches would\ndrop the smoothing this rule exists for, so there is no meaningful\ndefault and an unset value is a misconfiguration rather than\n\"pause immediately\".") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String thresholdDuration; + + public String getThresholdDuration() { + return thresholdDuration; + } + + public void setThresholdDuration(String thresholdDuration) { + this.thresholdDuration = thresholdDuration; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/OnIngressTraffic.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/OnIngressTraffic.java new file mode 100644 index 0000000..f9ad420 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/OnIngressTraffic.java @@ -0,0 +1,35 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pauseTimeout"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class OnIngressTraffic implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + * gateway writes Spec.PauseTime = now + PauseTimeout atomically with + * Spec.Paused = false, so the woken sandbox has running time before its + * next auto-pause. It applies only to auto-pause sandboxes (those that + * already carry Spec.PauseTime); never-timeout and shutdown-only + * sandboxes keep their timeout mode unchanged. + * When absent or non-positive, a traffic wake does not re-arm auto-pause: + * the woken sandbox keeps running until it is paused or deleted again. + * A positive value is subject to the resume timeout floor + * (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + * the floor are raised to it so the fresh PauseTime cannot expire while + * the sandbox is still resuming. + */ + @com.fasterxml.jackson.annotation.JsonProperty("pauseTimeout") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the\ngateway writes Spec.PauseTime = now + PauseTimeout atomically with\nSpec.Paused = false, so the woken sandbox has running time before its\nnext auto-pause. It applies only to auto-pause sandboxes (those that\nalready carry Spec.PauseTime); never-timeout and shutdown-only\nsandboxes keep their timeout mode unchanged.\nWhen absent or non-positive, a traffic wake does not re-arm auto-pause:\nthe woken sandbox keeps running until it is paused or deleted again.\nA positive value is subject to the resume timeout floor\n(timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below\nthe floor are raised to it so the fresh PauseTime cannot expire while\nthe sandbox is still resuming.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String pauseTimeout; + + public String getPauseTimeout() { + return pauseTimeout; + } + + public void setPauseTimeout(String pauseTimeout) { + this.pauseTimeout = pauseTimeout; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/WhenProbedScheduleTime.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/WhenProbedScheduleTime.java new file mode 100644 index 0000000..c2f1926 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/autopausepolicy/resume/WhenProbedScheduleTime.java @@ -0,0 +1,85 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.autopausepolicy.resume; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"leadTime","probe","timeFormat"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class WhenProbedScheduleTime implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * LeadTime is the duration before the parsed timestamp at which the + * sandbox should be resumed. For example, if the probe reports the + * next scheduled task at time T and LeadTime is 5m, the sandbox is + * resumed at T - 5m. + */ + @com.fasterxml.jackson.annotation.JsonProperty("leadTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("LeadTime is the duration before the parsed timestamp at which the\nsandbox should be resumed. For example, if the probe reports the\nnext scheduled task at time T and LeadTime is 5m, the sandbox is\nresumed at T - 5m.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String leadTime = "5m"; + + public String getLeadTime() { + return leadTime; + } + + public void setLeadTime(String leadTime) { + this.leadTime = leadTime; + } + + /** + * Probe is the name of the probe to evaluate for resume decisions. + * Must match a probe name in Spec.Probes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probe") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probe is the name of the probe to evaluate for resume decisions.\nMust match a probe name in Spec.Probes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String probe; + + public String getProbe() { + return probe; + } + + public void setProbe(String probe) { + this.probe = probe; + } + + public enum TimeFormat { + + @com.fasterxml.jackson.annotation.JsonProperty("unix") + UNIX("unix"), @com.fasterxml.jackson.annotation.JsonProperty("datetime") + DATETIME("datetime"); + + java.lang.String value; + + TimeFormat(java.lang.String value) { + this.value = value; + } + + @com.fasterxml.jackson.annotation.JsonValue() + public java.lang.String getValue() { + return value; + } + } + + /** + * TimeFormat indicates the format of the probe's Condition message for + * parsing as a timestamp, and defaults to "unix": + * + * unix - seconds since epoch, e.g. "1787040000" + * datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + * + * NextResumeTime is set to the parsed timestamp minus LeadTime. + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeFormat") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TimeFormat indicates the format of the probe's Condition message for\nparsing as a timestamp, and defaults to \"unix\":\n\n unix - seconds since epoch, e.g. \"1787040000\"\n datetime - RFC3339 with offset, e.g. \"2026-08-29T08:00:00+08:00\"\n\nNextResumeTime is set to the parsed timestamp minus LeadTime.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private TimeFormat timeFormat = io.fabric8.kubernetes.client.utils.Serialization.unmarshal("\"unix\"", TimeFormat.class); + + public TimeFormat getTimeFormat() { + return timeFormat; + } + + public void setTimeFormat(TimeFormat timeFormat) { + this.timeFormat = timeFormat; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Exec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Exec.java new file mode 100644 index 0000000..68f2c71 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Exec.java @@ -0,0 +1,28 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"command"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Exec implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Command is the command line to execute inside the container, the working directory for the + * command is root ('/') in the container's filesystem. The command is simply exec'd, it is + * not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + * a shell, you need to explicitly call out to that shell. + * Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + */ + @com.fasterxml.jackson.annotation.JsonProperty("command") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Command is the command line to execute inside the container, the working directory for the\ncommand is root ('/') in the container's filesystem. The command is simply exec'd, it is\nnot run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\na shell, you need to explicitly call out to that shell.\nExit status of 0 is treated as live/healthy and non-zero is unhealthy.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List command; + + public java.util.List getCommand() { + return command; + } + + public void setCommand(java.util.List command) { + this.command = command; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Grpc.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Grpc.java new file mode 100644 index 0000000..65a95b8 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/Grpc.java @@ -0,0 +1,44 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"port","service"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Grpc implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Port number of the gRPC service. Number must be in the range 1 to 65535. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Port number of the gRPC service. Number must be in the range 1 to 65535.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer port; + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + /** + * Service is the name of the service to place in the gRPC HealthCheckRequest + * (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + * + * If this is not specified, the default behavior is defined by gRPC. + */ + @com.fasterxml.jackson.annotation.JsonProperty("service") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Service is the name of the service to place in the gRPC HealthCheckRequest\n(see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\nIf this is not specified, the default behavior is defined by gRPC.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String service = ""; + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/HttpGet.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/HttpGet.java new file mode 100644 index 0000000..5183eae --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/HttpGet.java @@ -0,0 +1,93 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"host","httpHeaders","path","port","scheme"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class HttpGet implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Host name to connect to, defaults to the pod IP. You probably want to set + * "Host" in httpHeaders instead. + */ + @com.fasterxml.jackson.annotation.JsonProperty("host") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Host name to connect to, defaults to the pod IP. You probably want to set\n\"Host\" in httpHeaders instead.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String host; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Custom headers to set in the request. HTTP allows repeated headers. + */ + @com.fasterxml.jackson.annotation.JsonProperty("httpHeaders") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Custom headers to set in the request. HTTP allows repeated headers.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List httpHeaders; + + public java.util.List getHttpHeaders() { + return httpHeaders; + } + + public void setHttpHeaders(java.util.List httpHeaders) { + this.httpHeaders = httpHeaders; + } + + /** + * Path to access on the HTTP server. + */ + @com.fasterxml.jackson.annotation.JsonProperty("path") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Path to access on the HTTP server.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String path; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + /** + * Name or number of the port to access on the container. + * Number must be in the range 1 to 65535. + * Name must be an IANA_SVC_NAME. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name or number of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString port; + + public io.fabric8.kubernetes.api.model.IntOrString getPort() { + return port; + } + + public void setPort(io.fabric8.kubernetes.api.model.IntOrString port) { + this.port = port; + } + + /** + * Scheme to use for connecting to the host. + * Defaults to HTTP. + */ + @com.fasterxml.jackson.annotation.JsonProperty("scheme") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Scheme to use for connecting to the host.\nDefaults to HTTP.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String scheme; + + public String getScheme() { + return scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/TcpSocket.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/TcpSocket.java new file mode 100644 index 0000000..ded6611 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/TcpSocket.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"host","port"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class TcpSocket implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Optional: Host name to connect to, defaults to the pod IP. + */ + @com.fasterxml.jackson.annotation.JsonProperty("host") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Optional: Host name to connect to, defaults to the pod IP.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String host; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Number or name of the port to access on the container. + * Number must be in the range 1 to 65535. + * Name must be an IANA_SVC_NAME. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number or name of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString port; + + public io.fabric8.kubernetes.api.model.IntOrString getPort() { + return port; + } + + public void setPort(io.fabric8.kubernetes.api.model.IntOrString port) { + this.port = port; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/httpget/HttpHeaders.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/httpget/HttpHeaders.java new file mode 100644 index 0000000..f91d25a --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/probes/httpget/HttpHeaders.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.sandboxsetspec.probes.httpget; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"name","value"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class HttpHeaders implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * The header field name. + * This will be canonicalized upon output, so case-variant names will be understood as the same header. + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("The header field name.\nThis will be canonicalized upon output, so case-variant names will be understood as the same header.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * The header field value + */ + @com.fasterxml.jackson.annotation.JsonProperty("value") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("The header field value") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/AutoPausePolicy.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/AutoPausePolicy.java new file mode 100644 index 0000000..c6fa579 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/AutoPausePolicy.java @@ -0,0 +1,40 @@ +package io.openkruise.agents.client.v2.models.sandboxspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pause","resume"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class AutoPausePolicy implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Pause defines the pause policy for the sandbox. + */ + @com.fasterxml.jackson.annotation.JsonProperty("pause") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Pause defines the pause policy for the sandbox.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.Pause pause; + + public io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.Pause getPause() { + return pause; + } + + public void setPause(io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.Pause pause) { + this.pause = pause; + } + + /** + * Resume defines the resume policy for the sandbox. + */ + @com.fasterxml.jackson.annotation.JsonProperty("resume") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Resume defines the resume policy for the sandbox.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.Resume resume; + + public io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.Resume getResume() { + return resume; + } + + public void setResume(io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.Resume resume) { + this.resume = resume; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java new file mode 100644 index 0000000..ecbf882 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java @@ -0,0 +1,218 @@ +package io.openkruise.agents.client.v2.models.sandboxspec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"containerName","exec","failureThreshold","grpc","httpGet","initialDelaySeconds","name","periodSeconds","successThreshold","tcpSocket","terminationGracePeriodSeconds","timeoutSeconds"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Probes implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * ContainerName specifies which container to execute the probe in. + * If empty, defaults to the first container in the pod spec. + */ + @com.fasterxml.jackson.annotation.JsonProperty("containerName") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ContainerName specifies which container to execute the probe in.\nIf empty, defaults to the first container in the pod spec.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String containerName; + + public String getContainerName() { + return containerName; + } + + public void setContainerName(String containerName) { + this.containerName = containerName; + } + + /** + * Exec specifies a command to execute in the container. + */ + @com.fasterxml.jackson.annotation.JsonProperty("exec") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Exec specifies a command to execute in the container.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.probes.Exec exec; + + public io.openkruise.agents.client.v2.models.sandboxspec.probes.Exec getExec() { + return exec; + } + + public void setExec(io.openkruise.agents.client.v2.models.sandboxspec.probes.Exec exec) { + this.exec = exec; + } + + /** + * Minimum consecutive failures for the probe to be considered failed after having succeeded. + * Defaults to 3. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("failureThreshold") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Minimum consecutive failures for the probe to be considered failed after having succeeded.\nDefaults to 3. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer failureThreshold; + + public Integer getFailureThreshold() { + return failureThreshold; + } + + public void setFailureThreshold(Integer failureThreshold) { + this.failureThreshold = failureThreshold; + } + + /** + * GRPC specifies a GRPC HealthCheckRequest. + */ + @com.fasterxml.jackson.annotation.JsonProperty("grpc") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("GRPC specifies a GRPC HealthCheckRequest.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.probes.Grpc grpc; + + public io.openkruise.agents.client.v2.models.sandboxspec.probes.Grpc getGrpc() { + return grpc; + } + + public void setGrpc(io.openkruise.agents.client.v2.models.sandboxspec.probes.Grpc grpc) { + this.grpc = grpc; + } + + /** + * HTTPGet specifies an HTTP GET request to perform. + */ + @com.fasterxml.jackson.annotation.JsonProperty("httpGet") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("HTTPGet specifies an HTTP GET request to perform.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.probes.HttpGet httpGet; + + public io.openkruise.agents.client.v2.models.sandboxspec.probes.HttpGet getHttpGet() { + return httpGet; + } + + public void setHttpGet(io.openkruise.agents.client.v2.models.sandboxspec.probes.HttpGet httpGet) { + this.httpGet = httpGet; + } + + /** + * Number of seconds after the container has started before liveness probes are initiated. + * More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + */ + @com.fasterxml.jackson.annotation.JsonProperty("initialDelaySeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number of seconds after the container has started before liveness probes are initiated.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer initialDelaySeconds; + + public Integer getInitialDelaySeconds() { + return initialDelaySeconds; + } + + public void setInitialDelaySeconds(Integer initialDelaySeconds) { + this.initialDelaySeconds = initialDelaySeconds; + } + + /** + * Name is the unique identifier for this probe within the sandbox. + * Probe results are written to a Condition with type "agents.kruise.io/". + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the unique identifier for this probe within the sandbox.\nProbe results are written to a Condition with type \"agents.kruise.io/\".") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * How often (in seconds) to perform the probe. + * Default to 10 seconds. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("periodSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("How often (in seconds) to perform the probe.\nDefault to 10 seconds. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer periodSeconds; + + public Integer getPeriodSeconds() { + return periodSeconds; + } + + public void setPeriodSeconds(Integer periodSeconds) { + this.periodSeconds = periodSeconds; + } + + /** + * Minimum consecutive successes for the probe to be considered successful after having failed. + * Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("successThreshold") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Minimum consecutive successes for the probe to be considered successful after having failed.\nDefaults to 1. Must be 1 for liveness and startup. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer successThreshold; + + public Integer getSuccessThreshold() { + return successThreshold; + } + + public void setSuccessThreshold(Integer successThreshold) { + this.successThreshold = successThreshold; + } + + /** + * TCPSocket specifies a connection to a TCP port. + */ + @com.fasterxml.jackson.annotation.JsonProperty("tcpSocket") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TCPSocket specifies a connection to a TCP port.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.probes.TcpSocket tcpSocket; + + public io.openkruise.agents.client.v2.models.sandboxspec.probes.TcpSocket getTcpSocket() { + return tcpSocket; + } + + public void setTcpSocket(io.openkruise.agents.client.v2.models.sandboxspec.probes.TcpSocket tcpSocket) { + this.tcpSocket = tcpSocket; + } + + /** + * Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + * The grace period is the duration in seconds after the processes running in the pod are sent + * a termination signal and the time when the processes are forcibly halted with a kill signal. + * Set this value longer than the expected cleanup time for your process. + * If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + * value overrides the value provided by the pod spec. + * Value must be non-negative integer. The value zero indicates stop immediately via + * the kill signal (no opportunity to shut down). + * This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + * Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + */ + @com.fasterxml.jackson.annotation.JsonProperty("terminationGracePeriodSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\nThe grace period is the duration in seconds after the processes running in the pod are sent\na termination signal and the time when the processes are forcibly halted with a kill signal.\nSet this value longer than the expected cleanup time for your process.\nIf this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\nvalue overrides the value provided by the pod spec.\nValue must be non-negative integer. The value zero indicates stop immediately via\nthe kill signal (no opportunity to shut down).\nThis is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\nMinimum value is 1. spec.terminationGracePeriodSeconds is used if unset.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Long terminationGracePeriodSeconds; + + public Long getTerminationGracePeriodSeconds() { + return terminationGracePeriodSeconds; + } + + public void setTerminationGracePeriodSeconds(Long terminationGracePeriodSeconds) { + this.terminationGracePeriodSeconds = terminationGracePeriodSeconds; + } + + /** + * Number of seconds after which the probe times out. + * Defaults to 1 second. Minimum value is 1. + * More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeoutSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number of seconds after which the probe times out.\nDefaults to 1 second. Minimum value is 1.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer timeoutSeconds; + + public Integer getTimeoutSeconds() { + return timeoutSeconds; + } + + public void setTimeoutSeconds(Integer timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Pause.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Pause.java new file mode 100644 index 0000000..138234f --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Pause.java @@ -0,0 +1,25 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"whenProbedIdleState"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Pause implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * WhenProbedIdleState pauses the sandbox when a probe's Condition message + * matches MessageRegex for at least ThresholdDuration. + */ + @com.fasterxml.jackson.annotation.JsonProperty("whenProbedIdleState") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("WhenProbedIdleState pauses the sandbox when a probe's Condition message\nmatches MessageRegex for at least ThresholdDuration.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.pause.WhenProbedIdleState whenProbedIdleState; + + public io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.pause.WhenProbedIdleState getWhenProbedIdleState() { + return whenProbedIdleState; + } + + public void setWhenProbedIdleState(io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.pause.WhenProbedIdleState whenProbedIdleState) { + this.whenProbedIdleState = whenProbedIdleState; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Resume.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Resume.java new file mode 100644 index 0000000..6cf6113 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/Resume.java @@ -0,0 +1,45 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"onIngressTraffic","whenProbedScheduleTime"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Resume implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + * inbound traffic addressed to it while it is paused. Unlike the probed + * rules this one is event-driven: it needs no probe, it produces no + * Status.Schedules entry, and it is executed by the sandbox-gateway rather + * than by the sandbox controller. + */ + @com.fasterxml.jackson.annotation.JsonProperty("onIngressTraffic") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("OnIngressTraffic resumes the sandbox when the sandbox-gateway receives\ninbound traffic addressed to it while it is paused. Unlike the probed\nrules this one is event-driven: it needs no probe, it produces no\nStatus.Schedules entry, and it is executed by the sandbox-gateway rather\nthan by the sandbox controller.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume.OnIngressTraffic onIngressTraffic; + + public io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume.OnIngressTraffic getOnIngressTraffic() { + return onIngressTraffic; + } + + public void setOnIngressTraffic(io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume.OnIngressTraffic onIngressTraffic) { + this.onIngressTraffic = onIngressTraffic; + } + + /** + * WhenProbedScheduleTime resumes the sandbox before a scheduled task + * by parsing the probe's Condition message as a timestamp. + */ + @com.fasterxml.jackson.annotation.JsonProperty("whenProbedScheduleTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("WhenProbedScheduleTime resumes the sandbox before a scheduled task\nby parsing the probe's Condition message as a timestamp.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume.WhenProbedScheduleTime whenProbedScheduleTime; + + public io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume.WhenProbedScheduleTime getWhenProbedScheduleTime() { + return whenProbedScheduleTime; + } + + public void setWhenProbedScheduleTime(io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume.WhenProbedScheduleTime whenProbedScheduleTime) { + this.whenProbedScheduleTime = whenProbedScheduleTime; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/pause/WhenProbedIdleState.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/pause/WhenProbedIdleState.java new file mode 100644 index 0000000..8efb297 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/pause/WhenProbedIdleState.java @@ -0,0 +1,70 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.pause; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"messageRegex","probe","thresholdDuration"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class WhenProbedIdleState implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * MessageRegex is a regular expression matched against the probe's + * Condition message (stdout). When the message matches, the Agent is + * considered inactive. When it does not match, the Agent is considered + * active and the sandbox stays Running. + */ + @com.fasterxml.jackson.annotation.JsonProperty("messageRegex") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("MessageRegex is a regular expression matched against the probe's\nCondition message (stdout). When the message matches, the Agent is\nconsidered inactive. When it does not match, the Agent is considered\nactive and the sandbox stays Running.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String messageRegex; + + public String getMessageRegex() { + return messageRegex; + } + + public void setMessageRegex(String messageRegex) { + this.messageRegex = messageRegex; + } + + /** + * Probe is the name of the probe to evaluate for pause decisions. + * Must match a probe name in Spec.Probes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probe") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probe is the name of the probe to evaluate for pause decisions.\nMust match a probe name in Spec.Probes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String probe; + + public String getProbe() { + return probe; + } + + public void setProbe(String probe) { + this.probe = probe; + } + + /** + * ThresholdDuration is the minimum time the probe's Condition message + * must continuously match MessageRegex before the sandbox is paused. + * Measured from the Condition's lastTransitionTime. + * + * It is required: pausing as soon as a single probe report matches would + * drop the smoothing this rule exists for, so there is no meaningful + * default and an unset value is a misconfiguration rather than + * "pause immediately". + */ + @com.fasterxml.jackson.annotation.JsonProperty("thresholdDuration") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ThresholdDuration is the minimum time the probe's Condition message\nmust continuously match MessageRegex before the sandbox is paused.\nMeasured from the Condition's lastTransitionTime.\n\nIt is required: pausing as soon as a single probe report matches would\ndrop the smoothing this rule exists for, so there is no meaningful\ndefault and an unset value is a misconfiguration rather than\n\"pause immediately\".") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String thresholdDuration; + + public String getThresholdDuration() { + return thresholdDuration; + } + + public void setThresholdDuration(String thresholdDuration) { + this.thresholdDuration = thresholdDuration; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/OnIngressTraffic.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/OnIngressTraffic.java new file mode 100644 index 0000000..e0832af --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/OnIngressTraffic.java @@ -0,0 +1,35 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pauseTimeout"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class OnIngressTraffic implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + * gateway writes Spec.PauseTime = now + PauseTimeout atomically with + * Spec.Paused = false, so the woken sandbox has running time before its + * next auto-pause. It applies only to auto-pause sandboxes (those that + * already carry Spec.PauseTime); never-timeout and shutdown-only + * sandboxes keep their timeout mode unchanged. + * When absent or non-positive, a traffic wake does not re-arm auto-pause: + * the woken sandbox keeps running until it is paused or deleted again. + * A positive value is subject to the resume timeout floor + * (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + * the floor are raised to it so the fresh PauseTime cannot expire while + * the sandbox is still resuming. + */ + @com.fasterxml.jackson.annotation.JsonProperty("pauseTimeout") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the\ngateway writes Spec.PauseTime = now + PauseTimeout atomically with\nSpec.Paused = false, so the woken sandbox has running time before its\nnext auto-pause. It applies only to auto-pause sandboxes (those that\nalready carry Spec.PauseTime); never-timeout and shutdown-only\nsandboxes keep their timeout mode unchanged.\nWhen absent or non-positive, a traffic wake does not re-arm auto-pause:\nthe woken sandbox keeps running until it is paused or deleted again.\nA positive value is subject to the resume timeout floor\n(timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below\nthe floor are raised to it so the fresh PauseTime cannot expire while\nthe sandbox is still resuming.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String pauseTimeout; + + public String getPauseTimeout() { + return pauseTimeout; + } + + public void setPauseTimeout(String pauseTimeout) { + this.pauseTimeout = pauseTimeout; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/WhenProbedScheduleTime.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/WhenProbedScheduleTime.java new file mode 100644 index 0000000..6a6dfdf --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/autopausepolicy/resume/WhenProbedScheduleTime.java @@ -0,0 +1,85 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.autopausepolicy.resume; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"leadTime","probe","timeFormat"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class WhenProbedScheduleTime implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * LeadTime is the duration before the parsed timestamp at which the + * sandbox should be resumed. For example, if the probe reports the + * next scheduled task at time T and LeadTime is 5m, the sandbox is + * resumed at T - 5m. + */ + @com.fasterxml.jackson.annotation.JsonProperty("leadTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("LeadTime is the duration before the parsed timestamp at which the\nsandbox should be resumed. For example, if the probe reports the\nnext scheduled task at time T and LeadTime is 5m, the sandbox is\nresumed at T - 5m.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String leadTime = "5m"; + + public String getLeadTime() { + return leadTime; + } + + public void setLeadTime(String leadTime) { + this.leadTime = leadTime; + } + + /** + * Probe is the name of the probe to evaluate for resume decisions. + * Must match a probe name in Spec.Probes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probe") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probe is the name of the probe to evaluate for resume decisions.\nMust match a probe name in Spec.Probes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String probe; + + public String getProbe() { + return probe; + } + + public void setProbe(String probe) { + this.probe = probe; + } + + public enum TimeFormat { + + @com.fasterxml.jackson.annotation.JsonProperty("unix") + UNIX("unix"), @com.fasterxml.jackson.annotation.JsonProperty("datetime") + DATETIME("datetime"); + + java.lang.String value; + + TimeFormat(java.lang.String value) { + this.value = value; + } + + @com.fasterxml.jackson.annotation.JsonValue() + public java.lang.String getValue() { + return value; + } + } + + /** + * TimeFormat indicates the format of the probe's Condition message for + * parsing as a timestamp, and defaults to "unix": + * + * unix - seconds since epoch, e.g. "1787040000" + * datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + * + * NextResumeTime is set to the parsed timestamp minus LeadTime. + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeFormat") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TimeFormat indicates the format of the probe's Condition message for\nparsing as a timestamp, and defaults to \"unix\":\n\n unix - seconds since epoch, e.g. \"1787040000\"\n datetime - RFC3339 with offset, e.g. \"2026-08-29T08:00:00+08:00\"\n\nNextResumeTime is set to the parsed timestamp minus LeadTime.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private TimeFormat timeFormat = io.fabric8.kubernetes.client.utils.Serialization.unmarshal("\"unix\"", TimeFormat.class); + + public TimeFormat getTimeFormat() { + return timeFormat; + } + + public void setTimeFormat(TimeFormat timeFormat) { + this.timeFormat = timeFormat; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Exec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Exec.java new file mode 100644 index 0000000..c93b0e8 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Exec.java @@ -0,0 +1,28 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"command"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Exec implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Command is the command line to execute inside the container, the working directory for the + * command is root ('/') in the container's filesystem. The command is simply exec'd, it is + * not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + * a shell, you need to explicitly call out to that shell. + * Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + */ + @com.fasterxml.jackson.annotation.JsonProperty("command") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Command is the command line to execute inside the container, the working directory for the\ncommand is root ('/') in the container's filesystem. The command is simply exec'd, it is\nnot run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\na shell, you need to explicitly call out to that shell.\nExit status of 0 is treated as live/healthy and non-zero is unhealthy.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List command; + + public java.util.List getCommand() { + return command; + } + + public void setCommand(java.util.List command) { + this.command = command; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Grpc.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Grpc.java new file mode 100644 index 0000000..be2f9db --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/Grpc.java @@ -0,0 +1,44 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"port","service"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Grpc implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Port number of the gRPC service. Number must be in the range 1 to 65535. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Port number of the gRPC service. Number must be in the range 1 to 65535.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer port; + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + /** + * Service is the name of the service to place in the gRPC HealthCheckRequest + * (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + * + * If this is not specified, the default behavior is defined by gRPC. + */ + @com.fasterxml.jackson.annotation.JsonProperty("service") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Service is the name of the service to place in the gRPC HealthCheckRequest\n(see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\nIf this is not specified, the default behavior is defined by gRPC.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String service = ""; + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/HttpGet.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/HttpGet.java new file mode 100644 index 0000000..0ec0ea6 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/HttpGet.java @@ -0,0 +1,93 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"host","httpHeaders","path","port","scheme"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class HttpGet implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Host name to connect to, defaults to the pod IP. You probably want to set + * "Host" in httpHeaders instead. + */ + @com.fasterxml.jackson.annotation.JsonProperty("host") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Host name to connect to, defaults to the pod IP. You probably want to set\n\"Host\" in httpHeaders instead.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String host; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Custom headers to set in the request. HTTP allows repeated headers. + */ + @com.fasterxml.jackson.annotation.JsonProperty("httpHeaders") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Custom headers to set in the request. HTTP allows repeated headers.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List httpHeaders; + + public java.util.List getHttpHeaders() { + return httpHeaders; + } + + public void setHttpHeaders(java.util.List httpHeaders) { + this.httpHeaders = httpHeaders; + } + + /** + * Path to access on the HTTP server. + */ + @com.fasterxml.jackson.annotation.JsonProperty("path") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Path to access on the HTTP server.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String path; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + /** + * Name or number of the port to access on the container. + * Number must be in the range 1 to 65535. + * Name must be an IANA_SVC_NAME. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name or number of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString port; + + public io.fabric8.kubernetes.api.model.IntOrString getPort() { + return port; + } + + public void setPort(io.fabric8.kubernetes.api.model.IntOrString port) { + this.port = port; + } + + /** + * Scheme to use for connecting to the host. + * Defaults to HTTP. + */ + @com.fasterxml.jackson.annotation.JsonProperty("scheme") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Scheme to use for connecting to the host.\nDefaults to HTTP.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String scheme; + + public String getScheme() { + return scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/TcpSocket.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/TcpSocket.java new file mode 100644 index 0000000..e4b09a0 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/TcpSocket.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"host","port"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class TcpSocket implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Optional: Host name to connect to, defaults to the pod IP. + */ + @com.fasterxml.jackson.annotation.JsonProperty("host") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Optional: Host name to connect to, defaults to the pod IP.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String host; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Number or name of the port to access on the container. + * Number must be in the range 1 to 65535. + * Name must be an IANA_SVC_NAME. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number or name of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString port; + + public io.fabric8.kubernetes.api.model.IntOrString getPort() { + return port; + } + + public void setPort(io.fabric8.kubernetes.api.model.IntOrString port) { + this.port = port; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/httpget/HttpHeaders.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/httpget/HttpHeaders.java new file mode 100644 index 0000000..095f141 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/probes/httpget/HttpHeaders.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.sandboxspec.probes.httpget; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"name","value"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class HttpHeaders implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * The header field name. + * This will be canonicalized upon output, so case-variant names will be understood as the same header. + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("The header field name.\nThis will be canonicalized upon output, so case-variant names will be understood as the same header.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * The header field value + */ + @com.fasterxml.jackson.annotation.JsonProperty("value") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("The header field value") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java new file mode 100644 index 0000000..7589f8e --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java @@ -0,0 +1,65 @@ +package io.openkruise.agents.client.v2.models.sandboxstatus; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"nextPauseTime","nextResumeTime","reason"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Schedules implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * NextPauseTime is when the sandbox is expected to be paused, computed from + * the pause policy once the probed idle threshold is about to be reached. + * It is cleared after a pause is triggered. + */ + @com.fasterxml.jackson.annotation.JsonProperty("nextPauseTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("NextPauseTime is when the sandbox is expected to be paused, computed from\nthe pause policy once the probed idle threshold is about to be reached.\nIt is cleared after a pause is triggered.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.time.ZonedDateTime nextPauseTime; + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + public java.time.ZonedDateTime getNextPauseTime() { + return nextPauseTime; + } + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]") + public void setNextPauseTime(java.time.ZonedDateTime nextPauseTime) { + this.nextPauseTime = nextPauseTime; + } + + /** + * NextResumeTime is when the sandbox is expected to be resumed, computed from + * the resume policy's probed schedule time. It is cleared after a resume is triggered. + */ + @com.fasterxml.jackson.annotation.JsonProperty("nextResumeTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("NextResumeTime is when the sandbox is expected to be resumed, computed from\nthe resume policy's probed schedule time. It is cleared after a resume is triggered.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.time.ZonedDateTime nextResumeTime; + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssVV") + public java.time.ZonedDateTime getNextResumeTime() { + return nextResumeTime; + } + + @com.fasterxml.jackson.annotation.JsonFormat(shape = com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]") + public void setNextResumeTime(java.time.ZonedDateTime nextResumeTime) { + this.nextResumeTime = nextResumeTime; + } + + /** + * Reason indicates which auto-pause rule triggered this schedule entry. + * Examples: "probedIdle" (pause triggered by WhenProbedIdleState), + * "probedSchedule" (resume triggered by WhenProbedScheduleTime). + */ + @com.fasterxml.jackson.annotation.JsonProperty("reason") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Reason indicates which auto-pause rule triggered this schedule entry.\nExamples: \"probedIdle\" (pause triggered by WhenProbedIdleState),\n\"probedSchedule\" (resume triggered by WhenProbedScheduleTime).") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String reason; + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/AutoPausePolicy.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/AutoPausePolicy.java new file mode 100644 index 0000000..103fe47 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/AutoPausePolicy.java @@ -0,0 +1,40 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pause","resume"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class AutoPausePolicy implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Pause defines the pause policy for the sandbox. + */ + @com.fasterxml.jackson.annotation.JsonProperty("pause") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Pause defines the pause policy for the sandbox.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.Pause pause; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.Pause getPause() { + return pause; + } + + public void setPause(io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.Pause pause) { + this.pause = pause; + } + + /** + * Resume defines the resume policy for the sandbox. + */ + @com.fasterxml.jackson.annotation.JsonProperty("resume") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Resume defines the resume policy for the sandbox.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.Resume resume; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.Resume getResume() { + return resume; + } + + public void setResume(io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.Resume resume) { + this.resume = resume; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java new file mode 100644 index 0000000..3e22f30 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java @@ -0,0 +1,218 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"containerName","exec","failureThreshold","grpc","httpGet","initialDelaySeconds","name","periodSeconds","successThreshold","tcpSocket","terminationGracePeriodSeconds","timeoutSeconds"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Probes implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * ContainerName specifies which container to execute the probe in. + * If empty, defaults to the first container in the pod spec. + */ + @com.fasterxml.jackson.annotation.JsonProperty("containerName") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ContainerName specifies which container to execute the probe in.\nIf empty, defaults to the first container in the pod spec.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String containerName; + + public String getContainerName() { + return containerName; + } + + public void setContainerName(String containerName) { + this.containerName = containerName; + } + + /** + * Exec specifies a command to execute in the container. + */ + @com.fasterxml.jackson.annotation.JsonProperty("exec") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Exec specifies a command to execute in the container.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.Exec exec; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.Exec getExec() { + return exec; + } + + public void setExec(io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.Exec exec) { + this.exec = exec; + } + + /** + * Minimum consecutive failures for the probe to be considered failed after having succeeded. + * Defaults to 3. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("failureThreshold") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Minimum consecutive failures for the probe to be considered failed after having succeeded.\nDefaults to 3. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer failureThreshold; + + public Integer getFailureThreshold() { + return failureThreshold; + } + + public void setFailureThreshold(Integer failureThreshold) { + this.failureThreshold = failureThreshold; + } + + /** + * GRPC specifies a GRPC HealthCheckRequest. + */ + @com.fasterxml.jackson.annotation.JsonProperty("grpc") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("GRPC specifies a GRPC HealthCheckRequest.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.Grpc grpc; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.Grpc getGrpc() { + return grpc; + } + + public void setGrpc(io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.Grpc grpc) { + this.grpc = grpc; + } + + /** + * HTTPGet specifies an HTTP GET request to perform. + */ + @com.fasterxml.jackson.annotation.JsonProperty("httpGet") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("HTTPGet specifies an HTTP GET request to perform.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.HttpGet httpGet; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.HttpGet getHttpGet() { + return httpGet; + } + + public void setHttpGet(io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.HttpGet httpGet) { + this.httpGet = httpGet; + } + + /** + * Number of seconds after the container has started before liveness probes are initiated. + * More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + */ + @com.fasterxml.jackson.annotation.JsonProperty("initialDelaySeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number of seconds after the container has started before liveness probes are initiated.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer initialDelaySeconds; + + public Integer getInitialDelaySeconds() { + return initialDelaySeconds; + } + + public void setInitialDelaySeconds(Integer initialDelaySeconds) { + this.initialDelaySeconds = initialDelaySeconds; + } + + /** + * Name is the unique identifier for this probe within the sandbox. + * Probe results are written to a Condition with type "agents.kruise.io/". + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the unique identifier for this probe within the sandbox.\nProbe results are written to a Condition with type \"agents.kruise.io/\".") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * How often (in seconds) to perform the probe. + * Default to 10 seconds. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("periodSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("How often (in seconds) to perform the probe.\nDefault to 10 seconds. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer periodSeconds; + + public Integer getPeriodSeconds() { + return periodSeconds; + } + + public void setPeriodSeconds(Integer periodSeconds) { + this.periodSeconds = periodSeconds; + } + + /** + * Minimum consecutive successes for the probe to be considered successful after having failed. + * Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + */ + @com.fasterxml.jackson.annotation.JsonProperty("successThreshold") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Minimum consecutive successes for the probe to be considered successful after having failed.\nDefaults to 1. Must be 1 for liveness and startup. Minimum value is 1.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer successThreshold; + + public Integer getSuccessThreshold() { + return successThreshold; + } + + public void setSuccessThreshold(Integer successThreshold) { + this.successThreshold = successThreshold; + } + + /** + * TCPSocket specifies a connection to a TCP port. + */ + @com.fasterxml.jackson.annotation.JsonProperty("tcpSocket") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TCPSocket specifies a connection to a TCP port.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.TcpSocket tcpSocket; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.TcpSocket getTcpSocket() { + return tcpSocket; + } + + public void setTcpSocket(io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.TcpSocket tcpSocket) { + this.tcpSocket = tcpSocket; + } + + /** + * Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + * The grace period is the duration in seconds after the processes running in the pod are sent + * a termination signal and the time when the processes are forcibly halted with a kill signal. + * Set this value longer than the expected cleanup time for your process. + * If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + * value overrides the value provided by the pod spec. + * Value must be non-negative integer. The value zero indicates stop immediately via + * the kill signal (no opportunity to shut down). + * This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + * Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + */ + @com.fasterxml.jackson.annotation.JsonProperty("terminationGracePeriodSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\nThe grace period is the duration in seconds after the processes running in the pod are sent\na termination signal and the time when the processes are forcibly halted with a kill signal.\nSet this value longer than the expected cleanup time for your process.\nIf this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\nvalue overrides the value provided by the pod spec.\nValue must be non-negative integer. The value zero indicates stop immediately via\nthe kill signal (no opportunity to shut down).\nThis is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\nMinimum value is 1. spec.terminationGracePeriodSeconds is used if unset.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Long terminationGracePeriodSeconds; + + public Long getTerminationGracePeriodSeconds() { + return terminationGracePeriodSeconds; + } + + public void setTerminationGracePeriodSeconds(Long terminationGracePeriodSeconds) { + this.terminationGracePeriodSeconds = terminationGracePeriodSeconds; + } + + /** + * Number of seconds after which the probe times out. + * Defaults to 1 second. Minimum value is 1. + * More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeoutSeconds") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number of seconds after which the probe times out.\nDefaults to 1 second. Minimum value is 1.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer timeoutSeconds; + + public Integer getTimeoutSeconds() { + return timeoutSeconds; + } + + public void setTimeoutSeconds(Integer timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Pause.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Pause.java new file mode 100644 index 0000000..a06144d --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Pause.java @@ -0,0 +1,25 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"whenProbedIdleState"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Pause implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * WhenProbedIdleState pauses the sandbox when a probe's Condition message + * matches MessageRegex for at least ThresholdDuration. + */ + @com.fasterxml.jackson.annotation.JsonProperty("whenProbedIdleState") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("WhenProbedIdleState pauses the sandbox when a probe's Condition message\nmatches MessageRegex for at least ThresholdDuration.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.pause.WhenProbedIdleState whenProbedIdleState; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.pause.WhenProbedIdleState getWhenProbedIdleState() { + return whenProbedIdleState; + } + + public void setWhenProbedIdleState(io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.pause.WhenProbedIdleState whenProbedIdleState) { + this.whenProbedIdleState = whenProbedIdleState; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Resume.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Resume.java new file mode 100644 index 0000000..35b0c91 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/Resume.java @@ -0,0 +1,45 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"onIngressTraffic","whenProbedScheduleTime"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Resume implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + * inbound traffic addressed to it while it is paused. Unlike the probed + * rules this one is event-driven: it needs no probe, it produces no + * Status.Schedules entry, and it is executed by the sandbox-gateway rather + * than by the sandbox controller. + */ + @com.fasterxml.jackson.annotation.JsonProperty("onIngressTraffic") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("OnIngressTraffic resumes the sandbox when the sandbox-gateway receives\ninbound traffic addressed to it while it is paused. Unlike the probed\nrules this one is event-driven: it needs no probe, it produces no\nStatus.Schedules entry, and it is executed by the sandbox-gateway rather\nthan by the sandbox controller.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume.OnIngressTraffic onIngressTraffic; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume.OnIngressTraffic getOnIngressTraffic() { + return onIngressTraffic; + } + + public void setOnIngressTraffic(io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume.OnIngressTraffic onIngressTraffic) { + this.onIngressTraffic = onIngressTraffic; + } + + /** + * WhenProbedScheduleTime resumes the sandbox before a scheduled task + * by parsing the probe's Condition message as a timestamp. + */ + @com.fasterxml.jackson.annotation.JsonProperty("whenProbedScheduleTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("WhenProbedScheduleTime resumes the sandbox before a scheduled task\nby parsing the probe's Condition message as a timestamp.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume.WhenProbedScheduleTime whenProbedScheduleTime; + + public io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume.WhenProbedScheduleTime getWhenProbedScheduleTime() { + return whenProbedScheduleTime; + } + + public void setWhenProbedScheduleTime(io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume.WhenProbedScheduleTime whenProbedScheduleTime) { + this.whenProbedScheduleTime = whenProbedScheduleTime; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/pause/WhenProbedIdleState.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/pause/WhenProbedIdleState.java new file mode 100644 index 0000000..3956a2d --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/pause/WhenProbedIdleState.java @@ -0,0 +1,70 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.pause; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"messageRegex","probe","thresholdDuration"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class WhenProbedIdleState implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * MessageRegex is a regular expression matched against the probe's + * Condition message (stdout). When the message matches, the Agent is + * considered inactive. When it does not match, the Agent is considered + * active and the sandbox stays Running. + */ + @com.fasterxml.jackson.annotation.JsonProperty("messageRegex") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("MessageRegex is a regular expression matched against the probe's\nCondition message (stdout). When the message matches, the Agent is\nconsidered inactive. When it does not match, the Agent is considered\nactive and the sandbox stays Running.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String messageRegex; + + public String getMessageRegex() { + return messageRegex; + } + + public void setMessageRegex(String messageRegex) { + this.messageRegex = messageRegex; + } + + /** + * Probe is the name of the probe to evaluate for pause decisions. + * Must match a probe name in Spec.Probes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probe") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probe is the name of the probe to evaluate for pause decisions.\nMust match a probe name in Spec.Probes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String probe; + + public String getProbe() { + return probe; + } + + public void setProbe(String probe) { + this.probe = probe; + } + + /** + * ThresholdDuration is the minimum time the probe's Condition message + * must continuously match MessageRegex before the sandbox is paused. + * Measured from the Condition's lastTransitionTime. + * + * It is required: pausing as soon as a single probe report matches would + * drop the smoothing this rule exists for, so there is no meaningful + * default and an unset value is a misconfiguration rather than + * "pause immediately". + */ + @com.fasterxml.jackson.annotation.JsonProperty("thresholdDuration") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("ThresholdDuration is the minimum time the probe's Condition message\nmust continuously match MessageRegex before the sandbox is paused.\nMeasured from the Condition's lastTransitionTime.\n\nIt is required: pausing as soon as a single probe report matches would\ndrop the smoothing this rule exists for, so there is no meaningful\ndefault and an unset value is a misconfiguration rather than\n\"pause immediately\".") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String thresholdDuration; + + public String getThresholdDuration() { + return thresholdDuration; + } + + public void setThresholdDuration(String thresholdDuration) { + this.thresholdDuration = thresholdDuration; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/OnIngressTraffic.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/OnIngressTraffic.java new file mode 100644 index 0000000..5ffcf69 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/OnIngressTraffic.java @@ -0,0 +1,35 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"pauseTimeout"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class OnIngressTraffic implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + * gateway writes Spec.PauseTime = now + PauseTimeout atomically with + * Spec.Paused = false, so the woken sandbox has running time before its + * next auto-pause. It applies only to auto-pause sandboxes (those that + * already carry Spec.PauseTime); never-timeout and shutdown-only + * sandboxes keep their timeout mode unchanged. + * When absent or non-positive, a traffic wake does not re-arm auto-pause: + * the woken sandbox keeps running until it is paused or deleted again. + * A positive value is subject to the resume timeout floor + * (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + * the floor are raised to it so the fresh PauseTime cannot expire while + * the sandbox is still resuming. + */ + @com.fasterxml.jackson.annotation.JsonProperty("pauseTimeout") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the\ngateway writes Spec.PauseTime = now + PauseTimeout atomically with\nSpec.Paused = false, so the woken sandbox has running time before its\nnext auto-pause. It applies only to auto-pause sandboxes (those that\nalready carry Spec.PauseTime); never-timeout and shutdown-only\nsandboxes keep their timeout mode unchanged.\nWhen absent or non-positive, a traffic wake does not re-arm auto-pause:\nthe woken sandbox keeps running until it is paused or deleted again.\nA positive value is subject to the resume timeout floor\n(timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below\nthe floor are raised to it so the fresh PauseTime cannot expire while\nthe sandbox is still resuming.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String pauseTimeout; + + public String getPauseTimeout() { + return pauseTimeout; + } + + public void setPauseTimeout(String pauseTimeout) { + this.pauseTimeout = pauseTimeout; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/WhenProbedScheduleTime.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/WhenProbedScheduleTime.java new file mode 100644 index 0000000..aa2416a --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/autopausepolicy/resume/WhenProbedScheduleTime.java @@ -0,0 +1,85 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.autopausepolicy.resume; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"leadTime","probe","timeFormat"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class WhenProbedScheduleTime implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * LeadTime is the duration before the parsed timestamp at which the + * sandbox should be resumed. For example, if the probe reports the + * next scheduled task at time T and LeadTime is 5m, the sandbox is + * resumed at T - 5m. + */ + @com.fasterxml.jackson.annotation.JsonProperty("leadTime") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("LeadTime is the duration before the parsed timestamp at which the\nsandbox should be resumed. For example, if the probe reports the\nnext scheduled task at time T and LeadTime is 5m, the sandbox is\nresumed at T - 5m.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String leadTime = "5m"; + + public String getLeadTime() { + return leadTime; + } + + public void setLeadTime(String leadTime) { + this.leadTime = leadTime; + } + + /** + * Probe is the name of the probe to evaluate for resume decisions. + * Must match a probe name in Spec.Probes. + */ + @com.fasterxml.jackson.annotation.JsonProperty("probe") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Probe is the name of the probe to evaluate for resume decisions.\nMust match a probe name in Spec.Probes.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String probe; + + public String getProbe() { + return probe; + } + + public void setProbe(String probe) { + this.probe = probe; + } + + public enum TimeFormat { + + @com.fasterxml.jackson.annotation.JsonProperty("unix") + UNIX("unix"), @com.fasterxml.jackson.annotation.JsonProperty("datetime") + DATETIME("datetime"); + + java.lang.String value; + + TimeFormat(java.lang.String value) { + this.value = value; + } + + @com.fasterxml.jackson.annotation.JsonValue() + public java.lang.String getValue() { + return value; + } + } + + /** + * TimeFormat indicates the format of the probe's Condition message for + * parsing as a timestamp, and defaults to "unix": + * + * unix - seconds since epoch, e.g. "1787040000" + * datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + * + * NextResumeTime is set to the parsed timestamp minus LeadTime. + */ + @com.fasterxml.jackson.annotation.JsonProperty("timeFormat") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("TimeFormat indicates the format of the probe's Condition message for\nparsing as a timestamp, and defaults to \"unix\":\n\n unix - seconds since epoch, e.g. \"1787040000\"\n datetime - RFC3339 with offset, e.g. \"2026-08-29T08:00:00+08:00\"\n\nNextResumeTime is set to the parsed timestamp minus LeadTime.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private TimeFormat timeFormat = io.fabric8.kubernetes.client.utils.Serialization.unmarshal("\"unix\"", TimeFormat.class); + + public TimeFormat getTimeFormat() { + return timeFormat; + } + + public void setTimeFormat(TimeFormat timeFormat) { + this.timeFormat = timeFormat; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Exec.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Exec.java new file mode 100644 index 0000000..24a3a67 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Exec.java @@ -0,0 +1,28 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"command"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Exec implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Command is the command line to execute inside the container, the working directory for the + * command is root ('/') in the container's filesystem. The command is simply exec'd, it is + * not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + * a shell, you need to explicitly call out to that shell. + * Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + */ + @com.fasterxml.jackson.annotation.JsonProperty("command") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Command is the command line to execute inside the container, the working directory for the\ncommand is root ('/') in the container's filesystem. The command is simply exec'd, it is\nnot run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\na shell, you need to explicitly call out to that shell.\nExit status of 0 is treated as live/healthy and non-zero is unhealthy.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List command; + + public java.util.List getCommand() { + return command; + } + + public void setCommand(java.util.List command) { + this.command = command; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Grpc.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Grpc.java new file mode 100644 index 0000000..30fe2fa --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/Grpc.java @@ -0,0 +1,44 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"port","service"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class Grpc implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Port number of the gRPC service. Number must be in the range 1 to 65535. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Port number of the gRPC service. Number must be in the range 1 to 65535.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private Integer port; + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + /** + * Service is the name of the service to place in the gRPC HealthCheckRequest + * (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + * + * If this is not specified, the default behavior is defined by gRPC. + */ + @com.fasterxml.jackson.annotation.JsonProperty("service") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Service is the name of the service to place in the gRPC HealthCheckRequest\n(see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\nIf this is not specified, the default behavior is defined by gRPC.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String service = ""; + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/HttpGet.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/HttpGet.java new file mode 100644 index 0000000..a5fc348 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/HttpGet.java @@ -0,0 +1,93 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"host","httpHeaders","path","port","scheme"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class HttpGet implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Host name to connect to, defaults to the pod IP. You probably want to set + * "Host" in httpHeaders instead. + */ + @com.fasterxml.jackson.annotation.JsonProperty("host") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Host name to connect to, defaults to the pod IP. You probably want to set\n\"Host\" in httpHeaders instead.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String host; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Custom headers to set in the request. HTTP allows repeated headers. + */ + @com.fasterxml.jackson.annotation.JsonProperty("httpHeaders") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Custom headers to set in the request. HTTP allows repeated headers.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private java.util.List httpHeaders; + + public java.util.List getHttpHeaders() { + return httpHeaders; + } + + public void setHttpHeaders(java.util.List httpHeaders) { + this.httpHeaders = httpHeaders; + } + + /** + * Path to access on the HTTP server. + */ + @com.fasterxml.jackson.annotation.JsonProperty("path") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Path to access on the HTTP server.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String path; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + /** + * Name or number of the port to access on the container. + * Number must be in the range 1 to 65535. + * Name must be an IANA_SVC_NAME. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name or number of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString port; + + public io.fabric8.kubernetes.api.model.IntOrString getPort() { + return port; + } + + public void setPort(io.fabric8.kubernetes.api.model.IntOrString port) { + this.port = port; + } + + /** + * Scheme to use for connecting to the host. + * Defaults to HTTP. + */ + @com.fasterxml.jackson.annotation.JsonProperty("scheme") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Scheme to use for connecting to the host.\nDefaults to HTTP.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String scheme; + + public String getScheme() { + return scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/TcpSocket.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/TcpSocket.java new file mode 100644 index 0000000..d9f6e45 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/TcpSocket.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"host","port"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class TcpSocket implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * Optional: Host name to connect to, defaults to the pod IP. + */ + @com.fasterxml.jackson.annotation.JsonProperty("host") + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Optional: Host name to connect to, defaults to the pod IP.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String host; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Number or name of the port to access on the container. + * Number must be in the range 1 to 65535. + * Name must be an IANA_SVC_NAME. + */ + @com.fasterxml.jackson.annotation.JsonProperty("port") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("Number or name of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private io.fabric8.kubernetes.api.model.IntOrString port; + + public io.fabric8.kubernetes.api.model.IntOrString getPort() { + return port; + } + + public void setPort(io.fabric8.kubernetes.api.model.IntOrString port) { + this.port = port; + } +} + diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/httpget/HttpHeaders.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/httpget/HttpHeaders.java new file mode 100644 index 0000000..cb95b73 --- /dev/null +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/probes/httpget/HttpHeaders.java @@ -0,0 +1,43 @@ +package io.openkruise.agents.client.v2.models.sandboxtemplatespec.probes.httpget; + +@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) +@com.fasterxml.jackson.annotation.JsonPropertyOrder({"name","value"}) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +public class HttpHeaders implements io.fabric8.kubernetes.api.model.KubernetesResource { + + /** + * The header field name. + * This will be canonicalized upon output, so case-variant names will be understood as the same header. + */ + @com.fasterxml.jackson.annotation.JsonProperty("name") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("The header field name.\nThis will be canonicalized upon output, so case-variant names will be understood as the same header.") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * The header field value + */ + @com.fasterxml.jackson.annotation.JsonProperty("value") + @io.fabric8.generator.annotation.Required() + @com.fasterxml.jackson.annotation.JsonPropertyDescription("The header field value") + @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} + diff --git a/k8s/python/openkruise/agents/models/checkpoint.py b/k8s/python/openkruise/agents/models/checkpoint.py index 8beac42..bee7a62 100644 --- a/k8s/python/openkruise/agents/models/checkpoint.py +++ b/k8s/python/openkruise/agents/models/checkpoint.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: checkpoint_schema.json -# timestamp: 2026-08-27T10:23:17+00:00 +# timestamp: 2026-09-02T06:36:09+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/commit.py b/k8s/python/openkruise/agents/models/commit.py index 2856921..73703f4 100644 --- a/k8s/python/openkruise/agents/models/commit.py +++ b/k8s/python/openkruise/agents/models/commit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: commit_schema.json -# timestamp: 2026-08-27T10:23:17+00:00 +# timestamp: 2026-09-02T06:36:10+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globalsecurityprofile.py b/k8s/python/openkruise/agents/models/globalsecurityprofile.py index 4ec0710..a4707d4 100644 --- a/k8s/python/openkruise/agents/models/globalsecurityprofile.py +++ b/k8s/python/openkruise/agents/models/globalsecurityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globalsecurityprofile_schema.json -# timestamp: 2026-08-27T10:23:18+00:00 +# timestamp: 2026-09-02T06:36:10+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py index f351b4d..c653641 100644 --- a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py +++ b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globaltrafficpolicy_schema.json -# timestamp: 2026-08-27T10:23:18+00:00 +# timestamp: 2026-09-02T06:36:11+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/poolautoscaler.py b/k8s/python/openkruise/agents/models/poolautoscaler.py new file mode 100644 index 0000000..4113def --- /dev/null +++ b/k8s/python/openkruise/agents/models/poolautoscaler.py @@ -0,0 +1,327 @@ +# generated by datamodel-codegen: +# filename: poolautoscaler_schema.json +# timestamp: 2026-09-02T06:36:11+00:00 + +from __future__ import annotations + +from enum import StrEnum + +from kubernetes.client.models import V1ObjectMeta +from pydantic import AwareDatetime, BaseModel, ConfigDict, Field + + +class AppliedCronPolicy(BaseModel): + """ + CronScalingPolicyStatus records the last schedule time for a cron policy. + """ + + lastScheduleTime: AwareDatetime | None = None + """ + LastScheduleTime is the last time the policy was successfully scheduled. + """ + name: str + """ + Name is the cron policy name. + """ + + +class CapacityPolicy(BaseModel): + """ + CapacityPolicy defines the capacity configuration of the target resource pool. + """ + + scaleDown: ScaleDown | None = None + """ + ScaleDown is the scaling rule for scaling down. + """ + scaleUp: ScaleUp | None = None + """ + ScaleUp is the scaling rule for scaling up. + """ + targetAvailable: int | str + """ + TargetAvailable is the desired available replicas. + Can be an absolute number (ex: 5) or a percentage of current replicas (ex: 70%). + When the pool is empty, a percentage target is bootstrapped against + maxReplicas so the pool can seed its initial idle capacity. + """ + tolerance: int | str | None = None + """ + Tolerance is the tolerance between the watermark and desired value under which + no updates are made to the desired number of replicas. + Can be an absolute number (ex: 5) or a percentage (ex: 10%). + If not set, defaults to 10%. + A percentage tolerance is always resolved against the target value: + when targetAvailable is also a percentage, both percentages are combined + first and applied to the pool size; when targetAvailable is an absolute + number, the percentage tolerance is applied to that resolved target + (e.g. targetAvailable=5 with tolerance=10% yields watermarks [4, 6]). + """ + + +class Condition(BaseModel): + """ + Condition contains details for one aspect of the current state of this API Resource. + """ + + lastTransitionTime: AwareDatetime + """ + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + """ + message: str = Field(..., max_length=32768) + """ + message is a human readable message indicating details about the transition. + This may be an empty string. + """ + observedGeneration: int | None = Field(None, ge=0) + """ + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + """ + reason: str = Field( + ..., + max_length=1024, + min_length=1, + pattern="^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + ) + """ + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + """ + status: Status1 + """ + status of the condition, one of True, False, Unknown. + """ + type: str = Field( + ..., + max_length=316, + pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + ) + """ + type of condition in CamelCase or in foo.example.com/CamelCase. + """ + + +class CronPolicy(BaseModel): + """ + CronScalingPolicy defines the cron-based scaling configuration for the resource pool. + """ + + name: str + """ + Name is used to specify the scaling policy. + """ + schedule: str + """ + Schedule is a cron expression that defines when this policy should be executed. + Supports standard cron format with 5 fields (minute hour day month weekday). + """ + targetReplicas: int = Field(..., ge=0) + """ + TargetReplicas is the desired replicas when this policy executes. + """ + timeZone: str | None = None + """ + TimeZone is the time zone name for the given schedule, e.g. "Asia/Shanghai", "UTC". + If not specified, this will default to the time zone of the autoscaler controller manager process. + """ + + +class CurrentCapacity(BaseModel): + """ + CurrentCapacity is the last read state of the capacity used by this autoscaler. + """ + + available: int + """ + Available is current number of available pods managed by this autoscaler. + """ + + +class Kind(StrEnum): + """ + Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + """ + + SandboxSet = "SandboxSet" + + +class PoolAutoscaler(BaseModel): + """ + PoolAutoscaler is the configuration for a warming pool autoscaler, + which automatically manages the replica count of the warming pool + based on the policies specified. + """ + + model_config = ConfigDict(arbitrary_types_allowed=True) + + apiVersion: str | None = None + """ + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + """ + kind: str | None = None + """ + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + """ + metadata: V1ObjectMeta | None = None + spec: Spec | None = None + """ + Spec defines the desired behavior of the autoscaler. + """ + status: Status | None = None + """ + Status is the current information about the autoscaler. + """ + + +class ScaleDown(BaseModel): + """ + ScaleDown is the scaling rule for scaling down. + """ + + stabilizationWindowSeconds: int | None = Field(None, ge=60, le=3600) + """ + StabilizationWindowSeconds is the cooldown period after any scale action before + a scale in this direction is allowed. This is a cooldown model: the first scale + action is immediate, subsequent actions must wait for the window to elapse since + the most recent scale action (in either direction). + Must be >= 60 and <= 3600 (one hour) when set. + Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + least the process-wide Sandbox Pending timeout plus 10 seconds. + Scale-down defaults to 300 seconds when omitted. + """ + + +class ScaleTargetRef(BaseModel): + """ + ScaleTargetRef points to the target warming pool to scale, and is used to select the pods for which instance status + should be collected, as well as to actually change the replica count. + """ + + apiVersion: str | None = None + """ + API version of the referent + """ + kind: Kind + """ + Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + """ + name: str + """ + Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + """ + + +class ScaleUp(BaseModel): + """ + ScaleUp is the scaling rule for scaling up. + """ + + stabilizationWindowSeconds: int | None = Field(None, ge=60, le=3600) + """ + StabilizationWindowSeconds is the cooldown period after any scale action before + a scale in this direction is allowed. This is a cooldown model: the first scale + action is immediate, subsequent actions must wait for the window to elapse since + the most recent scale action (in either direction). + Must be >= 60 and <= 3600 (one hour) when set. + Scale-up defaults to 60 seconds when omitted and is normalized at runtime to at + least the process-wide Sandbox Pending timeout plus 10 seconds. + Scale-down defaults to 300 seconds when omitted. + """ + + +class Spec(BaseModel): + """ + Spec defines the desired behavior of the autoscaler. + """ + + capacityPolicy: CapacityPolicy | None = None + """ + CapacityPolicy defines the capacity configuration of the target resource pool. + """ + cronPolicies: list[CronPolicy] | None = None + """ + CronPolicies is a list of potential cron scaling policies which can be used during scaling. + When both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority. + """ + maxReplicas: int = Field(..., ge=1) + """ + MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. + It cannot be less than minReplicas. + """ + minReplicas: int | None = Field(0, ge=0) + """ + MinReplicas is the lower limit for the number of replicas to which the autoscaler + can scale down. It defaults to 0 pods. + """ + scaleTargetRef: ScaleTargetRef + """ + ScaleTargetRef points to the target warming pool to scale, and is used to select the pods for which instance status + should be collected, as well as to actually change the replica count. + """ + suspend: bool | None = None + """ + Suspend tells the controller to suspend subsequent executions. + Defaults to false. + """ + + +class Status(BaseModel): + """ + Status is the current information about the autoscaler. + """ + + appliedCronPolicies: list[AppliedCronPolicy] | None = None + """ + AppliedCronPolicies is the execution status of cron policies. + """ + conditions: list[Condition] | None = None + """ + Conditions is the set of conditions required for this autoscaler to scale its target. + """ + currentCapacity: CurrentCapacity | None = None + """ + CurrentCapacity is the last read state of the capacity used by this autoscaler. + """ + currentReplicas: int + """ + CurrentReplicas is current number of replicas of pods managed by this autoscaler. + """ + desiredReplicas: int + """ + DesiredReplicas is the desired number of replicas of pods managed by this autoscaler. + """ + lastScaleTime: AwareDatetime | None = None + """ + LastScaleTime is the last time the PoolAutoscaler scaled the number of pods. + """ + observedGeneration: int | None = None + """ + ObservedGeneration is the most recent generation observed by this autoscaler. + """ + suspended: bool | None = None + """ + Suspended indicates whether the autoscaler is currently suspended. + """ + + +class Status1(StrEnum): + """ + status of the condition, one of True, False, Unknown. + """ + + True_ = "True" + False_ = "False" + Unknown = "Unknown" diff --git a/k8s/python/openkruise/agents/models/sandbox.py b/k8s/python/openkruise/agents/models/sandbox.py index 6ab65d9..6ebc56f 100644 --- a/k8s/python/openkruise/agents/models/sandbox.py +++ b/k8s/python/openkruise/agents/models/sandbox.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandbox_schema.json -# timestamp: 2026-08-27T10:23:19+00:00 +# timestamp: 2026-09-02T06:36:12+00:00 from __future__ import annotations @@ -14,6 +14,26 @@ from pydantic import AwareDatetime, BaseModel, ConfigDict, Field +class AutoPausePolicy(BaseModel): + """ + AutoPausePolicy defines when the sandbox controller pauses or resumes + the sandbox. Probe-driven rules reference probes declared in + Spec.Probes and read their results (mirrored from + Pod.Status.Conditions to SandboxStatus.Conditions); the + OnIngressTraffic resume rule is event-driven and does not require a + probe. + """ + + pause: Pause | None = None + """ + Pause defines the pause policy for the sandbox. + """ + resume: Resume | None = None + """ + Resume defines the resume policy for the sandbox. + """ + + class Condition(BaseModel): """ Condition contains details for one aspect of the current state of this API Resource. @@ -79,6 +99,39 @@ class Exec(BaseModel): """ +class Exec2(BaseModel): + """ + Exec specifies a command to execute in the container. + """ + + command: list[str] | None = None + """ + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + """ + + +class Grpc(BaseModel): + """ + GRPC specifies a GRPC HealthCheckRequest. + """ + + port: int + """ + Port number of the gRPC service. Number must be in the range 1 to 65535. + """ + service: str | None = "" + """ + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + """ + + class HibernateStrategy(BaseModel): """ HibernateStrategy configures the storage medium for hibernate state. @@ -91,9 +144,56 @@ class HibernateStrategy(BaseModel): """ +class HttpGet(BaseModel): + """ + HTTPGet specifies an HTTP GET request to perform. + """ + + host: str | None = None + """ + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + """ + httpHeaders: list[HttpHeader] | None = None + """ + Custom headers to set in the request. HTTP allows repeated headers. + """ + path: str | None = None + """ + Path to access on the HTTP server. + """ + port: int | str + """ + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + """ + scheme: str | None = None + """ + Scheme to use for connecting to the host. + Defaults to HTTP. + """ + + +class HttpHeader(BaseModel): + """ + HTTPHeader describes a custom header to be used in HTTP probes + """ + + name: str + """ + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + """ + value: str + """ + The header field value + """ + + class Lifecycle(BaseModel): """ - Lifecycle defines lifecycle hooks for sandbox upgrade. + Lifecycle defines lifecycle hooks for sandbox. """ postUpgrade: PostUpgrade | None = None @@ -108,6 +208,44 @@ class Lifecycle(BaseModel): """ +class OnIngressTraffic(BaseModel): + """ + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + """ + + pauseTimeout: str | None = None + """ + PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + gateway writes Spec.PauseTime = now + PauseTimeout atomically with + Spec.Paused = false, so the woken sandbox has running time before its + next auto-pause. It applies only to auto-pause sandboxes (those that + already carry Spec.PauseTime); never-timeout and shutdown-only + sandboxes keep their timeout mode unchanged. + When absent or non-positive, a traffic wake does not re-arm auto-pause: + the woken sandbox keeps running until it is paused or deleted again. + A positive value is subject to the resume timeout floor + (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + the floor are raised to it so the fresh PauseTime cannot expire while + the sandbox is still resuming. + """ + + +class Pause(BaseModel): + """ + Pause defines the pause policy for the sandbox. + """ + + whenProbedIdleState: WhenProbedIdleState | None = None + """ + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + """ + + class PauseStrategy(BaseModel): """ PauseStrategy configures how a sandbox is paused when spec.paused is true. @@ -187,6 +325,102 @@ class PreUpgrade(BaseModel): """ +class Probe(BaseModel): + """ + Probe defines a named probe that writes its result to a Pod Condition. + Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. + are directly accessible. Currently only exec probes are supported; + other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported + in the future as needed. + """ + + containerName: str | None = None + """ + ContainerName specifies which container to execute the probe in. + If empty, defaults to the first container in the pod spec. + """ + exec: Exec2 | None = None + """ + Exec specifies a command to execute in the container. + """ + failureThreshold: int | None = None + """ + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + """ + grpc: Grpc | None = None + """ + GRPC specifies a GRPC HealthCheckRequest. + """ + httpGet: HttpGet | None = None + """ + HTTPGet specifies an HTTP GET request to perform. + """ + initialDelaySeconds: int | None = None + """ + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + """ + name: str + """ + Name is the unique identifier for this probe within the sandbox. + Probe results are written to a Condition with type "agents.kruise.io/". + """ + periodSeconds: int | None = None + """ + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + """ + successThreshold: int | None = None + """ + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + """ + tcpSocket: TcpSocket | None = None + """ + TCPSocket specifies a connection to a TCP port. + """ + terminationGracePeriodSeconds: int | None = None + """ + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + """ + timeoutSeconds: int | None = None + """ + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + """ + + +class Resume(BaseModel): + """ + Resume defines the resume policy for the sandbox. + """ + + onIngressTraffic: OnIngressTraffic | None = None + """ + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + """ + whenProbedScheduleTime: WhenProbedScheduleTime | None = None + """ + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + """ + + class Runtime(BaseModel): name: str @@ -224,6 +458,33 @@ class Sandbox(BaseModel): """ +class Schedule(BaseModel): + """ + Schedule tracks the upcoming pause/resume timing for the auto-pause controller. + Reason indicates which rule produced the current schedule, NextPauseTime is the + next expected pause time, and NextResumeTime is the next expected resume time. + Both times are cleared once the corresponding action is triggered. + """ + + nextPauseTime: AwareDatetime | None = None + """ + NextPauseTime is when the sandbox is expected to be paused, computed from + the pause policy once the probed idle threshold is about to be reached. + It is cleared after a pause is triggered. + """ + nextResumeTime: AwareDatetime | None = None + """ + NextResumeTime is when the sandbox is expected to be resumed, computed from + the resume policy's probed schedule time. It is cleared after a resume is triggered. + """ + reason: str | None = None + """ + Reason indicates which auto-pause rule triggered this schedule entry. + Examples: "probedIdle" (pause triggered by WhenProbedIdleState), + "probedSchedule" (resume triggered by WhenProbedScheduleTime). + """ + + class Spec(BaseModel): """ spec defines the desired state of Sandbox @@ -231,9 +492,18 @@ class Spec(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True) + autoPausePolicy: AutoPausePolicy | None = None + """ + AutoPausePolicy defines when the sandbox controller pauses or resumes + the sandbox. Probe-driven rules reference probes declared in + Spec.Probes and read their results (mirrored from + Pod.Status.Conditions to SandboxStatus.Conditions); the + OnIngressTraffic resume rule is event-driven and does not require a + probe. + """ lifecycle: Lifecycle | None = None """ - Lifecycle defines lifecycle hooks for sandbox upgrade. + Lifecycle defines lifecycle hooks for sandbox. """ pauseStrategy: PauseStrategy | None = None """ @@ -251,6 +521,19 @@ class Spec(BaseModel): """ PersistentContents indicates resume pod with persistent content, Enum: ip, memory, filesystem """ + probes: list[Probe] | None = None + """ + Probes defines a list of named probes that run periodically while the sandbox + is Running. Each probe writes its result to a Pod Status Condition with + type "agents.kruise.io/". Probes are generic — their semantics (e.g., + "activity detection" vs "cron task detection") are defined by + AutoPausePolicy.Pause/Resume, not by the probe itself. + + Probe execution is delegated to the agent-runtime sidecar via the + PodProbeMarker Serverless protocol (kruise.io/podprobe annotation). + The controller reads results from Pod.Status.Conditions and mirrors + them to SandboxStatus.Conditions for observability. + """ runtimes: list[Runtime] | None = None """ Runtimes - Runtime configuration for sandbox object @@ -319,6 +602,11 @@ class Status(BaseModel): """ SandboxIp is the ip address allocated to the sandbox. """ + schedules: list[Schedule] | None = None + """ + Schedules contains upcoming scheduled pause/resume events. + Only populated when Spec.AutoPausePolicy.Pause/Resume is configured. + """ updateRevision: str | None = None """ UpdateRevision is the template-hash calculated from `spec.template`. @@ -335,6 +623,23 @@ class Status1(StrEnum): Unknown = "Unknown" +class TcpSocket(BaseModel): + """ + TCPSocket specifies a connection to a TCP port. + """ + + host: str | None = None + """ + Optional: Host name to connect to, defaults to the pod IP. + """ + port: int | str + """ + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + """ + + class TemplateRef(BaseModel): """ TemplateRef references a SandboxTemplate, which will be used to create the sandbox. @@ -356,6 +661,21 @@ class TemplateRef(BaseModel): """ +class TimeFormat(StrEnum): + """ + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + """ + + unix = "unix" + datetime = "datetime" + + class Type(StrEnum): """ Type selects the pause mechanism. @@ -387,3 +707,64 @@ class UpgradePolicy(BaseModel): When empty (default), upgrading is disabled. Supported values: Recreate, CheckpointRestore. """ + + +class WhenProbedIdleState(BaseModel): + """ + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + """ + + messageRegex: str + """ + MessageRegex is a regular expression matched against the probe's + Condition message (stdout). When the message matches, the Agent is + considered inactive. When it does not match, the Agent is considered + active and the sandbox stays Running. + """ + probe: str + """ + Probe is the name of the probe to evaluate for pause decisions. + Must match a probe name in Spec.Probes. + """ + thresholdDuration: str + """ + ThresholdDuration is the minimum time the probe's Condition message + must continuously match MessageRegex before the sandbox is paused. + Measured from the Condition's lastTransitionTime. + + It is required: pausing as soon as a single probe report matches would + drop the smoothing this rule exists for, so there is no meaningful + default and an unset value is a misconfiguration rather than + "pause immediately". + """ + + +class WhenProbedScheduleTime(BaseModel): + """ + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + """ + + leadTime: str | None = "5m" + """ + LeadTime is the duration before the parsed timestamp at which the + sandbox should be resumed. For example, if the probe reports the + next scheduled task at time T and LeadTime is 5m, the sandbox is + resumed at T - 5m. + """ + probe: str + """ + Probe is the name of the probe to evaluate for resume decisions. + Must match a probe name in Spec.Probes. + """ + timeFormat: TimeFormat | None = "unix" + """ + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + """ diff --git a/k8s/python/openkruise/agents/models/sandboxclaim.py b/k8s/python/openkruise/agents/models/sandboxclaim.py index 7d0d078..adf33b2 100644 --- a/k8s/python/openkruise/agents/models/sandboxclaim.py +++ b/k8s/python/openkruise/agents/models/sandboxclaim.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxclaim_schema.json -# timestamp: 2026-08-27T10:23:19+00:00 +# timestamp: 2026-09-02T06:36:11+00:00 from __future__ import annotations @@ -132,15 +132,23 @@ class Resources(BaseModel): limits: dict[str, Limits] | None = None """ Limits specifies the target resource limits for each container. - Only CPU is supported for now. The container's original limit must already be set; - otherwise the value is ignored. + Only CPU and memory are supported; other resource names are rejected. + The container's original limit must already be set; otherwise the value is ignored. + A limit must not be lower than the target request of the same resource. + Memory may only be increased: a target lower than the container's current memory is rejected. + Memory resize may restart the container when the pod template declares + resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. The new value must not change the Pod's QoS class; otherwise the claim will be rejected. """ requests: dict[str, Requests] | None = None """ Requests specifies the target resource requests for each container. - Only CPU is supported for now. The container's original request must already be set; - otherwise the value is ignored. + Only CPU and memory are supported; other resource names are rejected. + The container's original request must already be set; otherwise the value is ignored. + A request must not exceed the target limit of the same resource. + Memory may only be increased: a target lower than the container's current memory is rejected. + Memory resize may restart the container when the pod template declares + resizePolicy: {resourceName: memory, restartPolicy: RestartContainer}. The new value must not change the Pod's QoS class; otherwise the claim will be rejected. """ diff --git a/k8s/python/openkruise/agents/models/sandboxset.py b/k8s/python/openkruise/agents/models/sandboxset.py index 8af91e7..133ac70 100644 --- a/k8s/python/openkruise/agents/models/sandboxset.py +++ b/k8s/python/openkruise/agents/models/sandboxset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxset_schema.json -# timestamp: 2026-08-27T10:23:20+00:00 +# timestamp: 2026-09-02T06:36:12+00:00 from __future__ import annotations @@ -14,6 +14,27 @@ from pydantic import AwareDatetime, BaseModel, ConfigDict, Field +class AutoPausePolicy(BaseModel): + """ + AutoPausePolicy defines the pause/resume decision rules for sandboxes + created from this SandboxSet. Probe-driven rules reference probes by + name (so they are normally set together with spec.probes); the + OnIngressTraffic resume rule is event-driven and does not require a + probe. The policy is copied verbatim onto each created Sandbox and is + part of the update revision hash, so changing it triggers a rolling + update of already-created pool sandboxes. + """ + + pause: Pause | None = None + """ + Pause defines the pause policy for the sandbox. + """ + resume: Resume | None = None + """ + Resume defines the resume policy for the sandbox. + """ + + class Condition(BaseModel): """ Condition contains details for one aspect of the current state of this API Resource. @@ -62,6 +83,39 @@ class Condition(BaseModel): """ +class Exec(BaseModel): + """ + Exec specifies a command to execute in the container. + """ + + command: list[str] | None = None + """ + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + """ + + +class Grpc(BaseModel): + """ + GRPC specifies a GRPC HealthCheckRequest. + """ + + port: int + """ + Port number of the gRPC service. Number must be in the range 1 to 65535. + """ + service: str | None = "" + """ + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + """ + + class HibernateStrategy(BaseModel): """ HibernateStrategy configures the storage medium for hibernate state. @@ -74,6 +128,91 @@ class HibernateStrategy(BaseModel): """ +class HttpGet(BaseModel): + """ + HTTPGet specifies an HTTP GET request to perform. + """ + + host: str | None = None + """ + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + """ + httpHeaders: list[HttpHeader] | None = None + """ + Custom headers to set in the request. HTTP allows repeated headers. + """ + path: str | None = None + """ + Path to access on the HTTP server. + """ + port: int | str + """ + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + """ + scheme: str | None = None + """ + Scheme to use for connecting to the host. + Defaults to HTTP. + """ + + +class HttpHeader(BaseModel): + """ + HTTPHeader describes a custom header to be used in HTTP probes + """ + + name: str + """ + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + """ + value: str + """ + The header field value + """ + + +class OnIngressTraffic(BaseModel): + """ + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + """ + + pauseTimeout: str | None = None + """ + PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + gateway writes Spec.PauseTime = now + PauseTimeout atomically with + Spec.Paused = false, so the woken sandbox has running time before its + next auto-pause. It applies only to auto-pause sandboxes (those that + already carry Spec.PauseTime); never-timeout and shutdown-only + sandboxes keep their timeout mode unchanged. + When absent or non-positive, a traffic wake does not re-arm auto-pause: + the woken sandbox keeps running until it is paused or deleted again. + A positive value is subject to the resume timeout floor + (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + the floor are raised to it so the fresh PauseTime cannot expire while + the sandbox is still resuming. + """ + + +class Pause(BaseModel): + """ + Pause defines the pause policy for the sandbox. + """ + + whenProbedIdleState: WhenProbedIdleState | None = None + """ + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + """ + + class PauseStrategy(BaseModel): """ PauseStrategy configures how sandboxes created from this SandboxSet are @@ -93,6 +232,102 @@ class PauseStrategy(BaseModel): """ +class Probe(BaseModel): + """ + Probe defines a named probe that writes its result to a Pod Condition. + Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. + are directly accessible. Currently only exec probes are supported; + other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported + in the future as needed. + """ + + containerName: str | None = None + """ + ContainerName specifies which container to execute the probe in. + If empty, defaults to the first container in the pod spec. + """ + exec: Exec | None = None + """ + Exec specifies a command to execute in the container. + """ + failureThreshold: int | None = None + """ + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + """ + grpc: Grpc | None = None + """ + GRPC specifies a GRPC HealthCheckRequest. + """ + httpGet: HttpGet | None = None + """ + HTTPGet specifies an HTTP GET request to perform. + """ + initialDelaySeconds: int | None = None + """ + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + """ + name: str + """ + Name is the unique identifier for this probe within the sandbox. + Probe results are written to a Condition with type "agents.kruise.io/". + """ + periodSeconds: int | None = None + """ + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + """ + successThreshold: int | None = None + """ + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + """ + tcpSocket: TcpSocket | None = None + """ + TCPSocket specifies a connection to a TCP port. + """ + terminationGracePeriodSeconds: int | None = None + """ + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + """ + timeoutSeconds: int | None = None + """ + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + """ + + +class Resume(BaseModel): + """ + Resume defines the resume policy for the sandbox. + """ + + onIngressTraffic: OnIngressTraffic | None = None + """ + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + """ + whenProbedScheduleTime: WhenProbedScheduleTime | None = None + """ + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + """ + + class Runtime(BaseModel): name: str @@ -138,10 +373,24 @@ class ScaleStrategy(BaseModel): maxUnavailable: int | str | None = None """ - The maximum number of sandboxes that can be unavailable for scaled sandboxes. - This field can control the changes rate of replicas for SandboxSet so as to minimize the impact for users' service. - The scale will fail if the number of unavailable sandboxes were greater than this MaxUnavailable at scaling up. - MaxUnavailable works only when scaling up. + MaxUnavailable caps concurrent physical scale-up operations and serves as + the startup budget for the ScalingLimited condition. It can be an absolute + number (ex: 5) or a percentage of desired pods (ex: 10%); percentages are + rounded up against spec.replicas. If unset or invalid, the controller uses + the base (equivalent to 100%, i.e. no cap). Scale-down is unaffected. + + The physical scale-up budget is charged by startup blockers: sandboxes + whose Ready condition is False with reason PodCreateFailed or + StartContainerFailed, sandboxes stuck in Creating/ResourcePending past the + configured --max-pending-timeout, and sandbox creations that have been + issued but are not yet observed by the controller (they release their slot + once observed as healthy Creating sandboxes). Healthy observed Creating + sandboxes do NOT count against the budget. + + The ScalingLimited condition becomes True with reason + StartupBudgetExhausted when failed plus pending-timeout sandboxes exhaust + the resolved startup budget. + MaxUnavailable works only for scale-up. """ @@ -152,6 +401,16 @@ class Spec(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True) + autoPausePolicy: AutoPausePolicy | None = None + """ + AutoPausePolicy defines the pause/resume decision rules for sandboxes + created from this SandboxSet. Probe-driven rules reference probes by + name (so they are normally set together with spec.probes); the + OnIngressTraffic resume rule is event-driven and does not require a + probe. The policy is copied verbatim onto each created Sandbox and is + part of the update revision hash, so changing it triggers a rolling + update of already-created pool sandboxes. + """ pauseStrategy: PauseStrategy | None = None """ PauseStrategy configures how sandboxes created from this SandboxSet are @@ -163,6 +422,13 @@ class Spec(BaseModel): """ PersistentContents indicates resume pod with persistent content, Enum: ip, memory, filesystem """ + probes: list[Probe] | None = None + """ + Probes defines the named probes that sandboxes created from this SandboxSet + run while they are Running. It is copied verbatim onto each created Sandbox + and is part of the update revision hash, so changing it triggers a rolling + update of already-created pool sandboxes. + """ replicas: int """ Replicas is the number of unused sandboxes, including available and creating ones. @@ -234,7 +500,8 @@ class Status(BaseModel): updateRevision: str | None = None """ UpdateRevision is the FNV-32 hash computed from spec.template, - spec.persistentContents, spec.runtimes, and spec.pauseStrategy. + spec.persistentContents, spec.runtimes, spec.pauseStrategy, + spec.probes, and spec.autoPausePolicy. It represents the latest desired template version. """ updatedAvailableReplicas: int | None = None @@ -257,6 +524,23 @@ class Status1(StrEnum): Unknown = "Unknown" +class TcpSocket(BaseModel): + """ + TCPSocket specifies a connection to a TCP port. + """ + + host: str | None = None + """ + Optional: Host name to connect to, defaults to the pod IP. + """ + port: int | str + """ + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + """ + + class TemplateRef(BaseModel): """ TemplateRef references a SandboxTemplate, which will be used to create the sandbox. @@ -278,6 +562,21 @@ class TemplateRef(BaseModel): """ +class TimeFormat(StrEnum): + """ + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + """ + + unix = "unix" + datetime = "datetime" + + class Type(StrEnum): """ Type selects the pause mechanism. @@ -300,3 +599,64 @@ class UpdateStrategy(BaseModel): Absolute number is calculated from percentage by rounding down. Default is 20%. """ + + +class WhenProbedIdleState(BaseModel): + """ + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + """ + + messageRegex: str + """ + MessageRegex is a regular expression matched against the probe's + Condition message (stdout). When the message matches, the Agent is + considered inactive. When it does not match, the Agent is considered + active and the sandbox stays Running. + """ + probe: str + """ + Probe is the name of the probe to evaluate for pause decisions. + Must match a probe name in Spec.Probes. + """ + thresholdDuration: str + """ + ThresholdDuration is the minimum time the probe's Condition message + must continuously match MessageRegex before the sandbox is paused. + Measured from the Condition's lastTransitionTime. + + It is required: pausing as soon as a single probe report matches would + drop the smoothing this rule exists for, so there is no meaningful + default and an unset value is a misconfiguration rather than + "pause immediately". + """ + + +class WhenProbedScheduleTime(BaseModel): + """ + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + """ + + leadTime: str | None = "5m" + """ + LeadTime is the duration before the parsed timestamp at which the + sandbox should be resumed. For example, if the probe reports the + next scheduled task at time T and LeadTime is 5m, the sandbox is + resumed at T - 5m. + """ + probe: str + """ + Probe is the name of the probe to evaluate for resume decisions. + Must match a probe name in Spec.Probes. + """ + timeFormat: TimeFormat | None = "unix" + """ + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + """ diff --git a/k8s/python/openkruise/agents/models/sandboxtemplate.py b/k8s/python/openkruise/agents/models/sandboxtemplate.py index ef27a2d..9ff3f44 100644 --- a/k8s/python/openkruise/agents/models/sandboxtemplate.py +++ b/k8s/python/openkruise/agents/models/sandboxtemplate.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxtemplate_schema.json -# timestamp: 2026-08-27T10:23:20+00:00 +# timestamp: 2026-09-02T06:36:13+00:00 from __future__ import annotations @@ -14,6 +14,57 @@ from pydantic import BaseModel, ConfigDict +class AutoPausePolicy(BaseModel): + """ + AutoPausePolicy defines the pause/resume decision rules for sandboxes + created from this template. It is only informational when a SandboxSet uses + spec.templateRef: SandboxSetSpec.AutoPausePolicy always takes precedence and + is what actually reaches created Sandboxes. + """ + + pause: Pause | None = None + """ + Pause defines the pause policy for the sandbox. + """ + resume: Resume | None = None + """ + Resume defines the resume policy for the sandbox. + """ + + +class Exec(BaseModel): + """ + Exec specifies a command to execute in the container. + """ + + command: list[str] | None = None + """ + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + """ + + +class Grpc(BaseModel): + """ + GRPC specifies a GRPC HealthCheckRequest. + """ + + port: int + """ + Port number of the gRPC service. Number must be in the range 1 to 65535. + """ + service: str | None = "" + """ + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + If this is not specified, the default behavior is defined by gRPC. + """ + + class HibernateStrategy(BaseModel): """ HibernateStrategy configures the storage medium for hibernate state. @@ -26,6 +77,91 @@ class HibernateStrategy(BaseModel): """ +class HttpGet(BaseModel): + """ + HTTPGet specifies an HTTP GET request to perform. + """ + + host: str | None = None + """ + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + """ + httpHeaders: list[HttpHeader] | None = None + """ + Custom headers to set in the request. HTTP allows repeated headers. + """ + path: str | None = None + """ + Path to access on the HTTP server. + """ + port: int | str + """ + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + """ + scheme: str | None = None + """ + Scheme to use for connecting to the host. + Defaults to HTTP. + """ + + +class HttpHeader(BaseModel): + """ + HTTPHeader describes a custom header to be used in HTTP probes + """ + + name: str + """ + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + """ + value: str + """ + The header field value + """ + + +class OnIngressTraffic(BaseModel): + """ + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + """ + + pauseTimeout: str | None = None + """ + PauseTimeout is the auto-pause timeout re-armed by a traffic wake: the + gateway writes Spec.PauseTime = now + PauseTimeout atomically with + Spec.Paused = false, so the woken sandbox has running time before its + next auto-pause. It applies only to auto-pause sandboxes (those that + already carry Spec.PauseTime); never-timeout and shutdown-only + sandboxes keep their timeout mode unchanged. + When absent or non-positive, a traffic wake does not re-arm auto-pause: + the woken sandbox keeps running until it is paused or deleted again. + A positive value is subject to the resume timeout floor + (timeout.DefaultMinResumeTimeoutSeconds, currently 300s): values below + the floor are raised to it so the fresh PauseTime cannot expire while + the sandbox is still resuming. + """ + + +class Pause(BaseModel): + """ + Pause defines the pause policy for the sandbox. + """ + + whenProbedIdleState: WhenProbedIdleState | None = None + """ + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + """ + + class PauseStrategy(BaseModel): """ PauseStrategy configures how sandboxes created from this template are @@ -45,6 +181,102 @@ class PauseStrategy(BaseModel): """ +class Probe(BaseModel): + """ + Probe defines a named probe that writes its result to a Pod Condition. + Embeds corev1.Probe inline so that exec/periodSeconds/timeoutSeconds/etc. + are directly accessible. Currently only exec probes are supported; + other corev1.Probe fields (httpGet, tcpSocket, grpc) may be supported + in the future as needed. + """ + + containerName: str | None = None + """ + ContainerName specifies which container to execute the probe in. + If empty, defaults to the first container in the pod spec. + """ + exec: Exec | None = None + """ + Exec specifies a command to execute in the container. + """ + failureThreshold: int | None = None + """ + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + """ + grpc: Grpc | None = None + """ + GRPC specifies a GRPC HealthCheckRequest. + """ + httpGet: HttpGet | None = None + """ + HTTPGet specifies an HTTP GET request to perform. + """ + initialDelaySeconds: int | None = None + """ + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + """ + name: str + """ + Name is the unique identifier for this probe within the sandbox. + Probe results are written to a Condition with type "agents.kruise.io/". + """ + periodSeconds: int | None = None + """ + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + """ + successThreshold: int | None = None + """ + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + """ + tcpSocket: TcpSocket | None = None + """ + TCPSocket specifies a connection to a TCP port. + """ + terminationGracePeriodSeconds: int | None = None + """ + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + """ + timeoutSeconds: int | None = None + """ + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + """ + + +class Resume(BaseModel): + """ + Resume defines the resume policy for the sandbox. + """ + + onIngressTraffic: OnIngressTraffic | None = None + """ + OnIngressTraffic resumes the sandbox when the sandbox-gateway receives + inbound traffic addressed to it while it is paused. Unlike the probed + rules this one is event-driven: it needs no probe, it produces no + Status.Schedules entry, and it is executed by the sandbox-gateway rather + than by the sandbox controller. + """ + whenProbedScheduleTime: WhenProbedScheduleTime | None = None + """ + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + """ + + class Runtime(BaseModel): name: str @@ -85,6 +317,13 @@ class Spec(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True) + autoPausePolicy: AutoPausePolicy | None = None + """ + AutoPausePolicy defines the pause/resume decision rules for sandboxes + created from this template. It is only informational when a SandboxSet uses + spec.templateRef: SandboxSetSpec.AutoPausePolicy always takes precedence and + is what actually reaches created Sandboxes. + """ pauseStrategy: PauseStrategy | None = None """ PauseStrategy configures how sandboxes created from this template are @@ -96,6 +335,13 @@ class Spec(BaseModel): """ PersistentContents indicates resume pod with persistent content, Enum: ip, memory, filesystem """ + probes: list[Probe] | None = None + """ + Probes defines the named probes that sandboxes created from this template + run while they are Running. It is only informational when a SandboxSet uses + spec.templateRef: SandboxSetSpec.Probes always takes precedence and is what + actually reaches created Sandboxes. + """ runtimes: list[Runtime] | None = None """ Runtimes - Runtime configuration for sandbox object @@ -111,6 +357,38 @@ class Spec(BaseModel): """ +class TcpSocket(BaseModel): + """ + TCPSocket specifies a connection to a TCP port. + """ + + host: str | None = None + """ + Optional: Host name to connect to, defaults to the pod IP. + """ + port: int | str + """ + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + """ + + +class TimeFormat(StrEnum): + """ + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + """ + + unix = "unix" + datetime = "datetime" + + class Type(StrEnum): """ Type selects the pause mechanism. @@ -118,3 +396,64 @@ class Type(StrEnum): Stop = "Stop" Hibernate = "Hibernate" + + +class WhenProbedIdleState(BaseModel): + """ + WhenProbedIdleState pauses the sandbox when a probe's Condition message + matches MessageRegex for at least ThresholdDuration. + """ + + messageRegex: str + """ + MessageRegex is a regular expression matched against the probe's + Condition message (stdout). When the message matches, the Agent is + considered inactive. When it does not match, the Agent is considered + active and the sandbox stays Running. + """ + probe: str + """ + Probe is the name of the probe to evaluate for pause decisions. + Must match a probe name in Spec.Probes. + """ + thresholdDuration: str + """ + ThresholdDuration is the minimum time the probe's Condition message + must continuously match MessageRegex before the sandbox is paused. + Measured from the Condition's lastTransitionTime. + + It is required: pausing as soon as a single probe report matches would + drop the smoothing this rule exists for, so there is no meaningful + default and an unset value is a misconfiguration rather than + "pause immediately". + """ + + +class WhenProbedScheduleTime(BaseModel): + """ + WhenProbedScheduleTime resumes the sandbox before a scheduled task + by parsing the probe's Condition message as a timestamp. + """ + + leadTime: str | None = "5m" + """ + LeadTime is the duration before the parsed timestamp at which the + sandbox should be resumed. For example, if the probe reports the + next scheduled task at time T and LeadTime is 5m, the sandbox is + resumed at T - 5m. + """ + probe: str + """ + Probe is the name of the probe to evaluate for resume decisions. + Must match a probe name in Spec.Probes. + """ + timeFormat: TimeFormat | None = "unix" + """ + TimeFormat indicates the format of the probe's Condition message for + parsing as a timestamp, and defaults to "unix": + + unix - seconds since epoch, e.g. "1787040000" + datetime - RFC3339 with offset, e.g. "2026-08-29T08:00:00+08:00" + + NextResumeTime is set to the parsed timestamp minus LeadTime. + """ diff --git a/k8s/python/openkruise/agents/models/sandboxupdateops.py b/k8s/python/openkruise/agents/models/sandboxupdateops.py index c230c3f..1799d21 100644 --- a/k8s/python/openkruise/agents/models/sandboxupdateops.py +++ b/k8s/python/openkruise/agents/models/sandboxupdateops.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxupdateops_schema.json -# timestamp: 2026-08-27T10:23:20+00:00 +# timestamp: 2026-09-02T06:36:13+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/securityprofile.py b/k8s/python/openkruise/agents/models/securityprofile.py index 755a706..8910494 100644 --- a/k8s/python/openkruise/agents/models/securityprofile.py +++ b/k8s/python/openkruise/agents/models/securityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: securityprofile_schema.json -# timestamp: 2026-08-27T10:23:21+00:00 +# timestamp: 2026-09-02T06:36:14+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/trafficpolicy.py b/k8s/python/openkruise/agents/models/trafficpolicy.py index cc7db34..cb42f77 100644 --- a/k8s/python/openkruise/agents/models/trafficpolicy.py +++ b/k8s/python/openkruise/agents/models/trafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: trafficpolicy_schema.json -# timestamp: 2026-08-27T10:23:21+00:00 +# timestamp: 2026-09-02T06:36:14+00:00 from __future__ import annotations From 6857fe18364d61645517d9d37e580b752230570f Mon Sep 17 00:00:00 2001 From: tianhr <344527078@qq.com> Date: Wed, 2 Sep 2026 18:14:01 +0800 Subject: [PATCH 2/5] feat/sync-agents --- agents/crds/agents.kruise.io_poolautoscalers.yaml | 8 ++++++++ agents/crds/agents.kruise.io_sandboxes.yaml | 5 +++++ agents/crds/agents.kruise.io_sandboxsets.yaml | 6 +++++- agents/crds/agents.kruise.io_sandboxtemplates.yaml | 6 +++++- agents/v1alpha1/poolautoscaler_types.go | 7 +++++-- agents/v1alpha1/sandbox_types.go | 4 ++++ agents/v1alpha1/sandboxset_types.go | 3 ++- agents/v1alpha1/sandboxtemplate_types.go | 3 ++- .../agents/client/v2/models/sandboxsetspec/Probes.java | 1 + .../agents/client/v2/models/sandboxspec/Probes.java | 1 + .../client/v2/models/sandboxtemplatespec/Probes.java | 1 + k8s/python/openkruise/agents/models/checkpoint.py | 2 +- k8s/python/openkruise/agents/models/commit.py | 2 +- .../openkruise/agents/models/globalsecurityprofile.py | 2 +- .../openkruise/agents/models/globaltrafficpolicy.py | 2 +- k8s/python/openkruise/agents/models/poolautoscaler.py | 4 ++-- k8s/python/openkruise/agents/models/sandbox.py | 6 ++++-- k8s/python/openkruise/agents/models/sandboxclaim.py | 2 +- k8s/python/openkruise/agents/models/sandboxset.py | 6 ++++-- k8s/python/openkruise/agents/models/sandboxtemplate.py | 8 +++++--- k8s/python/openkruise/agents/models/sandboxupdateops.py | 2 +- k8s/python/openkruise/agents/models/securityprofile.py | 2 +- k8s/python/openkruise/agents/models/trafficpolicy.py | 2 +- 23 files changed, 62 insertions(+), 23 deletions(-) diff --git a/agents/crds/agents.kruise.io_poolautoscalers.yaml b/agents/crds/agents.kruise.io_poolautoscalers.yaml index 27d3f34..abc2b2c 100644 --- a/agents/crds/agents.kruise.io_poolautoscalers.yaml +++ b/agents/crds/agents.kruise.io_poolautoscalers.yaml @@ -164,6 +164,9 @@ spec: - targetReplicas type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map maxReplicas: description: |- MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. @@ -232,6 +235,9 @@ spec: - name type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map conditions: description: Conditions is the set of conditions required for this autoscaler to scale its target. @@ -333,6 +339,8 @@ spec: - currentReplicas - desiredReplicas type: object + required: + - spec type: object served: true storage: true diff --git a/agents/crds/agents.kruise.io_sandboxes.yaml b/agents/crds/agents.kruise.io_sandboxes.yaml index f09f399..5109943 100644 --- a/agents/crds/agents.kruise.io_sandboxes.yaml +++ b/agents/crds/agents.kruise.io_sandboxes.yaml @@ -397,6 +397,8 @@ spec: description: |- Name is the unique identifier for this probe within the sandbox. Probe results are written to a Condition with type "agents.kruise.io/". + maxLength: 299 + pattern: ^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$ type: string periodSeconds: description: |- @@ -454,6 +456,9 @@ spec: - name type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map runtimes: description: Runtimes - Runtime configuration for sandbox object items: diff --git a/agents/crds/agents.kruise.io_sandboxsets.yaml b/agents/crds/agents.kruise.io_sandboxsets.yaml index 2c2fe59..1ae2e08 100644 --- a/agents/crds/agents.kruise.io_sandboxsets.yaml +++ b/agents/crds/agents.kruise.io_sandboxsets.yaml @@ -321,6 +321,8 @@ spec: description: |- Name is the unique identifier for this probe within the sandbox. Probe results are written to a Condition with type "agents.kruise.io/". + maxLength: 299 + pattern: ^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$ type: string periodSeconds: description: |- @@ -378,7 +380,9 @@ spec: - name type: object type: array - x-kubernetes-list-type: atomic + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map replicas: description: Replicas is the number of unused sandboxes, including available and creating ones. diff --git a/agents/crds/agents.kruise.io_sandboxtemplates.yaml b/agents/crds/agents.kruise.io_sandboxtemplates.yaml index 69017a1..f075dbb 100644 --- a/agents/crds/agents.kruise.io_sandboxtemplates.yaml +++ b/agents/crds/agents.kruise.io_sandboxtemplates.yaml @@ -299,6 +299,8 @@ spec: description: |- Name is the unique identifier for this probe within the sandbox. Probe results are written to a Condition with type "agents.kruise.io/". + maxLength: 299 + pattern: ^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$ type: string periodSeconds: description: |- @@ -356,7 +358,9 @@ spec: - name type: object type: array - x-kubernetes-list-type: atomic + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map runtimes: description: Runtimes - Runtime configuration for sandbox object items: diff --git a/agents/v1alpha1/poolautoscaler_types.go b/agents/v1alpha1/poolautoscaler_types.go index db34bda..c6e6b05 100644 --- a/agents/v1alpha1/poolautoscaler_types.go +++ b/agents/v1alpha1/poolautoscaler_types.go @@ -59,6 +59,8 @@ type PoolAutoscalerSpec struct { // CronPolicies is a list of potential cron scaling policies which can be used during scaling. // When both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority. // +optional + // +listType=map + // +listMapKey=name CronPolicies []CronScalingPolicy `json:"cronPolicies,omitempty"` // CapacityPolicy defines the capacity configuration of the target resource pool. @@ -161,6 +163,8 @@ type PoolAutoscalerStatus struct { // AppliedCronPolicies is the execution status of cron policies. // +optional + // +listType=map + // +listMapKey=name AppliedCronPolicies []CronScalingPolicyStatus `json:"appliedCronPolicies,omitempty"` // CurrentCapacity is the last read state of the capacity used by this autoscaler. @@ -224,8 +228,7 @@ type PoolAutoscaler struct { metav1.ObjectMeta `json:"metadata,omitempty,omitzero"` // Spec defines the desired behavior of the autoscaler. - // +optional - Spec PoolAutoscalerSpec `json:"spec,omitempty"` + Spec PoolAutoscalerSpec `json:"spec"` // Status is the current information about the autoscaler. // +optional diff --git a/agents/v1alpha1/sandbox_types.go b/agents/v1alpha1/sandbox_types.go index f18f1b6..b6b91e0 100644 --- a/agents/v1alpha1/sandbox_types.go +++ b/agents/v1alpha1/sandbox_types.go @@ -89,6 +89,8 @@ type SandboxSpec struct { // The controller reads results from Pod.Status.Conditions and mirrors // them to SandboxStatus.Conditions for observability. // +optional + // +listType=map + // +listMapKey=name Probes []Probe `json:"probes,omitempty"` // AutoPausePolicy defines when the sandbox controller pauses or resumes @@ -232,6 +234,8 @@ type Probe struct { // Name is the unique identifier for this probe within the sandbox. // Probe results are written to a Condition with type "agents.kruise.io/". // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=299 + // +kubebuilder:validation:Pattern=`^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$` Name string `json:"name"` // ContainerName specifies which container to execute the probe in. diff --git a/agents/v1alpha1/sandboxset_types.go b/agents/v1alpha1/sandboxset_types.go index c32dd01..fec4f9c 100644 --- a/agents/v1alpha1/sandboxset_types.go +++ b/agents/v1alpha1/sandboxset_types.go @@ -109,7 +109,8 @@ type SandboxSetSpec struct { // and is part of the update revision hash, so changing it triggers a rolling // update of already-created pool sandboxes. // +optional - // +listType=atomic + // +listType=map + // +listMapKey=name Probes []Probe `json:"probes,omitempty"` // AutoPausePolicy defines the pause/resume decision rules for sandboxes diff --git a/agents/v1alpha1/sandboxtemplate_types.go b/agents/v1alpha1/sandboxtemplate_types.go index e543d8d..9cd698f 100644 --- a/agents/v1alpha1/sandboxtemplate_types.go +++ b/agents/v1alpha1/sandboxtemplate_types.go @@ -57,7 +57,8 @@ type SandboxTemplateSpec struct { // spec.templateRef: SandboxSetSpec.Probes always takes precedence and is what // actually reaches created Sandboxes. // +optional - // +listType=atomic + // +listType=map + // +listMapKey=name Probes []Probe `json:"probes,omitempty"` // AutoPausePolicy defines the pause/resume decision rules for sandboxes diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java index 2cc854f..5b496c2 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxsetspec/Probes.java @@ -110,6 +110,7 @@ public void setInitialDelaySeconds(Integer initialDelaySeconds) { */ @com.fasterxml.jackson.annotation.JsonProperty("name") @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Pattern("^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$") @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the unique identifier for this probe within the sandbox.\nProbe results are written to a Condition with type \"agents.kruise.io/\".") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private String name; diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java index ecbf882..8575e79 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxspec/Probes.java @@ -110,6 +110,7 @@ public void setInitialDelaySeconds(Integer initialDelaySeconds) { */ @com.fasterxml.jackson.annotation.JsonProperty("name") @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Pattern("^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$") @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the unique identifier for this probe within the sandbox.\nProbe results are written to a Condition with type \"agents.kruise.io/\".") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private String name; diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java index 3e22f30..349e5af 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxtemplatespec/Probes.java @@ -110,6 +110,7 @@ public void setInitialDelaySeconds(Integer initialDelaySeconds) { */ @com.fasterxml.jackson.annotation.JsonProperty("name") @io.fabric8.generator.annotation.Required() + @io.fabric8.generator.annotation.Pattern("^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$") @com.fasterxml.jackson.annotation.JsonPropertyDescription("Name is the unique identifier for this probe within the sandbox.\nProbe results are written to a Condition with type \"agents.kruise.io/\".") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private String name; diff --git a/k8s/python/openkruise/agents/models/checkpoint.py b/k8s/python/openkruise/agents/models/checkpoint.py index bee7a62..eae63d3 100644 --- a/k8s/python/openkruise/agents/models/checkpoint.py +++ b/k8s/python/openkruise/agents/models/checkpoint.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: checkpoint_schema.json -# timestamp: 2026-09-02T06:36:09+00:00 +# timestamp: 2026-09-02T10:13:25+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/commit.py b/k8s/python/openkruise/agents/models/commit.py index 73703f4..201735c 100644 --- a/k8s/python/openkruise/agents/models/commit.py +++ b/k8s/python/openkruise/agents/models/commit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: commit_schema.json -# timestamp: 2026-09-02T06:36:10+00:00 +# timestamp: 2026-09-02T10:13:25+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globalsecurityprofile.py b/k8s/python/openkruise/agents/models/globalsecurityprofile.py index a4707d4..67bdb82 100644 --- a/k8s/python/openkruise/agents/models/globalsecurityprofile.py +++ b/k8s/python/openkruise/agents/models/globalsecurityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globalsecurityprofile_schema.json -# timestamp: 2026-09-02T06:36:10+00:00 +# timestamp: 2026-09-02T10:13:26+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py index c653641..517083d 100644 --- a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py +++ b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globaltrafficpolicy_schema.json -# timestamp: 2026-09-02T06:36:11+00:00 +# timestamp: 2026-09-02T10:13:26+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/poolautoscaler.py b/k8s/python/openkruise/agents/models/poolautoscaler.py index 4113def..0e709fa 100644 --- a/k8s/python/openkruise/agents/models/poolautoscaler.py +++ b/k8s/python/openkruise/agents/models/poolautoscaler.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: poolautoscaler_schema.json -# timestamp: 2026-09-02T06:36:11+00:00 +# timestamp: 2026-09-02T10:13:26+00:00 from __future__ import annotations @@ -176,7 +176,7 @@ class PoolAutoscaler(BaseModel): More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds """ metadata: V1ObjectMeta | None = None - spec: Spec | None = None + spec: Spec """ Spec defines the desired behavior of the autoscaler. """ diff --git a/k8s/python/openkruise/agents/models/sandbox.py b/k8s/python/openkruise/agents/models/sandbox.py index 6ebc56f..6a5771c 100644 --- a/k8s/python/openkruise/agents/models/sandbox.py +++ b/k8s/python/openkruise/agents/models/sandbox.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandbox_schema.json -# timestamp: 2026-09-02T06:36:12+00:00 +# timestamp: 2026-09-02T10:13:27+00:00 from __future__ import annotations @@ -361,7 +361,9 @@ class Probe(BaseModel): Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes """ - name: str + name: str = Field( + ..., max_length=299, pattern="^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$" + ) """ Name is the unique identifier for this probe within the sandbox. Probe results are written to a Condition with type "agents.kruise.io/". diff --git a/k8s/python/openkruise/agents/models/sandboxclaim.py b/k8s/python/openkruise/agents/models/sandboxclaim.py index adf33b2..ea7502e 100644 --- a/k8s/python/openkruise/agents/models/sandboxclaim.py +++ b/k8s/python/openkruise/agents/models/sandboxclaim.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxclaim_schema.json -# timestamp: 2026-09-02T06:36:11+00:00 +# timestamp: 2026-09-02T10:13:27+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandboxset.py b/k8s/python/openkruise/agents/models/sandboxset.py index 133ac70..425a4f4 100644 --- a/k8s/python/openkruise/agents/models/sandboxset.py +++ b/k8s/python/openkruise/agents/models/sandboxset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxset_schema.json -# timestamp: 2026-09-02T06:36:12+00:00 +# timestamp: 2026-09-02T10:13:28+00:00 from __future__ import annotations @@ -268,7 +268,9 @@ class Probe(BaseModel): Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes """ - name: str + name: str = Field( + ..., max_length=299, pattern="^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$" + ) """ Name is the unique identifier for this probe within the sandbox. Probe results are written to a Condition with type "agents.kruise.io/". diff --git a/k8s/python/openkruise/agents/models/sandboxtemplate.py b/k8s/python/openkruise/agents/models/sandboxtemplate.py index 9ff3f44..b4d161c 100644 --- a/k8s/python/openkruise/agents/models/sandboxtemplate.py +++ b/k8s/python/openkruise/agents/models/sandboxtemplate.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxtemplate_schema.json -# timestamp: 2026-09-02T06:36:13+00:00 +# timestamp: 2026-09-02T10:13:28+00:00 from __future__ import annotations @@ -11,7 +11,7 @@ V1PersistentVolumeClaim, V1PodTemplateSpec, ) -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field class AutoPausePolicy(BaseModel): @@ -217,7 +217,9 @@ class Probe(BaseModel): Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes """ - name: str + name: str = Field( + ..., max_length=299, pattern="^[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?$" + ) """ Name is the unique identifier for this probe within the sandbox. Probe results are written to a Condition with type "agents.kruise.io/". diff --git a/k8s/python/openkruise/agents/models/sandboxupdateops.py b/k8s/python/openkruise/agents/models/sandboxupdateops.py index 1799d21..018a13e 100644 --- a/k8s/python/openkruise/agents/models/sandboxupdateops.py +++ b/k8s/python/openkruise/agents/models/sandboxupdateops.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxupdateops_schema.json -# timestamp: 2026-09-02T06:36:13+00:00 +# timestamp: 2026-09-02T10:13:28+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/securityprofile.py b/k8s/python/openkruise/agents/models/securityprofile.py index 8910494..8e89716 100644 --- a/k8s/python/openkruise/agents/models/securityprofile.py +++ b/k8s/python/openkruise/agents/models/securityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: securityprofile_schema.json -# timestamp: 2026-09-02T06:36:14+00:00 +# timestamp: 2026-09-02T10:13:29+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/trafficpolicy.py b/k8s/python/openkruise/agents/models/trafficpolicy.py index cb42f77..c15b11a 100644 --- a/k8s/python/openkruise/agents/models/trafficpolicy.py +++ b/k8s/python/openkruise/agents/models/trafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: trafficpolicy_schema.json -# timestamp: 2026-09-02T06:36:14+00:00 +# timestamp: 2026-09-02T10:13:29+00:00 from __future__ import annotations From af0626832acc8987076ebf54267633788ffc0303 Mon Sep 17 00:00:00 2001 From: tianhr <344527078@qq.com> Date: Thu, 3 Sep 2026 11:44:29 +0800 Subject: [PATCH 3/5] feat/sync-agents --- .../agents.kruise.io_poolautoscalers.yaml | 1 + agents/crds/agents.kruise.io_sandboxes.yaml | 7 + agents/crds/agents.kruise.io_sandboxsets.yaml | 2 + .../agents.kruise.io_sandboxtemplates.yaml | 2 + agents/v1alpha1/poolautoscaler_types.go | 15 +- agents/v1alpha1/sandbox_types.go | 10 +- agents/v1alpha1/sandboxset_types.go | 1 + agents/v1alpha1/sandboxtemplate_types.go | 1 + agents/v1alpha1/zz_generated.deepcopy.go | 5 - hack/generate_python_sdk.sh | 6 + k8s/codegen/generate_python_init.py | 90 ++++++++ .../openkruise/agents/models/__init__.py | 210 ++++++++++++++++-- 12 files changed, 320 insertions(+), 30 deletions(-) create mode 100644 k8s/codegen/generate_python_init.py diff --git a/agents/crds/agents.kruise.io_poolautoscalers.yaml b/agents/crds/agents.kruise.io_poolautoscalers.yaml index abc2b2c..4b58661 100644 --- a/agents/crds/agents.kruise.io_poolautoscalers.yaml +++ b/agents/crds/agents.kruise.io_poolautoscalers.yaml @@ -163,6 +163,7 @@ spec: - schedule - targetReplicas type: object + maxItems: 20 type: array x-kubernetes-list-map-keys: - name diff --git a/agents/crds/agents.kruise.io_sandboxes.yaml b/agents/crds/agents.kruise.io_sandboxes.yaml index 5109943..1784a11 100644 --- a/agents/crds/agents.kruise.io_sandboxes.yaml +++ b/agents/crds/agents.kruise.io_sandboxes.yaml @@ -86,6 +86,7 @@ spec: Condition message (stdout). When the message matches, the Agent is considered inactive. When it does not match, the Agent is considered active and the sandbox stays Running. + maxLength: 512 type: string probe: description: |- @@ -455,6 +456,7 @@ spec: required: - name type: object + maxItems: 16 type: array x-kubernetes-list-map-keys: - name @@ -663,8 +665,13 @@ spec: Examples: "probedIdle" (pause triggered by WhenProbedIdleState), "probedSchedule" (resume triggered by WhenProbedScheduleTime). type: string + required: + - reason type: object type: array + x-kubernetes-list-map-keys: + - reason + x-kubernetes-list-type: map updateRevision: description: UpdateRevision is the template-hash calculated from `spec.template`. type: string diff --git a/agents/crds/agents.kruise.io_sandboxsets.yaml b/agents/crds/agents.kruise.io_sandboxsets.yaml index 1ae2e08..40471e6 100644 --- a/agents/crds/agents.kruise.io_sandboxsets.yaml +++ b/agents/crds/agents.kruise.io_sandboxsets.yaml @@ -85,6 +85,7 @@ spec: Condition message (stdout). When the message matches, the Agent is considered inactive. When it does not match, the Agent is considered active and the sandbox stays Running. + maxLength: 512 type: string probe: description: |- @@ -379,6 +380,7 @@ spec: required: - name type: object + maxItems: 16 type: array x-kubernetes-list-map-keys: - name diff --git a/agents/crds/agents.kruise.io_sandboxtemplates.yaml b/agents/crds/agents.kruise.io_sandboxtemplates.yaml index f075dbb..ea6cdce 100644 --- a/agents/crds/agents.kruise.io_sandboxtemplates.yaml +++ b/agents/crds/agents.kruise.io_sandboxtemplates.yaml @@ -63,6 +63,7 @@ spec: Condition message (stdout). When the message matches, the Agent is considered inactive. When it does not match, the Agent is considered active and the sandbox stays Running. + maxLength: 512 type: string probe: description: |- @@ -357,6 +358,7 @@ spec: required: - name type: object + maxItems: 16 type: array x-kubernetes-list-map-keys: - name diff --git a/agents/v1alpha1/poolautoscaler_types.go b/agents/v1alpha1/poolautoscaler_types.go index c6e6b05..87b1b24 100644 --- a/agents/v1alpha1/poolautoscaler_types.go +++ b/agents/v1alpha1/poolautoscaler_types.go @@ -61,6 +61,7 @@ type PoolAutoscalerSpec struct { // +optional // +listType=map // +listMapKey=name + // +kubebuilder:validation:MaxItems=20 CronPolicies []CronScalingPolicy `json:"cronPolicies,omitempty"` // CapacityPolicy defines the capacity configuration of the target resource pool. @@ -145,7 +146,7 @@ type CapacityScalingRules struct { type PoolAutoscalerStatus struct { // ObservedGeneration is the most recent generation observed by this autoscaler. // +optional - ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty"` // LastScaleTime is the last time the PoolAutoscaler scaled the number of pods. // +optional @@ -198,12 +199,12 @@ type CapacityStatus struct { type PoolAutoscalerConditionType string const ( - // ScalingActive indicates that the autoscaler is able to scale. - ScalingActive PoolAutoscalerConditionType = "ScalingActive" - // AbleToScale indicates that the autoscaler is able to calculate and set scale. - AbleToScale PoolAutoscalerConditionType = "AbleToScale" - // ScalingLimited indicates that the autoscaler is constrained by min/max bounds. - ScalingLimited PoolAutoscalerConditionType = "ScalingLimited" + // PoolAutoscalerConditionScalingActive indicates that the autoscaler is able to scale. + PoolAutoscalerConditionScalingActive PoolAutoscalerConditionType = "ScalingActive" + // PoolAutoscalerConditionAbleToScale indicates that the autoscaler is able to calculate and set scale. + PoolAutoscalerConditionAbleToScale PoolAutoscalerConditionType = "AbleToScale" + // PoolAutoscalerConditionScalingLimited indicates that the autoscaler is constrained by min/max bounds. + PoolAutoscalerConditionScalingLimited PoolAutoscalerConditionType = "ScalingLimited" ) // +genclient diff --git a/agents/v1alpha1/sandbox_types.go b/agents/v1alpha1/sandbox_types.go index b6b91e0..3e95f12 100644 --- a/agents/v1alpha1/sandbox_types.go +++ b/agents/v1alpha1/sandbox_types.go @@ -91,6 +91,7 @@ type SandboxSpec struct { // +optional // +listType=map // +listMapKey=name + // +kubebuilder:validation:MaxItems=16 Probes []Probe `json:"probes,omitempty"` // AutoPausePolicy defines when the sandbox controller pauses or resumes @@ -311,6 +312,7 @@ type ProbedIdleStateRule struct { // considered inactive. When it does not match, the Agent is considered // active and the sandbox stays Running. // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=512 MessageRegex string `json:"messageRegex"` // ThresholdDuration is the minimum time the probe's Condition message @@ -385,8 +387,8 @@ type Schedule struct { // Reason indicates which auto-pause rule triggered this schedule entry. // Examples: "probedIdle" (pause triggered by WhenProbedIdleState), // "probedSchedule" (resume triggered by WhenProbedScheduleTime). - // +optional - Reason string `json:"reason,omitempty"` + // +required + Reason string `json:"reason"` // NextPauseTime is when the sandbox is expected to be paused, computed from // the pause policy once the probed idle threshold is about to be reached. @@ -471,8 +473,8 @@ type SandboxStatus struct { // Schedules contains upcoming scheduled pause/resume events. // Only populated when Spec.AutoPausePolicy.Pause/Resume is configured. // +optional - // +patchMergeKey=reason - // +patchStrategy=merge + // +listType=map + // +listMapKey=reason Schedules []Schedule `json:"schedules,omitempty"` } diff --git a/agents/v1alpha1/sandboxset_types.go b/agents/v1alpha1/sandboxset_types.go index fec4f9c..954db1f 100644 --- a/agents/v1alpha1/sandboxset_types.go +++ b/agents/v1alpha1/sandboxset_types.go @@ -111,6 +111,7 @@ type SandboxSetSpec struct { // +optional // +listType=map // +listMapKey=name + // +kubebuilder:validation:MaxItems=16 Probes []Probe `json:"probes,omitempty"` // AutoPausePolicy defines the pause/resume decision rules for sandboxes diff --git a/agents/v1alpha1/sandboxtemplate_types.go b/agents/v1alpha1/sandboxtemplate_types.go index 9cd698f..6130951 100644 --- a/agents/v1alpha1/sandboxtemplate_types.go +++ b/agents/v1alpha1/sandboxtemplate_types.go @@ -59,6 +59,7 @@ type SandboxTemplateSpec struct { // +optional // +listType=map // +listMapKey=name + // +kubebuilder:validation:MaxItems=16 Probes []Probe `json:"probes,omitempty"` // AutoPausePolicy defines the pause/resume decision rules for sandboxes diff --git a/agents/v1alpha1/zz_generated.deepcopy.go b/agents/v1alpha1/zz_generated.deepcopy.go index 4c44bef..261a723 100644 --- a/agents/v1alpha1/zz_generated.deepcopy.go +++ b/agents/v1alpha1/zz_generated.deepcopy.go @@ -1145,11 +1145,6 @@ func (in *PoolAutoscalerSpec) DeepCopy() *PoolAutoscalerSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PoolAutoscalerStatus) DeepCopyInto(out *PoolAutoscalerStatus) { *out = *in - if in.ObservedGeneration != nil { - in, out := &in.ObservedGeneration, &out.ObservedGeneration - *out = new(int64) - **out = **in - } if in.LastScaleTime != nil { in, out := &in.LastScaleTime, &out.LastScaleTime *out = (*in).DeepCopy() diff --git a/hack/generate_python_sdk.sh b/hack/generate_python_sdk.sh index a5d9410..c646247 100755 --- a/hack/generate_python_sdk.sh +++ b/hack/generate_python_sdk.sh @@ -94,6 +94,12 @@ for crd_file in "${CRD_SOURCE_DIR}"/*.yaml; do ruff format -q "${output_model}" done +# ── Regenerate package exports ────────────────────────────────────────────── +# Rebuild models/__init__.py so newly added CRDs are re-exported +# automatically (no manual maintenance). +echo "==> Regenerating models/__init__.py exports..." +python3 "${PROJECT_ROOT}/k8s/codegen/generate_python_init.py" "${MODELS_DIR}" + # ── Summary ─────────────────────────────────────────────────────────────────── PY_FILE_COUNT=$(find "${MODELS_DIR}" -name '*.py' ! -name '__init__.py' | wc -l | tr -d ' ') echo "" diff --git a/k8s/codegen/generate_python_init.py b/k8s/codegen/generate_python_init.py new file mode 100644 index 0000000..b0c9092 --- /dev/null +++ b/k8s/codegen/generate_python_init.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +"""Regenerate openkruise/agents/models/__init__.py for the Python SDK. + +Scans every generated model module, locates the CRD root class (the only +top-level class carrying apiVersion + metadata fields) and re-exports it +along with all other top-level classes under a Kind-prefixed alias, e.g. +"Spec as PoolAutoscalerSpec". + +Classes with a numeric suffix (Status1, AuditItem1, Header2 ...) are +datamodel-codegen de-duplication artifacts and are skipped; they remain +importable from their source module directly. + +Usage: + python3 generate_python_init.py +""" + +from __future__ import annotations + +import ast +import re +import sys +from pathlib import Path + +NUMBERED_CLASS = re.compile(r"\d+$") + +HEADER = "# Code generated by hack/generate_python_sdk.sh. DO NOT EDIT." + + +def top_level_classes(path: Path) -> list[tuple[str, set[str]]]: + """Return [(class_name, annotated_field_names)] for every top-level class.""" + tree = ast.parse(path.read_text(encoding="utf-8")) + classes: list[tuple[str, set[str]]] = [] + for node in tree.body: + if isinstance(node, ast.ClassDef): + fields = { + stmt.target.id + for stmt in node.body + if isinstance(stmt, ast.AnnAssign) and isinstance(stmt.target, ast.Name) + } + classes.append((node.name, fields)) + return classes + + +def find_root_class(classes: list[tuple[str, set[str]]]) -> str | None: + """The CRD root object is the class that carries apiVersion + metadata.""" + for name, fields in classes: + if "apiVersion" in fields and "metadata" in fields: + return name + return None + + +def main() -> None: + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(1) + + models_dir = Path(sys.argv[1]) + if not models_dir.is_dir(): + print(f"ERROR: Directory not found: {models_dir}", file=sys.stderr) + sys.exit(1) + + blocks: list[str] = [] + for py_file in sorted(models_dir.glob("*.py")): + if py_file.name == "__init__.py": + continue + + classes = top_level_classes(py_file) + root = find_root_class(classes) + if root is None: + print(f" WARN: no CRD root class in {py_file.name}, skipping", file=sys.stderr) + continue + + lines = [f"from .{py_file.stem} import (", f" {root},"] + for name, _ in sorted(classes): + if name == root or NUMBERED_CLASS.search(name): + continue + lines.append(f" {name} as {root}{name},") + lines.append(")") + blocks.append("\n".join(lines)) + + content = f"{HEADER}\n\n" + "\n\n".join(blocks) + "\n" + init_path = models_dir / "__init__.py" + # newline="\n" keeps LF line endings on every platform + with open(init_path, "w", encoding="utf-8", newline="\n") as fh: + fh.write(content) + print(f" Generated {init_path} ({len(blocks)} modules)") + + +if __name__ == "__main__": + main() diff --git a/k8s/python/openkruise/agents/models/__init__.py b/k8s/python/openkruise/agents/models/__init__.py index b6cc052..db7b966 100644 --- a/k8s/python/openkruise/agents/models/__init__.py +++ b/k8s/python/openkruise/agents/models/__init__.py @@ -1,8 +1,11 @@ +# Code generated by hack/generate_python_sdk.sh. DO NOT EDIT. + from .checkpoint import ( Checkpoint, Spec as CheckpointSpec, Status as CheckpointStatus, ) + from .commit import ( Commit, Condition as CommitCondition, @@ -11,79 +14,258 @@ Spec as CommitSpec, Status as CommitStatus, ) + +from .globalsecurityprofile import ( + GlobalSecurityProfile, + Action as GlobalSecurityProfileAction, + Actions as GlobalSecurityProfileActions, + ApiKey as GlobalSecurityProfileApiKey, + AuditItem as GlobalSecurityProfileAuditItem, + Block as GlobalSecurityProfileBlock, + Body as GlobalSecurityProfileBody, + Condition as GlobalSecurityProfileCondition, + ConfigMap as GlobalSecurityProfileConfigMap, + CredentialProvider as GlobalSecurityProfileCredentialProvider, + CredentialRef as GlobalSecurityProfileCredentialRef, + DefaultAction as GlobalSecurityProfileDefaultAction, + DenyResponse as GlobalSecurityProfileDenyResponse, + FailStrategy as GlobalSecurityProfileFailStrategy, + Header as GlobalSecurityProfileHeader, + HeaderManipulation as GlobalSecurityProfileHeaderManipulation, + Input as GlobalSecurityProfileInput, + Kind as GlobalSecurityProfileKind, + MatchExpression as GlobalSecurityProfileMatchExpression, + MatchItem as GlobalSecurityProfileMatchItem, + McpToolPolicy as GlobalSecurityProfileMcpToolPolicy, + Method as GlobalSecurityProfileMethod, + Name as GlobalSecurityProfileName, + Parameters as GlobalSecurityProfileParameters, + Path as GlobalSecurityProfilePath, + Port as GlobalSecurityProfilePort, + QueryParam as GlobalSecurityProfileQueryParam, + RemoveItem as GlobalSecurityProfileRemoveItem, + Request as GlobalSecurityProfileRequest, + Rule as GlobalSecurityProfileRule, + Scheme as GlobalSecurityProfileScheme, + Secret as GlobalSecurityProfileSecret, + Selector as GlobalSecurityProfileSelector, + SetItem as GlobalSecurityProfileSetItem, + Spec as GlobalSecurityProfileSpec, + Status as GlobalSecurityProfileStatus, + TargetHeaders as GlobalSecurityProfileTargetHeaders, + TokenTransformation as GlobalSecurityProfileTokenTransformation, + Type as GlobalSecurityProfileType, + UnsupportedVersionAction as GlobalSecurityProfileUnsupportedVersionAction, + Value as GlobalSecurityProfileValue, + Webhook as GlobalSecurityProfileWebhook, + When as GlobalSecurityProfileWhen, +) + from .globaltrafficpolicy import ( GlobalTrafficPolicy, Action as GlobalTrafficPolicyAction, Condition as GlobalTrafficPolicyCondition, Egress as GlobalTrafficPolicyEgress, + FromItem as GlobalTrafficPolicyFromItem, Ingress as GlobalTrafficPolicyIngress, MatchExpression as GlobalTrafficPolicyMatchExpression, + Port as GlobalTrafficPolicyPort, Protocol as GlobalTrafficPolicyProtocol, Rule as GlobalTrafficPolicyRule, Selector as GlobalTrafficPolicySelector, Service as GlobalTrafficPolicyService, Spec as GlobalTrafficPolicySpec, Status as GlobalTrafficPolicyStatus, + ToItem as GlobalTrafficPolicyToItem, Workload as GlobalTrafficPolicyWorkload, ) + +from .poolautoscaler import ( + PoolAutoscaler, + AppliedCronPolicy as PoolAutoscalerAppliedCronPolicy, + CapacityPolicy as PoolAutoscalerCapacityPolicy, + Condition as PoolAutoscalerCondition, + CronPolicy as PoolAutoscalerCronPolicy, + CurrentCapacity as PoolAutoscalerCurrentCapacity, + Kind as PoolAutoscalerKind, + ScaleDown as PoolAutoscalerScaleDown, + ScaleTargetRef as PoolAutoscalerScaleTargetRef, + ScaleUp as PoolAutoscalerScaleUp, + Spec as PoolAutoscalerSpec, + Status as PoolAutoscalerStatus, +) + from .sandbox import ( Sandbox, - Spec as SandboxSpec, - Status as SandboxStatus, - TemplateRef as SandboxTemplateRef, + AutoPausePolicy as SandboxAutoPausePolicy, Condition as SandboxCondition, + Exec as SandboxExec, + Grpc as SandboxGrpc, + HibernateStrategy as SandboxHibernateStrategy, + HttpGet as SandboxHttpGet, + HttpHeader as SandboxHttpHeader, + Lifecycle as SandboxLifecycle, + OnIngressTraffic as SandboxOnIngressTraffic, + Pause as SandboxPause, + PauseStrategy as SandboxPauseStrategy, PodInfo as SandboxPodInfo, + PostUpgrade as SandboxPostUpgrade, + PreUpgrade as SandboxPreUpgrade, + Probe as SandboxProbe, + Resume as SandboxResume, Runtime as SandboxRuntime, + Schedule as SandboxSchedule, + Spec as SandboxSpec, + Status as SandboxStatus, + TcpSocket as SandboxTcpSocket, + TemplateRef as SandboxTemplateRef, + TimeFormat as SandboxTimeFormat, + Type as SandboxType, + UpgradePolicy as SandboxUpgradePolicy, + WhenProbedIdleState as SandboxWhenProbedIdleState, + WhenProbedScheduleTime as SandboxWhenProbedScheduleTime, ) + from .sandboxclaim import ( SandboxClaim, - Spec as SandboxClaimSpec, - Status as SandboxClaimStatus, Condition as SandboxClaimCondition, + DynamicVolumesMountItem as SandboxClaimDynamicVolumesMountItem, InplaceUpdate as SandboxClaimInplaceUpdate, + Limits as SandboxClaimLimits, + Requests as SandboxClaimRequests, + Resources as SandboxClaimResources, Runtime as SandboxClaimRuntime, + Spec as SandboxClaimSpec, + Status as SandboxClaimStatus, ) + from .sandboxset import ( SandboxSet, + AutoPausePolicy as SandboxSetAutoPausePolicy, + Condition as SandboxSetCondition, + Exec as SandboxSetExec, + Grpc as SandboxSetGrpc, + HibernateStrategy as SandboxSetHibernateStrategy, + HttpGet as SandboxSetHttpGet, + HttpHeader as SandboxSetHttpHeader, + OnIngressTraffic as SandboxSetOnIngressTraffic, + Pause as SandboxSetPause, + PauseStrategy as SandboxSetPauseStrategy, + Probe as SandboxSetProbe, + Resume as SandboxSetResume, + Runtime as SandboxSetRuntime, + ScaleStrategy as SandboxSetScaleStrategy, Spec as SandboxSetSpec, Status as SandboxSetStatus, + TcpSocket as SandboxSetTcpSocket, TemplateRef as SandboxSetTemplateRef, - Condition as SandboxSetCondition, - ScaleStrategy as SandboxSetScaleStrategy, - Runtime as SandboxSetRuntime, + TimeFormat as SandboxSetTimeFormat, + Type as SandboxSetType, + UpdateStrategy as SandboxSetUpdateStrategy, + WhenProbedIdleState as SandboxSetWhenProbedIdleState, + WhenProbedScheduleTime as SandboxSetWhenProbedScheduleTime, ) + from .sandboxtemplate import ( SandboxTemplate, - Spec as SandboxTemplateSpec, + AutoPausePolicy as SandboxTemplateAutoPausePolicy, + Exec as SandboxTemplateExec, + Grpc as SandboxTemplateGrpc, + HibernateStrategy as SandboxTemplateHibernateStrategy, + HttpGet as SandboxTemplateHttpGet, + HttpHeader as SandboxTemplateHttpHeader, + OnIngressTraffic as SandboxTemplateOnIngressTraffic, + Pause as SandboxTemplatePause, + PauseStrategy as SandboxTemplatePauseStrategy, + Probe as SandboxTemplateProbe, + Resume as SandboxTemplateResume, Runtime as SandboxTemplateRuntime, + Spec as SandboxTemplateSpec, + TcpSocket as SandboxTemplateTcpSocket, + TimeFormat as SandboxTemplateTimeFormat, + Type as SandboxTemplateType, + WhenProbedIdleState as SandboxTemplateWhenProbedIdleState, + WhenProbedScheduleTime as SandboxTemplateWhenProbedScheduleTime, ) + from .sandboxupdateops import ( SandboxUpdateOps, + Condition as SandboxUpdateOpsCondition, + Exec as SandboxUpdateOpsExec, + Lifecycle as SandboxUpdateOpsLifecycle, + MatchExpression as SandboxUpdateOpsMatchExpression, + PostUpgrade as SandboxUpdateOpsPostUpgrade, + PreUpgrade as SandboxUpdateOpsPreUpgrade, + Selector as SandboxUpdateOpsSelector, Spec as SandboxUpdateOpsSpec, + State as SandboxUpdateOpsState, + StateFilter as SandboxUpdateOpsStateFilter, Status as SandboxUpdateOpsStatus, - Selector as SandboxUpdateOpsSelector, - Lifecycle as SandboxUpdateOpsLifecycle, + Type as SandboxUpdateOpsType, + UpdateStrategy as SandboxUpdateOpsUpdateStrategy, ) + from .securityprofile import ( SecurityProfile, - Spec as SecurityProfileSpec, - Status as SecurityProfileStatus, - Rule as SecurityProfileRule, + Action as SecurityProfileAction, Actions as SecurityProfileActions, + ApiKey as SecurityProfileApiKey, + AuditItem as SecurityProfileAuditItem, + Block as SecurityProfileBlock, + Body as SecurityProfileBody, + Condition as SecurityProfileCondition, + ConfigMap as SecurityProfileConfigMap, + CredentialProvider as SecurityProfileCredentialProvider, + CredentialRef as SecurityProfileCredentialRef, + DefaultAction as SecurityProfileDefaultAction, + DenyResponse as SecurityProfileDenyResponse, + FailStrategy as SecurityProfileFailStrategy, + Header as SecurityProfileHeader, + HeaderManipulation as SecurityProfileHeaderManipulation, + Input as SecurityProfileInput, + Kind as SecurityProfileKind, + MatchExpression as SecurityProfileMatchExpression, + MatchItem as SecurityProfileMatchItem, + McpToolPolicy as SecurityProfileMcpToolPolicy, + Method as SecurityProfileMethod, + Name as SecurityProfileName, + Parameters as SecurityProfileParameters, + Path as SecurityProfilePath, + Port as SecurityProfilePort, + QueryParam as SecurityProfileQueryParam, + RemoveItem as SecurityProfileRemoveItem, + Request as SecurityProfileRequest, + Rule as SecurityProfileRule, + Scheme as SecurityProfileScheme, + Secret as SecurityProfileSecret, Selector as SecurityProfileSelector, + SetItem as SecurityProfileSetItem, + Spec as SecurityProfileSpec, + Status as SecurityProfileStatus, + TargetHeaders as SecurityProfileTargetHeaders, + TokenTransformation as SecurityProfileTokenTransformation, + Type as SecurityProfileType, + UnsupportedVersionAction as SecurityProfileUnsupportedVersionAction, + Value as SecurityProfileValue, + Webhook as SecurityProfileWebhook, + When as SecurityProfileWhen, ) + from .trafficpolicy import ( TrafficPolicy, Action as TrafficPolicyAction, Condition as TrafficPolicyCondition, Egress as TrafficPolicyEgress, + FromItem as TrafficPolicyFromItem, Ingress as TrafficPolicyIngress, MatchExpression as TrafficPolicyMatchExpression, + Port as TrafficPolicyPort, Protocol as TrafficPolicyProtocol, Rule as TrafficPolicyRule, Selector as TrafficPolicySelector, Service as TrafficPolicyService, Spec as TrafficPolicySpec, Status as TrafficPolicyStatus, + ToItem as TrafficPolicyToItem, Workload as TrafficPolicyWorkload, ) From 728352abec61b065263f94abd5e38e3072d43d24 Mon Sep 17 00:00:00 2001 From: tianhr <344527078@qq.com> Date: Thu, 3 Sep 2026 11:47:40 +0800 Subject: [PATCH 4/5] feat/sync-agents --- .../agents/client/v2/models/sandboxstatus/Schedules.java | 1 + k8s/python/openkruise/agents/models/checkpoint.py | 2 +- k8s/python/openkruise/agents/models/commit.py | 2 +- .../openkruise/agents/models/globalsecurityprofile.py | 2 +- .../openkruise/agents/models/globaltrafficpolicy.py | 2 +- k8s/python/openkruise/agents/models/poolautoscaler.py | 4 ++-- k8s/python/openkruise/agents/models/sandbox.py | 8 ++++---- k8s/python/openkruise/agents/models/sandboxclaim.py | 2 +- k8s/python/openkruise/agents/models/sandboxset.py | 6 +++--- k8s/python/openkruise/agents/models/sandboxtemplate.py | 6 +++--- k8s/python/openkruise/agents/models/sandboxupdateops.py | 2 +- k8s/python/openkruise/agents/models/securityprofile.py | 2 +- k8s/python/openkruise/agents/models/trafficpolicy.py | 2 +- 13 files changed, 21 insertions(+), 20 deletions(-) diff --git a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java index 7589f8e..7967345 100644 --- a/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java +++ b/k8s/java/src/main/java/io/openkruise/agents/client/v2/models/sandboxstatus/Schedules.java @@ -50,6 +50,7 @@ public void setNextResumeTime(java.time.ZonedDateTime nextResumeTime) { * "probedSchedule" (resume triggered by WhenProbedScheduleTime). */ @com.fasterxml.jackson.annotation.JsonProperty("reason") + @io.fabric8.generator.annotation.Required() @com.fasterxml.jackson.annotation.JsonPropertyDescription("Reason indicates which auto-pause rule triggered this schedule entry.\nExamples: \"probedIdle\" (pause triggered by WhenProbedIdleState),\n\"probedSchedule\" (resume triggered by WhenProbedScheduleTime).") @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP) private String reason; diff --git a/k8s/python/openkruise/agents/models/checkpoint.py b/k8s/python/openkruise/agents/models/checkpoint.py index eae63d3..5a991f7 100644 --- a/k8s/python/openkruise/agents/models/checkpoint.py +++ b/k8s/python/openkruise/agents/models/checkpoint.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: checkpoint_schema.json -# timestamp: 2026-09-02T10:13:25+00:00 +# timestamp: 2026-09-03T03:47:26+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/commit.py b/k8s/python/openkruise/agents/models/commit.py index 201735c..ebc72e7 100644 --- a/k8s/python/openkruise/agents/models/commit.py +++ b/k8s/python/openkruise/agents/models/commit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: commit_schema.json -# timestamp: 2026-09-02T10:13:25+00:00 +# timestamp: 2026-09-03T03:47:26+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globalsecurityprofile.py b/k8s/python/openkruise/agents/models/globalsecurityprofile.py index 67bdb82..fb9feb0 100644 --- a/k8s/python/openkruise/agents/models/globalsecurityprofile.py +++ b/k8s/python/openkruise/agents/models/globalsecurityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globalsecurityprofile_schema.json -# timestamp: 2026-09-02T10:13:26+00:00 +# timestamp: 2026-09-03T03:47:26+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py index 517083d..1b18a2e 100644 --- a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py +++ b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globaltrafficpolicy_schema.json -# timestamp: 2026-09-02T10:13:26+00:00 +# timestamp: 2026-09-03T03:47:27+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/poolautoscaler.py b/k8s/python/openkruise/agents/models/poolautoscaler.py index 0e709fa..d8affa7 100644 --- a/k8s/python/openkruise/agents/models/poolautoscaler.py +++ b/k8s/python/openkruise/agents/models/poolautoscaler.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: poolautoscaler_schema.json -# timestamp: 2026-09-02T10:13:26+00:00 +# timestamp: 2026-09-03T03:47:27+00:00 from __future__ import annotations @@ -251,7 +251,7 @@ class Spec(BaseModel): """ CapacityPolicy defines the capacity configuration of the target resource pool. """ - cronPolicies: list[CronPolicy] | None = None + cronPolicies: list[CronPolicy] | None = Field(None, max_length=20) """ CronPolicies is a list of potential cron scaling policies which can be used during scaling. When both CronPolicies and CapacityPolicy are set, CronPolicies takes higher priority. diff --git a/k8s/python/openkruise/agents/models/sandbox.py b/k8s/python/openkruise/agents/models/sandbox.py index 6a5771c..f03f95b 100644 --- a/k8s/python/openkruise/agents/models/sandbox.py +++ b/k8s/python/openkruise/agents/models/sandbox.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandbox_schema.json -# timestamp: 2026-09-02T10:13:27+00:00 +# timestamp: 2026-09-03T03:47:28+00:00 from __future__ import annotations @@ -479,7 +479,7 @@ class Schedule(BaseModel): NextResumeTime is when the sandbox is expected to be resumed, computed from the resume policy's probed schedule time. It is cleared after a resume is triggered. """ - reason: str | None = None + reason: str """ Reason indicates which auto-pause rule triggered this schedule entry. Examples: "probedIdle" (pause triggered by WhenProbedIdleState), @@ -523,7 +523,7 @@ class Spec(BaseModel): """ PersistentContents indicates resume pod with persistent content, Enum: ip, memory, filesystem """ - probes: list[Probe] | None = None + probes: list[Probe] | None = Field(None, max_length=16) """ Probes defines a list of named probes that run periodically while the sandbox is Running. Each probe writes its result to a Pod Status Condition with @@ -717,7 +717,7 @@ class WhenProbedIdleState(BaseModel): matches MessageRegex for at least ThresholdDuration. """ - messageRegex: str + messageRegex: str = Field(..., max_length=512) """ MessageRegex is a regular expression matched against the probe's Condition message (stdout). When the message matches, the Agent is diff --git a/k8s/python/openkruise/agents/models/sandboxclaim.py b/k8s/python/openkruise/agents/models/sandboxclaim.py index ea7502e..91571fc 100644 --- a/k8s/python/openkruise/agents/models/sandboxclaim.py +++ b/k8s/python/openkruise/agents/models/sandboxclaim.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxclaim_schema.json -# timestamp: 2026-09-02T10:13:27+00:00 +# timestamp: 2026-09-03T03:47:28+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandboxset.py b/k8s/python/openkruise/agents/models/sandboxset.py index 425a4f4..900bac7 100644 --- a/k8s/python/openkruise/agents/models/sandboxset.py +++ b/k8s/python/openkruise/agents/models/sandboxset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxset_schema.json -# timestamp: 2026-09-02T10:13:28+00:00 +# timestamp: 2026-09-03T03:47:29+00:00 from __future__ import annotations @@ -424,7 +424,7 @@ class Spec(BaseModel): """ PersistentContents indicates resume pod with persistent content, Enum: ip, memory, filesystem """ - probes: list[Probe] | None = None + probes: list[Probe] | None = Field(None, max_length=16) """ Probes defines the named probes that sandboxes created from this SandboxSet run while they are Running. It is copied verbatim onto each created Sandbox @@ -609,7 +609,7 @@ class WhenProbedIdleState(BaseModel): matches MessageRegex for at least ThresholdDuration. """ - messageRegex: str + messageRegex: str = Field(..., max_length=512) """ MessageRegex is a regular expression matched against the probe's Condition message (stdout). When the message matches, the Agent is diff --git a/k8s/python/openkruise/agents/models/sandboxtemplate.py b/k8s/python/openkruise/agents/models/sandboxtemplate.py index b4d161c..9116455 100644 --- a/k8s/python/openkruise/agents/models/sandboxtemplate.py +++ b/k8s/python/openkruise/agents/models/sandboxtemplate.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxtemplate_schema.json -# timestamp: 2026-09-02T10:13:28+00:00 +# timestamp: 2026-09-03T03:47:29+00:00 from __future__ import annotations @@ -337,7 +337,7 @@ class Spec(BaseModel): """ PersistentContents indicates resume pod with persistent content, Enum: ip, memory, filesystem """ - probes: list[Probe] | None = None + probes: list[Probe] | None = Field(None, max_length=16) """ Probes defines the named probes that sandboxes created from this template run while they are Running. It is only informational when a SandboxSet uses @@ -406,7 +406,7 @@ class WhenProbedIdleState(BaseModel): matches MessageRegex for at least ThresholdDuration. """ - messageRegex: str + messageRegex: str = Field(..., max_length=512) """ MessageRegex is a regular expression matched against the probe's Condition message (stdout). When the message matches, the Agent is diff --git a/k8s/python/openkruise/agents/models/sandboxupdateops.py b/k8s/python/openkruise/agents/models/sandboxupdateops.py index 018a13e..c05c30e 100644 --- a/k8s/python/openkruise/agents/models/sandboxupdateops.py +++ b/k8s/python/openkruise/agents/models/sandboxupdateops.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxupdateops_schema.json -# timestamp: 2026-09-02T10:13:28+00:00 +# timestamp: 2026-09-03T03:47:29+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/securityprofile.py b/k8s/python/openkruise/agents/models/securityprofile.py index 8e89716..000c7f3 100644 --- a/k8s/python/openkruise/agents/models/securityprofile.py +++ b/k8s/python/openkruise/agents/models/securityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: securityprofile_schema.json -# timestamp: 2026-09-02T10:13:29+00:00 +# timestamp: 2026-09-03T03:47:30+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/trafficpolicy.py b/k8s/python/openkruise/agents/models/trafficpolicy.py index c15b11a..0120128 100644 --- a/k8s/python/openkruise/agents/models/trafficpolicy.py +++ b/k8s/python/openkruise/agents/models/trafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: trafficpolicy_schema.json -# timestamp: 2026-09-02T10:13:29+00:00 +# timestamp: 2026-09-03T03:47:30+00:00 from __future__ import annotations From 01bdacdb8a52382d6a788b858692e4d589c387c8 Mon Sep 17 00:00:00 2001 From: tianhr <344527078@qq.com> Date: Thu, 3 Sep 2026 13:25:48 +0800 Subject: [PATCH 5/5] chore: align controller-gen version between Makefile and CRD headers --- AGENTS.md | 2 +- Makefile | 4 ++-- k8s/python/openkruise/agents/models/checkpoint.py | 2 +- k8s/python/openkruise/agents/models/commit.py | 2 +- k8s/python/openkruise/agents/models/globalsecurityprofile.py | 2 +- k8s/python/openkruise/agents/models/globaltrafficpolicy.py | 2 +- k8s/python/openkruise/agents/models/poolautoscaler.py | 2 +- k8s/python/openkruise/agents/models/sandbox.py | 2 +- k8s/python/openkruise/agents/models/sandboxclaim.py | 2 +- k8s/python/openkruise/agents/models/sandboxset.py | 2 +- k8s/python/openkruise/agents/models/sandboxtemplate.py | 2 +- k8s/python/openkruise/agents/models/sandboxupdateops.py | 2 +- k8s/python/openkruise/agents/models/securityprofile.py | 2 +- k8s/python/openkruise/agents/models/trafficpolicy.py | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c5f6258..9969acc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,7 +68,7 @@ agents-api/ - `github.com/go-bindata/go-bindata` v3.1.2 - `google.golang.org/protobuf` v1.36.9 - **Code Generation Tools**: - - `controller-gen` v0.16.5 (downloaded to `./bin/`) + - `controller-gen` v0.18.0 (downloaded to `./bin/`) - `openapi-gen` (version derived from go.mod) ## Build Commands diff --git a/Makefile b/Makefile index 0aa3043..696d42f 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,10 @@ generate: controller-gen CONTROLLER_GEN = $(shell pwd)/bin/controller-gen controller-gen: ## Download controller-gen locally if necessary. -ifeq ("$(shell $(CONTROLLER_GEN) --version 2> /dev/null)", "Version: v0.16.5") +ifeq ("$(shell $(CONTROLLER_GEN) --version 2> /dev/null)", "Version: v0.18.0") else rm -rf $(CONTROLLER_GEN) - $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.5) + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0) endif OPENAPI_GEN = $(shell pwd)/bin/openapi-gen diff --git a/k8s/python/openkruise/agents/models/checkpoint.py b/k8s/python/openkruise/agents/models/checkpoint.py index 5a991f7..8f8fb6a 100644 --- a/k8s/python/openkruise/agents/models/checkpoint.py +++ b/k8s/python/openkruise/agents/models/checkpoint.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: checkpoint_schema.json -# timestamp: 2026-09-03T03:47:26+00:00 +# timestamp: 2026-09-03T05:22:22+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/commit.py b/k8s/python/openkruise/agents/models/commit.py index ebc72e7..86cf9ff 100644 --- a/k8s/python/openkruise/agents/models/commit.py +++ b/k8s/python/openkruise/agents/models/commit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: commit_schema.json -# timestamp: 2026-09-03T03:47:26+00:00 +# timestamp: 2026-09-03T05:22:22+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globalsecurityprofile.py b/k8s/python/openkruise/agents/models/globalsecurityprofile.py index fb9feb0..1fabdc3 100644 --- a/k8s/python/openkruise/agents/models/globalsecurityprofile.py +++ b/k8s/python/openkruise/agents/models/globalsecurityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globalsecurityprofile_schema.json -# timestamp: 2026-09-03T03:47:26+00:00 +# timestamp: 2026-09-03T05:22:23+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py index 1b18a2e..6230964 100644 --- a/k8s/python/openkruise/agents/models/globaltrafficpolicy.py +++ b/k8s/python/openkruise/agents/models/globaltrafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: globaltrafficpolicy_schema.json -# timestamp: 2026-09-03T03:47:27+00:00 +# timestamp: 2026-09-03T05:22:23+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/poolautoscaler.py b/k8s/python/openkruise/agents/models/poolautoscaler.py index d8affa7..1900cc9 100644 --- a/k8s/python/openkruise/agents/models/poolautoscaler.py +++ b/k8s/python/openkruise/agents/models/poolautoscaler.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: poolautoscaler_schema.json -# timestamp: 2026-09-03T03:47:27+00:00 +# timestamp: 2026-09-03T05:22:23+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandbox.py b/k8s/python/openkruise/agents/models/sandbox.py index f03f95b..e571930 100644 --- a/k8s/python/openkruise/agents/models/sandbox.py +++ b/k8s/python/openkruise/agents/models/sandbox.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandbox_schema.json -# timestamp: 2026-09-03T03:47:28+00:00 +# timestamp: 2026-09-03T05:22:24+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandboxclaim.py b/k8s/python/openkruise/agents/models/sandboxclaim.py index 91571fc..d5ce731 100644 --- a/k8s/python/openkruise/agents/models/sandboxclaim.py +++ b/k8s/python/openkruise/agents/models/sandboxclaim.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxclaim_schema.json -# timestamp: 2026-09-03T03:47:28+00:00 +# timestamp: 2026-09-03T05:22:24+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandboxset.py b/k8s/python/openkruise/agents/models/sandboxset.py index 900bac7..dd18638 100644 --- a/k8s/python/openkruise/agents/models/sandboxset.py +++ b/k8s/python/openkruise/agents/models/sandboxset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxset_schema.json -# timestamp: 2026-09-03T03:47:29+00:00 +# timestamp: 2026-09-03T05:22:25+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandboxtemplate.py b/k8s/python/openkruise/agents/models/sandboxtemplate.py index 9116455..8690e1b 100644 --- a/k8s/python/openkruise/agents/models/sandboxtemplate.py +++ b/k8s/python/openkruise/agents/models/sandboxtemplate.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxtemplate_schema.json -# timestamp: 2026-09-03T03:47:29+00:00 +# timestamp: 2026-09-03T05:22:25+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/sandboxupdateops.py b/k8s/python/openkruise/agents/models/sandboxupdateops.py index c05c30e..82e7883 100644 --- a/k8s/python/openkruise/agents/models/sandboxupdateops.py +++ b/k8s/python/openkruise/agents/models/sandboxupdateops.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sandboxupdateops_schema.json -# timestamp: 2026-09-03T03:47:29+00:00 +# timestamp: 2026-09-03T05:22:25+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/securityprofile.py b/k8s/python/openkruise/agents/models/securityprofile.py index 000c7f3..c4d09b9 100644 --- a/k8s/python/openkruise/agents/models/securityprofile.py +++ b/k8s/python/openkruise/agents/models/securityprofile.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: securityprofile_schema.json -# timestamp: 2026-09-03T03:47:30+00:00 +# timestamp: 2026-09-03T05:22:26+00:00 from __future__ import annotations diff --git a/k8s/python/openkruise/agents/models/trafficpolicy.py b/k8s/python/openkruise/agents/models/trafficpolicy.py index 0120128..e698a5c 100644 --- a/k8s/python/openkruise/agents/models/trafficpolicy.py +++ b/k8s/python/openkruise/agents/models/trafficpolicy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: trafficpolicy_schema.json -# timestamp: 2026-09-03T03:47:30+00:00 +# timestamp: 2026-09-03T05:22:26+00:00 from __future__ import annotations