Skip to content

Commit 5bd74ed

Browse files
authored
Merge pull request #490 from elezar/add-mps-support
Add initial MPS support
2 parents 531e9e2 + 6ea5fa8 commit 5bd74ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+5518
-110
lines changed

api/config/v1/config.go

+4-25
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func NewConfig(c *cli.Context, flags []cli.Flag) (*Config, error) {
5959
// logger is used to issue warning in API functions without requiring an explicit implementation.
6060
type logger interface {
6161
Warning(...interface{})
62+
Warningf(string, ...interface{})
6263
}
6364

6465
// DisableResourceNamingInConfig temporarily disable the resource renaming feature of the plugin.
@@ -72,31 +73,9 @@ func DisableResourceNamingInConfig(logger logger, config *Config) {
7273
config.Resources.MIGs = nil
7374

7475
// Disable renaming / device selection in Sharing.TimeSlicing.Resources
75-
renameByDefault := config.Sharing.TimeSlicing.RenameByDefault
76-
setsNonDefaultRename := false
77-
setsDevices := false
78-
for i, r := range config.Sharing.TimeSlicing.Resources {
79-
if !renameByDefault && r.Rename != "" {
80-
setsNonDefaultRename = true
81-
config.Sharing.TimeSlicing.Resources[i].Rename = ""
82-
}
83-
if renameByDefault && r.Rename != r.Name.DefaultSharedRename() {
84-
setsNonDefaultRename = true
85-
config.Sharing.TimeSlicing.Resources[i].Rename = r.Name.DefaultSharedRename()
86-
}
87-
if !r.Devices.All {
88-
setsDevices = true
89-
config.Sharing.TimeSlicing.Resources[i].Devices.All = true
90-
config.Sharing.TimeSlicing.Resources[i].Devices.Count = 0
91-
config.Sharing.TimeSlicing.Resources[i].Devices.List = nil
92-
}
93-
}
94-
if setsNonDefaultRename {
95-
logger.Warning("Setting the 'rename' field in sharing.timeSlicing.resources is not yet supported in the config. Ignoring...")
96-
}
97-
if setsDevices {
98-
logger.Warning("Customizing the 'devices' field in sharing.timeSlicing.resources is not yet supported in the config. Ignoring...")
99-
}
76+
config.Sharing.TimeSlicing.disableResoureRenaming(logger, "timeSlicing")
77+
// Disable renaming / device selection in Sharing.MPS.Resources
78+
config.Sharing.MPS.disableResoureRenaming(logger, "mps")
10079
}
10180

10281
// parseConfig parses a config file as either YAML of JSON and unmarshals it into a Config struct.

api/config/v1/replicas.go

+48-4
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,57 @@ import (
2525
"github.com/google/uuid"
2626
)
2727

28-
// TimeSlicing defines the set of replicas to be made for timeSlicing available resources.
29-
type TimeSlicing struct {
28+
// ReplicatedResources defines generic options for replicating devices.
29+
type ReplicatedResources struct {
3030
RenameByDefault bool `json:"renameByDefault,omitempty" yaml:"renameByDefault,omitempty"`
3131
FailRequestsGreaterThanOne bool `json:"failRequestsGreaterThanOne,omitempty" yaml:"failRequestsGreaterThanOne,omitempty"`
3232
Resources []ReplicatedResource `json:"resources,omitempty" yaml:"resources,omitempty"`
3333
}
3434

35+
func (rrs *ReplicatedResources) disableResoureRenaming(logger logger, id string) {
36+
if rrs == nil {
37+
return
38+
}
39+
renameByDefault := rrs.RenameByDefault
40+
setsNonDefaultRename := false
41+
setsDevices := false
42+
for i, r := range rrs.Resources {
43+
if !renameByDefault && r.Rename != "" {
44+
setsNonDefaultRename = true
45+
rrs.Resources[i].Rename = ""
46+
}
47+
if renameByDefault && r.Rename != r.Name.DefaultSharedRename() {
48+
setsNonDefaultRename = true
49+
rrs.Resources[i].Rename = r.Name.DefaultSharedRename()
50+
}
51+
if !r.Devices.All {
52+
setsDevices = true
53+
rrs.Resources[i].Devices.All = true
54+
rrs.Resources[i].Devices.Count = 0
55+
rrs.Resources[i].Devices.List = nil
56+
}
57+
}
58+
if setsNonDefaultRename {
59+
logger.Warningf("Setting the 'rename' field in sharing.%s.resources is not yet supported in the config. Ignoring...", id)
60+
}
61+
if setsDevices {
62+
logger.Warningf("Customizing the 'devices' field in sharing.%s.resources is not yet supported in the config. Ignoring...", id)
63+
}
64+
65+
}
66+
67+
func (rrs *ReplicatedResources) isReplicated() bool {
68+
if rrs == nil {
69+
return false
70+
}
71+
for _, rr := range rrs.Resources {
72+
if rr.Replicas > 1 {
73+
return true
74+
}
75+
}
76+
return false
77+
}
78+
3579
// ReplicatedResource represents a resource to be replicated.
3680
type ReplicatedResource struct {
3781
Name ResourceName `json:"name" yaml:"name"`
@@ -117,8 +161,8 @@ func (d ReplicatedDeviceRef) IsMigUUID() bool {
117161
return true
118162
}
119163

120-
// UnmarshalJSON unmarshals raw bytes into a 'TimeSlicing' struct.
121-
func (s *TimeSlicing) UnmarshalJSON(b []byte) error {
164+
// UnmarshalJSON unmarshals raw bytes into a 'ReplicatedResources' struct.
165+
func (s *ReplicatedResources) UnmarshalJSON(b []byte) error {
122166
ts := make(map[string]json.RawMessage)
123167
err := json.Unmarshal(b, &ts)
124168
if err != nil {

api/config/v1/replicas_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,10 @@ func TestUnmarshalReplicatedResource(t *testing.T) {
371371
}
372372
}
373373

374-
func TestUnmarshalTimeSlicing(t *testing.T) {
374+
func TestUnmarshalReplicatedResources(t *testing.T) {
375375
testCases := []struct {
376376
input string
377-
output TimeSlicing
377+
output ReplicatedResources
378378
err bool
379379
}{
380380
{
@@ -400,7 +400,7 @@ func TestUnmarshalTimeSlicing(t *testing.T) {
400400
}
401401
]
402402
}`,
403-
output: TimeSlicing{
403+
output: ReplicatedResources{
404404
Resources: []ReplicatedResource{
405405
{
406406
Name: NoErrorNewResourceName("valid"),
@@ -423,7 +423,7 @@ func TestUnmarshalTimeSlicing(t *testing.T) {
423423
}
424424
]
425425
}`,
426-
output: TimeSlicing{
426+
output: ReplicatedResources{
427427
Resources: []ReplicatedResource{
428428
{
429429
Name: NoErrorNewResourceName("valid1"),
@@ -453,7 +453,7 @@ func TestUnmarshalTimeSlicing(t *testing.T) {
453453

454454
for i, tc := range testCases {
455455
t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) {
456-
var output TimeSlicing
456+
var output ReplicatedResources
457457
err := output.UnmarshalJSON([]byte(tc.input))
458458
if tc.err {
459459
require.Error(t, err)

api/config/v1/sharing.go

+32-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,36 @@ package v1
1818

1919
// Sharing encapsulates the set of sharing strategies that are supported.
2020
type Sharing struct {
21-
TimeSlicing TimeSlicing `json:"timeSlicing,omitempty" yaml:"timeSlicing,omitempty"`
21+
// TimeSlicing defines the set of replicas to be made for timeSlicing available resources.
22+
TimeSlicing ReplicatedResources `json:"timeSlicing,omitempty" yaml:"timeSlicing,omitempty"`
23+
// MPS defines the set of replicas to be shared using MPS
24+
MPS *ReplicatedResources `json:"mps,omitempty" yaml:"mps,omitempty"`
25+
}
26+
27+
type SharingStrategy string
28+
29+
const (
30+
SharingStrategyMPS = SharingStrategy("mps")
31+
SharingStrategyNone = SharingStrategy("none")
32+
SharingStrategyTimeSlicing = SharingStrategy("time-slicing")
33+
)
34+
35+
// SharingStrategy returns the active sharing strategy.
36+
func (s *Sharing) SharingStrategy() SharingStrategy {
37+
if s.MPS != nil && s.MPS.isReplicated() {
38+
return SharingStrategyMPS
39+
}
40+
41+
if s.TimeSlicing.isReplicated() {
42+
return SharingStrategyTimeSlicing
43+
}
44+
return SharingStrategyNone
45+
}
46+
47+
// ReplicatedResources returns the resources associated with the active sharing strategy.
48+
func (s *Sharing) ReplicatedResources() *ReplicatedResources {
49+
if s.MPS != nil {
50+
return s.MPS
51+
}
52+
return &s.TimeSlicing
2253
}

0 commit comments

Comments
 (0)