Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support MARKETS_API_INFO env var, and markets-repo, markets-api-url CLI flags. #6936

Merged
merged 11 commits into from
Jul 29, 2021
5 changes: 3 additions & 2 deletions cli/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ var AuthApiInfoToken = &cli.Command{

ti, ok := cctx.App.Metadata["repoType"]
if !ok {
log.Errorf("unknown repo type, are you sure you want to use GetAPI?")
log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?")
ti = repo.FullNode
}
t, ok := ti.(repo.RepoType)
Expand All @@ -128,7 +128,8 @@ var AuthApiInfoToken = &cli.Command{

// TODO: Log in audit log when it is implemented

fmt.Printf("%s=%s:%s\n", cliutil.EnvForRepo(t), string(token), ainfo.Addr)
currentEnv, _, _ := cliutil.EnvsForAPIInfos(t)
fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr)
raulk marked this conversation as resolved.
Show resolved Hide resolved
return nil
},
}
3 changes: 2 additions & 1 deletion cli/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func GetFullNodeServices(ctx *cli.Context) (ServicesAPI, error) {

var GetAPIInfo = cliutil.GetAPIInfo
var GetRawAPI = cliutil.GetRawAPI
var GetAPI = cliutil.GetAPI
var GetAPI = cliutil.GetCommonAPI

var DaemonContext = cliutil.DaemonContext
var ReqContext = cliutil.ReqContext
Expand All @@ -54,6 +54,7 @@ var GetFullNodeAPIV1 = cliutil.GetFullNodeAPIV1
var GetGatewayAPI = cliutil.GetGatewayAPI

var GetStorageMinerAPI = cliutil.GetStorageMinerAPI
var GetMarketsAPI = cliutil.GetMarketsAPI
var GetWorkerAPI = cliutil.GetWorkerAPI

var CommonCommands = []*cli.Command{
Expand Down
178 changes: 116 additions & 62 deletions cli/util/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,112 +27,145 @@ const (
metadataTraceContext = "traceContext"
)

// The flag passed on the command line with the listen address of the API
// server (only used by the tests)
func flagForAPI(t repo.RepoType) string {
// flagsForAPI returns flags passed on the command line with the listen address
// of the API server (only used by the tests), in the order of precedence they
// should be applied for the requested kind of node.
func flagsForAPI(t repo.RepoType) []string {
switch t {
case repo.FullNode:
return "api-url"
return []string{"api-url"}
case repo.StorageMiner:
return "miner-api-url"
return []string{"miner-api-url"}
case repo.Worker:
return "worker-api-url"
return []string{"worker-api-url"}
case repo.Markets:
// support split markets-miner and monolith deployments.
return []string{"markets-api-url", "miner-api-url"}
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}

func flagForRepo(t repo.RepoType) string {
func flagsForRepo(t repo.RepoType) []string {
switch t {
case repo.FullNode:
return "repo"
return []string{"repo"}
case repo.StorageMiner:
return "miner-repo"
return []string{"miner-repo"}
case repo.Worker:
return "worker-repo"
return []string{"worker-repo"}
case repo.Markets:
// support split markets-miner and monolith deployments.
return []string{"markets-repo", "miner-repo"}
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}

func EnvForRepo(t repo.RepoType) string {
// EnvsForAPIInfos returns the environment variables to use in order of precedence
// to determine the API endpoint of the specified node type.
//
// It returns the current variables and deprecated ones separately, so that
// the user can log a warning when deprecated ones are found to be in use.
func EnvsForAPIInfos(t repo.RepoType) (primary string, fallbacks []string, deprecated []string) {
switch t {
case repo.FullNode:
return "FULLNODE_API_INFO"
return "FULLNODE_API_INFO", nil, nil
case repo.StorageMiner:
return "MINER_API_INFO"
// TODO remove deprecated deprecation period
return "MINER_API_INFO", nil, []string{"STORAGE_API_INFO"}
case repo.Worker:
return "WORKER_API_INFO"
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}

// TODO remove after deprecation period
func envForRepoDeprecation(t repo.RepoType) string {
switch t {
case repo.FullNode:
return "FULLNODE_API_INFO"
case repo.StorageMiner:
return "STORAGE_API_INFO"
case repo.Worker:
return "WORKER_API_INFO"
return "WORKER_API_INFO", nil, nil
case repo.Markets:
// support split markets-miner and monolith deployments.
return "MARKETS_API_INFO", []string{"MINER_API_INFO"}, nil
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}

// GetAPIInfo returns the API endpoint to use for the specified kind of repo.
//
// The order of precedence is as follows:
//
// 1. *-api-url command line flags.
// 2. *_API_INFO environment variables
// 3. deprecated *_API_INFO environment variables
// 4. *-repo command line flags.
func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) {
// Check if there was a flag passed with the listen address of the API
// server (only used by the tests)
apiFlag := flagForAPI(t)
if ctx.IsSet(apiFlag) {
strma := ctx.String(apiFlag)
apiFlags := flagsForAPI(t)
for _, f := range apiFlags {
if !ctx.IsSet(f) {
continue
}
strma := ctx.String(f)
strma = strings.TrimSpace(strma)

return APIInfo{Addr: strma}, nil
}

envKey := EnvForRepo(t)
env, ok := os.LookupEnv(envKey)
if !ok {
// TODO remove after deprecation period
envKey = envForRepoDeprecation(t)
env, ok = os.LookupEnv(envKey)
if ok {
log.Warnf("Use deprecation env(%s) value, please use env(%s) instead.", envKey, EnvForRepo(t))
}
}
//
// Note: it is not correct/intuitive to prefer environment variables over
// CLI flags (repo flags below).
//
primaryEnv, fallbacksEnvs, deprecatedEnvs := EnvsForAPIInfos(t)
env, ok := os.LookupEnv(primaryEnv)
if ok {
return ParseApiInfo(env), nil
}

repoFlag := flagForRepo(t)

p, err := homedir.Expand(ctx.String(repoFlag))
if err != nil {
return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", repoFlag, err)
for _, env := range deprecatedEnvs {
env, ok := os.LookupEnv(env)
if ok {
log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, primaryEnv)
return ParseApiInfo(env), nil
}
}

r, err := repo.NewFS(p)
if err != nil {
return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err)
}
repoFlags := flagsForRepo(t)
for _, f := range repoFlags {
// cannot use ctx.IsSet because it ignores default values
path := ctx.String(f)
if path == "" {
continue
}

ma, err := r.APIEndpoint()
if err != nil {
return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err)
p, err := homedir.Expand(path)
if err != nil {
return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err)
}

r, err := repo.NewFS(p)
if err != nil {
return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err)
}

ma, err := r.APIEndpoint()
if err != nil {
return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err)
}

token, err := r.APIToken()
if err != nil {
log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err)
}

return APIInfo{
Addr: ma.String(),
Token: token,
}, nil
}

token, err := r.APIToken()
if err != nil {
log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err)
for _, env := range fallbacksEnvs {
env, ok := os.LookupEnv(env)
if ok {
return ParseApiInfo(env), nil
}
}

return APIInfo{
Addr: ma.String(),
Token: token,
}, nil
return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t)
}

func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) {
Expand All @@ -153,10 +186,10 @@ func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.
return addr, ainfo.AuthHeader(), nil
}

func GetAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) {
func GetCommonAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) {
ti, ok := ctx.App.Metadata["repoType"]
if !ok {
log.Errorf("unknown repo type, are you sure you want to use GetAPI?")
log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?")
ti = repo.FullNode
}
t, ok := ti.(repo.RepoType)
Expand Down Expand Up @@ -274,6 +307,27 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) {
return client.NewWorkerRPCV0(ctx.Context, addr, headers)
}

func GetMarketsAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) {
// to support lotus-miner cli tests.
if tn, ok := ctx.App.Metadata["testnode-storage"]; ok {
return tn.(api.StorageMiner), func() {}, nil
}

addr, headers, err := GetRawAPI(ctx, repo.Markets, "v0")
if err != nil {
return nil, nil, err
}

if IsVeryVerbose {
_, _ = fmt.Fprintln(ctx.App.Writer, "using markets API v0 endpoint:", addr)
}

// the markets node is a specialised miner's node, supporting only the
// markets API, which is a subset of the miner API. All non-markets
// operations will error out with "unsupported".
return client.NewStorageMinerRPCV0(ctx.Context, addr, headers)
}

func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) {
addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1")
if err != nil {
Expand Down
36 changes: 23 additions & 13 deletions cmd/lotus-miner/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ var infoCmd = &cli.Command{
}

func infoCmdAct(cctx *cli.Context) error {
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
minerApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()

marketsApi, closer, err := lcli.GetMarketsAPI(cctx)
if err != nil {
return err
}
Expand All @@ -64,12 +70,19 @@ func infoCmdAct(cctx *cli.Context) error {

ctx := lcli.ReqContext(cctx)

subsystems, err := nodeApi.RuntimeSubsystems(ctx)
subsystems, err := minerApi.RuntimeSubsystems(ctx)
if err != nil {
return err
}

fmt.Println("Enabled subsystems:", subsystems)
fmt.Println("Enabled subsystems (from miner API):", subsystems)

subsystems, err = marketsApi.RuntimeSubsystems(ctx)
if err != nil {
return err
}

fmt.Println("Enabled subsystems (from markets API):", subsystems)

fmt.Print("Chain: ")

Expand Down Expand Up @@ -103,18 +116,14 @@ func infoCmdAct(cctx *cli.Context) error {

fmt.Println()

if subsystems.Has(api.SubsystemSectorStorage) {
err := handleMiningInfo(ctx, cctx, fullapi, nodeApi)
if err != nil {
return err
}
err = handleMiningInfo(ctx, cctx, fullapi, minerApi)
if err != nil {
return err
}

if subsystems.Has(api.SubsystemMarkets) {
err := handleMarketsInfo(ctx, nodeApi)
if err != nil {
return err
}
err = handleMarketsInfo(ctx, marketsApi)
if err != nil {
return err
}

return nil
Expand Down Expand Up @@ -377,6 +386,7 @@ func handleMarketsInfo(ctx context.Context, nodeApi api.StorageMiner) error {
return sorted[i].status > sorted[j].status
})

fmt.Println()
fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes)))

tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0)
Expand Down
11 changes: 6 additions & 5 deletions cmd/lotus-miner/init_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"gopkg.in/cheggaaa/pb.v1"

"github.com/filecoin-project/go-address"
paramfetch "github.com/filecoin-project/go-paramfetch"
"github.com/filecoin-project/go-paramfetch"
"github.com/filecoin-project/go-state-types/big"

lapi "github.com/filecoin-project/lotus/api"
Expand Down Expand Up @@ -72,7 +72,9 @@ var restoreCmd = &cli.Command{
}
}

if err := restore(ctx, cctx, storageCfg, nil, func(api lapi.FullNode, maddr address.Address, peerid peer.ID, mi miner.MinerInfo) error {
repoPath := cctx.String(FlagMinerRepo)

if err := restore(ctx, cctx, repoPath, storageCfg, nil, func(api lapi.FullNode, maddr address.Address, peerid peer.ID, mi miner.MinerInfo) error {
log.Info("Checking proof parameters")

if err := paramfetch.GetParams(ctx, build.ParametersJSON(), build.SrsJSON(), uint64(mi.SectorSize)); err != nil {
Expand All @@ -94,7 +96,7 @@ var restoreCmd = &cli.Command{
},
}

func restore(ctx context.Context, cctx *cli.Context, strConfig *stores.StorageConfig, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi miner.MinerInfo) error) error {
func restore(ctx context.Context, cctx *cli.Context, targetPath string, strConfig *stores.StorageConfig, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi miner.MinerInfo) error) error {
if cctx.Args().Len() != 1 {
return xerrors.Errorf("expected 1 argument")
}
Expand Down Expand Up @@ -142,8 +144,7 @@ func restore(ctx context.Context, cctx *cli.Context, strConfig *stores.StorageCo

log.Info("Checking if repo exists")

repoPath := cctx.String(FlagMinerRepo)
r, err := repo.NewFS(repoPath)
r, err := repo.NewFS(targetPath)
if err != nil {
return err
}
Expand Down
Loading