Skip to content

Commit

Permalink
Merge pull request #2649 from oasislabs/tjanez/cli-ux-improvements
Browse files Browse the repository at this point in the history
Various CLI improvements
  • Loading branch information
tjanez authored Feb 6, 2020
2 parents d4c4116 + 6a1d149 commit 942511e
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 93 deletions.
3 changes: 3 additions & 0 deletions .changelog/2508.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add `oasis-node registry node is-registered` subcommand.

It checks whether the node is registered.
8 changes: 8 additions & 0 deletions .changelog/2649.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Add `oasis-node identity tendermint show-{node,consensus}-address` subcommands.

The `show-node-address` subcommmand returns node's public key converted to
Tendermint's address format.
It replaces the `oasis-node debug tendermint show-node-id` subcommand.

The `show-consensus-address` subcommand returns node's consensus key converted
to Tendermint's address format.
5 changes: 5 additions & 0 deletions .changelog/2649.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Make `oasis control is-synced` subcommand more verbose.

Running `oasis-node control is-synced` will now print a message indicating
whether a node has completed initial syncing or not to stdout in addition to
returning an appropriate status code.
3 changes: 3 additions & 0 deletions go/oasis-node/cmd/control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package control

import (
"context"
"fmt"
"os"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -77,8 +78,10 @@ func doIsSynced(cmd *cobra.Command, args []string) {
os.Exit(128)
}
if synced {
fmt.Println("node completed initial syncing")
os.Exit(0)
} else {
fmt.Println("node has not completed initial syncing")
os.Exit(1)
}
}
Expand Down
30 changes: 0 additions & 30 deletions go/oasis-node/cmd/debug/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"path/filepath"

"github.com/spf13/cobra"

"github.com/oasislabs/oasis-core/go/common/cbor"
"github.com/oasislabs/oasis-core/go/common/crypto/signature"
"github.com/oasislabs/oasis-core/go/common/identity"
"github.com/oasislabs/oasis-core/go/common/logging"
"github.com/oasislabs/oasis-core/go/consensus/tendermint/crypto"
"github.com/oasislabs/oasis-core/go/consensus/tendermint/inspector"
cmdCommon "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common"
)
Expand All @@ -32,12 +28,6 @@ var (
Short: "dump ABCI mux state as JSON",
Run: doDumpMuxState,
}

tmShowNodeIDCmd = &cobra.Command{
Use: "show-node-id",
Short: "otuputs tendermint node id",
Run: showNodeID,
}
)

func doDumpMuxState(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -83,29 +73,9 @@ func doDumpMuxState(cmd *cobra.Command, args []string) {
fmt.Printf("%s\n", buf.Bytes())
}

func showNodeID(cmd *cobra.Command, args []string) {
if err := cmdCommon.Init(); err != nil {
cmdCommon.EarlyLogAndExit(err)
}

logger := logging.GetLogger("cmd/debug/tendermint/show-node-id")

var pubKey signature.PublicKey

if err := pubKey.LoadPEM(filepath.Join(cmdCommon.DataDir(), identity.NodeKeyPubFilename), nil); err != nil {
logger.Error("failed to open node identity public key",
"err", err,
)
return
}

fmt.Println(crypto.PublicKeyToTendermint(&pubKey).Address())
}

// Register registers the tendermint sub-command and all of it's children.
func Register(parentCmd *cobra.Command) {
tmDumpMuxStateCmd.Flags().StringVarP(&stateFilename, "state", "s", "abci-mux-state.bolt.db", "ABCI mux state file to dump")
tmCmd.AddCommand(tmShowNodeIDCmd)
tmCmd.AddCommand(tmDumpMuxStateCmd)
parentCmd.AddCommand(tmCmd)
}
3 changes: 3 additions & 0 deletions go/oasis-node/cmd/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/oasislabs/oasis-core/go/common/logging"
cmdCommon "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common"
cmdFlags "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common/flags"
"github.com/oasislabs/oasis-core/go/oasis-node/cmd/identity/tendermint"
)

var (
Expand Down Expand Up @@ -56,6 +57,8 @@ func doNodeInit(cmd *cobra.Command, args []string) {

// Register registers the client sub-command and all of it's children.
func Register(parentCmd *cobra.Command) {
tendermint.Register(identityCmd)

identityInitCmd.Flags().AddFlagSet(cmdFlags.VerboseFlags)
identityCmd.AddCommand(identityInitCmd)

Expand Down
94 changes: 94 additions & 0 deletions go/oasis-node/cmd/identity/tendermint/tendermint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Package tendermint implements the tendermint identity sub-commands.
package tendermint

import (
"fmt"
"os"
"path/filepath"
"strings"
"unicode"

"github.com/spf13/cobra"
flag "github.com/spf13/pflag"

"github.com/oasislabs/oasis-core/go/common/crypto/signature"
"github.com/oasislabs/oasis-core/go/common/identity"
"github.com/oasislabs/oasis-core/go/common/logging"
"github.com/oasislabs/oasis-core/go/consensus/tendermint/crypto"
cmdCommon "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common"
cmdFlags "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common/flags"
tmCommon "github.com/tendermint/tendermint/libs/common"
)

var (
tmCmd = &cobra.Command{
Use: "tendermint",
Short: "tendermint backend utilities",
}

tmShowNodeAddressCmd = &cobra.Command{
Use: "show-node-address",
Short: "outputs node's tendermint address",
Run: showNodeAddress,
}

tmShowConsensusAddressCmd = &cobra.Command{
Use: "show-consensus-address",
Short: "outputs consensus' (validator's) tendermint address",
Run: showConsensusAddress,
}

logger = logging.GetLogger("cmd/identity/tendermint")

tmFlags = flag.NewFlagSet("", flag.ContinueOnError)
)

func printTmAddress(desc string, keyFile string) {
if err := cmdCommon.Init(); err != nil {
cmdCommon.EarlyLogAndExit(err)
}

var pubKey signature.PublicKey

if err := pubKey.LoadPEM(filepath.Join(cmdCommon.DataDir(), keyFile), nil); err != nil {
logger.Error("failed to open node's public key",
"err", err,
"key_file", keyFile,
)
os.Exit(1)
}

tmAddress := crypto.PublicKeyToTendermint(&pubKey).Address()
if cmdFlags.Verbose() {
descBytes := []byte(desc)
descBytes[0] = byte(unicode.ToUpper(rune(descBytes[0])))
fmt.Printf("%s: %s (fingerprint: %X)\n", descBytes, tmAddress, tmCommon.Fingerprint(tmAddress))
} else {
fmt.Println(tmAddress)
}
}

func showNodeAddress(cmd *cobra.Command, args []string) {
desc := strings.TrimPrefix(cmd.Short, "outputs ")
printTmAddress(desc, identity.NodeKeyPubFilename)
}

func showConsensusAddress(cmd *cobra.Command, args []string) {
desc := strings.TrimPrefix(cmd.Short, "outputs ")
printTmAddress(desc, identity.ConsensusKeyPubFilename)
}

// Register registers the tendermint sub-command and all of it's children.
func Register(parentCmd *cobra.Command) {
tmCmd.AddCommand(tmShowNodeAddressCmd)
tmCmd.AddCommand(tmShowConsensusAddressCmd)

tmShowNodeAddressCmd.Flags().AddFlagSet(tmFlags)
tmShowConsensusAddressCmd.Flags().AddFlagSet(tmFlags)

parentCmd.AddCommand(tmCmd)
}

func init() {
tmFlags.AddFlagSet(cmdFlags.VerboseFlags)
}
75 changes: 59 additions & 16 deletions go/oasis-node/cmd/registry/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ var (
Run: doList,
}

isRegisteredCmd = &cobra.Command{
Use: "is-registered",
Short: "check whether the node is registered",
Run: doIsRegistered,
}

logger = logging.GetLogger("cmd/registry/node")
)

Expand Down Expand Up @@ -325,31 +331,68 @@ func doList(cmd *cobra.Command, args []string) {
}
}

func doIsRegistered(cmd *cobra.Command, args []string) {
if err := cmdCommon.Init(); err != nil {
cmdCommon.EarlyLogAndExit(err)
}

dataDir, err := cmdCommon.DataDirOrPwd()
if err != nil {
logger.Error("failed to query data directory",
"err", err,
)
os.Exit(1)
}

// Load node's identity.
nodeSignerFactory := fileSigner.NewFactory(dataDir, signature.SignerNode, signature.SignerP2P, signature.SignerConsensus)
nodeIdentity, err := identity.Load(dataDir, nodeSignerFactory)
if err != nil {
logger.Error("failed to load node identity",
"err", err,
)
os.Exit(1)
}

conn, client := doConnect(cmd)
defer conn.Close()

nodes, err := client.GetNodes(context.Background(), consensus.HeightLatest)
if err != nil {
logger.Error("failed to query nodes",
"err", err,
)
os.Exit(1)
}

for _, node := range nodes {
if node.ID.Equal(nodeIdentity.NodeSigner.Public()) {
fmt.Println("node is registered")
os.Exit(0)
}
}
fmt.Println("node is not registered")
os.Exit(1)
}

// Register registers the node sub-command and all of it's children.
func Register(parentCmd *cobra.Command) {
for _, v := range []*cobra.Command{
initCmd,
listCmd,
} {
nodeCmd.AddCommand(v)
}
initCmd.Flags().AddFlagSet(flags)
initCmd.Flags().AddFlagSet(cmdFlags.DebugTestEntityFlags)
initCmd.Flags().AddFlagSet(cmdFlags.SignerFlags)

listCmd.Flags().AddFlagSet(cmdGrpc.ClientFlags)
listCmd.Flags().AddFlagSet(cmdFlags.VerboseFlags)

for _, v := range []*cobra.Command{
initCmd,
} {
v.Flags().AddFlagSet(cmdFlags.DebugTestEntityFlags)
v.Flags().AddFlagSet(cmdFlags.SignerFlags)
v.Flags().AddFlagSet(flags)
}
isRegisteredCmd.Flags().AddFlagSet(cmdGrpc.ClientFlags)

for _, v := range []*cobra.Command{
for _, subCmd := range []*cobra.Command{
initCmd,
listCmd,
isRegisteredCmd,
} {
v.Flags().AddFlagSet(cmdGrpc.ClientFlags)
nodeCmd.AddCommand(subCmd)
}

parentCmd.AddCommand(nodeCmd)
}

Expand Down
36 changes: 33 additions & 3 deletions go/oasis-test-runner/scenario/e2e/identity_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,49 @@ func (ident *identityCLIImpl) Fixture() (*oasis.NetworkFixture, error) {
}

func (ident *identityCLIImpl) Run(childEnv *env.Env) error {
// Provision node's identity.
args := []string{
"identity", "init",
"--" + common.CfgDataDir, ident.dataDir,
}
if err := cli.RunSubCommand(childEnv, ident.logger, "identity-init", ident.nodeBinary, args); err != nil {
return fmt.Errorf("scenario/e2e/identity_cli: failed provision node identity: %w", err)
return fmt.Errorf("scenario/e2e/identity_cli: failed provision node's identity: %w", err)
}

// Load created identity.
if err := ident.loadIdentity(); err != nil {
return fmt.Errorf("scenario/e2e/identity_cli: %w", err)
}

if err := ident.tendermintShowAddress(childEnv, "node"); err != nil {
return fmt.Errorf("scenario/e2e/identity_cli: %w", err)
}
if err := ident.tendermintShowAddress(childEnv, "consensus"); err != nil {
return fmt.Errorf("scenario/e2e/identity_cli: %w", err)
}

return nil
}

func (ident *identityCLIImpl) loadIdentity() error {
ident.logger.Info("loading generated entity")

factory := fileSigner.NewFactory(ident.dataDir, signature.SignerNode, signature.SignerP2P, signature.SignerConsensus)
if _, err := identity.Load(ident.dataDir, factory); err != nil {
return fmt.Errorf("scenario/e2e/identity_cli: failed to load node initialized identity: %w", err)
return fmt.Errorf("failed to load node's identity: %w", err)
}
return nil
}

func (ident *identityCLIImpl) tendermintShowAddress(childEnv *env.Env, addrName string) error {
subCmd := fmt.Sprintf("show-%s-address", addrName)
ident.logger.Info(fmt.Sprintf("running tendermint %s", subCmd))

args := []string{
"identity", "tendermint", subCmd,
"--" + common.CfgDataDir, ident.dataDir,
}
if out, err := cli.RunSubCommandWithOutput(childEnv, ident.logger, subCmd, ident.nodeBinary, args); err != nil {
return fmt.Errorf("failed to get %s's tendermint address: error: %w output: %s", addrName, err, out.String())
}
return nil
}
Loading

0 comments on commit 942511e

Please sign in to comment.