volcano.sh/volcano@v1.9.0/pkg/controllers/queue/queue_controller_action.go (about) 1 /* 2 Copyright 2019 The Volcano Authors. 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 queue 18 19 import ( 20 "context" 21 "fmt" 22 "reflect" 23 24 v1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/client-go/tools/cache" 27 "k8s.io/klog/v2" 28 29 "volcano.sh/apis/pkg/apis/bus/v1alpha1" 30 schedulingv1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1" 31 "volcano.sh/volcano/pkg/controllers/queue/state" 32 ) 33 34 func (c *queuecontroller) syncQueue(queue *schedulingv1beta1.Queue, updateStateFn state.UpdateQueueStatusFn) error { 35 klog.V(4).Infof("Begin to sync queue %s.", queue.Name) 36 defer klog.V(4).Infof("End sync queue %s.", queue.Name) 37 38 podGroups := c.getPodGroups(queue.Name) 39 queueStatus := schedulingv1beta1.QueueStatus{} 40 41 for _, pgKey := range podGroups { 42 // Ignore error here, tt can not occur. 43 ns, name, _ := cache.SplitMetaNamespaceKey(pgKey) 44 45 // TODO: check NotFound error and sync local cache. 46 pg, err := c.pgLister.PodGroups(ns).Get(name) 47 if err != nil { 48 return err 49 } 50 51 switch pg.Status.Phase { 52 case schedulingv1beta1.PodGroupPending: 53 queueStatus.Pending++ 54 case schedulingv1beta1.PodGroupRunning: 55 queueStatus.Running++ 56 case schedulingv1beta1.PodGroupUnknown: 57 queueStatus.Unknown++ 58 case schedulingv1beta1.PodGroupInqueue: 59 queueStatus.Inqueue++ 60 } 61 } 62 63 if updateStateFn != nil { 64 updateStateFn(&queueStatus, podGroups) 65 } else { 66 queueStatus.State = queue.Status.State 67 } 68 69 queueStatus.Allocated = queue.Status.Allocated.DeepCopy() 70 // queue.status.allocated will be updated after every session close in volcano scheduler, we should not depend on it because session may be time-consuming, 71 // and queue.status.allocated can't be updated timely. We initialize queue.status.allocated and update it here explicitly 72 // to avoid update queue err because update will fail when queue.status.allocated is nil. 73 if queueStatus.Allocated == nil { 74 queueStatus.Allocated = v1.ResourceList{} 75 } 76 77 // ignore update when status does not change 78 if reflect.DeepEqual(queueStatus, queue.Status) { 79 return nil 80 } 81 82 newQueue := queue.DeepCopy() 83 newQueue.Status = queueStatus 84 if _, err := c.vcClient.SchedulingV1beta1().Queues().UpdateStatus(context.TODO(), newQueue, metav1.UpdateOptions{}); err != nil { 85 klog.Errorf("Failed to update status of Queue %s: %v.", newQueue.Name, err) 86 return err 87 } 88 89 return nil 90 } 91 92 func (c *queuecontroller) openQueue(queue *schedulingv1beta1.Queue, updateStateFn state.UpdateQueueStatusFn) error { 93 klog.V(4).Infof("Begin to open queue %s.", queue.Name) 94 95 newQueue := queue.DeepCopy() 96 newQueue.Status.State = schedulingv1beta1.QueueStateOpen 97 98 if queue.Status.State != newQueue.Status.State { 99 if _, err := c.vcClient.SchedulingV1beta1().Queues().Update(context.TODO(), newQueue, metav1.UpdateOptions{}); err != nil { 100 c.recorder.Event(newQueue, v1.EventTypeWarning, string(v1alpha1.OpenQueueAction), 101 fmt.Sprintf("Open queue failed for %v", err)) 102 return err 103 } 104 105 c.recorder.Event(newQueue, v1.EventTypeNormal, string(v1alpha1.OpenQueueAction), "Open queue succeed") 106 } else { 107 return nil 108 } 109 110 q, err := c.vcClient.SchedulingV1beta1().Queues().Get(context.TODO(), newQueue.Name, metav1.GetOptions{}) 111 if err != nil { 112 return err 113 } 114 115 newQueue = q.DeepCopy() 116 if updateStateFn != nil { 117 updateStateFn(&newQueue.Status, nil) 118 } else { 119 return fmt.Errorf("internal error, update state function should be provided") 120 } 121 122 if queue.Status.State != newQueue.Status.State { 123 if _, err := c.vcClient.SchedulingV1beta1().Queues().UpdateStatus(context.TODO(), newQueue, metav1.UpdateOptions{}); err != nil { 124 c.recorder.Event(newQueue, v1.EventTypeWarning, string(v1alpha1.OpenQueueAction), 125 fmt.Sprintf("Update queue status from %s to %s failed for %v", 126 queue.Status.State, newQueue.Status.State, err)) 127 return err 128 } 129 } 130 131 return nil 132 } 133 134 func (c *queuecontroller) closeQueue(queue *schedulingv1beta1.Queue, updateStateFn state.UpdateQueueStatusFn) error { 135 klog.V(4).Infof("Begin to close queue %s.", queue.Name) 136 137 newQueue := queue.DeepCopy() 138 newQueue.Status.State = schedulingv1beta1.QueueStateClosed 139 140 if queue.Status.State != newQueue.Status.State { 141 if _, err := c.vcClient.SchedulingV1beta1().Queues().Update(context.TODO(), newQueue, metav1.UpdateOptions{}); err != nil { 142 c.recorder.Event(newQueue, v1.EventTypeWarning, string(v1alpha1.CloseQueueAction), 143 fmt.Sprintf("Close queue failed for %v", err)) 144 return err 145 } 146 147 c.recorder.Event(newQueue, v1.EventTypeNormal, string(v1alpha1.CloseQueueAction), "Close queue succeed") 148 } else { 149 return nil 150 } 151 152 q, err := c.vcClient.SchedulingV1beta1().Queues().Get(context.TODO(), newQueue.Name, metav1.GetOptions{}) 153 if err != nil { 154 return err 155 } 156 157 newQueue = q.DeepCopy() 158 podGroups := c.getPodGroups(newQueue.Name) 159 if updateStateFn != nil { 160 updateStateFn(&newQueue.Status, podGroups) 161 } else { 162 return fmt.Errorf("internal error, update state function should be provided") 163 } 164 165 if queue.Status.State != newQueue.Status.State { 166 if _, err := c.vcClient.SchedulingV1beta1().Queues().UpdateStatus(context.TODO(), newQueue, metav1.UpdateOptions{}); err != nil { 167 c.recorder.Event(newQueue, v1.EventTypeWarning, string(v1alpha1.CloseQueueAction), 168 fmt.Sprintf("Update queue status from %s to %s failed for %v", 169 queue.Status.State, newQueue.Status.State, err)) 170 return err 171 } 172 } 173 174 return nil 175 }