Skip to content

Commit 2c74c42

Browse files
author
calvin
committed
support split table for internal storage
Signed-off-by: calvin <[email protected]>
1 parent 29c0306 commit 2c74c42

File tree

6 files changed

+173
-60
lines changed

6 files changed

+173
-60
lines changed

examples/pediacluster.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ metadata:
44
name: cluster-example
55
spec:
66
apiserver: "https://10.30.43.43:6443"
7-
caData:
7+
caData:
88
tokenData:
99
certData:
1010
keyData:

pkg/storage/internalstorage/register.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ func NewStorageFactory(configPath string) (storage.StorageFactory, error) {
9393
sqlDB.SetMaxOpenConns(connPool.MaxOpenConns)
9494
sqlDB.SetConnMaxLifetime(connPool.ConnMaxLifetime)
9595

96-
return &StorageFactory{db}, nil
96+
return &StorageFactory{
97+
db: db,
98+
AutoMigration: cfg.AutoMigration,
99+
DivisionPolicy: cfg.DivisionPolicy,
100+
Mapper: cfg.Mapper,
101+
}, nil
97102
}
98103

99104
func newLogger(cfg *Config) (logger.Interface, error) {

pkg/storage/internalstorage/resource_storage.go

+35-28
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ import (
2727
)
2828

2929
type ResourceStorage struct {
30-
db *gorm.DB
31-
codec runtime.Codec
32-
30+
db *gorm.DB
31+
codec runtime.Codec
32+
model interface{}
3333
storageGroupResource schema.GroupResource
3434
storageVersion schema.GroupVersion
3535
memoryVersion schema.GroupVersion
@@ -116,14 +116,18 @@ func (s *ResourceStorage) Update(ctx context.Context, cluster string, obj runtim
116116
updatedResource["deleted_at"] = sql.NullTime{Time: deletedAt.Time, Valid: true}
117117
}
118118

119-
result := s.db.WithContext(ctx).Model(&Resource{}).Where(map[string]interface{}{
120-
"cluster": cluster,
121-
"group": s.storageGroupResource.Group,
122-
"version": s.storageVersion.Version,
123-
"resource": s.storageGroupResource.Resource,
124-
"namespace": metaobj.GetNamespace(),
125-
"name": metaobj.GetName(),
126-
}).Updates(updatedResource)
119+
result := s.db.WithContext(ctx).
120+
Model(s.model).
121+
Where(map[string]interface{}{
122+
"cluster": cluster,
123+
"group": s.storageGroupResource.Group,
124+
"version": s.storageVersion.Version,
125+
"resource": s.storageGroupResource.Resource,
126+
"namespace": metaobj.GetNamespace(),
127+
"name": metaobj.GetName(),
128+
}).
129+
Updates(updatedResource)
130+
127131
return InterpretResourceDBError(cluster, metaobj.GetName(), result.Error)
128132
}
129133

@@ -144,14 +148,16 @@ func (s *ResourceStorage) ConvertDeletedObject(obj interface{}) (runtime.Object,
144148
}
145149

146150
func (s *ResourceStorage) deleteObject(cluster, namespace, name string) *gorm.DB {
147-
return s.db.Model(&Resource{}).Where(map[string]interface{}{
148-
"cluster": cluster,
149-
"group": s.storageGroupResource.Group,
150-
"version": s.storageVersion.Version,
151-
"resource": s.storageGroupResource.Resource,
152-
"namespace": namespace,
153-
"name": name,
154-
}).Delete(&Resource{})
151+
return s.db.Model(s.model).
152+
Where(map[string]interface{}{
153+
"cluster": cluster,
154+
"group": s.storageGroupResource.Group,
155+
"version": s.storageVersion.Version,
156+
"resource": s.storageGroupResource.Resource,
157+
"namespace": namespace,
158+
"name": name,
159+
}).
160+
Delete(&Resource{})
155161
}
156162

157163
func (s *ResourceStorage) Delete(ctx context.Context, cluster string, obj runtime.Object) error {
@@ -167,14 +173,15 @@ func (s *ResourceStorage) Delete(ctx context.Context, cluster string, obj runtim
167173
}
168174

169175
func (s *ResourceStorage) genGetObjectQuery(ctx context.Context, cluster, namespace, name string) *gorm.DB {
170-
return s.db.WithContext(ctx).Model(&Resource{}).Select("object").Where(map[string]interface{}{
171-
"cluster": cluster,
172-
"group": s.storageGroupResource.Group,
173-
"version": s.storageVersion.Version,
174-
"resource": s.storageGroupResource.Resource,
175-
"namespace": namespace,
176-
"name": name,
177-
})
176+
return s.db.WithContext(ctx).Model(s.model).Select("object").
177+
Where(map[string]interface{}{
178+
"cluster": cluster,
179+
"group": s.storageGroupResource.Group,
180+
"version": s.storageVersion.Version,
181+
"resource": s.storageGroupResource.Resource,
182+
"namespace": namespace,
183+
"name": name,
184+
})
178185
}
179186

180187
func (s *ResourceStorage) Get(ctx context.Context, cluster, namespace, name string, into runtime.Object) error {
@@ -199,7 +206,7 @@ func (s *ResourceStorage) genListObjectsQuery(ctx context.Context, opts *interna
199206
result = &ResourceMetadataList{}
200207
}
201208

202-
query := s.db.WithContext(ctx).Model(&Resource{})
209+
query := s.db.WithContext(ctx).Model(s.model)
203210
query = query.Where(map[string]interface{}{
204211
"group": s.storageGroupResource.Group,
205212
"version": s.storageVersion.Version,

pkg/storage/internalstorage/resource_storage_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ func TestResourceStorage_Update(t *testing.T) {
465465

466466
func newTestResourceStorage(db *gorm.DB, storageGVK schema.GroupVersionResource) *ResourceStorage {
467467
return &ResourceStorage{
468-
db: db,
468+
db: db.Table("resources"),
469+
model: &Resource{},
469470
storageGroupResource: storageGVK.GroupResource(),
470471
storageVersion: storageGVK.GroupVersion(),
471472
}

pkg/storage/internalstorage/storage.go

+106-28
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package internalstorage
33
import (
44
"context"
55
"fmt"
6+
"strings"
7+
"sync"
68

79
"gorm.io/gorm"
810
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -11,6 +13,8 @@ import (
1113
"github.com/clusterpedia-io/clusterpedia/pkg/storage"
1214
)
1315

16+
var mutex sync.Mutex
17+
1418
type StorageFactory struct {
1519
db *gorm.DB
1620
AutoMigration *bool
@@ -19,35 +23,61 @@ type StorageFactory struct {
1923
}
2024

2125
func (s *StorageFactory) AutoMigrate() error {
26+
return nil
27+
}
28+
29+
func (s *StorageFactory) GetSupportedRequestVerbs() []string {
30+
return []string{"get", "list"}
31+
}
32+
33+
func (s *StorageFactory) NewResourceStorage(config *storage.ResourceStorageConfig) (storage.ResourceStorage, error) {
34+
mutex.Lock()
35+
defer mutex.Unlock()
36+
37+
gvr := schema.GroupVersionResource{
38+
Group: config.StorageGroupResource.Group,
39+
Version: config.StorageVersion.Version,
40+
Resource: config.StorageGroupResource.Resource,
41+
}
42+
table := s.tableName(gvr)
43+
44+
var model interface{}
2245
if s.AutoMigration != nil && *s.AutoMigration {
46+
model = &Resource{}
47+
2348
switch s.DivisionPolicy {
24-
if err := s.db.AutoMigrate(&Resource{}); err != nil {
25-
return err
49+
case DivisionPolicyNone:
50+
if exist := s.db.Migrator().HasTable(table); !exist {
51+
if err := s.db.AutoMigrate(&Resource{}); err != nil {
52+
return nil, err
53+
}
2654
}
27-
case "", DivisionPolicyNone:
2855
case DivisionPolicyGroupResource:
56+
model = &GroupVersionResource{}
2957

30-
}
58+
if exist := s.db.Migrator().HasTable(table); !exist {
59+
if err := s.db.AutoMigrate(&GroupVersionResource{}); err != nil {
60+
return nil, err
61+
}
3162

32-
if s.DivisionPolicy == "" || s.DivisionPolicy == DivisionPolicyNone {
33-
if err := s.db.AutoMigrate(&Resource{}); err != nil {
34-
return err
63+
err := s.db.Migrator().RenameTable("groupversionresources", table)
64+
if err != nil {
65+
return nil, err
66+
}
67+
}
68+
default:
69+
if exist := s.db.Migrator().HasTable(table); !exist {
70+
if err := s.db.AutoMigrate(&Resource{}); err != nil {
71+
return nil, err
72+
}
3573
}
3674
}
3775
}
3876

39-
return nil
40-
}
41-
42-
func (s *StorageFactory) GetSupportedRequestVerbs() []string {
43-
return []string{"get", "list"}
44-
}
45-
46-
func (s *StorageFactory) NewResourceStorage(config *storage.ResourceStorageConfig) (storage.ResourceStorage, error) {
4777
return &ResourceStorage{
48-
db: s.db,
49-
codec: config.Codec,
50-
78+
db: s.db.Table(table),
79+
model: model,
80+
codec: config.Codec,
5181
storageGroupResource: config.StorageGroupResource,
5282
storageVersion: config.StorageVersion,
5383
memoryVersion: config.MemoryVersion,
@@ -65,7 +95,8 @@ func (s *StorageFactory) NewCollectionResourceStorage(cr *internal.CollectionRes
6595

6696
func (s *StorageFactory) GetResourceVersions(ctx context.Context, cluster string) (map[schema.GroupVersionResource]map[string]interface{}, error) {
6797
var resources []Resource
68-
result := s.db.WithContext(ctx).Select("group", "version", "resource", "namespace", "name", "resource_version").
98+
result := s.db.WithContext(ctx).
99+
Select("group", "version", "resource", "namespace", "name", "resource_version").
69100
Where(map[string]interface{}{"cluster": cluster}).
70101
Find(&resources)
71102
if result.Error != nil {
@@ -91,18 +122,46 @@ func (s *StorageFactory) GetResourceVersions(ctx context.Context, cluster string
91122
}
92123

93124
func (s *StorageFactory) CleanCluster(ctx context.Context, cluster string) error {
94-
result := s.db.WithContext(ctx).Where(map[string]interface{}{"cluster": cluster}).Delete(&Resource{})
95-
return InterpretDBError(cluster, result.Error)
125+
mutex.Lock()
126+
tables, err := s.db.Migrator().GetTables()
127+
if err != nil {
128+
mutex.Unlock()
129+
return err
130+
}
131+
mutex.Unlock()
132+
133+
for _, table := range tables {
134+
result := s.db.WithContext(ctx).Table(table).Where(map[string]interface{}{"cluster": cluster}).Delete(&Resource{})
135+
if result.Error != nil {
136+
return InterpretDBError(cluster, result.Error)
137+
}
138+
}
139+
140+
return nil
96141
}
97142

98143
func (s *StorageFactory) CleanClusterResource(ctx context.Context, cluster string, gvr schema.GroupVersionResource) error {
99-
result := s.db.WithContext(ctx).Where(map[string]interface{}{
100-
"cluster": cluster,
101-
"group": gvr.Group,
102-
"version": gvr.Version,
103-
"resource": gvr.Resource,
104-
}).Delete(&Resource{})
105-
return InterpretDBError(fmt.Sprintf("%s/%s", cluster, gvr), result.Error)
144+
table := s.tableName(gvr)
145+
146+
err := s.db.Transaction(func(db *gorm.DB) error {
147+
result := s.db.WithContext(ctx).
148+
Table(table).
149+
Where(map[string]interface{}{
150+
"cluster": cluster,
151+
"group": gvr.Group,
152+
"version": gvr.Version,
153+
"resource": gvr.Resource,
154+
}).
155+
Delete(&Resource{})
156+
157+
if result.Error != nil {
158+
return result.Error
159+
}
160+
161+
return nil
162+
})
163+
164+
return InterpretDBError(fmt.Sprintf("%s/%s", cluster, gvr), err)
106165
}
107166

108167
func (s *StorageFactory) GetCollectionResources(ctx context.Context) ([]*internal.CollectionResource, error) {
@@ -116,3 +175,22 @@ func (s *StorageFactory) GetCollectionResources(ctx context.Context) ([]*interna
116175
func (s *StorageFactory) PrepareCluster(cluster string) error {
117176
return nil
118177
}
178+
179+
func (s *StorageFactory) tableName(gvr schema.GroupVersionResource) string {
180+
table := "resources"
181+
if s.DivisionPolicy == DivisionPolicyCustom {
182+
table = GenerateTableFor(gvr)
183+
}
184+
185+
return table
186+
}
187+
188+
// GenerateTableFor return table name using gvr string
189+
func GenerateTableFor(gvr schema.GroupVersionResource) string {
190+
if gvr.Group == "" {
191+
return fmt.Sprintf("%s_%s", gvr.Version, gvr.Resource)
192+
}
193+
194+
group := strings.ReplaceAll(gvr.Group, ".", "_")
195+
return fmt.Sprintf("%s_%s_%s", group, gvr.Version, gvr.Resource)
196+
}

pkg/storage/internalstorage/types.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type Resource struct {
5151
ID uint `gorm:"primaryKey"`
5252

5353
Group string `gorm:"size:63;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name;index:idx_group_version_resource_namespace_name;index:idx_group_version_resource_name"`
54-
Version string `gorm:"size:15;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name;index:idx_group_version_resource_namespace_name;index:idx_group_version_resource_name"`
54+
Version string `gorm:"size:14;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name;index:idx_group_version_resource_namespace_name;index:idx_group_version_resource_name"`
5555
Resource string `gorm:"size:63;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name;index:idx_group_version_resource_namespace_name;index:idx_group_version_resource_name"`
5656
Kind string `gorm:"size:63;not null"`
5757

@@ -99,6 +99,28 @@ func (res Resource) ConvertTo(codec runtime.Codec, object runtime.Object) (runti
9999
return obj, err
100100
}
101101

102+
type GroupVersionResource struct {
103+
ID uint `gorm:"primaryKey"`
104+
105+
Group string `gorm:"size:63;not null"`
106+
Version string `gorm:"size:14;not null"`
107+
Resource string `gorm:"size:63;not null"`
108+
Kind string `gorm:"size:63;not null"`
109+
110+
Cluster string `gorm:"size:253;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name,length:100;index:idx_cluster"`
111+
Namespace string `gorm:"size:253;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name,length:50;index:idx_group_version_resource_namespace_name"`
112+
Name string `gorm:"size:253;not null;uniqueIndex:uni_group_version_resource_cluster_namespace_name,length:100;index:idx_group_version_resource_namespace_name;index:idx_group_version_resource_name"`
113+
OwnerUID types.UID `gorm:"column:owner_uid;size:36;not null;default:''"`
114+
UID types.UID `gorm:"size:36;not null"`
115+
ResourceVersion string `gorm:"size:30;not null"`
116+
117+
Object datatypes.JSON `gorm:"not null"`
118+
119+
CreatedAt time.Time `gorm:"not null"`
120+
SyncedAt time.Time `gorm:"not null;autoUpdateTime"`
121+
DeletedAt sql.NullTime
122+
}
123+
102124
type ResourceMetadata struct {
103125
ResourceType `gorm:"embedded"`
104126

0 commit comments

Comments
 (0)