mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(master): add http args parser in master
. #22200600 Signed-off-by: slasher <mcq.sejust@gmail.com>
This commit is contained in:
parent
1877c03de8
commit
2742e1ddb7
@ -15,7 +15,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
@ -315,8 +314,7 @@ func newCmdFlashGroupClient(client *master.MasterClient) *cobra.Command {
|
||||
return
|
||||
}
|
||||
stdoutln("Client Response:")
|
||||
b, _ := json.MarshalIndent(fgv, "", " ")
|
||||
stdoutln(string(b))
|
||||
stdoutln(formatIndent(fgv))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,22 +38,30 @@ func newFlashNodeCmd(client *master.MasterClient) *cobra.Command {
|
||||
newCmdFlashNodeRemove(client),
|
||||
newCmdFlashNodeGet(client),
|
||||
newCmdFlashNodeList(client),
|
||||
|
||||
newCmdFlashNodeHTTPStat(client),
|
||||
newCmdFlashNodeHTTPEvict(client),
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newCmdFlashNodeSet(client *master.MasterClient) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: CliOpSet + _flashnodeAddr + " [state]",
|
||||
Use: CliOpSet + _flashnodeAddr + " [IsEnable]",
|
||||
Short: "set flash node enable or not",
|
||||
Args: cobra.MinimumNArgs(2),
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
var err error
|
||||
defer func() { errout(err) }()
|
||||
if err = client.NodeAPI().SetFlashNode(args[0], args[1]); err != nil {
|
||||
addr := args[0]
|
||||
enable, err := strconv.ParseBool(args[1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
stdoutlnf("set flashnode:%s state:%s success", args[0], args[1])
|
||||
if err = client.NodeAPI().SetFlashNode(addr, enable); err != nil {
|
||||
return
|
||||
}
|
||||
stdoutlnf("set flashnode:%s enable:%v success", addr, enable)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -117,6 +125,46 @@ func newCmdFlashNodeList(client *master.MasterClient) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newCmdFlashNodeHTTPStat(_ *master.MasterClient) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "httpStat" + _flashnodeAddr,
|
||||
Short: "show flashnode stat",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
var err error
|
||||
defer func() { errout(err) }()
|
||||
stat, err := httpclient.New().WithAddr(addr2Prof(args[0])).FlashNode().Stat()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
stdoutln(formatIndent(stat))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newCmdFlashNodeHTTPEvict(_ *master.MasterClient) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "httpEvict" + _flashnodeAddr + " [volume]",
|
||||
Short: "evict cache in flashnode",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
var err error
|
||||
defer func() { errout(err) }()
|
||||
addr := args[0]
|
||||
if len(args) == 1 {
|
||||
if err = httpclient.New().WithAddr(addr2Prof(addr)).FlashNode().EvictAll(); err == nil {
|
||||
stdoutlnf("%s evicts all [OK]", addr)
|
||||
}
|
||||
return
|
||||
}
|
||||
volume := args[1]
|
||||
if err = httpclient.New().WithAddr(addr2Prof(addr)).FlashNode().EvictVol(volume); err == nil {
|
||||
stdoutlnf("%s evicts volume(%s) [OK]", addr, volume)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func showFlashNodesView(flashNodeViewInfos []*proto.FlashNodeViewInfo, showStat bool, tbl table) table {
|
||||
client := httpclient.New()
|
||||
sort.Slice(flashNodeViewInfos, func(i, j int) bool {
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
@ -36,6 +37,11 @@ func formatAddr(ipAddr string, domainAddr string) (addr string) {
|
||||
return
|
||||
}
|
||||
|
||||
func formatIndent(v interface{}) string {
|
||||
b, _ := json.MarshalIndent(v, "", " ")
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func formatClusterView(cv *proto.ClusterView, cn *proto.ClusterNodeInfo, cp *proto.ClusterIP) string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString(fmt.Sprintf(" Cluster name : %v\n", cv.Name))
|
||||
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cubefs/cubefs/cmd/common"
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
"github.com/cubefs/cubefs/util"
|
||||
"github.com/cubefs/cubefs/util/compressor"
|
||||
@ -33,6 +34,8 @@ import (
|
||||
"github.com/cubefs/cubefs/util/log"
|
||||
)
|
||||
|
||||
var parseArgs = common.ParseArguments
|
||||
|
||||
// Parse the request that adds/deletes a raft node.
|
||||
func parseRequestForRaftNode(r *http.Request) (id uint64, host string, err error) {
|
||||
if err = r.ParseForm(); err != nil {
|
||||
|
||||
@ -157,10 +157,6 @@ const (
|
||||
quotaClass = "quotaClass"
|
||||
quotaOfClass = "quotaOfStorageClass"
|
||||
dataMediaTypeKey = "dataMediaType"
|
||||
|
||||
stateKey = "state"
|
||||
versionKey = "version"
|
||||
fgSlotsKey = "slots"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -23,6 +23,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cubefs/cubefs/cmd/common"
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
"github.com/cubefs/cubefs/util/errors"
|
||||
"github.com/cubefs/cubefs/util/exporter"
|
||||
@ -145,13 +146,13 @@ func (m *Server) turnFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupTurn, metric, err, nil)
|
||||
}()
|
||||
r.ParseForm()
|
||||
enabled, err := extractStatus(r)
|
||||
if err != nil {
|
||||
var enable common.Bool
|
||||
if err = parseArgs(r, enable.Enable()); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
topo := m.cluster.flashNodeTopo
|
||||
enabled := enable.V
|
||||
if enabled {
|
||||
topo.clientOff.Store([]byte(nil))
|
||||
} else {
|
||||
@ -199,13 +200,13 @@ func (m *Server) removeFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupRemove, metric, err, nil)
|
||||
}()
|
||||
var flashGroupID uint64
|
||||
if flashGroupID, err = extractFlashGroupID(r); err != nil {
|
||||
var flashGroupID common.Uint
|
||||
if err = parseArgs(r, flashGroupID.ID()); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
var flashGroup *FlashGroup
|
||||
if flashGroup, err = m.cluster.flashNodeTopo.getFlashGroup(flashGroupID); err != nil {
|
||||
if flashGroup, err = m.cluster.flashNodeTopo.getFlashGroup(flashGroupID.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
@ -239,7 +240,7 @@ func (c *Cluster) removeFlashGroup(flashGroup *FlashGroup) (err error) {
|
||||
|
||||
func (m *Server) setFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
flashGroupID uint64
|
||||
flashGroupID common.Uint
|
||||
fgStatus proto.FlashGroupStatus
|
||||
flashGroup *FlashGroup
|
||||
err error
|
||||
@ -248,11 +249,17 @@ func (m *Server) setFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupSet, metric, err, nil)
|
||||
}()
|
||||
if flashGroupID, fgStatus, err = parseRequestForSetFlashGroup(r); err != nil {
|
||||
|
||||
var active common.Bool
|
||||
if err = parseArgs(r, flashGroupID.ID(), active.Enable().OnValue(func() error {
|
||||
fgStatus = argConvertFlashGroupStatus(active.V)
|
||||
return nil
|
||||
}),
|
||||
); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
if flashGroup, err = m.cluster.flashNodeTopo.getFlashGroup(flashGroupID); err != nil {
|
||||
if flashGroup, err = m.cluster.flashNodeTopo.getFlashGroup(flashGroupID.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
@ -276,7 +283,7 @@ func (m *Server) setFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (m *Server) getFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
flashGroupID uint64
|
||||
flashGroupID common.Uint
|
||||
flashGroup *FlashGroup
|
||||
err error
|
||||
)
|
||||
@ -284,11 +291,11 @@ func (m *Server) getFlashGroup(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupGet, metric, err, nil)
|
||||
}()
|
||||
if flashGroupID, err = extractFlashGroupID(r); err != nil {
|
||||
if err = parseArgs(r, flashGroupID.ID()); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
if flashGroup, err = m.cluster.flashNodeTopo.getFlashGroup(flashGroupID); err != nil {
|
||||
if flashGroup, err = m.cluster.flashNodeTopo.getFlashGroup(flashGroupID.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
@ -301,8 +308,7 @@ func (m *Server) flashGroupAddFlashNode(w http.ResponseWriter, r *http.Request)
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupNodeAdd, metric, err, nil)
|
||||
}()
|
||||
|
||||
flashGroupID, addr, zoneName, count, err := parseRequestForManageFlashNodeOfFlashGroup(r)
|
||||
flashGroupID, addr, zoneName, count, err := parseArgsFlashGroupNode(r)
|
||||
if err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
@ -386,7 +392,7 @@ func (m *Server) flashGroupRemoveFlashNode(w http.ResponseWriter, r *http.Reques
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupNodeRemove, metric, err, nil)
|
||||
}()
|
||||
flashGroupID, addr, zoneName, count, err := parseRequestForManageFlashNodeOfFlashGroup(r)
|
||||
flashGroupID, addr, zoneName, count, err := parseArgsFlashGroupNode(r)
|
||||
if err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
@ -468,13 +474,19 @@ func (m *Server) listFlashGroups(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.AdminFlashGroupList, metric, err, nil)
|
||||
}()
|
||||
if fgStatus, err = extractFlashGroupStatus(r); err != nil {
|
||||
if value := r.FormValue(enableKey); value == "" {
|
||||
var active common.Bool
|
||||
if err = parseArgs(r, active.Enable().OmitEmpty().
|
||||
OnEmpty(func() error {
|
||||
allStatus = true // resp all flash groups
|
||||
} else {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}).
|
||||
OnValue(func() error {
|
||||
fgStatus = argConvertFlashGroupStatus(active.V)
|
||||
return nil
|
||||
}),
|
||||
); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
fgv := m.cluster.flashNodeTopo.getFlashGroupsAdminView(fgStatus, allStatus)
|
||||
sendOkReply(w, r, newSuccessHTTPReply(fgv))
|
||||
@ -494,65 +506,10 @@ func (m *Server) clientFlashGroups(w http.ResponseWriter, r *http.Request) {
|
||||
send(w, r, cache)
|
||||
}
|
||||
|
||||
func parseRequestForManageFlashNodeOfFlashGroup(r *http.Request) (flashGroupID uint64, addr, zoneName string, count int, err error) {
|
||||
if flashGroupID, err = extractFlashGroupID(r); err != nil {
|
||||
return
|
||||
}
|
||||
if addr = r.FormValue(addrKey); addr != "" {
|
||||
return
|
||||
}
|
||||
|
||||
if zoneName, err = extractZoneName(r); err != nil {
|
||||
return
|
||||
}
|
||||
if count, err = extractCount(r); err != nil {
|
||||
return
|
||||
}
|
||||
if count <= 0 {
|
||||
err = unmatchedKey(countKey)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseRequestForSetFlashGroup(r *http.Request) (flashGroupID uint64, fgStatus proto.FlashGroupStatus, err error) {
|
||||
if flashGroupID, err = extractFlashGroupID(r); err != nil {
|
||||
return
|
||||
}
|
||||
fgStatus, err = extractFlashGroupStatus(r)
|
||||
return
|
||||
}
|
||||
|
||||
func extractFlashGroupStatus(r *http.Request) (fgStatus proto.FlashGroupStatus, err error) {
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return
|
||||
}
|
||||
var status bool
|
||||
if status, err = extractStatus(r); err != nil {
|
||||
return
|
||||
}
|
||||
if status {
|
||||
fgStatus = proto.FlashGroupStatus_Active
|
||||
} else {
|
||||
fgStatus = proto.FlashGroupStatus_Inactive
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func extractFlashGroupID(r *http.Request) (ID uint64, err error) {
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return
|
||||
}
|
||||
var value string
|
||||
if value = r.FormValue(idKey); value == "" {
|
||||
err = keyNotFound(idKey)
|
||||
return
|
||||
}
|
||||
return strconv.ParseUint(value, 10, 64)
|
||||
}
|
||||
|
||||
func getSetSlots(r *http.Request) (slots []uint32) {
|
||||
r.ParseForm()
|
||||
slots = make([]uint32, 0)
|
||||
slotStr := r.FormValue(fgSlotsKey)
|
||||
slotStr := r.FormValue("slots")
|
||||
if slotStr != "" {
|
||||
arr := strings.Split(slotStr, ",")
|
||||
for i := 0; i < len(arr); i++ {
|
||||
@ -561,31 +518,38 @@ func getSetSlots(r *http.Request) (slots []uint32) {
|
||||
continue
|
||||
}
|
||||
if len(slots) >= defaultFlashGroupSlotsCount {
|
||||
continue
|
||||
return
|
||||
}
|
||||
|
||||
slots = append(slots, uint32(slot))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func extractZoneName(r *http.Request) (name string, err error) {
|
||||
if name = r.FormValue(zoneNameKey); name == "" {
|
||||
err = keyNotFound(zoneNameKey)
|
||||
func parseArgsFlashGroupNode(r *http.Request) (id uint64, addr, zoneName string, count int, err error) {
|
||||
var (
|
||||
idV common.Uint
|
||||
addrV common.String
|
||||
zoneV common.String
|
||||
countV common.Int
|
||||
)
|
||||
if err = parseArgs(r, idV.ID(), addrV.Addr()); err == nil {
|
||||
id = idV.V
|
||||
addr = addrV.V
|
||||
return
|
||||
}
|
||||
if err = parseArgs(r, idV.ID(), addrV.Addr().OmitEmpty(), zoneV.ZoneName(), countV.Count()); err == nil {
|
||||
id = idV.V
|
||||
addr = addrV.V
|
||||
zoneName = zoneV.V
|
||||
count = int(countV.V)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func extractCount(r *http.Request) (count int, err error) {
|
||||
var value string
|
||||
if value = r.FormValue(countKey); value == "" {
|
||||
return
|
||||
func argConvertFlashGroupStatus(active bool) proto.FlashGroupStatus {
|
||||
if active {
|
||||
return proto.FlashGroupStatus_Active
|
||||
}
|
||||
if count, err = strconv.Atoi(value); err != nil {
|
||||
err = unmatchedKey(countKey)
|
||||
return
|
||||
}
|
||||
return
|
||||
return proto.FlashGroupStatus_Inactive
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cubefs/cubefs/cmd/common"
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
"github.com/cubefs/cubefs/util"
|
||||
"github.com/cubefs/cubefs/util/errors"
|
||||
"github.com/cubefs/cubefs/util/exporter"
|
||||
"github.com/cubefs/cubefs/util/log"
|
||||
@ -156,9 +158,9 @@ func (flashNode *FlashNode) createHeartbeatTask(masterAddr string) (task *proto.
|
||||
|
||||
func (m *Server) addFlashNode(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
nodeAddr string
|
||||
zoneName string
|
||||
version string
|
||||
nodeAddr common.String
|
||||
zoneName common.String
|
||||
version common.String
|
||||
id uint64
|
||||
err error
|
||||
)
|
||||
@ -166,11 +168,19 @@ func (m *Server) addFlashNode(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.FlashNodeAdd, metric, err, nil)
|
||||
}()
|
||||
if nodeAddr, zoneName, version, err = parseRequestForAddFlashNode(r); err != nil {
|
||||
if err = parseArgs(r, argParserNodeAddr(&nodeAddr),
|
||||
zoneName.ZoneName().OmitEmpty().OnValue(func() error {
|
||||
if zoneName.V == "" {
|
||||
zoneName.V = DefaultZoneName
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
version.Key("version").OmitEmpty(),
|
||||
); err != nil {
|
||||
sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()})
|
||||
return
|
||||
}
|
||||
if id, err = m.cluster.addFlashNode(nodeAddr, zoneName, version); err != nil {
|
||||
if id, err = m.cluster.addFlashNode(nodeAddr.V, zoneName.V, version.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
@ -218,10 +228,11 @@ func (m *Server) listFlashNodes(w http.ResponseWriter, r *http.Request) {
|
||||
doStatAndMetric(proto.FlashNodeList, metric, nil, nil)
|
||||
}()
|
||||
zoneFlashNodes := make(map[string][]*proto.FlashNodeViewInfo)
|
||||
listAll := extractListAll(r)
|
||||
var listAll common.Bool
|
||||
parseArgs(r, listAll.All().OmitEmpty().OmitError())
|
||||
m.cluster.flashNodeTopo.flashNodeMap.Range(func(key, value interface{}) bool {
|
||||
flashNode := value.(*FlashNode)
|
||||
if listAll || flashNode.isActiveAndEnable() {
|
||||
if listAll.V || flashNode.isActiveAndEnable() {
|
||||
zoneFlashNodes[flashNode.ZoneName] = append(zoneFlashNodes[flashNode.ZoneName], flashNode.getFlashNodeViewInfo())
|
||||
}
|
||||
return true
|
||||
@ -235,13 +246,13 @@ func (m *Server) getFlashNode(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.FlashNodeGet, metric, err, nil)
|
||||
}()
|
||||
var nodeAddr string
|
||||
if nodeAddr, err = parseAndExtractNodeAddr(r); err != nil {
|
||||
var nodeAddr common.String
|
||||
if err = parseArgs(r, argParserNodeAddr(&nodeAddr)); err != nil {
|
||||
sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()})
|
||||
return
|
||||
}
|
||||
var flashNode *FlashNode
|
||||
if flashNode, err = m.cluster.peekFlashNode(nodeAddr); err != nil {
|
||||
if flashNode, err = m.cluster.peekFlashNode(nodeAddr.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
@ -254,13 +265,13 @@ func (m *Server) removeFlashNode(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.FlashNodeRemove, metric, err, nil)
|
||||
}()
|
||||
var offLineAddr string
|
||||
if offLineAddr, err = parseAndExtractNodeAddr(r); err != nil {
|
||||
var offLineAddr common.String
|
||||
if err = parseArgs(r, argParserNodeAddr(&offLineAddr)); err != nil {
|
||||
sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()})
|
||||
return
|
||||
}
|
||||
var node *FlashNode
|
||||
if node, err = m.cluster.peekFlashNode(offLineAddr); err != nil {
|
||||
if node, err = m.cluster.peekFlashNode(offLineAddr.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(proto.ErrDataNodeNotExists))
|
||||
return
|
||||
}
|
||||
@ -316,8 +327,8 @@ func (c *Cluster) delFlashNodeFromCache(flashNode *FlashNode) {
|
||||
|
||||
func (m *Server) setFlashNode(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
nodeAddr string
|
||||
state bool
|
||||
nodeAddr common.String
|
||||
enable common.Bool
|
||||
flashNode *FlashNode
|
||||
err error
|
||||
)
|
||||
@ -325,27 +336,27 @@ func (m *Server) setFlashNode(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
doStatAndMetric(proto.FlashNodeSet, metric, err, nil)
|
||||
}()
|
||||
if nodeAddr, state, err = parseAndExtractFlashNode(r); err != nil {
|
||||
if err = parseArgs(r, argParserNodeAddr(&nodeAddr), enable.Enable()); err != nil {
|
||||
sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()})
|
||||
return
|
||||
}
|
||||
if flashNode, err = m.cluster.peekFlashNode(nodeAddr); err != nil {
|
||||
if flashNode, err = m.cluster.peekFlashNode(nodeAddr.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
if err = m.cluster.updateFlashNode(flashNode, state); err != nil {
|
||||
if err = m.cluster.updateFlashNode(flashNode, enable.V); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
sendOkReply(w, r, newSuccessHTTPReply("set flashNode success"))
|
||||
}
|
||||
|
||||
func (c *Cluster) updateFlashNode(flashNode *FlashNode, state bool) (err error) {
|
||||
func (c *Cluster) updateFlashNode(flashNode *FlashNode, enable bool) (err error) {
|
||||
flashNode.Lock()
|
||||
defer flashNode.Unlock()
|
||||
if flashNode.IsEnable != state {
|
||||
if flashNode.IsEnable != enable {
|
||||
oldState := flashNode.IsEnable
|
||||
flashNode.IsEnable = state
|
||||
flashNode.IsEnable = enable
|
||||
if err = c.syncUpdateFlashNode(flashNode); err != nil {
|
||||
flashNode.IsEnable = oldState
|
||||
return
|
||||
@ -383,44 +394,19 @@ func (c *Cluster) syncPutFlashNodeInfo(opType uint32, flashNode *FlashNode) (err
|
||||
func (c *Cluster) peekFlashNode(addr string) (flashNode *FlashNode, err error) {
|
||||
value, ok := c.flashNodeTopo.flashNodeMap.Load(addr)
|
||||
if !ok {
|
||||
err = errors.Trace(flashNodeNotFound(addr), "%v not found", addr)
|
||||
err = errors.Trace(notFoundMsg(fmt.Sprintf("flashnode[%v]", addr)), "")
|
||||
return
|
||||
}
|
||||
flashNode = value.(*FlashNode)
|
||||
return
|
||||
}
|
||||
|
||||
func flashNodeNotFound(addr string) (err error) {
|
||||
return notFoundMsg(fmt.Sprintf("flashnode[%v]", addr))
|
||||
}
|
||||
|
||||
func parseRequestForAddFlashNode(r *http.Request) (nodeAddr, zoneName, version string, err error) {
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return
|
||||
}
|
||||
if nodeAddr, err = extractNodeAddr(r); err != nil {
|
||||
return
|
||||
}
|
||||
if zoneName = r.FormValue(zoneNameKey); zoneName == "" {
|
||||
zoneName = DefaultZoneName
|
||||
}
|
||||
version = r.FormValue(versionKey)
|
||||
return
|
||||
}
|
||||
|
||||
func parseAndExtractFlashNode(r *http.Request) (nodeAddr string, state bool, err error) {
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return
|
||||
}
|
||||
nodeAddr, err = extractNodeAddr(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
state, err = strconv.ParseBool(r.FormValue(stateKey))
|
||||
return
|
||||
}
|
||||
|
||||
func extractListAll(r *http.Request) (all bool) {
|
||||
all, _ = strconv.ParseBool(r.FormValue("all"))
|
||||
return
|
||||
func argParserNodeAddr(nodeAddr *common.String) *common.Argument {
|
||||
return nodeAddr.Addr().OnValue(func() error {
|
||||
if ipAddr, ok := util.ParseAddrToIpAddr(nodeAddr.V); ok {
|
||||
nodeAddr.V = ipAddr
|
||||
return nil
|
||||
}
|
||||
return unmatchedKey(new(common.String).Addr().Key())
|
||||
})
|
||||
}
|
||||
|
||||
@ -32,11 +32,11 @@ func testFlashNodeSet(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.True(t, fnView.IsEnable)
|
||||
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs1Addr, "false"))
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs1Addr, false))
|
||||
fnView, err = mc.NodeAPI().GetFlashNode(mfs1Addr)
|
||||
require.NoError(t, err)
|
||||
require.False(t, fnView.IsEnable)
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs1Addr, "true"))
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs1Addr, true))
|
||||
}
|
||||
|
||||
func testFlashNodeRemove(t *testing.T) {
|
||||
@ -94,9 +94,9 @@ func testFlashNodeList(t *testing.T) {
|
||||
require.Equal(t, 2, len(zoneNodes[testZone2]))
|
||||
require.Equal(t, 3, len(zoneNodes[testZone3]))
|
||||
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs7Addr, "0"))
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs7Addr, false))
|
||||
defer func() {
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs7Addr, "1"))
|
||||
require.NoError(t, mc.NodeAPI().SetFlashNode(mfs7Addr, true))
|
||||
}()
|
||||
|
||||
zoneNodes, err = mc.NodeAPI().ListFlashNodes(false)
|
||||
|
||||
@ -63,12 +63,12 @@ func (zone *FlashNodeZone) selectFlashNodes(count int, excludeHosts []string) (n
|
||||
if contains(excludeHosts, flashNode.Addr) {
|
||||
return true
|
||||
}
|
||||
if flashNode.isWriteable() {
|
||||
newHosts = append(newHosts, flashNode.Addr)
|
||||
}
|
||||
if len(newHosts) >= count {
|
||||
return false
|
||||
}
|
||||
if flashNode.isWriteable() {
|
||||
newHosts = append(newHosts, flashNode.Addr)
|
||||
}
|
||||
return true
|
||||
})
|
||||
if len(newHosts) != count {
|
||||
|
||||
@ -196,9 +196,9 @@ func (api *NodeAPI) AddFlashNode(serverAddr, zoneName, version string) (id uint6
|
||||
return
|
||||
}
|
||||
|
||||
func (api *NodeAPI) SetFlashNode(addr, state string) (err error) {
|
||||
return api.mc.request(newRequest(post, proto.FlashNodeSet).Header(api.h).
|
||||
addParam("addr", addr).addParam("state", state))
|
||||
func (api *NodeAPI) SetFlashNode(addr string, enable bool) (err error) {
|
||||
return api.mc.request(newRequest(post, proto.FlashNodeSet).
|
||||
Header(api.h).Param(anyParam{"addr", addr}, anyParam{"enable", enable}))
|
||||
}
|
||||
|
||||
func (api *NodeAPI) RemoveFlashNode(nodeAddr string) (result string, err error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user