eee53bfa4f
This commit makes all the changes to make Peers() a streaming call. While Peers is usually a non problematic call, for consistency, all calls returning collections assembled through broadcast to cluster peers are now streaming calls.
332 lines
7.0 KiB
Go
332 lines
7.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/ipfs/ipfs-cluster/api"
|
|
|
|
peer "github.com/libp2p/go-libp2p-core/peer"
|
|
|
|
humanize "github.com/dustin/go-humanize"
|
|
)
|
|
|
|
type addedOutputQuiet struct {
|
|
api.AddedOutput
|
|
quiet bool
|
|
}
|
|
|
|
func jsonFormatObject(resp interface{}) {
|
|
switch r := resp.(type) {
|
|
case nil:
|
|
return
|
|
case []addedOutputQuiet:
|
|
// print original objects as in JSON it makes
|
|
// no sense to have a human "quiet" output
|
|
var actual []api.AddedOutput
|
|
for _, s := range r {
|
|
actual = append(actual, s.AddedOutput)
|
|
}
|
|
jsonFormatPrint(actual)
|
|
default:
|
|
jsonFormatPrint(resp)
|
|
}
|
|
}
|
|
|
|
func jsonFormatPrint(obj interface{}) {
|
|
print := func(o interface{}) {
|
|
j, err := json.MarshalIndent(o, "", " ")
|
|
checkErr("generating json output", err)
|
|
fmt.Printf("%s\n", j)
|
|
}
|
|
|
|
switch r := obj.(type) {
|
|
case chan api.Pin:
|
|
for o := range r {
|
|
print(o)
|
|
}
|
|
case chan api.GlobalPinInfo:
|
|
for o := range r {
|
|
print(o)
|
|
}
|
|
case chan api.ID:
|
|
for o := range r {
|
|
print(o)
|
|
}
|
|
default:
|
|
print(obj)
|
|
}
|
|
|
|
}
|
|
|
|
func textFormatObject(resp interface{}) {
|
|
switch r := resp.(type) {
|
|
case nil:
|
|
return
|
|
case string:
|
|
fmt.Println(resp)
|
|
case api.ID:
|
|
textFormatPrintID(r)
|
|
case api.GlobalPinInfo:
|
|
textFormatPrintGPInfo(r)
|
|
case api.Pin:
|
|
textFormatPrintPin(r)
|
|
case api.AddedOutput:
|
|
textFormatPrintAddedOutput(r)
|
|
case addedOutputQuiet:
|
|
textFormatPrintAddedOutputQuiet(r)
|
|
case api.Version:
|
|
textFormatPrintVersion(r)
|
|
case api.Error:
|
|
textFormatPrintError(r)
|
|
case api.Metric:
|
|
textFormatPrintMetric(r)
|
|
case api.Alert:
|
|
textFormatPrintAlert(r)
|
|
case chan api.ID:
|
|
for item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case chan api.GlobalPinInfo:
|
|
for item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case chan api.Pin:
|
|
for item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case []api.AddedOutput:
|
|
for _, item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case []addedOutputQuiet:
|
|
for _, item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case []api.Metric:
|
|
for _, item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case api.GlobalRepoGC:
|
|
textFormatPrintGlobalRepoGC(r)
|
|
case []string:
|
|
for _, item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
case []api.Alert:
|
|
for _, item := range r {
|
|
textFormatObject(item)
|
|
}
|
|
default:
|
|
checkErr("", errors.New("unsupported type returned"+reflect.TypeOf(r).String()))
|
|
}
|
|
}
|
|
|
|
func textFormatPrintID(obj api.ID) {
|
|
if obj.Error != "" {
|
|
fmt.Printf("%s | ERROR: %s\n", obj.ID.Pretty(), obj.Error)
|
|
return
|
|
}
|
|
|
|
fmt.Printf(
|
|
"%s | %s | Sees %d other peers\n",
|
|
obj.ID.Pretty(),
|
|
obj.Peername,
|
|
len(obj.ClusterPeers)-1,
|
|
)
|
|
|
|
addrs := make(sort.StringSlice, 0, len(obj.Addresses))
|
|
for _, a := range obj.Addresses {
|
|
addrs = append(addrs, a.String())
|
|
}
|
|
addrs.Sort()
|
|
fmt.Println(" > Addresses:")
|
|
for _, a := range addrs {
|
|
fmt.Printf(" - %s\n", a)
|
|
}
|
|
if obj.IPFS.Error != "" {
|
|
fmt.Printf(" > IPFS ERROR: %s\n", obj.IPFS.Error)
|
|
return
|
|
}
|
|
|
|
ipfsAddrs := make(sort.StringSlice, 0, len(obj.Addresses))
|
|
for _, a := range obj.IPFS.Addresses {
|
|
ipfsAddrs = append(ipfsAddrs, a.String())
|
|
}
|
|
ipfsAddrs.Sort()
|
|
fmt.Printf(" > IPFS: %s\n", obj.IPFS.ID.Pretty())
|
|
for _, a := range ipfsAddrs {
|
|
fmt.Printf(" - %s\n", a)
|
|
}
|
|
}
|
|
|
|
func textFormatPrintGPInfo(obj api.GlobalPinInfo) {
|
|
var b strings.Builder
|
|
|
|
peers := make([]string, 0, len(obj.PeerMap))
|
|
for k := range obj.PeerMap {
|
|
peers = append(peers, k)
|
|
}
|
|
sort.Strings(peers)
|
|
|
|
fmt.Fprintf(&b, "%s", obj.Cid)
|
|
if obj.Name != "" {
|
|
fmt.Fprintf(&b, " | %s", obj.Name)
|
|
}
|
|
|
|
b.WriteString(":\n")
|
|
|
|
for _, k := range peers {
|
|
v := obj.PeerMap[k]
|
|
if len(v.PeerName) > 0 {
|
|
fmt.Fprintf(&b, " > %-20s : %s", v.PeerName, strings.ToUpper(v.Status.String()))
|
|
} else {
|
|
fmt.Fprintf(&b, " > %-20s : %s", k, strings.ToUpper(v.Status.String()))
|
|
}
|
|
if v.Error != "" {
|
|
fmt.Fprintf(&b, ": %s", v.Error)
|
|
}
|
|
txt, _ := v.TS.MarshalText()
|
|
fmt.Fprintf(&b, " | %s", txt)
|
|
fmt.Fprintf(&b, " | Attempts: %d", v.AttemptCount)
|
|
fmt.Fprintf(&b, " | Priority: %t", v.PriorityPin)
|
|
fmt.Fprintf(&b, "\n")
|
|
}
|
|
fmt.Print(b.String())
|
|
}
|
|
|
|
func textFormatPrintVersion(obj api.Version) {
|
|
fmt.Println(obj.Version)
|
|
}
|
|
|
|
func textFormatPrintPin(obj api.Pin) {
|
|
t := strings.ToUpper(obj.Type.String())
|
|
if obj.Mode == api.PinModeDirect {
|
|
t = t + "-DIRECT"
|
|
}
|
|
|
|
fmt.Printf("%s | %s | %s | ", obj.Cid, obj.Name, t)
|
|
|
|
if obj.IsPinEverywhere() {
|
|
fmt.Printf("Repl. Factor: -1 | Allocations: [everywhere]")
|
|
} else {
|
|
sortAlloc := api.PeersToStrings(obj.Allocations)
|
|
sort.Strings(sortAlloc)
|
|
fmt.Printf("Repl. Factor: %d--%d | Allocations: %s",
|
|
obj.ReplicationFactorMin, obj.ReplicationFactorMax,
|
|
sortAlloc)
|
|
}
|
|
var recStr string
|
|
switch obj.MaxDepth {
|
|
case 0:
|
|
recStr = "Direct"
|
|
case -1:
|
|
recStr = "Recursive"
|
|
default:
|
|
recStr = fmt.Sprintf("Recursive-%d", obj.MaxDepth)
|
|
}
|
|
|
|
fmt.Printf(" | %s", recStr)
|
|
|
|
fmt.Printf(" | Metadata:")
|
|
if len(obj.Metadata) == 0 {
|
|
fmt.Printf(" no")
|
|
} else {
|
|
fmt.Printf(" yes")
|
|
}
|
|
expireAt := "∞"
|
|
if !obj.ExpireAt.IsZero() {
|
|
expireAt = obj.Timestamp.Format("2006-01-02 15:04:05")
|
|
}
|
|
fmt.Printf(" | Exp: %s", expireAt)
|
|
|
|
added := "unknown"
|
|
if !obj.Timestamp.IsZero() {
|
|
added = obj.Timestamp.Format("2006-01-02 15:04:05")
|
|
}
|
|
fmt.Printf(" | Added: %s\n", added)
|
|
}
|
|
|
|
func textFormatPrintAddedOutput(obj api.AddedOutput) {
|
|
fmt.Printf("added %s %s\n", obj.Cid, obj.Name)
|
|
}
|
|
|
|
func textFormatPrintAddedOutputQuiet(obj addedOutputQuiet) {
|
|
if obj.quiet {
|
|
fmt.Printf("%s\n", obj.AddedOutput.Cid)
|
|
} else {
|
|
textFormatPrintAddedOutput(obj.AddedOutput)
|
|
}
|
|
}
|
|
|
|
func textFormatPrintMetric(obj api.Metric) {
|
|
v := obj.Value
|
|
if obj.Name == "freespace" && obj.Weight > 0 {
|
|
v = humanize.Bytes(uint64(obj.Weight))
|
|
}
|
|
|
|
fmt.Printf("%s | %s: %s | Expires in: %s\n", peer.Encode(obj.Peer), obj.Name, v, humanize.Time(time.Unix(0, obj.Expire)))
|
|
}
|
|
|
|
func textFormatPrintAlert(obj api.Alert) {
|
|
fmt.Printf("%s: %s. Expired at: %s. Triggered at: %s\n",
|
|
obj.Peer,
|
|
obj.Name,
|
|
humanize.Time(time.Unix(0, obj.Expire)),
|
|
humanize.Time(obj.TriggeredAt),
|
|
)
|
|
}
|
|
|
|
func textFormatPrintGlobalRepoGC(obj api.GlobalRepoGC) {
|
|
peers := make(sort.StringSlice, 0, len(obj.PeerMap))
|
|
for peer := range obj.PeerMap {
|
|
peers = append(peers, peer)
|
|
}
|
|
peers.Sort()
|
|
|
|
for _, peer := range peers {
|
|
item := obj.PeerMap[peer]
|
|
// If peer name is set, use it instead of peer ID.
|
|
if len(item.Peername) > 0 {
|
|
peer = item.Peername
|
|
}
|
|
if item.Error != "" {
|
|
fmt.Printf("%-15s | ERROR: %s\n", peer, item.Error)
|
|
} else {
|
|
fmt.Printf("%-15s\n", peer)
|
|
}
|
|
|
|
fmt.Printf(" > CIDs:\n")
|
|
for _, key := range item.Keys {
|
|
if key.Error != "" {
|
|
// key.Key will be empty
|
|
fmt.Printf(" - ERROR: %s\n", key.Error)
|
|
continue
|
|
}
|
|
|
|
fmt.Printf(" - %s\n", key.Key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func textFormatPrintError(obj api.Error) {
|
|
fmt.Printf("An error occurred:\n")
|
|
fmt.Printf(" Code: %d\n", obj.Code)
|
|
fmt.Printf(" Message: %s\n", obj.Message)
|
|
}
|
|
|
|
func trackerStatusAllString() string {
|
|
var strs []string
|
|
for _, st := range api.TrackerStatusAll() {
|
|
strs = append(strs, " - "+st.String())
|
|
}
|
|
|
|
sort.Strings(strs)
|
|
return strings.Join(strs, "\n")
|
|
}
|