@@ -92,6 +92,11 @@ type kuberTask struct {
92
92
93
93
type podStatusFunc func () (* api.PodStatus , error )
94
94
95
+ type NodeInfo struct {
96
+ Cores int
97
+ Mem int64 // in bytes
98
+ }
99
+
95
100
// KubernetesExecutor is an mesos executor that runs pods
96
101
// in a minion machine.
97
102
type KubernetesExecutor struct {
@@ -113,6 +118,7 @@ type KubernetesExecutor struct {
113
118
staticPodsConfigPath string
114
119
podController * framework.Controller
115
120
launchGracePeriod time.Duration
121
+ nodeInfos chan <- NodeInfo
116
122
}
117
123
118
124
type Config struct {
@@ -127,6 +133,7 @@ type Config struct {
127
133
StaticPodsConfigPath string
128
134
PodLW cache.ListerWatcher // mandatory, otherwise initialiation will panic
129
135
LaunchGracePeriod time.Duration
136
+ NodeInfos chan <- NodeInfo
130
137
}
131
138
132
139
func (k * KubernetesExecutor ) isConnected () bool {
@@ -152,6 +159,7 @@ func New(config Config) *KubernetesExecutor {
152
159
podStatusFunc : config .PodStatusFunc ,
153
160
staticPodsConfigPath : config .StaticPodsConfigPath ,
154
161
launchGracePeriod : config .LaunchGracePeriod ,
162
+ nodeInfos : config .NodeInfos ,
155
163
}
156
164
157
165
// watch pods from the given pod ListWatch
@@ -236,6 +244,10 @@ func (k *KubernetesExecutor) Registered(driver bindings.ExecutorDriver,
236
244
Pods : []* api.Pod {},
237
245
Op : kubetypes .SET ,
238
246
})
247
+
248
+ if slaveInfo != nil && k .nodeInfos != nil {
249
+ k .nodeInfos <- nodeInfo (slaveInfo , executorInfo ) // leave it behind the upper lock to avoid panics
250
+ }
239
251
}
240
252
241
253
// Reregistered is called when the executor is successfully re-registered with the slave.
@@ -255,6 +267,16 @@ func (k *KubernetesExecutor) Reregistered(driver bindings.ExecutorDriver, slaveI
255
267
log .Errorf ("cannot update node labels: %v" , err )
256
268
}
257
269
}
270
+
271
+ if slaveInfo != nil && k .nodeInfos != nil {
272
+ // make sure nodeInfos is not nil and send new NodeInfo
273
+ k .lock .Lock ()
274
+ defer k .lock .Unlock ()
275
+ if k .isDone () {
276
+ return
277
+ }
278
+ k .nodeInfos <- nodeInfo (slaveInfo , nil )
279
+ }
258
280
}
259
281
260
282
// initializeStaticPodsSource unzips the data slice into the static-pods directory
@@ -796,6 +818,7 @@ func (k *KubernetesExecutor) doShutdown(driver bindings.ExecutorDriver) {
796
818
// signal to all listeners that this KubeletExecutor is done!
797
819
close (k .terminate )
798
820
close (k .updateChan )
821
+ close (k .nodeInfos )
799
822
800
823
if k .shutdownAlert != nil {
801
824
func () {
@@ -926,3 +949,41 @@ func differentTime(a, b *unversionedapi.Time) bool {
926
949
func differentPeriod (a , b * int64 ) bool {
927
950
return (a == nil ) != (b == nil ) || (a != nil && b != nil && * a != * b )
928
951
}
952
+
953
+ func nodeInfo (si * mesos.SlaveInfo , ei * mesos.ExecutorInfo ) NodeInfo {
954
+ var executorCPU , executorMem float64
955
+
956
+ // get executor resources
957
+ if ei != nil {
958
+ for _ , r := range ei .GetResources () {
959
+ if r == nil || r .GetType () != mesos .Value_SCALAR {
960
+ continue
961
+ }
962
+ switch r .GetName () {
963
+ case "cpus" :
964
+ executorCPU = r .GetScalar ().GetValue ()
965
+ case "mem" :
966
+ executorMem = r .GetScalar ().GetValue ()
967
+ }
968
+ }
969
+ }
970
+
971
+ // get resource capacity of the node
972
+ ni := NodeInfo {}
973
+ for _ , r := range si .GetResources () {
974
+ if r == nil || r .GetType () != mesos .Value_SCALAR {
975
+ continue
976
+ }
977
+
978
+ switch r .GetName () {
979
+ case "cpus" :
980
+ // We intentionally take the floor of executorCPU because cores are integers
981
+ // and we would loose a complete cpu here if the value is <1.
982
+ // TODO(sttts): switch to float64 when "Machine Allocables" are implemented
983
+ ni .Cores = int (r .GetScalar ().GetValue () - float64 (int (executorCPU )))
984
+ case "mem" :
985
+ ni .Mem = int64 (r .GetScalar ().GetValue ()- executorMem ) * 1024 * 1024
986
+ }
987
+ }
988
+ return ni
989
+ }
0 commit comments