From 822a7451b0c3052d8f6c51d2a4c3c1510b296be3 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Wed, 16 Nov 2022 17:27:35 +0800 Subject: [PATCH] resource_manager: basic implement about manage resource group Signed-off-by: nolouch --- cmd/pd-server/main.go | 4 + go.mod | 27 +-- go.sum | 43 ++--- pkg/{msc => mcs}/docs.go | 4 +- pkg/{msc => mcs}/registry/registry.go | 2 + .../resource_manager/server/apis/v1/api.go | 157 ++++++++++++++++++ .../resource_manager/server/grpc_service.go | 130 +++++++++++++++ .../server/install/install.go | 32 ++++ pkg/mcs/resource_manager/server/manager.go | 143 ++++++++++++++++ pkg/mcs/resource_manager/server/metrics.go | 17 ++ .../resource_manager/server/token_bukets.go | 63 +++++++ pkg/mcs/resource_manager/server/types.go | 127 ++++++++++++++ pkg/storage/endpoint/key_path.go | 5 + pkg/storage/endpoint/resource_group.go | 39 +++++ server/server.go | 3 +- server/storage/storage.go | 1 + tests/client/go.mod | 14 +- tests/client/go.sum | 28 ++-- .../resource_manager/resource_manager_test.go | 69 ++++++++ tests/registry/registry_test.go | 2 +- 20 files changed, 857 insertions(+), 53 deletions(-) rename pkg/{msc => mcs}/docs.go (89%) rename pkg/{msc => mcs}/registry/registry.go (98%) create mode 100644 pkg/mcs/resource_manager/server/apis/v1/api.go create mode 100644 pkg/mcs/resource_manager/server/grpc_service.go create mode 100644 pkg/mcs/resource_manager/server/install/install.go create mode 100644 pkg/mcs/resource_manager/server/manager.go create mode 100644 pkg/mcs/resource_manager/server/metrics.go create mode 100644 pkg/mcs/resource_manager/server/token_bukets.go create mode 100644 pkg/mcs/resource_manager/server/types.go create mode 100644 pkg/storage/endpoint/resource_group.go create mode 100644 tests/msc/resource_manager/resource_manager_test.go diff --git a/cmd/pd-server/main.go b/cmd/pd-server/main.go index 20457cac28ad..0f39e20243cd 100644 --- a/cmd/pd-server/main.go +++ b/cmd/pd-server/main.go @@ -39,6 +39,10 @@ import ( // Register schedulers. _ "github.com/tikv/pd/server/schedulers" + + // Register Service + _ "github.com/tikv/pd/pkg/mcs/registry" + _ "github.com/tikv/pd/pkg/mcs/resource_manager/server/install" ) func main() { diff --git a/go.mod b/go.mod index 29286e152d88..dfc2ae402a9c 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/sasha-s/go-deadlock v0.2.0 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 github.com/swaggo/http-swagger v0.0.0-20200308142732-58ac5e232fba github.com/swaggo/swag v1.8.3 github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 @@ -50,6 +50,11 @@ require ( gotest.tools/gotestsum v1.7.0 ) +require ( + github.com/google/go-cmp v0.5.8 // indirect + github.com/onsi/gomega v1.20.1 // indirect +) + require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect @@ -74,7 +79,7 @@ require ( github.com/fogleman/gg v1.3.0 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/gin-contrib/gzip v0.0.1 // indirect + github.com/gin-contrib/gzip v0.0.1 github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect @@ -89,11 +94,11 @@ require ( github.com/goccy/go-graphviz v0.0.9 // indirect github.com/golang-jwt/jwt v3.2.1+incompatible // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/golang/protobuf v1.5.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/pprof v0.0.0-20211122183932-1daafda22083 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.0.0 // indirect + github.com/google/uuid v1.1.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 // indirect github.com/grpc-ecosystem/grpc-gateway v1.12.1 // indirect @@ -128,7 +133,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect github.com/prometheus/procfs v0.0.3 // indirect - github.com/rs/cors v1.7.0 // indirect + github.com/rs/cors v1.7.0 github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44 // indirect github.com/shirou/gopsutil v3.21.3+incompatible // indirect @@ -136,7 +141,7 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.4.2 // indirect github.com/soheilhy/cmux v0.1.4 // indirect - github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/objx v0.4.0 // indirect github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 // indirect github.com/thoas/go-funk v0.8.0 // indirect github.com/tidwall/gjson v1.9.3 // indirect @@ -158,10 +163,10 @@ require ( golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect - golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.4.0 // indirect @@ -169,15 +174,17 @@ require ( google.golang.org/protobuf v1.28.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect gorm.io/driver/mysql v1.0.6 // indirect gorm.io/driver/sqlite v1.1.4 // indirect gorm.io/gorm v1.21.9 // indirect moul.io/zapgorm2 v1.1.0 // indirect - sigs.k8s.io/yaml v1.1.0 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect ) // When you modify PD cooperatively with kvproto, this will be useful to submit the PR to PD and the PR to // kvproto at the same time. You can run `go mod tidy` to make it replaced with go-mod style specification. // After the PR to kvproto is merged, remember to comment this out and run `go mod tidy`. // replace github.com/pingcap/kvproto => github.com/$YourPrivateRepo $YourPrivateBranch + +replace github.com/pingcap/kvproto => github.com/nolouch/kvproto v0.0.0-20221215101412-004860b09b46 diff --git a/go.sum b/go.sum index 8f923489b9ea..6c6405f32f0a 100644 --- a/go.sum +++ b/go.sum @@ -164,7 +164,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ= github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v0.0.0-20180717141946-636bf0302bc9/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -179,14 +178,14 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v0.0.0-20180814211427-aa810b61a9c7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -196,16 +195,18 @@ github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20211122183932-1daafda22083 h1:c8EUapQFi+kjzedr4c6WqbwMdmB95+oDBWZ5XFHFYxY= github.com/google/pprof v0.0.0-20211122183932-1daafda22083/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -320,6 +321,8 @@ github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/R github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nolouch/kvproto v0.0.0-20221215101412-004860b09b46 h1:SqblNt1oTZg6N+g7ltm++c4D253bv08h1OeZ7BlvhLU= +github.com/nolouch/kvproto v0.0.0-20221215101412-004860b09b46/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= @@ -329,8 +332,9 @@ github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FW github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1/go.mod h1:eD5JxqMiuNYyFNmyY9rkJ/slN8y59oEu4Ei7F8OoKWQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/petermattis/goid v0.0.0-20211229010228-4d14c490ee36 h1:64bxqeTEN0/xoEqhKGowgihNuzISS9rEG6YUMU4bzJo= @@ -349,9 +353,6 @@ github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c h1:xpW9bvK+HuuTm github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce h1:Y1kCxlCtlPTMtVcOkjUcuQKh+YrluSo7+7YMCQSzy30= github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce/go.mod h1:w4PEZ5y16LeofeeGwdgZB4ddv9bLyDuIX+ljstgKZyk= -github.com/pingcap/kvproto v0.0.0-20191211054548-3c6b38ea5107/go.mod h1:WWLmULLO7l8IOcQG+t+ItJ3fEcrL5FxF0Wu+HrMy26w= -github.com/pingcap/kvproto v0.0.0-20221104101942-09d82b914df1 h1:iJXUNA0LoOYuuMJ6U0tJGg2gCo/8xGZVhKLvuUWNjzw= -github.com/pingcap/kvproto v0.0.0-20221104101942-09d82b914df1/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM= github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3 h1:HR/ylkkLmGdSSDaD8IDP+SZrdhV1Kibl9KrHxJ9eciw= @@ -424,8 +425,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -433,8 +434,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM= github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI= @@ -575,8 +577,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -615,8 +617,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -668,11 +670,9 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181004005441-af9cb2a35e7f/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/grpc v0.0.0-20180607172857-7a6a684ca69e/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -681,6 +681,7 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -708,8 +709,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.0.6 h1:mA0XRPjIKi4bkE9nv+NKs6qj6QWOchqUSdWOcpd3x1E= gorm.io/driver/mysql v1.0.6/go.mod h1:KdrTanmfLPPyAOeYGyG+UpDys7/7eeWT1zCq+oekYnU= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= @@ -727,5 +729,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= moul.io/zapgorm2 v1.1.0 h1:qwAlMBYf+qJkJ7PAzJl4oCe6eS6QGiKAXUPeis0+RBE= moul.io/zapgorm2 v1.1.0/go.mod h1:emRfKjNqSzVj5lcgasBdovIXY1jSOwFz2GQZn1Rddks= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/pkg/msc/docs.go b/pkg/mcs/docs.go similarity index 89% rename from pkg/msc/docs.go rename to pkg/mcs/docs.go index 3af6a2b241f3..e345fecc4235 100644 --- a/pkg/msc/docs.go +++ b/pkg/mcs/docs.go @@ -12,5 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package mcs used to implement the core logic of the external services which rely on the PD banckend provider. -package mcs +// Package msc used to implement the core logic of the external services which rely on the PD banckend provider. +package msc diff --git a/pkg/msc/registry/registry.go b/pkg/mcs/registry/registry.go similarity index 98% rename from pkg/msc/registry/registry.go rename to pkg/mcs/registry/registry.go index e8f74d569732..aadd84853a9d 100644 --- a/pkg/msc/registry/registry.go +++ b/pkg/mcs/registry/registry.go @@ -63,6 +63,7 @@ func (r *ServiceRegistry) InstallAllGRPCServices(srv *server.Server, g *grpc.Ser continue } l := builder(srv) + r.services[name] = l l.RegisterGRPCService(g) log.Info("gRPC service register success", zap.String("service-name", name)) } @@ -77,6 +78,7 @@ func (r *ServiceRegistry) InstallAllRESTHandler(srv *server.Server, h map[string continue } l := builder(srv) + r.services[name] = l l.RegisterRESTHandler(h) log.Info("restful API service register success", zap.String("service-name", name)) } diff --git a/pkg/mcs/resource_manager/server/apis/v1/api.go b/pkg/mcs/resource_manager/server/apis/v1/api.go new file mode 100644 index 000000000000..44575bbc20f0 --- /dev/null +++ b/pkg/mcs/resource_manager/server/apis/v1/api.go @@ -0,0 +1,157 @@ +// Copyright 2020 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apis + +import ( + "errors" + "net/http" + + "github.com/gin-contrib/gzip" + "github.com/gin-gonic/gin" + "github.com/pingcap/errcode" + cors "github.com/rs/cors/wrapper/gin" + rmserver "github.com/tikv/pd/pkg/mcs/resource_manager/server" + "github.com/tikv/pd/server" +) + +// APIPathPrefix is the prefix of the API path. +const APIPathPrefix = "/resource-manager/api/v1/" + +var ( + apiServiceGroup = server.APIServiceGroup{ + Name: "resource-manager", + Version: "v1", + IsCore: false, + PathPrefix: APIPathPrefix, + } +) + +func init() { + rmserver.SetUpRestHandler = func(srv *rmserver.Service) (http.Handler, server.APIServiceGroup) { + s := NewService(srv) + return s.handler(), apiServiceGroup + } +} + +// Service is the resource group service. +type Service struct { + apiHandlerEngine *gin.Engine + baseEndpoint *gin.RouterGroup + + manager *rmserver.Manager +} + +// NewService returns a new Service. +func NewService(srv *rmserver.Service) *Service { + apiHandlerEngine := gin.New() + apiHandlerEngine.Use(gin.Recovery()) + apiHandlerEngine.Use(cors.AllowAll()) + apiHandlerEngine.Use(gzip.Gzip(gzip.DefaultCompression)) + endpoint := apiHandlerEngine.Group(APIPathPrefix) + manager := srv.GetManager() + + s := &Service{ + manager: manager, + apiHandlerEngine: apiHandlerEngine, + baseEndpoint: endpoint, + } + s.RegisterRouter() + return s +} + +// RegisterRouter registers the router of the service. +func (s *Service) RegisterRouter() { + configEndpoint := s.baseEndpoint.Group("/config") + configEndpoint.POST("/group", s.putResourceGroup) + configEndpoint.PATCH("group", s.patchResourceGroup) + configEndpoint.GET("/group/:name", s.getResourceGroup) + configEndpoint.GET("/groups", s.getResourceGroupList) + configEndpoint.DELETE("/group/:name", s.deleteResourceGroup) +} + +func (s *Service) handler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + s.apiHandlerEngine.ServeHTTP(w, r) + }) +} + +// @Summary add a resource group +// @Param address path string true "ip:port" +// @Success 200 "added successfully" +// @Failure 401 {object} rest.ErrorResponse +// @Router /config/group/ [POST] +func (s *Service) putResourceGroup(c *gin.Context) { + var group rmserver.ResourceGroup + if err := c.ShouldBindJSON(&group); err != nil { + c.JSON(http.StatusBadRequest, err) + return + } + if err := s.manager.AddResourceGroup(&group); err != nil { + c.JSON(http.StatusInternalServerError, err) + return + } + c.JSON(http.StatusOK, "success") +} + +// @Summary add a resource group +// @Param address path string true "ip:port" +// @Success 200 "added successfully" +// @Failure 401 {object} rest.ErrorResponse +// @Router /config/group/ [PATCH] +func (s *Service) patchResourceGroup(c *gin.Context) { + var group rmserver.ResourceGroup + if err := c.ShouldBindJSON(&group); err != nil { + c.JSON(http.StatusBadRequest, err) + return + } + if err := s.manager.ModifyResourceGroup(&group); err != nil { + c.JSON(http.StatusInternalServerError, err) + return + } + c.JSON(http.StatusOK, "success") +} + +// @ID getResourceGroup +// @Summary Get current alert count from AlertManager +// @Success 200 {object} int +// @Param name string true "groupName" +// @Router /config/group/{name} [GET] +// @Failure 404 {object} rest.ErrorResponse +func (s *Service) getResourceGroup(c *gin.Context) { + group := s.manager.GetResourceGroup(c.Param("name")) + if group == nil { + c.JSON(http.StatusNotFound, errcode.NewNotFoundErr(errors.New("resource group not found"))) + } + c.JSON(http.StatusOK, group) +} + +// @ID getResourceGroupList +// @Summary Get current alert count from AlertManager +// @Success 200 {array} ResourceGroup +// @Router /config/groups [GET] +func (s *Service) getResourceGroupList(c *gin.Context) { + groups := s.manager.GetResourceGroupList() + c.JSON(http.StatusOK, groups) +} + +// @ID getResourceGroup +// @Summary Get current alert count from AlertManager +// @Success 200 "deleted successfully" +// @Param name string true "groupName" +// @Router /config/group/{name} [DELETE] +// @Failure 404 {object} error +func (s *Service) deleteResourceGroup(c *gin.Context) { + //TODO: Implement deleteResourceGroup +} diff --git a/pkg/mcs/resource_manager/server/grpc_service.go b/pkg/mcs/resource_manager/server/grpc_service.go new file mode 100644 index 000000000000..599f41653d65 --- /dev/null +++ b/pkg/mcs/resource_manager/server/grpc_service.go @@ -0,0 +1,130 @@ +// Copyright 2020 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "context" + "net/http" + + "github.com/pingcap/errors" + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" + "github.com/tikv/pd/pkg/mcs/registry" + "github.com/tikv/pd/server" + "google.golang.org/grpc" +) + +var _ rmpb.ResourceManagerServer = (*Service)(nil) + +// SetUpRestHandler is a hook to sets up the REST service. +var SetUpRestHandler = func(srv *Service) (http.Handler, server.APIServiceGroup) { + return dummyRestService{}, server.APIServiceGroup{} +} + +type dummyRestService struct{} + +func (d dummyRestService) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) + w.Write([]byte("not implemented")) +} + +// Service is the gRPC service for resource manager. +type Service struct { + ctx context.Context + manager *Manager + // settings +} + +// NewService creates a new resource manager service. +func NewService(svr *server.Server) registry.RegistrableService { + manager := NewManager(svr) + + return &Service{ + ctx: svr.Context(), + manager: manager, + } +} + +// RegisterGRPCService registers the service to gRPC server. +func (s *Service) RegisterGRPCService(g *grpc.Server) { + rmpb.RegisterResourceManagerServer(g, s) +} + +// RegisterRESTHandler registers the service to REST server. +func (s *Service) RegisterRESTHandler(userDefineHandlers map[string]http.Handler) { + hander, group := SetUpRestHandler(s) + server.RegisterUserDefinedHandlers(userDefineHandlers, &group, hander) +} + +// GetManager returns the resource manager. +func (s *Service) GetManager() *Manager { + return s.manager +} + +// GetResourceGroup implements ResourceManagerServer.GetResourceGroup. +func (s *Service) GetResourceGroup(ctx context.Context, req *rmpb.GetResourceGroupRequest) (*rmpb.GetResourceGroupResponse, error) { + rg := s.manager.GetResourceGroup(req.ResourceGroupName) + if rg == nil { + return nil, errors.New("resource group not found") + } + return &rmpb.GetResourceGroupResponse{ + Group: rg.IntoProtoResourceGroup(), + }, nil +} + +// ListResourceGroups implements ResourceManagerServer.ListResourceGroups. +func (s *Service) ListResourceGroups(ctx context.Context, req *rmpb.ListResourceGroupsRequest) (*rmpb.ListResourceGroupsResponse, error) { + groups := s.manager.GetResourceGroupList() + resp := &rmpb.ListResourceGroupsResponse{ + Groups: make([]*rmpb.ResourceGroup, 0, len(groups)), + } + for _, group := range groups { + resp.Groups = append(resp.Groups, group.IntoProtoResourceGroup()) + } + return resp, nil +} + +// AddResourceGroup implements ResourceManagerServer.AddResourceGroup. +func (s *Service) AddResourceGroup(ctx context.Context, req *rmpb.PutResourceGroupRequest) (*rmpb.PutResourceGroupResponse, error) { + rg := FromProtoResourceGroup(req.GetGroup()) + err := s.manager.AddResourceGroup(rg) + if err != nil { + return nil, err + } + return &rmpb.PutResourceGroupResponse{ResponseBody: "Success!"}, nil +} + +// DeleteResourceGroup implements ResourceManagerServer.DeleteResourceGroup. +func (s *Service) DeleteResourceGroup(ctx context.Context, req *rmpb.DeleteResourceGroupRequest) (*rmpb.DeleteResourceGroupResponse, error) { + err := s.manager.DeleteResourceGroup(req.ResourceGroupName) + if err != nil { + return nil, err + } + return &rmpb.DeleteResourceGroupResponse{ResponseBody: "Success!"}, nil +} + +// ModifyResourceGroup implements ResourceManagerServer.ModifyResourceGroup. +func (s *Service) ModifyResourceGroup(ctx context.Context, req *rmpb.PutResourceGroupRequest) (*rmpb.PutResourceGroupResponse, error) { + rg := FromProtoResourceGroup(req.GetGroup()) + err := s.manager.ModifyResourceGroup(rg) + if err != nil { + return nil, err + } + return &rmpb.PutResourceGroupResponse{ResponseBody: "Success!"}, nil +} + +// AcquireTokenBuckets implements ResourceManagerServer.AcquireTokenBuckets. +func (s *Service) AcquireTokenBuckets(stream rmpb.ResourceManager_AcquireTokenBucketsServer) error { + return errors.New("not implemented") +} diff --git a/pkg/mcs/resource_manager/server/install/install.go b/pkg/mcs/resource_manager/server/install/install.go new file mode 100644 index 000000000000..209a504cc4e3 --- /dev/null +++ b/pkg/mcs/resource_manager/server/install/install.go @@ -0,0 +1,32 @@ +// Copyright 2022 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package install + +import ( + "github.com/tikv/pd/pkg/mcs/registry" + rm_server "github.com/tikv/pd/pkg/mcs/resource_manager/server" + + // init API gorup + _ "github.com/tikv/pd/pkg/mcs/resource_manager/server/apis/v1" +) + +func init() { + Install(registry.ServerServiceRegistry) +} + +// Install registers the API group and grpc service. +func Install(register *registry.ServiceRegistry) { + register.RegisterService("ResourceManager", rm_server.NewService) +} diff --git a/pkg/mcs/resource_manager/server/manager.go b/pkg/mcs/resource_manager/server/manager.go new file mode 100644 index 000000000000..43b767cc5832 --- /dev/null +++ b/pkg/mcs/resource_manager/server/manager.go @@ -0,0 +1,143 @@ +// Copyright 2020 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "encoding/json" + "sort" + "sync" + + "github.com/pingcap/errors" + "github.com/tikv/pd/server" + "github.com/tikv/pd/server/core" + "github.com/tikv/pd/server/storage" +) + +// Manager is the manager of resource group. +type Manager struct { + sync.RWMutex + groups map[string]*ResourceGroup + storage func() storage.Storage + // TODO: dispatch resource group to storage node + getStores func() ([]*core.StoreInfo, error) +} + +// NewManager returns a new Manager. +func NewManager(srv *server.Server) *Manager { + getStores := func() ([]*core.StoreInfo, error) { + rc := srv.GetRaftCluster() + if rc == nil { + return nil, errors.New("RaftCluster is nil") + } + return rc.GetStores(), nil + } + + m := &Manager{ + groups: make(map[string]*ResourceGroup), + storage: srv.GetStorage, + getStores: getStores, + } + srv.AddStartCallback(m.Init) + return m +} + +// Init initializes the resource group manager. +func (m *Manager) Init() { + handler := func(k, v string) { + var group ResourceGroup + if err := json.Unmarshal([]byte(v), &group); err != nil { + panic(err) + } + m.groups[group.Name] = &group + } + m.storage().LoadResourceGroups(handler) +} + +// AddResourceGroup puts a resource group. +func (m *Manager) AddResourceGroup(group *ResourceGroup) error { + m.RLock() + _, ok := m.groups[group.Name] + m.RUnlock() + if ok { + return errors.New("this group already exists") + } + err := group.CheckAndInit() + if err != nil { + return err + } + if err := m.storage().SaveResourceGroup(group.Name, group); err != nil { + return err + } + m.Lock() + m.groups[group.Name] = group + m.Unlock() + return nil +} + +// ModifyResourceGroup modifies a exists resource group. +func (m *Manager) ModifyResourceGroup(group *ResourceGroup) error { + m.RLock() + _, ok := m.groups[group.Name] + m.RUnlock() + if !ok { + return errors.New("not exists the group") + } + err := group.CheckAndInit() + if err != nil { + return err + } + if err := m.storage().SaveResourceGroup(group.Name, group); err != nil { + return err + } + m.Lock() + m.groups[group.Name] = group + m.Unlock() + return nil +} + +// DeleteResourceGroup deletes a resource group. +func (m *Manager) DeleteResourceGroup(name string) error { + if err := m.storage().DeleteResourceGroup(name); err != nil { + return err + } + m.Lock() + delete(m.groups, name) + m.Unlock() + return nil +} + +// GetResourceGroup returns a resource group. +func (m *Manager) GetResourceGroup(name string) *ResourceGroup { + m.RLock() + defer m.RUnlock() + if group, ok := m.groups[name]; ok { + return group + } + return nil +} + +// GetResourceGroupList returns a resource group list. +func (m *Manager) GetResourceGroupList() []*ResourceGroup { + m.RLock() + res := make([]*ResourceGroup, 0, len(m.groups)) + for _, group := range m.groups { + res = append(res, group) + } + m.RUnlock() + sort.Slice(res, func(i, j int) bool { + return res[i].Name < res[j].Name + }) + return res +} diff --git a/pkg/mcs/resource_manager/server/metrics.go b/pkg/mcs/resource_manager/server/metrics.go new file mode 100644 index 000000000000..24bb84315878 --- /dev/null +++ b/pkg/mcs/resource_manager/server/metrics.go @@ -0,0 +1,17 @@ +// Copyright 2022 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +// TODO: add metrics diff --git a/pkg/mcs/resource_manager/server/token_bukets.go b/pkg/mcs/resource_manager/server/token_bukets.go new file mode 100644 index 000000000000..f763650a4882 --- /dev/null +++ b/pkg/mcs/resource_manager/server/token_bukets.go @@ -0,0 +1,63 @@ +// Copyright 2020 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS,g +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "time" + + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" +) + +const defaultRefillRate = 10000 + +const defaultInitialTokens = 10 * 10000 + +// GroupTokenBucket is a token bucket for a resource group. +type GroupTokenBucket struct { + *rmpb.TokenBucket `json:"token_bucket"` + Consumption *rmpb.TokenBucketsRequest `json:"consumption"` + LastUpdate time.Time `json:"last_update"` + Initialized bool `json:"initialized"` +} + +// Update updates the token bucket. +func (t *GroupTokenBucket) Update(now time.Time) { + if !t.Initialized { + t.Settings.Fillrate = defaultRefillRate + t.Tokens = defaultInitialTokens + t.LastUpdate = now + t.Initialized = true + return + } + + delta := now.Sub(t.LastUpdate) + if delta > 0 { + t.Tokens += float64(t.Settings.Fillrate) * delta.Seconds() + t.LastUpdate = now + } +} + +// GetTokenBucket returns the token bucket. +func (t *GroupTokenBucket) GetTokenBucket() *rmpb.TokenBucket { + return t.TokenBucket +} + +// Request requests tokens from the token bucket. +func (t *GroupTokenBucket) Request( + neededTokens float64, targetPeriodMs uint64, +) *rmpb.TokenBucket { + // TODO: Implement the token bucket algorithm. + return nil +} diff --git a/pkg/mcs/resource_manager/server/types.go b/pkg/mcs/resource_manager/server/types.go new file mode 100644 index 000000000000..82d1f1039f49 --- /dev/null +++ b/pkg/mcs/resource_manager/server/types.go @@ -0,0 +1,127 @@ +// Copyright 2022 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package server provides a set of struct definitions for the resource group, can be imported. +package server + +import ( + "github.com/pingcap/errors" + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" +) + +// ResourceGroup is the definition of a resource group, for REST API. +type ResourceGroup struct { + Name string `json:"name"` + Mode rmpb.GroupMode `json:"mode"` + // RU settings + RUSettings *RequestUnitSettings `json:"r_u_settings,omitempty"` + // Native resource settings + ResourceSettings *NativeResourceSettings `json:"resource_settings,omitempty"` +} + +// RequestUnitSettings is the definition of the RU settings. +type RequestUnitSettings struct { + RRU GroupTokenBucket `json:"rru,omitempty"` + WRU GroupTokenBucket `json:"wru,omitempty"` +} + +// NativeResourceSettings is the definition of the native resource settings. +type NativeResourceSettings struct { + CPU GroupTokenBucket `json:"cpu,omitempty"` + IOReadBandwidth GroupTokenBucket `json:"io_read_bandwidth,omitempty"` + IOWriteBandwidth GroupTokenBucket `json:"io_write_bandwidth,omitempty"` +} + +// CheckAndInit checks the validity of the resource group and initializes the default values if not setting. +func (rg *ResourceGroup) CheckAndInit() error { + if len(rg.Name) == 0 || len(rg.Name) > 32 { + return errors.New("invalid resource group name, the length should be in [1,32]") + } + if rg.Mode != rmpb.GroupMode_RUMode && rg.Mode != rmpb.GroupMode_NativeMode { + return errors.New("invalid resource group mode") + } + if rg.Mode == rmpb.GroupMode_RUMode { + if rg.RUSettings == nil { + rg.RUSettings = &RequestUnitSettings{} + } + rg.ResourceSettings = nil + } + if rg.Mode == rmpb.GroupMode_NativeMode { + if rg.ResourceSettings == nil { + rg.ResourceSettings = &NativeResourceSettings{} + } + rg.RUSettings = nil + } + return nil +} + +// FromProtoResourceGroup converts a rmpb.ResourceGroup to a ResourceGroup. +func FromProtoResourceGroup(group *rmpb.ResourceGroup) *ResourceGroup { + rg := &ResourceGroup{ + Name: group.ResourceGroupName, + Mode: group.Settings.Mode, + RUSettings: &RequestUnitSettings{ + RRU: GroupTokenBucket{ + TokenBucket: group.GetSettings().GetRUSettings().GetRRU(), + }, + WRU: GroupTokenBucket{ + TokenBucket: group.GetSettings().GetRUSettings().GetWRU(), + }, + }, + ResourceSettings: &NativeResourceSettings{ + CPU: GroupTokenBucket{ + TokenBucket: group.GetSettings().GetResourceSettings().GetCpu(), + }, + IOReadBandwidth: GroupTokenBucket{ + TokenBucket: group.GetSettings().GetResourceSettings().GetIoRead(), + }, + IOWriteBandwidth: GroupTokenBucket{ + TokenBucket: group.GetSettings().GetResourceSettings().GetIoWrite(), + }, + }, + } + return rg +} + +// IntoProtoResourceGroup converts a ResourceGroup to a rmpb.ResourceGroup. +func (rg *ResourceGroup) IntoProtoResourceGroup() *rmpb.ResourceGroup { + switch rg.Mode { + case rmpb.GroupMode_RUMode: // RU mode + group := &rmpb.ResourceGroup{ + ResourceGroupName: rg.Name, + Settings: &rmpb.GroupSettings{ + Mode: rmpb.GroupMode_RUMode, + RUSettings: &rmpb.GroupRequestUnitSettings{ + RRU: rg.RUSettings.RRU.GetTokenBucket(), + WRU: rg.RUSettings.WRU.GetTokenBucket(), + }, + }, + } + return group + case rmpb.GroupMode_NativeMode: // Native mode + group := &rmpb.ResourceGroup{ + ResourceGroupName: rg.Name, + Settings: &rmpb.GroupSettings{ + Mode: rmpb.GroupMode_NativeMode, + ResourceSettings: &rmpb.GroupResourceSettings{ + Cpu: rg.ResourceSettings.CPU.GetTokenBucket(), + IoRead: rg.ResourceSettings.IOReadBandwidth.GetTokenBucket(), + IoWrite: rg.ResourceSettings.IOWriteBandwidth.GetTokenBucket(), + }, + }, + } + return group + } + return nil +} diff --git a/pkg/storage/endpoint/key_path.go b/pkg/storage/endpoint/key_path.go index 3d73b3a5d4f9..2bb4c7e62988 100644 --- a/pkg/storage/endpoint/key_path.go +++ b/pkg/storage/endpoint/key_path.go @@ -28,6 +28,7 @@ const ( schedulePath = "schedule" gcPath = "gc" rulesPath = "rules" + resourceGroupPath = "resource_group" ruleGroupPath = "rule_group" regionLabelPath = "region_label" replicationPath = "replication_mode" @@ -104,6 +105,10 @@ func RegionPath(regionID uint64) string { return buf.String() } +func resourceGroupKeyPath(groupName string) string { + return path.Join(resourceGroupPath, groupName) +} + func ruleKeyPath(ruleKey string) string { return path.Join(rulesPath, ruleKey) } diff --git a/pkg/storage/endpoint/resource_group.go b/pkg/storage/endpoint/resource_group.go new file mode 100644 index 000000000000..4fc169973aba --- /dev/null +++ b/pkg/storage/endpoint/resource_group.go @@ -0,0 +1,39 @@ +// Copyright 2022 TiKV Project Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package endpoint + +// ResourceGroupStorage defines the storage operations on the rule. +type ResourceGroupStorage interface { + LoadResourceGroups(f func(k, v string)) error + SaveResourceGroup(groupName string, groupPayload interface{}) error + DeleteResourceGroup(groupName string) error +} + +var _ ResourceGroupStorage = (*StorageEndpoint)(nil) + +// SaveResourceGroup stores a resource group to storage. +func (se *StorageEndpoint) SaveResourceGroup(groupName string, payload interface{}) error { + return se.saveJSON(resourceGroupPath, groupName, payload) +} + +// DeleteResourceGroup removes a resource group from storage. +func (se *StorageEndpoint) DeleteResourceGroup(groupName string) error { + return se.Remove(resourceGroupKeyPath(groupName)) +} + +// LoadResourceGroups loads all resource groups from storage. +func (se *StorageEndpoint) LoadResourceGroups(f func(k, v string)) error { + return se.loadRangeByPrefix(resourceGroupPath+"/", f) +} diff --git a/server/server.go b/server/server.go index f09721b48441..89049b8e25be 100644 --- a/server/server.go +++ b/server/server.go @@ -234,8 +234,9 @@ func CreateServer(ctx context.Context, cfg *config.Config, legacyServiceBuilders keyspacepb.RegisterKeyspaceServer(gs, &KeyspaceServer{GrpcServer: grpcServer}) diagnosticspb.RegisterDiagnosticsServer(gs, s) // Register the micro services GRPC service. - NewServiceregistry().InstallAllGRPCServices(s, gs) + registry.InstallAllGRPCServices(s, gs) } + s.etcdCfg = etcdCfg s.lg = cfg.GetZapLogger() s.logProps = cfg.GetZapLogProperties() diff --git a/server/storage/storage.go b/server/storage/storage.go index 4a4d4c604faa..c3874b924702 100644 --- a/server/storage/storage.go +++ b/server/storage/storage.go @@ -42,6 +42,7 @@ type Storage interface { endpoint.ExternalTSStorage endpoint.KeySpaceGCSafePointStorage endpoint.KeyspaceStorage + endpoint.ResourceGroupStorage } // NewStorageWithMemoryBackend creates a new storage with memory backend. diff --git a/tests/client/go.mod b/tests/client/go.mod index 71ebce787e93..ad4962e28f57 100644 --- a/tests/client/go.mod +++ b/tests/client/go.mod @@ -6,7 +6,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 github.com/pingcap/kvproto v0.0.0-20221104101942-09d82b914df1 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 github.com/tikv/pd v0.0.0-00010101000000-000000000000 github.com/tikv/pd/client v0.0.0-00010101000000-000000000000 go.etcd.io/etcd v0.5.0-alpha.5.0.20220915004622-85b640cee793 @@ -60,7 +60,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/pprof v0.0.0-20211122183932-1daafda22083 // indirect - github.com/google/uuid v1.0.0 // indirect + github.com/google/uuid v1.1.2 // indirect github.com/gorilla/mux v1.7.4 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 // indirect @@ -109,7 +109,7 @@ require ( github.com/sirupsen/logrus v1.6.0 // indirect github.com/soheilhy/cmux v0.1.4 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/objx v0.4.0 // indirect github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 // indirect github.com/swaggo/http-swagger v0.0.0-20200308142732-58ac5e232fba // indirect github.com/swaggo/swag v1.8.3 // indirect @@ -133,10 +133,10 @@ require ( golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect - golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect golang.org/x/tools v0.1.10 // indirect @@ -145,12 +145,12 @@ require ( google.golang.org/protobuf v1.28.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect gorm.io/driver/mysql v1.0.6 // indirect gorm.io/driver/sqlite v1.1.4 // indirect gorm.io/gorm v1.21.9 // indirect moul.io/zapgorm2 v1.1.0 // indirect - sigs.k8s.io/yaml v1.1.0 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect ) replace ( diff --git a/tests/client/go.sum b/tests/client/go.sum index d8fa53d0a4ac..96adc47ede16 100644 --- a/tests/client/go.sum +++ b/tests/client/go.sum @@ -181,14 +181,15 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20211122183932-1daafda22083 h1:c8EUapQFi+kjzedr4c6WqbwMdmB95+oDBWZ5XFHFYxY= github.com/google/pprof v0.0.0-20211122183932-1daafda22083/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -294,8 +295,8 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1/go.mod h1:eD5JxqMiuNYyFNmyY9rkJ/slN8y59oEu4Ei7F8OoKWQ= @@ -379,16 +380,17 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM= github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI= @@ -520,8 +522,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -563,8 +565,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -658,8 +660,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.0.6 h1:mA0XRPjIKi4bkE9nv+NKs6qj6QWOchqUSdWOcpd3x1E= gorm.io/driver/mysql v1.0.6/go.mod h1:KdrTanmfLPPyAOeYGyG+UpDys7/7eeWT1zCq+oekYnU= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= @@ -672,5 +675,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= moul.io/zapgorm2 v1.1.0 h1:qwAlMBYf+qJkJ7PAzJl4oCe6eS6QGiKAXUPeis0+RBE= moul.io/zapgorm2 v1.1.0/go.mod h1:emRfKjNqSzVj5lcgasBdovIXY1jSOwFz2GQZn1Rddks= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/tests/msc/resource_manager/resource_manager_test.go b/tests/msc/resource_manager/resource_manager_test.go new file mode 100644 index 000000000000..31ad1049a4ab --- /dev/null +++ b/tests/msc/resource_manager/resource_manager_test.go @@ -0,0 +1,69 @@ +package resourcemanager_test + +import ( + "context" + "io" + "net/http" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "github.com/tikv/pd/pkg/utils/testutil" + "github.com/tikv/pd/tests" + "go.uber.org/goleak" + "google.golang.org/grpc" + + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" + + // Register Service + _ "github.com/tikv/pd/pkg/mcs/registry" + _ "github.com/tikv/pd/pkg/mcs/resource_manager/server/install" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m, testutil.LeakOptions...) +} + +func TestReourceGroupCURD(t *testing.T) { + re := require.New(t) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + cluster, err := tests.NewTestCluster(ctx, 1) + defer cluster.Destroy() + re.NoError(err) + + err = cluster.RunInitialServers() + re.NoError(err) + + leaderName := cluster.WaitLeader() + leader := cluster.GetServer(leaderName) + + // Test registered GRPC Service + cc, err := grpc.DialContext(ctx, strings.TrimPrefix(leader.GetAddr(), "http://"), grpc.WithInsecure()) + re.NoError(err) + defer cc.Close() + + grpcclient := rmpb.NewResourceManagerClient(cc) + + // Test CreateResourceGroup + resp, err := grpcclient.AddResourceGroup(ctx, &rmpb.PutResourceGroupRequest{ + Group: &rmpb.ResourceGroup{ + ResourceGroupName: "test", + Settings: &rmpb.GroupSettings{ + Mode: rmpb.GroupMode_RUMode, + }, + }, + }) + re.NoError(err) + re.Equal(resp.ResponseBody, "Success!") + + // Test ListResourceGroup (via HTTP) + resp1, err := http.Get(leader.GetAddr() + "/resource-manager/api/v1/config/groups") + re.NoError(err) + defer resp1.Body.Close() + re.Equal(http.StatusOK, resp1.StatusCode) + respString, err := io.ReadAll(resp1.Body) + re.NoError(err) + re.Contains(string(respString), "test") +} diff --git a/tests/registry/registry_test.go b/tests/registry/registry_test.go index 4cc8a57fdf73..66135c03ee7f 100644 --- a/tests/registry/registry_test.go +++ b/tests/registry/registry_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/tikv/pd/pkg/msc/registry" + "github.com/tikv/pd/pkg/mcs/registry" "github.com/tikv/pd/pkg/utils/testutil" "github.com/tikv/pd/server" "github.com/tikv/pd/tests"