Add env var for API token and location

Usage: FULLNODE_API_INFO or STORAGE_API_INFO
Content of env var: `<token>:<api multiaddr>`
Example: `FULLNODE_API_INFO="$(cat ~/.lotus/token)dsds:$(cat ~/.lotus/api)"`

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
This commit is contained in:
Jakub Sztandera 2019-12-09 13:36:56 +01:00
parent 3df30b1303
commit fb7850803e
No known key found for this signature in database
GPG Key ID: 9A9AF56F8B3879BA
5 changed files with 121 additions and 61 deletions

View File

@ -2,13 +2,16 @@ package cli
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
"strings"
"syscall" "syscall"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/mitchellh/go-homedir" "github.com/mitchellh/go-homedir"
"github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr-net" manet "github.com/multiformats/go-multiaddr-net"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
@ -28,59 +31,121 @@ const (
// ApiConnector returns API instance // ApiConnector returns API instance
type ApiConnector func() api.FullNode type ApiConnector func() api.FullNode
func RepoInfo(ctx *cli.Context, repoFlag string) (string, string, error) { type APIInfo struct {
Addr multiaddr.Multiaddr
Token []byte
}
func (a APIInfo) DialArgs() (string, error) {
_, addr, err := manet.DialArgs(a.Addr)
return "ws://" + addr + "/rpc/v0", err
}
func (a APIInfo) AuthHeader() http.Header {
if len(a.Token) != 0 {
headers := http.Header{}
headers.Add("Authorization", "Bearer "+string(a.Token))
return headers
}
log.Warn("API Token not set and requested, capabilities might be limited.")
return nil
}
func flagForRepo(t repo.RepoType) string {
switch t {
case repo.FullNode:
return "repo"
case repo.StorageMiner:
return "storagerepo"
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}
func envForRepo(t repo.RepoType) string {
switch t {
case repo.FullNode:
return "FULLNODE_API_INFO"
case repo.StorageMiner:
return "STORAGE_API_INFO"
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}
func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) {
if env, ok := os.LookupEnv(envForRepo(t)); ok {
sp := strings.SplitN(env, ":", 2)
if len(sp) != 2 {
log.Warnf("invalid env(%s) value, missing token or address", envForRepo(t))
} else {
ma, err := multiaddr.NewMultiaddr(sp[1])
if err != nil {
return APIInfo{}, xerrors.Errorf("could not parse multiaddr from env(%s): %w", envForRepo(t), err)
}
return APIInfo{
Addr: ma,
Token: []byte(sp[0]),
}, nil
}
}
repoFlag := flagForRepo(t)
p, err := homedir.Expand(ctx.String(repoFlag)) p, err := homedir.Expand(ctx.String(repoFlag))
if err != nil { if err != nil {
return "", "", err return APIInfo{}, xerrors.Errorf("cound not exand home dir (%s): %w", repoFlag, err)
} }
r, err := repo.NewFS(p) r, err := repo.NewFS(p)
if err != nil { if err != nil {
return "", "", err return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err)
} }
ma, err := r.APIEndpoint() ma, err := r.APIEndpoint()
if err != nil { if err != nil {
return "", "", xerrors.Errorf("failed to get api endpoint: (%s) %w", p, err) return APIInfo{}, xerrors.Errorf("could not get api enpoint: %w", err)
}
_, addr, err := manet.DialArgs(ma)
if err != nil {
return "", "", err
} }
return p, addr, nil
}
func GetRawAPI(ctx *cli.Context, repoFlag string) (string, http.Header, error) {
rdir, addr, err := RepoInfo(ctx, repoFlag)
if err != nil {
return "", nil, err
}
r, err := repo.NewFS(rdir)
if err != nil {
return "", nil, err
}
var headers http.Header
token, err := r.APIToken() token, err := r.APIToken()
if err != nil { if err != nil {
log.Warnf("Couldn't load CLI token, capabilities may be limited: %w", err) log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err)
} else {
headers = http.Header{}
headers.Add("Authorization", "Bearer "+string(token))
} }
return "ws://" + addr + "/rpc/v0", headers, nil return APIInfo{
Addr: ma,
Token: token,
}, nil
}
func GetRawAPI(ctx *cli.Context, t repo.RepoType) (string, http.Header, error) {
ainfo, err := GetAPIInfo(ctx, t)
if err != nil {
return "", nil, xerrors.Errorf("could not get API info: %w", err)
}
addr, err := ainfo.DialArgs()
if err != nil {
return "", nil, xerrors.Errorf("could not get DialArgs: %w", err)
}
return addr, ainfo.AuthHeader(), nil
} }
func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) {
f := "repo" ti, ok := ctx.App.Metadata["repoType"]
if ctx.String("storagerepo") != "" { if !ok {
f = "storagerepo" log.Errorf("unknown repo type, are you sure you want to use GetAPI?")
ti = repo.FullNode
}
t, ok := ti.(repo.RepoType)
if !ok {
log.Errorf("repoType type does not match the type of repo.RepoType")
} }
addr, headers, err := GetRawAPI(ctx, f) addr, headers, err := GetRawAPI(ctx, t)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -89,7 +154,7 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) {
} }
func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error) { func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error) {
addr, headers, err := GetRawAPI(ctx, "repo") addr, headers, err := GetRawAPI(ctx, repo.FullNode)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -98,7 +163,7 @@ func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error
} }
func GetStorageMinerAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) { func GetStorageMinerAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) {
addr, headers, err := GetRawAPI(ctx, "storagerepo") addr, headers, err := GetRawAPI(ctx, repo.StorageMiner)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -12,6 +12,8 @@ import (
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/node/repo"
manet "github.com/multiformats/go-multiaddr-net"
) )
var log = logging.Logger("main") var log = logging.Logger("main")
@ -55,6 +57,8 @@ func main() {
Commands: local, Commands: local,
} }
app.Setup()
app.Metadata["repoType"] = repo.StorageMiner
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
log.Warnf("%+v", err) log.Warnf("%+v", err)
@ -77,12 +81,11 @@ var runCmd = &cli.Command{
defer closer() defer closer()
ctx := lcli.ReqContext(cctx) ctx := lcli.ReqContext(cctx)
_, auth, err := lcli.GetRawAPI(cctx, "storagerepo") ainfo, err := lcli.GetAPIInfo(cctx, repo.StorageMiner)
_, storageAddr, err := lcli.RepoInfo(cctx, "storagerepo")
if err != nil { if err != nil {
return xerrors.Errorf("getting miner repo: %w", err) return xerrors.Errorf("could not get api info: %w", err)
} }
_, storageAddr, err := manet.DialArgs(ainfo.Addr)
r, err := homedir.Expand(cctx.String("repo")) r, err := homedir.Expand(cctx.String("repo"))
if err != nil { if err != nil {
@ -102,6 +105,6 @@ var runCmd = &cli.Command{
log.Warn("Shutting down..") log.Warn("Shutting down..")
}() }()
return acceptJobs(ctx, nodeApi, "http://"+storageAddr, auth, r, cctx.Bool("no-precommit"), cctx.Bool("no-commit")) return acceptJobs(ctx, nodeApi, "http://"+storageAddr, ainfo.AuthHeader(), r, cctx.Bool("no-precommit"), cctx.Bool("no-commit"))
}, },
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/tracing" "github.com/filecoin-project/lotus/tracing"
) )
@ -68,6 +69,8 @@ func main() {
Commands: append(local, lcli.Commands...), Commands: append(local, lcli.Commands...),
} }
app.Setup()
app.Metadata["repoType"] = repo.StorageMiner
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
log.Warnf("%+v", err) log.Warnf("%+v", err)

View File

@ -24,8 +24,6 @@ import (
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
) )
const defaultListen = "/ip4/127.0.0.1/tcp/"
var runCmd = &cli.Command{ var runCmd = &cli.Command{
Name: "run", Name: "run",
Usage: "Start a lotus storage miner process", Usage: "Start a lotus storage miner process",
@ -93,14 +91,15 @@ var runCmd = &cli.Command{
node.Online(), node.Online(),
node.Repo(r), node.Repo(r),
node.Override(node.SetApiEndpointKey, func(lr repo.LockedRepo) error { node.ApplyIf(func(s *node.Settings) bool { return cctx.IsSet("api") },
apima, err := parseApi(cctx.String("api")) node.Override(node.SetApiEndpointKey, func(lr repo.LockedRepo) error {
if err != nil { apima, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" +
return err cctx.String("api"))
} if err != nil {
return lr.SetAPIEndpoint(apima) return err
}), }
return lr.SetAPIEndpoint(apima)
})),
node.Override(new(api.FullNode), nodeApi), node.Override(new(api.FullNode), nodeApi),
) )
if err != nil { if err != nil {
@ -162,15 +161,3 @@ var runCmd = &cli.Command{
return srv.Serve(manet.NetListener(lst)) return srv.Serve(manet.NetListener(lst))
}, },
} }
func parseApi(api string) (multiaddr.Multiaddr, error) {
if api == "" {
return nil, xerrors.New("empty --api")
}
if api[0] != '/' {
api = defaultListen + api
}
return multiaddr.NewMultiaddr(api)
}

View File

@ -10,6 +10,7 @@ import (
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/tracing" "github.com/filecoin-project/lotus/tracing"
) )
@ -63,6 +64,7 @@ func main() {
} }
app.Setup() app.Setup()
app.Metadata["traceContext"] = ctx app.Metadata["traceContext"] = ctx
app.Metadata["repoType"] = repo.FullNode
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
span.SetStatus(trace.Status{ span.SetStatus(trace.Status{