Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Introduce version checking mechanism #1148

Merged
merged 37 commits into from
Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
cd02a27
update proto
nolouch Jul 5, 2018
52bee45
add version
nolouch Jul 6, 2018
595f133
update proto
nolouch Jul 12, 2018
2fdd381
on change cluster version
nolouch Jul 12, 2018
efc59f1
use cluster version to switch new feature
nolouch Jul 12, 2018
726ef07
add tests
nolouch Jul 12, 2018
3178fae
address comments
nolouch Jul 13, 2018
cbe6d32
update proto
nolouch Jul 13, 2018
9997f8d
merge master
nolouch Jul 13, 2018
d18d0aa
fix response
nolouch Jul 13, 2018
13bccce
rename version
nolouch Jul 16, 2018
69cf420
use go-semver
nolouch Jul 16, 2018
9d81d84
fix tests
nolouch Jul 16, 2018
9e6866e
clean up
nolouch Jul 16, 2018
f51bacf
handle onchange cluster version failed situation
nolouch Jul 16, 2018
365da06
address comments
nolouch Jul 16, 2018
e1a3e65
rename to OnStoreVersionChange
nolouch Jul 16, 2018
2eaabf1
address comment
nolouch Jul 16, 2018
0a1cea3
supported pd-ctl set cluster version
nolouch Jul 17, 2018
2b73eed
address comments
nolouch Jul 17, 2018
71bbf0f
Merge branch 'master' into version-introduce
nolouch Jul 17, 2018
e15af4f
add show cluster version command
nolouch Jul 17, 2018
7d9a99e
remove background check cluster version
nolouch Jul 17, 2018
5bfb86f
fix learn switch
nolouch Jul 17, 2018
4b007fa
address comments
nolouch Jul 18, 2018
94542d0
Merge remote-tracking branch 'upstream/master' into version-introduce
nolouch Jul 18, 2018
3fa0a54
Merge remote-tracking branch 'upstream/master' into version-introduce
nolouch Jul 18, 2018
4478e41
update proto
nolouch Jul 18, 2018
5eeca3d
address comment
nolouch Jul 19, 2018
3f711b8
fix
nolouch Jul 19, 2018
d099292
address comment
nolouch Jul 19, 2018
e40ff3d
address comment
nolouch Jul 19, 2018
1693736
Merge branch 'master' into version-introduce
nolouch Jul 19, 2018
8dccabd
address comment
nolouch Jul 19, 2018
c7c42ca
Merge branch 'master' into version-introduce
nolouch Jul 23, 2018
89a1d93
tiny clear
nolouch Jul 24, 2018
a01fc8f
Merge branch 'master' into version-introduce
nolouch Jul 24, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,3 @@
[[constraint]]
name = "github.com/pingcap/kvproto"
branch = "master"

55 changes: 49 additions & 6 deletions pdctl/command/config_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ import (
)

var (
configPrefix = "pd/api/v1/config"
schedulePrefix = "pd/api/v1/config/schedule"
replicationPrefix = "pd/api/v1/config/replicate"
namespacePrefix = "pd/api/v1/config/namespace"
labelPropertyPrefix = "pd/api/v1/config/label-property"
configPrefix = "pd/api/v1/config"
schedulePrefix = "pd/api/v1/config/schedule"
replicationPrefix = "pd/api/v1/config/replicate"
namespacePrefix = "pd/api/v1/config/namespace"
labelPropertyPrefix = "pd/api/v1/config/label-property"
clusterVersionPrefix = "pd/api/v1/config/cluster-version"
)

// NewConfigCommand return a config subcommand of rootCmd
Expand All @@ -55,6 +56,7 @@ func NewShowConfigCommand() *cobra.Command {
sc.AddCommand(NewShowNamespaceConfigCommand())
sc.AddCommand(NewShowReplicationConfigCommand())
sc.AddCommand(NewShowLabelPropertyCommand())
sc.AddCommand(NewShowClusterVersionCommand())
return sc
}

Expand Down Expand Up @@ -98,15 +100,26 @@ func NewShowLabelPropertyCommand() *cobra.Command {
return sc
}

// NewShowClusterVersionCommand returns a cluster version subcommand of show subcommand.
func NewShowClusterVersionCommand() *cobra.Command {
sc := &cobra.Command{
Use: "cluster-version",
Short: "show the cluster version",
Run: showClusterVersionCommandFunc,
}
return sc
}

// NewSetConfigCommand return a set subcommand of configCmd
func NewSetConfigCommand() *cobra.Command {
sc := &cobra.Command{
Use: "set <option> <value>, set namespace <name> <option> <value>, set label-property <type> <key> <value>",
Use: "set <option> <value>, set namespace <name> <option> <value>, set label-property <type> <key> <value>, set cluster-version <version>",
Short: "set the option with value",
Run: setConfigCommandFunc,
}
sc.AddCommand(NewSetNamespaceConfigCommand())
sc.AddCommand(NewSetLabelPropertyCommand())
sc.AddCommand(NewSetClusterVersionCommand())
return sc
}

Expand All @@ -130,6 +143,16 @@ func NewSetLabelPropertyCommand() *cobra.Command {
return sc
}

// NewSetClusterVersionCommand creates a set subcommand of set subcommand
func NewSetClusterVersionCommand() *cobra.Command {
sc := &cobra.Command{
Use: "cluster-version <version>",
Short: "set cluster version",
Run: setClusterVersionCommandFunc,
}
return sc
}

// NewDeleteConfigCommand a set subcommand of cfgCmd
func NewDeleteConfigCommand() *cobra.Command {
sc := &cobra.Command{
Expand Down Expand Up @@ -211,6 +234,15 @@ func showNamespaceConfigCommandFunc(cmd *cobra.Command, args []string) {
fmt.Println(r)
}

func showClusterVersionCommandFunc(cmd *cobra.Command, args []string) {
r, err := doRequest(cmd, clusterVersionPrefix, http.MethodGet)
if err != nil {
fmt.Printf("Failed to get cluster version: %s\n", err)
return
}
fmt.Println(r)
}

func postConfigDataWithPath(cmd *cobra.Command, key, value, path string) error {
var val interface{}
data := make(map[string]interface{})
Expand Down Expand Up @@ -305,3 +337,14 @@ func postLabelProperty(cmd *cobra.Command, action string, args []string) {
prefix := path.Join(labelPropertyPrefix)
postJSON(cmd, prefix, input)
}

func setClusterVersionCommandFunc(cmd *cobra.Command, args []string) {
if len(args) != 1 {
fmt.Println(cmd.UsageString())
return
}
input := map[string]interface{}{
"cluster-version": args[0],
}
postJSON(cmd, clusterVersionPrefix, input)
}
7 changes: 7 additions & 0 deletions pkg/integration_test/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"time"

"github.com/coreos/etcd/clientv3"
"github.com/coreos/go-semver/semver"
"github.com/juju/errors"
"github.com/pingcap/kvproto/pkg/pdpb"
"github.com/pingcap/pd/server"
Expand Down Expand Up @@ -116,6 +117,12 @@ func (s *testServer) GetClusterID() uint64 {
return s.server.ClusterID()
}

func (s *testServer) GetClusterVersion() semver.Version {
s.RLock()
defer s.RUnlock()
return s.server.GetClusterVersion()
}

func (s *testServer) GetServerID() uint64 {
s.RLock()
defer s.RUnlock()
Expand Down
148 changes: 148 additions & 0 deletions pkg/integration_test/version_upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Copyright 2018 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package integration

import (
"context"

"github.com/coreos/go-semver/semver"
. "github.com/pingcap/check"
"github.com/pingcap/kvproto/pkg/metapb"
"github.com/pingcap/kvproto/pkg/pdpb"
)

func (s *integrationTestSuite) bootstrapCluster(server *testServer, c *C) {
bootstrapReq := &pdpb.BootstrapRequest{
Header: &pdpb.RequestHeader{ClusterId: server.GetClusterID()},
Store: &metapb.Store{Id: 1, Address: "mock://1"},
Region: &metapb.Region{Id: 2, Peers: []*metapb.Peer{{3, 1, false}}},
}
_, err := server.server.Bootstrap(context.Background(), bootstrapReq)
c.Assert(err, IsNil)
}

func (s *integrationTestSuite) TestStoreRegister(c *C) {
c.Parallel()
cluster, err := newTestCluster(3)
c.Assert(err, IsNil)
defer cluster.Destory()

err = cluster.RunInitialServers()
c.Assert(err, IsNil)
cluster.WaitLeader()
leaderServer := cluster.GetServer(cluster.GetLeader())
s.bootstrapCluster(leaderServer, c)

putStoreRequest := &pdpb.PutStoreRequest{
Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()},
Store: &metapb.Store{
Id: 1,
Address: "mock-1",
Version: "2.0.1",
},
}
_, err = leaderServer.server.PutStore(context.Background(), putStoreRequest)
c.Assert(err, IsNil)
// FIX ME: read v0.0.0 in sometime
cluster.WaitLeader()
version := leaderServer.GetClusterVersion()
// Restart all PDs.
err = cluster.StopAll()
c.Assert(err, IsNil)
err = cluster.RunInitialServers()
c.Assert(err, IsNil)
cluster.WaitLeader()

leaderServer = cluster.GetServer(cluster.GetLeader())
newVersion := leaderServer.GetClusterVersion()
c.Assert(version, Equals, newVersion)

// putNewStore with old version
putStoreRequest = &pdpb.PutStoreRequest{
Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()},
Store: &metapb.Store{
Id: 4,
Address: "mock-4",
Version: "1.0.1",
},
}
_, err = leaderServer.server.PutStore(context.Background(), putStoreRequest)
c.Assert(err, NotNil)
}

func (s *integrationTestSuite) TestRollingUpgrade(c *C) {
c.Parallel()
cluster, err := newTestCluster(3)
c.Assert(err, IsNil)
defer cluster.Destory()
err = cluster.RunInitialServers()
c.Assert(err, IsNil)
cluster.WaitLeader()
leaderServer := cluster.GetServer(cluster.GetLeader())
s.bootstrapCluster(leaderServer, c)

stores := []*pdpb.PutStoreRequest{
{
Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()},
Store: &metapb.Store{
Id: 1,
Address: "mock-1",
Version: "2.0.1",
},
},
{
Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()},
Store: &metapb.Store{
Id: 4,
Address: "mock-4",
Version: "2.0.1",
},
},
{
Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()},
Store: &metapb.Store{
Id: 6,
Address: "mock-6",
Version: "2.0.1",
},
},
{
Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()},
Store: &metapb.Store{
Id: 7,
Address: "mock-7",
Version: "2.0.1",
},
},
}
for _, store := range stores {
_, err = leaderServer.server.PutStore(context.Background(), store)
c.Assert(err, IsNil)
}
c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 0, Patch: 1})
// rolling update
for i, store := range stores {
if i == 0 {
store.Store.State = metapb.StoreState_Tombstone
}
store.Store.Version = "2.1.0"
resp, err := leaderServer.server.PutStore(context.Background(), store)
c.Assert(err, IsNil)
if i != len(stores)-1 {
c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 0, Patch: 1})
c.Assert(resp.GetHeader().GetError(), IsNil)
}
}
c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 1})
}
23 changes: 23 additions & 0 deletions server/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/gorilla/mux"
"github.com/juju/errors"
"github.com/pingcap/pd/pkg/error_code"
"github.com/pingcap/pd/server"
"github.com/unrolled/render"
)
Expand Down Expand Up @@ -168,3 +169,25 @@ func (h *confHandler) SetLabelProperty(w http.ResponseWriter, r *http.Request) {
}
h.rd.JSON(w, http.StatusOK, nil)
}

func (h *confHandler) GetClusterVersion(w http.ResponseWriter, r *http.Request) {
h.rd.JSON(w, http.StatusOK, h.svr.GetClusterVersion())
}

func (h *confHandler) SetClusterVersion(w http.ResponseWriter, r *http.Request) {
input := make(map[string]string)
if err := readJSONRespondError(h.rd, w, r.Body, &input); err != nil {
return
}
version, ok := input["cluster-version"]
if !ok {
errorResp(h.rd, w, errcode.NewInvalidInputErr(errors.New("not set cluster-version")))
return
}
err := h.svr.SetClusterVersion(version)
if err != nil {
errorResp(h.rd, w, errcode.NewInternalErr(err))
return
}
h.rd.JSON(w, http.StatusOK, nil)
}
4 changes: 4 additions & 0 deletions server/api/label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) {
Value: "ssd",
},
},
Version: "2.0.0",
},
{
Id: 4,
Expand All @@ -61,6 +62,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) {
Value: "hdd",
},
},
Version: "2.0.0",
},
{
Id: 6,
Expand All @@ -76,6 +78,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) {
Value: "ssd",
},
},
Version: "2.0.0",
},
{
Id: 7,
Expand All @@ -95,6 +98,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) {
Value: "test",
},
},
Version: "2.0.0",
},
}

Expand Down
1 change: 1 addition & 0 deletions server/api/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func mustPutStore(c *C, svr *server.Server, id uint64, state metapb.StoreState,
Address: fmt.Sprintf("tikv%d", id),
State: state,
Labels: labels,
Version: server.MinSupportedVersion(server.Version2_0).String(),
},
})
c.Assert(err, IsNil)
Expand Down
2 changes: 2 additions & 0 deletions server/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ func createRouter(prefix string, svr *server.Server) *mux.Router {
router.HandleFunc("/api/v1/config/namespace/{name}", confHandler.DeleteNamespace).Methods("DELETE")
router.HandleFunc("/api/v1/config/label-property", confHandler.GetLabelProperty).Methods("GET")
router.HandleFunc("/api/v1/config/label-property", confHandler.SetLabelProperty).Methods("POST")
router.HandleFunc("/api/v1/config/cluster-version", confHandler.GetClusterVersion).Methods("GET")
router.HandleFunc("/api/v1/config/cluster-version", confHandler.SetClusterVersion).Methods("POST")

storeHandler := newStoreHandler(svr, rd)
router.HandleFunc("/api/v1/store/{id}", storeHandler.Get).Methods("GET")
Expand Down
Loading