Skip to content

Commit

Permalink
pdctl: cherry pick bugfixes (#1314)
Browse files Browse the repository at this point in the history
* pdctl: fix region key problems in detach mode (#1298)

* pd-ctl: escape the key before query the corresponding region (#1299)

* pdctl: fix decode key (#1308)

Signed-off-by: disksing <i@disksing.com>
  • Loading branch information
disksing authored Nov 8, 2018
1 parent 323010d commit e27a7de
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 9 deletions.
33 changes: 33 additions & 0 deletions server/api/region_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package api
import (
"fmt"
"math/rand"
"net/url"
"sort"

. "github.com/pingcap/check"
Expand Down Expand Up @@ -206,3 +207,35 @@ func (s *testRegionSuite) TestTopN(c *C) {
}
}
}

var _ = Suite(&testGetRegionSuite{})

type testGetRegionSuite struct {
svr *server.Server
cleanup cleanUpFunc
urlPrefix string
}

func (s *testGetRegionSuite) SetUpSuite(c *C) {
s.svr, s.cleanup = mustNewServer(c)
mustWaitLeader(c, []*server.Server{s.svr})

addr := s.svr.GetAddr()
s.urlPrefix = fmt.Sprintf("%s%s/api/v1", addr, apiPrefix)

mustBootstrapCluster(c, s.svr)
}

func (s *testGetRegionSuite) TearDownSuite(c *C) {
s.cleanup()
}

func (s *testGetRegionSuite) TestRegionKey(c *C) {
r := newTestRegionInfo(99, 1, []byte{0xFF, 0xFF, 0xAA}, []byte{0xFF, 0xFF, 0xCC}, core.SetWrittenBytes(500), core.SetReadBytes(800), core.SetRegionConfVer(3), core.SetRegionVersion(2))
mustRegionHeartbeat(c, s.svr, r)
url := fmt.Sprintf("%s/region/key/%s", s.urlPrefix, url.QueryEscape(string([]byte{0xFF, 0xFF, 0xBB})))
regionInfo := &regionInfo{}
err := readJSONWithURL(url, regionInfo)
c.Assert(err, IsNil)
c.Assert(r.GetID(), Equals, regionInfo.ID)
}
1 change: 1 addition & 0 deletions tools/pd-ctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func main() {
if pdAddr != "" {
os.Args = append(os.Args, "-u", pdAddr)
}
flag.CommandLine.ParseErrorsWhitelist.UnknownFlags = true
flag.Parse()

if version {
Expand Down
39 changes: 30 additions & 9 deletions tools/pd-ctl/pdctl/command/region_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"os/exec"
"strconv"
"strings"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -199,7 +201,7 @@ func showRegionTopSizeCommandFunc(cmd *cobra.Command, args []string) {
// NewRegionWithKeyCommand return a region with key subcommand of regionCmd
func NewRegionWithKeyCommand() *cobra.Command {
r := &cobra.Command{
Use: "key [--format=raw|pb|proto|protobuf] <key>",
Use: "key [--format=raw|encode] <key>",
Short: "show the region with key",
Run: showRegionWithTableCommandFunc,
}
Expand All @@ -222,8 +224,8 @@ func showRegionWithTableCommandFunc(cmd *cobra.Command, args []string) {
switch format {
case "raw":
key = args[0]
case "pb", "proto", "protobuf":
key, err = decodeProtobufText(args[0])
case "encode":
key, err = decodeKey(args[0])
if err != nil {
fmt.Println("Error: ", err)
return
Expand All @@ -232,18 +234,18 @@ func showRegionWithTableCommandFunc(cmd *cobra.Command, args []string) {
fmt.Println("Error: unknown format")
return
}
// TODO: Deal with path escaped

key = url.QueryEscape(key)
prefix := regionKeyPrefix + "/" + key
r, err := doRequest(cmd, prefix, http.MethodGet)
if err != nil {
fmt.Printf("Failed to get region: %s\n", err)
return
}
fmt.Println(r)

}

func decodeProtobufText(text string) (string, error) {
func decodeKey(text string) (string, error) {
var buf []byte
r := bytes.NewBuffer([]byte(text))
for {
Expand All @@ -254,13 +256,32 @@ func decodeProtobufText(text string) (string, error) {
}
break
}
if c == '\\' {
_, err := fmt.Sscanf(string(r.Next(3)), "%03o", &c)
if c != '\\' {
buf = append(buf, c)
continue
}
n := r.Next(1)
if len(n) == 0 {
return "", io.EOF
}
// See: https://golang.org/ref/spec#Rune_literals
if idx := strings.IndexByte(`abfnrtv\'"`, n[0]); idx != -1 {
buf = append(buf, []byte("\a\b\f\n\r\t\v\\'\"")[idx])
continue
}

switch n[0] {
case 'x':
fmt.Sscanf(string(r.Next(2)), "%02x", &c)
buf = append(buf, c)
default:
n = append(n, r.Next(2)...)
_, err := fmt.Sscanf(string(n), "%03o", &c)
if err != nil {
return "", err
}
buf = append(buf, c)
}
buf = append(buf, c)
}
return string(buf), nil
}
Expand Down

0 comments on commit e27a7de

Please sign in to comment.