Skip to content

Commit 6186a7d

Browse files
[Feat] Deprecate ForcedClusterUpgrade (#2075)
1 parent ffac341 commit 6186a7d

File tree

5 files changed

+5
-281
lines changed

5 files changed

+5
-281
lines changed

ray-operator/apis/config/v1alpha1/configuration_types.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ type Configuration struct {
3232
// If empty, all namespaces will be watched.
3333
WatchNamespace string `json:"watchNamespace,omitempty"`
3434

35-
// ForcedClusterUpgrade enables force upgrading clusters.
36-
ForcedClusterUpgrade bool `json:"forcedClusterUpgrade,omitempty"`
37-
3835
// LogFile is a path to a local file for synchronizing logs.
3936
LogFile string `json:"logFile,omitempty"`
4037

ray-operator/controllers/ray/raycluster_controller.go

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import (
4646

4747
var (
4848
DefaultRequeueDuration = 2 * time.Second
49-
ForcedClusterUpgrade bool
5049
EnableBatchScheduler bool
5150

5251
// Definition of a index field for pod name
@@ -697,42 +696,6 @@ func (r *RayClusterReconciler) reconcilePods(ctx context.Context, instance *rayv
697696
}
698697
}
699698

700-
if ForcedClusterUpgrade {
701-
if len(headPods.Items) == 1 {
702-
// head node amount is exactly 1, but we need to check if it has been changed
703-
res := utils.PodNotMatchingTemplate(headPods.Items[0], instance.Spec.HeadGroupSpec.Template)
704-
if res {
705-
logger.Info(fmt.Sprintf("need to delete old head pod %s", headPods.Items[0].Name))
706-
if err := r.Delete(ctx, &headPods.Items[0]); err != nil {
707-
return err
708-
}
709-
return nil
710-
}
711-
}
712-
713-
// check if WorkerGroupSpecs has been changed and we need to kill worker pods
714-
for _, worker := range instance.Spec.WorkerGroupSpecs {
715-
workerPods := corev1.PodList{}
716-
if err := r.List(ctx, &workerPods, common.RayClusterGroupPodsAssociationOptions(instance, worker.GroupName).ToListOptions()...); err != nil {
717-
return err
718-
}
719-
updatedWorkerPods := false
720-
for _, item := range workerPods.Items {
721-
if utils.PodNotMatchingTemplate(item, worker.Template) {
722-
logger.Info(fmt.Sprintf("need to delete old worker pod %s", item.Name))
723-
if err := r.Delete(ctx, &item); err != nil {
724-
logger.Info(fmt.Sprintf("error deleting worker pod %s", item.Name))
725-
return err
726-
}
727-
updatedWorkerPods = true
728-
}
729-
}
730-
if updatedWorkerPods {
731-
return nil
732-
}
733-
}
734-
}
735-
736699
// Reconcile worker pods now
737700
for _, worker := range instance.Spec.WorkerGroupSpecs {
738701
// workerReplicas will store the target number of pods for this worker group.

ray-operator/controllers/ray/utils/util.go

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -414,65 +414,6 @@ func CheckAllPodsRunning(ctx context.Context, runningPods corev1.PodList) bool {
414414
return true
415415
}
416416

417-
func PodNotMatchingTemplate(pod corev1.Pod, template corev1.PodTemplateSpec) bool {
418-
if pod.Status.Phase == corev1.PodRunning && pod.ObjectMeta.DeletionTimestamp == nil {
419-
if len(template.Spec.Containers) != len(pod.Spec.Containers) {
420-
return true
421-
}
422-
cmap := map[string]*corev1.Container{}
423-
for _, container := range pod.Spec.Containers {
424-
cmap[container.Name] = &container
425-
}
426-
for _, container1 := range template.Spec.Containers {
427-
if container2, ok := cmap[container1.Name]; ok {
428-
if container1.Image != container2.Image {
429-
// image name do not match
430-
return true
431-
}
432-
if len(container1.Resources.Requests) != len(container2.Resources.Requests) ||
433-
len(container1.Resources.Limits) != len(container2.Resources.Limits) {
434-
// resource entries do not match
435-
return true
436-
}
437-
438-
resources1 := []corev1.ResourceList{
439-
container1.Resources.Requests,
440-
container1.Resources.Limits,
441-
}
442-
resources2 := []corev1.ResourceList{
443-
container2.Resources.Requests,
444-
container2.Resources.Limits,
445-
}
446-
for i := range resources1 {
447-
// we need to make sure all fields match
448-
for name, quantity1 := range resources1[i] {
449-
if quantity2, ok := resources2[i][name]; ok {
450-
if quantity1.Cmp(quantity2) != 0 {
451-
// request amount does not match
452-
return true
453-
}
454-
} else {
455-
// no such request
456-
return true
457-
}
458-
}
459-
}
460-
461-
// now we consider them equal
462-
delete(cmap, container1.Name)
463-
} else {
464-
// container name do not match
465-
return true
466-
}
467-
}
468-
if len(cmap) != 0 {
469-
// one or more containers do not match
470-
return true
471-
}
472-
}
473-
return false
474-
}
475-
476417
// CompareJsonStruct This is a way to better compare if two objects are the same when they are json/yaml structs. reflect.DeepEqual will fail in some cases.
477418
func CompareJsonStruct(objA interface{}, objB interface{}) bool {
478419
a, err := json.Marshal(objA)

ray-operator/controllers/ray/utils/util_test.go

Lines changed: 0 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"testing"
66

77
"github.com/stretchr/testify/assert"
8-
"k8s.io/apimachinery/pkg/api/resource"
98
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
109
"k8s.io/utils/pointer"
1110

@@ -252,181 +251,6 @@ func TestGetHeadGroupServiceAccountName(t *testing.T) {
252251
}
253252
}
254253

255-
func TestReconcile_CheckNeedRemoveOldPod(t *testing.T) {
256-
namespaceStr := "default"
257-
258-
headTemplate := corev1.PodTemplateSpec{
259-
Spec: corev1.PodSpec{
260-
Containers: []corev1.Container{
261-
{
262-
Name: "ray-head",
263-
Image: "rayproject/autoscaler",
264-
Command: []string{"python"},
265-
Args: []string{"/opt/code.py"},
266-
Env: []corev1.EnvVar{
267-
{
268-
Name: "MY_POD_IP",
269-
ValueFrom: &corev1.EnvVarSource{
270-
FieldRef: &corev1.ObjectFieldSelector{
271-
FieldPath: "status.podIP",
272-
},
273-
},
274-
},
275-
},
276-
},
277-
},
278-
},
279-
}
280-
281-
pod := corev1.Pod{
282-
ObjectMeta: metav1.ObjectMeta{
283-
Name: "headNode",
284-
Namespace: namespaceStr,
285-
},
286-
Spec: corev1.PodSpec{
287-
Containers: []corev1.Container{
288-
{
289-
Name: "ray-head",
290-
Image: "rayproject/autoscaler",
291-
Command: []string{"python"},
292-
Args: []string{"/opt/code.py"},
293-
},
294-
},
295-
},
296-
Status: corev1.PodStatus{
297-
Phase: corev1.PodRunning,
298-
},
299-
}
300-
301-
assert.Equal(t, PodNotMatchingTemplate(pod, headTemplate), false, "expect template & pod matching")
302-
303-
pod.Spec.Containers = []corev1.Container{
304-
{
305-
Name: "ray-head",
306-
Image: "rayproject/autoscaler",
307-
Command: []string{"python"},
308-
Args: []string{"/opt/code.py"},
309-
},
310-
{
311-
Name: "ray-head",
312-
Image: "rayproject/autoscaler",
313-
Command: []string{"python"},
314-
Args: []string{"/opt/code.py"},
315-
},
316-
}
317-
318-
assert.Equal(t, PodNotMatchingTemplate(pod, headTemplate), true, "expect template & pod with 2 containers not matching")
319-
320-
workerTemplate := corev1.PodTemplateSpec{
321-
Spec: corev1.PodSpec{
322-
Containers: []corev1.Container{
323-
{
324-
Name: "ray-worker",
325-
Image: "rayproject/autoscaler",
326-
Command: []string{"echo"},
327-
Args: []string{"Hello Ray"},
328-
Env: []corev1.EnvVar{
329-
{
330-
Name: "MY_POD_IP",
331-
ValueFrom: &corev1.EnvVarSource{
332-
FieldRef: &corev1.ObjectFieldSelector{
333-
FieldPath: "status.podIP",
334-
},
335-
},
336-
},
337-
},
338-
},
339-
},
340-
},
341-
}
342-
343-
pod = corev1.Pod{
344-
ObjectMeta: metav1.ObjectMeta{
345-
Name: "pod1",
346-
Namespace: namespaceStr,
347-
},
348-
Spec: corev1.PodSpec{
349-
Containers: []corev1.Container{
350-
{
351-
Name: "ray-worker",
352-
Image: "rayproject/autoscaler",
353-
Command: []string{"echo"},
354-
Args: []string{"Hello Ray"},
355-
},
356-
},
357-
},
358-
Status: corev1.PodStatus{
359-
Phase: corev1.PodRunning,
360-
},
361-
}
362-
363-
assert.Equal(t, PodNotMatchingTemplate(pod, workerTemplate), false, "expect template & pod matching")
364-
365-
workerTemplate = corev1.PodTemplateSpec{
366-
Spec: corev1.PodSpec{
367-
Containers: []corev1.Container{
368-
{
369-
Name: "ray-worker",
370-
Image: "rayproject/autoscaler",
371-
Command: []string{"echo"},
372-
Args: []string{"Hello Ray"},
373-
Resources: corev1.ResourceRequirements{
374-
Limits: corev1.ResourceList{
375-
corev1.ResourceCPU: resource.MustParse("500m"),
376-
corev1.ResourceMemory: resource.MustParse("512Mi"),
377-
},
378-
Requests: corev1.ResourceList{
379-
corev1.ResourceCPU: resource.MustParse("256m"),
380-
corev1.ResourceMemory: resource.MustParse("256Mi"),
381-
},
382-
},
383-
},
384-
},
385-
},
386-
}
387-
388-
pod = corev1.Pod{
389-
ObjectMeta: metav1.ObjectMeta{
390-
Name: "pod1",
391-
Namespace: namespaceStr,
392-
},
393-
Spec: corev1.PodSpec{
394-
Containers: []corev1.Container{
395-
{
396-
Name: "ray-worker",
397-
Image: "rayproject/autoscaler",
398-
Command: []string{"echo"},
399-
Args: []string{"Hello Ray"},
400-
Resources: corev1.ResourceRequirements{
401-
Limits: corev1.ResourceList{
402-
corev1.ResourceCPU: resource.MustParse("500m"),
403-
corev1.ResourceMemory: resource.MustParse("512Mi"),
404-
},
405-
Requests: corev1.ResourceList{
406-
corev1.ResourceCPU: resource.MustParse("256m"),
407-
corev1.ResourceMemory: resource.MustParse("256Mi"),
408-
},
409-
},
410-
},
411-
},
412-
},
413-
Status: corev1.PodStatus{
414-
Phase: corev1.PodRunning,
415-
},
416-
}
417-
418-
assert.Equal(t, PodNotMatchingTemplate(pod, workerTemplate), false, "expect template & pod matching")
419-
420-
pod.Spec.Containers[0].Resources.Limits[corev1.ResourceCPU] = resource.MustParse("50m")
421-
422-
assert.Equal(t, PodNotMatchingTemplate(pod, workerTemplate), true, "expect template & pod not matching")
423-
424-
pod.Spec.Containers[0].Resources.Limits[corev1.ResourceCPU] = resource.MustParse("500m")
425-
pod.Spec.Containers[0].Resources.Requests[corev1.ResourceCPU] = resource.MustParse("250m")
426-
427-
assert.Equal(t, PodNotMatchingTemplate(pod, workerTemplate), true, "expect template & pod not matching")
428-
}
429-
430254
func TestCalculateAvailableReplicas(t *testing.T) {
431255
podList := corev1.PodList{
432256
Items: []corev1.Pod{

ray-operator/main.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func main() {
5959
var probeAddr string
6060
var reconcileConcurrency int
6161
var watchNamespace string
62+
var forcedClusterUpgrade bool
6263
var logFile string
6364
var logFileEncoder string
6465
var logStdoutEncoder string
@@ -78,8 +79,8 @@ func main() {
7879
"watch-namespace",
7980
"",
8081
"Specify a list of namespaces to watch for custom resources, separated by commas. If left empty, all namespaces will be watched.")
81-
flag.BoolVar(&ray.ForcedClusterUpgrade, "forced-cluster-upgrade", false,
82-
"Forced cluster upgrade flag")
82+
flag.BoolVar(&forcedClusterUpgrade, "forced-cluster-upgrade", false,
83+
"(Deprecated) Forced cluster upgrade flag")
8384
flag.StringVar(&logFile, "log-file-path", "",
8485
"Synchronize logs to local file")
8586
flag.StringVar(&logFileEncoder, "log-file-encoder", "json",
@@ -108,7 +109,6 @@ func main() {
108109
exitOnError(err, "failed to decode config file")
109110

110111
// TODO: remove globally-scoped variables
111-
ray.ForcedClusterUpgrade = config.ForcedClusterUpgrade
112112
ray.EnableBatchScheduler = config.EnableBatchScheduler
113113
} else {
114114
config.MetricsAddr = metricsAddr
@@ -117,7 +117,6 @@ func main() {
117117
config.LeaderElectionNamespace = leaderElectionNamespace
118118
config.ReconcileConcurrency = reconcileConcurrency
119119
config.WatchNamespace = watchNamespace
120-
config.ForcedClusterUpgrade = ray.ForcedClusterUpgrade
121120
config.LogFile = logFile
122121
config.LogFileEncoder = logFileEncoder
123122
config.LogStdoutEncoder = logStdoutEncoder
@@ -153,8 +152,8 @@ func main() {
153152
ctrl.SetLogger(k8szap.New(k8szap.UseFlagOptions(&opts)))
154153
}
155154

156-
if ray.ForcedClusterUpgrade {
157-
setupLog.Info("Feature flag forced-cluster-upgrade is enabled.")
155+
if forcedClusterUpgrade {
156+
setupLog.Info("Deprecated feature flag forced-cluster-upgrade is enabled, which has no effect.")
158157
}
159158
if ray.EnableBatchScheduler {
160159
setupLog.Info("Feature flag enable-batch-scheduler is enabled.")

0 commit comments

Comments
 (0)