@@ -23,15 +23,13 @@ import (
23
23
24
24
log "github.com/sirupsen/logrus"
25
25
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
26
- "k8s.io/apimachinery/pkg/runtime"
26
+ "k8s.io/apimachinery/pkg/runtime/schema "
27
27
"k8s.io/apimachinery/pkg/util/wait"
28
28
"k8s.io/client-go/tools/cache"
29
29
"k8s.io/client-go/util/workqueue"
30
- vcqueue "volcano.sh/apis/pkg/apis/scheduling/v1beta1"
31
-
32
30
"paddleflow/pkg/apiserver/models"
33
31
"paddleflow/pkg/common/k8s"
34
- "paddleflow/pkg/common/schema"
32
+ queueschema "paddleflow/pkg/common/schema"
35
33
)
36
34
37
35
const (
@@ -47,9 +45,10 @@ type QueueSyncInfo struct {
47
45
48
46
type QueueSync struct {
49
47
sync.Mutex
50
- opt * k8s.DynamicClientOption
51
- jobQueue workqueue.RateLimitingInterface
52
- vcQueueInformer cache.SharedIndexInformer
48
+ opt * k8s.DynamicClientOption
49
+ jobQueue workqueue.RateLimitingInterface
50
+ // informerMap contains GroupVersionKind and informer for queue, and ElasticResourceQuota
51
+ informerMap map [schema.GroupVersionKind ]cache.SharedIndexInformer
53
52
}
54
53
55
54
func NewQueueSync () Controller {
@@ -64,29 +63,32 @@ func (qs *QueueSync) Initialize(opt *k8s.DynamicClientOption) error {
64
63
log .Infof ("Initialize %s controller!" , qs .Name ())
65
64
qs .opt = opt
66
65
qs .jobQueue = workqueue .NewRateLimitingQueue (workqueue .DefaultControllerRateLimiter ())
67
-
68
- vcQueueGVRMap , err := qs .opt .GetGVR (k8s .VCQueueGVK )
69
- if err != nil {
70
- log .Warnf ("cann't find GroupVersionKind [%s]" , k8s .VCQueueGVK )
71
- } else {
72
- qs .vcQueueInformer = qs .opt .DynamicFactory .ForResource (vcQueueGVRMap .Resource ).Informer ()
73
- qs .vcQueueInformer .AddEventHandler (cache.ResourceEventHandlerFuncs {
74
- UpdateFunc : qs .updateQueue ,
75
- DeleteFunc : qs .deleteQueue ,
76
- })
66
+ qs .informerMap = make (map [schema.GroupVersionKind ]cache.SharedIndexInformer )
67
+
68
+ for _ , gvk := range k8s .GVKToQuotaType {
69
+ gvrMap , err := qs .opt .GetGVR (gvk )
70
+ if err != nil {
71
+ log .Warnf ("cann't find GroupVersionKind [%s]" , gvk )
72
+ } else {
73
+ qs .informerMap [gvk ] = qs .opt .DynamicFactory .ForResource (gvrMap .Resource ).Informer ()
74
+ qs .informerMap [gvk ].AddEventHandler (cache.ResourceEventHandlerFuncs {
75
+ UpdateFunc : qs .updateQueue ,
76
+ DeleteFunc : qs .deleteQueue ,
77
+ })
78
+ }
77
79
}
78
80
return nil
79
81
}
80
82
81
83
func (qs * QueueSync ) Run (stopCh <- chan struct {}) {
82
- if qs .vcQueueInformer == nil {
83
- log .Infof ("Cluster hasn't vc queue , skip %s controller!" , qs .Name ())
84
+ if len ( qs .informerMap ) == 0 {
85
+ log .Infof ("Cluster hasn't needed GroupVersionKind , skip %s controller!" , qs .Name ())
84
86
return
85
87
}
86
88
go qs .opt .DynamicFactory .Start (stopCh )
87
89
88
- if qs . vcQueueInformer != nil {
89
- if ! cache .WaitForCacheSync (stopCh , qs . vcQueueInformer .HasSynced ) {
90
+ for _ , informer := range qs . informerMap {
91
+ if ! cache .WaitForCacheSync (stopCh , informer .HasSynced ) {
90
92
log .Errorf ("timed out waiting for caches to %s" , qs .Name ())
91
93
return
92
94
}
@@ -124,51 +126,57 @@ func (qs *QueueSync) processWorkItem() bool {
124
126
125
127
// updateQueue for queue update event
126
128
func (qs * QueueSync ) updateQueue (oldObj , newObj interface {}) {
127
- oldQueue , err := unstructuredToVCQueue (oldObj )
128
- if err != nil {
129
+ oldQueue := oldObj .(* unstructured.Unstructured )
130
+ queue := newObj .(* unstructured.Unstructured )
131
+
132
+ oldSpec , err := getResourceSpec (oldQueue )
133
+ if err != nil || oldSpec == nil {
134
+ log .Errorf ("get spec from old resource object %s failed" , oldQueue .GetName ())
129
135
return
130
136
}
131
- queue , err := unstructuredToVCQueue (newObj )
132
- if err != nil {
137
+ spec , err := getResourceSpec (queue )
138
+ if err != nil || spec == nil {
139
+ log .Errorf ("get spec from new resource object %s failed" , queue .GetName ())
133
140
return
134
141
}
135
- log .Debugf ("vcQueueInformer update begin. oldQueue:%v newQueue:%v" , oldQueue , queue )
136
- if reflect .DeepEqual (oldQueue .Spec , queue .Spec ) && oldQueue .Status == queue .Status {
142
+
143
+ log .Debugf ("%s queue resource is updated. old:%v new:%v" , queue .GroupVersionKind (), oldQueue , queue )
144
+ if reflect .DeepEqual (oldSpec , spec ) {
137
145
return
138
146
}
139
- status := string (queue .Status .State )
140
- if ! reflect .DeepEqual (oldQueue .Spec , queue .Spec ) {
141
- status = schema .StatusQueueUnavailable
142
- }
147
+
148
+ log .Infof ("watch %s resource is updated, name is %s" , queue .GroupVersionKind (), queue .GetName ())
149
+ var status = queueschema .StatusQueueUnavailable
143
150
queueInfo := & QueueSyncInfo {
144
- Name : queue .Name ,
151
+ Name : queue .GetName () ,
145
152
Status : status ,
146
- Message : fmt .Sprintf ("queue[%s] is update from cluster" , queue .Name ),
153
+ Message : fmt .Sprintf ("queue[%s] is update from cluster" , queue .GetName () ),
147
154
}
148
155
qs .jobQueue .Add (queueInfo )
149
156
}
150
157
151
- // deleteQueue for queue delete event
158
+ // deleteQueue for queue resource delete event
152
159
func (qs * QueueSync ) deleteQueue (obj interface {}) {
153
- queue , err := unstructuredToVCQueue (obj )
154
- if err != nil {
155
- return
156
- }
157
- log .Debugf ("vcQueueInformer DeleteFunc. queueName:%s" , queue .Name )
160
+ queueObj := obj .(* unstructured.Unstructured )
161
+ log .Infof ("watch %s resource is deleted, name is %s" , queueObj .GroupVersionKind (), queueObj .GetName ())
162
+
158
163
queueInfo := & QueueSyncInfo {
159
- Name : queue . Name ,
160
- Status : schema .StatusQueueUnavailable ,
161
- Message : fmt .Sprintf ("queue[%s] is deleted from cluster" , queue . Name ),
164
+ Name : queueObj . GetName () ,
165
+ Status : queueschema .StatusQueueUnavailable ,
166
+ Message : fmt .Sprintf ("queue resource [%s] is deleted from cluster" , queueObj . GetName () ),
162
167
}
163
168
qs .jobQueue .Add (queueInfo )
164
169
}
165
170
166
- func unstructuredToVCQueue (obj interface {}) (* vcqueue.Queue , error ) {
167
- queueObj := obj .(* unstructured.Unstructured )
168
- queue := & vcqueue.Queue {}
169
- if err := runtime .DefaultUnstructuredConverter .FromUnstructured (queueObj .Object , queue ); err != nil {
170
- log .Errorf ("convert unstructured object[%+v] to sparkApp failed: %v" , obj , err )
171
- return nil , err
171
+ func getResourceSpec (queueObj * unstructured.Unstructured ) (interface {}, error ) {
172
+ spec , ok , unerr := unstructured .NestedFieldCopy (queueObj .Object , "spec" )
173
+ if ! ok {
174
+ if unerr != nil {
175
+ log .Error (unerr , "NestedFieldCopy unstructured to spec error" )
176
+ return nil , unerr
177
+ }
178
+ log .Info ("NestedFieldCopy unstructured to spec error: Spec is not found in resource" )
179
+ return nil , fmt .Errorf ("get spec from unstructured object failed" )
172
180
}
173
- return queue , nil
181
+ return spec , nil
174
182
}
0 commit comments