5733c71c50
We were ignoring quite a few error cases, and had one case where we weren't actually updating state where we wanted to. Unfortunately, if the linter doesn't pass, nobody has any reason to actually check lint failures in CI. There are three remaining XXXs marked in the code for lint.
139 lines
2.2 KiB
Go
139 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"sync"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/filecoin-project/go-jsonrpc"
|
|
|
|
"github.com/filecoin-project/lotus/node/repo"
|
|
)
|
|
|
|
type NodeState int
|
|
|
|
const (
|
|
NodeUnknown = iota //nolint:deadcode
|
|
NodeRunning
|
|
NodeStopped
|
|
)
|
|
|
|
type api struct {
|
|
cmds int32
|
|
running map[int32]*runningNode
|
|
runningLk sync.Mutex
|
|
genesis string
|
|
}
|
|
|
|
type nodeInfo struct {
|
|
Repo string
|
|
ID int32
|
|
APIPort int32
|
|
State NodeState
|
|
|
|
FullNode string // only for storage nodes
|
|
Storage bool
|
|
}
|
|
|
|
func (api *api) Nodes() []nodeInfo {
|
|
api.runningLk.Lock()
|
|
out := make([]nodeInfo, 0, len(api.running))
|
|
for _, node := range api.running {
|
|
out = append(out, node.meta)
|
|
}
|
|
|
|
api.runningLk.Unlock()
|
|
|
|
return out
|
|
}
|
|
|
|
func (api *api) TokenFor(id int32) (string, error) {
|
|
api.runningLk.Lock()
|
|
defer api.runningLk.Unlock()
|
|
|
|
rnd, ok := api.running[id]
|
|
if !ok {
|
|
return "", xerrors.New("no running node with this ID")
|
|
}
|
|
|
|
r, err := repo.NewFS(rnd.meta.Repo)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
t, err := r.APIToken()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return string(t), nil
|
|
}
|
|
|
|
func (api *api) FullID(id int32) (int32, error) {
|
|
api.runningLk.Lock()
|
|
defer api.runningLk.Unlock()
|
|
|
|
stor, ok := api.running[id]
|
|
if !ok {
|
|
return 0, xerrors.New("storage node not found")
|
|
}
|
|
|
|
if !stor.meta.Storage {
|
|
return 0, xerrors.New("node is not a storage node")
|
|
}
|
|
|
|
for id, n := range api.running {
|
|
if n.meta.Repo == stor.meta.FullNode {
|
|
return id, nil
|
|
}
|
|
}
|
|
return 0, xerrors.New("node not found")
|
|
}
|
|
|
|
func (api *api) CreateRandomFile(size int64) (string, error) {
|
|
tf, err := ioutil.TempFile(os.TempDir(), "pond-random-")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
_, err = io.CopyN(tf, rand.Reader, size)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if err := tf.Close(); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return tf.Name(), nil
|
|
}
|
|
|
|
func (api *api) Stop(node int32) error {
|
|
api.runningLk.Lock()
|
|
nd, ok := api.running[node]
|
|
api.runningLk.Unlock()
|
|
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
nd.stop()
|
|
return nil
|
|
}
|
|
|
|
type client struct {
|
|
Nodes func() []nodeInfo
|
|
}
|
|
|
|
func apiClient() (*client, error) {
|
|
c := &client{}
|
|
if _, err := jsonrpc.NewClient("ws://"+listenAddr+"/rpc/v0", "Pond", c, nil); err != nil {
|
|
return nil, err
|
|
}
|
|
return c, nil
|
|
}
|