Skip to content

Commit 8637790

Browse files
feat: add scenarios field to space resources and support auto allocate sandbox resource (#1255)
Co-authored-by: ruibo.qin <qinphantom@gmail.com>
1 parent 0979069 commit 8637790

9 files changed

Lines changed: 156 additions & 16 deletions

File tree

_mocks/opencsg.com/csghub-server/builder/store/database/mock_SpaceResourceStore.go

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SET statement_timeout = 0;
2+
3+
--bun:split
4+
5+
ALTER TABLE space_resources DROP COLUMN IF EXISTS scenarios;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SET statement_timeout = 0;
2+
3+
--bun:split
4+
5+
ALTER TABLE space_resources ADD COLUMN IF NOT EXISTS scenarios text[] DEFAULT '{}';

builder/store/database/space_resource.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"fmt"
77

8+
"github.com/uptrace/bun/dialect/pgdialect"
9+
810
"opencsg.com/csghub-server/common/errorx"
911
"opencsg.com/csghub-server/common/types"
1012
)
@@ -23,6 +25,7 @@ type SpaceResourceStore interface {
2325
FindAll(ctx context.Context) ([]SpaceResource, error)
2426
FindAllResourceTypes(ctx context.Context, clusterId string) ([]string, error)
2527
FindByHardwareType(ctx context.Context, hardwareType string) ([]SpaceResource, error)
28+
FindByScenarios(ctx context.Context, scenarios []string) ([]SpaceResource, error)
2629
}
2730

2831
func NewSpaceResourceStore() SpaceResourceStore {
@@ -34,10 +37,11 @@ func NewSpaceResourceStoreWithDB(db *DB) SpaceResourceStore {
3437
}
3538

3639
type SpaceResource struct {
37-
ID int64 `bun:",pk,autoincrement" json:"id"`
38-
Name string `bun:",notnull" json:"name"`
39-
Resources string `bun:",notnull" json:"resources"`
40-
ClusterID string `bun:",notnull" json:"cluster_id"`
40+
ID int64 `bun:",pk,autoincrement" json:"id"`
41+
Name string `bun:",notnull" json:"name"`
42+
Resources string `bun:",notnull" json:"resources"`
43+
ClusterID string `bun:",notnull" json:"cluster_id"`
44+
Scenarios []string `bun:",array" json:"scenarios"`
4145
times
4246
}
4347

@@ -67,6 +71,9 @@ func (s *spaceResourceStoreImpl) Index(ctx context.Context, filter types.SpaceRe
6771
}
6872

6973
func (s *spaceResourceStoreImpl) Create(ctx context.Context, input SpaceResource) (*SpaceResource, error) {
74+
if input.Scenarios == nil {
75+
input.Scenarios = []string{}
76+
}
7077
res, err := s.db.Core.NewInsert().Model(&input).Exec(ctx, &input)
7178
if err := assertAffectedOneRow(res, err); err != nil {
7279
err = errorx.HandleDBError(err, errorx.Ctx().
@@ -180,3 +187,14 @@ func (s *spaceResourceStoreImpl) FindByHardwareType(ctx context.Context, hardwar
180187
}
181188
return result, nil
182189
}
190+
191+
func (s *spaceResourceStoreImpl) FindByScenarios(ctx context.Context, scenarios []string) ([]SpaceResource, error) {
192+
var result []SpaceResource
193+
err := s.db.Operator.Core.NewSelect().Model(&result).
194+
Where("scenarios && ?", pgdialect.Array(scenarios)).
195+
Scan(ctx)
196+
if err != nil {
197+
return nil, errorx.HandleDBError(err, nil)
198+
}
199+
return result, nil
200+
}

common/types/sandbox.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,20 @@ type SandboxVolume struct {
1818
type SandboxCreateRequest struct {
1919
UUID string `json:"-"`
2020
Image string `json:"image" binding:"required"`
21-
ResourceID int64 `json:"resource_id" binding:"required"`
21+
ResourceID int64 `json:"resource_id"`
2222
SandboxName string `json:"sandbox_name" binding:"required"`
2323
Environments map[string]string `json:"environments,omitempty"`
2424
Volumes []SandboxVolume `json:"volumes,omitempty"`
2525
Port int `json:"port,omitempty"`
2626
Timeout int `json:"timeout,omitempty"`
27+
MinCPU string `json:"min_cpu"`
28+
MinMemory string `json:"min_memory"`
2729
}
2830

2931
type SandboxUpdateRequest struct {
3032
UUID string `json:"-"`
3133
Image string `json:"image" binding:"required"`
32-
ResourceID int64 `json:"resource_id" binding:"required"`
34+
ResourceID int64 `json:"resource_id"`
3335
Environments map[string]string `json:"environments,omitempty"`
3436
Volumes []SandboxVolume `json:"volumes,omitempty"`
3537
Port int `json:"port,omitempty"`

common/types/space_resource.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
type ResourceType string
88
type PayMode string
9+
type ScenarioType string
910

1011
const (
1112
ResourceTypeCPU ResourceType = "cpu"
@@ -20,6 +21,8 @@ const (
2021
PayModeMinute PayMode = "minute"
2122
PayModeMonth PayMode = "month"
2223
PayModeYear PayMode = "year"
24+
25+
ScenarioSandbox ScenarioType = "sandbox"
2326
)
2427

2528
func ResourceTypeValid(resourceType ResourceType) bool {
@@ -53,18 +56,21 @@ type SpaceResource struct {
5356
OrderDetailId int64 `json:"order_detail_id"`
5457
AvailableStatusList []ResourceAvailableStatus `json:"available_status_list"`
5558
PriceUndefined bool `json:"price_undefined"`
59+
Scenarios []string `json:"scenarios"`
5660
}
5761

5862
type CreateSpaceResourceReq struct {
59-
Name string `json:"name" binding:"required"`
60-
Resources string `json:"resources" binding:"required"`
61-
ClusterID string `json:"cluster_id" binding:"required"`
63+
Name string `json:"name" binding:"required"`
64+
Resources string `json:"resources" binding:"required"`
65+
ClusterID string `json:"cluster_id" binding:"required"`
66+
Scenarios []string `json:"scenarios"`
6267
}
6368

6469
type UpdateSpaceResourceReq struct {
65-
ID int64 `json:"-"`
66-
Name string `json:"name"`
67-
Resources string `json:"resources"`
70+
ID int64 `json:"-"`
71+
Name string `json:"name"`
72+
Resources string `json:"resources"`
73+
Scenarios []string `json:"scenarios"`
6874
}
6975

7076
type SpaceResourceIndexReq struct {

component/space_resource.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ func validateResources(resources string) error {
4949
return nil
5050
}
5151

52+
func sanitizeScenarios(scenarios []string) []string {
53+
if scenarios == nil {
54+
return []string{}
55+
}
56+
seen := make(map[string]bool)
57+
result := make([]string, 0, len(scenarios))
58+
for _, s := range scenarios {
59+
s = strings.TrimSpace(s)
60+
if s == "" || seen[s] {
61+
continue
62+
}
63+
seen[s] = true
64+
result = append(result, s)
65+
}
66+
return result
67+
}
68+
5269
func (c *spaceResourceComponentImpl) Index(ctx context.Context, req *types.SpaceResourceIndexReq) ([]types.SpaceResource, int, error) {
5370
var result []types.SpaceResource
5471
var total int
@@ -100,6 +117,10 @@ func (c *spaceResourceComponentImpl) Index(ctx context.Context, req *types.Space
100117
}
101118
}
102119
resourceType := common.ResourceType(hardware)
120+
scenarios := r.Scenarios
121+
if scenarios == nil {
122+
scenarios = []string{}
123+
}
103124
singleClusterResult = append(singleClusterResult, types.SpaceResource{
104125
ID: r.ID,
105126
ClusterID: r.ClusterID,
@@ -108,6 +129,7 @@ func (c *spaceResourceComponentImpl) Index(ctx context.Context, req *types.Space
108129
Resources: r.Resources,
109130
IsAvailable: isAvailable,
110131
Type: resourceType,
132+
Scenarios: scenarios,
111133
AvailableStatusList: availableStatusList,
112134
})
113135
resourceCount++
@@ -144,16 +166,25 @@ func (c *spaceResourceComponentImpl) Update(ctx context.Context, req *types.Upda
144166
sr.Name = req.Name
145167
sr.Resources = req.Resources
146168

169+
if req.Scenarios != nil {
170+
sr.Scenarios = sanitizeScenarios(req.Scenarios)
171+
}
172+
147173
sr, err = c.spaceResourceStore.Update(ctx, *sr)
148174
if err != nil {
149175
slog.Error("error updating space resource", slog.Any("error", err))
150176
return nil, err
151177
}
152178

179+
scenarios := sr.Scenarios
180+
if scenarios == nil {
181+
scenarios = []string{}
182+
}
153183
result := &types.SpaceResource{
154184
ID: sr.ID,
155185
Name: sr.Name,
156186
Resources: sr.Resources,
187+
Scenarios: scenarios,
157188
}
158189

159190
return result, nil
@@ -167,17 +198,23 @@ func (c *spaceResourceComponentImpl) Create(ctx context.Context, req *types.Crea
167198
Name: req.Name,
168199
Resources: req.Resources,
169200
ClusterID: req.ClusterID,
201+
Scenarios: sanitizeScenarios(req.Scenarios),
170202
}
171203
res, err := c.spaceResourceStore.Create(ctx, sr)
172204
if err != nil {
173205
slog.Error("error creating space resource", slog.Any("error", err))
174206
return nil, err
175207
}
176208

209+
scenariosResult := res.Scenarios
210+
if scenariosResult == nil {
211+
scenariosResult = []string{}
212+
}
177213
result := &types.SpaceResource{
178214
ID: res.ID,
179215
Name: res.Name,
180216
Resources: res.Resources,
217+
Scenarios: scenariosResult,
181218
}
182219

183220
return result, nil
@@ -216,11 +253,16 @@ func (c *spaceResourceComponentImpl) ListAll(ctx context.Context) ([]types.Space
216253

217254
result := make([]types.SpaceResource, 0, len(dbResources))
218255
for _, r := range dbResources {
256+
scenarios := r.Scenarios
257+
if scenarios == nil {
258+
scenarios = []string{}
259+
}
219260
result = append(result, types.SpaceResource{
220261
ID: r.ID,
221262
Name: r.Name,
222263
ClusterID: r.ClusterID,
223264
Resources: r.Resources,
265+
Scenarios: scenarios,
224266
})
225267
}
226268

component/space_resource_ce_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestSpaceResourceComponent_Index(t *testing.T) {
3535
require.Equal(t, []types.SpaceResource{
3636
{
3737
ID: 1, Name: "sr", Resources: `{"memory": "1000", "gpu": {"num": "5"}}`,
38-
IsAvailable: false, Type: "gpu",
38+
IsAvailable: false, Type: "gpu", Scenarios: []string{},
3939
},
4040
}, data)
4141

component/space_resource_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func TestSpaceResourceComponent_Update(t *testing.T) {
7070
ID: 1,
7171
Name: "n",
7272
Resources: validResourcesJSON,
73+
Scenarios: []string{},
7374
}, data)
7475
}
7576

@@ -93,7 +94,8 @@ func TestSpaceResourceComponent_Create(t *testing.T) {
9394
Name: "n",
9495
Resources: validResourcesJSON,
9596
ClusterID: "c",
96-
}).Return(&database.SpaceResource{ID: 1, Name: "n", Resources: validResourcesJSON}, nil)
97+
Scenarios: []string{},
98+
}).Return(&database.SpaceResource{ID: 1, Name: "n", Resources: validResourcesJSON, Scenarios: []string{}}, nil)
9799

98100
data, err := sc.Create(ctx, &types.CreateSpaceResourceReq{
99101
Name: "n",
@@ -105,6 +107,7 @@ func TestSpaceResourceComponent_Create(t *testing.T) {
105107
ID: 1,
106108
Name: "n",
107109
Resources: validResourcesJSON,
110+
Scenarios: []string{},
108111
}, data)
109112
}
110113

@@ -187,8 +190,8 @@ func TestSpaceResourceComponent_ListAll(t *testing.T) {
187190
resources, err := sc.ListAll(ctx)
188191
require.Nil(t, err)
189192
require.Equal(t, []types.SpaceResource{
190-
{ID: 1, Name: "resource1", ClusterID: "c1", Resources: "{}"},
191-
{ID: 2, Name: "resource2", ClusterID: "c2", Resources: "{}"},
193+
{ID: 1, Name: "resource1", ClusterID: "c1", Resources: "{}", Scenarios: []string{}},
194+
{ID: 2, Name: "resource2", ClusterID: "c2", Resources: "{}", Scenarios: []string{}},
192195
}, resources)
193196
})
194197
t.Run("error listing all resources", func(t *testing.T) {

0 commit comments

Comments
 (0)