Skip to content

Commit 2aef474

Browse files
JeffwanModiCodeCraftsman
authored andcommitted
Add RoleSet and StormService detail spec (vllm-project#1226)
Signed-off-by: Jiaxin Shan <[email protected]> Signed-off-by: Modi Tamam <[email protected]>
1 parent 15fcec5 commit 2aef474

File tree

11 files changed

+8354
-31
lines changed

11 files changed

+8354
-31
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
Copyright 2025 The Aibrix Team.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import (
20+
corev1 "k8s.io/api/core/v1"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
)
23+
24+
// A ConditionType represents a condition a resource could be in.
25+
type ConditionType string
26+
27+
// A Condition that may apply to a resource.
28+
type Condition struct {
29+
// Type of this condition. At most one of each condition type may apply to a resource at any point in time.
30+
Type ConditionType `json:"type"`
31+
32+
// Status of this condition; is it currently True, False, or Unknown?
33+
Status corev1.ConditionStatus `json:"status"`
34+
35+
// LastTransitionTime is the last time this condition transitioned from one status to another.
36+
// +optional
37+
LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
38+
39+
// LastUpdateTime is the last time this condition was updated.
40+
// +optional
41+
LastUpdateTime *metav1.Time `json:"lastUpdateTime,omitempty"`
42+
43+
// LastUpdateMicroTime is the last time with microsecond level precision this condition was updated.
44+
// +optional
45+
LastUpdateMicroTime *metav1.MicroTime `json:"lastUpdateMicroTime,omitempty"`
46+
47+
// The Reason for the condition's last transition.
48+
Reason string `json:"reason,omitempty"`
49+
50+
// A Message containing details about this condition's last transition from one status to another, if any.
51+
// +optional
52+
Message string `json:"message,omitempty"`
53+
}
54+
55+
func NewCondition(ct ConditionType, status corev1.ConditionStatus, msg string) Condition {
56+
return Condition{
57+
Type: ct,
58+
Status: status,
59+
Message: msg,
60+
}
61+
}
62+
63+
// Conditions reflects the observed status of a resource. Only
64+
// one condition of each type may exist.
65+
type Conditions []Condition
66+
67+
// GetCondition returns the condition for the given ConditionType if exists,
68+
// otherwise returns nil
69+
func (s Conditions) GetCondition(ct ConditionType) Condition {
70+
for _, c := range s {
71+
if c.Type == ct {
72+
return c
73+
}
74+
}
75+
76+
return Condition{Type: ct, Status: corev1.ConditionUnknown}
77+
}
78+
79+
// SetConditions sets the supplied conditions, replacing any existing conditions
80+
// of the same type. This is a no-op if all supplied conditions are identical,
81+
// ignoring the last transition time, to those already set.
82+
func (s *Conditions) SetConditions(conditions ...Condition) {
83+
for _, c := range conditions {
84+
found := false
85+
for i := range *s {
86+
ref := &(*s)[i]
87+
if ref.Type != c.Type {
88+
continue
89+
}
90+
91+
found = true
92+
93+
if ref.Equal(&c) {
94+
if !c.LastUpdateTime.Equal(ref.LastUpdateTime) {
95+
ref.LastUpdateTime = c.LastUpdateTime
96+
}
97+
if !c.LastUpdateMicroTime.Equal(ref.LastUpdateMicroTime) {
98+
ref.LastUpdateMicroTime = c.LastUpdateMicroTime
99+
}
100+
continue
101+
}
102+
if ref.Status != c.Status {
103+
now := metav1.Now()
104+
c.LastTransitionTime = &now
105+
}
106+
*ref = c
107+
}
108+
if !found {
109+
now := metav1.Now()
110+
c.LastTransitionTime = &now
111+
*s = append(*s, c)
112+
}
113+
}
114+
}
115+
116+
// Equal used to judge weather two condition is equal.
117+
// LastTransitionTime, LastUpdateTime and LastUpdateMicroTime is ignored.
118+
func (c *Condition) Equal(candidate *Condition) bool {
119+
return c.Message == candidate.Message &&
120+
c.Type == candidate.Type &&
121+
c.Status == candidate.Status
122+
}

api/orchestration/v1alpha1/groupversion_info.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ import (
2424
"sigs.k8s.io/controller-runtime/pkg/scheme"
2525
)
2626

27+
const (
28+
StormServiceKind = "StormService"
29+
RoleSetKind = "RoleSet"
30+
)
31+
2732
var (
2833
// GroupVersion is group version used to register these objects
2934
GroupVersion = schema.GroupVersion{Group: "orchestration.aibrix.ai", Version: "v1alpha1"}

api/orchestration/v1alpha1/roleset_types.go

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,111 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20+
v1 "k8s.io/api/core/v1"
2021
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21-
)
22+
"k8s.io/apimachinery/pkg/util/intstr"
2223

23-
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
24-
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
24+
// let's temporarily use godel scheduler's definition, consider to switch to community definitions
25+
schedv1alpha1 "github.com/kubewharf/godel-scheduler-api/pkg/apis/scheduling/v1alpha1"
26+
)
2527

2628
// RoleSetSpec defines the desired state of RoleSet
2729
type RoleSetSpec struct {
28-
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
29-
// Important: Run "make" to regenerate code after modifying this file
30+
Roles []RoleSpec `json:"roles,omitempty"`
31+
32+
// +optional
33+
UpdateStrategy RoleSetUpdateStrategyType `json:"updateStrategy,omitempty"`
34+
35+
// +optional
36+
SchedulingStrategy SchedulingStrategy `json:"schedulingStrategy,omitempty"`
37+
}
3038

31-
// Foo is an example field of RoleSet. Edit roleset_types.go to remove/update
32-
Foo string `json:"foo,omitempty"`
39+
// +enum
40+
type SchedulingStrategy struct {
41+
PodGroup *schedv1alpha1.PodGroupSpec `json:"podGroup,omitempty"`
42+
}
43+
44+
// +enum
45+
type RoleSetUpdateStrategyType string
46+
47+
const (
48+
// ParallelRoleSetUpdateStrategyType update all roles in parallel
49+
ParallelRoleSetUpdateStrategyType RoleSetUpdateStrategyType = "Parallel"
50+
// SequentialRoleSetStrategyType update all roles in sequential
51+
SequentialRoleSetStrategyType RoleSetUpdateStrategyType = "Sequential"
52+
// InterleaveRoleSetStrategyType update all roles in interleave, follow the rolling step defined in roles
53+
InterleaveRoleSetStrategyType RoleSetUpdateStrategyType = "Interleave"
54+
)
55+
56+
type DisruptionTolerance struct {
57+
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
58+
}
59+
60+
type RoleSpec struct {
61+
Name string `json:"name,omitempty"`
62+
63+
// Replicas is the number of desired replicas.
64+
// +optional
65+
Replicas *int32 `json:"replicas,omitempty"`
66+
67+
// +optional
68+
// +patchStrategy=retainKeys
69+
UpdateStrategy RoleUpdateStrategy `json:"updateStrategy,omitempty"`
70+
71+
// +optional
72+
Stateful bool `json:"stateful,omitempty"`
73+
74+
// +optional
75+
Template v1.PodTemplateSpec `json:"template,omitempty"`
76+
77+
// DisruptionTolerance indicates how many pods can be unavailable during the preemption/eviction.
78+
// +optional
79+
DisruptionTolerance DisruptionTolerance `json:"disruptionTolerance,omitempty"`
80+
}
81+
82+
// +enum
83+
type RoleUpdateStrategy struct {
84+
// +optional
85+
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,1,opt,name=maxUnavailable"`
86+
87+
// +optional
88+
MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty" protobuf:"bytes,2,opt,name=maxSurge"`
3389
}
3490

3591
// RoleSetStatus defines the observed state of RoleSet
3692
type RoleSetStatus struct {
37-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
38-
// Important: Run "make" to regenerate code after modifying this file
93+
Roles []RoleStatus `json:"roles,omitempty"`
94+
// +optional
95+
// +patchMergeKey=type
96+
// +patchStrategy=merge
97+
Conditions Conditions `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
98+
}
99+
100+
// These are valid conditions of roleSet.
101+
const (
102+
// RoleSetReady means the roleSet meeting the minimal requirements for the roleSet to be considered ready.
103+
RoleSetReady ConditionType = "Ready"
104+
RoleSetReplicaFailure ConditionType = "ReplicaFailure"
105+
RoleSetProgressing ConditionType = "Progressing"
106+
)
107+
108+
type RoleStatus struct {
109+
Name string `json:"name,omitempty"`
110+
111+
// Replicas is the most recently oberved number of replicas.
112+
Replicas int32 `json:"replicas"`
113+
114+
// +optional
115+
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
116+
117+
// +optional
118+
NotReadyReplicas int32 `json:"notReadyReplicas,omitempty"`
119+
120+
// +optional
121+
UpdatedReplicas int32 `json:"updatedReplicas,omitempty"`
122+
123+
// +optional
124+
UpdatedReadyReplicas int32 `json:"updatedReadyReplicas,omitempty"`
39125
}
40126

41127
//+kubebuilder:object:root=true

0 commit comments

Comments
 (0)