cubefs
136 строк · 3.3 Кб
1// Copyright 2022 The CubeFS Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12// implied. See the License for the specific language governing
13// permissions and limitations under the License.
14
15package clustermgr
16
17import (
18"context"
19"encoding/json"
20"net/http"
21
22"github.com/cubefs/cubefs/blobstore/common/errors"
23"github.com/cubefs/cubefs/blobstore/common/proto"
24"github.com/cubefs/cubefs/blobstore/common/rpc"
25)
26
27const (
28MemberTypeMin = MemberType(iota)
29MemberTypeLearner
30MemberTypeNormal
31MemberTypeMax
32)
33
34var retryCodes = []int{
35http.StatusInternalServerError,
36http.StatusBadGateway,
37http.StatusGatewayTimeout,
38int(errors.ErrRaftReadIndex),
39}
40
41type MemberType uint8
42
43type Config struct {
44rpc.LbConfig
45}
46
47type Client struct {
48rpc.Client
49}
50
51var _ ClientAPI = (*Client)(nil)
52
53var defaultShouldRetry = func(code int, err error) bool {
54for i := range retryCodes {
55if code == retryCodes[i] {
56return true
57}
58}
59
60return err != nil
61}
62
63func New(cfg *Config) *Client {
64if cfg.ShouldRetry == nil {
65cfg.ShouldRetry = defaultShouldRetry
66}
67return &Client{rpc.NewLbClient(&cfg.LbConfig, nil)}
68}
69
70type BidScopeArgs struct {
71Count uint64 `json:"count"`
72}
73
74type BidScopeRet struct {
75StartBid proto.BlobID `json:"start_bid"`
76EndBid proto.BlobID `json:"end_bid"`
77}
78
79// BidAlloc return available bid scope
80func (c *Client) AllocBid(ctx context.Context, args *BidScopeArgs) (ret *BidScopeRet, err error) {
81ret = &BidScopeRet{}
82err = c.PostWith(ctx, "/bid/alloc", ret, args)
83return
84}
85
86type AddMemberArgs struct {
87PeerID uint64 `json:"peer_id"`
88Host string `json:"host"`
89MemberType MemberType `json:"member_type"`
90NodeHost string `json:"node_host"`
91}
92
93type MemberContext struct {
94NodeHost string `json:"node_host"`
95}
96
97func (mc *MemberContext) Marshal() ([]byte, error) {
98return json.Marshal(mc)
99}
100
101func (mc *MemberContext) Unmarshal(data []byte) error {
102return json.Unmarshal(data, mc)
103}
104
105type RemoveMemberArgs struct {
106PeerID uint64 `json:"peer_id"`
107}
108
109// AddMember add new member(normal or learner) into raft cluster
110func (c *Client) AddMember(ctx context.Context, args *AddMemberArgs) (err error) {
111err = c.PostWith(ctx, "/member/add", nil, args)
112return
113}
114
115// RemoveMember remove member from raft cluster
116func (c *Client) RemoveMember(ctx context.Context, peerID uint64) (err error) {
117err = c.PostWith(ctx, "/member/remove", nil, &RemoveMemberArgs{PeerID: peerID})
118return
119}
120
121// RemoveMember remove member from raft cluster
122func (c *Client) TransferLeadership(ctx context.Context, transfereeID uint64) (err error) {
123err = c.PostWith(ctx, "/leadership/transfer", nil, &RemoveMemberArgs{PeerID: transfereeID})
124return
125}
126
127// Stat return cluster's statics info, like space info and raft status and so on
128func (c *Client) Stat(ctx context.Context) (ret *StatInfo, err error) {
129ret = &StatInfo{}
130err = c.GetWith(ctx, "/stat", ret)
131return
132}
133
134func (c *Client) Snapshot(ctx context.Context) (*http.Response, error) {
135return c.Get(ctx, "/snapshot/dump")
136}
137