Skip to content

Commit 3f059e7

Browse files
committed
Merge branch 'master' into KUBERAY-2237
2 parents 5221359 + 78b9828 commit 3f059e7

File tree

16 files changed

+290
-49
lines changed

16 files changed

+290
-49
lines changed

helm-chart/kuberay-operator/crds/ray.io_rayclusters.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

helm-chart/kuberay-operator/crds/ray.io_rayjobs.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

helm-chart/kuberay-operator/crds/ray.io_rayservices.yaml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ray-operator/apis/ray/v1/raycluster_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ const (
182182
type HeadInfo struct {
183183
PodIP string `json:"podIP,omitempty"`
184184
ServiceIP string `json:"serviceIP,omitempty"`
185+
PodName string `json:"podName,omitempty"`
185186
ServiceName string `json:"serviceName,omitempty"`
186187
}
187188

ray-operator/config/crd/bases/ray.io_rayclusters.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ray-operator/config/crd/bases/ray.io_rayjobs.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ray-operator/config/crd/bases/ray.io_rayservices.yaml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ray-operator/controllers/ray/batchscheduler/schedulermanager.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ import (
1111
rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
1212
schedulerinterface "github.com/ray-project/kuberay/ray-operator/controllers/ray/batchscheduler/interface"
1313
"github.com/ray-project/kuberay/ray-operator/controllers/ray/batchscheduler/volcano"
14+
"github.com/ray-project/kuberay/ray-operator/controllers/ray/batchscheduler/yunikorn"
1415
"github.com/ray-project/kuberay/ray-operator/controllers/ray/utils"
1516
)
1617

1718
var schedulerContainers = map[string]schedulerinterface.BatchSchedulerFactory{
1819
schedulerinterface.GetDefaultPluginName(): &schedulerinterface.DefaultBatchSchedulerFactory{},
1920
volcano.GetPluginName(): &volcano.VolcanoBatchSchedulerFactory{},
21+
yunikorn.GetPluginName(): &yunikorn.YuniKornSchedulerFactory{},
2022
}
2123

2224
func GetRegisteredNames() []string {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package yunikorn
2+
3+
import (
4+
"context"
5+
6+
"github.com/go-logr/logr"
7+
corev1 "k8s.io/api/core/v1"
8+
"k8s.io/apimachinery/pkg/runtime"
9+
"k8s.io/client-go/rest"
10+
"sigs.k8s.io/controller-runtime/pkg/builder"
11+
logf "sigs.k8s.io/controller-runtime/pkg/log"
12+
13+
rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
14+
schedulerinterface "github.com/ray-project/kuberay/ray-operator/controllers/ray/batchscheduler/interface"
15+
)
16+
17+
const (
18+
SchedulerName string = "yunikorn"
19+
YuniKornPodApplicationIDLabelName string = "applicationId"
20+
YuniKornPodQueueLabelName string = "queue"
21+
RayClusterApplicationIDLabelName string = "yunikorn.apache.org/application-id"
22+
RayClusterQueueLabelName string = "yunikorn.apache.org/queue-name"
23+
)
24+
25+
type YuniKornScheduler struct {
26+
log logr.Logger
27+
}
28+
29+
type YuniKornSchedulerFactory struct{}
30+
31+
func GetPluginName() string {
32+
return SchedulerName
33+
}
34+
35+
func (y *YuniKornScheduler) Name() string {
36+
return GetPluginName()
37+
}
38+
39+
func (y *YuniKornScheduler) DoBatchSchedulingOnSubmission(_ context.Context, _ *rayv1.RayCluster) error {
40+
// yunikorn doesn't require any resources to be created upfront
41+
// this is a no-opt for this implementation
42+
return nil
43+
}
44+
45+
func (y *YuniKornScheduler) populatePodLabels(app *rayv1.RayCluster, pod *corev1.Pod, sourceKey string, targetKey string) {
46+
// check labels
47+
if value, exist := app.Labels[sourceKey]; exist {
48+
y.log.Info("Updating pod label based on RayCluster annotations",
49+
"sourceKey", sourceKey, "targetKey", targetKey, "value", value)
50+
pod.Labels[targetKey] = value
51+
}
52+
}
53+
54+
func (y *YuniKornScheduler) AddMetadataToPod(app *rayv1.RayCluster, _ string, pod *corev1.Pod) {
55+
y.populatePodLabels(app, pod, RayClusterApplicationIDLabelName, YuniKornPodApplicationIDLabelName)
56+
y.populatePodLabels(app, pod, RayClusterQueueLabelName, YuniKornPodQueueLabelName)
57+
pod.Spec.SchedulerName = y.Name()
58+
}
59+
60+
func (yf *YuniKornSchedulerFactory) New(_ *rest.Config) (schedulerinterface.BatchScheduler, error) {
61+
return &YuniKornScheduler{
62+
log: logf.Log.WithName(SchedulerName),
63+
}, nil
64+
}
65+
66+
func (yf *YuniKornSchedulerFactory) AddToScheme(_ *runtime.Scheme) {
67+
// No extra scheme needs to be registered
68+
}
69+
70+
func (yf *YuniKornSchedulerFactory) ConfigureReconciler(b *builder.Builder) *builder.Builder {
71+
return b
72+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package yunikorn
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
v1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
10+
rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
11+
)
12+
13+
func TestPopulatePodLabels(t *testing.T) {
14+
yk := &YuniKornScheduler{}
15+
16+
// --- case 1
17+
// Ray Cluster CR has labels defined
18+
job1 := "job-1-01234"
19+
queue1 := "root.default"
20+
21+
rayCluster1 := createRayClusterWithLabels(
22+
"ray-cluster-with-labels",
23+
"test",
24+
map[string]string{
25+
RayClusterApplicationIDLabelName: job1,
26+
RayClusterQueueLabelName: queue1,
27+
},
28+
)
29+
30+
rayPod := createPod("my-pod-1", "test")
31+
yk.populatePodLabels(rayCluster1, rayPod, RayClusterApplicationIDLabelName, YuniKornPodApplicationIDLabelName)
32+
yk.populatePodLabels(rayCluster1, rayPod, RayClusterQueueLabelName, YuniKornPodQueueLabelName)
33+
assert.Equal(t, podLabelsContains(rayPod, YuniKornPodApplicationIDLabelName, job1), true)
34+
assert.Equal(t, podLabelsContains(rayPod, YuniKornPodQueueLabelName, queue1), true)
35+
36+
// --- case 2
37+
// Ray Cluster CR has nothing
38+
// In this case, the pod will not be populated with the required labels
39+
job2 := "job-2-01234"
40+
queue2 := "root.default"
41+
42+
rayCluster2 := createRayClusterWithLabels(
43+
"ray-cluster-without-labels",
44+
"test",
45+
nil, // empty labels
46+
)
47+
rayPod3 := createPod("my-pod-2", "test")
48+
yk.populatePodLabels(rayCluster2, rayPod3, RayClusterApplicationIDLabelName, YuniKornPodApplicationIDLabelName)
49+
yk.populatePodLabels(rayCluster2, rayPod3, RayClusterQueueLabelName, YuniKornPodQueueLabelName)
50+
assert.Equal(t, podLabelsContains(rayPod3, YuniKornPodApplicationIDLabelName, job2), false)
51+
assert.Equal(t, podLabelsContains(rayPod3, YuniKornPodQueueLabelName, queue2), false)
52+
}
53+
54+
func createRayClusterWithLabels(name string, namespace string, labels map[string]string) *rayv1.RayCluster {
55+
rayCluster := &rayv1.RayCluster{
56+
ObjectMeta: metav1.ObjectMeta{
57+
Name: name,
58+
Namespace: namespace,
59+
Labels: labels,
60+
},
61+
}
62+
63+
return rayCluster
64+
}
65+
66+
func createPod(name string, namespace string) *v1.Pod {
67+
return &v1.Pod{
68+
ObjectMeta: metav1.ObjectMeta{
69+
Name: name,
70+
Namespace: namespace,
71+
Labels: make(map[string]string),
72+
Annotations: make(map[string]string),
73+
},
74+
}
75+
}
76+
77+
func podLabelsContains(pod *v1.Pod, key string, value string) bool {
78+
if pod == nil {
79+
return false
80+
}
81+
82+
if len(pod.Labels) > 0 {
83+
labelValue, exist := pod.Labels[key]
84+
if exist {
85+
if labelValue == value {
86+
return true
87+
}
88+
}
89+
}
90+
91+
return false
92+
}

0 commit comments

Comments
 (0)