Add sqlite, miniredis as mysql, redis mock suite, to f… (#293)

* test(manager): add sqlite, miniredis as mysql, redis mock suite, to fix manager unit test

Signed-off-by: hanson.yj <hanson.yj@alibaba-inc.com>

* fix(manager): add sync.Mutex when get/set leaseid

Signed-off-by: hanson.yj <hanson.yj@alibaba-inc.com>

* feat(manager): modify manager store config, add yaml config exaple

Signed-off-by: hanson.yj <hanson.yj@alibaba-inc.com>

* feat(manager): modify manager store config, add yaml config exaple

Signed-off-by: hanson.yj <hanson.yj@alibaba-inc.com>

* fix(manager): add comment for StoreSource

Signed-off-by: hanson.yj <hanson.yj@alibaba-inc.com>

Co-authored-by: hanson.yj <hanson.yj@alibaba-inc.com>
This commit is contained in:
yangjun289519474 2021-06-10 15:19:34 +08:00 committed by Gaius
parent 3e2be181d6
commit cf4944894d
No known key found for this signature in database
GPG Key ID: 8B4E5D1290FA2FFB
12 changed files with 257 additions and 56 deletions

View File

@ -16,7 +16,7 @@ PROJECT_NAME := "d7y.io/dragonfly/v2"
DFGET_NAME := "dfget" DFGET_NAME := "dfget"
VERSION := "2.0.0" VERSION := "2.0.0"
PKG := "$(PROJECT_NAME)" PKG := "$(PROJECT_NAME)"
PKG_LIST := $(shell go list ${PKG}/... | grep -v /vendor/ | grep -v '\(/cdnsystem/\|manager\)') PKG_LIST := $(shell go list ${PKG}/... | grep -v /vendor/ | grep -v '\(/cdnsystem/\)')
GIT_COMMIT := $(shell git rev-parse --verify HEAD --short=7) GIT_COMMIT := $(shell git rev-parse --verify HEAD --short=7)
GIT_COMMIT_LONG := $(shell git rev-parse --verify HEAD) GIT_COMMIT_LONG := $(shell git rev-parse --verify HEAD)
DFGET_ARCHIVE_PREFIX := "$(DFGET_NAME)_$(GIT_COMMIT)" DFGET_ARCHIVE_PREFIX := "$(DFGET_NAME)_$(GIT_COMMIT)"

View File

@ -0,0 +1,20 @@
server:
ip: ""
port: 8004
configure:
store-name: "store1"
redis:
addrs:
- "127.0.0.1:6379"
stores:
-
name: "store1"
source:
mysql:
user: "root"
password: "root1234"
addr: "127.0.0.1:3306"
db: "dragonfly_manager"

2
go.mod
View File

@ -5,6 +5,7 @@ go 1.15
require ( require (
github.com/HuKeping/rbtree v0.0.0-20210106022122-8ad34838eb2b github.com/HuKeping/rbtree v0.0.0-20210106022122-8ad34838eb2b
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/alicebob/miniredis/v2 v2.14.5
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/docker/go-units v0.4.0 github.com/docker/go-units v0.4.0
@ -60,6 +61,7 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
gorm.io/driver/mysql v1.0.4 gorm.io/driver/mysql v1.0.4
gorm.io/driver/sqlite v1.1.4
gorm.io/gorm v1.21.3 gorm.io/gorm v1.21.3
k8s.io/apimachinery v0.20.1 k8s.io/apimachinery v0.20.1
k8s.io/client-go v11.0.0+incompatible k8s.io/client-go v11.0.0+incompatible

15
go.sum
View File

@ -30,6 +30,10 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.14.5 h1:iCFJiSur7871KaFJLAsBEpmc3DJHJ4YuB7W1hYLWs+U=
github.com/alicebob/miniredis/v2 v2.14.5/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I=
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4= github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4=
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@ -47,6 +51,9 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@ -287,6 +294,8 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -436,6 +445,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/xo/dburl v0.7.0 h1:sGcxE2sefO6yJwX99EDzZCU0AACvWUKEqT4eIHFDPmY= github.com/xo/dburl v0.7.0 h1:sGcxE2sefO6yJwX99EDzZCU0AACvWUKEqT4eIHFDPmY=
github.com/xo/dburl v0.7.0/go.mod h1:W68zXnBfTb4zcKLI1yEYRyYIQjcjoyCRn4YMD/QzcpE= github.com/xo/dburl v0.7.0/go.mod h1:W68zXnBfTb4zcKLI1yEYRyYIQjcjoyCRn4YMD/QzcpE=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@ -548,6 +559,7 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -692,6 +704,9 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclp
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.0.4 h1:TATTzt+kR+IV0+h3iUB3dHUe8omCvQ0rOkmfCsUBohk= gorm.io/driver/mysql v1.0.4 h1:TATTzt+kR+IV0+h3iUB3dHUe8omCvQ0rOkmfCsUBohk=
gorm.io/driver/mysql v1.0.4/go.mod h1:MEgp8tk2n60cSBCq5iTcPDw3ns8Gs+zOva9EUhkknTs= gorm.io/driver/mysql v1.0.4/go.mod h1:MEgp8tk2n60cSBCq5iTcPDw3ns8Gs+zOva9EUhkknTs=
gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM=
gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw=
gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.21.3 h1:qDFi55ZOsjZTwk5eN+uhAmHi8GysJ/qCTichM/yO7ME= gorm.io/gorm v1.21.3 h1:qDFi55ZOsjZTwk5eN+uhAmHi8GysJ/qCTichM/yO7ME=
gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=

View File

@ -31,14 +31,23 @@ type MysqlConfig struct {
Db string `yaml:"db" mapstructure:"db"` Db string `yaml:"db" mapstructure:"db"`
} }
type SQLiteConfig struct {
Db string `yaml:"db" mapstructure:"db"`
}
type OssConfig struct { type OssConfig struct {
} }
// Only one of Mysql, SQLit and Oss can be used at the same time
type StoreSource struct {
Mysql *MysqlConfig `yaml:"mysql,omitempty" mapstructure:"mysql,omitempty"`
SQLite *SQLiteConfig `yaml:"sqlite,omitempty" mapstructure:"sqlite,omitempty"`
Oss *OssConfig `yaml:"oss,omitempty" mapstructure:"oss,omitempty"`
}
type StoreConfig struct { type StoreConfig struct {
Name string `yaml:"name" mapstructure:"name"` Name string `yaml:"name" mapstructure:"name"`
Type string `yaml:"type" mapstructure:"type"` Source *StoreSource `yaml:"source" mapstructure:"source"`
Mysql *MysqlConfig `yaml:"mysql,omitempty" mapstructure:"mysql,omitempty"`
Oss *OssConfig `yaml:"oss,omitempty" mapstructure:"oss,omitempty"`
} }
type HostService struct { type HostService struct {
@ -73,50 +82,63 @@ func New() *Config {
Stores: []*StoreConfig{ Stores: []*StoreConfig{
{ {
Name: "store1", Name: "store1",
Type: "mysql", Source: &StoreSource{
Mysql: &MysqlConfig{ Mysql: &MysqlConfig{
User: "root", User: "root",
Password: "root1234", Password: "root1234",
Addr: "127.0.0.1:3306", Addr: "127.0.0.1:3306",
Db: "dragonfly_manager", Db: "dragonfly_manager",
},
}, },
Oss: nil,
}, },
}, },
HostService: &HostService{}, HostService: &HostService{},
} }
} }
func (cfg *StoreConfig) Valid() error { func (cfg *StoreConfig) Valid() (string, error) {
if (cfg.Mysql == nil && cfg.Oss == nil) || (cfg.Mysql != nil && cfg.Oss != nil) { if len(cfg.Name) <= 0 {
return dferrors.Newf(dfcodes.ManagerConfigError, "store config error: please select one of mysql or oss") return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Name is null")
} }
if cfg.Mysql != nil { if cfg.Source == nil {
if len(cfg.Mysql.User) == 0 { return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source is null")
return dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Mysql.User is null")
}
if len(cfg.Mysql.Password) == 0 {
return dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Mysql.Password is null")
}
if len(cfg.Mysql.Addr) == 0 {
return dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Mysql.Addr is null")
}
if len(cfg.Mysql.Db) == 0 {
return dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Mysql.Db is null")
}
return nil
} }
if cfg.Oss != nil { source := cfg.Source
return dferrors.Newf(dfcodes.ManagerConfigError, "store config error: oss not support yet") if source.Mysql != nil {
if len(source.Mysql.User) == 0 {
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source.Mysql.User is null")
}
if len(source.Mysql.Password) == 0 {
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source.Mysql.Password is null")
}
if len(source.Mysql.Addr) == 0 {
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source.Mysql.Addr is null")
}
if len(source.Mysql.Db) == 0 {
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source.Mysql.Db is null")
}
return "mysql", nil
} }
return nil if source.SQLite != nil {
if len(source.SQLite.Db) == 0 {
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source.SQLite.Db is null")
}
return "sqlite", nil
}
if source.Oss != nil {
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source.Oss not support yet")
}
return "", dferrors.Newf(dfcodes.ManagerConfigError, "store config error: Source must be set one of mysql, sqlite, oss")
} }
func (cfg *RedisConfig) Valid() error { func (cfg *RedisConfig) Valid() error {
@ -140,5 +162,11 @@ func (cfg *Config) Valid() error {
return dferrors.Newf(dfcodes.ManagerConfigError, "stores config error: Stores is null") return dferrors.Newf(dfcodes.ManagerConfigError, "stores config error: Stores is null")
} }
for _, store := range cfg.Stores {
if _, err := store.Valid(); err != nil {
return err
}
}
return nil return nil
} }

View File

@ -147,13 +147,25 @@ func (svc *ConfigSvc) grantKeepAliveLease() (lease.LeaseID, chan struct{}, error
return leaseID, ch, nil return leaseID, ch, nil
} }
func (svc *ConfigSvc) setKeepAliveLeaseID(id lease.LeaseID) {
svc.mu.Lock()
defer svc.mu.Unlock()
svc.keepAliveLeaseID = id
}
func (svc *ConfigSvc) getKeepAliveLeaseID() lease.LeaseID {
svc.mu.Lock()
defer svc.mu.Unlock()
return svc.keepAliveLeaseID
}
func (svc *ConfigSvc) grantKeepAliveLeaseLoop() { func (svc *ConfigSvc) grantKeepAliveLeaseLoop() {
defer svc.wg.Done() defer svc.wg.Done()
var ka chan struct{} var ka chan struct{}
id, ch, err := svc.grantKeepAliveLease() id, ch, err := svc.grantKeepAliveLease()
if err == nil { if err == nil {
svc.keepAliveLeaseID = id svc.setKeepAliveLeaseID(id)
ka = ch ka = ch
} }
@ -162,12 +174,12 @@ func (svc *ConfigSvc) grantKeepAliveLeaseLoop() {
case <-svc.stopC: case <-svc.stopC:
return return
case <-ka: case <-ka:
svc.keepAliveLeaseID = lease.NoLease svc.setKeepAliveLeaseID(lease.NoLease)
case <-time.After(svc.grantKeepAliveLeaseIDTime): case <-time.After(svc.grantKeepAliveLeaseIDTime):
if svc.keepAliveLeaseID == lease.NoLease { if svc.getKeepAliveLeaseID() == lease.NoLease {
id, ch, err := svc.grantKeepAliveLease() id, ch, err := svc.grantKeepAliveLease()
if err == nil { if err == nil {
svc.keepAliveLeaseID = id svc.setKeepAliveLeaseID(id)
ka = ch ka = ch
} }
} }
@ -183,7 +195,7 @@ func (svc *ConfigSvc) checkKeepAliveLoop() {
case <-svc.stopC: case <-svc.stopC:
return return
case <-time.After(svc.checkKeepAliveTime): case <-time.After(svc.checkKeepAliveTime):
if svc.keepAliveLeaseID != lease.NoLease { if svc.getKeepAliveLeaseID() != lease.NoLease {
svc.updateAllInstanceState() svc.updateAllInstanceState()
} }
} }

View File

@ -7,8 +7,8 @@ import (
"testing" "testing"
"time" "time"
"d7y.io/dragonfly/v2/manager/config"
"d7y.io/dragonfly/v2/manager/lease" "d7y.io/dragonfly/v2/manager/lease"
"d7y.io/dragonfly/v2/manager/server/mocks"
"d7y.io/dragonfly/v2/manager/store/client" "d7y.io/dragonfly/v2/manager/store/client"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -186,7 +186,7 @@ func (suite *LeaseTestSuite) randPrefix() string {
func (suite *LeaseTestSuite) SetupTest() { func (suite *LeaseTestSuite) SetupTest() {
assert := assert.New(suite.T()) assert := assert.New(suite.T())
cfg := config.New() cfg := mocks.NewMockConfig()
store, err := client.NewStore(cfg) store, err := client.NewStore(cfg)
assert.Nil(err) assert.Nil(err)
assert.NotNil(store) assert.NotNil(store)

View File

@ -0,0 +1,35 @@
package mocks
import (
"path"
"d7y.io/dragonfly/v2/internal/dfpath"
"d7y.io/dragonfly/v2/manager/config"
)
func NewMockConfig() *config.Config {
return &config.Config{
Server: &config.ServerConfig{
Port: 8004,
},
Configure: &config.ConfigureConfig{
StoreName: "store1",
},
Redis: &config.RedisConfig{
User: "",
Password: "",
Addrs: []string{"127.0.0.1:6379"},
},
Stores: []*config.StoreConfig{
{
Name: "store1",
Source: &config.StoreSource{
SQLite: &config.SQLiteConfig{
Db: path.Join(dfpath.WorkHome, "dragonfly_manager.db"),
},
},
},
},
HostService: &config.HostService{},
}
}

View File

@ -112,6 +112,4 @@ func (s *Server) Stop() {
if err != nil { if err != nil {
logger.Errorf("failed to stop manager http server: %+v", err) logger.Errorf("failed to stop manager http server: %+v", err)
} }
s.httpServer = nil
} }

View File

@ -8,19 +8,21 @@ import (
"time" "time"
"d7y.io/dragonfly/v2/manager/apis/v2/types" "d7y.io/dragonfly/v2/manager/apis/v2/types"
"d7y.io/dragonfly/v2/manager/config"
"d7y.io/dragonfly/v2/manager/configsvc" "d7y.io/dragonfly/v2/manager/configsvc"
"d7y.io/dragonfly/v2/manager/server/mocks"
"d7y.io/dragonfly/v2/manager/store" "d7y.io/dragonfly/v2/manager/store"
"d7y.io/dragonfly/v2/pkg/basic/dfnet" "d7y.io/dragonfly/v2/pkg/basic/dfnet"
"d7y.io/dragonfly/v2/pkg/dflog/logcore" "d7y.io/dragonfly/v2/pkg/dflog/logcore"
"d7y.io/dragonfly/v2/pkg/rpc/manager" "d7y.io/dragonfly/v2/pkg/rpc/manager"
"d7y.io/dragonfly/v2/pkg/rpc/manager/client" "d7y.io/dragonfly/v2/pkg/rpc/manager/client"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
type ServerTestSuite struct { type ServerTestSuite struct {
suite.Suite suite.Suite
redis *miniredis.Miniredis
server *Server server *Server
client client.ManagerClient client client.ManagerClient
} }
@ -764,7 +766,11 @@ func (suite *ServerTestSuite) SetupSuite() {
configsvc.KeepAliveTimeoutMax = 2 * time.Second configsvc.KeepAliveTimeoutMax = 2 * time.Second
_ = logcore.InitManager(false) _ = logcore.InitManager(false)
cfg := config.New() cfg := mocks.NewMockConfig()
suite.redis = miniredis.NewMiniRedis()
_ = suite.redis.StartAddr(cfg.Redis.Addrs[0])
server, err := New(cfg) server, err := New(cfg)
assert.Nil(err) assert.Nil(err)
assert.NotNil(server) assert.NotNil(server)
@ -785,6 +791,7 @@ func (suite *ServerTestSuite) SetupSuite() {
} }
func (suite *ServerTestSuite) TearDownSuite() { func (suite *ServerTestSuite) TearDownSuite() {
suite.redis.Close()
suite.server.Stop() suite.server.Stop()
} }

View File

@ -11,7 +11,8 @@ import (
type storeSetup func(cfg *config.StoreConfig) (store.Store, error) type storeSetup func(cfg *config.StoreConfig) (store.Store, error)
var storePlugins = map[string]storeSetup{ var storePlugins = map[string]storeSetup{
"mysql": orm.NewOrmStore, "mysql": orm.NewMySQLOrmStore,
"sqlite": orm.NewSQLiteOrmStore,
} }
func NewStore(cfg *config.Config) (store.Store, error) { func NewStore(cfg *config.Config) (store.Store, error) {
@ -20,8 +21,13 @@ func NewStore(cfg *config.Config) (store.Store, error) {
} }
for _, store := range cfg.Stores { for _, store := range cfg.Stores {
source, err := store.Valid()
if err != nil {
return nil, err
}
if cfg.Configure.StoreName == store.Name { if cfg.Configure.StoreName == store.Name {
p, ok := storePlugins[store.Type] p, ok := storePlugins[source]
if ok { if ok {
s, err := p(store) s, err := p(store)
if err != nil { if err != nil {

View File

@ -2,15 +2,20 @@ package orm
import ( import (
"context" "context"
"fmt"
"net/url" "net/url"
"os"
"path"
"d7y.io/dragonfly/v2/manager/config" "d7y.io/dragonfly/v2/manager/config"
"d7y.io/dragonfly/v2/manager/store" "d7y.io/dragonfly/v2/manager/store"
"d7y.io/dragonfly/v2/pkg/dfcodes" "d7y.io/dragonfly/v2/pkg/dfcodes"
"d7y.io/dragonfly/v2/pkg/dferrors" "d7y.io/dragonfly/v2/pkg/dferrors"
"d7y.io/dragonfly/v2/pkg/util/fileutils"
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
"github.com/xo/dburl" "github.com/xo/dburl"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/driver/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -31,19 +36,24 @@ var ormTables = map[store.ResourceType]newTableSetup{
store.Lease: NewLeaseStore, store.Lease: NewLeaseStore,
} }
func newOrmStore(cfg *config.StoreConfig) (*ormStore, error) { func NewMySQLOrmStore(cfg *config.StoreConfig) (store.Store, error) {
if err := cfg.Valid(); err != nil { source, err := cfg.Valid()
if err != nil {
return nil, err return nil, err
} }
if source != "mysql" {
return nil, dferrors.Newf(dfcodes.ManagerConfigError, "store config error: source is not mysql")
}
u, err := dburl.Parse("mysql://user:pass@localhost/dbname?") u, err := dburl.Parse("mysql://user:pass@localhost/dbname?")
if err != nil { if err != nil {
return nil, err return nil, err
} }
u.Host = cfg.Mysql.Addr u.Host = cfg.Source.Mysql.Addr
u.Path = cfg.Mysql.Db u.Path = cfg.Source.Mysql.Db
u.User = url.UserPassword(cfg.Mysql.User, cfg.Mysql.Password) u.User = url.UserPassword(cfg.Source.Mysql.User, cfg.Source.Mysql.Password)
q := u.Query() q := u.Query()
q.Add("charset", "utf8") q.Add("charset", "utf8")
q.Add("parseTime", "True") q.Add("parseTime", "True")
@ -79,8 +89,76 @@ func newOrmStore(cfg *config.StoreConfig) (*ormStore, error) {
return orm, nil return orm, nil
} }
func NewOrmStore(cfg *config.StoreConfig) (store.Store, error) { func createSQLiteDB(db string) error {
return newOrmStore(cfg) dir := path.Dir(db)
if !fileutils.PathExist(dir) {
if err := fileutils.MkdirAll(dir); err != nil {
return err
}
}
if !fileutils.PathExist(db) {
dbFile, err := os.OpenFile(db, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer dbFile.Close()
}
return nil
}
func NewSQLiteOrmStore(cfg *config.StoreConfig) (store.Store, error) {
source, err := cfg.Valid()
if err != nil {
return nil, err
}
if source != "sqlite" {
return nil, dferrors.Newf(dfcodes.ManagerConfigError, "store config error: source is not sqlite")
}
if err := createSQLiteDB(cfg.Source.SQLite.Db); err != nil {
return nil, err
}
u, err := dburl.Parse(fmt.Sprintf("sqlite://%s?", cfg.Source.SQLite.Db))
if err != nil {
return nil, err
}
q := u.Query()
q.Add("cache", "shared")
q.Add("mode", "memory")
u.RawQuery = q.Encode()
dsn, err := dburl.GenOpaque(u)
if err != nil {
return nil, err
}
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
if err != nil {
return nil, err
}
orm := &ormStore{
db: db,
stores: make(map[store.ResourceType]store.Store),
tables: make(map[store.ResourceType]string),
}
for t, f := range ormTables {
table := strcase.ToSnake(t.String())
s, err := f(db, table)
if err != nil {
return nil, err
}
orm.stores[t] = s
orm.tables[t] = table
}
return orm, nil
} }
func (orm *ormStore) listTables() []string { func (orm *ormStore) listTables() []string {