@@ -11,12 +11,14 @@ import (
11
11
"path/filepath"
12
12
"strconv"
13
13
"strings"
14
+ "sync"
14
15
"time"
15
16
16
17
"github.com/docker/go-connections/nat"
17
18
"github.com/docker/go-units"
18
19
"github.com/pkg/errors"
19
20
21
+ corecluster "github.com/projecteru2/core/cluster"
20
22
"github.com/projecteru2/core/log"
21
23
22
24
dockertypes "github.com/docker/docker/api/types"
@@ -31,9 +33,10 @@ import (
31
33
)
32
34
33
35
const (
34
- minMemory = units .MiB * 4
35
- maxMemory = math .MaxInt64
36
- root = "root"
36
+ minMemory = units .MiB * 4
37
+ maxMemory = math .MaxInt64
38
+ defaultCPUShare = 1024
39
+ root = "root"
37
40
)
38
41
39
42
type rawArgs struct {
@@ -220,8 +223,56 @@ func (e *Engine) VirtualizationCreate(ctx context.Context, opts *enginetypes.Vir
220
223
return r , err
221
224
}
222
225
226
+ // VirtualizationResourceRemap to re-distribute resource according to the whole picture
227
+ // supposedly it's exclusively executed, so free feel to operate IO from remote dockerd
223
228
func (e * Engine ) VirtualizationResourceRemap (ctx context.Context , opts * enginetypes.VirtualizationRemapOptions ) (<- chan enginetypes.VirtualizationRemapMessage , error ) {
224
- return nil , nil
229
+ // calculate share pool
230
+ sharePool := []string {}
231
+ for cpuID , available := range opts .CPUAvailable {
232
+ if available >= opts .CPUShareBase {
233
+ sharePool = append (sharePool , cpuID )
234
+ }
235
+ }
236
+ shareCPUSet := strings .Join (sharePool , "," )
237
+ if shareCPUSet == "" {
238
+ info , err := e .Info (ctx )
239
+ if err != nil {
240
+ return nil , errors .WithStack (err )
241
+ }
242
+ shareCPUSet = fmt .Sprintf ("0-%d" , info .NCPU - 1 )
243
+ }
244
+
245
+ // filter out workloads non-binding
246
+ freeWorkloadResources := map [string ]enginetypes.VirtualizationResource {}
247
+ for workloadID , resource := range opts .WorkloadResources {
248
+ if resource .CPU == nil {
249
+ freeWorkloadResources [workloadID ] = resource
250
+ }
251
+ }
252
+
253
+ // update!
254
+ wg := sync.WaitGroup {}
255
+ ch := make (chan enginetypes.VirtualizationRemapMessage )
256
+ for id , resource := range freeWorkloadResources {
257
+ // TODO@zc: limit the max goroutine
258
+ wg .Add (1 )
259
+ go func (id string , resource enginetypes.VirtualizationResource ) {
260
+ defer wg .Done ()
261
+ updateConfig := dockercontainer.UpdateConfig {Resources : dockercontainer.Resources {
262
+ CPUQuota : int64 (resource .Quota * float64 (corecluster .CPUPeriodBase )),
263
+ CPUPeriod : corecluster .CPUPeriodBase ,
264
+ CpusetCpus : shareCPUSet ,
265
+ CPUShares : defaultCPUShare ,
266
+ }}
267
+ _ , err := e .client .ContainerUpdate (ctx , id , updateConfig )
268
+ ch <- enginetypes.VirtualizationRemapMessage {
269
+ ID : id ,
270
+ Error : err ,
271
+ }
272
+ }(id , resource )
273
+ }
274
+ wg .Wait ()
275
+ return ch , nil
225
276
}
226
277
227
278
// VirtualizationCopyTo copy things to virtualization
0 commit comments